Merge mdocml v1.12.3 into head
MFC after: 2 weeks
This commit is contained in:
commit
0745c80c73
370
contrib/mdocml/NEWS
Normal file
370
contrib/mdocml/NEWS
Normal file
@ -0,0 +1,370 @@
|
||||
$Id: NEWS,v 1.3 2013/10/13 16:06:50 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mdocml.bsd.lv distribution.
|
||||
|
||||
Changes in version 1.12.3, released on December 31, 2013
|
||||
|
||||
* In the mdoc(7) SYNOPSIS, line breaks and hanging indentation
|
||||
now work correctly for .Fo/.Fa/.Fc and .Fn blocks.
|
||||
Thanks to Franco Fichtner for doing part of the work.
|
||||
* The mdoc(7) .Bk macro got some addititonal bugfixes.
|
||||
* In mdoc(7) macro arguments, double quotes can now be quoted
|
||||
by doubling them, just like in man(7).
|
||||
Thanks to Tsugutomo ENAMI for the patch.
|
||||
* At the end of man(7) macro lines, end-of-sentence spacing
|
||||
now works. Thanks to Franco Fichtner for the patch.
|
||||
* For backward compatibility, the man(7) parser now supports the
|
||||
man-ext .UR/.UE (uniform resource identifier) block macros.
|
||||
* The man(7) parser now handles closing blocks that are not open
|
||||
more gracefully.
|
||||
* The man(7) parser now ignores blank lines right after .SH and .SS.
|
||||
* In the man(7) formatter, reset indentation when leaving a block,
|
||||
not just when entering the next one.
|
||||
* The roff(7) .nr request now supports incrementing and decrementing
|
||||
number registers and stops parsing the number right before the
|
||||
first non-digit character.
|
||||
* The roff(7) parser now supports the alternative escape sequence
|
||||
syntax \C'uXXXX' for Unicode characters.
|
||||
* The roff(7) parser now parses and ignores the .fam (font family)
|
||||
and .hw (hyphenation points) requests and the \d and \u escape
|
||||
sequences.
|
||||
* The roff(7) manual got a new ESCAPE SEQUENCE REFERENCE.
|
||||
|
||||
Changes in version 1.12.2, released on Oktober 5, 2013
|
||||
|
||||
* The mdoc(7) to man(7) converter, to be called as mandoc -Tman,
|
||||
is now fully functional.
|
||||
* The mandoc(1) utility now supports the -Ios (default operating system)
|
||||
input option, and the -Tutf8 output mode now actually works.
|
||||
* The mandocdb(8) utility no longer truncates existing databases when
|
||||
starting to build new ones, but only replaces them when the build
|
||||
actually succeeds.
|
||||
* The man(7) parser now supports the PD macro (paragraph distance),
|
||||
and (for GNU man-ext compatibility only) EX (example block) and EE
|
||||
(example end). Plus several bugfixes regarding indentation, line
|
||||
breaks, and vertical spacing, and regarding RS following TP.
|
||||
* The roff(7) parser now supports the \f(BI (bold+italic) font escape,
|
||||
the \z (zero cursor advance) escape and the cc (change control
|
||||
character) and it (input line trap) requests. Plus bugfixes regarding
|
||||
the \t (tab) escape, nested escape sequences, and conditional requests.
|
||||
* In mdoc(7), several bugs were fixed related to UTF-8 output of quoting
|
||||
enclosures, delimiter handling, list indentation and horizontal and
|
||||
vertical spacing, formatting of the Lk, %U, and %C macros, plus some
|
||||
bugfixes related to the handling of syntax errors like badly nested
|
||||
font blocks, stray Ta macros outside column lists, unterminated It Xo
|
||||
blocks, and non-text children of Nm blocks.
|
||||
* In tbl(7), the width of horizontal spans and the vertical spacing
|
||||
around tables was corrected, and in man(7) files, a crash was fixed
|
||||
that was triggered by some particular unclosed T{ macros.
|
||||
* For mandoc developers, we now provide a tbl(3) library manual and
|
||||
gmdiff, a very small, very simplistic groff-versus-mandoc output
|
||||
comparison tool.
|
||||
* Provide this NEWS file.
|
||||
|
||||
Changes in version 1.12.1, released on March 23, 2012
|
||||
|
||||
* Significant work on apropos(1) and mandocdb(8). These tools are now
|
||||
much more robust. A whatis(1) implementation is now handled as an
|
||||
apropos(1) mode. These tools are also able to minimally handle
|
||||
pre-formatted pages, that is, those already formatted by another
|
||||
utility such as GNU troff.
|
||||
* The man.cgi(7) script is also now available for wider testing.
|
||||
It interfaces with mandocdb(8) manuals cached by catman(8).
|
||||
HTML output is generated on-the-fly by libmandoc or internal
|
||||
methods to convert pre-formatted pages.
|
||||
* The mailing list archive for the discuss and tech lists are being
|
||||
hosted by Gmane at gmane.comp.tools.mdocml.user and
|
||||
gmane.comp.tools.mdocml.devel, respectively.
|
||||
|
||||
Changes in version 1.12.0, released on October 8, 2011
|
||||
|
||||
* This version features a new, work-in-progress mandoc(1) output mode:
|
||||
-Tman. This mode allows a system maintainer to distribute man(7)
|
||||
media for older systems that may not natively support mdoc(7), such
|
||||
as old Solaris systems.
|
||||
* The -Ofragment option was added to mandoc(1)'s -Thtml and -Txhtml modes.
|
||||
* While adding features, an apropos(1) utility has been merged from the
|
||||
mandoc-tools sandbox. This interfaces with mandocdb(8) for semantic
|
||||
search of manual content. apropos(1) is different from the traditional
|
||||
apropos primarily in allowing keyword search (such as for functions,
|
||||
utilities, etc.) and regular expressions. Note that the calling
|
||||
syntax for apropos is likely to change as it settles down.
|
||||
* In documentation news, the mdoc(7) and man(7) manuals have been
|
||||
made considerably more readable by adding MACRO OVERVIEW sections, by
|
||||
moving the gory details of the LANGUAGE SYNTAX to the roff(7) manual,
|
||||
and by moving the very technical MACRO SYNTAX sections down to the
|
||||
bottom of the page.
|
||||
* Furthermore, for tbl(7), the -Tascii mode horizontal spacing of tables
|
||||
was rewritten completely. It is now compatible with groff(1), both
|
||||
with and without frames and rulers.
|
||||
* Nesting of indented blocks is now supported in man(7), and several
|
||||
bugs were fixed regarding indentation and alignment.
|
||||
* The page headers in mdoc(7) are now nicer for very long titles.
|
||||
|
||||
Changes in version 1.11.7, released on September 2, 2011
|
||||
|
||||
* Added demandoc(1) utility for stripping away macros and escapes.
|
||||
This replaces the historical deroff(1) utility.
|
||||
* Also improved the mdoc(7) and man(7) manuals.
|
||||
|
||||
Changes in version 1.11.6, released on August 16, 2011
|
||||
|
||||
* Handling of tr macro in roff(7) implemented. This makes Perl
|
||||
documentation much more readable. Hyphenation is also now enabled in
|
||||
man(7) format documents. Many other general improvements have been
|
||||
implemented.
|
||||
|
||||
Changes in version 1.11.5, released on July 24, 2011
|
||||
|
||||
* Significant eqn(7) improvements. mdocml can now parse arbitrary eqn
|
||||
input (although few GNU extensions are accepted, nor is mixing
|
||||
low-level roff with eqn). See the eqn(7) manual for details.
|
||||
For the time being, equations are rendered as simple in-line text.
|
||||
The equation parser satisfies the language specified in the
|
||||
Second Edition User's Guide:
|
||||
http://www.kohala.com/start/troff/v7man/eqn/eqn2e.ps
|
||||
|
||||
Changes in version 1.11.4, released on July 12, 2011
|
||||
|
||||
* Bug-fixes and clean-ups across all systems, especially in mandocdb(8)
|
||||
and the man(7) parser. This release was significantly assisted by
|
||||
participants in OpenBSD's c2k11. Thanks!
|
||||
|
||||
Changes in version 1.11.3, released on May 26, 2011
|
||||
|
||||
* Introduce locale-encoding of output with the -Tlocale output option and
|
||||
Unicode escaped-character input. See mandoc(1) and mandoc_char(7),
|
||||
respectively, for details. This allows for non-ASCII characters (e.g.,
|
||||
\[u5000]) to be rendered in the locale's encoding, if said environment
|
||||
supports wide-character encoding (if it does not, -Tascii is used
|
||||
instead). Locale support can be turned off at compile time by removing
|
||||
-DUSE_WCHAR in the Makefile, in which case -Tlocale is always a synonym
|
||||
for -Tascii.
|
||||
* Furthermore, multibyte-encoded documents, such as those in UTF-8, may
|
||||
be on-the-fly recoded into mandoc(1) input by using the newly-added
|
||||
preconv(1) utility. Note: in the future, this feature may be
|
||||
integrated into mandoc(1).
|
||||
|
||||
Changes in version 1.11.2, released on May 12, 2011
|
||||
|
||||
* Corrected some installation issues in version 1.11.1.
|
||||
* Further migration to libmandoc.
|
||||
* Initial public release (this utility is very much under development)
|
||||
of mandocdb(8). This utility produces keyword databases of manual
|
||||
content, which features semantic querying of manual content.
|
||||
|
||||
Changes in version 1.11.1, released on April 4, 2011
|
||||
|
||||
* The earlier libroff, libmdoc, and libman soup have been merged into
|
||||
a single library, libmandoc, which manages all aspects of parsing
|
||||
real manuals, from line-handling to tbl(7) parsing.
|
||||
* As usual, many general fixes and improvements have also occurred.
|
||||
In particular, a great deal of redundancy and superfluous code has
|
||||
been removed with the merging of the backend libraries.
|
||||
* see also the changes in 1.10.10
|
||||
|
||||
Changes in version 1.10.10, March 20, 2011, NOT released
|
||||
|
||||
* Initial eqn(7) functionality is in place. For the time being,
|
||||
this is limited to the recognition of equation blocks;
|
||||
future version of mdocml will expand upon this framework.
|
||||
|
||||
Changes in version 1.10.9, released on January 7, 2011
|
||||
|
||||
* Many back-end fixes have been implemented: argument handling (quoting),
|
||||
man(7) improvements, error/warning classes, and many more.
|
||||
* Initial tbl(7) functionality (see the "TS", "TE", and "T&" macros in
|
||||
the roff(7) manual) has been merged from tbl.bsd.lv. Output is still
|
||||
minimal, especially for -Thtml and -Txhtml, but manages to at least
|
||||
display data. This means that mandoc(1) now has built-in support
|
||||
for two troff preprocessors via libroff: soelim(1) and tbl(1).
|
||||
|
||||
Changes in version 1.10.8, released on December 24, 2010
|
||||
|
||||
* Overhauled the -Thtml and -Txhtml output modes. They now display
|
||||
readable output in arbitrary browsers, including text-based ones like
|
||||
lynx(1). See HTML and XHTML manuals in the DOCUMENTATION section
|
||||
for examples. Attention: available style-sheet classes have been
|
||||
considerably changed! See the example.style.css file for details.
|
||||
Lastly, libmdoc and libman have been cleaned up and reduced in size
|
||||
and complexity.
|
||||
* see also the changes in 1.10.7
|
||||
|
||||
Changes in version 1.10.7, December 6, 2010, NOT released
|
||||
|
||||
Significant improvements merged from OpenBSD downstream, including:
|
||||
* many new roff(7) components,
|
||||
* in-line implementation of troff's soelim(1),
|
||||
* broken-block handling,
|
||||
* overhauled error classifications, and
|
||||
* cleaned up handling of error conditions.
|
||||
|
||||
Changes in version 1.10.6, released on September 27, 2010
|
||||
|
||||
* Calling conventions for mandoc(1) have changed: -W improved and -f
|
||||
deprecated.
|
||||
* Non-ASCII characters are also now uniformly discarded.
|
||||
* Lots of documentation improvements.
|
||||
* Many incremental fixes accomodating for groff's more interesting
|
||||
productions.
|
||||
* Lastly, pod2man(1) preambles are now fully accepted after some
|
||||
considerable roff(7) and special character support.
|
||||
|
||||
Changes in version 1.10.5, released on July 27, 2010
|
||||
|
||||
* Primarily a bug-fix and polish release, but including -Tpdf support
|
||||
in mandoc(1) by way of "Summer of Code". Highlights:
|
||||
* fix "Sm" and "Bd" handling
|
||||
* fix end-of-sentence handling for embedded sentences
|
||||
* polish man(7) documentation
|
||||
* document all mdoc(7) macros
|
||||
* polish mandoc(1) -Tps output
|
||||
* lots of internal clean-ups in character escapes
|
||||
* un-break literal contexts in man(7) documents
|
||||
* improve -Thtml output for -man
|
||||
* add mandoc(1) -Tpdf support
|
||||
|
||||
Changes in version 1.10.4, released on July 12, 2010
|
||||
|
||||
* Lots of features developed during both "Summer of Code" and the
|
||||
OpenBSD c2k10 hackathon:
|
||||
* minimal "ds" roff(7) symbols are supported
|
||||
* beautified SYNOPSIS section output
|
||||
* acceptance of scope-block breakage in mdoc(7)
|
||||
* clarify error message status
|
||||
* many minor bug-fixes and formatting issues resolved
|
||||
* see also changes in 1.10.3
|
||||
|
||||
Changes in version 1.10.3, June 29, 2010, NOT released
|
||||
|
||||
* variable font-width and paper-size support in mandoc(1) -Tps output
|
||||
* "Bk" mdoc(7) support
|
||||
|
||||
Changes in version 1.10.2, released on June 19, 2010
|
||||
|
||||
* Small release featuring text-decoration in -Tps output,
|
||||
a few minor relaxations of errors, and some optimisations.
|
||||
|
||||
Changes in version 1.10.1, released on June 7, 2010
|
||||
|
||||
* This primarily focusses on the "Bl" and "It" macros described in
|
||||
mdoc(7). Multi-line column support is now fully compatible with groff,
|
||||
as are implicit list entries for columns.
|
||||
* Removed manuals(7) in favour of http://manpages.bsd.lv.
|
||||
* The way we handle the SYNOPSIS section (see the SYNOPSIS documentation
|
||||
in MANUAL STRUCTURE) has also been considerably simplified compared
|
||||
to groff's method.
|
||||
* Furthermore, the -Owidth=width output option has been added to -Tascii,
|
||||
see mandoc(1).
|
||||
* Lastly, initial PostScript output has been added with the -Tps option
|
||||
to mandoc(1). It's brutally simple at the moment: fixed-font, with no
|
||||
font decorations.
|
||||
|
||||
Changes in version 1.10.0, released on May 29, 2010
|
||||
|
||||
* Release consisting of the results from the m2k10 hackathon and up-merge
|
||||
from OpenBSD. This requires a significant note of thanks to Ingo
|
||||
Schwarze (OpenBSD) and Joerg Sonnenberger (NetBSD) for their hard work,
|
||||
and again to Joerg for hosting m2k10. Highlights (mostly cribbed from
|
||||
Ingo's m2k10 report) follow in no particular order:
|
||||
* a libroff preprocessor in front of libmdoc and libman stripping out
|
||||
roff(7) instructions;
|
||||
* end-of-sentence (EOS) detection in free-form and macro lines;
|
||||
* correct handling of tab-separated columnar lists in mdoc(7);
|
||||
* improved main calling routines to optionally use mmap(3) for better
|
||||
performance;
|
||||
* cleaned up exiting when invoked as -Tlint or over multiple files
|
||||
with -fign-errors;
|
||||
* error and warning message handling re-written to be unified for
|
||||
libroff, libmdoc, and libman;
|
||||
* handling of badly-nested explicit-scoped macros;
|
||||
* improved free-form text parsing in libman and libmdoc;
|
||||
* significant GNU troff compatibility improvements in -Tascii,
|
||||
largely in terms of spacing;
|
||||
* a regression framework for making sure the many fragilities of GNU
|
||||
troff aren't trampled in subsequent work;
|
||||
* support for -Tascii breaking at hyphens encountered in free-form text;
|
||||
* and many more minor fixes and improvements
|
||||
|
||||
Changes in version 1.9.25, released on May 13, 2010
|
||||
|
||||
* Fixed handling of "\*(Ba" escape.
|
||||
* Backed out -fno-ign-chars (pointless complexity).
|
||||
* Fixed erroneous breaking of literal lines.
|
||||
* Fixed SYNOPSIS breaking lines before non-initial macros.
|
||||
* Changed default section ordering.
|
||||
* Most importantly, the framework for end-of-sentence double-spacing is
|
||||
in place, now implemented for the "end-of-sentence, end-of-line" rule.
|
||||
* This is a stable roll-back point before the mandoc hackathon in Rostock!
|
||||
|
||||
Changes in version 1.9.24, released on May 9, 2010
|
||||
|
||||
* Rolled back break-at-hyphen.
|
||||
* -DUGLY is now the default (no feature splits!).
|
||||
* Free-form text is not de-chunked any more: lines are passed
|
||||
whole-sale into the front-end, including whitespace.
|
||||
* Added mailing lists.
|
||||
|
||||
Changes in version 1.9.23, released on April 7, 2010
|
||||
|
||||
* mdocml has been linked to the OpenBSD build.
|
||||
* This version incorporates many small changes, mostly from patches
|
||||
by OpenBSD, allowing crufty manuals to slip by with warnings instead
|
||||
of erroring-out.
|
||||
* Some subtle semantic issues, such as punctuation scope, have also
|
||||
been fixed.
|
||||
* Lastly, some issues with -Thtml have been fixed, which prompted an
|
||||
update to the online manual pages style layout.
|
||||
|
||||
Changes in version 1.9.22, released on March 31, 2010
|
||||
|
||||
* Adjusted merge of the significant work by Ingo Schwarze
|
||||
in getting "Xo" blocks (block full implicit, e.g., "It"
|
||||
for non-columnar lists) to work properly. This isn't
|
||||
enabled by default: you must specify -DUGLY as a compiler
|
||||
flag (see the Makefile for details).
|
||||
|
||||
Changes in version 1.9.20, released on March 30, 2010
|
||||
|
||||
* More efforts to get roff instructions in man(7) documents under
|
||||
control. Note that roff instructions embedded in line-scoped,
|
||||
next-line macros (e.g. "B") are not supported.
|
||||
* Leading punctuation for mdoc(7) macros, such as "Fl ( ( a",
|
||||
are now correctly handled.
|
||||
|
||||
Changes in version 1.9.18, released on March 27, 2010
|
||||
|
||||
* Many fixes (largely pertaining to scope)
|
||||
and improvements (e.g., handling of apostrophe-control macros,
|
||||
which fixes the strange "BR" seen in some macro output)
|
||||
to handling roff instructions in man(7) documents.
|
||||
|
||||
Changes in version 1.9.17, released on March 25, 2010
|
||||
|
||||
* Accept perlpod(1) standard preamble.
|
||||
* Also accept (and discard) "de", "dei", "am", "ami", and "ig"
|
||||
roff macro blocks.
|
||||
|
||||
Changes in version 1.9.16, released on March 22, 2010
|
||||
|
||||
* Inspired by patches and bug reports by Ingo Schwarze,
|
||||
allowed man(7) to accept non-printing elements to be nested
|
||||
within next-line scopes, such as "br" within "B" or "TH",
|
||||
which is valid roff.
|
||||
* Longsoon architecture also noted and Makefile cleaned up.
|
||||
|
||||
Changes in version 1.9.15, released on February 18, 2010
|
||||
|
||||
* Moved to our new BSD.lv home.
|
||||
* XHTML is now an acceptable output mode for mandoc(1);
|
||||
* "Xr" made more compatible with groff;
|
||||
* "Vt" fixed when invoked in SYNOPSIS;
|
||||
* "\\" escape removed;
|
||||
* end-of-line white-space detected for all lines;
|
||||
* subtle bug fixed in list display for some modes;
|
||||
* compatibility layer checked in for compilation in diverse
|
||||
UNIX systems;
|
||||
* and column lengths handled correctly.
|
||||
|
||||
For older releases, see the ChangeLog files
|
||||
in http://mdocml.bsd.lv/snapshots/ .
|
330
contrib/mdocml/TODO
Normal file
330
contrib/mdocml/TODO
Normal file
@ -0,0 +1,330 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.162 2013/12/25 14:40:34 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* crashes
|
||||
************************************************************************
|
||||
|
||||
None known.
|
||||
|
||||
************************************************************************
|
||||
* missing features
|
||||
************************************************************************
|
||||
|
||||
--- missing roff features ----------------------------------------------
|
||||
|
||||
- roff.c should treat \n(.H>23 and \n(.V>19 in the pod2man(1)
|
||||
preamble as true, see for example AUTHORS in MooseX::Getopt.3p
|
||||
reported by Andreas Voegele <mail at andreasvoegele dot com>
|
||||
Tue, 22 Nov 2011 15:34:47 +0100 on ports@
|
||||
|
||||
- .ad (adjust margins)
|
||||
.ad l -- adjust left margin only (flush left)
|
||||
.ad r -- adjust right margin only (flush right)
|
||||
.ad c -- center text on line
|
||||
.ad b -- adjust both margins (alias: .ad n)
|
||||
.na -- temporarily disable adjustment without changing the mode
|
||||
.ad -- re-enable adjustment without changing the mode
|
||||
Adjustment mode is ignored while in no-fill mode (.nf).
|
||||
|
||||
- .as (append to string)
|
||||
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
|
||||
|
||||
- .ce (center N lines)
|
||||
found by naddy@ in xloadimage(1)
|
||||
found by Juan Francisco Cantero Hurtado <iam at juanfra dot info>
|
||||
in lang/racket(1) Thu, 20 Jun 2013 03:19:11 +0200
|
||||
|
||||
- .fc (field control)
|
||||
found by naddy@ in xloadimage(1)
|
||||
|
||||
- .ll (line length)
|
||||
found by naddy@ in textproc/enchant(1) Sat, 12 Oct 2013 03:27:10 +0200
|
||||
|
||||
- .nr third argument (auto-increment step size, requires \n+)
|
||||
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
|
||||
|
||||
- .ns (no-space mode) occurs in xine-config(1)
|
||||
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
|
||||
|
||||
- .ta (tab settings) occurs in ircbug(1) and probably gnats(1)
|
||||
reported by brad@ Sat, 15 Jan 2011 15:50:51 -0500
|
||||
|
||||
- .ti (temporary indent)
|
||||
found by naddy@ in xloadimage(1)
|
||||
found by bentley@ in nmh(1) Mon, 23 Apr 2012 13:38:28 -0600
|
||||
|
||||
- .while and .shift
|
||||
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
|
||||
|
||||
- \c (interrupted text) should prevent the line break
|
||||
even inside .Bd literal; that occurs in chat(8)
|
||||
also found in cclive(1) - DocBook output
|
||||
|
||||
- \h horizontal move
|
||||
found in cclive(1) DocBook output
|
||||
Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600
|
||||
|
||||
- \n+ and \n- numerical register increment and decrement
|
||||
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
|
||||
|
||||
- using undefined strings or macros defines them to be empty
|
||||
wl@ Mon, 14 Nov 2011 14:37:01 +0000
|
||||
|
||||
--- missing mdoc features ----------------------------------------------
|
||||
|
||||
- fix bad block nesting involving multiple identical explicit blocks
|
||||
see the OpenBSD mdoc_macro.c 1.47 commit message
|
||||
|
||||
- .Bl -column .Xo support is missing
|
||||
ultimate goal:
|
||||
restore .Xr and .Dv to
|
||||
lib/libc/compat-43/sigvec.3
|
||||
lib/libc/gen/signal.3
|
||||
lib/libc/sys/sigaction.2
|
||||
|
||||
- edge case: decide how to deal with blk_full bad nesting, e.g.
|
||||
.Sh .Nm .Bk .Nm .Ek .Sh found by jmc@ in ssh-keygen(1)
|
||||
from jmc@ Wed, 14 Jul 2010 18:10:32 +0100
|
||||
|
||||
- \\ is now implemented correctly
|
||||
* when defining strings and macros using .ds and .de
|
||||
* when parsing roff(7) and man(7) macro arguments
|
||||
It does not yet work in mdoc(7) macro arguments
|
||||
because libmdoc does not yet use mandoc_getarg().
|
||||
Also check what happens in plain text, it must be identical to \e.
|
||||
|
||||
- .Bd -filled should not be the same as .Bd -ragged, but align both
|
||||
the left and right margin. In groff, it is implemented in terms
|
||||
of .ad b, which we don't have either. Found in cksum(1).
|
||||
|
||||
- implement blank `Bl -column', such as
|
||||
.Bl -column
|
||||
.It foo Ta bar
|
||||
.El
|
||||
|
||||
- explicitly disallow nested `Bl -column', which would clobber internal
|
||||
flags defined for struct mdoc_macro
|
||||
|
||||
- In .Bl -column .It, the end of the line probably has to be regarded
|
||||
as an implicit .Ta, if there could be one, see the following mildly
|
||||
ugly code from login.conf(5):
|
||||
.Bl -column minpasswordlen program xetcxmotd
|
||||
.It path Ta path Ta value of Dv _PATH_DEFPATH
|
||||
.br
|
||||
Default search path.
|
||||
reported by Michal Mazurek <akfaew at jasminek dot net>
|
||||
via jmc@ Thu, 7 Apr 2011 16:00:53 +0059
|
||||
|
||||
- inside `.Bl -column' phrases, punctuation is handled like normal
|
||||
text, e.g. `.Bl -column .It Fl x . Ta ...' should give "-x -."
|
||||
|
||||
- inside `.Bl -column' phrases, TERMP_IGNDELIM handling by `Pf'
|
||||
is not safe, e.g. `.Bl -column .It Pf a b .' gives "ab."
|
||||
but should give "ab ."
|
||||
|
||||
- set a meaningful default if no `Bl' list type is assigned
|
||||
|
||||
- have a blank `It' head for `Bl -tag' not puke
|
||||
|
||||
- prohibit `Nm' from having non-text HEAD children
|
||||
(e.g., NetBSD mDNSShared/dns-sd.1)
|
||||
(mdoc_html.c and mdoc_term.c `Nm' handlers can be slightly simplified)
|
||||
|
||||
- When there is free text in the SYNOPSIS and that free text contains
|
||||
the .Nm macro, groff somehow understands to treat the .Nm as an in-line
|
||||
macro, while mandoc treats it as a block macro and breaks the line.
|
||||
No idea how the logic for distinguishing in-line and block instances
|
||||
should be, needs investigation.
|
||||
uqs@ Thu, 2 Jun 2011 11:03:51 +0200
|
||||
uqs@ Thu, 2 Jun 2011 11:33:35 +0200
|
||||
|
||||
--- missing man features -----------------------------------------------
|
||||
|
||||
- groff an-ext.tmac macros (.UR, .UE) occur in xine(5)
|
||||
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
|
||||
also occur in freeciv-client(6) freeciv-server(6) freeciv-modpack(6)
|
||||
reported by bentley@ Tue, 30 Oct 2012 01:05:57 -0600
|
||||
|
||||
- -T[x]html doesn't stipulate non-collapsing spaces in literal mode
|
||||
|
||||
--- missing tbl features -----------------------------------------------
|
||||
|
||||
- implement basic non-parametric .de to support e.g. sox(1)
|
||||
reported by naddy@ Sat, 16 Oct 2010 23:51:57 +0200
|
||||
*** sox(1) still doesn't work, tbl(1) errors need investigation
|
||||
|
||||
- allow standalone `.' to be interpreted as an end-of-layout
|
||||
delimiter instead of being thrown away as a no-op roff line
|
||||
reported by Yuri Pankov, Wed 18 May 2011 11:34:59 CEST
|
||||
|
||||
--- missing misc features ----------------------------------------------
|
||||
|
||||
- italic correction (\/) in PostScript mode
|
||||
Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46
|
||||
|
||||
- The whatis(1) utility looks for whole words in Nm.
|
||||
If the file name of a page does not agree with the contents of any
|
||||
of its Nm macros (e.g. pool(9)), add the file name as an Nm entry
|
||||
to the mandoc.db as well, such that whatis(1) finds it.
|
||||
If there is a page with a file name that does not appear as a substring
|
||||
neither in Nm nor in Nd, the same fix would allow finding that page
|
||||
with apropos(1) using the file name as a key, as well.
|
||||
Issue reported by tedu@ Fri, 05 Jul 2013 21:15:23 -0400
|
||||
|
||||
- clean up escape sequence handling, creating three classes:
|
||||
(1) fully implemented, or parsed and ignored without loss of content
|
||||
(2) unimplemented, potentially causing loss of content
|
||||
or serious mangling of formatting (e.g. \n) -> ERROR
|
||||
see textproc/mgdiff(1) for nice examples
|
||||
(3) undefined, just output the character -> perhaps WARNING
|
||||
|
||||
- look at pages generated from reStructeredText, e.g. devel/mercurial hg(1)
|
||||
These are a weird mixture of man(7) and custom autogenerated low-level
|
||||
roff stuff. Figure out to what extent we can cope.
|
||||
For details, see http://docutils.sourceforge.net/rst.html
|
||||
noted by stsp@ Sat, 24 Apr 2010 09:17:55 +0200
|
||||
reminded by nicm@ Mon, 3 May 2010 09:52:41 +0100
|
||||
|
||||
- look at pages generated from Texinfo source by yat2m, e.g. security/gnupg
|
||||
First impression is not that bad.
|
||||
|
||||
- check compatibility with Plan9:
|
||||
http://swtch.com/usr/local/plan9/tmac/tmac.an
|
||||
http://swtch.com/plan9port/man/man7/man.html
|
||||
"Anthony J. Bentley" <anthonyjbentley@gmail.com> 28 Dec 2010 21:58:40 -0700
|
||||
|
||||
************************************************************************
|
||||
* formatting issues: ugly output
|
||||
************************************************************************
|
||||
|
||||
- a column list with blank `Ta' cells triggers a spurrious
|
||||
start-with-whitespace printing of a newline
|
||||
|
||||
- In .Bl -column,
|
||||
.It Em Authentication<tab>Key Length
|
||||
ought to render "Key Length" with emphasis, too,
|
||||
see OpenBSD iked.conf(5).
|
||||
reported again Nicolas Joly via wiz@ Wed, 12 Oct 2011 00:20:00 +0200
|
||||
|
||||
- empty phrases in .Bl column produce too few blanks
|
||||
try e.g. .Bl -column It Ta Ta
|
||||
reported by millert Fri, 02 Apr 2010 16:13:46 -0400
|
||||
|
||||
- .%T can have trailing punctuation. Currently, it puts the trailing
|
||||
punctuation into a trailing MDOC_TEXT element inside its own scope.
|
||||
That element should rather be outside its scope, such that the
|
||||
punctuation does not get underlines. This is not trivial to
|
||||
implement because .%T then needs some features of in_line_eoln() -
|
||||
slurp all arguments into one single text element - and one feature
|
||||
of in_line() - put trailing punctuation out of scope.
|
||||
Found in mount_nfs(8) and exports(5), search for "Appendix".
|
||||
|
||||
- Trailing punctuation after .%T triggers EOS spacing, at least
|
||||
outside .Rs (eek!). Simply setting ARGSFL_DELIM for .%T is not
|
||||
the right solution, it sends mandoc into an endless loop.
|
||||
reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100
|
||||
|
||||
- in enclosures, mandoc sometimes fancies a bogus end of sentence
|
||||
reminded by jmc@ Thu, 23 Sep 2010 18:13:39 +0059
|
||||
|
||||
- formatting /usr/local/man/man1/latex2man.1 with groff and mandoc
|
||||
reveals lots of bugs both in groff and mandoc...
|
||||
reported by bentley@ Wed, 22 May 2013 23:49:30 -0600
|
||||
|
||||
************************************************************************
|
||||
* formatting issues: gratuitous differences
|
||||
************************************************************************
|
||||
|
||||
- .Rv (and probably .Ex) print different text if an `Nm' has been named
|
||||
or not (run a manual without `Nm blah' to see this). I'm not sure
|
||||
that this exists in the wild, but it's still an error.
|
||||
|
||||
- In .Bl -bullet, the groff bullet is "+\b+\bo\bo", the mandoc bullet
|
||||
is just "o\bo".
|
||||
see for example OpenBSD ksh(1)
|
||||
|
||||
- .Pp between two .It in .Bl -column should produce one,
|
||||
not two blank lines, see e.g. login.conf(5).
|
||||
reported by jmc@ Sun, 17 Apr 2011 14:04:58 +0059
|
||||
reported again by sthen@ Wed, 18 Jan 2012 02:09:39 +0000 (UTC)
|
||||
|
||||
- If the *first* line after .It is .Pp, break the line right after
|
||||
the tag, do not pad with space characters before breaking.
|
||||
See the description of the a, c, and i commands in sed(1).
|
||||
|
||||
- If the first line after .It is .D1, do not assert a blank line
|
||||
in between, see for example tmux(1).
|
||||
reported by nicm@ 13 Jan 2011 00:18:57 +0000
|
||||
|
||||
- Trailing punctuation after .It should trigger EOS spacing.
|
||||
reported by Nicolas Joly Sat, 17 Nov 2012 11:49:54 +0100
|
||||
Probably, this should be fixed somewhere in termp_it_pre(), not sure.
|
||||
|
||||
- .Nx 1.0a
|
||||
should be "NetBSD 1.0A", not "NetBSD 1.0a",
|
||||
see OpenBSD ccdconfig(8).
|
||||
|
||||
- In .Bl -tag, if a tag exceeds the right margin and must be continued
|
||||
on the next line, it must be indented by -width, not width+1;
|
||||
see "rule block|pass" in OpenBSD ifconfig(8).
|
||||
|
||||
- When the -width string contains macros, the macros must be rendered
|
||||
before measuring the width, for example
|
||||
.Bl -tag -width ".Dv message"
|
||||
in magic(5), located in src/usr.bin/file, is the same
|
||||
as -width 7n, not -width 11n.
|
||||
The same applies to .Bl -column column widths;
|
||||
reported again by Nicolas Joly Thu, 1 Mar 2012 13:41:26 +0100 via wiz@ 5 Mar
|
||||
reported again by Franco Fichtner Fri, 27 Sep 2013 21:02:28 +0200
|
||||
An easy partial fix would be to just skip the first word if it starts
|
||||
with a dot, including any following white space, when measuring.
|
||||
|
||||
- The \& zero-width character counts as output.
|
||||
That is, when it is alone on a line between two .Pp,
|
||||
we want three blank lines, not two as in mandoc.
|
||||
|
||||
- Header lines of excessive length:
|
||||
Port OpenBSD man_term.c rev. 1.25 to mdoc_term.c
|
||||
and document it in mdoc(7) and man(7) COMPATIBILITY
|
||||
found while talking to Chris Bennett
|
||||
|
||||
- trailing whitespace must be ignored even when followed by a font escape,
|
||||
see for example
|
||||
makes
|
||||
\fBdig \fR
|
||||
operate in batch mode
|
||||
in dig(1).
|
||||
|
||||
************************************************************************
|
||||
* performance issues
|
||||
************************************************************************
|
||||
|
||||
Several areas can be cleaned up to make mandoc even faster. These are
|
||||
|
||||
- improve hashing mechanism for macros (quite important: performance)
|
||||
|
||||
- improve hashing mechanism for characters (not as important)
|
||||
|
||||
- the PDF file is HUGE: this can be reduced by using relative offsets
|
||||
|
||||
- instead of re-initialising the roff predefined-strings set before each
|
||||
parse, create a read-only version the first time and copy it
|
||||
|
||||
************************************************************************
|
||||
* structural issues
|
||||
************************************************************************
|
||||
|
||||
- We use the input line number at several places to distinguish
|
||||
same-line from different-line input. That plainly doesn't work
|
||||
with user-defined macros, leading to random breakage.
|
||||
|
||||
- Find better ways to prevent endless loops
|
||||
in roff(7) macro and string expansion.
|
||||
|
||||
- Finish cleanup of date handling.
|
||||
Decide which formats should be recognized where.
|
||||
Update both mdoc(7) and man(7) documentation.
|
||||
Triggered by Tim van der Molen Tue, 22 Feb 2011 20:30:45 +0100
|
@ -1,4 +1,4 @@
|
||||
/* $Id: arch.in,v 1.12 2012/01/28 14:02:17 joerg Exp $ */
|
||||
/* $Id: arch.in,v 1.14 2013/09/16 22:12:57 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -38,9 +38,9 @@ LINE("arm", "ARM")
|
||||
LINE("arm26", "ARM26")
|
||||
LINE("arm32", "ARM32")
|
||||
LINE("armish", "ARMISH")
|
||||
LINE("armv7", "ARMv7")
|
||||
LINE("aviion", "AViiON")
|
||||
LINE("atari", "ATARI")
|
||||
LINE("beagle", "Beagle")
|
||||
LINE("bebox", "BeBox")
|
||||
LINE("cats", "cats")
|
||||
LINE("cesfic", "CESFIC")
|
||||
@ -81,6 +81,7 @@ LINE("netwinder", "NetWinder")
|
||||
LINE("news68k", "NeWS68k")
|
||||
LINE("newsmips", "NeWSMIPS")
|
||||
LINE("next68k", "NeXT68k")
|
||||
LINE("octeon", "OCTEON")
|
||||
LINE("ofppc", "OFPPC")
|
||||
LINE("palm", "Palm")
|
||||
LINE("pc532", "PC532")
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: chars.c,v 1.52 2011/11/08 00:15:23 kristaps Exp $ */
|
||||
/* $Id: chars.c,v 1.54 2013/06/20 22:39:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -37,7 +37,7 @@ struct ln {
|
||||
int unicode;
|
||||
};
|
||||
|
||||
#define LINES_MAX 328
|
||||
#define LINES_MAX 329
|
||||
|
||||
#define CHAR(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code) },
|
||||
@ -77,7 +77,7 @@ mchars_alloc(void)
|
||||
*/
|
||||
|
||||
tab = mandoc_malloc(sizeof(struct mchars));
|
||||
htab = mandoc_calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
|
||||
htab = mandoc_calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln *));
|
||||
|
||||
for (i = 0; i < LINES_MAX; i++) {
|
||||
hash = (int)lines[i].code[0] - PRINT_LO;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: chars.in,v 1.42 2011/10/02 10:02:26 kristaps Exp $ */
|
||||
/* $Id: chars.in,v 1.43 2013/06/20 22:39:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -42,6 +42,7 @@ CHAR("&", "", 0)
|
||||
CHAR("^", "", 0)
|
||||
CHAR("|", "", 0)
|
||||
CHAR("}", "", 0)
|
||||
CHAR("t", "", 0)
|
||||
|
||||
/* Accents. */
|
||||
CHAR("a\"", "\"", 779)
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define VERSION "1.12.3"
|
||||
#define HAVE_FGETLN
|
||||
#define HAVE_STRPTIME
|
||||
#define HAVE_GETSUBOPT
|
||||
@ -31,14 +32,16 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# define htobe32(x) OSSwapHostToBigInt32(x)
|
||||
# define betoh32(x) OSSwapBigToHostInt32(x)
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define betoh64(x) OSSwapBigToHostInt64(x)
|
||||
#elif defined(__linux__)
|
||||
# define betoh32(x) be32toh(x)
|
||||
# define betoh64(x) be64toh(x)
|
||||
#ifndef HAVE_BETOH64
|
||||
# if defined(__APPLE__)
|
||||
# define betoh64(x) OSSwapBigToHostInt64(x)
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# elif defined(__sun)
|
||||
# define betoh64(x) BE_64(x)
|
||||
# define htobe64(x) BE_64(x)
|
||||
# else
|
||||
# define betoh64(x) be64toh(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: eqn.7,v 1.28 2011/09/25 18:37:09 schwarze Exp $
|
||||
.\" $Id: eqn.7,v 1.29 2013/07/13 19:41:16 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: September 25 2011 $
|
||||
.Dd $Mdocdate: July 13 2013 $
|
||||
.Dt EQN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -276,5 +276,4 @@ was added in 2011.
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: html.c,v 1.150 2011/10/05 21:35:17 kristaps Exp $ */
|
||||
/* $Id: html.c,v 1.152 2013/08/08 20:07:47 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -235,6 +235,9 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
case (ESCAPE_FONTBOLD):
|
||||
font = HTMLFONT_BOLD;
|
||||
break;
|
||||
case (ESCAPE_FONTBI):
|
||||
font = HTMLFONT_BI;
|
||||
break;
|
||||
case (ESCAPE_FONT):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTROMAN):
|
||||
@ -253,17 +256,27 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
h->metal = h->metac;
|
||||
h->metac = font;
|
||||
|
||||
if (HTMLFONT_NONE != font)
|
||||
h->metaf = HTMLFONT_BOLD == font ?
|
||||
print_otag(h, TAG_B, 0, NULL) :
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
switch (font) {
|
||||
case (HTMLFONT_ITALIC):
|
||||
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
||||
break;
|
||||
case (HTMLFONT_BOLD):
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
break;
|
||||
case (HTMLFONT_BI):
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
html_strlen(const char *cp)
|
||||
{
|
||||
int ssz, sz;
|
||||
const char *seq, *p;
|
||||
size_t rsz;
|
||||
int skip, sz;
|
||||
|
||||
/*
|
||||
* Account for escaped sequences within string length
|
||||
@ -274,10 +287,21 @@ html_strlen(const char *cp)
|
||||
*/
|
||||
|
||||
sz = 0;
|
||||
while (NULL != (p = strchr(cp, '\\'))) {
|
||||
sz += (int)(p - cp);
|
||||
++cp;
|
||||
switch (mandoc_escape(&cp, &seq, &ssz)) {
|
||||
skip = 0;
|
||||
while (1) {
|
||||
rsz = strcspn(cp, "\\");
|
||||
if (rsz) {
|
||||
cp += rsz;
|
||||
if (skip) {
|
||||
skip = 0;
|
||||
rsz--;
|
||||
}
|
||||
sz += rsz;
|
||||
}
|
||||
if ('\0' == *cp)
|
||||
break;
|
||||
cp++;
|
||||
switch (mandoc_escape(&cp, NULL, NULL)) {
|
||||
case (ESCAPE_ERROR):
|
||||
return(sz);
|
||||
case (ESCAPE_UNICODE):
|
||||
@ -285,15 +309,19 @@ html_strlen(const char *cp)
|
||||
case (ESCAPE_NUMBERED):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_SPECIAL):
|
||||
sz++;
|
||||
if (skip)
|
||||
skip = 0;
|
||||
else
|
||||
sz++;
|
||||
break;
|
||||
case (ESCAPE_SKIPCHAR):
|
||||
skip = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(sz >= 0);
|
||||
return(sz + strlen(cp));
|
||||
return(sz);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -308,6 +336,12 @@ print_encode(struct html *h, const char *p, int norecurse)
|
||||
nospace = 0;
|
||||
|
||||
while ('\0' != *p) {
|
||||
if (HTML_SKIPCHAR & h->flags && '\\' != *p) {
|
||||
h->flags &= ~HTML_SKIPCHAR;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
sz = strcspn(p, rejs);
|
||||
|
||||
fwrite(p, 1, sz, stdout);
|
||||
@ -337,6 +371,33 @@ print_encode(struct html *h, const char *p, int norecurse)
|
||||
if (ESCAPE_ERROR == esc)
|
||||
break;
|
||||
|
||||
switch (esc) {
|
||||
case (ESCAPE_FONT):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTPREV):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTBOLD):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTITALIC):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTBI):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTROMAN):
|
||||
if (0 == norecurse)
|
||||
print_metaf(h, esc);
|
||||
continue;
|
||||
case (ESCAPE_SKIPCHAR):
|
||||
h->flags |= HTML_SKIPCHAR;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (h->flags & HTML_SKIPCHAR) {
|
||||
h->flags &= ~HTML_SKIPCHAR;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (esc) {
|
||||
case (ESCAPE_UNICODE):
|
||||
/* Skip passed "u" header. */
|
||||
@ -356,19 +417,6 @@ print_encode(struct html *h, const char *p, int norecurse)
|
||||
else if (-1 == c && 1 == len)
|
||||
putchar((int)*seq);
|
||||
break;
|
||||
case (ESCAPE_FONT):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTPREV):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTBOLD):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTITALIC):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTROMAN):
|
||||
if (norecurse)
|
||||
break;
|
||||
print_metaf(h, esc);
|
||||
break;
|
||||
case (ESCAPE_NOSPACE):
|
||||
if ('\0' == *p)
|
||||
nospace = 1;
|
||||
@ -511,10 +559,20 @@ print_text(struct html *h, const char *word)
|
||||
}
|
||||
|
||||
assert(NULL == h->metaf);
|
||||
if (HTMLFONT_NONE != h->metac)
|
||||
h->metaf = HTMLFONT_BOLD == h->metac ?
|
||||
print_otag(h, TAG_B, 0, NULL) :
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
switch (h->metac) {
|
||||
case (HTMLFONT_ITALIC):
|
||||
h->metaf = print_otag(h, TAG_I, 0, NULL);
|
||||
break;
|
||||
case (HTMLFONT_BOLD):
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
break;
|
||||
case (HTMLFONT_BI):
|
||||
h->metaf = print_otag(h, TAG_B, 0, NULL);
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
assert(word);
|
||||
if ( ! print_encode(h, word, 0)) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: html.h,v 1.47 2011/10/05 21:35:17 kristaps Exp $ */
|
||||
/* $Id: html.h,v 1.49 2013/08/08 20:07:47 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -75,6 +75,7 @@ enum htmlfont {
|
||||
HTMLFONT_NONE = 0,
|
||||
HTMLFONT_BOLD,
|
||||
HTMLFONT_ITALIC,
|
||||
HTMLFONT_BI,
|
||||
HTMLFONT_MAX
|
||||
};
|
||||
|
||||
@ -117,6 +118,7 @@ struct html {
|
||||
#define HTML_PREKEEP (1 << 3)
|
||||
#define HTML_NONOSPACE (1 << 4) /* never add spaces */
|
||||
#define HTML_LITERAL (1 << 5) /* literal (e.g., <PRE>) context */
|
||||
#define HTML_SKIPCHAR (1 << 6) /* skip the next character */
|
||||
struct tagq tags; /* stack of open tags */
|
||||
struct rofftbl tbl; /* current table */
|
||||
struct tag *tblt; /* current open table scope */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: lib.in,v 1.13 2012/01/28 23:46:28 joerg Exp $ */
|
||||
/* $Id: lib.in,v 1.17 2013/10/13 15:24:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -38,18 +38,24 @@ LINE("libcipher", "FreeSec Crypt Library (libcipher, \\-lcipher)")
|
||||
LINE("libcompat", "Compatibility Library (libcompat, \\-lcompat)")
|
||||
LINE("libcrypt", "Crypt Library (libcrypt, \\-lcrypt)")
|
||||
LINE("libcurses", "Curses Library (libcurses, \\-lcurses)")
|
||||
LINE("libdevattr", "Device attribute and event library (libdevattr, \\-ldevattr)")
|
||||
LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)")
|
||||
LINE("libdevstat", "Device Statistics Library (libdevstat, \\-ldevstat)")
|
||||
LINE("libdisk", "Interface to Slice and Partition Labels Library (libdisk, \\-ldisk)")
|
||||
LINE("libdm", "Device Mapper Library (libdm, \\-ldm)")
|
||||
LINE("libdwarf", "DWARF Access Library (libdwarf, \\-ldwarf)")
|
||||
LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)")
|
||||
LINE("libefi", "EFI Runtime Services Library (libefi, \\-lefi)")
|
||||
LINE("libelf", "ELF Access Library (libelf, \\-lelf)")
|
||||
LINE("libevent", "Event Notification Library (libevent, \\-levent)")
|
||||
LINE("libfetch", "File Transfer Library for URLs (libfetch, \\-lfetch)")
|
||||
LINE("libexecinfo", "Backtrace Information Library (libexecinfo, \\-lexecinfo)")
|
||||
LINE("libfetch", "File Transfer Library (libfetch, \\-lfetch)")
|
||||
LINE("libfsid", "Filesystem Identification Library (libfsid, \\-lfsid)")
|
||||
LINE("libftpio", "FTP Connection Management Library (libftpio, \\-lftpio)")
|
||||
LINE("libform", "Curses Form Library (libform, \\-lform)")
|
||||
LINE("libgeom", "Userland API Library for kernel GEOM subsystem (libgeom, \\-lgeom)")
|
||||
LINE("libgeom", "Userland API Library for Kernel GEOM subsystem (libgeom, \\-lgeom)")
|
||||
LINE("libgpib", "General-Purpose Instrument Bus (GPIB) library (libgpib, \\-lgpib)")
|
||||
LINE("libhammer", "HAMMER Filesystem Userland Library (libhammer, \\-lhammer)")
|
||||
LINE("libi386", "i386 Architecture Library (libi386, \\-li386)")
|
||||
LINE("libintl", "Internationalized Message Handling Library (libintl, \\-lintl)")
|
||||
LINE("libipsec", "IPsec Policy Control Library (libipsec, \\-lipsec)")
|
||||
@ -57,24 +63,31 @@ LINE("libipx", "IPX Address Conversion Support Library (libipx, \\-lipx)")
|
||||
LINE("libiscsi", "iSCSI protocol library (libiscsi, \\-liscsi)")
|
||||
LINE("libisns", "Internet Storage Name Service Library (libisns, \\-lisns)")
|
||||
LINE("libjail", "Jail Library (libjail, \\-ljail)")
|
||||
LINE("libkiconv", "Kernel side iconv library (libkiconv, \\-lkiconv)")
|
||||
LINE("libkcore", "Kernel Memory Core Access Library (libkcore, \\-lkcore)")
|
||||
LINE("libkiconv", "Kernel-side iconv Library (libkiconv, \\-lkiconv)")
|
||||
LINE("libkse", "N:M Threading Library (libkse, \\-lkse)")
|
||||
LINE("libkvm", "Kernel Data Access Library (libkvm, \\-lkvm)")
|
||||
LINE("libm", "Math Library (libm, \\-lm)")
|
||||
LINE("libm68k", "m68k Architecture Library (libm68k, \\-lm68k)")
|
||||
LINE("libmagic", "Magic Number Recognition Library (libmagic, \\-lmagic)")
|
||||
LINE("libmandoc", "Mandoc Macro Compiler Library (libmandoc, \\-lmandoc)")
|
||||
LINE("libmd", "Message Digest (MD4, MD5, etc.) Support Library (libmd, \\-lmd)")
|
||||
LINE("libmemstat", "Kernel Memory Allocator Statistics Library (libmemstat, \\-lmemstat)")
|
||||
LINE("libmenu", "Curses Menu Library (libmenu, \\-lmenu)")
|
||||
LINE("libmj", "Minimalist JSON library (libmj, \\-lmj)")
|
||||
LINE("libnetgraph", "Netgraph User Library (libnetgraph, \\-lnetgraph)")
|
||||
LINE("libnetpgp", "Netpgp signing, verification, encryption and decryption (libnetpgp, \\-lnetpgp)")
|
||||
LINE("libnetpgp", "Netpgp Signing, Verification, Encryption and Decryption (libnetpgp, \\-lnetpgp)")
|
||||
LINE("libnetpgpverify", "Netpgp Verification (libnetpgpverify, \\-lnetpgpverify)")
|
||||
LINE("libnpf", "NPF Packet Filter Library (libnpf, \\-lnpf)")
|
||||
LINE("libnv", "Name/value pairs library (libnv, \\-lnv)")
|
||||
LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
|
||||
LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
|
||||
LINE("libpcap", "Packet Capture Library (libpcap, \\-lpcap)")
|
||||
LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)")
|
||||
LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)")
|
||||
LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)")
|
||||
LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)")
|
||||
LINE("libposix1e", "POSIX.1e Security API Library (libposix1e, \\-lposix1e)")
|
||||
LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)")
|
||||
LINE("libproc", "Processor Monitoring and Analysis Library (libproc, \\-lproc)")
|
||||
LINE("libprocstat", "Process and Files Information Retrieval (libprocstat, \\-lprocstat)")
|
||||
@ -82,6 +95,7 @@ LINE("libprop", "Property Container Object Library (libprop, \\-lprop)")
|
||||
LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
|
||||
LINE("libpuffs", "puffs Convenience Library (libpuffs, \\-lpuffs)")
|
||||
LINE("libquota", "Disk Quota Access and Control Library (libquota, \\-lquota)")
|
||||
LINE("libradius", "RADIUS Client Library (libradius, \\-lradius)")
|
||||
LINE("librefuse", "File System in Userspace Convenience Library (librefuse, \\-lrefuse)")
|
||||
LINE("libresolv", "DNS Resolver Library (libresolv, \\-lresolv)")
|
||||
LINE("librpcsec_gss", "RPC GSS-API Authentication Library (librpcsec_gss, \\-lrpcsec_gss)")
|
||||
@ -94,6 +108,8 @@ LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-l
|
||||
LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)")
|
||||
LINE("libstdthreads", "C11 Threads Library (libstdthreads, \\-lstdthreads)")
|
||||
LINE("libSystem", "System Library (libSystem, \\-lSystem)")
|
||||
LINE("libtacplus", "TACACS+ Client Library (libtacplus, \\-ltacplus)")
|
||||
LINE("libtcplay", "TrueCrypt-compatible API library (libtcplay, \\-ltcplay)")
|
||||
LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)")
|
||||
LINE("libterminfo", "Terminal Information Library (libterminfo, \\-lterminfo)")
|
||||
LINE("libthr", "1:1 Threading Library (libthr, \\-lthr)")
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: libman.h,v 1.55 2011/11/07 01:24:40 schwarze Exp $ */
|
||||
/* $Id: libman.h,v 1.56 2012/11/17 00:26:33 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -39,7 +39,7 @@ struct man {
|
||||
struct roff *roff;
|
||||
};
|
||||
|
||||
#define MACRO_PROT_ARGS struct man *m, \
|
||||
#define MACRO_PROT_ARGS struct man *man, \
|
||||
enum mant tok, \
|
||||
int line, \
|
||||
int ppos, \
|
||||
@ -61,10 +61,10 @@ extern const struct man_macro *const man_macros;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define man_pmsg(m, l, p, t) \
|
||||
mandoc_msg((t), (m)->parse, (l), (p), NULL)
|
||||
#define man_nmsg(m, n, t) \
|
||||
mandoc_msg((t), (m)->parse, (n)->line, (n)->pos, NULL)
|
||||
#define man_pmsg(man, l, p, t) \
|
||||
mandoc_msg((t), (man)->parse, (l), (p), NULL)
|
||||
#define man_nmsg(man, n, t) \
|
||||
mandoc_msg((t), (man)->parse, (n)->line, (n)->pos, NULL)
|
||||
int man_word_alloc(struct man *, int, int, const char *);
|
||||
int man_block_alloc(struct man *, int, int, enum mant);
|
||||
int man_head_alloc(struct man *, int, int, enum mant);
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: libmandoc.h,v 1.29 2011/12/02 01:37:14 schwarze Exp $ */
|
||||
/* $Id: libmandoc.h,v 1.35 2013/12/15 21:23:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -29,11 +30,6 @@ enum rofferr {
|
||||
ROFF_ERR /* badness: puke and stop */
|
||||
};
|
||||
|
||||
enum regs {
|
||||
REG_nS = 0, /* nS register */
|
||||
REG__MAX
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct roff;
|
||||
@ -47,12 +43,11 @@ void mandoc_vmsg(enum mandocerr, struct mparse *,
|
||||
char *mandoc_getarg(struct mparse *, char **, int, int *);
|
||||
char *mandoc_normdate(struct mparse *, char *, int, int);
|
||||
int mandoc_eos(const char *, size_t, int);
|
||||
int mandoc_getcontrol(const char *, int *);
|
||||
int mandoc_strntoi(const char *, size_t, int);
|
||||
const char *mandoc_a2msec(const char*);
|
||||
|
||||
void mdoc_free(struct mdoc *);
|
||||
struct mdoc *mdoc_alloc(struct roff *, struct mparse *);
|
||||
struct mdoc *mdoc_alloc(struct roff *, struct mparse *, char *);
|
||||
void mdoc_reset(struct mdoc *);
|
||||
int mdoc_parseln(struct mdoc *, int, char *, int);
|
||||
int mdoc_endparse(struct mdoc *);
|
||||
@ -68,15 +63,16 @@ int man_addspan(struct man *, const struct tbl_span *);
|
||||
int man_addeqn(struct man *, const struct eqn *);
|
||||
|
||||
void roff_free(struct roff *);
|
||||
struct roff *roff_alloc(struct mparse *);
|
||||
struct roff *roff_alloc(enum mparset, struct mparse *);
|
||||
void roff_reset(struct roff *);
|
||||
enum rofferr roff_parseln(struct roff *, int,
|
||||
char **, size_t *, int, int *);
|
||||
void roff_endparse(struct roff *);
|
||||
int roff_regisset(const struct roff *, enum regs);
|
||||
unsigned int roff_regget(const struct roff *, enum regs);
|
||||
void roff_regunset(struct roff *, enum regs);
|
||||
void roff_setreg(struct roff *, const char *, int, char sign);
|
||||
int roff_getreg(const struct roff *, const char *);
|
||||
char *roff_strdup(const struct roff *, const char *);
|
||||
int roff_getcontrol(const struct roff *,
|
||||
const char *, int *);
|
||||
#if 0
|
||||
char roff_eqndelim(const struct roff *);
|
||||
void roff_openeqn(struct roff *, const char *,
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: libmdoc.h,v 1.78 2011/12/02 01:37:14 schwarze Exp $ */
|
||||
/* $Id: libmdoc.h,v 1.82 2013/10/21 23:47:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -24,6 +25,7 @@ enum mdoc_next {
|
||||
|
||||
struct mdoc {
|
||||
struct mparse *parse; /* parse pointer */
|
||||
char *defos; /* default argument for .Os */
|
||||
int flags; /* parse flags */
|
||||
#define MDOC_HALT (1 << 0) /* error in parse: halt */
|
||||
#define MDOC_LITERAL (1 << 1) /* in a literal scope */
|
||||
@ -33,6 +35,8 @@ struct mdoc {
|
||||
#define MDOC_PPHRASE (1 << 5) /* within a partial phrase */
|
||||
#define MDOC_FREECOL (1 << 6) /* `It' invocation should close */
|
||||
#define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting */
|
||||
#define MDOC_KEEP (1 << 8) /* in a word keep */
|
||||
#define MDOC_SMOFF (1 << 9) /* spacing is off */
|
||||
enum mdoc_next next; /* where to put the next node */
|
||||
struct mdoc_node *last; /* the last node parsed */
|
||||
struct mdoc_node *first; /* the first node parsed */
|
||||
@ -42,7 +46,7 @@ struct mdoc {
|
||||
struct roff *roff;
|
||||
};
|
||||
|
||||
#define MACRO_PROT_ARGS struct mdoc *m, \
|
||||
#define MACRO_PROT_ARGS struct mdoc *mdoc, \
|
||||
enum mdoct tok, \
|
||||
int line, \
|
||||
int ppos, \
|
||||
@ -56,8 +60,8 @@ struct mdoc_macro {
|
||||
#define MDOC_PARSED (1 << 1)
|
||||
#define MDOC_EXPLICIT (1 << 2)
|
||||
#define MDOC_PROLOGUE (1 << 3)
|
||||
#define MDOC_IGNDELIM (1 << 4)
|
||||
/* Reserved words in arguments treated as text. */
|
||||
#define MDOC_IGNDELIM (1 << 4)
|
||||
#define MDOC_JOIN (1 << 5)
|
||||
};
|
||||
|
||||
enum margserr {
|
||||
@ -99,13 +103,14 @@ extern const struct mdoc_macro *const mdoc_macros;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define mdoc_pmsg(m, l, p, t) \
|
||||
mandoc_msg((t), (m)->parse, (l), (p), NULL)
|
||||
#define mdoc_nmsg(m, n, t) \
|
||||
mandoc_msg((t), (m)->parse, (n)->line, (n)->pos, NULL)
|
||||
#define mdoc_pmsg(mdoc, l, p, t) \
|
||||
mandoc_msg((t), (mdoc)->parse, (l), (p), NULL)
|
||||
#define mdoc_nmsg(mdoc, n, t) \
|
||||
mandoc_msg((t), (mdoc)->parse, (n)->line, (n)->pos, NULL)
|
||||
int mdoc_macro(MACRO_PROT_ARGS);
|
||||
int mdoc_word_alloc(struct mdoc *,
|
||||
int, int, const char *);
|
||||
void mdoc_word_append(struct mdoc *, const char *);
|
||||
int mdoc_elem_alloc(struct mdoc *, int, int,
|
||||
enum mdoct, struct mdoc_arg *);
|
||||
int mdoc_block_alloc(struct mdoc *, int, int,
|
||||
@ -113,10 +118,10 @@ int mdoc_block_alloc(struct mdoc *, int, int,
|
||||
int mdoc_head_alloc(struct mdoc *, int, int, enum mdoct);
|
||||
int mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct);
|
||||
int mdoc_body_alloc(struct mdoc *, int, int, enum mdoct);
|
||||
int mdoc_endbody_alloc(struct mdoc *m, int line, int pos,
|
||||
enum mdoct tok, struct mdoc_node *body,
|
||||
enum mdoc_endbody end);
|
||||
int mdoc_endbody_alloc(struct mdoc *, int, int, enum mdoct,
|
||||
struct mdoc_node *, enum mdoc_endbody);
|
||||
void mdoc_node_delete(struct mdoc *, struct mdoc_node *);
|
||||
int mdoc_node_relink(struct mdoc *, struct mdoc_node *);
|
||||
void mdoc_hash_init(void);
|
||||
enum mdoct mdoc_hash_find(const char *);
|
||||
const char *mdoc_a2att(const char *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: libroff.h,v 1.27 2011/07/25 15:37:00 kristaps Exp $ */
|
||||
/* $Id: libroff.h,v 1.28 2013/05/31 21:37:17 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -31,7 +31,7 @@ struct tbl_node {
|
||||
int pos; /* invocation column */
|
||||
int line; /* invocation line */
|
||||
enum tbl_part part;
|
||||
struct tbl opts;
|
||||
struct tbl_opts opts;
|
||||
struct tbl_row *first_row;
|
||||
struct tbl_row *last_row;
|
||||
struct tbl_span *first_span;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: main.c,v 1.165 2011/10/06 22:29:12 kristaps Exp $ */
|
||||
/* $Id: main.c,v 1.167 2012/11/19 17:22:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -85,6 +85,7 @@ main(int argc, char *argv[])
|
||||
struct curparse curp;
|
||||
enum mparset type;
|
||||
enum mandoclevel rc;
|
||||
char *defos;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == NULL)
|
||||
@ -97,10 +98,24 @@ main(int argc, char *argv[])
|
||||
type = MPARSE_AUTO;
|
||||
curp.outtype = OUTT_ASCII;
|
||||
curp.wlevel = MANDOCLEVEL_FATAL;
|
||||
defos = NULL;
|
||||
|
||||
/* LINTED */
|
||||
while (-1 != (c = getopt(argc, argv, "m:O:T:VW:")))
|
||||
while (-1 != (c = getopt(argc, argv, "I:m:O:T:VW:")))
|
||||
switch (c) {
|
||||
case ('I'):
|
||||
if (strncmp(optarg, "os=", 3)) {
|
||||
fprintf(stderr, "-I%s: Bad argument\n",
|
||||
optarg);
|
||||
return((int)MANDOCLEVEL_BADARG);
|
||||
}
|
||||
if (defos) {
|
||||
fprintf(stderr, "-I%s: Duplicate argument\n",
|
||||
optarg);
|
||||
return((int)MANDOCLEVEL_BADARG);
|
||||
}
|
||||
defos = mandoc_strdup(optarg + 3);
|
||||
break;
|
||||
case ('m'):
|
||||
if ( ! moptions(&type, optarg))
|
||||
return((int)MANDOCLEVEL_BADARG);
|
||||
@ -125,7 +140,7 @@ main(int argc, char *argv[])
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp);
|
||||
curp.mp = mparse_alloc(type, curp.wlevel, mmsg, &curp, defos);
|
||||
|
||||
/*
|
||||
* Conditionally start up the lookaside buffer before parsing.
|
||||
@ -152,6 +167,7 @@ main(int argc, char *argv[])
|
||||
(*curp.outfree)(curp.outdata);
|
||||
if (curp.mp)
|
||||
mparse_free(curp.mp);
|
||||
free(defos);
|
||||
|
||||
return((int)rc);
|
||||
}
|
||||
@ -170,12 +186,12 @@ usage(void)
|
||||
|
||||
fprintf(stderr, "usage: %s "
|
||||
"[-V] "
|
||||
"[-foption] "
|
||||
"[-Ios=name] "
|
||||
"[-mformat] "
|
||||
"[-Ooption] "
|
||||
"[-Toutput] "
|
||||
"[-Wlevel] "
|
||||
"[file...]\n",
|
||||
"[-Wlevel]\n"
|
||||
"\t [file ...]\n",
|
||||
progname);
|
||||
|
||||
exit((int)MANDOCLEVEL_BADARG);
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: man.7,v 1.113 2012/01/03 15:16:24 kristaps Exp $
|
||||
.\" $Id: man.7,v 1.120 2013/09/16 22:58:57 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 3 2012 $
|
||||
.Dd $Mdocdate: September 16 2013 $
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -253,6 +253,7 @@ in the alphabetical reference below.
|
||||
.It Sx IP Ta indented paragraph: Op Ar head Op Ar width
|
||||
.It Sx TP Ta tagged paragraph: Op Ar width
|
||||
.It Sx HP Ta hanged paragraph: Op Ar width
|
||||
.It Sx PD Ta set vertical paragraph distance: Op Ar height
|
||||
.It Sx \&br Ta force output line break in text mode (no arguments)
|
||||
.It Sx \&sp Ta force vertical space: Op Ar height
|
||||
.It Sx fi , nf Ta fill mode and no-fill mode (no arguments)
|
||||
@ -272,10 +273,6 @@ in the alphabetical reference below.
|
||||
.It Sx RB Ta alternate between roman and boldface fonts
|
||||
.It Sx RI Ta alternate between roman and italic fonts
|
||||
.El
|
||||
.Ss Semantic markup
|
||||
.Bl -column "PP, LP, P" description
|
||||
.It Sx OP Ta optional arguments
|
||||
.El
|
||||
.Sh MACRO REFERENCE
|
||||
This section is a canonical reference to all macros, arranged
|
||||
alphabetically.
|
||||
@ -343,6 +340,18 @@ and
|
||||
.Ss \&DT
|
||||
Has no effect.
|
||||
Included for compatibility.
|
||||
.Ss \&EE
|
||||
This is a non-standard GNU extension, included only for compatibility.
|
||||
In
|
||||
.Xr mandoc 1 ,
|
||||
it does the same as
|
||||
.Sx \&fi .
|
||||
.Ss \&EX
|
||||
This is a non-standard GNU extension, included only for compatibility.
|
||||
In
|
||||
.Xr mandoc 1 ,
|
||||
it does the same as
|
||||
.Sx \&nf .
|
||||
.Ss \&HP
|
||||
Begin a paragraph whose initial output line is left-justified, but
|
||||
subsequent output lines are indented, with the following syntax:
|
||||
@ -353,8 +362,9 @@ subsequent output lines are indented, with the following syntax:
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument must conform to
|
||||
.Sx Scaling Widths .
|
||||
argument is a
|
||||
.Xr roff 7
|
||||
scaling width.
|
||||
If specified, it's saved for later paragraph left-margins; if unspecified, the
|
||||
saved or default width is used.
|
||||
.Pp
|
||||
@ -396,8 +406,9 @@ Begin an indented paragraph with the following syntax:
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument defines the width of the left margin and is defined by
|
||||
.Sx Scaling Widths .
|
||||
argument is a
|
||||
.Xr roff 7
|
||||
scaling width defining the left margin.
|
||||
It's saved for later paragraph left-margins; if unspecified, the saved or
|
||||
default width is used.
|
||||
.Pp
|
||||
@ -443,7 +454,8 @@ and
|
||||
.Sx \&TP .
|
||||
.Ss \&OP
|
||||
Optional command-line argument.
|
||||
This has the following syntax:
|
||||
This is a non-standard GNU extension, included only for compatibility.
|
||||
It has the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&OP
|
||||
.Cm key Op Cm value
|
||||
@ -465,6 +477,36 @@ See also
|
||||
.Sx \&PP ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&PD
|
||||
Specify the vertical space to be inserted before each new paragraph.
|
||||
.br
|
||||
The syntax is as follows:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&PD
|
||||
.Op Cm height
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Cm height
|
||||
argument is a
|
||||
.Xr roff 7
|
||||
scaling width.
|
||||
It defaults to
|
||||
.Cm 1v .
|
||||
If the unit is omitted,
|
||||
.Cm v
|
||||
is assumed.
|
||||
.Pp
|
||||
This macro affects the spacing before any subsequent instances of
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
.Sx \&PP ,
|
||||
.Sx \&SH ,
|
||||
.Sx \&SS ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&PP
|
||||
Synonym for
|
||||
.Sx \&LP .
|
||||
@ -529,8 +571,9 @@ This has the following syntax:
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument must conform to
|
||||
.Sx Scaling Widths .
|
||||
argument is a
|
||||
.Xr roff 7
|
||||
scaling width.
|
||||
If not specified, the saved or default width is used.
|
||||
.Pp
|
||||
See also
|
||||
@ -595,8 +638,9 @@ The syntax is as follows:
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument must conform to
|
||||
.Sx Scaling Widths .
|
||||
argument is a
|
||||
.Xr roff 7
|
||||
scaling width.
|
||||
If specified, it's saved for later paragraph left-margins; if
|
||||
unspecified, the saved or default width is used.
|
||||
.Pp
|
||||
@ -609,7 +653,8 @@ and
|
||||
.Sx \&PP .
|
||||
.Ss \&UC
|
||||
Sets the volume for the footer for compatibility with man pages from
|
||||
BSD releases.
|
||||
.Bx
|
||||
releases.
|
||||
The optional first argument specifies which release it is from.
|
||||
.Ss \&br
|
||||
Breaks the current line.
|
||||
@ -653,10 +698,10 @@ Insert vertical spaces into output with the following syntax:
|
||||
.Op Cm height
|
||||
.Ed
|
||||
.Pp
|
||||
Insert
|
||||
The
|
||||
.Cm height
|
||||
spaces, which must conform to
|
||||
.Sx Scaling Widths .
|
||||
argument is a scaling width as described in
|
||||
.Xr roff 7 .
|
||||
If 0, this is equivalent to the
|
||||
.Sx \&br
|
||||
macro.
|
||||
@ -904,8 +949,7 @@ utility written by Kristaps Dzonsons appeared in
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
Do not use this language.
|
||||
Use
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man.c,v 1.115 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/* $Id: man.c,v 1.121 2013/11/10 22:54:40 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -40,7 +40,8 @@ const char *const __man_macronames[MAN_MAX] = {
|
||||
"RI", "na", "sp", "nf",
|
||||
"fi", "RE", "RS", "DT",
|
||||
"UC", "PD", "AT", "in",
|
||||
"ft", "OP"
|
||||
"ft", "OP", "EX", "EE",
|
||||
"UR", "UE"
|
||||
};
|
||||
|
||||
const char * const *man_macronames = __man_macronames;
|
||||
@ -60,20 +61,20 @@ static int man_descope(struct man *, int, int);
|
||||
|
||||
|
||||
const struct man_node *
|
||||
man_node(const struct man *m)
|
||||
man_node(const struct man *man)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
return(m->first);
|
||||
assert( ! (MAN_HALT & man->flags));
|
||||
return(man->first);
|
||||
}
|
||||
|
||||
|
||||
const struct man_meta *
|
||||
man_meta(const struct man *m)
|
||||
man_meta(const struct man *man)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
return(&m->meta);
|
||||
assert( ! (MAN_HALT & man->flags));
|
||||
return(&man->meta);
|
||||
}
|
||||
|
||||
|
||||
@ -112,28 +113,28 @@ man_alloc(struct roff *roff, struct mparse *parse)
|
||||
|
||||
|
||||
int
|
||||
man_endparse(struct man *m)
|
||||
man_endparse(struct man *man)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
if (man_macroend(m))
|
||||
assert( ! (MAN_HALT & man->flags));
|
||||
if (man_macroend(man))
|
||||
return(1);
|
||||
m->flags |= MAN_HALT;
|
||||
man->flags |= MAN_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_parseln(struct man *m, int ln, char *buf, int offs)
|
||||
man_parseln(struct man *man, int ln, char *buf, int offs)
|
||||
{
|
||||
|
||||
m->flags |= MAN_NEWLINE;
|
||||
man->flags |= MAN_NEWLINE;
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
assert( ! (MAN_HALT & man->flags));
|
||||
|
||||
return (mandoc_getcontrol(buf, &offs) ?
|
||||
man_pmacro(m, ln, buf, offs) :
|
||||
man_ptext(m, ln, buf, offs));
|
||||
return (roff_getcontrol(man->roff, buf, &offs) ?
|
||||
man_pmacro(man, ln, buf, offs) :
|
||||
man_ptext(man, ln, buf, offs));
|
||||
}
|
||||
|
||||
|
||||
@ -157,16 +158,16 @@ man_free1(struct man *man)
|
||||
|
||||
|
||||
static void
|
||||
man_alloc1(struct man *m)
|
||||
man_alloc1(struct man *man)
|
||||
{
|
||||
|
||||
memset(&m->meta, 0, sizeof(struct man_meta));
|
||||
m->flags = 0;
|
||||
m->last = mandoc_calloc(1, sizeof(struct man_node));
|
||||
m->first = m->last;
|
||||
m->last->type = MAN_ROOT;
|
||||
m->last->tok = MAN_MAX;
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
memset(&man->meta, 0, sizeof(struct man_meta));
|
||||
man->flags = 0;
|
||||
man->last = mandoc_calloc(1, sizeof(struct man_node));
|
||||
man->first = man->last;
|
||||
man->last->type = MAN_ROOT;
|
||||
man->last->tok = MAN_MAX;
|
||||
man->next = MAN_NEXT_CHILD;
|
||||
}
|
||||
|
||||
|
||||
@ -234,7 +235,7 @@ man_node_append(struct man *man, struct man_node *p)
|
||||
|
||||
|
||||
static struct man_node *
|
||||
man_node_alloc(struct man *m, int line, int pos,
|
||||
man_node_alloc(struct man *man, int line, int pos,
|
||||
enum man_type type, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
@ -245,89 +246,89 @@ man_node_alloc(struct man *m, int line, int pos,
|
||||
p->type = type;
|
||||
p->tok = tok;
|
||||
|
||||
if (MAN_NEWLINE & m->flags)
|
||||
if (MAN_NEWLINE & man->flags)
|
||||
p->flags |= MAN_LINE;
|
||||
m->flags &= ~MAN_NEWLINE;
|
||||
man->flags &= ~MAN_NEWLINE;
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_elem_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
man_elem_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(m, line, pos, MAN_ELEM, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
p = man_node_alloc(man, line, pos, MAN_ELEM, tok);
|
||||
if ( ! man_node_append(man, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
man->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_tail_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
man_tail_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(m, line, pos, MAN_TAIL, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
p = man_node_alloc(man, line, pos, MAN_TAIL, tok);
|
||||
if ( ! man_node_append(man, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
man->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_head_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
man_head_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(m, line, pos, MAN_HEAD, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
p = man_node_alloc(man, line, pos, MAN_HEAD, tok);
|
||||
if ( ! man_node_append(man, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
man->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_body_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
man_body_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(m, line, pos, MAN_BODY, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
p = man_node_alloc(man, line, pos, MAN_BODY, tok);
|
||||
if ( ! man_node_append(man, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
man->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_block_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
man_block_alloc(struct man *man, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(m, line, pos, MAN_BLOCK, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
p = man_node_alloc(man, line, pos, MAN_BLOCK, tok);
|
||||
if ( ! man_node_append(man, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
man->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
man_word_alloc(struct man *m, int line, int pos, const char *word)
|
||||
man_word_alloc(struct man *man, int line, int pos, const char *word)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
n = man_node_alloc(m, line, pos, MAN_TEXT, MAN_MAX);
|
||||
n->string = roff_strdup(m->roff, word);
|
||||
n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX);
|
||||
n->string = roff_strdup(man->roff, word);
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
if ( ! man_node_append(man, n))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
man->next = MAN_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -347,52 +348,52 @@ man_node_free(struct man_node *p)
|
||||
|
||||
|
||||
void
|
||||
man_node_delete(struct man *m, struct man_node *p)
|
||||
man_node_delete(struct man *man, struct man_node *p)
|
||||
{
|
||||
|
||||
while (p->child)
|
||||
man_node_delete(m, p->child);
|
||||
man_node_delete(man, p->child);
|
||||
|
||||
man_node_unlink(m, p);
|
||||
man_node_unlink(man, p);
|
||||
man_node_free(p);
|
||||
}
|
||||
|
||||
int
|
||||
man_addeqn(struct man *m, const struct eqn *ep)
|
||||
man_addeqn(struct man *man, const struct eqn *ep)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
assert( ! (MAN_HALT & man->flags));
|
||||
|
||||
n = man_node_alloc(m, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
|
||||
n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
|
||||
n->eqn = ep;
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
if ( ! man_node_append(man, n))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
return(man_descope(m, ep->ln, ep->pos));
|
||||
man->next = MAN_NEXT_SIBLING;
|
||||
return(man_descope(man, ep->ln, ep->pos));
|
||||
}
|
||||
|
||||
int
|
||||
man_addspan(struct man *m, const struct tbl_span *sp)
|
||||
man_addspan(struct man *man, const struct tbl_span *sp)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
assert( ! (MAN_HALT & man->flags));
|
||||
|
||||
n = man_node_alloc(m, sp->line, 0, MAN_TBL, MAN_MAX);
|
||||
n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX);
|
||||
n->span = sp;
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
if ( ! man_node_append(man, n))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
return(man_descope(m, sp->line, 0));
|
||||
man->next = MAN_NEXT_SIBLING;
|
||||
return(man_descope(man, sp->line, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
man_descope(struct man *m, int line, int offs)
|
||||
man_descope(struct man *man, int line, int offs)
|
||||
{
|
||||
/*
|
||||
* Co-ordinate what happens with having a next-line scope open:
|
||||
@ -400,44 +401,51 @@ man_descope(struct man *m, int line, int offs)
|
||||
* out the block scope (also if applicable).
|
||||
*/
|
||||
|
||||
if (MAN_ELINE & m->flags) {
|
||||
m->flags &= ~MAN_ELINE;
|
||||
if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
|
||||
if (MAN_ELINE & man->flags) {
|
||||
man->flags &= ~MAN_ELINE;
|
||||
if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ( ! (MAN_BLINE & m->flags))
|
||||
if ( ! (MAN_BLINE & man->flags))
|
||||
return(1);
|
||||
m->flags &= ~MAN_BLINE;
|
||||
man->flags &= ~MAN_BLINE;
|
||||
|
||||
if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
|
||||
if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
|
||||
return(0);
|
||||
return(man_body_alloc(m, line, offs, m->last->tok));
|
||||
return(man_body_alloc(man, line, offs, man->last->tok));
|
||||
}
|
||||
|
||||
static int
|
||||
man_ptext(struct man *m, int line, char *buf, int offs)
|
||||
man_ptext(struct man *man, int line, char *buf, int offs)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Literal free-form text whitespace is preserved. */
|
||||
|
||||
if (MAN_LITERAL & m->flags) {
|
||||
if ( ! man_word_alloc(m, line, offs, buf + offs))
|
||||
if (MAN_LITERAL & man->flags) {
|
||||
if ( ! man_word_alloc(man, line, offs, buf + offs))
|
||||
return(0);
|
||||
return(man_descope(m, line, offs));
|
||||
return(man_descope(man, line, offs));
|
||||
}
|
||||
|
||||
/* Pump blank lines directly into the backend. */
|
||||
|
||||
for (i = offs; ' ' == buf[i]; i++)
|
||||
/* Skip leading whitespace. */ ;
|
||||
|
||||
/*
|
||||
* Blank lines are ignored right after headings
|
||||
* but add a single vertical space elsewhere.
|
||||
*/
|
||||
|
||||
if ('\0' == buf[i]) {
|
||||
/* Allocate a blank entry. */
|
||||
if ( ! man_word_alloc(m, line, offs, ""))
|
||||
return(0);
|
||||
return(man_descope(m, line, offs));
|
||||
if (MAN_SH != man->last->tok &&
|
||||
MAN_SS != man->last->tok) {
|
||||
if ( ! man_elem_alloc(man, line, offs, MAN_sp))
|
||||
return(0);
|
||||
man->next = MAN_NEXT_SIBLING;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -450,7 +458,7 @@ man_ptext(struct man *m, int line, char *buf, int offs)
|
||||
|
||||
if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
|
||||
if (i > 1 && '\\' != buf[i - 2])
|
||||
man_pmsg(m, line, i - 1, MANDOCERR_EOLNSPACE);
|
||||
man_pmsg(man, line, i - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
for (--i; i && ' ' == buf[i]; i--)
|
||||
/* Spin back to non-space. */ ;
|
||||
@ -461,7 +469,7 @@ man_ptext(struct man *m, int line, char *buf, int offs)
|
||||
buf[i] = '\0';
|
||||
}
|
||||
|
||||
if ( ! man_word_alloc(m, line, offs, buf + offs))
|
||||
if ( ! man_word_alloc(man, line, offs, buf + offs))
|
||||
return(0);
|
||||
|
||||
/*
|
||||
@ -472,13 +480,13 @@ man_ptext(struct man *m, int line, char *buf, int offs)
|
||||
|
||||
assert(i);
|
||||
if (mandoc_eos(buf, (size_t)i, 0))
|
||||
m->last->flags |= MAN_EOS;
|
||||
man->last->flags |= MAN_EOS;
|
||||
|
||||
return(man_descope(m, line, offs));
|
||||
return(man_descope(man, line, offs));
|
||||
}
|
||||
|
||||
static int
|
||||
man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
man_pmacro(struct man *man, int ln, char *buf, int offs)
|
||||
{
|
||||
int i, ppos;
|
||||
enum mant tok;
|
||||
@ -486,7 +494,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
struct man_node *n;
|
||||
|
||||
if ('"' == buf[offs]) {
|
||||
man_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT);
|
||||
man_pmsg(man, ln, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
} else if ('\0' == buf[offs])
|
||||
return(1);
|
||||
@ -508,7 +516,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX;
|
||||
|
||||
if (MAN_MAX == tok) {
|
||||
mandoc_vmsg(MANDOCERR_MACRO, m->parse, ln,
|
||||
mandoc_vmsg(MANDOCERR_MACRO, man->parse, ln,
|
||||
ppos, "%s", buf + ppos - 1);
|
||||
return(1);
|
||||
}
|
||||
@ -524,7 +532,7 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
*/
|
||||
|
||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
||||
man_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
||||
man_pmsg(man, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
/*
|
||||
* Remove prior ELINE macro, as it's being clobbered by a new
|
||||
@ -533,8 +541,8 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
*/
|
||||
|
||||
if ( ! (MAN_NSCOPED & man_macros[tok].flags) &&
|
||||
m->flags & MAN_ELINE) {
|
||||
n = m->last;
|
||||
man->flags & MAN_ELINE) {
|
||||
n = man->last;
|
||||
assert(MAN_TEXT != n->type);
|
||||
|
||||
/* Remove repeated NSCOPED macros causing ELINE. */
|
||||
@ -542,20 +550,20 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
if (MAN_NSCOPED & man_macros[n->tok].flags)
|
||||
n = n->parent;
|
||||
|
||||
mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line,
|
||||
mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line,
|
||||
n->pos, "%s breaks %s", man_macronames[tok],
|
||||
man_macronames[n->tok]);
|
||||
|
||||
man_node_delete(m, n);
|
||||
m->flags &= ~MAN_ELINE;
|
||||
man_node_delete(man, n);
|
||||
man->flags &= ~MAN_ELINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove prior BLINE macro that is being clobbered.
|
||||
*/
|
||||
if ((m->flags & MAN_BLINE) &&
|
||||
if ((man->flags & MAN_BLINE) &&
|
||||
(MAN_BSCOPE & man_macros[tok].flags)) {
|
||||
n = m->last;
|
||||
n = man->last;
|
||||
|
||||
/* Might be a text node like 8 in
|
||||
* .TP 8
|
||||
@ -573,12 +581,12 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
assert(MAN_BLOCK == n->type);
|
||||
assert(MAN_SCOPED & man_macros[n->tok].flags);
|
||||
|
||||
mandoc_vmsg(MANDOCERR_LINESCOPE, m->parse, n->line,
|
||||
mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line,
|
||||
n->pos, "%s breaks %s", man_macronames[tok],
|
||||
man_macronames[n->tok]);
|
||||
|
||||
man_node_delete(m, n);
|
||||
m->flags &= ~MAN_BLINE;
|
||||
man_node_delete(man, n);
|
||||
man->flags &= ~MAN_BLINE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -587,13 +595,13 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
* when they exit.
|
||||
*/
|
||||
|
||||
if (MAN_BLINE & m->flags)
|
||||
m->flags |= MAN_BPLINE;
|
||||
if (MAN_BLINE & man->flags)
|
||||
man->flags |= MAN_BPLINE;
|
||||
|
||||
/* Call to handler... */
|
||||
|
||||
assert(man_macros[tok].fp);
|
||||
if ( ! (*man_macros[tok].fp)(m, tok, ln, ppos, &offs, buf))
|
||||
if ( ! (*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
@ -601,19 +609,19 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
* above-parsed macro, so return.
|
||||
*/
|
||||
|
||||
if ( ! (MAN_BPLINE & m->flags)) {
|
||||
m->flags &= ~MAN_ILINE;
|
||||
if ( ! (MAN_BPLINE & man->flags)) {
|
||||
man->flags &= ~MAN_ILINE;
|
||||
return(1);
|
||||
}
|
||||
m->flags &= ~MAN_BPLINE;
|
||||
man->flags &= ~MAN_BPLINE;
|
||||
|
||||
/*
|
||||
* If we're in a block scope, then allow this macro to slip by
|
||||
* without closing scope around it.
|
||||
*/
|
||||
|
||||
if (MAN_ILINE & m->flags) {
|
||||
m->flags &= ~MAN_ILINE;
|
||||
if (MAN_ILINE & man->flags) {
|
||||
man->flags &= ~MAN_ILINE;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -622,30 +630,30 @@ man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
* now, as the next line will close out the block scope.
|
||||
*/
|
||||
|
||||
if (MAN_ELINE & m->flags)
|
||||
if (MAN_ELINE & man->flags)
|
||||
return(1);
|
||||
|
||||
/* Close out the block scope opened in the prior line. */
|
||||
|
||||
assert(MAN_BLINE & m->flags);
|
||||
m->flags &= ~MAN_BLINE;
|
||||
assert(MAN_BLINE & man->flags);
|
||||
man->flags &= ~MAN_BLINE;
|
||||
|
||||
if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
|
||||
if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
|
||||
return(0);
|
||||
return(man_body_alloc(m, ln, ppos, m->last->tok));
|
||||
return(man_body_alloc(man, ln, ppos, man->last->tok));
|
||||
|
||||
err: /* Error out. */
|
||||
|
||||
m->flags |= MAN_HALT;
|
||||
man->flags |= MAN_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlink a node from its context. If "m" is provided, the last parse
|
||||
* Unlink a node from its context. If "man" is provided, the last parse
|
||||
* point will also be adjusted accordingly.
|
||||
*/
|
||||
static void
|
||||
man_node_unlink(struct man *m, struct man_node *n)
|
||||
man_node_unlink(struct man *man, struct man_node *n)
|
||||
{
|
||||
|
||||
/* Adjust siblings. */
|
||||
@ -665,26 +673,26 @@ man_node_unlink(struct man *m, struct man_node *n)
|
||||
|
||||
/* Adjust parse point, if applicable. */
|
||||
|
||||
if (m && m->last == n) {
|
||||
if (man && man->last == n) {
|
||||
/*XXX: this can occur when bailing from validation. */
|
||||
/*assert(NULL == n->next);*/
|
||||
if (n->prev) {
|
||||
m->last = n->prev;
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
man->last = n->prev;
|
||||
man->next = MAN_NEXT_SIBLING;
|
||||
} else {
|
||||
m->last = n->parent;
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
man->last = n->parent;
|
||||
man->next = MAN_NEXT_CHILD;
|
||||
}
|
||||
}
|
||||
|
||||
if (m && m->first == n)
|
||||
m->first = NULL;
|
||||
if (man && man->first == n)
|
||||
man->first = NULL;
|
||||
}
|
||||
|
||||
const struct mparse *
|
||||
man_mparse(const struct man *m)
|
||||
man_mparse(const struct man *man)
|
||||
{
|
||||
|
||||
assert(m && m->parse);
|
||||
return(m->parse);
|
||||
assert(man && man->parse);
|
||||
return(man->parse);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man.h,v 1.60 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/* $Id: man.h,v 1.62 2013/10/17 20:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -52,6 +52,10 @@ enum mant {
|
||||
MAN_in,
|
||||
MAN_ft,
|
||||
MAN_OP,
|
||||
MAN_EX,
|
||||
MAN_EE,
|
||||
MAN_UR,
|
||||
MAN_UE,
|
||||
MAN_MAX
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: man_html.c,v 1.86 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/* $Id: man_html.c,v 1.90 2013/10/17 20:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -37,7 +38,7 @@
|
||||
|
||||
#define INDENT 5
|
||||
|
||||
#define MAN_ARGS const struct man_meta *m, \
|
||||
#define MAN_ARGS const struct man_meta *man, \
|
||||
const struct man_node *n, \
|
||||
struct mhtml *mh, \
|
||||
struct html *h
|
||||
@ -70,6 +71,7 @@ static int man_RS_pre(MAN_ARGS);
|
||||
static int man_SH_pre(MAN_ARGS);
|
||||
static int man_SM_pre(MAN_ARGS);
|
||||
static int man_SS_pre(MAN_ARGS);
|
||||
static int man_UR_pre(MAN_ARGS);
|
||||
static int man_alt_pre(MAN_ARGS);
|
||||
static int man_br_pre(MAN_ARGS);
|
||||
static int man_ign_pre(MAN_ARGS);
|
||||
@ -113,6 +115,10 @@ static const struct htmlman mans[MAN_MAX] = {
|
||||
{ man_in_pre, NULL }, /* in */
|
||||
{ man_ign_pre, NULL }, /* ft */
|
||||
{ man_OP_pre, NULL }, /* OP */
|
||||
{ man_literal_pre, NULL }, /* EX */
|
||||
{ man_literal_pre, NULL }, /* EE */
|
||||
{ man_UR_pre, NULL }, /* UR */
|
||||
{ NULL, NULL }, /* UE */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -139,12 +145,12 @@ print_bvspace(struct html *h, const struct man_node *n)
|
||||
}
|
||||
|
||||
void
|
||||
html_man(void *arg, const struct man *m)
|
||||
html_man(void *arg, const struct man *man)
|
||||
{
|
||||
struct mhtml mh;
|
||||
|
||||
memset(&mh, 0, sizeof(struct mhtml));
|
||||
print_man(man_meta(m), man_node(m), &mh, (struct html *)arg);
|
||||
print_man(man_meta(man), man_node(man), &mh, (struct html *)arg);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
@ -160,14 +166,14 @@ print_man(MAN_ARGS)
|
||||
print_gen_decls(h);
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
tt = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
print_man_head(m, n, mh, h);
|
||||
print_man_head(man, n, mh, h);
|
||||
print_tagq(h, tt);
|
||||
print_otag(h, TAG_BODY, 0, NULL);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
||||
print_man_nodelist(m, n, mh, h);
|
||||
print_man_nodelist(man, n, mh, h);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
@ -178,9 +184,9 @@ print_man_head(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_gen_head(h);
|
||||
assert(m->title);
|
||||
assert(m->msec);
|
||||
bufcat_fmt(h, "%s(%s)", m->title, m->msec);
|
||||
assert(man->title);
|
||||
assert(man->msec);
|
||||
bufcat_fmt(h, "%s(%s)", man->title, man->msec);
|
||||
print_otag(h, TAG_TITLE, 0, NULL);
|
||||
print_text(h, h->buf);
|
||||
}
|
||||
@ -190,9 +196,9 @@ static void
|
||||
print_man_nodelist(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_man_node(m, n, mh, h);
|
||||
print_man_node(man, n, mh, h);
|
||||
if (n->next)
|
||||
print_man_nodelist(m, n->next, mh, h);
|
||||
print_man_nodelist(man, n->next, mh, h);
|
||||
}
|
||||
|
||||
|
||||
@ -207,7 +213,7 @@ print_man_node(MAN_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_ROOT):
|
||||
man_root_pre(m, n, mh, h);
|
||||
man_root_pre(man, n, mh, h);
|
||||
break;
|
||||
case (MAN_TEXT):
|
||||
/*
|
||||
@ -258,25 +264,25 @@ print_man_node(MAN_ARGS)
|
||||
t = h->tags.head;
|
||||
}
|
||||
if (mans[n->tok].pre)
|
||||
child = (*mans[n->tok].pre)(m, n, mh, h);
|
||||
child = (*mans[n->tok].pre)(man, n, mh, h);
|
||||
break;
|
||||
}
|
||||
|
||||
if (child && n->child)
|
||||
print_man_nodelist(m, n->child, mh, h);
|
||||
print_man_nodelist(man, n->child, mh, h);
|
||||
|
||||
/* This will automatically close out any font scope. */
|
||||
print_stagq(h, t);
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_ROOT):
|
||||
man_root_post(m, n, mh, h);
|
||||
man_root_post(man, n, mh, h);
|
||||
break;
|
||||
case (MAN_EQN):
|
||||
break;
|
||||
default:
|
||||
if (mans[n->tok].post)
|
||||
(*mans[n->tok].post)(m, n, mh, h);
|
||||
(*mans[n->tok].post)(man, n, mh, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -304,12 +310,12 @@ man_root_pre(MAN_ARGS)
|
||||
char b[BUFSIZ], title[BUFSIZ];
|
||||
|
||||
b[0] = 0;
|
||||
if (m->vol)
|
||||
(void)strlcat(b, m->vol, BUFSIZ);
|
||||
if (man->vol)
|
||||
(void)strlcat(b, man->vol, BUFSIZ);
|
||||
|
||||
assert(m->title);
|
||||
assert(m->msec);
|
||||
snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec);
|
||||
assert(man->title);
|
||||
assert(man->msec);
|
||||
snprintf(title, BUFSIZ - 1, "%s(%s)", man->title, man->msec);
|
||||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
||||
PAIR_CLASS_INIT(&tag[1], "head");
|
||||
@ -363,16 +369,16 @@ man_root_post(MAN_ARGS)
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-date");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
assert(m->date);
|
||||
print_text(h, m->date);
|
||||
assert(man->date);
|
||||
print_text(h, man->date);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-os");
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
|
||||
if (m->source)
|
||||
print_text(h, m->source);
|
||||
if (man->source)
|
||||
print_text(h, man->source);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
@ -468,7 +474,7 @@ man_alt_pre(MAN_ARGS)
|
||||
if (TAG_MAX != fp)
|
||||
t = print_otag(h, fp, 0, NULL);
|
||||
|
||||
print_man_node(m, nn, mh, h);
|
||||
print_man_node(man, nn, mh, h);
|
||||
|
||||
if (t)
|
||||
print_tagq(h, t);
|
||||
@ -543,14 +549,14 @@ man_IP_pre(MAN_ARGS)
|
||||
/* For IP, only print the first header element. */
|
||||
|
||||
if (MAN_IP == n->tok && n->child)
|
||||
print_man_node(m, n->child, mh, h);
|
||||
print_man_node(man, n->child, mh, h);
|
||||
|
||||
/* For TP, only print next-line header elements. */
|
||||
|
||||
if (MAN_TP == n->tok)
|
||||
for (nn = n->child; nn; nn = nn->next)
|
||||
if (nn->line > n->line)
|
||||
print_man_node(m, nn, mh, h);
|
||||
print_man_node(man, nn, mh, h);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@ -638,7 +644,7 @@ static int
|
||||
man_literal_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
if (MAN_nf != n->tok) {
|
||||
if (MAN_fi == n->tok || MAN_EE == n->tok) {
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
} else
|
||||
@ -686,3 +692,27 @@ man_RS_pre(MAN_ARGS)
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_UR_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag[2];
|
||||
|
||||
n = n->child;
|
||||
assert(MAN_HEAD == n->type);
|
||||
if (n->nchild) {
|
||||
assert(MAN_TEXT == n->child->type);
|
||||
PAIR_CLASS_INIT(&tag[0], "link-ext");
|
||||
PAIR_HREF_INIT(&tag[1], n->child->string);
|
||||
print_otag(h, TAG_A, 2, tag);
|
||||
}
|
||||
|
||||
assert(MAN_BODY == n->next->type);
|
||||
if (n->next->nchild)
|
||||
n = n->next;
|
||||
|
||||
print_man_nodelist(man, n->child, mh, h);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* $Id: man_macro.c,v 1.71 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/* $Id: man_macro.c,v 1.79 2013/12/25 00:50:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -77,7 +79,7 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* nf */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* fi */
|
||||
{ blk_close, 0 }, /* RE */
|
||||
{ blk_exp, MAN_EXPLICIT }, /* RS */
|
||||
{ blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* RS */
|
||||
{ in_line_eoln, 0 }, /* DT */
|
||||
{ in_line_eoln, 0 }, /* UC */
|
||||
{ in_line_eoln, 0 }, /* PD */
|
||||
@ -85,6 +87,10 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
||||
{ in_line_eoln, 0 }, /* in */
|
||||
{ in_line_eoln, 0 }, /* ft */
|
||||
{ in_line_eoln, 0 }, /* OP */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EX */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EE */
|
||||
{ blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* UR */
|
||||
{ blk_close, 0 }, /* UE */
|
||||
};
|
||||
|
||||
const struct man_macro * const man_macros = __man_macros;
|
||||
@ -94,7 +100,7 @@ const struct man_macro * const man_macros = __man_macros;
|
||||
* Warn when "n" is an explicit non-roff macro.
|
||||
*/
|
||||
static void
|
||||
rew_warn(struct man *m, struct man_node *n, enum mandocerr er)
|
||||
rew_warn(struct man *man, struct man_node *n, enum mandocerr er)
|
||||
{
|
||||
|
||||
if (er == MANDOCERR_MAX || MAN_BLOCK != n->type)
|
||||
@ -105,7 +111,7 @@ rew_warn(struct man *m, struct man_node *n, enum mandocerr er)
|
||||
return;
|
||||
|
||||
assert(er < MANDOCERR_FATAL);
|
||||
man_nmsg(m, n, er);
|
||||
man_nmsg(man, n, er);
|
||||
}
|
||||
|
||||
|
||||
@ -114,33 +120,33 @@ rew_warn(struct man *m, struct man_node *n, enum mandocerr er)
|
||||
* will be used if an explicit block scope is being closed out.
|
||||
*/
|
||||
int
|
||||
man_unscope(struct man *m, const struct man_node *to,
|
||||
man_unscope(struct man *man, const struct man_node *to,
|
||||
enum mandocerr er)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
assert(to);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
man->next = MAN_NEXT_SIBLING;
|
||||
|
||||
/* LINTED */
|
||||
while (m->last != to) {
|
||||
while (man->last != to) {
|
||||
/*
|
||||
* Save the parent here, because we may delete the
|
||||
* m->last node in the post-validation phase and reset
|
||||
* it to m->last->parent, causing a step in the closing
|
||||
* man->last node in the post-validation phase and reset
|
||||
* it to man->last->parent, causing a step in the closing
|
||||
* out to be lost.
|
||||
*/
|
||||
n = m->last->parent;
|
||||
rew_warn(m, m->last, er);
|
||||
if ( ! man_valid_post(m))
|
||||
n = man->last->parent;
|
||||
rew_warn(man, man->last, er);
|
||||
if ( ! man_valid_post(man))
|
||||
return(0);
|
||||
m->last = n;
|
||||
assert(m->last);
|
||||
man->last = n;
|
||||
assert(man->last);
|
||||
}
|
||||
|
||||
rew_warn(m, m->last, er);
|
||||
if ( ! man_valid_post(m))
|
||||
rew_warn(man, man->last, er);
|
||||
if ( ! man_valid_post(man))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
@ -183,8 +189,12 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
|
||||
return(REW_NOHALT);
|
||||
|
||||
/* First: rewind to ourselves. */
|
||||
if (type == n->type && tok == n->tok)
|
||||
return(REW_REWIND);
|
||||
if (type == n->type && tok == n->tok) {
|
||||
if (MAN_EXPLICIT & man_macros[n->tok].flags)
|
||||
return(REW_HALT);
|
||||
else
|
||||
return(REW_REWIND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Next follow the implicit scope-smashings as defined by man.7:
|
||||
@ -200,6 +210,10 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
|
||||
return(c);
|
||||
break;
|
||||
case (MAN_RS):
|
||||
/* Preserve empty paragraphs before RS. */
|
||||
if (0 == n->nchild && (MAN_P == n->tok ||
|
||||
MAN_PP == n->tok || MAN_LP == n->tok))
|
||||
return(REW_HALT);
|
||||
/* Rewind to a subsection, if a block. */
|
||||
if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
|
||||
return(c);
|
||||
@ -230,13 +244,13 @@ rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
|
||||
* scopes. When a scope is closed, it must be validated and actioned.
|
||||
*/
|
||||
static int
|
||||
rew_scope(enum man_type type, struct man *m, enum mant tok)
|
||||
rew_scope(enum man_type type, struct man *man, enum mant tok)
|
||||
{
|
||||
struct man_node *n;
|
||||
enum rew c;
|
||||
|
||||
/* LINTED */
|
||||
for (n = m->last; n; n = n->parent) {
|
||||
for (n = man->last; n; n = n->parent) {
|
||||
/*
|
||||
* Whether we should stop immediately (REW_HALT), stop
|
||||
* and rewind until this point (REW_REWIND), or keep
|
||||
@ -255,7 +269,7 @@ rew_scope(enum man_type type, struct man *m, enum mant tok)
|
||||
*/
|
||||
assert(n);
|
||||
|
||||
return(man_unscope(m, n, MANDOCERR_MAX));
|
||||
return(man_unscope(man, n, MANDOCERR_MAX));
|
||||
}
|
||||
|
||||
|
||||
@ -273,22 +287,24 @@ blk_close(MACRO_PROT_ARGS)
|
||||
case (MAN_RE):
|
||||
ntok = MAN_RS;
|
||||
break;
|
||||
case (MAN_UE):
|
||||
ntok = MAN_UR;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
for (nn = m->last->parent; nn; nn = nn->parent)
|
||||
if (ntok == nn->tok)
|
||||
for (nn = man->last->parent; nn; nn = nn->parent)
|
||||
if (ntok == nn->tok && MAN_BLOCK == nn->type)
|
||||
break;
|
||||
|
||||
if (NULL == nn)
|
||||
man_pmsg(m, line, ppos, MANDOCERR_NOSCOPE);
|
||||
|
||||
if ( ! rew_scope(MAN_BODY, m, ntok))
|
||||
return(0);
|
||||
if ( ! rew_scope(MAN_BLOCK, m, ntok))
|
||||
return(0);
|
||||
if (NULL == nn) {
|
||||
man_pmsg(man, line, ppos, MANDOCERR_NOSCOPE);
|
||||
if ( ! rew_scope(MAN_BLOCK, man, MAN_PP))
|
||||
return(0);
|
||||
} else
|
||||
man_unscope(man, nn, MANDOCERR_MAX);
|
||||
|
||||
return(1);
|
||||
}
|
||||
@ -298,34 +314,40 @@ blk_close(MACRO_PROT_ARGS)
|
||||
int
|
||||
blk_exp(MACRO_PROT_ARGS)
|
||||
{
|
||||
struct man_node *n;
|
||||
int la;
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* Close out prior scopes. "Regular" explicit macros cannot be
|
||||
* nested, but we allow roff macros to be placed just about
|
||||
* anywhere.
|
||||
*/
|
||||
/* Close out prior implicit scopes. */
|
||||
|
||||
if ( ! man_block_alloc(m, line, ppos, tok))
|
||||
if ( ! rew_scope(MAN_BLOCK, man, tok))
|
||||
return(0);
|
||||
if ( ! man_head_alloc(m, line, ppos, tok))
|
||||
|
||||
if ( ! man_block_alloc(man, line, ppos, tok))
|
||||
return(0);
|
||||
if ( ! man_head_alloc(man, line, ppos, tok))
|
||||
return(0);
|
||||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
if ( ! man_args(m, line, pos, buf, &p))
|
||||
if ( ! man_args(man, line, pos, buf, &p))
|
||||
break;
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
if ( ! man_word_alloc(man, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
||||
assert(m);
|
||||
assert(man);
|
||||
assert(tok != MAN_MAX);
|
||||
|
||||
if ( ! rew_scope(MAN_HEAD, m, tok))
|
||||
return(0);
|
||||
return(man_body_alloc(m, line, ppos, tok));
|
||||
for (n = man->last; n; n = n->parent) {
|
||||
if (n->tok != tok)
|
||||
continue;
|
||||
assert(MAN_HEAD == n->type);
|
||||
man_unscope(man, n, MANDOCERR_MAX);
|
||||
break;
|
||||
}
|
||||
|
||||
return(man_body_alloc(man, line, ppos, tok));
|
||||
}
|
||||
|
||||
|
||||
@ -346,27 +368,27 @@ blk_imp(MACRO_PROT_ARGS)
|
||||
|
||||
/* Close out prior scopes. */
|
||||
|
||||
if ( ! rew_scope(MAN_BODY, m, tok))
|
||||
if ( ! rew_scope(MAN_BODY, man, tok))
|
||||
return(0);
|
||||
if ( ! rew_scope(MAN_BLOCK, m, tok))
|
||||
if ( ! rew_scope(MAN_BLOCK, man, tok))
|
||||
return(0);
|
||||
|
||||
/* Allocate new block & head scope. */
|
||||
|
||||
if ( ! man_block_alloc(m, line, ppos, tok))
|
||||
if ( ! man_block_alloc(man, line, ppos, tok))
|
||||
return(0);
|
||||
if ( ! man_head_alloc(m, line, ppos, tok))
|
||||
if ( ! man_head_alloc(man, line, ppos, tok))
|
||||
return(0);
|
||||
|
||||
n = m->last;
|
||||
n = man->last;
|
||||
|
||||
/* Add line arguments. */
|
||||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
if ( ! man_args(m, line, pos, buf, &p))
|
||||
if ( ! man_args(man, line, pos, buf, &p))
|
||||
break;
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
if ( ! man_word_alloc(man, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -375,17 +397,17 @@ blk_imp(MACRO_PROT_ARGS)
|
||||
if (MAN_SCOPED & man_macros[tok].flags) {
|
||||
/* If we're forcing scope (`TP'), keep it open. */
|
||||
if (MAN_FSCOPED & man_macros[tok].flags) {
|
||||
m->flags |= MAN_BLINE;
|
||||
man->flags |= MAN_BLINE;
|
||||
return(1);
|
||||
} else if (n == m->last) {
|
||||
m->flags |= MAN_BLINE;
|
||||
} else if (n == man->last) {
|
||||
man->flags |= MAN_BLINE;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! rew_scope(MAN_HEAD, m, tok))
|
||||
if ( ! rew_scope(MAN_HEAD, man, tok))
|
||||
return(0);
|
||||
return(man_body_alloc(m, line, ppos, tok));
|
||||
return(man_body_alloc(man, line, ppos, tok));
|
||||
}
|
||||
|
||||
|
||||
@ -397,28 +419,37 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
char *p;
|
||||
struct man_node *n;
|
||||
|
||||
if ( ! man_elem_alloc(m, line, ppos, tok))
|
||||
if ( ! man_elem_alloc(man, line, ppos, tok))
|
||||
return(0);
|
||||
|
||||
n = m->last;
|
||||
n = man->last;
|
||||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
if ( ! man_args(m, line, pos, buf, &p))
|
||||
if ( ! man_args(man, line, pos, buf, &p))
|
||||
break;
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
if ( ! man_word_alloc(man, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append MAN_EOS in case the last snipped argument
|
||||
* ends with a dot, e.g. `.IR syslog (3).'
|
||||
*/
|
||||
|
||||
if (n != man->last &&
|
||||
mandoc_eos(man->last->string, strlen(man->last->string), 0))
|
||||
man->last->flags |= MAN_EOS;
|
||||
|
||||
/*
|
||||
* If no arguments are specified and this is MAN_SCOPED (i.e.,
|
||||
* next-line scoped), then set our mode to indicate that we're
|
||||
* waiting for terms to load into our context.
|
||||
*/
|
||||
|
||||
if (n == m->last && MAN_SCOPED & man_macros[tok].flags) {
|
||||
if (n == man->last && MAN_SCOPED & man_macros[tok].flags) {
|
||||
assert( ! (MAN_NSCOPED & man_macros[tok].flags));
|
||||
m->flags |= MAN_ELINE;
|
||||
man->flags |= MAN_ELINE;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -426,11 +457,11 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
|
||||
if (MAN_NSCOPED & man_macros[tok].flags) {
|
||||
assert( ! (MAN_SCOPED & man_macros[tok].flags));
|
||||
m->flags |= MAN_ILINE;
|
||||
man->flags |= MAN_ILINE;
|
||||
}
|
||||
|
||||
assert(MAN_ROOT != m->last->type);
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
assert(MAN_ROOT != man->last->type);
|
||||
man->next = MAN_NEXT_SIBLING;
|
||||
|
||||
/*
|
||||
* Rewind our element scope. Note that when TH is pruned, we'll
|
||||
@ -438,22 +469,22 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
* its sibling.
|
||||
*/
|
||||
|
||||
for ( ; m->last; m->last = m->last->parent) {
|
||||
if (m->last == n)
|
||||
for ( ; man->last; man->last = man->last->parent) {
|
||||
if (man->last == n)
|
||||
break;
|
||||
if (m->last->type == MAN_ROOT)
|
||||
if (man->last->type == MAN_ROOT)
|
||||
break;
|
||||
if ( ! man_valid_post(m))
|
||||
if ( ! man_valid_post(man))
|
||||
return(0);
|
||||
}
|
||||
|
||||
assert(m->last);
|
||||
assert(man->last);
|
||||
|
||||
/*
|
||||
* Same here regarding whether we're back at the root.
|
||||
*/
|
||||
|
||||
if (m->last->type != MAN_ROOT && ! man_valid_post(m))
|
||||
if (man->last->type != MAN_ROOT && ! man_valid_post(man))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
@ -461,14 +492,14 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
|
||||
|
||||
int
|
||||
man_macroend(struct man *m)
|
||||
man_macroend(struct man *man)
|
||||
{
|
||||
|
||||
return(man_unscope(m, m->first, MANDOCERR_SCOPEEXIT));
|
||||
return(man_unscope(man, man->first, MANDOCERR_SCOPEEXIT));
|
||||
}
|
||||
|
||||
static int
|
||||
man_args(struct man *m, int line, int *pos, char *buf, char **v)
|
||||
man_args(struct man *man, int line, int *pos, char *buf, char **v)
|
||||
{
|
||||
char *start;
|
||||
|
||||
@ -479,6 +510,6 @@ man_args(struct man *m, int line, int *pos, char *buf, char **v)
|
||||
if ('\0' == *start)
|
||||
return(0);
|
||||
|
||||
*v = mandoc_getarg(m->parse, v, line, pos);
|
||||
*v = mandoc_getarg(man->parse, v, line, pos);
|
||||
return(1);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: man_term.c,v 1.127 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/* $Id: man_term.c,v 1.139 2013/12/22 23:34:13 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -35,8 +35,6 @@
|
||||
|
||||
#define MAXMARGINS 64 /* maximum number of indented scopes */
|
||||
|
||||
/* FIXME: have PD set the default vspace width. */
|
||||
|
||||
struct mtermp {
|
||||
int fl;
|
||||
#define MANT_LITERAL (1 << 0)
|
||||
@ -44,12 +42,13 @@ struct mtermp {
|
||||
int lmargincur; /* index of current margin */
|
||||
int lmarginsz; /* actual number of nested margins */
|
||||
size_t offset; /* default offset to visible page */
|
||||
int pardist; /* vert. space before par., unit: [v] */
|
||||
};
|
||||
|
||||
#define DECL_ARGS struct termp *p, \
|
||||
struct mtermp *mt, \
|
||||
const struct man_node *n, \
|
||||
const struct man_meta *m
|
||||
const struct man_meta *meta
|
||||
|
||||
struct termact {
|
||||
int (*pre)(DECL_ARGS);
|
||||
@ -66,18 +65,20 @@ static void print_man_node(DECL_ARGS);
|
||||
static void print_man_head(struct termp *, const void *);
|
||||
static void print_man_foot(struct termp *, const void *);
|
||||
static void print_bvspace(struct termp *,
|
||||
const struct man_node *);
|
||||
const struct man_node *, int);
|
||||
|
||||
static int pre_B(DECL_ARGS);
|
||||
static int pre_HP(DECL_ARGS);
|
||||
static int pre_I(DECL_ARGS);
|
||||
static int pre_IP(DECL_ARGS);
|
||||
static int pre_OP(DECL_ARGS);
|
||||
static int pre_PD(DECL_ARGS);
|
||||
static int pre_PP(DECL_ARGS);
|
||||
static int pre_RS(DECL_ARGS);
|
||||
static int pre_SH(DECL_ARGS);
|
||||
static int pre_SS(DECL_ARGS);
|
||||
static int pre_TP(DECL_ARGS);
|
||||
static int pre_UR(DECL_ARGS);
|
||||
static int pre_alternate(DECL_ARGS);
|
||||
static int pre_ft(DECL_ARGS);
|
||||
static int pre_ign(DECL_ARGS);
|
||||
@ -91,6 +92,7 @@ static void post_RS(DECL_ARGS);
|
||||
static void post_SH(DECL_ARGS);
|
||||
static void post_SS(DECL_ARGS);
|
||||
static void post_TP(DECL_ARGS);
|
||||
static void post_UR(DECL_ARGS);
|
||||
|
||||
static const struct termact termacts[MAN_MAX] = {
|
||||
{ pre_sp, NULL, MAN_NOTEXT }, /* br */
|
||||
@ -122,11 +124,15 @@ static const struct termact termacts[MAN_MAX] = {
|
||||
{ pre_RS, post_RS, 0 }, /* RS */
|
||||
{ pre_ign, NULL, 0 }, /* DT */
|
||||
{ pre_ign, NULL, 0 }, /* UC */
|
||||
{ pre_ign, NULL, 0 }, /* PD */
|
||||
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
|
||||
{ pre_ign, NULL, 0 }, /* AT */
|
||||
{ pre_in, NULL, MAN_NOTEXT }, /* in */
|
||||
{ pre_ft, NULL, MAN_NOTEXT }, /* ft */
|
||||
{ pre_OP, NULL, 0 }, /* OP */
|
||||
{ pre_literal, NULL, 0 }, /* EX */
|
||||
{ pre_literal, NULL, 0 }, /* EE */
|
||||
{ pre_UR, post_UR, 0 }, /* UR */
|
||||
{ NULL, NULL, 0 }, /* UE */
|
||||
};
|
||||
|
||||
|
||||
@ -136,7 +142,7 @@ terminal_man(void *arg, const struct man *man)
|
||||
{
|
||||
struct termp *p;
|
||||
const struct man_node *n;
|
||||
const struct man_meta *m;
|
||||
const struct man_meta *meta;
|
||||
struct mtermp mt;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
@ -152,18 +158,19 @@ terminal_man(void *arg, const struct man *man)
|
||||
p->symtab = mchars_alloc();
|
||||
|
||||
n = man_node(man);
|
||||
m = man_meta(man);
|
||||
meta = man_meta(man);
|
||||
|
||||
term_begin(p, print_man_head, print_man_foot, m);
|
||||
term_begin(p, print_man_head, print_man_foot, meta);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
memset(&mt, 0, sizeof(struct mtermp));
|
||||
|
||||
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
|
||||
mt.offset = term_len(p, p->defindent);
|
||||
mt.pardist = 1;
|
||||
|
||||
if (n->child)
|
||||
print_man_nodelist(p, &mt, n->child, m);
|
||||
print_man_nodelist(p, &mt, n->child, meta);
|
||||
|
||||
term_end(p);
|
||||
}
|
||||
@ -201,8 +208,9 @@ a2width(const struct termp *p, const char *cp)
|
||||
* first, print it.
|
||||
*/
|
||||
static void
|
||||
print_bvspace(struct termp *p, const struct man_node *n)
|
||||
print_bvspace(struct termp *p, const struct man_node *n, int pardist)
|
||||
{
|
||||
int i;
|
||||
|
||||
term_newln(p);
|
||||
|
||||
@ -214,7 +222,8 @@ print_bvspace(struct termp *p, const struct man_node *n)
|
||||
if (NULL == n->prev)
|
||||
return;
|
||||
|
||||
term_vspace(p);
|
||||
for (i = 0; i < pardist; i++)
|
||||
term_vspace(p);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -243,7 +252,7 @@ pre_literal(DECL_ARGS)
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (MAN_nf == n->tok)
|
||||
if (MAN_nf == n->tok || MAN_EX == n->tok)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
else
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
@ -256,13 +265,29 @@ pre_literal(DECL_ARGS)
|
||||
if (MAN_HP == n->parent->tok && p->rmargin < p->maxrmargin) {
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_TWOSPACE);
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
pre_PD(DECL_ARGS)
|
||||
{
|
||||
|
||||
n = n->child;
|
||||
if (0 == n) {
|
||||
mt->pardist = 1;
|
||||
return(0);
|
||||
}
|
||||
assert(MAN_TEXT == n->type);
|
||||
mt->pardist = atoi(n->string);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
pre_alternate(DECL_ARGS)
|
||||
@ -307,7 +332,7 @@ pre_alternate(DECL_ARGS)
|
||||
term_fontrepl(p, font[i]);
|
||||
if (savelit && NULL == nn->next)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
print_man_node(p, mt, nn, m);
|
||||
print_man_node(p, mt, nn, meta);
|
||||
if (nn->next)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
@ -438,28 +463,54 @@ pre_in(DECL_ARGS)
|
||||
static int
|
||||
pre_sp(DECL_ARGS)
|
||||
{
|
||||
char *s;
|
||||
size_t i, len;
|
||||
int neg;
|
||||
|
||||
if ((NULL == n->prev && n->parent)) {
|
||||
if (MAN_SS == n->parent->tok)
|
||||
return(0);
|
||||
if (MAN_SH == n->parent->tok)
|
||||
switch (n->parent->tok) {
|
||||
case (MAN_SH):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_SS):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_PP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_LP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_P):
|
||||
/* FALLTHROUGH */
|
||||
return(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
neg = 0;
|
||||
switch (n->tok) {
|
||||
case (MAN_br):
|
||||
len = 0;
|
||||
break;
|
||||
default:
|
||||
len = n->child ? a2height(p, n->child->string) : 1;
|
||||
if (NULL == n->child) {
|
||||
len = 1;
|
||||
break;
|
||||
}
|
||||
s = n->child->string;
|
||||
if ('-' == *s) {
|
||||
neg = 1;
|
||||
s++;
|
||||
}
|
||||
len = a2height(p, s);
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == len)
|
||||
term_newln(p);
|
||||
for (i = 0; i < len; i++)
|
||||
term_vspace(p);
|
||||
else if (neg)
|
||||
p->skipvsp += len;
|
||||
else
|
||||
for (i = 0; i < len; i++)
|
||||
term_vspace(p);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@ -475,16 +526,19 @@ pre_HP(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
print_bvspace(p, n);
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
return(1);
|
||||
case (MAN_BODY):
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->flags |= TERMP_TWOSPACE;
|
||||
break;
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ( ! (MANT_LITERAL & mt->fl)) {
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 2;
|
||||
}
|
||||
|
||||
len = mt->lmargin[mt->lmargincur];
|
||||
ival = -1;
|
||||
|
||||
@ -514,13 +568,10 @@ post_HP(DECL_ARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
term_flushln(p);
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
term_flushln(p);
|
||||
term_newln(p);
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags &= ~TERMP_TWOSPACE;
|
||||
p->trailspace = 0;
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = p->maxrmargin;
|
||||
break;
|
||||
@ -538,7 +589,7 @@ pre_PP(DECL_ARGS)
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
|
||||
print_bvspace(p, n);
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
break;
|
||||
default:
|
||||
p->offset = mt->offset;
|
||||
@ -563,9 +614,10 @@ pre_IP(DECL_ARGS)
|
||||
break;
|
||||
case (MAN_HEAD):
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
case (MAN_BLOCK):
|
||||
print_bvspace(p, n);
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
return(1);
|
||||
@ -598,7 +650,7 @@ pre_IP(DECL_ARGS)
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
|
||||
if (n->child)
|
||||
print_man_node(p, mt, n->child, m);
|
||||
print_man_node(p, mt, n->child, meta);
|
||||
|
||||
if (savelit)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
@ -625,10 +677,12 @@ post_IP(DECL_ARGS)
|
||||
case (MAN_HEAD):
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->trailspace = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
term_newln(p);
|
||||
p->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -647,12 +701,13 @@ pre_TP(DECL_ARGS)
|
||||
switch (n->type) {
|
||||
case (MAN_HEAD):
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case (MAN_BLOCK):
|
||||
print_bvspace(p, n);
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
return(1);
|
||||
@ -683,7 +738,7 @@ pre_TP(DECL_ARGS)
|
||||
/* Don't print same-line elements. */
|
||||
for (nn = n->child; nn; nn = nn->next)
|
||||
if (nn->line > n->line)
|
||||
print_man_node(p, mt, nn, m);
|
||||
print_man_node(p, mt, nn, meta);
|
||||
|
||||
if (savelit)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
@ -694,6 +749,8 @@ pre_TP(DECL_ARGS)
|
||||
case (MAN_BODY):
|
||||
p->offset = mt->offset + len;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -711,12 +768,10 @@ post_TP(DECL_ARGS)
|
||||
switch (n->type) {
|
||||
case (MAN_HEAD):
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags &= ~TERMP_TWOSPACE;
|
||||
p->rmargin = p->maxrmargin;
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
term_newln(p);
|
||||
p->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -728,6 +783,7 @@ post_TP(DECL_ARGS)
|
||||
static int
|
||||
pre_SS(DECL_ARGS)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
@ -740,11 +796,12 @@ pre_SS(DECL_ARGS)
|
||||
break;
|
||||
if (NULL == n->prev)
|
||||
break;
|
||||
term_vspace(p);
|
||||
for (i = 0; i < mt->pardist; i++)
|
||||
term_vspace(p);
|
||||
break;
|
||||
case (MAN_HEAD):
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
p->offset = term_len(p, p->defindent/2);
|
||||
p->offset = term_len(p, 3);
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
p->offset = mt->offset;
|
||||
@ -779,6 +836,7 @@ post_SS(DECL_ARGS)
|
||||
static int
|
||||
pre_SH(DECL_ARGS)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
@ -792,7 +850,8 @@ pre_SH(DECL_ARGS)
|
||||
/* If the first macro, no vspae. */
|
||||
if (NULL == n->prev)
|
||||
break;
|
||||
term_vspace(p);
|
||||
for (i = 0; i < mt->pardist; i++)
|
||||
term_vspace(p);
|
||||
break;
|
||||
case (MAN_HEAD):
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
@ -890,6 +949,32 @@ post_RS(DECL_ARGS)
|
||||
mt->lmargincur = mt->lmarginsz;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
pre_UR(DECL_ARGS)
|
||||
{
|
||||
|
||||
return (MAN_HEAD != n->type);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
post_UR(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MAN_BLOCK != n->type)
|
||||
return;
|
||||
|
||||
term_word(p, "<");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
if (NULL != n->child->child)
|
||||
print_man_node(p, mt, n->child->child, meta);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ">");
|
||||
}
|
||||
|
||||
static void
|
||||
print_man_node(DECL_ARGS)
|
||||
{
|
||||
@ -910,29 +995,8 @@ print_man_node(DECL_ARGS)
|
||||
term_newln(p);
|
||||
|
||||
term_word(p, n->string);
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If we're in a literal context, make sure that words
|
||||
* togehter on the same line stay together. This is a
|
||||
* POST-printing call, so we check the NEXT word. Since
|
||||
* -man doesn't have nested macros, we don't need to be
|
||||
* more specific than this.
|
||||
*/
|
||||
if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
|
||||
(NULL == n->next ||
|
||||
n->next->line > n->line)) {
|
||||
rm = p->rmargin;
|
||||
rmax = p->maxrmargin;
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_flushln(p);
|
||||
p->rmargin = rm;
|
||||
p->maxrmargin = rmax;
|
||||
}
|
||||
|
||||
if (MAN_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
return;
|
||||
case (MAN_EQN):
|
||||
term_eqn(p, n->eqn);
|
||||
return;
|
||||
@ -954,16 +1018,41 @@ print_man_node(DECL_ARGS)
|
||||
|
||||
c = 1;
|
||||
if (termacts[n->tok].pre)
|
||||
c = (*termacts[n->tok].pre)(p, mt, n, m);
|
||||
c = (*termacts[n->tok].pre)(p, mt, n, meta);
|
||||
|
||||
if (c && n->child)
|
||||
print_man_nodelist(p, mt, n->child, m);
|
||||
print_man_nodelist(p, mt, n->child, meta);
|
||||
|
||||
if (termacts[n->tok].post)
|
||||
(*termacts[n->tok].post)(p, mt, n, m);
|
||||
(*termacts[n->tok].post)(p, mt, n, meta);
|
||||
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
out:
|
||||
/*
|
||||
* If we're in a literal context, make sure that words
|
||||
* together on the same line stay together. This is a
|
||||
* POST-printing call, so we check the NEXT word. Since
|
||||
* -man doesn't have nested macros, we don't need to be
|
||||
* more specific than this.
|
||||
*/
|
||||
if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
|
||||
(NULL == n->next || n->next->line > n->line)) {
|
||||
rm = p->rmargin;
|
||||
rmax = p->maxrmargin;
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (NULL != n->string && '\0' != *n->string)
|
||||
term_flushln(p);
|
||||
else
|
||||
term_newln(p);
|
||||
if (rm < rmax && n->parent->tok == MAN_HP) {
|
||||
p->offset = rm;
|
||||
p->rmargin = rmax;
|
||||
} else
|
||||
p->rmargin = rm;
|
||||
p->maxrmargin = rmax;
|
||||
}
|
||||
if (MAN_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
}
|
||||
@ -973,10 +1062,10 @@ static void
|
||||
print_man_nodelist(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_man_node(p, mt, n, m);
|
||||
print_man_node(p, mt, n, meta);
|
||||
if ( ! n->next)
|
||||
return;
|
||||
print_man_nodelist(p, mt, n->next, m);
|
||||
print_man_nodelist(p, mt, n->next, meta);
|
||||
}
|
||||
|
||||
|
||||
@ -1016,6 +1105,7 @@ print_man_foot(struct termp *p, const void *arg)
|
||||
/* Bottom left corner: manual source. */
|
||||
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
p->offset = 0;
|
||||
p->rmargin = (p->maxrmargin - datelen + term_len(p, 1)) / 2;
|
||||
|
||||
@ -1038,6 +1128,7 @@ print_man_foot(struct termp *p, const void *arg)
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->trailspace = 0;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
|
||||
@ -1051,24 +1142,25 @@ print_man_head(struct termp *p, const void *arg)
|
||||
{
|
||||
char buf[BUFSIZ], title[BUFSIZ];
|
||||
size_t buflen, titlen;
|
||||
const struct man_meta *m;
|
||||
const struct man_meta *meta;
|
||||
|
||||
m = (const struct man_meta *)arg;
|
||||
assert(m->title);
|
||||
assert(m->msec);
|
||||
meta = (const struct man_meta *)arg;
|
||||
assert(meta->title);
|
||||
assert(meta->msec);
|
||||
|
||||
if (m->vol)
|
||||
strlcpy(buf, m->vol, BUFSIZ);
|
||||
if (meta->vol)
|
||||
strlcpy(buf, meta->vol, BUFSIZ);
|
||||
else
|
||||
buf[0] = '\0';
|
||||
buflen = term_strlen(p, buf);
|
||||
|
||||
/* Top left corner: manual title and section. */
|
||||
|
||||
snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec);
|
||||
snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
|
||||
titlen = term_strlen(p, title);
|
||||
|
||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||
p->trailspace = 1;
|
||||
p->offset = 0;
|
||||
p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
|
||||
(p->maxrmargin -
|
||||
@ -1091,6 +1183,7 @@ print_man_head(struct termp *p, const void *arg)
|
||||
/* Top right corner: title and section, again. */
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->trailspace = 0;
|
||||
if (p->rmargin + titlen <= p->maxrmargin) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: man_validate.c,v 1.80 2012/01/03 15:16:24 kristaps Exp $ */
|
||||
/* $Id: man_validate.c,v 1.86 2013/10/17 20:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -35,7 +35,7 @@
|
||||
#include "libman.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
#define CHKARGS struct man *m, struct man_node *n
|
||||
#define CHKARGS struct man *man, struct man_node *n
|
||||
|
||||
typedef int (*v_check)(CHKARGS);
|
||||
|
||||
@ -49,12 +49,14 @@ static int check_eq2(CHKARGS);
|
||||
static int check_le1(CHKARGS);
|
||||
static int check_ge2(CHKARGS);
|
||||
static int check_le5(CHKARGS);
|
||||
static int check_head1(CHKARGS);
|
||||
static int check_par(CHKARGS);
|
||||
static int check_part(CHKARGS);
|
||||
static int check_root(CHKARGS);
|
||||
static void check_text(CHKARGS);
|
||||
|
||||
static int post_AT(CHKARGS);
|
||||
static int post_IP(CHKARGS);
|
||||
static int post_vs(CHKARGS);
|
||||
static int post_fi(CHKARGS);
|
||||
static int post_ft(CHKARGS);
|
||||
@ -70,6 +72,8 @@ static v_check posts_eq0[] = { check_eq0, NULL };
|
||||
static v_check posts_eq2[] = { check_eq2, NULL };
|
||||
static v_check posts_fi[] = { check_eq0, post_fi, NULL };
|
||||
static v_check posts_ft[] = { post_ft, NULL };
|
||||
static v_check posts_ip[] = { post_IP, NULL };
|
||||
static v_check posts_le1[] = { check_le1, NULL };
|
||||
static v_check posts_nf[] = { check_eq0, post_nf, NULL };
|
||||
static v_check posts_par[] = { check_par, NULL };
|
||||
static v_check posts_part[] = { check_part, NULL };
|
||||
@ -77,6 +81,7 @@ static v_check posts_sec[] = { post_sec, NULL };
|
||||
static v_check posts_sp[] = { post_vs, check_le1, NULL };
|
||||
static v_check posts_th[] = { check_ge2, check_le5, post_TH, NULL };
|
||||
static v_check posts_uc[] = { post_UC, NULL };
|
||||
static v_check posts_ur[] = { check_head1, check_part, NULL };
|
||||
static v_check pres_sec[] = { pre_sec, NULL };
|
||||
|
||||
static const struct man_valid man_valids[MAN_MAX] = {
|
||||
@ -88,7 +93,7 @@ static const struct man_valid man_valids[MAN_MAX] = {
|
||||
{ NULL, posts_par }, /* LP */
|
||||
{ NULL, posts_par }, /* PP */
|
||||
{ NULL, posts_par }, /* P */
|
||||
{ NULL, NULL }, /* IP */
|
||||
{ NULL, posts_ip }, /* IP */
|
||||
{ NULL, NULL }, /* HP */
|
||||
{ NULL, NULL }, /* SM */
|
||||
{ NULL, NULL }, /* SB */
|
||||
@ -109,16 +114,20 @@ static const struct man_valid man_valids[MAN_MAX] = {
|
||||
{ NULL, posts_part }, /* RS */
|
||||
{ NULL, NULL }, /* DT */
|
||||
{ NULL, posts_uc }, /* UC */
|
||||
{ NULL, NULL }, /* PD */
|
||||
{ NULL, posts_le1 }, /* PD */
|
||||
{ NULL, posts_at }, /* AT */
|
||||
{ NULL, NULL }, /* in */
|
||||
{ NULL, posts_ft }, /* ft */
|
||||
{ NULL, posts_eq2 }, /* OP */
|
||||
{ NULL, posts_nf }, /* EX */
|
||||
{ NULL, posts_fi }, /* EE */
|
||||
{ NULL, posts_ur }, /* UR */
|
||||
{ NULL, NULL }, /* UE */
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
man_valid_pre(struct man *m, struct man_node *n)
|
||||
man_valid_pre(struct man *man, struct man_node *n)
|
||||
{
|
||||
v_check *cp;
|
||||
|
||||
@ -138,27 +147,27 @@ man_valid_pre(struct man *m, struct man_node *n)
|
||||
if (NULL == (cp = man_valids[n->tok].pres))
|
||||
return(1);
|
||||
for ( ; *cp; cp++)
|
||||
if ( ! (*cp)(m, n))
|
||||
if ( ! (*cp)(man, n))
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_valid_post(struct man *m)
|
||||
man_valid_post(struct man *man)
|
||||
{
|
||||
v_check *cp;
|
||||
|
||||
if (MAN_VALID & m->last->flags)
|
||||
if (MAN_VALID & man->last->flags)
|
||||
return(1);
|
||||
m->last->flags |= MAN_VALID;
|
||||
man->last->flags |= MAN_VALID;
|
||||
|
||||
switch (m->last->type) {
|
||||
switch (man->last->type) {
|
||||
case (MAN_TEXT):
|
||||
check_text(m, m->last);
|
||||
check_text(man, man->last);
|
||||
return(1);
|
||||
case (MAN_ROOT):
|
||||
return(check_root(m, m->last));
|
||||
return(check_root(man, man->last));
|
||||
case (MAN_EQN):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TBL):
|
||||
@ -167,10 +176,10 @@ man_valid_post(struct man *m)
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL == (cp = man_valids[m->last->tok].posts))
|
||||
if (NULL == (cp = man_valids[man->last->tok].posts))
|
||||
return(1);
|
||||
for ( ; *cp; cp++)
|
||||
if ( ! (*cp)(m, m->last))
|
||||
if ( ! (*cp)(man, man->last))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
@ -181,29 +190,29 @@ static int
|
||||
check_root(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BLINE & m->flags)
|
||||
man_nmsg(m, n, MANDOCERR_SCOPEEXIT);
|
||||
else if (MAN_ELINE & m->flags)
|
||||
man_nmsg(m, n, MANDOCERR_SCOPEEXIT);
|
||||
if (MAN_BLINE & man->flags)
|
||||
man_nmsg(man, n, MANDOCERR_SCOPEEXIT);
|
||||
else if (MAN_ELINE & man->flags)
|
||||
man_nmsg(man, n, MANDOCERR_SCOPEEXIT);
|
||||
|
||||
m->flags &= ~MAN_BLINE;
|
||||
m->flags &= ~MAN_ELINE;
|
||||
man->flags &= ~MAN_BLINE;
|
||||
man->flags &= ~MAN_ELINE;
|
||||
|
||||
if (NULL == m->first->child) {
|
||||
man_nmsg(m, n, MANDOCERR_NODOCBODY);
|
||||
if (NULL == man->first->child) {
|
||||
man_nmsg(man, n, MANDOCERR_NODOCBODY);
|
||||
return(0);
|
||||
} else if (NULL == m->meta.title) {
|
||||
man_nmsg(m, n, MANDOCERR_NOTITLE);
|
||||
} else if (NULL == man->meta.title) {
|
||||
man_nmsg(man, n, MANDOCERR_NOTITLE);
|
||||
|
||||
/*
|
||||
* If a title hasn't been set, do so now (by
|
||||
* implication, date and section also aren't set).
|
||||
*/
|
||||
|
||||
m->meta.title = mandoc_strdup("unknown");
|
||||
m->meta.msec = mandoc_strdup("1");
|
||||
m->meta.date = mandoc_normdate
|
||||
(m->parse, NULL, n->line, n->pos);
|
||||
man->meta.title = mandoc_strdup("unknown");
|
||||
man->meta.msec = mandoc_strdup("1");
|
||||
man->meta.date = mandoc_normdate
|
||||
(man->parse, NULL, n->line, n->pos);
|
||||
}
|
||||
|
||||
return(1);
|
||||
@ -214,12 +223,12 @@ check_text(CHKARGS)
|
||||
{
|
||||
char *cp, *p;
|
||||
|
||||
if (MAN_LITERAL & m->flags)
|
||||
if (MAN_LITERAL & man->flags)
|
||||
return;
|
||||
|
||||
cp = n->string;
|
||||
for (p = cp; NULL != (p = strchr(p, '\t')); p++)
|
||||
man_pmsg(m, n->line, (int)(p - cp), MANDOCERR_BADTAB);
|
||||
man_pmsg(man, n->line, (int)(p - cp), MANDOCERR_BADTAB);
|
||||
}
|
||||
|
||||
#define INEQ_DEFINE(x, ineq, name) \
|
||||
@ -228,7 +237,7 @@ check_##name(CHKARGS) \
|
||||
{ \
|
||||
if (n->nchild ineq (x)) \
|
||||
return(1); \
|
||||
mandoc_vmsg(MANDOCERR_ARGCOUNT, m->parse, n->line, n->pos, \
|
||||
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, \
|
||||
"line arguments %s %d (have %d)", \
|
||||
#ineq, (x), n->nchild); \
|
||||
return(1); \
|
||||
@ -240,6 +249,17 @@ INEQ_DEFINE(1, <=, le1)
|
||||
INEQ_DEFINE(2, >=, ge2)
|
||||
INEQ_DEFINE(5, <=, le5)
|
||||
|
||||
static int
|
||||
check_head1(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_HEAD == n->type && 1 != n->nchild)
|
||||
mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line,
|
||||
n->pos, "line arguments eq 1 (have %d)", n->nchild);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_ft(CHKARGS)
|
||||
{
|
||||
@ -282,14 +302,14 @@ post_ft(CHKARGS)
|
||||
|
||||
if (0 == ok) {
|
||||
mandoc_vmsg
|
||||
(MANDOCERR_BADFONT, m->parse,
|
||||
(MANDOCERR_BADFONT, man->parse,
|
||||
n->line, n->pos, "%s", cp);
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
if (1 < n->nchild)
|
||||
mandoc_vmsg
|
||||
(MANDOCERR_ARGCOUNT, m->parse, n->line,
|
||||
(MANDOCERR_ARGCOUNT, man->parse, n->line,
|
||||
n->pos, "want one child (have %d)",
|
||||
n->nchild);
|
||||
|
||||
@ -301,7 +321,7 @@ pre_sec(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BLOCK == n->type)
|
||||
m->flags &= ~MAN_LITERAL;
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -312,7 +332,7 @@ post_sec(CHKARGS)
|
||||
if ( ! (MAN_HEAD == n->type && 0 == n->nchild))
|
||||
return(1);
|
||||
|
||||
man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
|
||||
man_nmsg(man, n, MANDOCERR_SYNTARGCOUNT);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -321,7 +341,7 @@ check_part(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BODY == n->type && 0 == n->nchild)
|
||||
mandoc_msg(MANDOCERR_ARGCWARN, m->parse, n->line,
|
||||
mandoc_msg(MANDOCERR_ARGCWARN, man->parse, n->line,
|
||||
n->pos, "want children (have none)");
|
||||
|
||||
return(1);
|
||||
@ -335,15 +355,15 @@ check_par(CHKARGS)
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
if (0 == n->body->nchild)
|
||||
man_node_delete(m, n);
|
||||
man_node_delete(man, n);
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
if (0 == n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_IGNPAR);
|
||||
man_nmsg(man, n, MANDOCERR_IGNPAR);
|
||||
break;
|
||||
case (MAN_HEAD):
|
||||
if (n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_ARGSLOST);
|
||||
man_nmsg(man, n, MANDOCERR_ARGSLOST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -352,6 +372,24 @@ check_par(CHKARGS)
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_IP(CHKARGS)
|
||||
{
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_BLOCK):
|
||||
if (0 == n->head->nchild && 0 == n->body->nchild)
|
||||
man_node_delete(man, n);
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
if (0 == n->parent->head->nchild && 0 == n->nchild)
|
||||
man_nmsg(man, n, MANDOCERR_IGNPAR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_TH(CHKARGS)
|
||||
@ -359,21 +397,16 @@ post_TH(CHKARGS)
|
||||
const char *p;
|
||||
int line, pos;
|
||||
|
||||
if (m->meta.title)
|
||||
free(m->meta.title);
|
||||
if (m->meta.vol)
|
||||
free(m->meta.vol);
|
||||
if (m->meta.source)
|
||||
free(m->meta.source);
|
||||
if (m->meta.msec)
|
||||
free(m->meta.msec);
|
||||
if (m->meta.date)
|
||||
free(m->meta.date);
|
||||
free(man->meta.title);
|
||||
free(man->meta.vol);
|
||||
free(man->meta.source);
|
||||
free(man->meta.msec);
|
||||
free(man->meta.date);
|
||||
|
||||
line = n->line;
|
||||
pos = n->pos;
|
||||
m->meta.title = m->meta.vol = m->meta.date =
|
||||
m->meta.msec = m->meta.source = NULL;
|
||||
man->meta.title = man->meta.vol = man->meta.date =
|
||||
man->meta.msec = man->meta.source = NULL;
|
||||
|
||||
/* ->TITLE<- MSEC DATE SOURCE VOL */
|
||||
|
||||
@ -383,22 +416,22 @@ post_TH(CHKARGS)
|
||||
/* Only warn about this once... */
|
||||
if (isalpha((unsigned char)*p) &&
|
||||
! isupper((unsigned char)*p)) {
|
||||
man_nmsg(m, n, MANDOCERR_UPPERCASE);
|
||||
man_nmsg(man, n, MANDOCERR_UPPERCASE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m->meta.title = mandoc_strdup(n->string);
|
||||
man->meta.title = mandoc_strdup(n->string);
|
||||
} else
|
||||
m->meta.title = mandoc_strdup("");
|
||||
man->meta.title = mandoc_strdup("");
|
||||
|
||||
/* TITLE ->MSEC<- DATE SOURCE VOL */
|
||||
|
||||
if (n)
|
||||
n = n->next;
|
||||
if (n && n->string)
|
||||
m->meta.msec = mandoc_strdup(n->string);
|
||||
man->meta.msec = mandoc_strdup(n->string);
|
||||
else
|
||||
m->meta.msec = mandoc_strdup("");
|
||||
man->meta.msec = mandoc_strdup("");
|
||||
|
||||
/* TITLE MSEC ->DATE<- SOURCE VOL */
|
||||
|
||||
@ -406,30 +439,30 @@ post_TH(CHKARGS)
|
||||
n = n->next;
|
||||
if (n && n->string && '\0' != n->string[0]) {
|
||||
pos = n->pos;
|
||||
m->meta.date = mandoc_normdate
|
||||
(m->parse, n->string, line, pos);
|
||||
man->meta.date = mandoc_normdate
|
||||
(man->parse, n->string, line, pos);
|
||||
} else
|
||||
m->meta.date = mandoc_strdup("");
|
||||
man->meta.date = mandoc_strdup("");
|
||||
|
||||
/* TITLE MSEC DATE ->SOURCE<- VOL */
|
||||
|
||||
if (n && (n = n->next))
|
||||
m->meta.source = mandoc_strdup(n->string);
|
||||
man->meta.source = mandoc_strdup(n->string);
|
||||
|
||||
/* TITLE MSEC DATE SOURCE ->VOL<- */
|
||||
/* If missing, use the default VOL name for MSEC. */
|
||||
|
||||
if (n && (n = n->next))
|
||||
m->meta.vol = mandoc_strdup(n->string);
|
||||
else if ('\0' != m->meta.msec[0] &&
|
||||
(NULL != (p = mandoc_a2msec(m->meta.msec))))
|
||||
m->meta.vol = mandoc_strdup(p);
|
||||
man->meta.vol = mandoc_strdup(n->string);
|
||||
else if ('\0' != man->meta.msec[0] &&
|
||||
(NULL != (p = mandoc_a2msec(man->meta.msec))))
|
||||
man->meta.vol = mandoc_strdup(p);
|
||||
|
||||
/*
|
||||
* Remove the `TH' node after we've processed it for our
|
||||
* meta-data.
|
||||
*/
|
||||
man_node_delete(m, m->last);
|
||||
man_node_delete(man, man->last);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -437,10 +470,10 @@ static int
|
||||
post_nf(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_LITERAL & m->flags)
|
||||
man_nmsg(m, n, MANDOCERR_SCOPEREP);
|
||||
if (MAN_LITERAL & man->flags)
|
||||
man_nmsg(man, n, MANDOCERR_SCOPEREP);
|
||||
|
||||
m->flags |= MAN_LITERAL;
|
||||
man->flags |= MAN_LITERAL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -448,10 +481,10 @@ static int
|
||||
post_fi(CHKARGS)
|
||||
{
|
||||
|
||||
if ( ! (MAN_LITERAL & m->flags))
|
||||
man_nmsg(m, n, MANDOCERR_WNOSCOPE);
|
||||
if ( ! (MAN_LITERAL & man->flags))
|
||||
man_nmsg(man, n, MANDOCERR_WNOSCOPE);
|
||||
|
||||
m->flags &= ~MAN_LITERAL;
|
||||
man->flags &= ~MAN_LITERAL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -488,10 +521,8 @@ post_UC(CHKARGS)
|
||||
p = bsd_versions[0];
|
||||
}
|
||||
|
||||
if (m->meta.source)
|
||||
free(m->meta.source);
|
||||
|
||||
m->meta.source = mandoc_strdup(p);
|
||||
free(man->meta.source);
|
||||
man->meta.source = mandoc_strdup(p);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -528,10 +559,8 @@ post_AT(CHKARGS)
|
||||
p = unix_versions[0];
|
||||
}
|
||||
|
||||
if (m->meta.source)
|
||||
free(m->meta.source);
|
||||
|
||||
m->meta.source = mandoc_strdup(p);
|
||||
free(man->meta.source);
|
||||
man->meta.source = mandoc_strdup(p);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -539,12 +568,25 @@ static int
|
||||
post_vs(CHKARGS)
|
||||
{
|
||||
|
||||
/*
|
||||
* Don't warn about this because it occurs in pod2man and would
|
||||
* cause considerable (unfixable) warnage.
|
||||
*/
|
||||
if (NULL == n->prev && MAN_ROOT == n->parent->type)
|
||||
man_node_delete(m, n);
|
||||
if (NULL != n->prev)
|
||||
return(1);
|
||||
|
||||
switch (n->parent->tok) {
|
||||
case (MAN_SH):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_SS):
|
||||
man_nmsg(man, n, MANDOCERR_IGNPAR);
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_MAX):
|
||||
/*
|
||||
* Don't warn about this because it occurs in pod2man
|
||||
* and would cause considerable (unfixable) warnage.
|
||||
*/
|
||||
man_node_delete(man, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
.\" $Id: mandoc.1,v 1.100 2011/12/25 19:35:44 kristaps Exp $
|
||||
.\" $Id: mandoc.1,v 1.103 2013/07/13 19:41:16 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -14,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: December 25 2011 $
|
||||
.Dd $Mdocdate: July 13 2013 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -23,6 +24,9 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm mandoc
|
||||
.Op Fl V
|
||||
.Sm off
|
||||
.Op Fl I Cm os Li = Ar name
|
||||
.Sm on
|
||||
.Op Fl m Ns Ar format
|
||||
.Op Fl O Ns Ar option
|
||||
.Op Fl T Ns Ar output
|
||||
@ -49,6 +53,15 @@ output.
|
||||
.Pp
|
||||
The arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.Sm off
|
||||
.It Fl I Cm os Li = Ar name
|
||||
.Sm on
|
||||
Override the default operating system
|
||||
.Ar name
|
||||
for the
|
||||
.Xr mdoc 7
|
||||
.Sq \&Os
|
||||
macro.
|
||||
.It Fl m Ns Ar format
|
||||
Input format.
|
||||
See
|
||||
@ -334,7 +347,7 @@ for font style specification and available command-line arguments.
|
||||
Translate input format into
|
||||
.Xr man 7
|
||||
output format.
|
||||
This is useful for distributing manual sources to legancy systems
|
||||
This is useful for distributing manual sources to legacy systems
|
||||
lacking
|
||||
.Xr mdoc 7
|
||||
formatters.
|
||||
@ -637,8 +650,7 @@ lists render similarly.
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
In
|
||||
.Fl T Ns Cm html
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc.3,v 1.17 2012/01/13 15:27:14 joerg Exp $
|
||||
.\" $Id: mandoc.3,v 1.22 2013/10/06 17:01:52 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 13 2012 $
|
||||
.Dd $Mdocdate: October 6 2013 $
|
||||
.Dt MANDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -43,15 +43,15 @@
|
||||
.Nm mparse_strlevel
|
||||
.Nd mandoc macro compiler library
|
||||
.Sh LIBRARY
|
||||
.Lb mandoc
|
||||
.Lb libmandoc
|
||||
.Sh SYNOPSIS
|
||||
.In man.h
|
||||
.In mdoc.h
|
||||
.In mandoc.h
|
||||
.Ft "enum mandoc_esc"
|
||||
.Fo mandoc_escape
|
||||
.Fa "const char **end"
|
||||
.Fa "const char **start"
|
||||
.Fa "const char const **end"
|
||||
.Fa "const char const **start"
|
||||
.Fa "int *sz"
|
||||
.Fc
|
||||
.Ft "const struct man_meta *"
|
||||
@ -67,7 +67,7 @@
|
||||
.Fa "const struct man *man"
|
||||
.Fc
|
||||
.Ft "struct mchars *"
|
||||
.Fn mchars_alloc
|
||||
.Fn mchars_alloc "void"
|
||||
.Ft void
|
||||
.Fn mchars_free "struct mchars *p"
|
||||
.Ft char
|
||||
@ -86,7 +86,6 @@
|
||||
.Fa "const struct mchars *p"
|
||||
.Fa "const char *cp"
|
||||
.Fa "size_t sz"
|
||||
.Ft "const char *"
|
||||
.Fc
|
||||
.Ft "const struct mdoc_meta *"
|
||||
.Fo mdoc_meta
|
||||
@ -257,16 +256,32 @@ and
|
||||
.Va sz
|
||||
may be
|
||||
.Dv NULL .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa mandoc.c .
|
||||
.It Fn man_meta
|
||||
Obtain the meta-data of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
Declared in
|
||||
.In man.h ,
|
||||
implemented in
|
||||
.Pa man.c .
|
||||
.It Fn man_mparse
|
||||
Get the parser used for the current output.
|
||||
Declared in
|
||||
.In man.h ,
|
||||
implemented in
|
||||
.Pa man.c .
|
||||
.It Fn man_node
|
||||
Obtain the root node of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
Declared in
|
||||
.In man.h ,
|
||||
implemented in
|
||||
.Pa man.c .
|
||||
.It Fn mchars_alloc
|
||||
Allocate an
|
||||
.Vt "struct mchars *"
|
||||
@ -276,33 +291,65 @@ See
|
||||
for an overview of special characters.
|
||||
The object must be freed with
|
||||
.Fn mchars_free .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa chars.c .
|
||||
.It Fn mchars_free
|
||||
Free an object created with
|
||||
.Fn mchars_alloc .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa chars.c .
|
||||
.It Fn mchars_num2char
|
||||
Convert a character index (e.g., the \eN\(aq\(aq escape) into a
|
||||
printable ASCII character.
|
||||
Returns \e0 (the nil character) if the input sequence is malformed.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa chars.c .
|
||||
.It Fn mchars_num2uc
|
||||
Convert a hexadecimal character index (e.g., the \e[uNNNN] escape) into
|
||||
a Unicode codepoint.
|
||||
Returns \e0 (the nil character) if the input sequence is malformed.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa chars.c .
|
||||
.It Fn mchars_spec2cp
|
||||
Convert a special character into a valid Unicode codepoint.
|
||||
Returns \-1 on failure or a non-zero Unicode codepoint on success.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa chars.c .
|
||||
.It Fn mchars_spec2str
|
||||
Convert a special character into an ASCII string.
|
||||
Returns
|
||||
.Dv NULL
|
||||
on failure.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa chars.c .
|
||||
.It Fn mdoc_meta
|
||||
Obtain the meta-data of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
Declared in
|
||||
.In mdoc.h ,
|
||||
implemented in
|
||||
.Pa mdoc.c .
|
||||
.It Fn mdoc_node
|
||||
Obtain the root node of a successful parse.
|
||||
This may only be used on a pointer returned by
|
||||
.Fn mparse_result .
|
||||
Declared in
|
||||
.In mdoc.h ,
|
||||
implemented in
|
||||
.Pa mdoc.c .
|
||||
.It Fn mparse_alloc
|
||||
Allocate a parser.
|
||||
The same parser may be used for multiple files so long as
|
||||
@ -310,18 +357,34 @@ The same parser may be used for multiple files so long as
|
||||
is called between parses.
|
||||
.Fn mparse_free
|
||||
must be called to free the memory allocated by this function.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_free
|
||||
Free all memory allocated by
|
||||
.Fn mparse_alloc .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_getkeep
|
||||
Acquire the keep buffer.
|
||||
Must follow a call of
|
||||
.Fn mparse_keep .
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_keep
|
||||
Instruct the parser to retain a copy of its parsed input.
|
||||
This can be acquired with subsequent
|
||||
.Fn mparse_getkeep
|
||||
calls.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_readfd
|
||||
Parse a file or file descriptor.
|
||||
If
|
||||
@ -336,10 +399,18 @@ is assumed to be the name associated with
|
||||
This may be called multiple times with different parameters; however,
|
||||
.Fn mparse_reset
|
||||
should be invoked between parses.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_reset
|
||||
Reset a parser so that
|
||||
.Fn mparse_readfd
|
||||
may be used again.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_result
|
||||
Obtain the result of a parse.
|
||||
Only successful parses
|
||||
@ -350,10 +421,22 @@ returned less than MANDOCLEVEL_FATAL
|
||||
.Pc
|
||||
should invoke this function, in which case one of the two pointers will
|
||||
be filled in.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_strerror
|
||||
Return a statically-allocated string representation of an error code.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.It Fn mparse_strlevel
|
||||
Return a statically-allocated string representation of a level code.
|
||||
Declared in
|
||||
.In mandoc.h ,
|
||||
implemented in
|
||||
.Pa read.c .
|
||||
.El
|
||||
.Ss Variables
|
||||
.Bl -ohang
|
||||
@ -596,5 +679,4 @@ levels of badly-nested blocks.
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc.c,v 1.62 2011/12/03 16:08:51 schwarze Exp $ */
|
||||
/* $Id: mandoc.c,v 1.74 2013/12/30 18:30:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -37,83 +37,38 @@
|
||||
|
||||
static int a2time(time_t *, const char *, const char *);
|
||||
static char *time2a(time_t);
|
||||
static int numescape(const char *);
|
||||
|
||||
/*
|
||||
* Pass over recursive numerical expressions. This context of this
|
||||
* function is important: it's only called within character-terminating
|
||||
* escapes (e.g., \s[xxxyyy]), so all we need to do is handle initial
|
||||
* recursion: we don't care about what's in these blocks.
|
||||
* This returns the number of characters skipped or -1 if an error
|
||||
* occurs (the caller should bail).
|
||||
*/
|
||||
static int
|
||||
numescape(const char *start)
|
||||
{
|
||||
int i;
|
||||
size_t sz;
|
||||
const char *cp;
|
||||
|
||||
i = 0;
|
||||
|
||||
/* The expression consists of a subexpression. */
|
||||
|
||||
if ('\\' == start[i]) {
|
||||
cp = &start[++i];
|
||||
/*
|
||||
* Read past the end of the subexpression.
|
||||
* Bail immediately on errors.
|
||||
*/
|
||||
if (ESCAPE_ERROR == mandoc_escape(&cp, NULL, NULL))
|
||||
return(-1);
|
||||
return(i + cp - &start[i]);
|
||||
}
|
||||
|
||||
if ('(' != start[i++])
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* A parenthesised subexpression. Read until the closing
|
||||
* parenthesis, making sure to handle any nested subexpressions
|
||||
* that might ruin our parse.
|
||||
*/
|
||||
|
||||
while (')' != start[i]) {
|
||||
sz = strcspn(&start[i], ")\\");
|
||||
i += (int)sz;
|
||||
|
||||
if ('\0' == start[i])
|
||||
return(-1);
|
||||
else if ('\\' != start[i])
|
||||
continue;
|
||||
|
||||
cp = &start[++i];
|
||||
if (ESCAPE_ERROR == mandoc_escape(&cp, NULL, NULL))
|
||||
return(-1);
|
||||
i += cp - &start[i];
|
||||
}
|
||||
|
||||
/* Read past the terminating ')'. */
|
||||
return(++i);
|
||||
}
|
||||
|
||||
enum mandoc_esc
|
||||
mandoc_escape(const char **end, const char **start, int *sz)
|
||||
{
|
||||
char c, term, numeric;
|
||||
int i, lim, ssz, rlim;
|
||||
const char *cp, *rstart;
|
||||
const char *local_start;
|
||||
int local_sz;
|
||||
char term;
|
||||
enum mandoc_esc gly;
|
||||
|
||||
cp = *end;
|
||||
rstart = cp;
|
||||
if (start)
|
||||
*start = rstart;
|
||||
i = lim = 0;
|
||||
gly = ESCAPE_ERROR;
|
||||
term = numeric = '\0';
|
||||
/*
|
||||
* When the caller doesn't provide return storage,
|
||||
* use local storage.
|
||||
*/
|
||||
|
||||
switch ((c = cp[i++])) {
|
||||
if (NULL == start)
|
||||
start = &local_start;
|
||||
if (NULL == sz)
|
||||
sz = &local_sz;
|
||||
|
||||
/*
|
||||
* Beyond the backslash, at least one input character
|
||||
* is part of the escape sequence. With one exception
|
||||
* (see below), that character won't be returned.
|
||||
*/
|
||||
|
||||
gly = ESCAPE_ERROR;
|
||||
*start = ++*end;
|
||||
*sz = 0;
|
||||
term = '\0';
|
||||
|
||||
switch ((*start)[-1]) {
|
||||
/*
|
||||
* First the glyphs. There are several different forms of
|
||||
* these, but each eventually returns a substring of the glyph
|
||||
@ -121,7 +76,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
*/
|
||||
case ('('):
|
||||
gly = ESCAPE_SPECIAL;
|
||||
lim = 2;
|
||||
*sz = 2;
|
||||
break;
|
||||
case ('['):
|
||||
gly = ESCAPE_SPECIAL;
|
||||
@ -131,17 +86,38 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
* Unicode codepoint. Here, however, only check whether
|
||||
* it's not a zero-width escape.
|
||||
*/
|
||||
if ('u' == cp[i] && ']' != cp[i + 1])
|
||||
if ('u' == (*start)[0] && ']' != (*start)[1])
|
||||
gly = ESCAPE_UNICODE;
|
||||
term = ']';
|
||||
break;
|
||||
case ('C'):
|
||||
if ('\'' != cp[i])
|
||||
if ('\'' != **start)
|
||||
return(ESCAPE_ERROR);
|
||||
gly = ESCAPE_SPECIAL;
|
||||
*start = ++*end;
|
||||
if ('u' == (*start)[0] && '\'' != (*start)[1])
|
||||
gly = ESCAPE_UNICODE;
|
||||
else
|
||||
gly = ESCAPE_SPECIAL;
|
||||
term = '\'';
|
||||
break;
|
||||
|
||||
/*
|
||||
* Escapes taking no arguments at all.
|
||||
*/
|
||||
case ('d'):
|
||||
/* FALLTHROUGH */
|
||||
case ('u'):
|
||||
return(ESCAPE_IGNORE);
|
||||
|
||||
/*
|
||||
* The \z escape is supposed to output the following
|
||||
* character without advancing the cursor position.
|
||||
* Since we are mostly dealing with terminal mode,
|
||||
* let us just skip the next character.
|
||||
*/
|
||||
case ('z'):
|
||||
return(ESCAPE_SKIPCHAR);
|
||||
|
||||
/*
|
||||
* Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where
|
||||
* 'X' is the trigger. These have opaque sub-strings.
|
||||
@ -166,21 +142,17 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
case ('f'):
|
||||
if (ESCAPE_ERROR == gly)
|
||||
gly = ESCAPE_FONT;
|
||||
|
||||
rstart= &cp[i];
|
||||
if (start)
|
||||
*start = rstart;
|
||||
|
||||
switch (cp[i++]) {
|
||||
switch (**start) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
*start = ++*end;
|
||||
*sz = 2;
|
||||
break;
|
||||
case ('['):
|
||||
*start = ++*end;
|
||||
term = ']';
|
||||
break;
|
||||
default:
|
||||
lim = 1;
|
||||
i--;
|
||||
*sz = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -193,18 +165,23 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
/* FALLTHROUGH */
|
||||
case ('b'):
|
||||
/* FALLTHROUGH */
|
||||
case ('B'):
|
||||
/* FALLTHROUGH */
|
||||
case ('D'):
|
||||
/* FALLTHROUGH */
|
||||
case ('o'):
|
||||
/* FALLTHROUGH */
|
||||
case ('R'):
|
||||
/* FALLTHROUGH */
|
||||
case ('w'):
|
||||
/* FALLTHROUGH */
|
||||
case ('X'):
|
||||
/* FALLTHROUGH */
|
||||
case ('Z'):
|
||||
if ('\'' != cp[i++])
|
||||
if ('\'' != **start)
|
||||
return(ESCAPE_ERROR);
|
||||
gly = ESCAPE_IGNORE;
|
||||
*start = ++*end;
|
||||
term = '\'';
|
||||
break;
|
||||
|
||||
@ -212,8 +189,6 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
* These escapes are of the form \X'N', where 'X' is the trigger
|
||||
* and 'N' resolves to a numerical expression.
|
||||
*/
|
||||
case ('B'):
|
||||
/* FALLTHROUGH */
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('H'):
|
||||
@ -221,20 +196,17 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
case ('L'):
|
||||
/* FALLTHROUGH */
|
||||
case ('l'):
|
||||
gly = ESCAPE_NUMBERED;
|
||||
/* FALLTHROUGH */
|
||||
case ('S'):
|
||||
/* FALLTHROUGH */
|
||||
case ('v'):
|
||||
/* FALLTHROUGH */
|
||||
case ('w'):
|
||||
/* FALLTHROUGH */
|
||||
case ('x'):
|
||||
if (ESCAPE_ERROR == gly)
|
||||
gly = ESCAPE_IGNORE;
|
||||
if ('\'' != cp[i++])
|
||||
if ('\'' != **start)
|
||||
return(ESCAPE_ERROR);
|
||||
term = numeric = '\'';
|
||||
gly = ESCAPE_IGNORE;
|
||||
*start = ++*end;
|
||||
term = '\'';
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -242,17 +214,17 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
* XXX Do any other escapes need similar handling?
|
||||
*/
|
||||
case ('N'):
|
||||
if ('\0' == cp[i])
|
||||
if ('\0' == **start)
|
||||
return(ESCAPE_ERROR);
|
||||
*end = &cp[++i];
|
||||
if (isdigit((unsigned char)cp[i-1]))
|
||||
(*end)++;
|
||||
if (isdigit((unsigned char)**start)) {
|
||||
*sz = 1;
|
||||
return(ESCAPE_IGNORE);
|
||||
}
|
||||
(*start)++;
|
||||
while (isdigit((unsigned char)**end))
|
||||
(*end)++;
|
||||
if (start)
|
||||
*start = &cp[i];
|
||||
if (sz)
|
||||
*sz = *end - &cp[i];
|
||||
*sz = *end - *start;
|
||||
if ('\0' != **end)
|
||||
(*end)++;
|
||||
return(ESCAPE_NUMBERED);
|
||||
@ -263,122 +235,93 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
case ('s'):
|
||||
gly = ESCAPE_IGNORE;
|
||||
|
||||
rstart = &cp[i];
|
||||
if (start)
|
||||
*start = rstart;
|
||||
|
||||
/* See +/- counts as a sign. */
|
||||
c = cp[i];
|
||||
if ('+' == c || '-' == c || ASCII_HYPH == c)
|
||||
++i;
|
||||
if ('+' == **end || '-' == **end || ASCII_HYPH == **end)
|
||||
(*end)++;
|
||||
|
||||
switch (cp[i++]) {
|
||||
switch (**end) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
*start = ++*end;
|
||||
*sz = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = numeric = ']';
|
||||
*start = ++*end;
|
||||
term = ']';
|
||||
break;
|
||||
case ('\''):
|
||||
term = numeric = '\'';
|
||||
*start = ++*end;
|
||||
term = '\'';
|
||||
break;
|
||||
default:
|
||||
lim = 1;
|
||||
i--;
|
||||
*sz = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* See +/- counts as a sign. */
|
||||
c = cp[i];
|
||||
if ('+' == c || '-' == c || ASCII_HYPH == c)
|
||||
++i;
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
* Anything else is assumed to be a glyph.
|
||||
* In this case, pass back the character after the backslash.
|
||||
*/
|
||||
default:
|
||||
gly = ESCAPE_SPECIAL;
|
||||
lim = 1;
|
||||
i--;
|
||||
*start = --*end;
|
||||
*sz = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(ESCAPE_ERROR != gly);
|
||||
|
||||
rstart = &cp[i];
|
||||
if (start)
|
||||
*start = rstart;
|
||||
|
||||
/*
|
||||
* If a terminating block has been specified, we need to
|
||||
* handle the case of recursion, which could have their
|
||||
* own terminating blocks that mess up our parse. This, by the
|
||||
* way, means that the "start" and "size" values will be
|
||||
* effectively meaningless.
|
||||
*/
|
||||
|
||||
ssz = 0;
|
||||
if (numeric && -1 == (ssz = numescape(&cp[i])))
|
||||
return(ESCAPE_ERROR);
|
||||
|
||||
i += ssz;
|
||||
rlim = -1;
|
||||
|
||||
/*
|
||||
* We have a character terminator. Try to read up to that
|
||||
* character. If we can't (i.e., we hit the nil), then return
|
||||
* an error; if we can, calculate our length, read past the
|
||||
* terminating character, and exit.
|
||||
* Read up to the terminating character,
|
||||
* paying attention to nested escapes.
|
||||
*/
|
||||
|
||||
if ('\0' != term) {
|
||||
*end = strchr(&cp[i], term);
|
||||
if ('\0' == *end)
|
||||
while (**end != term) {
|
||||
switch (**end) {
|
||||
case ('\0'):
|
||||
return(ESCAPE_ERROR);
|
||||
case ('\\'):
|
||||
(*end)++;
|
||||
if (ESCAPE_ERROR ==
|
||||
mandoc_escape(end, NULL, NULL))
|
||||
return(ESCAPE_ERROR);
|
||||
break;
|
||||
default:
|
||||
(*end)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*sz = (*end)++ - *start;
|
||||
} else {
|
||||
assert(*sz > 0);
|
||||
if ((size_t)*sz > strlen(*start))
|
||||
return(ESCAPE_ERROR);
|
||||
|
||||
rlim = *end - &cp[i];
|
||||
if (sz)
|
||||
*sz = rlim;
|
||||
(*end)++;
|
||||
goto out;
|
||||
*end += *sz;
|
||||
}
|
||||
|
||||
assert(lim > 0);
|
||||
|
||||
/*
|
||||
* We have a numeric limit. If the string is shorter than that,
|
||||
* stop and return an error. Else adjust our endpoint, length,
|
||||
* and return the current glyph.
|
||||
*/
|
||||
|
||||
if ((size_t)lim > strlen(&cp[i]))
|
||||
return(ESCAPE_ERROR);
|
||||
|
||||
rlim = lim;
|
||||
if (sz)
|
||||
*sz = rlim;
|
||||
|
||||
*end = &cp[i] + lim;
|
||||
|
||||
out:
|
||||
assert(rlim >= 0 && rstart);
|
||||
|
||||
/* Run post-processors. */
|
||||
|
||||
switch (gly) {
|
||||
case (ESCAPE_FONT):
|
||||
/*
|
||||
* Pretend that the constant-width font modes are the
|
||||
* same as the regular font modes.
|
||||
*/
|
||||
if (2 == rlim && 'C' == *rstart)
|
||||
rstart++;
|
||||
else if (1 != rlim)
|
||||
if (2 == *sz) {
|
||||
if ('C' == **start) {
|
||||
/*
|
||||
* Treat constant-width font modes
|
||||
* just like regular font modes.
|
||||
*/
|
||||
(*start)++;
|
||||
(*sz)--;
|
||||
} else {
|
||||
if ('B' == (*start)[0] && 'I' == (*start)[1])
|
||||
gly = ESCAPE_FONTBI;
|
||||
break;
|
||||
}
|
||||
} else if (1 != *sz)
|
||||
break;
|
||||
|
||||
switch (*rstart) {
|
||||
switch (**start) {
|
||||
case ('3'):
|
||||
/* FALLTHROUGH */
|
||||
case ('B'):
|
||||
@ -400,9 +343,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
}
|
||||
break;
|
||||
case (ESCAPE_SPECIAL):
|
||||
if (1 != rlim)
|
||||
break;
|
||||
if ('c' == *rstart)
|
||||
if (1 == *sz && 'c' == **start)
|
||||
gly = ESCAPE_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
@ -484,10 +425,10 @@ mandoc_strdup(const char *ptr)
|
||||
* Parse a quoted or unquoted roff-style request or macro argument.
|
||||
* Return a pointer to the parsed argument, which is either the original
|
||||
* pointer or advanced by one byte in case the argument is quoted.
|
||||
* Null-terminate the argument in place.
|
||||
* NUL-terminate the argument in place.
|
||||
* Collapse pairs of quotes inside quoted arguments.
|
||||
* Advance the argument pointer to the next argument,
|
||||
* or to the null byte terminating the argument line.
|
||||
* or to the NUL byte terminating the argument line.
|
||||
*/
|
||||
char *
|
||||
mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
|
||||
@ -506,17 +447,35 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
|
||||
pairs = 0;
|
||||
white = 0;
|
||||
for (cp = start; '\0' != *cp; cp++) {
|
||||
/* Move left after quoted quotes and escaped backslashes. */
|
||||
|
||||
/*
|
||||
* Move the following text left
|
||||
* after quoted quotes and after "\\" and "\t".
|
||||
*/
|
||||
if (pairs)
|
||||
cp[-pairs] = cp[0];
|
||||
|
||||
if ('\\' == cp[0]) {
|
||||
if ('\\' == cp[1]) {
|
||||
/* Poor man's copy mode. */
|
||||
/*
|
||||
* In copy mode, translate double to single
|
||||
* backslashes and backslash-t to literal tabs.
|
||||
*/
|
||||
switch (cp[1]) {
|
||||
case ('t'):
|
||||
cp[0] = '\t';
|
||||
/* FALLTHROUGH */
|
||||
case ('\\'):
|
||||
pairs++;
|
||||
cp++;
|
||||
} else if (0 == quoted && ' ' == cp[1])
|
||||
break;
|
||||
case (' '):
|
||||
/* Skip escaped blanks. */
|
||||
cp++;
|
||||
if (0 == quoted)
|
||||
cp++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (0 == quoted) {
|
||||
if (' ' == cp[0]) {
|
||||
/* Unescaped blanks end unquoted args. */
|
||||
@ -540,7 +499,7 @@ mandoc_getarg(struct mparse *parse, char **cpp, int ln, int *pos)
|
||||
if (1 == quoted)
|
||||
mandoc_msg(MANDOCERR_BADQUOTE, parse, ln, *pos, NULL);
|
||||
|
||||
/* Null-terminate this argument and move to the next one. */
|
||||
/* NUL-terminate this argument and move to the next one. */
|
||||
if (pairs)
|
||||
cp[-pairs] = '\0';
|
||||
if ('\0' != *cp) {
|
||||
@ -677,32 +636,6 @@ mandoc_eos(const char *p, size_t sz, int enclosed)
|
||||
return(found && !enclosed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out whether a line is a macro line or not. If it is, adjust the
|
||||
* current position and return one; if it isn't, return zero and don't
|
||||
* change the current position.
|
||||
*/
|
||||
int
|
||||
mandoc_getcontrol(const char *cp, int *ppos)
|
||||
{
|
||||
int pos;
|
||||
|
||||
pos = *ppos;
|
||||
|
||||
if ('\\' == cp[pos] && '.' == cp[pos + 1])
|
||||
pos += 2;
|
||||
else if ('.' == cp[pos] || '\'' == cp[pos])
|
||||
pos++;
|
||||
else
|
||||
return(0);
|
||||
|
||||
while (' ' == cp[pos] || '\t' == cp[pos])
|
||||
pos++;
|
||||
|
||||
*ppos = pos;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string to a long that may not be <0.
|
||||
* If the string is invalid, or is less than 0, return -1.
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: mandoc.h,v 1.99 2012/02/16 20:51:31 joerg Exp $ */
|
||||
/* $Id: mandoc.h,v 1.112 2013/12/30 18:30:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -50,6 +51,7 @@ enum mandocerr {
|
||||
MANDOCERR_NOTITLE, /* no title in document */
|
||||
MANDOCERR_UPPERCASE, /* document title should be all caps */
|
||||
MANDOCERR_BADMSEC, /* unknown manual section */
|
||||
MANDOCERR_BADVOLARCH, /* unknown manual volume or arch */
|
||||
MANDOCERR_NODATE, /* date missing, using today's date */
|
||||
MANDOCERR_BADDATE, /* cannot parse date, using it verbatim */
|
||||
MANDOCERR_PROLOGOOO, /* prologue macros out of order */
|
||||
@ -61,14 +63,14 @@ enum mandocerr {
|
||||
MANDOCERR_SO, /* .so is fragile, better use ln(1) */
|
||||
MANDOCERR_NAMESECFIRST, /* NAME section must come first */
|
||||
MANDOCERR_BADNAMESEC, /* bad NAME section contents */
|
||||
MANDOCERR_NONAME, /* manual name not yet set */
|
||||
MANDOCERR_SECOOO, /* sections out of conventional order */
|
||||
MANDOCERR_SECREP, /* duplicate section name */
|
||||
MANDOCERR_SECMSEC, /* section not in conventional manual section */
|
||||
MANDOCERR_SECMSEC, /* section header suited to sections ... */
|
||||
|
||||
/* related to macros and nesting */
|
||||
MANDOCERR_MACROOBS, /* skipping obsolete macro */
|
||||
MANDOCERR_IGNPAR, /* skipping paragraph macro */
|
||||
MANDOCERR_MOVEPAR, /* moving paragraph macro out of list */
|
||||
MANDOCERR_IGNNS, /* skipping no-space macro */
|
||||
MANDOCERR_SCOPENEST, /* blocks badly nested */
|
||||
MANDOCERR_CHILD, /* child violates parent syntax */
|
||||
@ -129,10 +131,12 @@ enum mandocerr {
|
||||
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
||||
MANDOCERR_BADCHAR, /* skipping bad character */
|
||||
MANDOCERR_NAMESC, /* escaped character not allowed in a name */
|
||||
MANDOCERR_NONAME, /* manual name not yet set */
|
||||
MANDOCERR_NOTEXT, /* skipping text before the first section header */
|
||||
MANDOCERR_MACRO, /* skipping unknown macro */
|
||||
MANDOCERR_REQUEST, /* NOT IMPLEMENTED: skipping request */
|
||||
MANDOCERR_ARGCOUNT, /* argument count wrong */
|
||||
MANDOCERR_STRAYTA, /* skipping column outside column list */
|
||||
MANDOCERR_NOSCOPE, /* skipping end of block that is not open */
|
||||
MANDOCERR_SCOPEBROKEN, /* missing end of block */
|
||||
MANDOCERR_SCOPEEXIT, /* scope open on exit */
|
||||
@ -141,6 +145,7 @@ enum mandocerr {
|
||||
MANDOCERR_NOARGS, /* macro requires line argument(s) */
|
||||
MANDOCERR_NOBODY, /* macro requires body argument(s) */
|
||||
MANDOCERR_NOARGV, /* macro requires argument(s) */
|
||||
MANDOCERR_NUMERIC, /* request requires a numeric argument */
|
||||
MANDOCERR_LISTTYPE, /* missing list type */
|
||||
MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
|
||||
MANDOCERR_BODYLOST, /* body argument(s) will be lost */
|
||||
@ -160,7 +165,7 @@ enum mandocerr {
|
||||
MANDOCERR_MAX
|
||||
};
|
||||
|
||||
struct tbl {
|
||||
struct tbl_opts {
|
||||
char tab; /* cell-separator */
|
||||
char decimal; /* decimal point */
|
||||
int linesize;
|
||||
@ -175,20 +180,14 @@ struct tbl {
|
||||
int cols; /* number of columns */
|
||||
};
|
||||
|
||||
enum tbl_headt {
|
||||
TBL_HEAD_DATA, /* plug in data from tbl_dat */
|
||||
TBL_HEAD_VERT, /* vertical spacer */
|
||||
TBL_HEAD_DVERT /* double-vertical spacer */
|
||||
};
|
||||
|
||||
/*
|
||||
* The head of a table specifies all of its columns. When formatting a
|
||||
* tbl_span, iterate over these and plug in data from the tbl_span when
|
||||
* appropriate, using tbl_cell as a guide to placement.
|
||||
*/
|
||||
struct tbl_head {
|
||||
enum tbl_headt pos;
|
||||
int ident; /* 0 <= unique id < cols */
|
||||
int vert; /* width of preceding vertical line */
|
||||
struct tbl_head *next;
|
||||
struct tbl_head *prev;
|
||||
};
|
||||
@ -203,8 +202,6 @@ enum tbl_cellt {
|
||||
TBL_CELL_DOWN, /* ^ */
|
||||
TBL_CELL_HORIZ, /* _, - */
|
||||
TBL_CELL_DHORIZ, /* = */
|
||||
TBL_CELL_VERT, /* | */
|
||||
TBL_CELL_DVERT, /* || */
|
||||
TBL_CELL_MAX
|
||||
};
|
||||
|
||||
@ -213,6 +210,7 @@ enum tbl_cellt {
|
||||
*/
|
||||
struct tbl_cell {
|
||||
struct tbl_cell *next;
|
||||
int vert; /* width of preceding vertical line */
|
||||
enum tbl_cellt pos;
|
||||
size_t spacing;
|
||||
int flags;
|
||||
@ -266,7 +264,7 @@ enum tbl_spant {
|
||||
* A row of data in a table.
|
||||
*/
|
||||
struct tbl_span {
|
||||
struct tbl *tbl;
|
||||
struct tbl_opts *opts;
|
||||
struct tbl_head *head;
|
||||
struct tbl_row *layout; /* layout row */
|
||||
struct tbl_dat *first;
|
||||
@ -382,11 +380,13 @@ enum mandoc_esc {
|
||||
ESCAPE_FONT, /* a generic font mode */
|
||||
ESCAPE_FONTBOLD, /* bold font mode */
|
||||
ESCAPE_FONTITALIC, /* italic font mode */
|
||||
ESCAPE_FONTBI, /* bold italic font mode */
|
||||
ESCAPE_FONTROMAN, /* roman font mode */
|
||||
ESCAPE_FONTPREV, /* previous font mode */
|
||||
ESCAPE_NUMBERED, /* a numbered glyph */
|
||||
ESCAPE_UNICODE, /* a unicode codepoint */
|
||||
ESCAPE_NOSPACE /* suppress space if the last on a line */
|
||||
ESCAPE_NOSPACE, /* suppress space if the last on a line */
|
||||
ESCAPE_SKIPCHAR /* skip the next character */
|
||||
};
|
||||
|
||||
typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel,
|
||||
@ -413,8 +413,8 @@ int mchars_spec2cp(const struct mchars *,
|
||||
const char *, size_t);
|
||||
const char *mchars_spec2str(const struct mchars *,
|
||||
const char *, size_t, size_t *);
|
||||
struct mparse *mparse_alloc(enum mparset,
|
||||
enum mandoclevel, mandocmsg, void *);
|
||||
struct mparse *mparse_alloc(enum mparset, enum mandoclevel,
|
||||
mandocmsg, void *, char *);
|
||||
void mparse_free(struct mparse *);
|
||||
void mparse_keep(struct mparse *);
|
||||
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_char.7,v 1.51 2011/11/23 10:09:30 kristaps Exp $
|
||||
.\" $Id: mandoc_char.7,v 1.56 2013/12/26 17:23:42 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: November 23 2011 $
|
||||
.Dd $Mdocdate: December 26 2013 $
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -98,26 +98,27 @@ in literal context, and when none of the following special cases apply,
|
||||
just use the normal space character
|
||||
.Pq Sq \ .
|
||||
.Pp
|
||||
When filling text, lines may be broken between words, i.e. at space
|
||||
When filling text, output lines may be broken between words, i.e. at space
|
||||
characters.
|
||||
To prevent a line break between two particular words,
|
||||
use the non-breaking space escape sequence
|
||||
.Pq Sq \e~
|
||||
use the unpaddable non-breaking space escape sequence
|
||||
.Pq Sq \e\ \&
|
||||
instead of the normal space character.
|
||||
For example, the input string
|
||||
.Dq number\e~1
|
||||
.Dq number\e\ 1
|
||||
will be kept together as
|
||||
.Dq number\~1
|
||||
.Dq number\ 1
|
||||
on the same output line.
|
||||
.Pp
|
||||
On request and macro lines, the normal space character serves as an
|
||||
argument delimiter.
|
||||
To include whitespace into arguments, quoting is usually the best choice.
|
||||
In some cases, using either the non-breaking
|
||||
.Pq Sq \e~
|
||||
or the breaking
|
||||
To include whitespace into arguments, quoting is usually the best choice;
|
||||
see the MACRO SYNTAX section in
|
||||
.Xr roff 7 .
|
||||
In some cases, using the non-breaking space escape sequence
|
||||
.Pq Sq \e\ \&
|
||||
space escape sequence may be preferable.
|
||||
may be preferable.
|
||||
.Pp
|
||||
To escape macro names and to protect whitespace at the end
|
||||
of input lines, the zero-width space
|
||||
.Pq Sq \e&
|
||||
@ -194,14 +195,13 @@ manual.
|
||||
Spacing:
|
||||
.Bl -column "Input" "Description" -offset indent -compact
|
||||
.It Em Input Ta Em Description
|
||||
.It \e~ Ta non-breaking, non-collapsing space
|
||||
.It \e Ta breaking, non-collapsing n-width space
|
||||
.It \e^ Ta zero-width space
|
||||
.It \e% Ta zero-width space
|
||||
.It Sq \e\ \& Ta unpaddable non-breaking space
|
||||
.It \e~ Ta paddable non-breaking space
|
||||
.It \e0 Ta unpaddable, breaking digit-width space
|
||||
.It \e| Ta one-sixth \e(em narrow space, zero width in nroff mode
|
||||
.It \e^ Ta one-twelfth \e(em half-narrow space, zero width in nroff
|
||||
.It \e& Ta zero-width space
|
||||
.It \e| Ta zero-width space
|
||||
.It \e0 Ta breaking, non-collapsing digit-width space
|
||||
.It \ec Ta removes any trailing space (if applicable)
|
||||
.It \e% Ta zero-width space allowing hyphenation
|
||||
.El
|
||||
.Pp
|
||||
Lines:
|
||||
@ -655,13 +655,18 @@ manual.
|
||||
.It \e*(Ai Ta \*(Ai Ta ANSI standard name
|
||||
.El
|
||||
.Sh UNICODE CHARACTERS
|
||||
The escape sequence
|
||||
The escape sequences
|
||||
.Pp
|
||||
.Dl \e[uXXXX]
|
||||
.Dl \e[uXXXX] and \eC'uXXXX'
|
||||
.Pp
|
||||
is interpreted as a Unicode codepoint.
|
||||
are interpreted as Unicode codepoints.
|
||||
The codepoint must be in the range above U+0080 and less than U+10FFFF.
|
||||
For compatibility, points must be zero-padded to four characters; if
|
||||
For compatibility, the hexadecimal digits
|
||||
.Sq A
|
||||
to
|
||||
.Sq F
|
||||
must be given as uppercase characters,
|
||||
and points must be zero-padded to four characters; if
|
||||
greater than four characters, no zero padding is allowed.
|
||||
Unicode surrogates are not allowed.
|
||||
.\" .Pp
|
||||
@ -684,7 +689,7 @@ For example, do not use \eN'34', use \e(dq, or even the plain
|
||||
.Sq \(dq
|
||||
character where possible.
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility between mandoc and other other
|
||||
This section documents compatibility between mandoc and other
|
||||
troff implementations, at this time limited to GNU troff
|
||||
.Pq Qq groff .
|
||||
.Pp
|
||||
@ -728,12 +733,11 @@ known representation.
|
||||
The
|
||||
.Nm
|
||||
manual page was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
The
|
||||
The predefined string
|
||||
.Sq \e*(Ba
|
||||
escape mimics the behaviour of the
|
||||
mimics the behaviour of the
|
||||
.Sq \&|
|
||||
character in
|
||||
.Xr mdoc 7 ;
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: mdoc.7,v 1.214 2012/01/03 10:18:05 kristaps Exp $
|
||||
.\" $Id: mdoc.7,v 1.223 2013/12/25 14:09:32 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 3 2012 $
|
||||
.Dd $Mdocdate: December 25 2013 $
|
||||
.Dt MDOC 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -477,6 +477,7 @@ in the alphabetical
|
||||
.Bl -column "Brq, Bro, Brc" description
|
||||
.It Sx \&Lb Ta function library (one argument)
|
||||
.It Sx \&In Ta include file (one argument)
|
||||
.It Sx \&Fd Ta other preprocessor directive (>0 arguments)
|
||||
.It Sx \&Ft Ta function type (>0 arguments)
|
||||
.It Sx \&Fo , \&Fc Ta function block: Ar funcname
|
||||
.It Sx \&Fn Ta function name:
|
||||
@ -657,7 +658,7 @@ for all other author listings.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.An -nosplit
|
||||
.Dl \&.An Kristaps Dzonsons \&Aq kristaps@bsd.lv
|
||||
.Dl \&.An Kristaps Dzonsons \&Aq \&Mt kristaps@bsd.lv
|
||||
.Ss \&Ao
|
||||
Begin a block enclosed by angle brackets.
|
||||
Does not have any head arguments.
|
||||
@ -711,7 +712,9 @@ for fixed strings to be passed verbatim as arguments, use
|
||||
or
|
||||
.Sx \&Cm .
|
||||
.Ss \&At
|
||||
Formats an AT&T version.
|
||||
Formats an
|
||||
.At
|
||||
version.
|
||||
Accepts one optional argument:
|
||||
.Pp
|
||||
.Bl -tag -width "v[1-7] | 32vX" -offset indent -compact
|
||||
@ -820,8 +823,8 @@ The most popular is the imaginary macro
|
||||
which resolves to
|
||||
.Sy 6n .
|
||||
.It
|
||||
A width using the syntax described in
|
||||
.Sx Scaling Widths .
|
||||
A scaling width as described in
|
||||
.Xr roff 7 .
|
||||
.It
|
||||
An arbitrary string, which indents by the length of this string.
|
||||
.El
|
||||
@ -926,8 +929,8 @@ The
|
||||
.Fl width
|
||||
and
|
||||
.Fl offset
|
||||
arguments accept
|
||||
.Sx Scaling Widths
|
||||
arguments accept scaling widths as described in
|
||||
.Xr roff 7
|
||||
or use the length of the given string.
|
||||
The
|
||||
.Fl offset
|
||||
@ -956,9 +959,9 @@ A columnated list.
|
||||
The
|
||||
.Fl width
|
||||
argument has no effect; instead, each argument specifies the width
|
||||
of one column, using either the
|
||||
.Sx Scaling Widths
|
||||
syntax or the string length of the argument.
|
||||
of one column, using either the scaling width syntax described in
|
||||
.Xr roff 7
|
||||
or the string length of the argument.
|
||||
If the first line of the body of a
|
||||
.Fl column
|
||||
list is not an
|
||||
@ -1089,7 +1092,9 @@ Examples:
|
||||
See also
|
||||
.Sx \&Bro .
|
||||
.Ss \&Bsx
|
||||
Format the BSD/OS version provided as an argument, or a default value if
|
||||
Format the
|
||||
.Bsx
|
||||
version provided as an argument, or a default value if
|
||||
no argument is provided.
|
||||
.Pp
|
||||
Examples:
|
||||
@ -1109,7 +1114,9 @@ and
|
||||
Prints
|
||||
.Dq is currently in beta test.
|
||||
.Ss \&Bx
|
||||
Format the BSD version provided as an argument, or a default value if no
|
||||
Format the
|
||||
.Bx
|
||||
version provided as an argument, or a default value if no
|
||||
argument is provided.
|
||||
.Pp
|
||||
Examples:
|
||||
@ -1401,11 +1408,16 @@ See also
|
||||
.Sx \&Er
|
||||
and
|
||||
.Sx \&Ev
|
||||
for special-purpose constants and
|
||||
for special-purpose constants,
|
||||
.Sx \&Va
|
||||
for variable symbols.
|
||||
for variable symbols, and
|
||||
.Sx \&Fd
|
||||
for listing preprocessor variable definitions in the
|
||||
.Em SYNOPSIS .
|
||||
.Ss \&Dx
|
||||
Format the DragonFly BSD version provided as an argument, or a default
|
||||
Format the
|
||||
.Dx
|
||||
version provided as an argument, or a default
|
||||
value if no argument is provided.
|
||||
.Pp
|
||||
Examples:
|
||||
@ -1562,15 +1574,32 @@ See also
|
||||
End a function context started by
|
||||
.Sx \&Fo .
|
||||
.Ss \&Fd
|
||||
Historically used to document include files.
|
||||
This usage has been deprecated in favour of
|
||||
Preprocessor directive, in particular for listing it in the
|
||||
.Em SYNOPSIS .
|
||||
Historically, it was also used to document include files.
|
||||
The latter usage has been deprecated in favour of
|
||||
.Sx \&In .
|
||||
Do not use this macro.
|
||||
.Pp
|
||||
Its syntax is as follows:
|
||||
.Bd -ragged -offset indent
|
||||
.Pf \. Sx \&Fd
|
||||
.Li # Ns Ar directive
|
||||
.Op Ar argument ...
|
||||
.Ed
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Fd #define sa_handler __sigaction_u.__sa_handler
|
||||
.Dl \&.Fd #define SIO_MAXNFDS
|
||||
.Dl \&.Fd #ifdef FS_DEBUG
|
||||
.Dl \&.Ft void
|
||||
.Dl \&.Fn dbg_open \(dqconst char *\(dq
|
||||
.Dl \&.Fd #endif
|
||||
.Pp
|
||||
See also
|
||||
.Sx MANUAL STRUCTURE
|
||||
.Sx MANUAL STRUCTURE ,
|
||||
.Sx \&In ,
|
||||
and
|
||||
.Sx \&In .
|
||||
.Sx \&Dv .
|
||||
.Ss \&Fl
|
||||
Command-line flag or option.
|
||||
Used when listing arguments to command-line utilities.
|
||||
@ -1851,7 +1880,7 @@ section as described in
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Lb libz
|
||||
.Dl \&.Lb mdoc
|
||||
.Dl \&.Lb libmandoc
|
||||
.Ss \&Li
|
||||
Denotes text that should be in a
|
||||
.Li literal
|
||||
@ -1902,6 +1931,7 @@ Its syntax is as follows:
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Mt discuss@manpages.bsd.lv
|
||||
.Dl \&.An Kristaps Dzonsons \&Aq \&Mt kristaps@bsd.lv
|
||||
.Ss \&Nd
|
||||
A one line description of the manual's content.
|
||||
This may only be invoked in the
|
||||
@ -2083,7 +2113,7 @@ This macro is obsolete and not implemented in
|
||||
.Xr mandoc 1 .
|
||||
.Pp
|
||||
Historical
|
||||
.Xr mdoc 7
|
||||
.Nm
|
||||
packages described it as
|
||||
.Dq "old function type (FORTRAN)" .
|
||||
.Ss \&Ox
|
||||
@ -2347,20 +2377,26 @@ The following standards are recognised:
|
||||
.St -p1003.1b-93
|
||||
.It \-p1003.1c-95
|
||||
.St -p1003.1c-95
|
||||
.It \-p1003.1d-99
|
||||
.St -p1003.1d-99
|
||||
.It \-p1003.1g-2000
|
||||
.St -p1003.1g-2000
|
||||
.It \-p1003.1i-95
|
||||
.St -p1003.1i-95
|
||||
.It \-p1003.1j-2000
|
||||
.St -p1003.1j-2000
|
||||
.It \-p1003.1q-2000
|
||||
.St -p1003.1q-2000
|
||||
.It \-p1003.2
|
||||
.St -p1003.2
|
||||
.It \-p1003.2-92
|
||||
.St -p1003.2-92
|
||||
.It \-p1003.2a-92
|
||||
.St -p1003.2a-92
|
||||
.It \-p1387.2-95
|
||||
.St -p1387.2-95
|
||||
.It \-p1003.2
|
||||
.St -p1003.2
|
||||
.It \-p1387.2
|
||||
.St -p1387.2
|
||||
.It \-p1387.2-95
|
||||
.St -p1387.2-95
|
||||
.It \-isoC
|
||||
.St -isoC
|
||||
.It \-isoC-90
|
||||
@ -2407,6 +2443,8 @@ The following standards are recognised:
|
||||
.St -xbd5
|
||||
.It \-xcu5
|
||||
.St -xcu5
|
||||
.It \-xsh4.2
|
||||
.St -xsh4.2
|
||||
.It \-xsh5
|
||||
.St -xsh5
|
||||
.It \-xns5
|
||||
@ -2467,7 +2505,9 @@ Examples:
|
||||
Prints out
|
||||
.Dq currently under development.
|
||||
.Ss \&Ux
|
||||
Format the UNIX name.
|
||||
Format the
|
||||
.Ux
|
||||
name.
|
||||
Accepts no argument.
|
||||
.Pp
|
||||
Examples:
|
||||
@ -2532,20 +2572,14 @@ Link to another manual
|
||||
.Pq Qq cross-reference .
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Sx \&Xr Ar name section
|
||||
.D1 Pf \. Sx \&Xr Ar name Op section
|
||||
.Pp
|
||||
The
|
||||
Cross reference the
|
||||
.Ar name
|
||||
and
|
||||
.Ar section
|
||||
are the name and section of the linked manual.
|
||||
If
|
||||
.Ar section
|
||||
is followed by non-punctuation, an
|
||||
.Sx \&Ns
|
||||
is inserted into the token stream.
|
||||
This behaviour is for compatibility with
|
||||
GNU troff.
|
||||
number of another man page;
|
||||
omitting the section number is rarely useful.
|
||||
.Pp
|
||||
Examples:
|
||||
.Dl \&.Xr mandoc 1
|
||||
@ -2569,8 +2603,8 @@ Its syntax is as follows:
|
||||
.Pp
|
||||
The
|
||||
.Ar height
|
||||
argument must be formatted as described in
|
||||
.Sx Scaling Widths .
|
||||
argument is a scaling width as described in
|
||||
.Xr roff 7 .
|
||||
If unspecified,
|
||||
.Sx \&sp
|
||||
asserts a single vertical space.
|
||||
@ -2964,7 +2998,7 @@ Manually switching the font using the
|
||||
.Ql \ef
|
||||
font escape sequences is never required.
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility between mandoc and other other
|
||||
This section documents compatibility between mandoc and other
|
||||
troff implementations, at this time limited to GNU troff
|
||||
.Pq Qq groff .
|
||||
The term
|
||||
@ -3168,5 +3202,4 @@ utility written by Kristaps Dzonsons appeared in
|
||||
The
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc.c,v 1.196 2011/09/30 00:13:28 schwarze Exp $ */
|
||||
/* $Id: mdoc.c,v 1.206 2013/12/24 19:11:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -104,20 +104,20 @@ static int mdoc_ptext(struct mdoc *, int, char *, int);
|
||||
static int mdoc_pmacro(struct mdoc *, int, char *, int);
|
||||
|
||||
const struct mdoc_node *
|
||||
mdoc_node(const struct mdoc *m)
|
||||
mdoc_node(const struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
return(m->first);
|
||||
assert( ! (MDOC_HALT & mdoc->flags));
|
||||
return(mdoc->first);
|
||||
}
|
||||
|
||||
|
||||
const struct mdoc_meta *
|
||||
mdoc_meta(const struct mdoc *m)
|
||||
mdoc_meta(const struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
return(&m->meta);
|
||||
assert( ! (MDOC_HALT & mdoc->flags));
|
||||
return(&mdoc->meta);
|
||||
}
|
||||
|
||||
|
||||
@ -197,13 +197,14 @@ mdoc_free(struct mdoc *mdoc)
|
||||
* Allocate volatile and non-volatile parse resources.
|
||||
*/
|
||||
struct mdoc *
|
||||
mdoc_alloc(struct roff *roff, struct mparse *parse)
|
||||
mdoc_alloc(struct roff *roff, struct mparse *parse, char *defos)
|
||||
{
|
||||
struct mdoc *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct mdoc));
|
||||
|
||||
p->parse = parse;
|
||||
p->defos = defos;
|
||||
p->roff = roff;
|
||||
|
||||
mdoc_hash_init();
|
||||
@ -217,61 +218,61 @@ mdoc_alloc(struct roff *roff, struct mparse *parse)
|
||||
* through to macro_end() in macro.c.
|
||||
*/
|
||||
int
|
||||
mdoc_endparse(struct mdoc *m)
|
||||
mdoc_endparse(struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
if (mdoc_macroend(m))
|
||||
assert( ! (MDOC_HALT & mdoc->flags));
|
||||
if (mdoc_macroend(mdoc))
|
||||
return(1);
|
||||
m->flags |= MDOC_HALT;
|
||||
mdoc->flags |= MDOC_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
mdoc_addeqn(struct mdoc *m, const struct eqn *ep)
|
||||
mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
assert( ! (MDOC_HALT & mdoc->flags));
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
mdoc_pmsg(m, ep->ln, ep->pos, MANDOCERR_NOTEXT);
|
||||
if (SEC_NONE == mdoc->lastnamed) {
|
||||
mdoc_pmsg(mdoc, ep->ln, ep->pos, MANDOCERR_NOTEXT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
n = node_alloc(m, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
|
||||
n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
|
||||
n->eqn = ep;
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
if ( ! node_append(mdoc, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
mdoc_addspan(struct mdoc *m, const struct tbl_span *sp)
|
||||
mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
assert( ! (MDOC_HALT & mdoc->flags));
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
mdoc_pmsg(m, sp->line, 0, MANDOCERR_NOTEXT);
|
||||
if (SEC_NONE == mdoc->lastnamed) {
|
||||
mdoc_pmsg(mdoc, sp->line, 0, MANDOCERR_NOTEXT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
n = node_alloc(m, sp->line, 0, MDOC_MAX, MDOC_TBL);
|
||||
n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, MDOC_TBL);
|
||||
n->span = sp;
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
if ( ! node_append(mdoc, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -281,12 +282,12 @@ mdoc_addspan(struct mdoc *m, const struct tbl_span *sp)
|
||||
* the macro (mdoc_pmacro()) or text parser (mdoc_ptext()).
|
||||
*/
|
||||
int
|
||||
mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs)
|
||||
mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
assert( ! (MDOC_HALT & mdoc->flags));
|
||||
|
||||
m->flags |= MDOC_NEWLINE;
|
||||
mdoc->flags |= MDOC_NEWLINE;
|
||||
|
||||
/*
|
||||
* Let the roff nS register switch SYNOPSIS mode early,
|
||||
@ -294,16 +295,14 @@ mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs)
|
||||
* whether this mode is on or off.
|
||||
* Note that this mode is also switched by the Sh macro.
|
||||
*/
|
||||
if (roff_regisset(m->roff, REG_nS)) {
|
||||
if (roff_regget(m->roff, REG_nS))
|
||||
m->flags |= MDOC_SYNOPSIS;
|
||||
else
|
||||
m->flags &= ~MDOC_SYNOPSIS;
|
||||
}
|
||||
if (roff_getreg(mdoc->roff, "nS"))
|
||||
mdoc->flags |= MDOC_SYNOPSIS;
|
||||
else
|
||||
mdoc->flags &= ~MDOC_SYNOPSIS;
|
||||
|
||||
return(mandoc_getcontrol(buf, &offs) ?
|
||||
mdoc_pmacro(m, ln, buf, offs) :
|
||||
mdoc_ptext(m, ln, buf, offs));
|
||||
return(roff_getcontrol(mdoc->roff, buf, &offs) ?
|
||||
mdoc_pmacro(mdoc, ln, buf, offs) :
|
||||
mdoc_ptext(mdoc, ln, buf, offs));
|
||||
}
|
||||
|
||||
int
|
||||
@ -314,31 +313,31 @@ mdoc_macro(MACRO_PROT_ARGS)
|
||||
/* If we're in the body, deny prologue calls. */
|
||||
|
||||
if (MDOC_PROLOGUE & mdoc_macros[tok].flags &&
|
||||
MDOC_PBODY & m->flags) {
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_BADBODY);
|
||||
MDOC_PBODY & mdoc->flags) {
|
||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADBODY);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* If we're in the prologue, deny "body" macros. */
|
||||
|
||||
if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) &&
|
||||
! (MDOC_PBODY & m->flags)) {
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_BADPROLOG);
|
||||
if (NULL == m->meta.msec)
|
||||
m->meta.msec = mandoc_strdup("1");
|
||||
if (NULL == m->meta.title)
|
||||
m->meta.title = mandoc_strdup("UNKNOWN");
|
||||
if (NULL == m->meta.vol)
|
||||
m->meta.vol = mandoc_strdup("LOCAL");
|
||||
if (NULL == m->meta.os)
|
||||
m->meta.os = mandoc_strdup("LOCAL");
|
||||
if (NULL == m->meta.date)
|
||||
m->meta.date = mandoc_normdate
|
||||
(m->parse, NULL, line, ppos);
|
||||
m->flags |= MDOC_PBODY;
|
||||
! (MDOC_PBODY & mdoc->flags)) {
|
||||
mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADPROLOG);
|
||||
if (NULL == mdoc->meta.msec)
|
||||
mdoc->meta.msec = mandoc_strdup("1");
|
||||
if (NULL == mdoc->meta.title)
|
||||
mdoc->meta.title = mandoc_strdup("UNKNOWN");
|
||||
if (NULL == mdoc->meta.vol)
|
||||
mdoc->meta.vol = mandoc_strdup("LOCAL");
|
||||
if (NULL == mdoc->meta.os)
|
||||
mdoc->meta.os = mandoc_strdup("LOCAL");
|
||||
if (NULL == mdoc->meta.date)
|
||||
mdoc->meta.date = mandoc_normdate
|
||||
(mdoc->parse, NULL, line, ppos);
|
||||
mdoc->flags |= MDOC_PBODY;
|
||||
}
|
||||
|
||||
return((*mdoc_macros[tok].fp)(m, tok, line, ppos, pos, buf));
|
||||
return((*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf));
|
||||
}
|
||||
|
||||
|
||||
@ -374,6 +373,8 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
||||
|
||||
switch (p->type) {
|
||||
case (MDOC_BODY):
|
||||
if (ENDBODY_NOT != p->end)
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_TAIL):
|
||||
/* FALLTHROUGH */
|
||||
@ -424,97 +425,99 @@ node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
||||
|
||||
|
||||
static struct mdoc_node *
|
||||
node_alloc(struct mdoc *m, int line, int pos,
|
||||
node_alloc(struct mdoc *mdoc, int line, int pos,
|
||||
enum mdoct tok, enum mdoc_type type)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct mdoc_node));
|
||||
p->sec = m->lastsec;
|
||||
p->sec = mdoc->lastsec;
|
||||
p->line = line;
|
||||
p->pos = pos;
|
||||
p->lastline = line;
|
||||
p->tok = tok;
|
||||
p->type = type;
|
||||
|
||||
/* Flag analysis. */
|
||||
|
||||
if (MDOC_SYNOPSIS & m->flags)
|
||||
if (MDOC_SYNOPSIS & mdoc->flags)
|
||||
p->flags |= MDOC_SYNPRETTY;
|
||||
else
|
||||
p->flags &= ~MDOC_SYNPRETTY;
|
||||
if (MDOC_NEWLINE & m->flags)
|
||||
if (MDOC_NEWLINE & mdoc->flags)
|
||||
p->flags |= MDOC_LINE;
|
||||
m->flags &= ~MDOC_NEWLINE;
|
||||
mdoc->flags &= ~MDOC_NEWLINE;
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_tail_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
|
||||
mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_TAIL);
|
||||
if ( ! node_append(m, p))
|
||||
p = node_alloc(mdoc, line, pos, tok, MDOC_TAIL);
|
||||
if ( ! node_append(mdoc, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_head_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
|
||||
mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
assert(m->first);
|
||||
assert(m->last);
|
||||
assert(mdoc->first);
|
||||
assert(mdoc->last);
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_HEAD);
|
||||
if ( ! node_append(m, p))
|
||||
p = node_alloc(mdoc, line, pos, tok, MDOC_HEAD);
|
||||
if ( ! node_append(mdoc, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_body_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
|
||||
mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_BODY);
|
||||
if ( ! node_append(m, p))
|
||||
p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
|
||||
if ( ! node_append(mdoc, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_endbody_alloc(struct mdoc *m, int line, int pos, enum mdoct tok,
|
||||
mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
|
||||
struct mdoc_node *body, enum mdoc_endbody end)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_BODY);
|
||||
p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
|
||||
p->pending = body;
|
||||
p->norm = body->norm;
|
||||
p->end = end;
|
||||
if ( ! node_append(m, p))
|
||||
if ( ! node_append(mdoc, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_block_alloc(struct mdoc *m, int line, int pos,
|
||||
mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
|
||||
enum mdoct tok, struct mdoc_arg *args)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_BLOCK);
|
||||
p = node_alloc(mdoc, line, pos, tok, MDOC_BLOCK);
|
||||
p->args = args;
|
||||
if (p->args)
|
||||
(args->refcnt)++;
|
||||
@ -533,20 +536,20 @@ mdoc_block_alloc(struct mdoc *m, int line, int pos,
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! node_append(m, p))
|
||||
if ( ! node_append(mdoc, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_elem_alloc(struct mdoc *m, int line, int pos,
|
||||
mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos,
|
||||
enum mdoct tok, struct mdoc_arg *args)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_ELEM);
|
||||
p = node_alloc(mdoc, line, pos, tok, MDOC_ELEM);
|
||||
p->args = args;
|
||||
if (p->args)
|
||||
(args->refcnt)++;
|
||||
@ -559,27 +562,44 @@ mdoc_elem_alloc(struct mdoc *m, int line, int pos,
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! node_append(m, p))
|
||||
if ( ! node_append(mdoc, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p)
|
||||
mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
n = node_alloc(m, line, pos, MDOC_MAX, MDOC_TEXT);
|
||||
n->string = roff_strdup(m->roff, p);
|
||||
n = node_alloc(mdoc, line, pos, MDOC_MAX, MDOC_TEXT);
|
||||
n->string = roff_strdup(mdoc->roff, p);
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
if ( ! node_append(mdoc, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
mdoc_word_append(struct mdoc *mdoc, const char *p)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
char *addstr, *newstr;
|
||||
|
||||
n = mdoc->last;
|
||||
addstr = roff_strdup(mdoc->roff, p);
|
||||
if (-1 == asprintf(&newstr, "%s %s", n->string, addstr)) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
free(addstr);
|
||||
free(n->string);
|
||||
n->string = newstr;
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
}
|
||||
|
||||
static void
|
||||
mdoc_node_free(struct mdoc_node *p)
|
||||
@ -596,7 +616,7 @@ mdoc_node_free(struct mdoc_node *p)
|
||||
|
||||
|
||||
static void
|
||||
mdoc_node_unlink(struct mdoc *m, struct mdoc_node *n)
|
||||
mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n)
|
||||
{
|
||||
|
||||
/* Adjust siblings. */
|
||||
@ -618,35 +638,43 @@ mdoc_node_unlink(struct mdoc *m, struct mdoc_node *n)
|
||||
|
||||
/* Adjust parse point, if applicable. */
|
||||
|
||||
if (m && m->last == n) {
|
||||
if (mdoc && mdoc->last == n) {
|
||||
if (n->prev) {
|
||||
m->last = n->prev;
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
mdoc->last = n->prev;
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
} else {
|
||||
m->last = n->parent;
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
mdoc->last = n->parent;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
}
|
||||
}
|
||||
|
||||
if (m && m->first == n)
|
||||
m->first = NULL;
|
||||
if (mdoc && mdoc->first == n)
|
||||
mdoc->first = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
|
||||
mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p)
|
||||
{
|
||||
|
||||
while (p->child) {
|
||||
assert(p->nchild);
|
||||
mdoc_node_delete(m, p->child);
|
||||
mdoc_node_delete(mdoc, p->child);
|
||||
}
|
||||
assert(0 == p->nchild);
|
||||
|
||||
mdoc_node_unlink(m, p);
|
||||
mdoc_node_unlink(mdoc, p);
|
||||
mdoc_node_free(p);
|
||||
}
|
||||
|
||||
int
|
||||
mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p)
|
||||
{
|
||||
|
||||
mdoc_node_unlink(mdoc, p);
|
||||
return(node_append(mdoc, p));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Pre-treat a text line.
|
||||
@ -658,7 +686,7 @@ mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
|
||||
* the end-of-line, i.e., will re-enter in the next roff parse.
|
||||
*/
|
||||
static int
|
||||
mdoc_preptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
mdoc_preptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
||||
{
|
||||
char *start, *end;
|
||||
char delim;
|
||||
@ -666,12 +694,12 @@ mdoc_preptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
while ('\0' != buf[offs]) {
|
||||
/* Mark starting position if eqn is set. */
|
||||
start = NULL;
|
||||
if ('\0' != (delim = roff_eqndelim(m->roff)))
|
||||
if ('\0' != (delim = roff_eqndelim(mdoc->roff)))
|
||||
if (NULL != (start = strchr(buf + offs, delim)))
|
||||
*start++ = '\0';
|
||||
|
||||
/* Parse text as normal. */
|
||||
if ( ! mdoc_ptext(m, line, buf, offs))
|
||||
if ( ! mdoc_ptext(mdoc, line, buf, offs))
|
||||
return(0);
|
||||
|
||||
/* Continue only if an equation exists. */
|
||||
@ -688,11 +716,11 @@ mdoc_preptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
}
|
||||
|
||||
/* Parse the equation itself. */
|
||||
roff_openeqn(m->roff, NULL, line, offs, buf);
|
||||
roff_openeqn(mdoc->roff, NULL, line, offs, buf);
|
||||
|
||||
/* Process a finished equation? */
|
||||
if (roff_closeeqn(m->roff))
|
||||
if ( ! mdoc_addeqn(m, roff_eqn(m->roff)))
|
||||
if (roff_closeeqn(mdoc->roff))
|
||||
if ( ! mdoc_addeqn(mdoc, roff_eqn(mdoc->roff)))
|
||||
return(0);
|
||||
offs += (end - (buf + offs));
|
||||
}
|
||||
@ -706,20 +734,20 @@ mdoc_preptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
* control character.
|
||||
*/
|
||||
static int
|
||||
mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
|
||||
{
|
||||
char *c, *ws, *end;
|
||||
struct mdoc_node *n;
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
mdoc_pmsg(m, line, offs, MANDOCERR_NOTEXT);
|
||||
if (SEC_NONE == mdoc->lastnamed) {
|
||||
mdoc_pmsg(mdoc, line, offs, MANDOCERR_NOTEXT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
assert(m->last);
|
||||
n = m->last;
|
||||
assert(mdoc->last);
|
||||
n = mdoc->last;
|
||||
|
||||
/*
|
||||
* Divert directly to list processing if we're encountering a
|
||||
@ -731,8 +759,8 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
|
||||
LIST_column == n->norm->Bl.type) {
|
||||
/* `Bl' is open without any children. */
|
||||
m->flags |= MDOC_FREECOL;
|
||||
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf));
|
||||
}
|
||||
|
||||
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
|
||||
@ -740,8 +768,8 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
MDOC_Bl == n->parent->tok &&
|
||||
LIST_column == n->parent->norm->Bl.type) {
|
||||
/* `Bl' has block-level `It' children. */
|
||||
m->flags |= MDOC_FREECOL;
|
||||
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -769,7 +797,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
* Strip trailing tabs in literal context only;
|
||||
* outside, they affect the next line.
|
||||
*/
|
||||
if (MDOC_LITERAL & m->flags)
|
||||
if (MDOC_LITERAL & mdoc->flags)
|
||||
continue;
|
||||
break;
|
||||
case '\\':
|
||||
@ -786,27 +814,28 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
*end = '\0';
|
||||
|
||||
if (ws)
|
||||
mdoc_pmsg(m, line, (int)(ws-buf), MANDOCERR_EOLNSPACE);
|
||||
mdoc_pmsg(mdoc, line, (int)(ws-buf), MANDOCERR_EOLNSPACE);
|
||||
|
||||
if ('\0' == buf[offs] && ! (MDOC_LITERAL & m->flags)) {
|
||||
mdoc_pmsg(m, line, (int)(c-buf), MANDOCERR_NOBLANKLN);
|
||||
if ('\0' == buf[offs] && ! (MDOC_LITERAL & mdoc->flags)) {
|
||||
mdoc_pmsg(mdoc, line, (int)(c-buf), MANDOCERR_NOBLANKLN);
|
||||
|
||||
/*
|
||||
* Insert a `sp' in the case of a blank line. Technically,
|
||||
* blank lines aren't allowed, but enough manuals assume this
|
||||
* behaviour that we want to work around it.
|
||||
*/
|
||||
if ( ! mdoc_elem_alloc(m, line, offs, MDOC_sp, NULL))
|
||||
if ( ! mdoc_elem_alloc(mdoc, line, offs, MDOC_sp, NULL))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
mdoc->next = MDOC_NEXT_SIBLING;
|
||||
|
||||
return(mdoc_valid_post(mdoc));
|
||||
}
|
||||
|
||||
if ( ! mdoc_word_alloc(m, line, offs, buf+offs))
|
||||
if ( ! mdoc_word_alloc(mdoc, line, offs, buf+offs))
|
||||
return(0);
|
||||
|
||||
if (MDOC_LITERAL & m->flags)
|
||||
if (MDOC_LITERAL & mdoc->flags)
|
||||
return(1);
|
||||
|
||||
/*
|
||||
@ -818,7 +847,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
assert(buf < end);
|
||||
|
||||
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs), 0))
|
||||
m->last->flags |= MDOC_EOS;
|
||||
mdoc->last->flags |= MDOC_EOS;
|
||||
|
||||
return(1);
|
||||
}
|
||||
@ -829,7 +858,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
* character.
|
||||
*/
|
||||
static int
|
||||
mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
|
||||
{
|
||||
enum mdoct tok;
|
||||
int i, sv;
|
||||
@ -839,7 +868,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
/* Empty post-control lines are ignored. */
|
||||
|
||||
if ('"' == buf[offs]) {
|
||||
mdoc_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT);
|
||||
mdoc_pmsg(mdoc, ln, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
} else if ('\0' == buf[offs])
|
||||
return(1);
|
||||
@ -861,7 +890,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
tok = (i > 1 || i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
|
||||
|
||||
if (MDOC_MAX == tok) {
|
||||
mandoc_vmsg(MANDOCERR_MACRO, m->parse,
|
||||
mandoc_vmsg(MANDOCERR_MACRO, mdoc->parse,
|
||||
ln, sv, "%s", buf + sv - 1);
|
||||
return(1);
|
||||
}
|
||||
@ -882,21 +911,21 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
*/
|
||||
|
||||
if ('\0' == buf[offs] && ' ' == buf[offs - 1])
|
||||
mdoc_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
||||
mdoc_pmsg(mdoc, ln, offs - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
/*
|
||||
* If an initial macro or a list invocation, divert directly
|
||||
* into macro processing.
|
||||
*/
|
||||
|
||||
if (NULL == m->last || MDOC_It == tok || MDOC_El == tok) {
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf))
|
||||
if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
|
||||
if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf))
|
||||
goto err;
|
||||
return(1);
|
||||
}
|
||||
|
||||
n = m->last;
|
||||
assert(m->last);
|
||||
n = mdoc->last;
|
||||
assert(mdoc->last);
|
||||
|
||||
/*
|
||||
* If the first macro of a `Bl -column', open an `It' block
|
||||
@ -905,8 +934,8 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
|
||||
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
|
||||
LIST_column == n->norm->Bl.type) {
|
||||
m->flags |= MDOC_FREECOL;
|
||||
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf))
|
||||
goto err;
|
||||
return(1);
|
||||
}
|
||||
@ -921,22 +950,22 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
NULL != n->parent &&
|
||||
MDOC_Bl == n->parent->tok &&
|
||||
LIST_column == n->parent->norm->Bl.type) {
|
||||
m->flags |= MDOC_FREECOL;
|
||||
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
|
||||
mdoc->flags |= MDOC_FREECOL;
|
||||
if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf))
|
||||
goto err;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Normal processing of a macro. */
|
||||
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf))
|
||||
if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf))
|
||||
goto err;
|
||||
|
||||
return(1);
|
||||
|
||||
err: /* Error out. */
|
||||
|
||||
m->flags |= MDOC_HALT;
|
||||
mdoc->flags |= MDOC_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -980,7 +1009,7 @@ mdoc_isdelim(const char *p)
|
||||
|
||||
if (0 == strcmp(p + 1, "."))
|
||||
return(DELIM_CLOSE);
|
||||
if (0 == strcmp(p + 1, "*(Ba"))
|
||||
if (0 == strcmp(p + 1, "fR|\\fP"))
|
||||
return(DELIM_MIDDLE);
|
||||
|
||||
return(DELIM_NONE);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc.h,v 1.122 2011/03/22 14:05:45 kristaps Exp $ */
|
||||
/* $Id: mdoc.h,v 1.125 2013/12/24 19:11:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -311,6 +311,7 @@ struct mdoc_bl {
|
||||
int comp; /* -compact */
|
||||
size_t ncols; /* -column arg count */
|
||||
const char **cols; /* -column val ptr */
|
||||
int count; /* -enum counter */
|
||||
};
|
||||
|
||||
struct mdoc_bf {
|
||||
@ -350,6 +351,7 @@ struct mdoc_node {
|
||||
int nchild; /* number children */
|
||||
int line; /* parse line */
|
||||
int pos; /* parse column */
|
||||
int lastline; /* the node ends on this line */
|
||||
enum mdoct tok; /* tok or MDOC__MAX if none */
|
||||
int flags;
|
||||
#define MDOC_VALID (1 << 0) /* has been validated */
|
||||
@ -362,6 +364,7 @@ struct mdoc_node {
|
||||
enum mdoc_type type; /* AST node type */
|
||||
enum mdoc_sec sec; /* current named section */
|
||||
union mdoc_data *norm; /* normalised args */
|
||||
const void *prev_font; /* before entering this node */
|
||||
/* FIXME: these can be union'd to shave a few bytes. */
|
||||
struct mdoc_arg *args; /* BLOCK/ELEM */
|
||||
struct mdoc_node *pending; /* BLOCK */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: mdoc_argv.c,v 1.82 2012/03/23 05:50:24 kristaps Exp $ */
|
||||
/* $Id: mdoc_argv.c,v 1.89 2013/12/25 00:50:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -42,8 +43,7 @@ enum argsflag {
|
||||
enum argvflag {
|
||||
ARGV_NONE, /* no args to flag (e.g., -split) */
|
||||
ARGV_SINGLE, /* one arg to flag (e.g., -file xxx) */
|
||||
ARGV_MULTI, /* multiple args (e.g., -column xxx yyy) */
|
||||
ARGV_OPT_SINGLE /* optional arg (e.g., -offset [xxx]) */
|
||||
ARGV_MULTI /* multiple args (e.g., -column xxx yyy) */
|
||||
};
|
||||
|
||||
struct mdocarg {
|
||||
@ -57,8 +57,6 @@ static enum margserr args(struct mdoc *, int, int *,
|
||||
static int args_checkpunct(const char *, int);
|
||||
static int argv_multi(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_opt_single(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_single(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
|
||||
@ -69,7 +67,7 @@ static const enum argvflag argvflags[MDOC_ARG_MAX] = {
|
||||
ARGV_NONE, /* MDOC_Unfilled */
|
||||
ARGV_NONE, /* MDOC_Literal */
|
||||
ARGV_SINGLE, /* MDOC_File */
|
||||
ARGV_OPT_SINGLE, /* MDOC_Offset */
|
||||
ARGV_SINGLE, /* MDOC_Offset */
|
||||
ARGV_NONE, /* MDOC_Bullet */
|
||||
ARGV_NONE, /* MDOC_Dash */
|
||||
ARGV_NONE, /* MDOC_Hyphen */
|
||||
@ -81,7 +79,7 @@ static const enum argvflag argvflags[MDOC_ARG_MAX] = {
|
||||
ARGV_NONE, /* MDOC_Ohang */
|
||||
ARGV_NONE, /* MDOC_Inset */
|
||||
ARGV_MULTI, /* MDOC_Column */
|
||||
ARGV_OPT_SINGLE, /* MDOC_Width */
|
||||
ARGV_SINGLE, /* MDOC_Width */
|
||||
ARGV_NONE, /* MDOC_Compact */
|
||||
ARGV_NONE, /* MDOC_Std */
|
||||
ARGV_NONE, /* MDOC_Filled */
|
||||
@ -146,7 +144,7 @@ static const enum mdocargt args_Bl[] = {
|
||||
};
|
||||
|
||||
static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_NONE, NULL }, /* Ap */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ap */
|
||||
{ ARGSFL_NONE, NULL }, /* Dd */
|
||||
{ ARGSFL_NONE, NULL }, /* Dt */
|
||||
{ ARGSFL_NONE, NULL }, /* Os */
|
||||
@ -163,7 +161,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_DELIM, NULL }, /* Ad */
|
||||
{ ARGSFL_DELIM, args_An }, /* An */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ar */
|
||||
{ ARGSFL_NONE, NULL }, /* Cd */
|
||||
{ ARGSFL_DELIM, NULL }, /* Cd */
|
||||
{ ARGSFL_DELIM, NULL }, /* Cm */
|
||||
{ ARGSFL_DELIM, NULL }, /* Dv */
|
||||
{ ARGSFL_DELIM, NULL }, /* Er */
|
||||
@ -175,7 +173,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_DELIM, NULL }, /* Fn */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ft */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ic */
|
||||
{ ARGSFL_NONE, NULL }, /* In */
|
||||
{ ARGSFL_DELIM, NULL }, /* In */
|
||||
{ ARGSFL_DELIM, NULL }, /* Li */
|
||||
{ ARGSFL_NONE, NULL }, /* Nd */
|
||||
{ ARGSFL_DELIM, NULL }, /* Nm */
|
||||
@ -243,7 +241,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_DELIM, NULL }, /* Xc */
|
||||
{ ARGSFL_NONE, NULL }, /* Xo */
|
||||
{ ARGSFL_NONE, NULL }, /* Fo */
|
||||
{ ARGSFL_NONE, NULL }, /* Fc */
|
||||
{ ARGSFL_DELIM, NULL }, /* Fc */
|
||||
{ ARGSFL_NONE, NULL }, /* Oo */
|
||||
{ ARGSFL_DELIM, NULL }, /* Oc */
|
||||
{ ARGSFL_NONE, args_Bk }, /* Bk */
|
||||
@ -252,7 +250,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_NONE, NULL }, /* Hf */
|
||||
{ ARGSFL_NONE, NULL }, /* Fr */
|
||||
{ ARGSFL_NONE, NULL }, /* Ud */
|
||||
{ ARGSFL_NONE, NULL }, /* Lb */
|
||||
{ ARGSFL_DELIM, NULL }, /* Lb */
|
||||
{ ARGSFL_NONE, NULL }, /* Lp */
|
||||
{ ARGSFL_DELIM, NULL }, /* Lk */
|
||||
{ ARGSFL_DELIM, NULL }, /* Mt */
|
||||
@ -262,7 +260,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_NONE, NULL }, /* %C */
|
||||
{ ARGSFL_NONE, NULL }, /* Es */
|
||||
{ ARGSFL_NONE, NULL }, /* En */
|
||||
{ ARGSFL_NONE, NULL }, /* Dx */
|
||||
{ ARGSFL_DELIM, NULL }, /* Dx */
|
||||
{ ARGSFL_NONE, NULL }, /* %Q */
|
||||
{ ARGSFL_NONE, NULL }, /* br */
|
||||
{ ARGSFL_NONE, NULL }, /* sp */
|
||||
@ -277,7 +275,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
* one mandatory value, an optional single value, or no value.
|
||||
*/
|
||||
enum margverr
|
||||
mdoc_argv(struct mdoc *m, int line, enum mdoct tok,
|
||||
mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
|
||||
struct mdoc_arg **v, int *pos, char *buf)
|
||||
{
|
||||
char *p, sv;
|
||||
@ -344,15 +342,11 @@ mdoc_argv(struct mdoc *m, int line, enum mdoct tok,
|
||||
|
||||
switch (argvflags[tmp.arg]) {
|
||||
case (ARGV_SINGLE):
|
||||
if ( ! argv_single(m, line, &tmp, pos, buf))
|
||||
if ( ! argv_single(mdoc, line, &tmp, pos, buf))
|
||||
return(ARGV_ERROR);
|
||||
break;
|
||||
case (ARGV_MULTI):
|
||||
if ( ! argv_multi(m, line, &tmp, pos, buf))
|
||||
return(ARGV_ERROR);
|
||||
break;
|
||||
case (ARGV_OPT_SINGLE):
|
||||
if ( ! argv_opt_single(m, line, &tmp, pos, buf))
|
||||
if ( ! argv_multi(mdoc, line, &tmp, pos, buf))
|
||||
return(ARGV_ERROR);
|
||||
break;
|
||||
case (ARGV_NONE):
|
||||
@ -413,14 +407,14 @@ argn_free(struct mdoc_arg *p, int iarg)
|
||||
}
|
||||
|
||||
enum margserr
|
||||
mdoc_zargs(struct mdoc *m, int line, int *pos, char *buf, char **v)
|
||||
mdoc_zargs(struct mdoc *mdoc, int line, int *pos, char *buf, char **v)
|
||||
{
|
||||
|
||||
return(args(m, line, pos, buf, ARGSFL_NONE, v));
|
||||
return(args(mdoc, line, pos, buf, ARGSFL_NONE, v));
|
||||
}
|
||||
|
||||
enum margserr
|
||||
mdoc_args(struct mdoc *m, int line, int *pos,
|
||||
mdoc_args(struct mdoc *mdoc, int line, int *pos,
|
||||
char *buf, enum mdoct tok, char **v)
|
||||
{
|
||||
enum argsflag fl;
|
||||
@ -429,7 +423,7 @@ mdoc_args(struct mdoc *m, int line, int *pos,
|
||||
fl = mdocargs[tok].flags;
|
||||
|
||||
if (MDOC_It != tok)
|
||||
return(args(m, line, pos, buf, fl, v));
|
||||
return(args(mdoc, line, pos, buf, fl, v));
|
||||
|
||||
/*
|
||||
* We know that we're in an `It', so it's reasonable to expect
|
||||
@ -438,35 +432,36 @@ mdoc_args(struct mdoc *m, int line, int *pos,
|
||||
* safe fall-back into the default behaviour.
|
||||
*/
|
||||
|
||||
for (n = m->last; n; n = n->parent)
|
||||
for (n = mdoc->last; n; n = n->parent)
|
||||
if (MDOC_Bl == n->tok)
|
||||
if (LIST_column == n->norm->Bl.type) {
|
||||
fl = ARGSFL_TABSEP;
|
||||
break;
|
||||
}
|
||||
|
||||
return(args(m, line, pos, buf, fl, v));
|
||||
return(args(mdoc, line, pos, buf, fl, v));
|
||||
}
|
||||
|
||||
static enum margserr
|
||||
args(struct mdoc *m, int line, int *pos,
|
||||
args(struct mdoc *mdoc, int line, int *pos,
|
||||
char *buf, enum argsflag fl, char **v)
|
||||
{
|
||||
char *p, *pp;
|
||||
int pairs;
|
||||
enum margserr rc;
|
||||
|
||||
if ('\0' == buf[*pos]) {
|
||||
if (MDOC_PPHRASE & m->flags)
|
||||
if (MDOC_PPHRASE & mdoc->flags)
|
||||
return(ARGS_EOLN);
|
||||
/*
|
||||
* If we're not in a partial phrase and the flag for
|
||||
* being a phrase literal is still set, the punctuation
|
||||
* is unterminated.
|
||||
*/
|
||||
if (MDOC_PHRASELIT & m->flags)
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE);
|
||||
if (MDOC_PHRASELIT & mdoc->flags)
|
||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE);
|
||||
|
||||
m->flags &= ~MDOC_PHRASELIT;
|
||||
mdoc->flags &= ~MDOC_PHRASELIT;
|
||||
return(ARGS_EOLN);
|
||||
}
|
||||
|
||||
@ -489,7 +484,7 @@ args(struct mdoc *m, int line, int *pos,
|
||||
pp = NULL;
|
||||
|
||||
/* Scan ahead to unescaped `Ta'. */
|
||||
if ( ! (MDOC_PHRASELIT & m->flags))
|
||||
if ( ! (MDOC_PHRASELIT & mdoc->flags))
|
||||
for (pp = *v; ; pp++) {
|
||||
if (NULL == (pp = strstr(pp, "Ta")))
|
||||
break;
|
||||
@ -523,7 +518,7 @@ args(struct mdoc *m, int line, int *pos,
|
||||
|
||||
/* Whitespace check for eoln case... */
|
||||
if ('\0' == *p && ' ' == *(p - 1))
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE);
|
||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE);
|
||||
|
||||
*pos += (int)(p - *v);
|
||||
|
||||
@ -541,37 +536,48 @@ args(struct mdoc *m, int line, int *pos,
|
||||
/* Skip ahead. */ ;
|
||||
|
||||
return(rc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Process a quoted literal. A quote begins with a double-quote
|
||||
* and ends with a double-quote NOT preceded by a double-quote.
|
||||
* NUL-terminate the literal in place.
|
||||
* Collapse pairs of quotes inside quoted literals.
|
||||
* Whitespace is NOT involved in literal termination.
|
||||
*/
|
||||
|
||||
if (MDOC_PHRASELIT & m->flags || '\"' == buf[*pos]) {
|
||||
if ( ! (MDOC_PHRASELIT & m->flags))
|
||||
if (MDOC_PHRASELIT & mdoc->flags || '\"' == buf[*pos]) {
|
||||
if ( ! (MDOC_PHRASELIT & mdoc->flags))
|
||||
*v = &buf[++(*pos)];
|
||||
|
||||
if (MDOC_PPHRASE & m->flags)
|
||||
m->flags |= MDOC_PHRASELIT;
|
||||
if (MDOC_PPHRASE & mdoc->flags)
|
||||
mdoc->flags |= MDOC_PHRASELIT;
|
||||
|
||||
pairs = 0;
|
||||
for ( ; buf[*pos]; (*pos)++) {
|
||||
/* Move following text left after quoted quotes. */
|
||||
if (pairs)
|
||||
buf[*pos - pairs] = buf[*pos];
|
||||
if ('\"' != buf[*pos])
|
||||
continue;
|
||||
/* Unquoted quotes end quoted args. */
|
||||
if ('\"' != buf[*pos + 1])
|
||||
break;
|
||||
/* Quoted quotes collapse. */
|
||||
pairs++;
|
||||
(*pos)++;
|
||||
}
|
||||
if (pairs)
|
||||
buf[*pos - pairs] = '\0';
|
||||
|
||||
if ('\0' == buf[*pos]) {
|
||||
if (MDOC_PPHRASE & m->flags)
|
||||
if (MDOC_PPHRASE & mdoc->flags)
|
||||
return(ARGS_QWORD);
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE);
|
||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_BADQUOTE);
|
||||
return(ARGS_QWORD);
|
||||
}
|
||||
|
||||
m->flags &= ~MDOC_PHRASELIT;
|
||||
mdoc->flags &= ~MDOC_PHRASELIT;
|
||||
buf[(*pos)++] = '\0';
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
@ -581,13 +587,13 @@ args(struct mdoc *m, int line, int *pos,
|
||||
(*pos)++;
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE);
|
||||
mdoc_pmsg(mdoc, line, *pos, MANDOCERR_EOLNSPACE);
|
||||
|
||||
return(ARGS_QWORD);
|
||||
}
|
||||
|
||||
p = &buf[*pos];
|
||||
*v = mandoc_getarg(m->parse, &p, line, pos);
|
||||
*v = mandoc_getarg(mdoc->parse, &p, line, pos);
|
||||
|
||||
return(ARGS_WORD);
|
||||
}
|
||||
@ -643,7 +649,7 @@ args_checkpunct(const char *buf, int i)
|
||||
}
|
||||
|
||||
static int
|
||||
argv_multi(struct mdoc *m, int line,
|
||||
argv_multi(struct mdoc *mdoc, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
enum margserr ac;
|
||||
@ -652,7 +658,7 @@ argv_multi(struct mdoc *m, int line,
|
||||
for (v->sz = 0; ; v->sz++) {
|
||||
if ('-' == buf[*pos])
|
||||
break;
|
||||
ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
|
||||
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
else if (ARGS_EOLN == ac)
|
||||
@ -669,16 +675,13 @@ argv_multi(struct mdoc *m, int line,
|
||||
}
|
||||
|
||||
static int
|
||||
argv_opt_single(struct mdoc *m, int line,
|
||||
argv_single(struct mdoc *mdoc, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
enum margserr ac;
|
||||
char *p;
|
||||
|
||||
if ('-' == buf[*pos])
|
||||
return(1);
|
||||
|
||||
ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
|
||||
ac = args(mdoc, line, pos, buf, ARGSFL_NONE, &p);
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
if (ARGS_EOLN == ac)
|
||||
@ -690,27 +693,3 @@ argv_opt_single(struct mdoc *m, int line,
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
argv_single(struct mdoc *m, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
int ppos;
|
||||
enum margserr ac;
|
||||
char *p;
|
||||
|
||||
ppos = *pos;
|
||||
|
||||
ac = args(m, line, pos, buf, ARGSFL_NONE, &p);
|
||||
if (ARGS_EOLN == ac) {
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT);
|
||||
return(0);
|
||||
} else if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
|
||||
v->sz = 1;
|
||||
v->value = mandoc_malloc(sizeof(char *));
|
||||
v->value[0] = mandoc_strdup(p);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_html.c,v 1.182 2011/11/03 20:37:00 schwarze Exp $ */
|
||||
/* $Id: mdoc_html.c,v 1.186 2013/12/24 20:45:27 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
#define INDENT 5
|
||||
|
||||
#define MDOC_ARGS const struct mdoc_meta *m, \
|
||||
#define MDOC_ARGS const struct mdoc_meta *meta, \
|
||||
const struct mdoc_node *n, \
|
||||
struct html *h
|
||||
|
||||
@ -260,10 +260,11 @@ static const char * const lists[LIST_MAX] = {
|
||||
};
|
||||
|
||||
void
|
||||
html_mdoc(void *arg, const struct mdoc *m)
|
||||
html_mdoc(void *arg, const struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
print_mdoc(mdoc_meta(m), mdoc_node(m), (struct html *)arg);
|
||||
print_mdoc(mdoc_meta(mdoc), mdoc_node(mdoc),
|
||||
(struct html *)arg);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
@ -361,14 +362,14 @@ print_mdoc(MDOC_ARGS)
|
||||
print_gen_decls(h);
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
tt = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
print_mdoc_head(m, n, h);
|
||||
print_mdoc_head(meta, n, h);
|
||||
print_tagq(h, tt);
|
||||
print_otag(h, TAG_BODY, 0, NULL);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
||||
print_mdoc_nodelist(m, n, h);
|
||||
print_mdoc_nodelist(meta, n, h);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
@ -380,10 +381,10 @@ print_mdoc_head(MDOC_ARGS)
|
||||
|
||||
print_gen_head(h);
|
||||
bufinit(h);
|
||||
bufcat_fmt(h, "%s(%s)", m->title, m->msec);
|
||||
bufcat_fmt(h, "%s(%s)", meta->title, meta->msec);
|
||||
|
||||
if (m->arch)
|
||||
bufcat_fmt(h, " (%s)", m->arch);
|
||||
if (meta->arch)
|
||||
bufcat_fmt(h, " (%s)", meta->arch);
|
||||
|
||||
print_otag(h, TAG_TITLE, 0, NULL);
|
||||
print_text(h, h->buf);
|
||||
@ -394,9 +395,9 @@ static void
|
||||
print_mdoc_nodelist(MDOC_ARGS)
|
||||
{
|
||||
|
||||
print_mdoc_node(m, n, h);
|
||||
print_mdoc_node(meta, n, h);
|
||||
if (n->next)
|
||||
print_mdoc_nodelist(m, n->next, h);
|
||||
print_mdoc_nodelist(meta, n->next, h);
|
||||
}
|
||||
|
||||
|
||||
@ -411,7 +412,7 @@ print_mdoc_node(MDOC_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_ROOT):
|
||||
child = mdoc_root_pre(m, n, h);
|
||||
child = mdoc_root_pre(meta, n, h);
|
||||
break;
|
||||
case (MDOC_TEXT):
|
||||
/* No tables in this mode... */
|
||||
@ -454,36 +455,32 @@ print_mdoc_node(MDOC_ARGS)
|
||||
|
||||
assert(NULL == h->tblt);
|
||||
if (mdocs[n->tok].pre && ENDBODY_NOT == n->end)
|
||||
child = (*mdocs[n->tok].pre)(m, n, h);
|
||||
child = (*mdocs[n->tok].pre)(meta, n, h);
|
||||
break;
|
||||
}
|
||||
|
||||
if (HTML_KEEP & h->flags) {
|
||||
if (n->prev && n->prev->line != n->line) {
|
||||
if (n->prev ? (n->prev->lastline != n->line) :
|
||||
(n->parent && n->parent->line != n->line)) {
|
||||
h->flags &= ~HTML_KEEP;
|
||||
h->flags |= HTML_PREKEEP;
|
||||
} else if (NULL == n->prev) {
|
||||
if (n->parent && n->parent->line != n->line) {
|
||||
h->flags &= ~HTML_KEEP;
|
||||
h->flags |= HTML_PREKEEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (child && n->child)
|
||||
print_mdoc_nodelist(m, n->child, h);
|
||||
print_mdoc_nodelist(meta, n->child, h);
|
||||
|
||||
print_stagq(h, t);
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_ROOT):
|
||||
mdoc_root_post(m, n, h);
|
||||
mdoc_root_post(meta, n, h);
|
||||
break;
|
||||
case (MDOC_EQN):
|
||||
break;
|
||||
default:
|
||||
if (mdocs[n->tok].post && ENDBODY_NOT == n->end)
|
||||
(*mdocs[n->tok].post)(m, n, h);
|
||||
(*mdocs[n->tok].post)(meta, n, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -509,13 +506,13 @@ mdoc_root_post(MDOC_ARGS)
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-date");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
print_text(h, m->date);
|
||||
print_text(h, meta->date);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-os");
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
print_text(h, m->os);
|
||||
print_text(h, meta->os);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
@ -528,15 +525,15 @@ mdoc_root_pre(MDOC_ARGS)
|
||||
struct tag *t, *tt;
|
||||
char b[BUFSIZ], title[BUFSIZ];
|
||||
|
||||
strlcpy(b, m->vol, BUFSIZ);
|
||||
strlcpy(b, meta->vol, BUFSIZ);
|
||||
|
||||
if (m->arch) {
|
||||
if (meta->arch) {
|
||||
strlcat(b, " (", BUFSIZ);
|
||||
strlcat(b, m->arch, BUFSIZ);
|
||||
strlcat(b, meta->arch, BUFSIZ);
|
||||
strlcat(b, ")", BUFSIZ);
|
||||
}
|
||||
|
||||
snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec);
|
||||
snprintf(title, BUFSIZ - 1, "%s(%s)", meta->title, meta->msec);
|
||||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
||||
PAIR_CLASS_INIT(&tag[1], "head");
|
||||
@ -689,13 +686,13 @@ mdoc_nm_pre(MDOC_ARGS)
|
||||
synopsis_pre(h, n);
|
||||
PAIR_CLASS_INIT(&tag, "name");
|
||||
print_otag(h, TAG_B, 1, &tag);
|
||||
if (NULL == n->child && m->name)
|
||||
print_text(h, m->name);
|
||||
if (NULL == n->child && meta->name)
|
||||
print_text(h, meta->name);
|
||||
return(1);
|
||||
case (MDOC_HEAD):
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
if (NULL == n->child && m->name)
|
||||
print_text(h, m->name);
|
||||
if (NULL == n->child && meta->name)
|
||||
print_text(h, meta->name);
|
||||
return(1);
|
||||
case (MDOC_BODY):
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
@ -712,8 +709,8 @@ mdoc_nm_pre(MDOC_ARGS)
|
||||
if (MDOC_TEXT == n->type)
|
||||
len += html_strlen(n->string);
|
||||
|
||||
if (0 == len && m->name)
|
||||
len = html_strlen(m->name);
|
||||
if (0 == len && meta->name)
|
||||
len = html_strlen(meta->name);
|
||||
|
||||
SCALE_HS_INIT(&su, (double)len);
|
||||
bufinit(h);
|
||||
@ -981,8 +978,6 @@ mdoc_bl_pre(MDOC_ARGS)
|
||||
struct roffsu su;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
bufinit(h);
|
||||
|
||||
if (MDOC_BODY == n->type) {
|
||||
if (LIST_column == n->norm->Bl.type)
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
@ -1001,6 +996,7 @@ mdoc_bl_pre(MDOC_ARGS)
|
||||
*/
|
||||
|
||||
for (i = 0; i < (int)n->norm->Bl.ncols; i++) {
|
||||
bufinit(h);
|
||||
a2width(n->norm->Bl.cols[i], &su);
|
||||
if (i < (int)n->norm->Bl.ncols - 1)
|
||||
bufcat_su(h, "width", &su);
|
||||
@ -1014,6 +1010,7 @@ mdoc_bl_pre(MDOC_ARGS)
|
||||
}
|
||||
|
||||
SCALE_VS_INIT(&su, 0);
|
||||
bufinit(h);
|
||||
bufcat_su(h, "margin-top", &su);
|
||||
bufcat_su(h, "margin-bottom", &su);
|
||||
PAIR_STYLE_INIT(&tag[0], h);
|
||||
@ -1225,7 +1222,7 @@ mdoc_bd_pre(MDOC_ARGS)
|
||||
h->flags |= HTML_LITERAL;
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
print_mdoc_node(m, nn, h);
|
||||
print_mdoc_node(meta, nn, h);
|
||||
/*
|
||||
* If the printed node flushes its own line, then we
|
||||
* needn't do it here as well. This is hacky, but the
|
||||
@ -2273,7 +2270,7 @@ mdoc_quote_post(MDOC_ARGS)
|
||||
case (MDOC_So):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Sq):
|
||||
print_text(h, "\\(aq");
|
||||
print_text(h, "\\(cq");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,8 @@
|
||||
/* $Id: mdoc_term.c,v 1.238 2011/11/13 13:15:14 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.258 2013/12/25 21:24:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -41,8 +42,8 @@ struct termpair {
|
||||
|
||||
#define DECL_ARGS struct termp *p, \
|
||||
struct termpair *pair, \
|
||||
const struct mdoc_meta *m, \
|
||||
const struct mdoc_node *n
|
||||
const struct mdoc_meta *meta, \
|
||||
struct mdoc_node *n
|
||||
|
||||
struct termact {
|
||||
int (*pre)(DECL_ARGS);
|
||||
@ -69,7 +70,7 @@ static void termp_an_post(DECL_ARGS);
|
||||
static void termp_bd_post(DECL_ARGS);
|
||||
static void termp_bk_post(DECL_ARGS);
|
||||
static void termp_bl_post(DECL_ARGS);
|
||||
static void termp_d1_post(DECL_ARGS);
|
||||
static void termp_fd_post(DECL_ARGS);
|
||||
static void termp_fo_post(DECL_ARGS);
|
||||
static void termp_in_post(DECL_ARGS);
|
||||
static void termp_it_post(DECL_ARGS);
|
||||
@ -100,7 +101,6 @@ static int termp_fl_pre(DECL_ARGS);
|
||||
static int termp_fn_pre(DECL_ARGS);
|
||||
static int termp_fo_pre(DECL_ARGS);
|
||||
static int termp_ft_pre(DECL_ARGS);
|
||||
static int termp_igndelim_pre(DECL_ARGS);
|
||||
static int termp_in_pre(DECL_ARGS);
|
||||
static int termp_it_pre(DECL_ARGS);
|
||||
static int termp_li_pre(DECL_ARGS);
|
||||
@ -129,8 +129,8 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_sh_pre, termp_sh_post }, /* Sh */
|
||||
{ termp_ss_pre, termp_ss_post }, /* Ss */
|
||||
{ termp_sp_pre, NULL }, /* Pp */
|
||||
{ termp_d1_pre, termp_d1_post }, /* D1 */
|
||||
{ termp_d1_pre, termp_d1_post }, /* Dl */
|
||||
{ termp_d1_pre, termp_bl_post }, /* D1 */
|
||||
{ termp_d1_pre, termp_bl_post }, /* Dl */
|
||||
{ termp_bd_pre, termp_bd_post }, /* Bd */
|
||||
{ NULL, NULL }, /* Ed */
|
||||
{ termp_bl_pre, termp_bl_post }, /* Bl */
|
||||
@ -146,7 +146,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ NULL, NULL }, /* Ev */
|
||||
{ termp_ex_pre, NULL }, /* Ex */
|
||||
{ termp_fa_pre, NULL }, /* Fa */
|
||||
{ termp_fd_pre, NULL }, /* Fd */
|
||||
{ termp_fd_pre, termp_fd_post }, /* Fd */
|
||||
{ termp_fl_pre, NULL }, /* Fl */
|
||||
{ termp_fn_pre, NULL }, /* Fn */
|
||||
{ termp_ft_pre, NULL }, /* Ft */
|
||||
@ -194,12 +194,12 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_quote_pre, termp_quote_post }, /* Eo */
|
||||
{ termp_xx_pre, NULL }, /* Fx */
|
||||
{ termp_bold_pre, NULL }, /* Ms */
|
||||
{ termp_igndelim_pre, NULL }, /* No */
|
||||
{ NULL, NULL }, /* No */
|
||||
{ termp_ns_pre, NULL }, /* Ns */
|
||||
{ termp_xx_pre, NULL }, /* Nx */
|
||||
{ termp_xx_pre, NULL }, /* Ox */
|
||||
{ NULL, NULL }, /* Pc */
|
||||
{ termp_igndelim_pre, termp_pf_post }, /* Pf */
|
||||
{ NULL, termp_pf_post }, /* Pf */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Po */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Pq */
|
||||
{ NULL, NULL }, /* Qc */
|
||||
@ -242,7 +242,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ NULL, termp____post }, /* %Q */
|
||||
{ termp_sp_pre, NULL }, /* br */
|
||||
{ termp_sp_pre, NULL }, /* sp */
|
||||
{ termp_under_pre, termp____post }, /* %U */
|
||||
{ NULL, termp____post }, /* %U */
|
||||
{ NULL, NULL }, /* Ta */
|
||||
};
|
||||
|
||||
@ -251,7 +251,7 @@ void
|
||||
terminal_mdoc(void *arg, const struct mdoc *mdoc)
|
||||
{
|
||||
const struct mdoc_node *n;
|
||||
const struct mdoc_meta *m;
|
||||
const struct mdoc_meta *meta;
|
||||
struct termp *p;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
@ -267,12 +267,12 @@ terminal_mdoc(void *arg, const struct mdoc *mdoc)
|
||||
p->symtab = mchars_alloc();
|
||||
|
||||
n = mdoc_node(mdoc);
|
||||
m = mdoc_meta(mdoc);
|
||||
meta = mdoc_meta(mdoc);
|
||||
|
||||
term_begin(p, print_mdoc_head, print_mdoc_foot, m);
|
||||
term_begin(p, print_mdoc_head, print_mdoc_foot, meta);
|
||||
|
||||
if (n->child)
|
||||
print_mdoc_nodelist(p, NULL, m, n->child);
|
||||
print_mdoc_nodelist(p, NULL, meta, n->child);
|
||||
|
||||
term_end(p);
|
||||
}
|
||||
@ -282,9 +282,9 @@ static void
|
||||
print_mdoc_nodelist(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_mdoc_node(p, pair, m, n);
|
||||
print_mdoc_node(p, pair, meta, n);
|
||||
if (n->next)
|
||||
print_mdoc_nodelist(p, pair, m, n->next);
|
||||
print_mdoc_nodelist(p, pair, meta, n->next);
|
||||
}
|
||||
|
||||
|
||||
@ -293,14 +293,13 @@ static void
|
||||
print_mdoc_node(DECL_ARGS)
|
||||
{
|
||||
int chld;
|
||||
const void *font;
|
||||
struct termpair npair;
|
||||
size_t offset, rmargin;
|
||||
|
||||
chld = 1;
|
||||
offset = p->offset;
|
||||
rmargin = p->rmargin;
|
||||
font = term_fontq(p);
|
||||
n->prev_font = term_fontq(p);
|
||||
|
||||
memset(&npair, 0, sizeof(struct termpair));
|
||||
npair.ppair = pair;
|
||||
@ -308,33 +307,16 @@ print_mdoc_node(DECL_ARGS)
|
||||
/*
|
||||
* Keeps only work until the end of a line. If a keep was
|
||||
* invoked in a prior line, revert it to PREKEEP.
|
||||
*
|
||||
* Also let SYNPRETTY sections behave as if they were wrapped
|
||||
* in a `Bk' block.
|
||||
*/
|
||||
|
||||
if (TERMP_KEEP & p->flags || MDOC_SYNPRETTY & n->flags) {
|
||||
if (n->prev && n->prev->line != n->line) {
|
||||
if (TERMP_KEEP & p->flags) {
|
||||
if (n->prev ? (n->prev->lastline != n->line) :
|
||||
(n->parent && n->parent->line != n->line)) {
|
||||
p->flags &= ~TERMP_KEEP;
|
||||
p->flags |= TERMP_PREKEEP;
|
||||
} else if (NULL == n->prev) {
|
||||
if (n->parent && n->parent->line != n->line) {
|
||||
p->flags &= ~TERMP_KEEP;
|
||||
p->flags |= TERMP_PREKEEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Since SYNPRETTY sections aren't "turned off" with `Ek',
|
||||
* we have to intuit whether we should disable formatting.
|
||||
*/
|
||||
|
||||
if ( ! (MDOC_SYNPRETTY & n->flags) &&
|
||||
((n->prev && MDOC_SYNPRETTY & n->prev->flags) ||
|
||||
(n->parent && MDOC_SYNPRETTY & n->parent->flags)))
|
||||
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
||||
|
||||
/*
|
||||
* After the keep flags have been set up, we may now
|
||||
* produce output. Note that some pre-handlers do so.
|
||||
@ -359,14 +341,15 @@ print_mdoc_node(DECL_ARGS)
|
||||
default:
|
||||
if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
|
||||
chld = (*termacts[n->tok].pre)
|
||||
(p, &npair, m, n);
|
||||
(p, &npair, meta, n);
|
||||
break;
|
||||
}
|
||||
|
||||
if (chld && n->child)
|
||||
print_mdoc_nodelist(p, &npair, m, n->child);
|
||||
print_mdoc_nodelist(p, &npair, meta, n->child);
|
||||
|
||||
term_fontpopq(p, font);
|
||||
term_fontpopq(p,
|
||||
(ENDBODY_NOT == n->end ? n : n->pending)->prev_font);
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_TEXT):
|
||||
@ -378,7 +361,7 @@ print_mdoc_node(DECL_ARGS)
|
||||
default:
|
||||
if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags)
|
||||
break;
|
||||
(void)(*termacts[n->tok].post)(p, &npair, m, n);
|
||||
(void)(*termacts[n->tok].post)(p, &npair, meta, n);
|
||||
|
||||
/*
|
||||
* Explicit end tokens not only call the post
|
||||
@ -409,9 +392,9 @@ print_mdoc_node(DECL_ARGS)
|
||||
static void
|
||||
print_mdoc_foot(struct termp *p, const void *arg)
|
||||
{
|
||||
const struct mdoc_meta *m;
|
||||
const struct mdoc_meta *meta;
|
||||
|
||||
m = (const struct mdoc_meta *)arg;
|
||||
meta = (const struct mdoc_meta *)arg;
|
||||
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
@ -427,25 +410,27 @@ print_mdoc_foot(struct termp *p, const void *arg)
|
||||
|
||||
p->offset = 0;
|
||||
p->rmargin = (p->maxrmargin -
|
||||
term_strlen(p, m->date) + term_len(p, 1)) / 2;
|
||||
term_strlen(p, meta->date) + term_len(p, 1)) / 2;
|
||||
p->trailspace = 1;
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||
|
||||
term_word(p, m->os);
|
||||
term_word(p, meta->os);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin - term_strlen(p, m->os);
|
||||
p->rmargin = p->maxrmargin - term_strlen(p, meta->os);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
term_word(p, m->date);
|
||||
term_word(p, meta->date);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
term_word(p, m->os);
|
||||
term_word(p, meta->os);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = 0;
|
||||
@ -459,9 +444,9 @@ print_mdoc_head(struct termp *p, const void *arg)
|
||||
{
|
||||
char buf[BUFSIZ], title[BUFSIZ];
|
||||
size_t buflen, titlen;
|
||||
const struct mdoc_meta *m;
|
||||
const struct mdoc_meta *meta;
|
||||
|
||||
m = (const struct mdoc_meta *)arg;
|
||||
meta = (const struct mdoc_meta *)arg;
|
||||
|
||||
/*
|
||||
* The header is strange. It has three components, which are
|
||||
@ -479,20 +464,21 @@ print_mdoc_head(struct termp *p, const void *arg)
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
|
||||
assert(m->vol);
|
||||
strlcpy(buf, m->vol, BUFSIZ);
|
||||
assert(meta->vol);
|
||||
strlcpy(buf, meta->vol, BUFSIZ);
|
||||
buflen = term_strlen(p, buf);
|
||||
|
||||
if (m->arch) {
|
||||
if (meta->arch) {
|
||||
strlcat(buf, " (", BUFSIZ);
|
||||
strlcat(buf, m->arch, BUFSIZ);
|
||||
strlcat(buf, meta->arch, BUFSIZ);
|
||||
strlcat(buf, ")", BUFSIZ);
|
||||
}
|
||||
|
||||
snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec);
|
||||
snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
|
||||
titlen = term_strlen(p, title);
|
||||
|
||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||
p->trailspace = 1;
|
||||
p->offset = 0;
|
||||
p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
|
||||
(p->maxrmargin -
|
||||
@ -511,6 +497,7 @@ print_mdoc_head(struct termp *p, const void *arg)
|
||||
term_flushln(p);
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->trailspace = 0;
|
||||
if (p->rmargin + titlen <= p->maxrmargin) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
@ -727,12 +714,10 @@ termp_it_pre(DECL_ARGS)
|
||||
case (LIST_dash):
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_hyphen):
|
||||
if (width < term_len(p, 4))
|
||||
width = term_len(p, 4);
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_enum):
|
||||
if (width < term_len(p, 5))
|
||||
width = term_len(p, 5);
|
||||
if (width < term_len(p, 2))
|
||||
width = term_len(p, 2);
|
||||
break;
|
||||
case (LIST_hang):
|
||||
if (0 == width)
|
||||
@ -787,20 +772,26 @@ termp_it_pre(DECL_ARGS)
|
||||
*/
|
||||
|
||||
switch (type) {
|
||||
case (LIST_enum):
|
||||
/*
|
||||
* Weird special case.
|
||||
* Very narrow enum lists actually hang.
|
||||
*/
|
||||
if (width == term_len(p, 2))
|
||||
p->flags |= TERMP_HANG;
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_bullet):
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_dash):
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_enum):
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_hyphen):
|
||||
if (MDOC_HEAD == n->type)
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
if (MDOC_HEAD != n->type)
|
||||
break;
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
case (LIST_hang):
|
||||
if (MDOC_HEAD == n->type)
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
else
|
||||
if (MDOC_HEAD != n->type)
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -812,16 +803,18 @@ termp_it_pre(DECL_ARGS)
|
||||
if (n->next->child &&
|
||||
(MDOC_Bl == n->next->child->tok ||
|
||||
MDOC_Bd == n->next->child->tok))
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
else
|
||||
p->flags |= TERMP_HANG;
|
||||
break;
|
||||
|
||||
p->flags |= TERMP_NOBREAK | TERMP_HANG;
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
case (LIST_tag):
|
||||
if (MDOC_HEAD == n->type)
|
||||
p->flags |= TERMP_NOBREAK | TERMP_TWOSPACE;
|
||||
|
||||
if (MDOC_HEAD != n->type)
|
||||
break;
|
||||
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 2;
|
||||
|
||||
if (NULL == n->next || NULL == n->next->child)
|
||||
p->flags |= TERMP_DANGLE;
|
||||
break;
|
||||
@ -829,15 +822,20 @@ termp_it_pre(DECL_ARGS)
|
||||
if (MDOC_HEAD == n->type)
|
||||
break;
|
||||
|
||||
if (NULL == n->next)
|
||||
if (NULL == n->next) {
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
else
|
||||
p->trailspace = 0;
|
||||
} else {
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case (LIST_diag):
|
||||
if (MDOC_HEAD == n->type)
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
if (MDOC_HEAD != n->type)
|
||||
break;
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -989,8 +987,8 @@ termp_it_post(DECL_ARGS)
|
||||
|
||||
p->flags &= ~TERMP_DANGLE;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags &= ~TERMP_TWOSPACE;
|
||||
p->flags &= ~TERMP_HANG;
|
||||
p->trailspace = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -999,22 +997,25 @@ static int
|
||||
termp_nm_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_BLOCK == n->type)
|
||||
if (MDOC_BLOCK == n->type) {
|
||||
p->flags |= TERMP_PREKEEP;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (MDOC_BODY == n->type) {
|
||||
if (NULL == n->child)
|
||||
return(0);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset += term_len(p, 1) +
|
||||
(NULL == n->prev->child ? term_strlen(p, m->name) :
|
||||
(NULL == n->prev->child ?
|
||||
term_strlen(p, meta->name) :
|
||||
MDOC_TEXT == n->prev->child->type ?
|
||||
term_strlen(p, n->prev->child->string) :
|
||||
term_strlen(p, n->prev->child->string) :
|
||||
term_len(p, 5));
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (NULL == n->child && NULL == m->name)
|
||||
if (NULL == n->child && NULL == meta->name)
|
||||
return(0);
|
||||
|
||||
if (MDOC_HEAD == n->type)
|
||||
@ -1022,9 +1023,10 @@ termp_nm_pre(DECL_ARGS)
|
||||
|
||||
if (MDOC_HEAD == n->type && n->next->child) {
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
p->rmargin = p->offset + term_len(p, 1);
|
||||
if (NULL == n->child) {
|
||||
p->rmargin += term_strlen(p, m->name);
|
||||
p->rmargin += term_strlen(p, meta->name);
|
||||
} else if (MDOC_TEXT == n->child->type) {
|
||||
p->rmargin += term_strlen(p, n->child->string);
|
||||
if (n->child->next)
|
||||
@ -1037,7 +1039,7 @@ termp_nm_pre(DECL_ARGS)
|
||||
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
if (NULL == n->child)
|
||||
term_word(p, m->name);
|
||||
term_word(p, meta->name);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -1047,9 +1049,12 @@ static void
|
||||
termp_nm_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_HEAD == n->type && n->next->child) {
|
||||
if (MDOC_BLOCK == n->type) {
|
||||
p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
|
||||
} else if (MDOC_HEAD == n->type && n->next->child) {
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
|
||||
p->trailspace = 0;
|
||||
} else if (MDOC_BODY == n->type && n->child)
|
||||
term_flushln(p);
|
||||
}
|
||||
@ -1375,14 +1380,14 @@ termp_vt_pre(DECL_ARGS)
|
||||
|
||||
if (MDOC_ELEM == n->type) {
|
||||
synopsis_pre(p, n);
|
||||
return(termp_under_pre(p, pair, m, n));
|
||||
return(termp_under_pre(p, pair, meta, n));
|
||||
} else if (MDOC_BLOCK == n->type) {
|
||||
synopsis_pre(p, n);
|
||||
return(1);
|
||||
} else if (MDOC_HEAD == n->type)
|
||||
return(0);
|
||||
|
||||
return(termp_under_pre(p, pair, m, n));
|
||||
return(termp_under_pre(p, pair, meta, n));
|
||||
}
|
||||
|
||||
|
||||
@ -1402,7 +1407,16 @@ termp_fd_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
synopsis_pre(p, n);
|
||||
return(termp_bold_pre(p, pair, m, n));
|
||||
return(termp_bold_pre(p, pair, meta, n));
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
termp_fd_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_newln(p);
|
||||
}
|
||||
|
||||
|
||||
@ -1425,6 +1439,8 @@ termp_sh_pre(DECL_ARGS)
|
||||
break;
|
||||
case (MDOC_BODY):
|
||||
p->offset = term_len(p, p->defindent);
|
||||
if (SEC_AUTHORS == n->sec)
|
||||
p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1497,17 +1513,6 @@ termp_d1_pre(DECL_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
termp_d1_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_BLOCK != n->type)
|
||||
return;
|
||||
term_newln(p);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
termp_ft_pre(DECL_ARGS)
|
||||
@ -1524,6 +1529,7 @@ termp_ft_pre(DECL_ARGS)
|
||||
static int
|
||||
termp_fn_pre(DECL_ARGS)
|
||||
{
|
||||
size_t rmargin = 0;
|
||||
int pretty;
|
||||
|
||||
pretty = MDOC_SYNPRETTY & n->flags;
|
||||
@ -1533,11 +1539,24 @@ termp_fn_pre(DECL_ARGS)
|
||||
if (NULL == (n = n->child))
|
||||
return(0);
|
||||
|
||||
if (pretty) {
|
||||
rmargin = p->rmargin;
|
||||
p->rmargin = p->offset + term_len(p, 4);
|
||||
p->flags |= TERMP_NOBREAK | TERMP_HANG;
|
||||
}
|
||||
|
||||
assert(MDOC_TEXT == n->type);
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (pretty) {
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = rmargin;
|
||||
}
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "(");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -1545,6 +1564,8 @@ termp_fn_pre(DECL_ARGS)
|
||||
for (n = n->next; n; n = n->next) {
|
||||
assert(MDOC_TEXT == n->type);
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
if (pretty)
|
||||
p->flags |= TERMP_NBRWORD;
|
||||
term_word(p, n->string);
|
||||
term_fontpop(p);
|
||||
|
||||
@ -1560,6 +1581,7 @@ termp_fn_pre(DECL_ARGS)
|
||||
if (pretty) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ";");
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
return(0);
|
||||
@ -1579,20 +1601,16 @@ termp_fa_pre(DECL_ARGS)
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
p->flags |= TERMP_NBRWORD;
|
||||
term_word(p, nn->string);
|
||||
term_fontpop(p);
|
||||
|
||||
if (nn->next) {
|
||||
if (nn->next || (n->next && n->next->tok == MDOC_Fa)) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
}
|
||||
|
||||
if (n->child && n->next && n->next->tok == MDOC_Fa) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ",");
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -1602,7 +1620,7 @@ static int
|
||||
termp_bd_pre(DECL_ARGS)
|
||||
{
|
||||
size_t tabwidth, rm, rmax;
|
||||
const struct mdoc_node *nn;
|
||||
struct mdoc_node *nn;
|
||||
|
||||
if (MDOC_BLOCK == n->type) {
|
||||
print_bvspace(p, n, n);
|
||||
@ -1634,7 +1652,7 @@ termp_bd_pre(DECL_ARGS)
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
print_mdoc_node(p, pair, m, nn);
|
||||
print_mdoc_node(p, pair, meta, nn);
|
||||
/*
|
||||
* If the printed node flushes its own line, then we
|
||||
* needn't do it here as well. This is hacky, but the
|
||||
@ -1751,7 +1769,8 @@ termp_xx_pre(DECL_ARGS)
|
||||
pp = "UNIX";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
term_word(p, pp);
|
||||
@ -1765,16 +1784,6 @@ termp_xx_pre(DECL_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
termp_igndelim_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
p->flags |= TERMP_IGNDELIM;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
termp_pf_post(DECL_ARGS)
|
||||
@ -1923,7 +1932,7 @@ termp_quote_pre(DECL_ARGS)
|
||||
case (MDOC_Do):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Dq):
|
||||
term_word(p, "``");
|
||||
term_word(p, "\\(lq");
|
||||
break;
|
||||
case (MDOC_Eo):
|
||||
break;
|
||||
@ -1944,7 +1953,7 @@ termp_quote_pre(DECL_ARGS)
|
||||
case (MDOC_So):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Sq):
|
||||
term_word(p, "`");
|
||||
term_word(p, "\\(oq");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -1989,7 +1998,7 @@ termp_quote_post(DECL_ARGS)
|
||||
case (MDOC_Do):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Dq):
|
||||
term_word(p, "''");
|
||||
term_word(p, "\\(rq");
|
||||
break;
|
||||
case (MDOC_Eo):
|
||||
break;
|
||||
@ -2010,7 +2019,7 @@ termp_quote_post(DECL_ARGS)
|
||||
case (MDOC_So):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Sq):
|
||||
term_word(p, "'");
|
||||
term_word(p, "\\(cq");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -2023,16 +2032,31 @@ termp_quote_post(DECL_ARGS)
|
||||
static int
|
||||
termp_fo_pre(DECL_ARGS)
|
||||
{
|
||||
size_t rmargin = 0;
|
||||
int pretty;
|
||||
|
||||
pretty = MDOC_SYNPRETTY & n->flags;
|
||||
|
||||
if (MDOC_BLOCK == n->type) {
|
||||
synopsis_pre(p, n);
|
||||
return(1);
|
||||
} else if (MDOC_BODY == n->type) {
|
||||
if (pretty) {
|
||||
rmargin = p->rmargin;
|
||||
p->rmargin = p->offset + term_len(p, 4);
|
||||
p->flags |= TERMP_NOBREAK | TERMP_HANG;
|
||||
}
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, "(");
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (pretty) {
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = rmargin;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == n->child)
|
||||
return(0);
|
||||
@ -2060,6 +2084,7 @@ termp_fo_post(DECL_ARGS)
|
||||
if (MDOC_SYNPRETTY & n->flags) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ";");
|
||||
term_flushln(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2071,7 +2096,7 @@ termp_bf_pre(DECL_ARGS)
|
||||
|
||||
if (MDOC_HEAD == n->type)
|
||||
return(0);
|
||||
else if (MDOC_BLOCK != n->type)
|
||||
else if (MDOC_BODY != n->type)
|
||||
return(1);
|
||||
|
||||
if (FONT_Em == n->norm->Bf.font)
|
||||
@ -2157,25 +2182,24 @@ termp_li_pre(DECL_ARGS)
|
||||
static int
|
||||
termp_lk_pre(DECL_ARGS)
|
||||
{
|
||||
const struct mdoc_node *nn, *sv;
|
||||
const struct mdoc_node *link, *descr;
|
||||
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
if (NULL == (link = n->child))
|
||||
return(0);
|
||||
|
||||
nn = sv = n->child;
|
||||
|
||||
if (NULL == nn || NULL == nn->next)
|
||||
return(1);
|
||||
|
||||
for (nn = nn->next; nn; nn = nn->next)
|
||||
term_word(p, nn->string);
|
||||
|
||||
term_fontpop(p);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ":");
|
||||
if (NULL != (descr = link->next)) {
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
while (NULL != descr) {
|
||||
term_word(p, descr->string);
|
||||
descr = descr->next;
|
||||
}
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ":");
|
||||
term_fontpop(p);
|
||||
}
|
||||
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, sv->string);
|
||||
term_word(p, link->string);
|
||||
term_fontpop(p);
|
||||
|
||||
return(0);
|
||||
@ -2225,9 +2249,9 @@ termp__t_post(DECL_ARGS)
|
||||
*/
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
n->parent->norm->Rs.quote_T)
|
||||
termp_quote_post(p, pair, m, n);
|
||||
termp_quote_post(p, pair, meta, n);
|
||||
|
||||
termp____post(p, pair, m, n);
|
||||
termp____post(p, pair, meta, n);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@ -2241,7 +2265,7 @@ termp__t_pre(DECL_ARGS)
|
||||
*/
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
n->parent->norm->Rs.quote_T)
|
||||
return(termp_quote_pre(p, pair, m, n));
|
||||
return(termp_quote_pre(p, pair, meta, n));
|
||||
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
return(1);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc_validate.c,v 1.182 2012/03/23 05:50:25 kristaps Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.198 2013/12/15 21:23:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -19,7 +19,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef OSNAME
|
||||
#ifndef OSNAME
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
@ -97,17 +97,19 @@ static int post_bl_block_width(POST_ARGS);
|
||||
static int post_bl_block_tag(POST_ARGS);
|
||||
static int post_bl_head(POST_ARGS);
|
||||
static int post_bx(POST_ARGS);
|
||||
static int post_defaults(POST_ARGS);
|
||||
static int post_dd(POST_ARGS);
|
||||
static int post_dt(POST_ARGS);
|
||||
static int post_defaults(POST_ARGS);
|
||||
static int post_literal(POST_ARGS);
|
||||
static int post_eoln(POST_ARGS);
|
||||
static int post_hyph(POST_ARGS);
|
||||
static int post_ignpar(POST_ARGS);
|
||||
static int post_it(POST_ARGS);
|
||||
static int post_lb(POST_ARGS);
|
||||
static int post_literal(POST_ARGS);
|
||||
static int post_nm(POST_ARGS);
|
||||
static int post_ns(POST_ARGS);
|
||||
static int post_os(POST_ARGS);
|
||||
static int post_ignpar(POST_ARGS);
|
||||
static int post_par(POST_ARGS);
|
||||
static int post_prol(POST_ARGS);
|
||||
static int post_root(POST_ARGS);
|
||||
static int post_rs(POST_ARGS);
|
||||
@ -141,27 +143,30 @@ static v_post posts_bx[] = { post_bx, NULL };
|
||||
static v_post posts_bool[] = { ebool, NULL };
|
||||
static v_post posts_eoln[] = { post_eoln, NULL };
|
||||
static v_post posts_defaults[] = { post_defaults, NULL };
|
||||
static v_post posts_d1[] = { bwarn_ge1, post_hyph, NULL };
|
||||
static v_post posts_dd[] = { post_dd, post_prol, NULL };
|
||||
static v_post posts_dl[] = { post_literal, bwarn_ge1, NULL };
|
||||
static v_post posts_dt[] = { post_dt, post_prol, NULL };
|
||||
static v_post posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL };
|
||||
static v_post posts_hyph[] = { post_hyph, NULL };
|
||||
static v_post posts_hyphtext[] = { ewarn_ge1, post_hyph, NULL };
|
||||
static v_post posts_it[] = { post_it, NULL };
|
||||
static v_post posts_lb[] = { post_lb, NULL };
|
||||
static v_post posts_nd[] = { berr_ge1, NULL };
|
||||
static v_post posts_nd[] = { berr_ge1, post_hyph, NULL };
|
||||
static v_post posts_nm[] = { post_nm, NULL };
|
||||
static v_post posts_notext[] = { ewarn_eq0, NULL };
|
||||
static v_post posts_ns[] = { post_ns, NULL };
|
||||
static v_post posts_os[] = { post_os, post_prol, NULL };
|
||||
static v_post posts_pp[] = { post_par, ewarn_eq0, NULL };
|
||||
static v_post posts_rs[] = { post_rs, NULL };
|
||||
static v_post posts_sh[] = { post_ignpar, hwarn_ge1, post_sh, NULL };
|
||||
static v_post posts_sp[] = { ewarn_le1, NULL };
|
||||
static v_post posts_ss[] = { post_ignpar, hwarn_ge1, NULL };
|
||||
static v_post posts_sh[] = { post_ignpar,hwarn_ge1,post_sh,post_hyph,NULL };
|
||||
static v_post posts_sp[] = { post_par, ewarn_le1, NULL };
|
||||
static v_post posts_ss[] = { post_ignpar, hwarn_ge1, post_hyph, NULL };
|
||||
static v_post posts_st[] = { post_st, NULL };
|
||||
static v_post posts_std[] = { post_std, NULL };
|
||||
static v_post posts_text[] = { ewarn_ge1, NULL };
|
||||
static v_post posts_text1[] = { ewarn_eq1, NULL };
|
||||
static v_post posts_vt[] = { post_vt, NULL };
|
||||
static v_post posts_wline[] = { bwarn_ge1, NULL };
|
||||
static v_pre pres_an[] = { pre_an, NULL };
|
||||
static v_pre pres_bd[] = { pre_display, pre_bd, pre_literal, pre_par, NULL };
|
||||
static v_pre pres_bl[] = { pre_bl, pre_par, NULL };
|
||||
@ -169,8 +174,6 @@ static v_pre pres_d1[] = { pre_display, NULL };
|
||||
static v_pre pres_dl[] = { pre_literal, pre_display, NULL };
|
||||
static v_pre pres_dd[] = { pre_dd, NULL };
|
||||
static v_pre pres_dt[] = { pre_dt, NULL };
|
||||
static v_pre pres_er[] = { NULL, NULL };
|
||||
static v_pre pres_fd[] = { NULL, NULL };
|
||||
static v_pre pres_it[] = { pre_it, pre_par, NULL };
|
||||
static v_pre pres_os[] = { pre_os, NULL };
|
||||
static v_pre pres_pp[] = { pre_par, NULL };
|
||||
@ -185,8 +188,8 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
{ pres_os, posts_os }, /* Os */
|
||||
{ pres_sh, posts_sh }, /* Sh */
|
||||
{ pres_ss, posts_ss }, /* Ss */
|
||||
{ pres_pp, posts_notext }, /* Pp */
|
||||
{ pres_d1, posts_wline }, /* D1 */
|
||||
{ pres_pp, posts_pp }, /* Pp */
|
||||
{ pres_d1, posts_d1 }, /* D1 */
|
||||
{ pres_dl, posts_dl }, /* Dl */
|
||||
{ pres_bd, posts_bd }, /* Bd */
|
||||
{ NULL, NULL }, /* Ed */
|
||||
@ -199,11 +202,11 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
{ NULL, NULL }, /* Cd */
|
||||
{ NULL, NULL }, /* Cm */
|
||||
{ NULL, NULL }, /* Dv */
|
||||
{ pres_er, NULL }, /* Er */
|
||||
{ NULL, NULL }, /* Er */
|
||||
{ NULL, NULL }, /* Ev */
|
||||
{ pres_std, posts_std }, /* Ex */
|
||||
{ NULL, NULL }, /* Fa */
|
||||
{ pres_fd, posts_text }, /* Fd */
|
||||
{ NULL, posts_text }, /* Fd */
|
||||
{ NULL, NULL }, /* Fl */
|
||||
{ NULL, NULL }, /* Fn */
|
||||
{ NULL, NULL }, /* Ft */
|
||||
@ -221,15 +224,15 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
{ NULL, posts_vt }, /* Vt */
|
||||
{ NULL, posts_text }, /* Xr */
|
||||
{ NULL, posts_text }, /* %A */
|
||||
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */
|
||||
{ NULL, posts_hyphtext }, /* %B */ /* FIXME: can be used outside Rs/Re. */
|
||||
{ NULL, posts_text }, /* %D */
|
||||
{ NULL, posts_text }, /* %I */
|
||||
{ NULL, posts_text }, /* %J */
|
||||
{ NULL, posts_text }, /* %N */
|
||||
{ NULL, posts_text }, /* %O */
|
||||
{ NULL, posts_hyphtext }, /* %N */
|
||||
{ NULL, posts_hyphtext }, /* %O */
|
||||
{ NULL, posts_text }, /* %P */
|
||||
{ NULL, posts_text }, /* %R */
|
||||
{ NULL, posts_text }, /* %T */ /* FIXME: can be used outside Rs/Re. */
|
||||
{ NULL, posts_hyphtext }, /* %R */
|
||||
{ NULL, posts_hyphtext }, /* %T */ /* FIXME: can be used outside Rs/Re. */
|
||||
{ NULL, posts_text }, /* %V */
|
||||
{ NULL, NULL }, /* Ac */
|
||||
{ NULL, NULL }, /* Ao */
|
||||
@ -269,7 +272,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
{ NULL, NULL }, /* So */
|
||||
{ NULL, NULL }, /* Sq */
|
||||
{ NULL, posts_bool }, /* Sm */
|
||||
{ NULL, NULL }, /* Sx */
|
||||
{ NULL, posts_hyph }, /* Sx */
|
||||
{ NULL, NULL }, /* Sy */
|
||||
{ NULL, NULL }, /* Tn */
|
||||
{ NULL, NULL }, /* Ux */
|
||||
@ -286,7 +289,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
{ NULL, NULL }, /* Fr */
|
||||
{ NULL, posts_eoln }, /* Ud */
|
||||
{ NULL, posts_lb }, /* Lb */
|
||||
{ NULL, posts_notext }, /* Lp */
|
||||
{ pres_pp, posts_pp }, /* Lp */
|
||||
{ NULL, NULL }, /* Lk */
|
||||
{ NULL, posts_defaults }, /* Mt */
|
||||
{ NULL, NULL }, /* Brq */
|
||||
@ -297,8 +300,8 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
|
||||
{ NULL, NULL }, /* En */
|
||||
{ NULL, NULL }, /* Dx */
|
||||
{ NULL, posts_text }, /* %Q */
|
||||
{ NULL, posts_notext }, /* br */
|
||||
{ pres_pp, posts_sp }, /* sp */
|
||||
{ NULL, posts_pp }, /* br */
|
||||
{ NULL, posts_sp }, /* sp */
|
||||
{ NULL, posts_text1 }, /* %U */
|
||||
{ NULL, NULL }, /* Ta */
|
||||
};
|
||||
@ -314,12 +317,12 @@ static const enum mdoct rsord[RSORD_MAX] = {
|
||||
MDOC__R,
|
||||
MDOC__N,
|
||||
MDOC__V,
|
||||
MDOC__U,
|
||||
MDOC__P,
|
||||
MDOC__Q,
|
||||
MDOC__D,
|
||||
MDOC__O,
|
||||
MDOC__C,
|
||||
MDOC__U
|
||||
MDOC__D,
|
||||
MDOC__O
|
||||
};
|
||||
|
||||
static const char * const secnames[SEC__MAX] = {
|
||||
@ -414,29 +417,29 @@ mdoc_valid_post(struct mdoc *mdoc)
|
||||
}
|
||||
|
||||
static int
|
||||
check_count(struct mdoc *m, enum mdoc_type type,
|
||||
check_count(struct mdoc *mdoc, enum mdoc_type type,
|
||||
enum check_lvl lvl, enum check_ineq ineq, int val)
|
||||
{
|
||||
const char *p;
|
||||
enum mandocerr t;
|
||||
|
||||
if (m->last->type != type)
|
||||
if (mdoc->last->type != type)
|
||||
return(1);
|
||||
|
||||
switch (ineq) {
|
||||
case (CHECK_LT):
|
||||
p = "less than ";
|
||||
if (m->last->nchild < val)
|
||||
if (mdoc->last->nchild < val)
|
||||
return(1);
|
||||
break;
|
||||
case (CHECK_GT):
|
||||
p = "more than ";
|
||||
if (m->last->nchild > val)
|
||||
if (mdoc->last->nchild > val)
|
||||
return(1);
|
||||
break;
|
||||
case (CHECK_EQ):
|
||||
p = "";
|
||||
if (val == m->last->nchild)
|
||||
if (val == mdoc->last->nchild)
|
||||
return(1);
|
||||
break;
|
||||
default:
|
||||
@ -445,9 +448,9 @@ check_count(struct mdoc *m, enum mdoc_type type,
|
||||
}
|
||||
|
||||
t = lvl == CHECK_WARN ? MANDOCERR_ARGCWARN : MANDOCERR_ARGCOUNT;
|
||||
mandoc_vmsg(t, m->parse, m->last->line, m->last->pos,
|
||||
mandoc_vmsg(t, mdoc->parse, mdoc->last->line, mdoc->last->pos,
|
||||
"want %s%d children (have %d)",
|
||||
p, val, m->last->nchild);
|
||||
p, val, mdoc->last->nchild);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -513,7 +516,7 @@ hwarn_le1(POST_ARGS)
|
||||
}
|
||||
|
||||
static void
|
||||
check_args(struct mdoc *m, struct mdoc_node *n)
|
||||
check_args(struct mdoc *mdoc, struct mdoc_node *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -522,34 +525,34 @@ check_args(struct mdoc *m, struct mdoc_node *n)
|
||||
|
||||
assert(n->args->argc);
|
||||
for (i = 0; i < (int)n->args->argc; i++)
|
||||
check_argv(m, n, &n->args->argv[i]);
|
||||
check_argv(mdoc, n, &n->args->argv[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
check_argv(struct mdoc *m, struct mdoc_node *n, struct mdoc_argv *v)
|
||||
check_argv(struct mdoc *mdoc, struct mdoc_node *n, struct mdoc_argv *v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (int)v->sz; i++)
|
||||
check_text(m, v->line, v->pos, v->value[i]);
|
||||
check_text(mdoc, v->line, v->pos, v->value[i]);
|
||||
|
||||
/* FIXME: move to post_std(). */
|
||||
|
||||
if (MDOC_Std == v->arg)
|
||||
if ( ! (v->sz || m->meta.name))
|
||||
mdoc_nmsg(m, n, MANDOCERR_NONAME);
|
||||
if ( ! (v->sz || mdoc->meta.name))
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_NONAME);
|
||||
}
|
||||
|
||||
static void
|
||||
check_text(struct mdoc *m, int ln, int pos, char *p)
|
||||
check_text(struct mdoc *mdoc, int ln, int pos, char *p)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (MDOC_LITERAL & m->flags)
|
||||
if (MDOC_LITERAL & mdoc->flags)
|
||||
return;
|
||||
|
||||
for (cp = p; NULL != (p = strchr(p, '\t')); p++)
|
||||
mdoc_pmsg(m, ln, pos + (int)(p - cp), MANDOCERR_BADTAB);
|
||||
mdoc_pmsg(mdoc, ln, pos + (int)(p - cp), MANDOCERR_BADTAB);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -733,14 +736,14 @@ pre_bl(PRE_ARGS)
|
||||
/*
|
||||
* Validate the width field. Some list types don't need width
|
||||
* types and should be warned about them. Others should have it
|
||||
* and must also be warned.
|
||||
* and must also be warned. Yet others have a default and need
|
||||
* no warning.
|
||||
*/
|
||||
|
||||
switch (n->norm->Bl.type) {
|
||||
case (LIST_tag):
|
||||
if (n->norm->Bl.width)
|
||||
break;
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG);
|
||||
if (NULL == n->norm->Bl.width)
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG);
|
||||
break;
|
||||
case (LIST_column):
|
||||
/* FALLTHROUGH */
|
||||
@ -754,6 +757,18 @@ pre_bl(PRE_ARGS)
|
||||
if (n->norm->Bl.width)
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV);
|
||||
break;
|
||||
case (LIST_bullet):
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_dash):
|
||||
/* FALLTHROUGH */
|
||||
case (LIST_hyphen):
|
||||
if (NULL == n->norm->Bl.width)
|
||||
n->norm->Bl.width = "2n";
|
||||
break;
|
||||
case (LIST_enum):
|
||||
if (NULL == n->norm->Bl.width)
|
||||
n->norm->Bl.width = "3n";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -874,8 +889,6 @@ pre_sh(PRE_ARGS)
|
||||
|
||||
if (MDOC_BLOCK != n->type)
|
||||
return(1);
|
||||
|
||||
roff_regunset(mdoc->roff, REG_nS);
|
||||
return(check_parent(mdoc, n, MDOC_MAX, MDOC_ROOT));
|
||||
}
|
||||
|
||||
@ -1111,24 +1124,29 @@ post_nm(POST_ARGS)
|
||||
char buf[BUFSIZ];
|
||||
int c;
|
||||
|
||||
/* If no child specified, make sure we have the meta name. */
|
||||
|
||||
if (NULL == mdoc->last->child && NULL == mdoc->meta.name) {
|
||||
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME);
|
||||
return(1);
|
||||
} else if (mdoc->meta.name)
|
||||
if (NULL != mdoc->meta.name)
|
||||
return(1);
|
||||
|
||||
/* If no meta name, set it from the child. */
|
||||
/* Try to use our children for setting the meta name. */
|
||||
|
||||
buf[0] = '\0';
|
||||
if (-1 == (c = concat(buf, mdoc->last->child, BUFSIZ))) {
|
||||
if (NULL != mdoc->last->child) {
|
||||
buf[0] = '\0';
|
||||
c = concat(buf, mdoc->last->child, BUFSIZ);
|
||||
} else
|
||||
c = 0;
|
||||
|
||||
switch (c) {
|
||||
case (-1):
|
||||
mdoc_nmsg(mdoc, mdoc->last->child, MANDOCERR_MEM);
|
||||
return(0);
|
||||
case (0):
|
||||
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NONAME);
|
||||
mdoc->meta.name = mandoc_strdup("UNKNOWN");
|
||||
break;
|
||||
default:
|
||||
mdoc->meta.name = mandoc_strdup(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
assert(c);
|
||||
mdoc->meta.name = mandoc_strdup(buf);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -1334,7 +1352,7 @@ post_it(POST_ARGS)
|
||||
static int
|
||||
post_bl_block(POST_ARGS)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
struct mdoc_node *n, *ni, *nc;
|
||||
|
||||
/*
|
||||
* These are fairly complicated, so we've broken them into two
|
||||
@ -1350,13 +1368,42 @@ post_bl_block(POST_ARGS)
|
||||
NULL == n->norm->Bl.width) {
|
||||
if ( ! post_bl_block_tag(mdoc))
|
||||
return(0);
|
||||
assert(n->norm->Bl.width);
|
||||
} else if (NULL != n->norm->Bl.width) {
|
||||
if ( ! post_bl_block_width(mdoc))
|
||||
return(0);
|
||||
} else
|
||||
return(1);
|
||||
assert(n->norm->Bl.width);
|
||||
}
|
||||
|
||||
assert(n->norm->Bl.width);
|
||||
for (ni = n->body->child; ni; ni = ni->next) {
|
||||
if (NULL == ni->body)
|
||||
continue;
|
||||
nc = ni->body->last;
|
||||
while (NULL != nc) {
|
||||
switch (nc->tok) {
|
||||
case (MDOC_Pp):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Lp):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_br):
|
||||
break;
|
||||
default:
|
||||
nc = NULL;
|
||||
continue;
|
||||
}
|
||||
if (NULL == ni->next) {
|
||||
mdoc_nmsg(mdoc, nc, MANDOCERR_MOVEPAR);
|
||||
if ( ! mdoc_node_relink(mdoc, nc))
|
||||
return(0);
|
||||
} else if (0 == n->norm->Bl.comp &&
|
||||
LIST_column != n->norm->Bl.type) {
|
||||
mdoc_nmsg(mdoc, nc, MANDOCERR_IGNPAR);
|
||||
mdoc_node_delete(mdoc, nc);
|
||||
} else
|
||||
break;
|
||||
nc = ni->body->last;
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -1544,32 +1591,71 @@ post_bl_head(POST_ARGS)
|
||||
static int
|
||||
post_bl(POST_ARGS)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
struct mdoc_node *nparent, *nprev; /* of the Bl block */
|
||||
struct mdoc_node *nblock, *nbody; /* of the Bl */
|
||||
struct mdoc_node *nchild, *nnext; /* of the Bl body */
|
||||
|
||||
if (MDOC_HEAD == mdoc->last->type)
|
||||
return(post_bl_head(mdoc));
|
||||
if (MDOC_BLOCK == mdoc->last->type)
|
||||
nbody = mdoc->last;
|
||||
switch (nbody->type) {
|
||||
case (MDOC_BLOCK):
|
||||
return(post_bl_block(mdoc));
|
||||
if (MDOC_BODY != mdoc->last->type)
|
||||
case (MDOC_HEAD):
|
||||
return(post_bl_head(mdoc));
|
||||
case (MDOC_BODY):
|
||||
break;
|
||||
default:
|
||||
return(1);
|
||||
}
|
||||
|
||||
for (n = mdoc->last->child; n; n = n->next) {
|
||||
switch (n->tok) {
|
||||
case (MDOC_Lp):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Pp):
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_CHILD);
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_It):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Sm):
|
||||
nchild = nbody->child;
|
||||
while (NULL != nchild) {
|
||||
if (MDOC_It == nchild->tok || MDOC_Sm == nchild->tok) {
|
||||
nchild = nchild->next;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_SYNTCHILD);
|
||||
return(0);
|
||||
mdoc_nmsg(mdoc, nchild, MANDOCERR_CHILD);
|
||||
|
||||
/*
|
||||
* Move the node out of the Bl block.
|
||||
* First, collect all required node pointers.
|
||||
*/
|
||||
|
||||
nblock = nbody->parent;
|
||||
nprev = nblock->prev;
|
||||
nparent = nblock->parent;
|
||||
nnext = nchild->next;
|
||||
|
||||
/*
|
||||
* Unlink this child.
|
||||
*/
|
||||
|
||||
assert(NULL == nchild->prev);
|
||||
if (0 == --nbody->nchild) {
|
||||
nbody->child = NULL;
|
||||
nbody->last = NULL;
|
||||
assert(NULL == nnext);
|
||||
} else {
|
||||
nbody->child = nnext;
|
||||
nnext->prev = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Relink this child.
|
||||
*/
|
||||
|
||||
nchild->parent = nparent;
|
||||
nchild->prev = nprev;
|
||||
nchild->next = nblock;
|
||||
|
||||
nblock->prev = nchild;
|
||||
nparent->nchild++;
|
||||
if (NULL == nprev)
|
||||
nparent->child = nchild;
|
||||
else
|
||||
nprev->next = nchild;
|
||||
|
||||
nchild = nnext;
|
||||
}
|
||||
|
||||
return(1);
|
||||
@ -1588,10 +1674,16 @@ ebool(struct mdoc *mdoc)
|
||||
|
||||
assert(MDOC_TEXT == mdoc->last->child->type);
|
||||
|
||||
if (0 == strcmp(mdoc->last->child->string, "on"))
|
||||
if (0 == strcmp(mdoc->last->child->string, "on")) {
|
||||
if (MDOC_Sm == mdoc->last->tok)
|
||||
mdoc->flags &= ~MDOC_SMOFF;
|
||||
return(1);
|
||||
if (0 == strcmp(mdoc->last->child->string, "off"))
|
||||
}
|
||||
if (0 == strcmp(mdoc->last->child->string, "off")) {
|
||||
if (MDOC_Sm == mdoc->last->tok)
|
||||
mdoc->flags |= MDOC_SMOFF;
|
||||
return(1);
|
||||
}
|
||||
|
||||
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_BADBOOL);
|
||||
return(1);
|
||||
@ -1771,6 +1863,47 @@ post_rs(POST_ARGS)
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* For some arguments of some macros,
|
||||
* convert all breakable hyphens into ASCII_HYPH.
|
||||
*/
|
||||
static int
|
||||
post_hyph(POST_ARGS)
|
||||
{
|
||||
struct mdoc_node *n, *nch;
|
||||
char *cp;
|
||||
|
||||
n = mdoc->last;
|
||||
switch (n->type) {
|
||||
case (MDOC_HEAD):
|
||||
if (MDOC_Sh == n->tok || MDOC_Ss == n->tok)
|
||||
break;
|
||||
return(1);
|
||||
case (MDOC_BODY):
|
||||
if (MDOC_D1 == n->tok || MDOC_Nd == n->tok)
|
||||
break;
|
||||
return(1);
|
||||
case (MDOC_ELEM):
|
||||
break;
|
||||
default:
|
||||
return(1);
|
||||
}
|
||||
|
||||
for (nch = n->child; nch; nch = nch->next) {
|
||||
if (MDOC_TEXT != nch->type)
|
||||
continue;
|
||||
cp = nch->string;
|
||||
if (3 > strnlen(cp, 3))
|
||||
continue;
|
||||
while ('\0' != *(++cp))
|
||||
if ('-' == *cp &&
|
||||
isalpha((unsigned char)cp[-1]) &&
|
||||
isalpha((unsigned char)cp[1]))
|
||||
*cp = ASCII_HYPH;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_ns(POST_ARGS)
|
||||
{
|
||||
@ -1857,10 +1990,13 @@ post_sh_head(POST_ARGS)
|
||||
|
||||
/* The SYNOPSIS gets special attention in other areas. */
|
||||
|
||||
if (SEC_SYNOPSIS == sec)
|
||||
if (SEC_SYNOPSIS == sec) {
|
||||
roff_setreg(mdoc->roff, "nS", 1, '=');
|
||||
mdoc->flags |= MDOC_SYNOPSIS;
|
||||
else
|
||||
} else {
|
||||
roff_setreg(mdoc->roff, "nS", 0, '=');
|
||||
mdoc->flags &= ~MDOC_SYNOPSIS;
|
||||
}
|
||||
|
||||
/* Mark our last section. */
|
||||
|
||||
@ -1916,7 +2052,8 @@ post_sh_head(POST_ARGS)
|
||||
break;
|
||||
if (*mdoc->meta.msec == '9')
|
||||
break;
|
||||
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SECMSEC);
|
||||
mandoc_msg(MANDOCERR_SECMSEC, mdoc->parse,
|
||||
mdoc->last->line, mdoc->last->pos, buf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1962,7 +2099,9 @@ pre_par(PRE_ARGS)
|
||||
* block: `Lp', `Pp', or non-compact `Bd' or `Bl'.
|
||||
*/
|
||||
|
||||
if (MDOC_Pp != mdoc->last->tok && MDOC_Lp != mdoc->last->tok)
|
||||
if (MDOC_Pp != mdoc->last->tok &&
|
||||
MDOC_Lp != mdoc->last->tok &&
|
||||
MDOC_br != mdoc->last->tok)
|
||||
return(1);
|
||||
if (MDOC_Bl == n->tok && n->norm->Bl.comp)
|
||||
return(1);
|
||||
@ -1976,6 +2115,32 @@ pre_par(PRE_ARGS)
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_par(POST_ARGS)
|
||||
{
|
||||
|
||||
if (MDOC_ELEM != mdoc->last->type &&
|
||||
MDOC_BLOCK != mdoc->last->type)
|
||||
return(1);
|
||||
|
||||
if (NULL == mdoc->last->prev) {
|
||||
if (MDOC_Sh != mdoc->last->parent->tok &&
|
||||
MDOC_Ss != mdoc->last->parent->tok)
|
||||
return(1);
|
||||
} else {
|
||||
if (MDOC_Pp != mdoc->last->prev->tok &&
|
||||
MDOC_Lp != mdoc->last->prev->tok &&
|
||||
(MDOC_br != mdoc->last->tok ||
|
||||
(MDOC_sp != mdoc->last->prev->tok &&
|
||||
MDOC_br != mdoc->last->prev->tok)))
|
||||
return(1);
|
||||
}
|
||||
|
||||
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_IGNPAR);
|
||||
mdoc_node_delete(mdoc, mdoc->last);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_literal(PRE_ARGS)
|
||||
{
|
||||
@ -2129,9 +2294,9 @@ post_dt(POST_ARGS)
|
||||
free(mdoc->meta.vol);
|
||||
mdoc->meta.vol = mandoc_strdup(cp);
|
||||
} else {
|
||||
/* FIXME: warn about bad arch. */
|
||||
cp = mdoc_a2arch(nn->string);
|
||||
if (NULL == cp) {
|
||||
mdoc_nmsg(mdoc, nn, MANDOCERR_BADVOLARCH);
|
||||
free(mdoc->meta.vol);
|
||||
mdoc->meta.vol = mandoc_strdup(nn->string);
|
||||
} else
|
||||
@ -2192,14 +2357,15 @@ post_os(POST_ARGS)
|
||||
n = mdoc->last;
|
||||
|
||||
/*
|
||||
* Set the operating system by way of the `Os' macro. Note that
|
||||
* if an argument isn't provided and -DOSNAME="\"foo\"" is
|
||||
* provided during compilation, this value will be used instead
|
||||
* of filling in "sysname release" from uname().
|
||||
* Set the operating system by way of the `Os' macro.
|
||||
* The order of precedence is:
|
||||
* 1. the argument of the `Os' macro, unless empty
|
||||
* 2. the -Ios=foo command line argument, if provided
|
||||
* 3. -DOSNAME="\"foo\"", if provided during compilation
|
||||
* 4. "sysname release" from uname(3)
|
||||
*/
|
||||
|
||||
if (mdoc->meta.os)
|
||||
free(mdoc->meta.os);
|
||||
free(mdoc->meta.os);
|
||||
|
||||
buf[0] = '\0';
|
||||
if (-1 == (c = concat(buf, n->child, BUFSIZ))) {
|
||||
@ -2209,11 +2375,11 @@ post_os(POST_ARGS)
|
||||
|
||||
assert(c);
|
||||
|
||||
/* XXX: yes, these can all be dynamically-adjusted buffers, but
|
||||
* it's really not worth the extra hackery.
|
||||
*/
|
||||
|
||||
if ('\0' == buf[0]) {
|
||||
if (mdoc->defos) {
|
||||
mdoc->meta.os = mandoc_strdup(mdoc->defos);
|
||||
return(1);
|
||||
}
|
||||
#ifdef OSNAME
|
||||
if (strlcat(buf, OSNAME, BUFSIZ) >= BUFSIZ) {
|
||||
mdoc_nmsg(mdoc, n, MANDOCERR_MEM);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: out.c,v 1.43 2011/09/20 23:05:49 schwarze Exp $ */
|
||||
/* $Id: out.c,v 1.46 2013/10/05 20:30:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -32,11 +32,11 @@
|
||||
#include "out.h"
|
||||
|
||||
static void tblcalc_data(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl *, const struct tbl_dat *);
|
||||
const struct tbl_opts *, const struct tbl_dat *);
|
||||
static void tblcalc_literal(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl_dat *);
|
||||
static void tblcalc_number(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl *, const struct tbl_dat *);
|
||||
const struct tbl_opts *, const struct tbl_dat *);
|
||||
|
||||
/*
|
||||
* Convert a `scaling unit' to a consistent form, or fail. Scaling
|
||||
@ -142,7 +142,6 @@ void
|
||||
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_dat *dp;
|
||||
const struct tbl_head *hp;
|
||||
struct roffcol *col;
|
||||
int spans;
|
||||
|
||||
@ -154,9 +153,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
||||
|
||||
assert(NULL == tbl->cols);
|
||||
tbl->cols = mandoc_calloc
|
||||
((size_t)sp->tbl->cols, sizeof(struct roffcol));
|
||||
|
||||
hp = sp->head;
|
||||
((size_t)sp->opts->cols, sizeof(struct roffcol));
|
||||
|
||||
for ( ; sp; sp = sp->next) {
|
||||
if (TBL_SPAN_DATA != sp->pos)
|
||||
@ -175,33 +172,14 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
||||
continue;
|
||||
assert(dp->layout);
|
||||
col = &tbl->cols[dp->layout->head->ident];
|
||||
tblcalc_data(tbl, col, sp->tbl, dp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate width of the spanners. These get one space for a
|
||||
* vertical line, two for a double-vertical line.
|
||||
*/
|
||||
|
||||
for ( ; hp; hp = hp->next) {
|
||||
col = &tbl->cols[hp->ident];
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
col->width = (*tbl->len)(1, tbl->arg);
|
||||
break;
|
||||
case (TBL_HEAD_DVERT):
|
||||
col->width = (*tbl->len)(2, tbl->arg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
tblcalc_data(tbl, col, sp->opts, dp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl *tp, const struct tbl_dat *dp)
|
||||
const struct tbl_opts *opts, const struct tbl_dat *dp)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
@ -225,7 +203,7 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
tblcalc_literal(tbl, col, dp);
|
||||
break;
|
||||
case (TBL_CELL_NUMBER):
|
||||
tblcalc_number(tbl, col, tp, dp);
|
||||
tblcalc_number(tbl, col, opts, dp);
|
||||
break;
|
||||
case (TBL_CELL_DOWN):
|
||||
break;
|
||||
@ -251,7 +229,7 @@ tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
|
||||
|
||||
static void
|
||||
tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl *tp, const struct tbl_dat *dp)
|
||||
const struct tbl_opts *opts, const struct tbl_dat *dp)
|
||||
{
|
||||
int i;
|
||||
size_t sz, psz, ssz, d;
|
||||
@ -273,12 +251,12 @@ tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
|
||||
|
||||
/* FIXME: TBL_DATA_HORIZ et al.? */
|
||||
|
||||
buf[0] = tp->decimal;
|
||||
buf[0] = opts->decimal;
|
||||
buf[1] = '\0';
|
||||
|
||||
psz = (*tbl->slen)(buf, tbl->arg);
|
||||
|
||||
if (NULL != (cp = strrchr(str, tp->decimal))) {
|
||||
if (NULL != (cp = strrchr(str, opts->decimal))) {
|
||||
buf[1] = '\0';
|
||||
for (ssz = 0, i = 0; cp != &str[i]; i++) {
|
||||
buf[0] = str[i];
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: predefs.in,v 1.3 2011/07/31 11:36:49 schwarze Exp $ */
|
||||
/* $Id: predefs.in,v 1.4 2012/07/18 10:39:19 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
PREDEF("Am", "&")
|
||||
PREDEF("Ba", "|")
|
||||
PREDEF("Ba", "\\fR|\\fP")
|
||||
PREDEF("Ge", "\\(>=")
|
||||
PREDEF("Gt", ">")
|
||||
PREDEF("If", "infinity")
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: read.c,v 1.28 2012/02/16 20:51:31 joerg Exp $ */
|
||||
/* $Id: read.c,v 1.39 2013/09/16 00:25:07 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -40,10 +40,6 @@
|
||||
#include "man.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
|
||||
#define REPARSE_LIMIT 1000
|
||||
|
||||
struct buf {
|
||||
@ -66,14 +62,16 @@ struct mparse {
|
||||
void *arg; /* argument to mmsg */
|
||||
const char *file;
|
||||
struct buf *secondary;
|
||||
char *defos; /* default operating system */
|
||||
};
|
||||
|
||||
static void resize_buf(struct buf *, size_t);
|
||||
static void mparse_buf_r(struct mparse *, struct buf, int);
|
||||
static void mparse_readfd_r(struct mparse *, int, const char *, int);
|
||||
static void pset(const char *, int, struct mparse *);
|
||||
static int read_whole_file(const char *, int, struct buf *, int *);
|
||||
static void mparse_end(struct mparse *);
|
||||
static void mparse_parse_buffer(struct mparse *, struct buf,
|
||||
const char *);
|
||||
|
||||
static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = {
|
||||
MANDOCERR_OK,
|
||||
@ -94,6 +92,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"no title in document",
|
||||
"document title should be all caps",
|
||||
"unknown manual section",
|
||||
"unknown manual volume or arch",
|
||||
"date missing, using today's date",
|
||||
"cannot parse date, using it verbatim",
|
||||
"prologue macros out of order",
|
||||
@ -105,14 +104,14 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
".so is fragile, better use ln(1)",
|
||||
"NAME section must come first",
|
||||
"bad NAME section contents",
|
||||
"manual name not yet set",
|
||||
"sections out of conventional order",
|
||||
"duplicate section name",
|
||||
"section not in conventional manual section",
|
||||
"section header suited to sections 2, 3, and 9 only",
|
||||
|
||||
/* related to macros and nesting */
|
||||
"skipping obsolete macro",
|
||||
"skipping paragraph macro",
|
||||
"moving paragraph macro out of list",
|
||||
"skipping no-space macro",
|
||||
"blocks badly nested",
|
||||
"child violates parent syntax",
|
||||
@ -173,10 +172,12 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"input stack limit exceeded, infinite loop?",
|
||||
"skipping bad character",
|
||||
"escaped character not allowed in a name",
|
||||
"manual name not yet set",
|
||||
"skipping text before the first section header",
|
||||
"skipping unknown macro",
|
||||
"NOT IMPLEMENTED, please use groff: skipping request",
|
||||
"argument count wrong",
|
||||
"skipping column outside column list",
|
||||
"skipping end of block that is not open",
|
||||
"missing end of block",
|
||||
"scope open on exit",
|
||||
@ -184,6 +185,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"macro requires line argument(s)",
|
||||
"macro requires body argument(s)",
|
||||
"macro requires argument(s)",
|
||||
"request requires a numeric argument",
|
||||
"missing list type",
|
||||
"line argument(s) will be lost",
|
||||
"body argument(s) will be lost",
|
||||
@ -247,7 +249,8 @@ pset(const char *buf, int pos, struct mparse *curp)
|
||||
switch (curp->inttype) {
|
||||
case (MPARSE_MDOC):
|
||||
if (NULL == curp->pmdoc)
|
||||
curp->pmdoc = mdoc_alloc(curp->roff, curp);
|
||||
curp->pmdoc = mdoc_alloc(curp->roff, curp,
|
||||
curp->defos);
|
||||
assert(curp->pmdoc);
|
||||
curp->mdoc = curp->pmdoc;
|
||||
return;
|
||||
@ -263,7 +266,8 @@ pset(const char *buf, int pos, struct mparse *curp)
|
||||
|
||||
if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
|
||||
if (NULL == curp->pmdoc)
|
||||
curp->pmdoc = mdoc_alloc(curp->roff, curp);
|
||||
curp->pmdoc = mdoc_alloc(curp->roff, curp,
|
||||
curp->defos);
|
||||
assert(curp->pmdoc);
|
||||
curp->mdoc = curp->pmdoc;
|
||||
return;
|
||||
@ -322,6 +326,15 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we have space for at least
|
||||
* one backslash and one other character
|
||||
* and the trailing NUL byte.
|
||||
*/
|
||||
|
||||
if (pos + 2 >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
|
||||
/*
|
||||
* Warn about bogus characters. If you're using
|
||||
* non-ASCII encoding, you're screwing your
|
||||
@ -338,8 +351,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
||||
mandoc_msg(MANDOCERR_BADCHAR, curp,
|
||||
curp->line, pos, NULL);
|
||||
i++;
|
||||
if (pos >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
ln.buf[pos++] = '?';
|
||||
continue;
|
||||
}
|
||||
@ -347,8 +358,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
||||
/* Trailing backslash = a plain char. */
|
||||
|
||||
if ('\\' != blk.buf[i] || i + 1 == (int)blk.sz) {
|
||||
if (pos >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
continue;
|
||||
}
|
||||
@ -390,10 +399,20 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Some other escape sequence, copy & cont. */
|
||||
/* Catch escaped bogus characters. */
|
||||
|
||||
if (pos + 1 >= (int)ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
c = (unsigned char) blk.buf[i+1];
|
||||
|
||||
if ( ! (isascii(c) &&
|
||||
(isgraph(c) || isblank(c)))) {
|
||||
mandoc_msg(MANDOCERR_BADCHAR, curp,
|
||||
curp->line, pos, NULL);
|
||||
i += 2;
|
||||
ln.buf[pos++] = '?';
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Some other escape sequence, copy & cont. */
|
||||
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
@ -469,7 +488,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, int start)
|
||||
*/
|
||||
if (curp->secondary)
|
||||
curp->secondary->sz -= pos + 1;
|
||||
mparse_readfd_r(curp, -1, ln.buf + of, 1);
|
||||
mparse_readfd(curp, -1, ln.buf + of);
|
||||
if (MANDOCLEVEL_FATAL <= curp->file_status)
|
||||
break;
|
||||
pos = 0;
|
||||
@ -575,8 +594,7 @@ read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap)
|
||||
}
|
||||
*with_mmap = 1;
|
||||
fb->sz = (size_t)st.st_size;
|
||||
fb->buf = mmap(NULL, fb->sz, PROT_READ,
|
||||
MAP_FILE|MAP_SHARED, fd, 0);
|
||||
fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (fb->buf != MAP_FAILED)
|
||||
return(1);
|
||||
}
|
||||
@ -643,19 +661,25 @@ mparse_end(struct mparse *curp)
|
||||
}
|
||||
|
||||
static void
|
||||
mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file,
|
||||
int re)
|
||||
mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file)
|
||||
{
|
||||
const char *svfile;
|
||||
static int recursion_depth;
|
||||
|
||||
if (64 < recursion_depth) {
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP, curp, curp->line, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Line number is per-file. */
|
||||
svfile = curp->file;
|
||||
curp->file = file;
|
||||
curp->line = 1;
|
||||
recursion_depth++;
|
||||
|
||||
mparse_buf_r(curp, blk, 1);
|
||||
|
||||
if (0 == re && MANDOCLEVEL_FATAL > curp->file_status)
|
||||
if (0 == --recursion_depth && MANDOCLEVEL_FATAL > curp->file_status)
|
||||
mparse_end(curp);
|
||||
|
||||
curp->file = svfile;
|
||||
@ -670,12 +694,12 @@ mparse_readmem(struct mparse *curp, const void *buf, size_t len,
|
||||
blk.buf = UNCONST(buf);
|
||||
blk.sz = len;
|
||||
|
||||
mparse_parse_buffer(curp, blk, file, 0);
|
||||
mparse_parse_buffer(curp, blk, file);
|
||||
return(curp->file_status);
|
||||
}
|
||||
|
||||
static void
|
||||
mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re)
|
||||
enum mandoclevel
|
||||
mparse_readfd(struct mparse *curp, int fd, const char *file)
|
||||
{
|
||||
struct buf blk;
|
||||
int with_mmap;
|
||||
@ -684,7 +708,7 @@ mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re)
|
||||
if (-1 == (fd = open(file, O_RDONLY, 0))) {
|
||||
perror(file);
|
||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Run for each opened file; may be called more than once for
|
||||
@ -695,10 +719,10 @@ mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re)
|
||||
|
||||
if ( ! read_whole_file(file, fd, &blk, &with_mmap)) {
|
||||
curp->file_status = MANDOCLEVEL_SYSERR;
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mparse_parse_buffer(curp, blk, file, re);
|
||||
mparse_parse_buffer(curp, blk, file);
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
if (with_mmap)
|
||||
@ -709,18 +733,13 @@ mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re)
|
||||
|
||||
if (STDIN_FILENO != fd && -1 == close(fd))
|
||||
perror(file);
|
||||
}
|
||||
|
||||
enum mandoclevel
|
||||
mparse_readfd(struct mparse *curp, int fd, const char *file)
|
||||
{
|
||||
|
||||
mparse_readfd_r(curp, fd, file, 0);
|
||||
out:
|
||||
return(curp->file_status);
|
||||
}
|
||||
|
||||
struct mparse *
|
||||
mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, mandocmsg mmsg, void *arg)
|
||||
mparse_alloc(enum mparset inttype, enum mandoclevel wlevel,
|
||||
mandocmsg mmsg, void *arg, char *defos)
|
||||
{
|
||||
struct mparse *curp;
|
||||
|
||||
@ -732,8 +751,9 @@ mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, mandocmsg mmsg, void
|
||||
curp->mmsg = mmsg;
|
||||
curp->arg = arg;
|
||||
curp->inttype = inttype;
|
||||
curp->defos = defos;
|
||||
|
||||
curp->roff = roff_alloc(curp);
|
||||
curp->roff = roff_alloc(inttype, curp);
|
||||
return(curp);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: roff.7,v 1.37 2011/12/11 00:38:11 schwarze Exp $
|
||||
.\" $Id: roff.7,v 1.46 2013/12/26 02:43:18 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: December 11 2011 $
|
||||
.Dd $Mdocdate: December 26 2013 $
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -32,7 +32,7 @@ and
|
||||
manual formatting languages are based on it,
|
||||
many real-world manuals use small numbers of
|
||||
.Nm
|
||||
requests intermixed with their
|
||||
requests and escape sequences intermixed with their
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
@ -41,8 +41,8 @@ To properly format such manuals, the
|
||||
.Xr mandoc 1
|
||||
utility supports a tiny subset of
|
||||
.Nm
|
||||
requests.
|
||||
Only these requests supported by
|
||||
requests and escapes.
|
||||
Only these requests and escapes supported by
|
||||
.Xr mandoc 1
|
||||
are documented in the present manual,
|
||||
together with the basic language syntax shared by
|
||||
@ -83,9 +83,9 @@ depends on the respective processing context.
|
||||
.Nm
|
||||
documents may contain only graphable 7-bit ASCII characters, the space
|
||||
character, and, in certain circumstances, the tab character.
|
||||
The back-space character
|
||||
The backslash character
|
||||
.Sq \e
|
||||
indicates the start of an escape sequence for
|
||||
indicates the start of an escape sequence, used for example for
|
||||
.Sx Comments ,
|
||||
.Sx Special Characters ,
|
||||
.Sx Predefined Strings ,
|
||||
@ -93,6 +93,9 @@ and
|
||||
user-defined strings defined using the
|
||||
.Sx ds
|
||||
request.
|
||||
For a listing of escape sequences, consult the
|
||||
.Sx ESCAPE SEQUENCE REFERENCE
|
||||
below.
|
||||
.Ss Comments
|
||||
Text following an escaped double-quote
|
||||
.Sq \e\(dq ,
|
||||
@ -146,12 +149,19 @@ respectively) may be used instead.
|
||||
The indicator or numerical representative may be preceded by C
|
||||
(constant-width), which is ignored.
|
||||
.Pp
|
||||
The two-character indicator
|
||||
.Sq BI
|
||||
requests a font that is both bold and italic.
|
||||
It may not be portable to old roff implementations.
|
||||
.Pp
|
||||
Examples:
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Li \efBbold\efR
|
||||
Write in bold, then switch to regular font mode.
|
||||
Write in \fBbold\fP, then switch to regular font mode.
|
||||
.It Li \efIitalic\efP
|
||||
Write in italic, then return to previous font mode.
|
||||
Write in \fIitalic\fP, then return to previous font mode.
|
||||
.It Li \ef(BIbold italic\efP
|
||||
Write in \f(BIbold italic\fP, then return to previous font mode.
|
||||
.El
|
||||
.Pp
|
||||
Text decoration is
|
||||
@ -417,6 +427,18 @@ The syntax of this request is the same as that of
|
||||
It is currently ignored by
|
||||
.Xr mandoc 1 ,
|
||||
as are its children.
|
||||
.Ss \&cc
|
||||
Changes the control character.
|
||||
Its syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
.Pf . Cm \&cc Op Ar c
|
||||
.Ed
|
||||
.Pp
|
||||
If
|
||||
.Ar c
|
||||
is not specified, the control character is reset to
|
||||
.Sq \&. .
|
||||
Trailing characters are ignored.
|
||||
.Ss \&de
|
||||
Define a
|
||||
.Nm
|
||||
@ -619,6 +641,15 @@ Begin an equation block.
|
||||
See
|
||||
.Xr eqn 7
|
||||
for a description of the equation language.
|
||||
.Ss \&fam
|
||||
Change the font family.
|
||||
This line-scoped request is intended to have one argument specifying
|
||||
the font family to be selected.
|
||||
It is a groff extension, and currently, it is ignored including its
|
||||
arguments, and the number of arguments is not checked.
|
||||
.Ss \&hw
|
||||
Specify hyphenation points in words.
|
||||
This line-scoped request is currently ignored.
|
||||
.Ss \&hy
|
||||
Set automatic hyphenation mode.
|
||||
This line-scoped request is currently ignored.
|
||||
@ -786,19 +817,22 @@ the name of the request, macro or string to be undefined.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
.Ss \&nr
|
||||
Define a register.
|
||||
Define or change a register.
|
||||
A register is an arbitrary string value that defines some sort of state,
|
||||
which influences parsing and/or formatting.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Cm \&nr Ar name Ar value
|
||||
.D1 Pf \. Cm \&nr Ar name Oo +|- Oc Ns Ar value
|
||||
.Pp
|
||||
The
|
||||
.Ar value
|
||||
may, at the moment, only be an integer.
|
||||
So far, only the following register
|
||||
If it is prefixed by a sign, the register will be
|
||||
incremented or decremented instead of assigned to.
|
||||
.Pp
|
||||
The following register
|
||||
.Ar name
|
||||
is recognised:
|
||||
is handled specially:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm nS
|
||||
If set to a positive integer value, certain
|
||||
@ -895,8 +929,251 @@ Begin a table, which formats input in aligned rows and columns.
|
||||
See
|
||||
.Xr tbl 7
|
||||
for a description of the tbl language.
|
||||
.Sh ESCAPE SEQUENCE REFERENCE
|
||||
The
|
||||
.Xr mandoc 1
|
||||
.Nm
|
||||
parser recognises the following escape sequences.
|
||||
Note that the
|
||||
.Nm
|
||||
language defines more escape sequences not implemented in
|
||||
.Xr mandoc 1 .
|
||||
In
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
documents, using escape sequences is discouraged except for those
|
||||
described in the
|
||||
.Sx LANGUAGE SYNTAX
|
||||
section above.
|
||||
.Pp
|
||||
A backslash followed by any character not listed here
|
||||
simply prints that character itself.
|
||||
.Ss \e<newline>
|
||||
A backslash at the end of an input line can be used to continue the
|
||||
logical input line on the next physical input line, joining the text
|
||||
on both lines together as if it were on a single input line.
|
||||
.Ss \e<space>
|
||||
The escape sequence backslash-space
|
||||
.Pq Sq \e\ \&
|
||||
is an unpaddable space-sized non-breaking space character; see
|
||||
.Sx Whitespace .
|
||||
.Ss \e\(dq
|
||||
The rest of the input line is treated as
|
||||
.Sx Comments .
|
||||
.Ss \e%
|
||||
Hyphenation allowed at this point of the word; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \e&
|
||||
Non-printing zero-width character; see
|
||||
.Sx Whitespace .
|
||||
.Ss \e\(aq
|
||||
Acute accent special character; use
|
||||
.Sq \e(aa
|
||||
instead.
|
||||
.Ss \e( Ns Ar cc
|
||||
.Sx Special Characters
|
||||
with two-letter names, see
|
||||
.Xr mandoc_char 7 .
|
||||
.Ss \e*[ Ns Ar name ]
|
||||
Interpolate the string with the
|
||||
.Ar name ;
|
||||
see
|
||||
.Sx Predefined Strings
|
||||
and
|
||||
.Sx ds .
|
||||
For short names, there are variants
|
||||
.No \e* Ns Ar c
|
||||
and
|
||||
.No \e*( Ns Ar cc .
|
||||
.Ss \e-
|
||||
Special character
|
||||
.Dq mathematical minus sign .
|
||||
.Ss \e[ Ns Ar name ]
|
||||
.Sx Special Characters
|
||||
with names of arbitrary length, see
|
||||
.Xr mandoc_char 7 .
|
||||
.Ss \e^
|
||||
One-twelfth em half-narrow space character, effectively zero-width in
|
||||
.Xr mandoc 1 .
|
||||
.Ss \e`
|
||||
Grave accent special character; use
|
||||
.Sq \e(ga
|
||||
instead.
|
||||
.Ss \e{
|
||||
Begin conditional input; see
|
||||
.Sx if .
|
||||
.Ss \e\(ba
|
||||
One-sixth em narrow space character, effectively zero-width in
|
||||
.Xr mandoc 1 .
|
||||
.Ss \e}
|
||||
End conditional input; see
|
||||
.Sx if .
|
||||
.Ss \e~
|
||||
Paddable non-breaking space character.
|
||||
.Ss \e0
|
||||
Digit width space character.
|
||||
.Ss \eA\(aq Ns Ar string Ns \(aq
|
||||
Anchor definition; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eB\(aq Ns Ar string Ns \(aq
|
||||
Test whether
|
||||
.Ar string
|
||||
is a numerical expession; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eb\(aq Ns Ar string Ns \(aq
|
||||
Bracket building function; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eC\(aq Ns Ar name Ns \(aq
|
||||
.Sx Special Characters
|
||||
with names of arbitrary length.
|
||||
.Ss \ec
|
||||
Interrupt text processing to insert requests or macros; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eD\(aq Ns Ar string Ns \(aq
|
||||
Draw graphics function; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ed
|
||||
Move down by half a line; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ee
|
||||
Backslash special character.
|
||||
.Ss \eF[ Ns Ar name ]
|
||||
Switch font family (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \eF Ns Ar c
|
||||
and
|
||||
.No \eF( Ns Ar cc .
|
||||
.Ss \ef[ Ns Ar name ]
|
||||
Switch to the font
|
||||
.Ar name ,
|
||||
see
|
||||
.Sx Text Decoration .
|
||||
For short names, there are variants
|
||||
.No \ef Ns Ar c
|
||||
and
|
||||
.No \ef( Ns Ar cc .
|
||||
.Ss \eg[ Ns Ar name ]
|
||||
Interpolate the format of a number register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \eg Ns Ar c
|
||||
and
|
||||
.No \eg( Ns Ar cc .
|
||||
.Ss \eH\(aq Ns Oo +|- Oc Ns Ar number Ns \(aq
|
||||
Set the height of the current font; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eh\(aq Ns Ar number Ns \(aq
|
||||
Horizontal motion; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ek[ Ns Ar name ]
|
||||
Mark horizontal input place in register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \ek Ns Ar c
|
||||
and
|
||||
.No \ek( Ns Ar cc .
|
||||
.Ss \eL\(aq Ns Ar number Ns Oo Ar c Oc Ns \(aq
|
||||
Vertical line drawing function; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \el\(aq Ns Ar number Ns Oo Ar c Oc Ns \(aq
|
||||
Horizontal line drawing function; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eM[ Ns Ar name ]
|
||||
Set fill (background) color (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \eM Ns Ar c
|
||||
and
|
||||
.No \eM( Ns Ar cc .
|
||||
.Ss \em[ Ns Ar name ]
|
||||
Set glyph drawing color (groff extension); ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \em Ns Ar c
|
||||
and
|
||||
.No \em( Ns Ar cc .
|
||||
.Ss \eN\(aq Ns Ar number Ns \(aq
|
||||
Character
|
||||
.Ar number
|
||||
on the current font.
|
||||
.Ss \en[ Ns Ar name ]
|
||||
Interpolate the number register
|
||||
.Ar name .
|
||||
For short names, there are variants
|
||||
.No \en Ns Ar c
|
||||
and
|
||||
.No \en( Ns Ar cc .
|
||||
.Ss \eo\(aq Ns Ar string Ns \(aq
|
||||
Overstrike
|
||||
.Ar string ;
|
||||
ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eR\(aq Ns Ar name Oo +|- Oc Ns Ar number Ns \(aq
|
||||
Set number register; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eS\(aq Ns Ar number Ns \(aq
|
||||
Slant output; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \es\(aq Ns Oo +|- Oc Ns Ar number Ns \(aq
|
||||
Change point size; ignored by
|
||||
.Xr mandoc 1 .
|
||||
Alternative forms
|
||||
.No \es Ns Oo +|- Oc Ns Ar n ,
|
||||
.No \es Ns Oo +|- Oc Ns \(aq Ns Ar number Ns \(aq ,
|
||||
.No \es Ns [ Oo +|- Oc Ns Ar number ] ,
|
||||
and
|
||||
.No \es Ns Oo +|- Oc Ns [ Ar number Ns ]
|
||||
are also parsed and ignored.
|
||||
.Ss \et
|
||||
Horizontal tab; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eu
|
||||
Move up by half a line; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eV[ Ns Ar name ]
|
||||
Interpolate an environment variable; ignored by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \eV Ns Ar c
|
||||
and
|
||||
.No \eV( Ns Ar cc .
|
||||
.Ss \ev\(aq Ns Ar number Ns \(aq
|
||||
Vertical motion; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ew\(aq Ns Ar string Ns \(aq
|
||||
Interpolate the width of the
|
||||
.Ar string ;
|
||||
ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eX\(aq Ns Ar string Ns \(aq
|
||||
Output
|
||||
.Ar string
|
||||
as device control function; ignored in nroff mode and by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ex\(aq Ns Ar number Ns \(aq
|
||||
Extra line space function; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \eY[ Ns Ar name ]
|
||||
Output a string as a device control function; ignored in nroff mode and by
|
||||
.Xr mandoc 1 .
|
||||
For short names, there are variants
|
||||
.No \eY Ns Ar c
|
||||
and
|
||||
.No \eY( Ns Ar cc .
|
||||
.Ss \eZ\(aq Ns Ar string Ns \(aq
|
||||
Print
|
||||
.Ar string
|
||||
with zero width and height; ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss \ez
|
||||
Output the next character without advancing the cursor position;
|
||||
approximated in
|
||||
.Xr mandoc 1
|
||||
by simply skipping the next character.
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility between mandoc and other other
|
||||
This section documents compatibility between mandoc and other
|
||||
.Nm
|
||||
implementations, at this time limited to GNU troff
|
||||
.Pq Qq groff .
|
||||
@ -982,8 +1259,6 @@ In 1989, James Clarke re-implemented troff in C++, naming it groff.
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv ;
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||
and
|
||||
.An Ingo Schwarze ,
|
||||
.Mt schwarze@openbsd.org .
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $Id: st.in,v 1.19 2012/02/26 21:47:09 schwarze Exp $ */
|
||||
/* $Id: st.in,v 1.22 2013/12/25 14:09:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -35,16 +35,19 @@ LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)")
|
||||
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)")
|
||||
LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)")
|
||||
LINE("-p1003.1d-99", "IEEE Std 1003.1d-1999 (\\(lqPOSIX.1d\\(rq)")
|
||||
LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)")
|
||||
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)")
|
||||
LINE("-p1003.1j-2000", "IEEE Std 1003.1j-2000 (\\(lqPOSIX.1j\\(rq)")
|
||||
LINE("-p1003.1q-2000", "IEEE Std 1003.1q-2000 (\\(lqPOSIX.1q\\(rq)")
|
||||
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1387.2-95", "IEEE Std 1387.2-1995 (\\(lqPOSIX.7.2\\(rq)")
|
||||
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1387.2", "IEEE Std 1387.2 (\\(lqPOSIX.7.2\\(rq)")
|
||||
LINE("-p1387.2-95", "IEEE Std 1387.2-1995 (\\(lqPOSIX.7.2\\(rq)")
|
||||
LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
||||
LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)")
|
||||
LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO\\~C90, Amendment 1\\(rq)")
|
||||
@ -68,11 +71,12 @@ LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\
|
||||
LINE("-xpg4.3", "X/Open Portability Guide Issue\\~4, Version\\~3 (\\(lqXPG4.3\\(rq)")
|
||||
LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)")
|
||||
LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)")
|
||||
LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)")
|
||||
LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)")
|
||||
LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)")
|
||||
LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)")
|
||||
LINE("-xns5.2d2.0", "X/Open Networking Services Issue\\~5.2 Draft\\~2.0 (\\(lqXNS5.2D2.0\\(rq)")
|
||||
LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(lqXCURSES4.2\\(rq)")
|
||||
LINE("-susv2", "Version\\~2 of the Single UNIX Specification")
|
||||
LINE("-susv3", "Version\\~3 of the Single UNIX Specification")
|
||||
LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(lqSUSv2\\(rq)")
|
||||
LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(lqSUSv3\\(rq)")
|
||||
LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)")
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: tbl.7,v 1.16 2011/09/03 00:29:21 kristaps Exp $
|
||||
.\" $Id: tbl.7,v 1.18 2013/09/16 22:39:19 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: September 3 2011 $
|
||||
.Dd $Mdocdate: September 16 2013 $
|
||||
.Dt TBL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -69,13 +69,6 @@ c5 c5 c5.
|
||||
4:5:6
|
||||
.TE
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
implementation in
|
||||
.Xr mandoc 1
|
||||
is
|
||||
.Ud
|
||||
.Sh TABLE STRUCTURE
|
||||
Tables are enclosed by the
|
||||
.Sq TS
|
||||
@ -344,5 +337,4 @@ utility.
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons ,
|
||||
.Mt kristaps@bsd.lv .
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv .
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl.c,v 1.26 2011/07/25 15:37:00 kristaps Exp $ */
|
||||
/* $Id: tbl.c,v 1.27 2013/05/31 22:08:09 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -72,21 +72,21 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
|
||||
struct tbl_node *
|
||||
tbl_alloc(int pos, int line, struct mparse *parse)
|
||||
{
|
||||
struct tbl_node *p;
|
||||
struct tbl_node *tbl;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct tbl_node));
|
||||
p->line = line;
|
||||
p->pos = pos;
|
||||
p->parse = parse;
|
||||
p->part = TBL_PART_OPTS;
|
||||
p->opts.tab = '\t';
|
||||
p->opts.linesize = 12;
|
||||
p->opts.decimal = '.';
|
||||
return(p);
|
||||
tbl = mandoc_calloc(1, sizeof(struct tbl_node));
|
||||
tbl->line = line;
|
||||
tbl->pos = pos;
|
||||
tbl->parse = parse;
|
||||
tbl->part = TBL_PART_OPTS;
|
||||
tbl->opts.tab = '\t';
|
||||
tbl->opts.linesize = 12;
|
||||
tbl->opts.decimal = '.';
|
||||
return(tbl);
|
||||
}
|
||||
|
||||
void
|
||||
tbl_free(struct tbl_node *p)
|
||||
tbl_free(struct tbl_node *tbl)
|
||||
{
|
||||
struct tbl_row *rp;
|
||||
struct tbl_cell *cp;
|
||||
@ -94,8 +94,8 @@ tbl_free(struct tbl_node *p)
|
||||
struct tbl_dat *dp;
|
||||
struct tbl_head *hp;
|
||||
|
||||
while (NULL != (rp = p->first_row)) {
|
||||
p->first_row = rp->next;
|
||||
while (NULL != (rp = tbl->first_row)) {
|
||||
tbl->first_row = rp->next;
|
||||
while (rp->first) {
|
||||
cp = rp->first;
|
||||
rp->first = cp->next;
|
||||
@ -104,8 +104,8 @@ tbl_free(struct tbl_node *p)
|
||||
free(rp);
|
||||
}
|
||||
|
||||
while (NULL != (sp = p->first_span)) {
|
||||
p->first_span = sp->next;
|
||||
while (NULL != (sp = tbl->first_span)) {
|
||||
tbl->first_span = sp->next;
|
||||
while (sp->first) {
|
||||
dp = sp->first;
|
||||
sp->first = dp->next;
|
||||
@ -116,12 +116,12 @@ tbl_free(struct tbl_node *p)
|
||||
free(sp);
|
||||
}
|
||||
|
||||
while (NULL != (hp = p->first_head)) {
|
||||
p->first_head = hp->next;
|
||||
while (NULL != (hp = tbl->first_head)) {
|
||||
tbl->first_head = hp->next;
|
||||
free(hp);
|
||||
}
|
||||
|
||||
free(p);
|
||||
free(tbl);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_data.c,v 1.24 2011/03/20 16:02:05 kristaps Exp $ */
|
||||
/* $Id: tbl_data.c,v 1.27 2013/06/01 04:56:50 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -49,13 +49,11 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
||||
cp = dp->layout->first;
|
||||
|
||||
/*
|
||||
* Skip over spanners and vertical lines to data formats, since
|
||||
* Skip over spanners, since
|
||||
* we want to match data with data layout cells in the header.
|
||||
*/
|
||||
|
||||
while (cp && (TBL_CELL_VERT == cp->pos ||
|
||||
TBL_CELL_DVERT == cp->pos ||
|
||||
TBL_CELL_SPAN == cp->pos))
|
||||
while (cp && TBL_CELL_SPAN == cp->pos)
|
||||
cp = cp->next;
|
||||
|
||||
/*
|
||||
@ -104,7 +102,7 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
|
||||
|
||||
if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) {
|
||||
tbl->part = TBL_PART_CDATA;
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
assert(*pos - sv >= 0);
|
||||
@ -187,7 +185,7 @@ newspan(struct tbl_node *tbl, int line, struct tbl_row *rp)
|
||||
|
||||
dp = mandoc_calloc(1, sizeof(struct tbl_span));
|
||||
dp->line = line;
|
||||
dp->tbl = &tbl->opts;
|
||||
dp->opts = &tbl->opts;
|
||||
dp->layout = rp;
|
||||
dp->head = tbl->first_head;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_html.c,v 1.9 2011/09/18 14:14:15 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.10 2012/05/27 17:54:54 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -119,20 +119,12 @@ print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
print_stagq(h, tt);
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_DVERT):
|
||||
continue;
|
||||
case (TBL_HEAD_DATA):
|
||||
if (NULL == dp)
|
||||
break;
|
||||
if (TBL_CELL_DOWN != dp->layout->pos)
|
||||
if (dp->string)
|
||||
print_text(h, dp->string);
|
||||
dp = dp->next;
|
||||
if (NULL == dp)
|
||||
break;
|
||||
}
|
||||
if (TBL_CELL_DOWN != dp->layout->pos)
|
||||
if (dp->string)
|
||||
print_text(h, dp->string);
|
||||
dp = dp->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: tbl_layout.c,v 1.22 2011/09/18 14:14:15 schwarze Exp $ */
|
||||
/* $Id: tbl_layout.c,v 1.23 2012/05/27 17:54:54 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -51,8 +52,7 @@ static const struct tbl_phrase keys[KEYS_MAX] = {
|
||||
{ '^', TBL_CELL_DOWN },
|
||||
{ '-', TBL_CELL_HORIZ },
|
||||
{ '_', TBL_CELL_HORIZ },
|
||||
{ '=', TBL_CELL_DHORIZ },
|
||||
{ '|', TBL_CELL_VERT }
|
||||
{ '=', TBL_CELL_DHORIZ }
|
||||
};
|
||||
|
||||
static int mods(struct tbl_node *, struct tbl_cell *,
|
||||
@ -60,10 +60,8 @@ static int mods(struct tbl_node *, struct tbl_cell *,
|
||||
static int cell(struct tbl_node *, struct tbl_row *,
|
||||
int, const char *, int *);
|
||||
static void row(struct tbl_node *, int, const char *, int *);
|
||||
static struct tbl_cell *cell_alloc(struct tbl_node *,
|
||||
struct tbl_row *, enum tbl_cellt);
|
||||
static void head_adjust(const struct tbl_cell *,
|
||||
struct tbl_head *);
|
||||
static struct tbl_cell *cell_alloc(struct tbl_node *, struct tbl_row *,
|
||||
enum tbl_cellt, int vert);
|
||||
|
||||
static int
|
||||
mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||
@ -80,10 +78,6 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||
case (TBL_CELL_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_DHORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_DVERT):
|
||||
return(1);
|
||||
default:
|
||||
break;
|
||||
@ -214,10 +208,17 @@ static int
|
||||
cell(struct tbl_node *tbl, struct tbl_row *rp,
|
||||
int ln, const char *p, int *pos)
|
||||
{
|
||||
int i;
|
||||
int vert, i;
|
||||
enum tbl_cellt c;
|
||||
|
||||
/* Parse the column position (`r', `R', `|', ...). */
|
||||
/* Handle vertical lines. */
|
||||
|
||||
for (vert = 0; '|' == p[*pos]; ++*pos)
|
||||
vert++;
|
||||
while (' ' == p[*pos])
|
||||
(*pos)++;
|
||||
|
||||
/* Parse the column position (`c', `l', `r', ...). */
|
||||
|
||||
for (i = 0; i < KEYS_MAX; i++)
|
||||
if (tolower((unsigned char)p[*pos]) == keys[i].name)
|
||||
@ -246,8 +247,6 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
||||
return(0);
|
||||
} else if (rp->last)
|
||||
switch (rp->last->pos) {
|
||||
case (TBL_CELL_VERT):
|
||||
case (TBL_CELL_DVERT):
|
||||
case (TBL_CELL_HORIZ):
|
||||
case (TBL_CELL_DHORIZ):
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
|
||||
@ -270,25 +269,16 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
|
||||
|
||||
(*pos)++;
|
||||
|
||||
/* Extra check for the double-vertical. */
|
||||
|
||||
if (TBL_CELL_VERT == c && '|' == p[*pos]) {
|
||||
(*pos)++;
|
||||
c = TBL_CELL_DVERT;
|
||||
}
|
||||
|
||||
/* Disallow adjacent spacers. */
|
||||
|
||||
if (rp->last && (TBL_CELL_VERT == c || TBL_CELL_DVERT == c) &&
|
||||
(TBL_CELL_VERT == rp->last->pos ||
|
||||
TBL_CELL_DVERT == rp->last->pos)) {
|
||||
if (vert > 2) {
|
||||
mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos - 1, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Allocate cell then parse its modifiers. */
|
||||
|
||||
return(mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos));
|
||||
return(mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos));
|
||||
}
|
||||
|
||||
|
||||
@ -308,11 +298,11 @@ row(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
||||
*/
|
||||
|
||||
rp = mandoc_calloc(1, sizeof(struct tbl_row));
|
||||
if (tbl->last_row) {
|
||||
if (tbl->last_row)
|
||||
tbl->last_row->next = rp;
|
||||
tbl->last_row = rp;
|
||||
} else
|
||||
tbl->last_row = tbl->first_row = rp;
|
||||
else
|
||||
tbl->first_row = rp;
|
||||
tbl->last_row = rp;
|
||||
|
||||
cell:
|
||||
while (isspace((unsigned char)p[*pos]))
|
||||
@ -357,7 +347,8 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p)
|
||||
}
|
||||
|
||||
static struct tbl_cell *
|
||||
cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
|
||||
cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos,
|
||||
int vert)
|
||||
{
|
||||
struct tbl_cell *p, *pp;
|
||||
struct tbl_head *h, *hp;
|
||||
@ -365,108 +356,35 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
|
||||
p = mandoc_calloc(1, sizeof(struct tbl_cell));
|
||||
|
||||
if (NULL != (pp = rp->last)) {
|
||||
rp->last->next = p;
|
||||
rp->last = p;
|
||||
} else
|
||||
rp->last = rp->first = p;
|
||||
pp->next = p;
|
||||
h = pp->head->next;
|
||||
} else {
|
||||
rp->first = p;
|
||||
h = tbl->first_head;
|
||||
}
|
||||
rp->last = p;
|
||||
|
||||
p->pos = pos;
|
||||
p->vert = vert;
|
||||
|
||||
/*
|
||||
* This is a little bit complicated. Here we determine the
|
||||
* header the corresponds to a cell. We add headers dynamically
|
||||
* when need be or re-use them, otherwise. As an example, given
|
||||
* the following:
|
||||
*
|
||||
* 1 c || l
|
||||
* 2 | c | l
|
||||
* 3 l l
|
||||
* 3 || c | l |.
|
||||
*
|
||||
* We first add the new headers (as there are none) in (1); then
|
||||
* in (2) we insert the first spanner (as it doesn't match up
|
||||
* with the header); then we re-use the prior data headers,
|
||||
* skipping over the spanners; then we re-use everything and add
|
||||
* a last spanner. Note that VERT headers are made into DVERT
|
||||
* ones.
|
||||
*/
|
||||
|
||||
h = pp ? pp->head->next : tbl->first_head;
|
||||
/* Re-use header. */
|
||||
|
||||
if (h) {
|
||||
/* Re-use data header. */
|
||||
if (TBL_HEAD_DATA == h->pos &&
|
||||
(TBL_CELL_VERT != p->pos &&
|
||||
TBL_CELL_DVERT != p->pos)) {
|
||||
p->head = h;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Re-use spanner header. */
|
||||
if (TBL_HEAD_DATA != h->pos &&
|
||||
(TBL_CELL_VERT == p->pos ||
|
||||
TBL_CELL_DVERT == p->pos)) {
|
||||
head_adjust(p, h);
|
||||
p->head = h;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Right-shift headers with a new spanner. */
|
||||
if (TBL_HEAD_DATA == h->pos &&
|
||||
(TBL_CELL_VERT == p->pos ||
|
||||
TBL_CELL_DVERT == p->pos)) {
|
||||
hp = mandoc_calloc(1, sizeof(struct tbl_head));
|
||||
hp->ident = tbl->opts.cols++;
|
||||
hp->prev = h->prev;
|
||||
if (h->prev)
|
||||
h->prev->next = hp;
|
||||
if (h == tbl->first_head)
|
||||
tbl->first_head = hp;
|
||||
h->prev = hp;
|
||||
hp->next = h;
|
||||
head_adjust(p, hp);
|
||||
p->head = hp;
|
||||
return(p);
|
||||
}
|
||||
|
||||
if (NULL != (h = h->next)) {
|
||||
head_adjust(p, h);
|
||||
p->head = h;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Fall through to default case... */
|
||||
p->head = h;
|
||||
return(p);
|
||||
}
|
||||
|
||||
hp = mandoc_calloc(1, sizeof(struct tbl_head));
|
||||
hp->ident = tbl->opts.cols++;
|
||||
hp->vert = vert;
|
||||
|
||||
if (tbl->last_head) {
|
||||
hp->prev = tbl->last_head;
|
||||
tbl->last_head->next = hp;
|
||||
tbl->last_head = hp;
|
||||
} else
|
||||
tbl->last_head = tbl->first_head = hp;
|
||||
tbl->first_head = hp;
|
||||
tbl->last_head = hp;
|
||||
|
||||
head_adjust(p, hp);
|
||||
p->head = hp;
|
||||
return(p);
|
||||
}
|
||||
|
||||
static void
|
||||
head_adjust(const struct tbl_cell *cellp, struct tbl_head *head)
|
||||
{
|
||||
if (TBL_CELL_VERT != cellp->pos &&
|
||||
TBL_CELL_DVERT != cellp->pos) {
|
||||
head->pos = TBL_HEAD_DATA;
|
||||
return;
|
||||
}
|
||||
|
||||
if (TBL_CELL_VERT == cellp->pos)
|
||||
if (TBL_HEAD_DVERT != head->pos)
|
||||
head->pos = TBL_HEAD_VERT;
|
||||
|
||||
if (TBL_CELL_DVERT == cellp->pos)
|
||||
head->pos = TBL_HEAD_DVERT;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: tbl_term.c,v 1.21 2011/09/20 23:05:49 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.25 2013/05/31 21:37:17 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -31,14 +31,14 @@
|
||||
static size_t term_tbl_len(size_t, void *);
|
||||
static size_t term_tbl_strlen(const char *, void *);
|
||||
static void tbl_char(struct termp *, char, size_t);
|
||||
static void tbl_data(struct termp *, const struct tbl *,
|
||||
static void tbl_data(struct termp *, const struct tbl_opts *,
|
||||
const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static size_t tbl_rulewidth(struct termp *, const struct tbl_head *);
|
||||
static void tbl_hframe(struct termp *, const struct tbl_span *, int);
|
||||
static void tbl_literal(struct termp *, const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_number(struct termp *, const struct tbl *,
|
||||
static void tbl_number(struct termp *, const struct tbl_opts *,
|
||||
const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_hrule(struct termp *, const struct tbl_span *);
|
||||
@ -96,16 +96,16 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
/* Horizontal frame at the start of boxed tables. */
|
||||
|
||||
if (TBL_SPAN_FIRST & sp->flags) {
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts)
|
||||
if (TBL_OPT_DBOX & sp->opts->opts)
|
||||
tbl_hframe(tp, sp, 1);
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts ||
|
||||
TBL_OPT_BOX & sp->tbl->opts)
|
||||
if (TBL_OPT_DBOX & sp->opts->opts ||
|
||||
TBL_OPT_BOX & sp->opts->opts)
|
||||
tbl_hframe(tp, sp, 0);
|
||||
}
|
||||
|
||||
/* Vertical frame at the start of each row. */
|
||||
|
||||
if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts)
|
||||
if (TBL_OPT_BOX & sp->opts->opts || TBL_OPT_DBOX & sp->opts->opts)
|
||||
term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
|
||||
TBL_SPAN_DHORIZ == sp->pos ? "+" : "|");
|
||||
|
||||
@ -126,49 +126,23 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
dp = sp->first;
|
||||
spans = 0;
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
|
||||
/*
|
||||
* If the current data header is invoked during
|
||||
* a spanner ("spans" > 0), don't emit anything
|
||||
* at all.
|
||||
*/
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_DVERT):
|
||||
if (spans <= 0)
|
||||
tbl_vrule(tp, hp);
|
||||
continue;
|
||||
case (TBL_HEAD_DATA):
|
||||
break;
|
||||
}
|
||||
|
||||
if (--spans >= 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* All cells get a leading blank, except the
|
||||
* first one and those after double rulers.
|
||||
*/
|
||||
/* Separate columns. */
|
||||
|
||||
if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
|
||||
tbl_char(tp, ASCII_NBRSP, 1);
|
||||
if (NULL != hp->prev)
|
||||
tbl_vrule(tp, hp);
|
||||
|
||||
col = &tp->tbl.cols[hp->ident];
|
||||
tbl_data(tp, sp->tbl, dp, col);
|
||||
|
||||
/* No trailing blanks. */
|
||||
|
||||
if (NULL == hp->next)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Add another blank between cells,
|
||||
* or two when there is no vertical ruler.
|
||||
*/
|
||||
|
||||
tbl_char(tp, ASCII_NBRSP,
|
||||
TBL_HEAD_VERT == hp->next->pos ||
|
||||
TBL_HEAD_DVERT == hp->next->pos ? 1 : 2);
|
||||
tbl_data(tp, sp->opts, dp, col);
|
||||
|
||||
/*
|
||||
* Go to the next data cell and assign the
|
||||
@ -185,7 +159,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
|
||||
/* Vertical frame at the end of each row. */
|
||||
|
||||
if (TBL_OPT_BOX & sp->tbl->opts || TBL_OPT_DBOX & sp->tbl->opts)
|
||||
if (TBL_OPT_BOX & sp->opts->opts || TBL_OPT_DBOX & sp->opts->opts)
|
||||
term_word(tp, TBL_SPAN_HORIZ == sp->pos ||
|
||||
TBL_SPAN_DHORIZ == sp->pos ? "+" : " |");
|
||||
term_flushln(tp);
|
||||
@ -196,11 +170,15 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
*/
|
||||
|
||||
if (TBL_SPAN_LAST & sp->flags) {
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts ||
|
||||
TBL_OPT_BOX & sp->tbl->opts)
|
||||
if (TBL_OPT_DBOX & sp->opts->opts ||
|
||||
TBL_OPT_BOX & sp->opts->opts) {
|
||||
tbl_hframe(tp, sp, 0);
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts)
|
||||
tp->skipvsp = 1;
|
||||
}
|
||||
if (TBL_OPT_DBOX & sp->opts->opts) {
|
||||
tbl_hframe(tp, sp, 1);
|
||||
tp->skipvsp = 2;
|
||||
}
|
||||
assert(tp->tbl.cols);
|
||||
free(tp->tbl.cols);
|
||||
tp->tbl.cols = NULL;
|
||||
@ -222,17 +200,14 @@ tbl_rulewidth(struct termp *tp, const struct tbl_head *hp)
|
||||
size_t width;
|
||||
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
if (TBL_HEAD_DATA == hp->pos) {
|
||||
/* Account for leading blanks. */
|
||||
if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
|
||||
width++;
|
||||
/* Account for trailing blanks. */
|
||||
width++;
|
||||
if (hp->next &&
|
||||
TBL_HEAD_VERT != hp->next->pos &&
|
||||
TBL_HEAD_DVERT != hp->next->pos)
|
||||
width++;
|
||||
}
|
||||
|
||||
/* Account for leading blanks. */
|
||||
if (hp->prev)
|
||||
width += 2 - hp->vert;
|
||||
|
||||
/* Account for trailing blank. */
|
||||
width++;
|
||||
|
||||
return(width);
|
||||
}
|
||||
|
||||
@ -250,10 +225,11 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp)
|
||||
if (TBL_SPAN_DHORIZ == sp->pos)
|
||||
c = '=';
|
||||
|
||||
for (hp = sp->head; hp; hp = hp->next)
|
||||
tbl_char(tp,
|
||||
TBL_HEAD_DATA == hp->pos ? c : '+',
|
||||
tbl_rulewidth(tp, hp));
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
if (hp->prev && hp->vert)
|
||||
tbl_char(tp, '+', hp->vert);
|
||||
tbl_char(tp, c, tbl_rulewidth(tp, hp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -268,16 +244,17 @@ tbl_hframe(struct termp *tp, const struct tbl_span *sp, int outer)
|
||||
const struct tbl_head *hp;
|
||||
|
||||
term_word(tp, "+");
|
||||
for (hp = sp->head; hp; hp = hp->next)
|
||||
tbl_char(tp,
|
||||
outer || TBL_HEAD_DATA == hp->pos ? '-' : '+',
|
||||
tbl_rulewidth(tp, hp));
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
if (hp->prev && hp->vert)
|
||||
tbl_char(tp, (outer ? '-' : '+'), hp->vert);
|
||||
tbl_char(tp, '-', tbl_rulewidth(tp, hp));
|
||||
}
|
||||
term_word(tp, "+");
|
||||
term_flushln(tp);
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_data(struct termp *tp, const struct tbl *tbl,
|
||||
tbl_data(struct termp *tp, const struct tbl_opts *opts,
|
||||
const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
@ -323,7 +300,7 @@ tbl_data(struct termp *tp, const struct tbl *tbl,
|
||||
tbl_literal(tp, dp, col);
|
||||
break;
|
||||
case (TBL_CELL_NUMBER):
|
||||
tbl_number(tp, tbl, dp, col);
|
||||
tbl_number(tp, opts, dp, col);
|
||||
break;
|
||||
case (TBL_CELL_DOWN):
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
@ -338,16 +315,11 @@ static void
|
||||
tbl_vrule(struct termp *tp, const struct tbl_head *hp)
|
||||
{
|
||||
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
term_word(tp, "|");
|
||||
break;
|
||||
case (TBL_HEAD_DVERT):
|
||||
term_word(tp, "||");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
tbl_char(tp, ASCII_NBRSP, 1);
|
||||
if (0 < hp->vert)
|
||||
tbl_char(tp, '|', hp->vert);
|
||||
if (2 > hp->vert)
|
||||
tbl_char(tp, ASCII_NBRSP, 2 - hp->vert);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -369,11 +341,19 @@ static void
|
||||
tbl_literal(struct termp *tp, const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
size_t len, padl, padr;
|
||||
struct tbl_head *hp;
|
||||
size_t width, len, padl, padr;
|
||||
int spans;
|
||||
|
||||
assert(dp->string);
|
||||
len = term_strlen(tp, dp->string);
|
||||
padr = col->width > len ? col->width - len : 0;
|
||||
|
||||
hp = dp->layout->head->next;
|
||||
width = col->width;
|
||||
for (spans = dp->spans; spans--; hp = hp->next)
|
||||
width += tp->tbl.cols[hp->ident].width + 3;
|
||||
|
||||
padr = width > len ? width - len : 0;
|
||||
padl = 0;
|
||||
|
||||
switch (dp->layout->pos) {
|
||||
@ -401,7 +381,7 @@ tbl_literal(struct termp *tp, const struct tbl_dat *dp,
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_number(struct termp *tp, const struct tbl *tbl,
|
||||
tbl_number(struct termp *tp, const struct tbl_opts *opts,
|
||||
const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
@ -419,12 +399,12 @@ tbl_number(struct termp *tp, const struct tbl *tbl,
|
||||
|
||||
sz = term_strlen(tp, dp->string);
|
||||
|
||||
buf[0] = tbl->decimal;
|
||||
buf[0] = opts->decimal;
|
||||
buf[1] = '\0';
|
||||
|
||||
psz = term_strlen(tp, buf);
|
||||
|
||||
if (NULL != (cp = strrchr(dp->string, tbl->decimal))) {
|
||||
if (NULL != (cp = strrchr(dp->string, opts->decimal))) {
|
||||
buf[1] = '\0';
|
||||
for (ssz = 0, i = 0; cp != &dp->string[i]; i++) {
|
||||
buf[0] = dp->string[i];
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: term.c,v 1.201 2011/09/21 09:57:13 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.214 2013/12/25 00:39:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -33,7 +33,8 @@
|
||||
#include "term.h"
|
||||
#include "main.h"
|
||||
|
||||
static void adjbuf(struct termp *p, int);
|
||||
static size_t cond_width(const struct termp *, int, int *);
|
||||
static void adjbuf(struct termp *p, size_t);
|
||||
static void bufferc(struct termp *, char);
|
||||
static void encode(struct termp *, const char *, size_t);
|
||||
static void encode1(struct termp *, int);
|
||||
@ -82,9 +83,8 @@ term_end(struct termp *p)
|
||||
* - TERMP_NOBREAK: this is the most important and is used when making
|
||||
* columns. In short: don't print a newline and instead expect the
|
||||
* next call to do the padding up to the start of the next column.
|
||||
*
|
||||
* - TERMP_TWOSPACE: make sure there is room for at least two space
|
||||
* characters of padding. Otherwise, rather break the line.
|
||||
* p->trailspace may be set to 0, 1, or 2, depending on how many
|
||||
* space characters are required at the end of the column.
|
||||
*
|
||||
* - TERMP_DANGLE: don't newline when TERMP_NOBREAK is specified and
|
||||
* the line is overrun, and don't pad-right if it's underrun.
|
||||
@ -104,14 +104,15 @@ term_end(struct termp *p)
|
||||
void
|
||||
term_flushln(struct termp *p)
|
||||
{
|
||||
int i; /* current input position in p->buf */
|
||||
size_t i; /* current input position in p->buf */
|
||||
int ntab; /* number of tabs to prepend */
|
||||
size_t vis; /* current visual position on output */
|
||||
size_t vbl; /* number of blanks to prepend to output */
|
||||
size_t vend; /* end of word visual position on output */
|
||||
size_t bp; /* visual right border position */
|
||||
size_t dv; /* temporary for visual pos calculations */
|
||||
int j; /* temporary loop index for p->buf */
|
||||
int jhy; /* last hyph before overflow w/r/t j */
|
||||
size_t j; /* temporary loop index for p->buf */
|
||||
size_t jhy; /* last hyph before overflow w/r/t j */
|
||||
size_t maxvis; /* output position of visible boundary */
|
||||
size_t mmax; /* used in calculating bp */
|
||||
|
||||
@ -119,7 +120,12 @@ term_flushln(struct termp *p)
|
||||
* First, establish the maximum columns of "visible" content.
|
||||
* This is usually the difference between the right-margin and
|
||||
* an indentation, but can be, for tagged lists or columns, a
|
||||
* small set of values.
|
||||
* small set of values.
|
||||
*
|
||||
* The following unsigned-signed subtractions look strange,
|
||||
* but they are actually correct. If the int p->overstep
|
||||
* is negative, it gets sign extended. Subtracting that
|
||||
* very large size_t effectively adds a small number to dv.
|
||||
*/
|
||||
assert (p->rmargin >= p->offset);
|
||||
dv = p->rmargin - p->offset;
|
||||
@ -143,10 +149,12 @@ term_flushln(struct termp *p)
|
||||
* Handle literal tab characters: collapse all
|
||||
* subsequent tabs into a single huge set of spaces.
|
||||
*/
|
||||
ntab = 0;
|
||||
while (i < p->col && '\t' == p->buf[i]) {
|
||||
vend = (vis / p->tabwidth + 1) * p->tabwidth;
|
||||
vbl += vend - vis;
|
||||
vis = vend;
|
||||
ntab++;
|
||||
i++;
|
||||
}
|
||||
|
||||
@ -158,7 +166,7 @@ term_flushln(struct termp *p)
|
||||
*/
|
||||
|
||||
for (j = i, jhy = 0; j < p->col; j++) {
|
||||
if ((j && ' ' == p->buf[j]) || '\t' == p->buf[j])
|
||||
if (' ' == p->buf[j] || '\t' == p->buf[j])
|
||||
break;
|
||||
|
||||
/* Back over the the last printed character. */
|
||||
@ -191,7 +199,16 @@ term_flushln(struct termp *p)
|
||||
} else
|
||||
vbl = p->offset;
|
||||
|
||||
/* Remove the p->overstep width. */
|
||||
/* use pending tabs on the new line */
|
||||
|
||||
if (0 < ntab)
|
||||
vbl += ntab * p->tabwidth;
|
||||
|
||||
/*
|
||||
* Remove the p->overstep width.
|
||||
* Again, if p->overstep is negative,
|
||||
* sign extension does the right thing.
|
||||
*/
|
||||
|
||||
bp += (size_t)p->overstep;
|
||||
p->overstep = 0;
|
||||
@ -207,7 +224,7 @@ term_flushln(struct termp *p)
|
||||
j = i;
|
||||
while (' ' == p->buf[i])
|
||||
i++;
|
||||
dv = (size_t)(i - j) * (*p->width)(p, ' ');
|
||||
dv = (i - j) * (*p->width)(p, ' ');
|
||||
vbl += dv;
|
||||
vend += dv;
|
||||
break;
|
||||
@ -260,20 +277,17 @@ term_flushln(struct termp *p)
|
||||
}
|
||||
|
||||
if (TERMP_HANG & p->flags) {
|
||||
/* We need one blank after the tag. */
|
||||
p->overstep = (int)(vis - maxvis + (*p->width)(p, ' '));
|
||||
p->overstep = (int)(vis - maxvis +
|
||||
p->trailspace * (*p->width)(p, ' '));
|
||||
|
||||
/*
|
||||
* Behave exactly the same way as groff:
|
||||
* If we have overstepped the margin, temporarily move
|
||||
* it to the right and flag the rest of the line to be
|
||||
* shorter.
|
||||
* If we landed right at the margin, be happy.
|
||||
* If we are one step before the margin, temporarily
|
||||
* move it one step LEFT and flag the rest of the line
|
||||
* to be longer.
|
||||
* If there is a request to keep the columns together,
|
||||
* allow negative overstep when the column is not full.
|
||||
*/
|
||||
if (p->overstep < -1)
|
||||
if (p->trailspace && p->overstep < 0)
|
||||
p->overstep = 0;
|
||||
return;
|
||||
|
||||
@ -281,8 +295,7 @@ term_flushln(struct termp *p)
|
||||
return;
|
||||
|
||||
/* If the column was overrun, break the line. */
|
||||
if (maxvis <= vis +
|
||||
((TERMP_TWOSPACE & p->flags) ? (*p->width)(p, ' ') : 0)) {
|
||||
if (maxvis < vis + p->trailspace * (*p->width)(p, ' ')) {
|
||||
(*p->endline)(p);
|
||||
p->viscol = 0;
|
||||
}
|
||||
@ -316,7 +329,10 @@ term_vspace(struct termp *p)
|
||||
|
||||
term_newln(p);
|
||||
p->viscol = 0;
|
||||
(*p->endline)(p);
|
||||
if (0 < p->skipvsp)
|
||||
p->skipvsp--;
|
||||
else
|
||||
(*p->endline)(p);
|
||||
}
|
||||
|
||||
void
|
||||
@ -369,7 +385,7 @@ void
|
||||
term_fontpopq(struct termp *p, const void *key)
|
||||
{
|
||||
|
||||
while (p->fonti >= 0 && key != &p->fontq[p->fonti])
|
||||
while (p->fonti >= 0 && key < (void *)(p->fontq + p->fonti))
|
||||
p->fonti--;
|
||||
assert(p->fonti >= 0);
|
||||
}
|
||||
@ -391,6 +407,7 @@ term_fontpop(struct termp *p)
|
||||
void
|
||||
term_word(struct termp *p, const char *word)
|
||||
{
|
||||
const char nbrsp[2] = { ASCII_NBRSP, 0 };
|
||||
const char *seq, *cp;
|
||||
char c;
|
||||
int sz, uc;
|
||||
@ -399,29 +416,42 @@ term_word(struct termp *p, const char *word)
|
||||
|
||||
if ( ! (TERMP_NOSPACE & p->flags)) {
|
||||
if ( ! (TERMP_KEEP & p->flags)) {
|
||||
if (TERMP_PREKEEP & p->flags)
|
||||
p->flags |= TERMP_KEEP;
|
||||
bufferc(p, ' ');
|
||||
if (TERMP_SENTENCE & p->flags)
|
||||
bufferc(p, ' ');
|
||||
} else
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
}
|
||||
if (TERMP_PREKEEP & p->flags)
|
||||
p->flags |= TERMP_KEEP;
|
||||
|
||||
if ( ! (p->flags & TERMP_NONOSPACE))
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
else
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM);
|
||||
p->flags &= ~TERMP_SENTENCE;
|
||||
|
||||
while ('\0' != *word) {
|
||||
if ((ssz = strcspn(word, "\\")) > 0)
|
||||
if ('\\' != *word) {
|
||||
if (TERMP_SKIPCHAR & p->flags) {
|
||||
p->flags &= ~TERMP_SKIPCHAR;
|
||||
word++;
|
||||
continue;
|
||||
}
|
||||
if (TERMP_NBRWORD & p->flags) {
|
||||
if (' ' == *word) {
|
||||
encode(p, nbrsp, 1);
|
||||
word++;
|
||||
continue;
|
||||
}
|
||||
ssz = strcspn(word, "\\ ");
|
||||
} else
|
||||
ssz = strcspn(word, "\\");
|
||||
encode(p, word, ssz);
|
||||
|
||||
word += (int)ssz;
|
||||
if ('\\' != *word)
|
||||
word += (int)ssz;
|
||||
continue;
|
||||
}
|
||||
|
||||
word++;
|
||||
esc = mandoc_escape(&word, &seq, &sz);
|
||||
@ -468,6 +498,9 @@ term_word(struct termp *p, const char *word)
|
||||
case (ESCAPE_FONTITALIC):
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
break;
|
||||
case (ESCAPE_FONTBI):
|
||||
term_fontrepl(p, TERMFONT_BI);
|
||||
break;
|
||||
case (ESCAPE_FONT):
|
||||
/* FALLTHROUGH */
|
||||
case (ESCAPE_FONTROMAN):
|
||||
@ -477,17 +510,23 @@ term_word(struct termp *p, const char *word)
|
||||
term_fontlast(p);
|
||||
break;
|
||||
case (ESCAPE_NOSPACE):
|
||||
if ('\0' == *word)
|
||||
if (TERMP_SKIPCHAR & p->flags)
|
||||
p->flags &= ~TERMP_SKIPCHAR;
|
||||
else if ('\0' == *word)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case (ESCAPE_SKIPCHAR):
|
||||
p->flags |= TERMP_SKIPCHAR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->flags &= ~TERMP_NBRWORD;
|
||||
}
|
||||
|
||||
static void
|
||||
adjbuf(struct termp *p, int sz)
|
||||
adjbuf(struct termp *p, size_t sz)
|
||||
{
|
||||
|
||||
if (0 == p->maxcols)
|
||||
@ -495,8 +534,7 @@ adjbuf(struct termp *p, int sz)
|
||||
while (sz >= p->maxcols)
|
||||
p->maxcols <<= 2;
|
||||
|
||||
p->buf = mandoc_realloc
|
||||
(p->buf, sizeof(int) * (size_t)p->maxcols);
|
||||
p->buf = mandoc_realloc(p->buf, sizeof(int) * p->maxcols);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -519,31 +557,39 @@ encode1(struct termp *p, int c)
|
||||
{
|
||||
enum termfont f;
|
||||
|
||||
if (p->col + 4 >= p->maxcols)
|
||||
adjbuf(p, p->col + 4);
|
||||
if (TERMP_SKIPCHAR & p->flags) {
|
||||
p->flags &= ~TERMP_SKIPCHAR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->col + 6 >= p->maxcols)
|
||||
adjbuf(p, p->col + 6);
|
||||
|
||||
f = term_fonttop(p);
|
||||
|
||||
if (TERMFONT_NONE == f) {
|
||||
p->buf[p->col++] = c;
|
||||
return;
|
||||
} else if (TERMFONT_UNDER == f) {
|
||||
if (TERMFONT_UNDER == f || TERMFONT_BI == f) {
|
||||
p->buf[p->col++] = '_';
|
||||
} else
|
||||
p->buf[p->col++] = c;
|
||||
|
||||
p->buf[p->col++] = 8;
|
||||
p->buf[p->col++] = 8;
|
||||
}
|
||||
if (TERMFONT_BOLD == f || TERMFONT_BI == f) {
|
||||
if (ASCII_HYPH == c)
|
||||
p->buf[p->col++] = '-';
|
||||
else
|
||||
p->buf[p->col++] = c;
|
||||
p->buf[p->col++] = 8;
|
||||
}
|
||||
p->buf[p->col++] = c;
|
||||
}
|
||||
|
||||
static void
|
||||
encode(struct termp *p, const char *word, size_t sz)
|
||||
{
|
||||
enum termfont f;
|
||||
int i, len;
|
||||
size_t i;
|
||||
|
||||
/* LINTED */
|
||||
len = sz;
|
||||
if (TERMP_SKIPCHAR & p->flags) {
|
||||
p->flags &= ~TERMP_SKIPCHAR;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode and buffer a string of characters. If the current
|
||||
@ -551,35 +597,25 @@ encode(struct termp *p, const char *word, size_t sz)
|
||||
* character by character.
|
||||
*/
|
||||
|
||||
if (TERMFONT_NONE == (f = term_fonttop(p))) {
|
||||
if (p->col + len >= p->maxcols)
|
||||
adjbuf(p, p->col + len);
|
||||
for (i = 0; i < len; i++)
|
||||
if (TERMFONT_NONE == term_fonttop(p)) {
|
||||
if (p->col + sz >= p->maxcols)
|
||||
adjbuf(p, p->col + sz);
|
||||
for (i = 0; i < sz; i++)
|
||||
p->buf[p->col++] = word[i];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pre-buffer, assuming worst-case. */
|
||||
|
||||
if (p->col + 1 + (len * 3) >= p->maxcols)
|
||||
adjbuf(p, p->col + 1 + (len * 3));
|
||||
if (p->col + 1 + (sz * 5) >= p->maxcols)
|
||||
adjbuf(p, p->col + 1 + (sz * 5));
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (ASCII_HYPH != word[i] &&
|
||||
! isgraph((unsigned char)word[i])) {
|
||||
p->buf[p->col++] = word[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TERMFONT_UNDER == f)
|
||||
p->buf[p->col++] = '_';
|
||||
else if (ASCII_HYPH == word[i])
|
||||
p->buf[p->col++] = '-';
|
||||
for (i = 0; i < sz; i++) {
|
||||
if (ASCII_HYPH == word[i] ||
|
||||
isgraph((unsigned char)word[i]))
|
||||
encode1(p, word[i]);
|
||||
else
|
||||
p->buf[p->col++] = word[i];
|
||||
|
||||
p->buf[p->col++] = 8;
|
||||
p->buf[p->col++] = word[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,12 +626,22 @@ term_len(const struct termp *p, size_t sz)
|
||||
return((*p->width)(p, ' ') * sz);
|
||||
}
|
||||
|
||||
static size_t
|
||||
cond_width(const struct termp *p, int c, int *skip)
|
||||
{
|
||||
|
||||
if (*skip) {
|
||||
(*skip) = 0;
|
||||
return(0);
|
||||
} else
|
||||
return((*p->width)(p, c));
|
||||
}
|
||||
|
||||
size_t
|
||||
term_strlen(const struct termp *p, const char *cp)
|
||||
{
|
||||
size_t sz, rsz, i;
|
||||
int ssz, c;
|
||||
int ssz, skip, c;
|
||||
const char *seq, *rhs;
|
||||
enum mandoc_esc esc;
|
||||
static const char rej[] = { '\\', ASCII_HYPH, ASCII_NBRSP, '\0' };
|
||||
@ -607,10 +653,11 @@ term_strlen(const struct termp *p, const char *cp)
|
||||
*/
|
||||
|
||||
sz = 0;
|
||||
skip = 0;
|
||||
while ('\0' != *cp) {
|
||||
rsz = strcspn(cp, rej);
|
||||
for (i = 0; i < rsz; i++)
|
||||
sz += (*p->width)(p, *cp++);
|
||||
sz += cond_width(p, *cp++, &skip);
|
||||
|
||||
c = 0;
|
||||
switch (*cp) {
|
||||
@ -627,14 +674,14 @@ term_strlen(const struct termp *p, const char *cp)
|
||||
(seq + 1, ssz - 1);
|
||||
if ('\0' == c)
|
||||
break;
|
||||
sz += (*p->width)(p, c);
|
||||
sz += cond_width(p, c, &skip);
|
||||
continue;
|
||||
case (ESCAPE_SPECIAL):
|
||||
c = mchars_spec2cp
|
||||
(p->symtab, seq, ssz);
|
||||
if (c <= 0)
|
||||
break;
|
||||
sz += (*p->width)(p, c);
|
||||
sz += cond_width(p, c, &skip);
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
@ -644,12 +691,12 @@ term_strlen(const struct termp *p, const char *cp)
|
||||
|
||||
switch (esc) {
|
||||
case (ESCAPE_UNICODE):
|
||||
sz += (*p->width)(p, '?');
|
||||
sz += cond_width(p, '?', &skip);
|
||||
break;
|
||||
case (ESCAPE_NUMBERED):
|
||||
c = mchars_num2char(seq, ssz);
|
||||
if ('\0' != c)
|
||||
sz += (*p->width)(p, c);
|
||||
sz += cond_width(p, c, &skip);
|
||||
break;
|
||||
case (ESCAPE_SPECIAL):
|
||||
rhs = mchars_spec2str
|
||||
@ -661,6 +708,9 @@ term_strlen(const struct termp *p, const char *cp)
|
||||
rhs = seq;
|
||||
rsz = ssz;
|
||||
break;
|
||||
case (ESCAPE_SKIPCHAR):
|
||||
skip = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -668,15 +718,20 @@ term_strlen(const struct termp *p, const char *cp)
|
||||
if (NULL == rhs)
|
||||
break;
|
||||
|
||||
if (skip) {
|
||||
skip = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < rsz; i++)
|
||||
sz += (*p->width)(p, *rhs++);
|
||||
break;
|
||||
case (ASCII_NBRSP):
|
||||
sz += (*p->width)(p, ' ');
|
||||
sz += cond_width(p, ' ', &skip);
|
||||
cp++;
|
||||
break;
|
||||
case (ASCII_HYPH):
|
||||
sz += (*p->width)(p, '-');
|
||||
sz += cond_width(p, '-', &skip);
|
||||
cp++;
|
||||
break;
|
||||
default:
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: term.h,v 1.90 2011/12/04 23:10:52 schwarze Exp $ */
|
||||
/* $Id: term.h,v 1.97 2013/12/25 00:39:31 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -37,6 +38,7 @@ enum termfont {
|
||||
TERMFONT_NONE = 0,
|
||||
TERMFONT_BOLD,
|
||||
TERMFONT_UNDER,
|
||||
TERMFONT_BI,
|
||||
TERMFONT__MAX
|
||||
};
|
||||
|
||||
@ -57,26 +59,28 @@ struct termp {
|
||||
size_t defrmargin; /* Right margin of the device. */
|
||||
size_t rmargin; /* Current right margin. */
|
||||
size_t maxrmargin; /* Max right margin. */
|
||||
int maxcols; /* Max size of buf. */
|
||||
size_t maxcols; /* Max size of buf. */
|
||||
size_t offset; /* Margin offest. */
|
||||
size_t tabwidth; /* Distance of tab positions. */
|
||||
int col; /* Bytes in buf. */
|
||||
size_t col; /* Bytes in buf. */
|
||||
size_t viscol; /* Chars on current line. */
|
||||
size_t trailspace; /* See termp_flushln(). */
|
||||
int overstep; /* See termp_flushln(). */
|
||||
int skipvsp; /* Vertical space to skip. */
|
||||
int flags;
|
||||
#define TERMP_SENTENCE (1 << 1) /* Space before a sentence. */
|
||||
#define TERMP_NOSPACE (1 << 2) /* No space before words. */
|
||||
#define TERMP_NOBREAK (1 << 4) /* See term_flushln(). */
|
||||
#define TERMP_IGNDELIM (1 << 6) /* Delims like regulars. */
|
||||
#define TERMP_NONOSPACE (1 << 7) /* No space (no autounset). */
|
||||
#define TERMP_DANGLE (1 << 8) /* See term_flushln(). */
|
||||
#define TERMP_HANG (1 << 9) /* See term_flushln(). */
|
||||
#define TERMP_TWOSPACE (1 << 10) /* See term_flushln(). */
|
||||
#define TERMP_NONOSPACE (1 << 3) /* No space (no autounset). */
|
||||
#define TERMP_NBRWORD (1 << 4) /* Make next word nonbreaking. */
|
||||
#define TERMP_KEEP (1 << 5) /* Keep words together. */
|
||||
#define TERMP_PREKEEP (1 << 6) /* ...starting with the next one. */
|
||||
#define TERMP_SKIPCHAR (1 << 7) /* Skip the next character. */
|
||||
#define TERMP_NOBREAK (1 << 8) /* See term_flushln(). */
|
||||
#define TERMP_DANGLE (1 << 9) /* See term_flushln(). */
|
||||
#define TERMP_HANG (1 << 10) /* See term_flushln(). */
|
||||
#define TERMP_NOSPLIT (1 << 11) /* See termp_an_pre/post(). */
|
||||
#define TERMP_SPLIT (1 << 12) /* See termp_an_pre/post(). */
|
||||
#define TERMP_ANPREC (1 << 13) /* See termp_an_pre(). */
|
||||
#define TERMP_KEEP (1 << 14) /* Keep words together. */
|
||||
#define TERMP_PREKEEP (1 << 15) /* ...starting with the next one. */
|
||||
int *buf; /* Output buffer. */
|
||||
enum termenc enc; /* Type of encoding. */
|
||||
struct mchars *symtab; /* Encoded-symbol table. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: term_ascii.c,v 1.20 2011/12/04 23:10:52 schwarze Exp $ */
|
||||
/* $Id: term_ascii.c,v 1.21 2013/06/01 14:27:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
@ -73,7 +73,6 @@ ascii_init(enum termenc enc, char *outopts)
|
||||
struct termp *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct termp));
|
||||
p->enc = enc;
|
||||
|
||||
p->tabwidth = 5;
|
||||
p->defrmargin = 78;
|
||||
@ -93,7 +92,7 @@ ascii_init(enum termenc enc, char *outopts)
|
||||
if (TERMENC_ASCII != enc) {
|
||||
v = TERMENC_LOCALE == enc ?
|
||||
setlocale(LC_ALL, "") :
|
||||
setlocale(LC_CTYPE, "UTF-8");
|
||||
setlocale(LC_CTYPE, "en_US.UTF-8");
|
||||
if (NULL != v && MB_CUR_MAX > 1) {
|
||||
p->enc = enc;
|
||||
p->advance = locale_advance;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: tree.c,v 1.47 2011/09/18 14:14:15 schwarze Exp $ */
|
||||
/* $Id: tree.c,v 1.50 2013/12/24 19:11:46 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -58,13 +59,11 @@ print_mdoc(const struct mdoc_node *n, int indent)
|
||||
{
|
||||
const char *p, *t;
|
||||
int i, j;
|
||||
size_t argc, sz;
|
||||
char **params;
|
||||
size_t argc;
|
||||
struct mdoc_argv *argv;
|
||||
|
||||
argv = NULL;
|
||||
argc = sz = 0;
|
||||
params = NULL;
|
||||
argc = 0;
|
||||
t = p = NULL;
|
||||
|
||||
switch (n->type) {
|
||||
@ -161,11 +160,14 @@ print_mdoc(const struct mdoc_node *n, int indent)
|
||||
if (argv[i].sz > 0)
|
||||
printf(" ]");
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)sz; i++)
|
||||
printf(" [%s]", params[i]);
|
||||
|
||||
printf(" %d:%d\n", n->line, n->pos);
|
||||
putchar(' ');
|
||||
if (MDOC_LINE & n->flags)
|
||||
putchar('*');
|
||||
printf("%d:%d", n->line, n->pos);
|
||||
if (n->lastline != n->line)
|
||||
printf("-%d", n->lastline);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
if (n->child)
|
||||
|
@ -15,6 +15,6 @@ SRCS= arch.c att.c chars.c \
|
||||
tbl.c tbl_data.c tbl_layout.c tbl_opts.c vol.c
|
||||
|
||||
WARNS?= 3
|
||||
CFLAGS+= -DHAVE_CONFIG_H -DVERSION="\"1.12.1\""
|
||||
CFLAGS+= -DHAVE_CONFIG_H
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -15,7 +15,7 @@ SRCS= eqn_html.c eqn_term.c html.c main.c man_html.c man_term.c mdoc_html.c \
|
||||
term_ascii.c term_ps.c tree.c
|
||||
|
||||
WARNS?= 3
|
||||
CFLAGS+= -DHAVE_CONFIG_H -DVERSION="\"1.12.1\""
|
||||
CFLAGS+= -DHAVE_CONFIG_H
|
||||
DPADD= ${LIBMANDOC}
|
||||
LDADD= ${LIBMANDOC}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user