+++ /dev/null
-.\" $Id: mandoc_char.7,v 1.33 2010/03/23 13:25:01 kristaps Exp $
-.\"
-.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd March 27, 2010
-.Dt MANDOC_CHAR 7
-.Os
-.
-.
-.Sh NAME
-.Nm mandoc_char
-.Nd mandoc special characters
-.
-.
-.Sh DESCRIPTION
-This page documents the special characters and predefined strings accepted by
-.Xr mandoc 1
-to format
-.Xr mdoc 7
-and
-.Xr man 7
-documents.
-.
-.Pp
-Both
-.Xr mdoc 7
-and
-.Xr man 7
-encode special characters with
-.Sq \eX
-.Pq for a one-character escape ,
-.Sq \e(XX
-.Pq two-character ,
-and
-.Sq \e[N]
-.Pq N-character .
-One may generalise
-.Sq \e(XX
-as
-.Sq \e[XX]
-and
-.Sq \eX
-as
-.Sq \e[X] .
-Predefined strings are functionally similar to special characters, using
-.Sq \e*X
-.Pq for a one-character escape ,
-.Sq \e*(XX
-.Pq two-character ,
-and
-.Sq \e*[N]
-.Pq N-character .
-One may generalise
-.Sq \e*(XX
-as
-.Sq \e*[XX]
-and
-.Sq \e*X
-as
-.Sq \e*[X] .
-.
-.Pp
-Note that each output mode will have a different rendering of the
-characters.
-It's guaranteed that each input symbol will correspond to a
-(more or less) meaningful output rendering, regardless the mode.
-.
-.
-.Sh SPECIAL CHARACTERS
-These are the preferred input symbols for producing special characters.
-.
-.Pp
-Spacing:
-.Bl -column -compact -offset indent "Input" "Description"
-.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 \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)
-.El
-.
-.Pp
-Lines:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(ba Ta \(ba Ta bar
-.It \e(br Ta \(br Ta box rule
-.It \e(ul Ta \(ul Ta underscore
-.It \e(rl Ta \(rl Ta overline
-.It \e(bb Ta \(bb Ta broken bar
-.It \e(sl Ta \(sl Ta forward slash
-.It \e(rs Ta \(rs Ta backward slash
-.El
-.
-.Pp
-Text markers:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(ci Ta \(ci Ta circle
-.It \e(bu Ta \(bu Ta bullet
-.It \e(dd Ta \(dd Ta double dagger
-.It \e(dg Ta \(dg Ta dagger
-.It \e(lz Ta \(lz Ta lozenge
-.It \e(sq Ta \(sq Ta white square
-.It \e(ps Ta \(ps Ta paragraph
-.It \e(sc Ta \(sc Ta section
-.It \e(lh Ta \(lh Ta left hand
-.It \e(rh Ta \(rh Ta right hand
-.It \e(at Ta \(at Ta at
-.It \e(sh Ta \(sh Ta hash (pound)
-.It \e(CR Ta \(CR Ta carriage return
-.It \e(OK Ta \(OK Ta check mark
-.El
-.
-.Pp
-Legal symbols:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(co Ta \(co Ta copyright
-.It \e(rg Ta \(rg Ta registered
-.It \e(tm Ta \(tm Ta trademarked
-.El
-.
-.Pp
-Punctuation:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(em Ta \(em Ta em-dash
-.It \e(en Ta \(en Ta en-dash
-.It \e(hy Ta \(hy Ta hyphen
-.It \ee Ta \e Ta back-slash
-.It \e. Ta \. Ta period
-.It \e(r! Ta \(r! Ta upside-down exclamation
-.It \e(r? Ta \(r? Ta upside-down question
-.El
-.
-.Pp
-Quotes:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(Bq Ta \(Bq Ta right low double-quote
-.It \e(bq Ta \(bq Ta right low single-quote
-.It \e(lq Ta \(lq Ta left double-quote
-.It \e(rq Ta \(rq Ta right double-quote
-.It \e(oq Ta \(oq Ta left single-quote
-.It \e(cq Ta \(cq Ta right single-quote
-.It \e(aq Ta \(aq Ta apostrophe quote (text)
-.It \e(dq Ta \(dq Ta double quote (text)
-.It \e(Fo Ta \(Fo Ta left guillemet
-.It \e(Fc Ta \(Fc Ta right guillemet
-.It \e(fo Ta \(fo Ta left single guillemet
-.It \e(fc Ta \(fc Ta right single guillemet
-.El
-.
-.Pp
-Brackets:
-.Bl -column -compact -offset indent "x[bracketrightbp]" Rendered Description
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(lB Ta \(lB Ta left bracket
-.It \e(rB Ta \(rB Ta right bracket
-.It \e(lC Ta \(lC Ta left brace
-.It \e(rC Ta \(rC Ta right brace
-.It \e(la Ta \(la Ta left angle
-.It \e(ra Ta \(ra Ta right angle
-.It \e(bv Ta \(bv Ta brace extension
-.It \e[braceex] Ta \[braceex] Ta brace extension
-.It \e[bracketlefttp] Ta \[bracketlefttp] Ta top-left hooked bracket
-.It \e[bracketleftbp] Ta \[bracketleftbp] Ta bottom-left hooked bracket
-.It \e[bracketleftex] Ta \[bracketleftex] Ta left hooked bracket extension
-.It \e[bracketrighttp] Ta \[bracketrighttp] Ta top-right hooked bracket
-.It \e[bracketrightbp] Ta \[bracketrightbp] Ta bottom-right hooked bracket
-.It \e[bracketrightex] Ta \[bracketrightex] Ta right hooked bracket extension
-.It \e(lt Ta \(lt Ta top-left hooked brace
-.It \e[bracelefttp] Ta \[bracelefttp] Ta top-left hooked brace
-.It \e(lk Ta \(lk Ta mid-left hooked brace
-.It \e[braceleftmid] Ta \[braceleftmid] Ta mid-left hooked brace
-.It \e(lb Ta \(lb Ta bottom-left hooked brace
-.It \e[braceleftbp] Ta \[braceleftbp] Ta bottom-left hooked brace
-.It \e[braceleftex] Ta \[braceleftex] Ta left hooked brace extension
-.It \e(rt Ta \(rt Ta top-left hooked brace
-.It \e[bracerighttp] Ta \[bracerighttp] Ta top-right hooked brace
-.It \e(rk Ta \(rk Ta mid-right hooked brace
-.It \e[bracerightmid] Ta \[bracerightmid] Ta mid-right hooked brace
-.It \e(rb Ta \(rb Ta bottom-right hooked brace
-.It \e[bracerightbp] Ta \[bracerightbp] Ta bottom-right hooked brace
-.It \e[bracerightex] Ta \[bracerightex] Ta right hooked brace extension
-.It \e[parenlefttp] Ta \[parenlefttp] Ta top-left hooked parenthesis
-.It \e[parenleftbp] Ta \[parenleftbp] Ta bottom-left hooked parenthesis
-.It \e[parenleftex] Ta \[parenleftex] Ta left hooked parenthesis extension
-.It \e[parenrighttp] Ta \[parenrighttp] Ta top-right hooked parenthesis
-.It \e[parenrightbp] Ta \[parenrightbp] Ta bottom-right hooked parenthesis
-.It \e[parenrightex] Ta \[parenrightex] Ta right hooked parenthesis extension
-.El
-.
-.Pp
-Arrows:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(<- Ta \(<- Ta left arrow
-.It \e(-> Ta \(-> Ta right arrow
-.It \e(<> Ta \(<> Ta left-right arrow
-.It \e(da Ta \(da Ta down arrow
-.It \e(ua Ta \(ua Ta up arrow
-.It \e(va Ta \(va Ta up-down arrow
-.It \e(lA Ta \(lA Ta left double-arrow
-.It \e(rA Ta \(rA Ta right double-arrow
-.It \e(hA Ta \(hA Ta left-right double-arrow
-.It \e(uA Ta \(uA Ta up double-arrow
-.It \e(dA Ta \(dA Ta down double-arrow
-.It \e(vA Ta \(vA Ta up-down double-arrow
-.El
-.
-.Pp
-Logical:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(AN Ta \(AN Ta logical and
-.It \e(OR Ta \(OR Ta logical or
-.It \e(no Ta \(no Ta logical not
-.It \e[tno] Ta \[tno] Ta logical not (text)
-.It \e(te Ta \(te Ta existential quantifier
-.It \e(fa Ta \(fa Ta universal quantifier
-.It \e(st Ta \(st Ta such that
-.It \e(tf Ta \(tf Ta therefore
-.It \e(3d Ta \(3d Ta therefore
-.It \e(or Ta \(or Ta bitwise or
-.El
-.
-.Pp
-Mathematical:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(pl Ta \(pl Ta plus
-.It \e(mi Ta \(mi Ta minus
-.It \e- Ta \- Ta minus (text)
-.It \e(-+ Ta \(-+ Ta minus-plus
-.It \e(+- Ta \(+- Ta plus-minus
-.It \e[t+-] Ta \[t+-] Ta plus-minus (text)
-.It \e(pc Ta \(pc Ta centre-dot
-.It \e(mu Ta \(mu Ta multiply
-.It \e[tmu] Ta \[tmu] Ta multiply (text)
-.It \e(c* Ta \(c* Ta circle-multiply
-.It \e(c+ Ta \(c+ Ta circle-plus
-.It \e(di Ta \(di Ta divide
-.It \e[tdi] Ta \[tdi] Ta divide (text)
-.It \e(f/ Ta \(f/ Ta fraction
-.It \e(** Ta \(** Ta asterisk
-.It \e(<= Ta \(<= Ta less-than-equal
-.It \e(>= Ta \(>= Ta greater-than-equal
-.It \e(<< Ta \(<< Ta much less
-.It \e(>> Ta \(>> Ta much greater
-.It \e(eq Ta \(eq Ta equal
-.It \e(!= Ta \(!= Ta not equal
-.It \e(== Ta \(== Ta equivalent
-.It \e(ne Ta \(ne Ta not equivalent
-.It \e(=~ Ta \(=~ Ta congruent
-.It \e(-~ Ta \(-~ Ta asymptotically congruent
-.It \e(ap Ta \(ap Ta asymptotically similar
-.It \e(~~ Ta \(~~ Ta approximately similar
-.It \e(~= Ta \(~= Ta approximately equal
-.It \e(pt Ta \(pt Ta proportionate
-.It \e(es Ta \(es Ta empty set
-.It \e(mo Ta \(mo Ta element
-.It \e(nm Ta \(nm Ta not element
-.It \e(sb Ta \(sb Ta proper subset
-.It \e(nb Ta \(nb Ta not subset
-.It \e(sp Ta \(sp Ta proper superset
-.It \e(nc Ta \(nc Ta not superset
-.It \e(ib Ta \(ib Ta reflexive subset
-.It \e(ip Ta \(ip Ta reflexive superset
-.It \e(ca Ta \(ca Ta intersection
-.It \e(cu Ta \(cu Ta union
-.It \e(/_ Ta \(/_ Ta angle
-.It \e(pp Ta \(pp Ta perpendicular
-.It \e(is Ta \(is Ta integral
-.It \e[integral] Ta \[integral] Ta integral
-.It \e[sum] Ta \[sum] Ta summation
-.It \e[product] Ta \[product] Ta product
-.It \e[coproduct] Ta \[coproduct] Ta coproduct
-.It \e(gr Ta \(gr Ta gradient
-.It \e(sr Ta \(sr Ta square root
-.It \e[sqrt] Ta \[sqrt] Ta square root
-.It \e(lc Ta \(lc Ta left-ceiling
-.It \e(rc Ta \(rc Ta right-ceiling
-.It \e(lf Ta \(lf Ta left-floor
-.It \e(rf Ta \(rf Ta right-floor
-.It \e(if Ta \(if Ta infinity
-.It \e(Ah Ta \(Ah Ta aleph
-.It \e(Im Ta \(Im Ta imaginary
-.It \e(Re Ta \(Re Ta real
-.It \e(pd Ta \(pd Ta partial differential
-.It \e(-h Ta \(-h Ta Planck constant over 2\(*p
-.El
-.
-.Pp
-Ligatures:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(ff Ta \(ff Ta ff ligature
-.It \e(fi Ta \(fi Ta fi ligature
-.It \e(fl Ta \(fl Ta fl ligature
-.It \e(Fi Ta \(Fi Ta ffi ligature
-.It \e(Fl Ta \(Fl Ta ffl ligature
-.It \e(AE Ta \(AE Ta AE
-.It \e(ae Ta \(ae Ta ae
-.It \e(OE Ta \(OE Ta OE
-.It \e(oe Ta \(oe Ta oe
-.It \e(ss Ta \(ss Ta German eszett
-.It \e(IJ Ta \(IJ Ta IJ ligature
-.It \e(ij Ta \(ij Ta ij ligature
-.El
-.
-.Pp
-Accents:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(a" Ta \(a" Ta Hungarian umlaut
-.It \e(a- Ta \(a- Ta macron
-.It \e(a. Ta \(a. Ta dotted
-.It \e(a^ Ta \(a^ Ta circumflex
-.It \e(aa Ta \(aa Ta acute
-.It \e' Ta \' Ta acute
-.It \e(ga Ta \(ga Ta grave
-.It \e` Ta \` Ta grave
-.It \e(ab Ta \(ab Ta breve
-.It \e(ac Ta \(ac Ta cedilla
-.It \e(ad Ta \(ad Ta dieresis
-.It \e(ah Ta \(ah Ta caron
-.It \e(ao Ta \(ao Ta ring
-.It \e(a~ Ta \(a~ Ta tilde
-.It \e(ho Ta \(ho Ta ogonek
-.It \e(ha Ta \(ha Ta hat (text)
-.It \e(ti Ta \(ti Ta tilde (text)
-.El
-.
-.Pp
-Accented letters:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e('A Ta \('A Ta acute A
-.It \e('E Ta \('E Ta acute E
-.It \e('I Ta \('I Ta acute I
-.It \e('O Ta \('O Ta acute O
-.It \e('U Ta \('U Ta acute U
-.It \e('a Ta \('a Ta acute a
-.It \e('e Ta \('e Ta acute e
-.It \e('i Ta \('i Ta acute i
-.It \e('o Ta \('o Ta acute o
-.It \e('u Ta \('u Ta acute u
-.It \e(`A Ta \(`A Ta grave A
-.It \e(`E Ta \(`E Ta grave E
-.It \e(`I Ta \(`I Ta grave I
-.It \e(`O Ta \(`O Ta grave O
-.It \e(`U Ta \(`U Ta grave U
-.It \e(`a Ta \(`a Ta grave a
-.It \e(`e Ta \(`e Ta grave e
-.It \e(`i Ta \(`i Ta grave i
-.It \e(`o Ta \(`i Ta grave o
-.It \e(`u Ta \(`u Ta grave u
-.It \e(~A Ta \(~A Ta tilde A
-.It \e(~N Ta \(~N Ta tilde N
-.It \e(~O Ta \(~O Ta tilde O
-.It \e(~a Ta \(~a Ta tilde a
-.It \e(~n Ta \(~n Ta tilde n
-.It \e(~o Ta \(~o Ta tilde o
-.It \e(:A Ta \(:A Ta dieresis A
-.It \e(:E Ta \(:E Ta dieresis E
-.It \e(:I Ta \(:I Ta dieresis I
-.It \e(:O Ta \(:O Ta dieresis O
-.It \e(:U Ta \(:U Ta dieresis U
-.It \e(:a Ta \(:a Ta dieresis a
-.It \e(:e Ta \(:e Ta dieresis e
-.It \e(:i Ta \(:i Ta dieresis i
-.It \e(:o Ta \(:o Ta dieresis o
-.It \e(:u Ta \(:u Ta dieresis u
-.It \e(:y Ta \(:y Ta dieresis y
-.It \e(^A Ta \(^A Ta circumflex A
-.It \e(^E Ta \(^E Ta circumflex E
-.It \e(^I Ta \(^I Ta circumflex I
-.It \e(^O Ta \(^O Ta circumflex O
-.It \e(^U Ta \(^U Ta circumflex U
-.It \e(^a Ta \(^a Ta circumflex a
-.It \e(^e Ta \(^e Ta circumflex e
-.It \e(^i Ta \(^i Ta circumflex i
-.It \e(^o Ta \(^o Ta circumflex o
-.It \e(^u Ta \(^u Ta circumflex u
-.It \e(,C Ta \(,C Ta cedilla C
-.It \e(,c Ta \(,c Ta cedilla c
-.It \e(/L Ta \(/L Ta stroke L
-.It \e(/l Ta \(/l Ta stroke l
-.It \e(/O Ta \(/O Ta stroke O
-.It \e(/o Ta \(/o Ta stroke o
-.It \e(oA Ta \(oA Ta ring A
-.It \e(oa Ta \(oa Ta ring a
-.El
-.
-.Pp
-Special letters:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(-D Ta \(-D Ta Eth
-.It \e(Sd Ta \(Sd Ta eth
-.It \e(TP Ta \(TP Ta Thorn
-.It \e(Tp Ta \(Tp Ta thorn
-.It \e(.i Ta \(.i Ta dotless i
-.It \e(.j Ta \(.j Ta dotless j
-.El
-.
-.Pp
-Currency:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(Do Ta \(Do Ta dollar
-.It \e(ct Ta \(ct Ta cent
-.It \e(Eu Ta \(Eu Ta Euro symbol
-.It \e(eu Ta \(eu Ta Euro symbol
-.It \e(Ye Ta \(Ye Ta yen
-.It \e(Po Ta \(Po Ta pound
-.It \e(Cs Ta \(Cs Ta Scandinavian
-.It \e(Fn Ta \(Fn Ta florin
-.El
-.
-.Pp
-Units:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(de Ta \(de Ta degree
-.It \e(%0 Ta \(%0 Ta per-thousand
-.It \e(fm Ta \(fm Ta minute
-.It \e(sd Ta \(sd Ta second
-.It \e(mc Ta \(mc Ta micro
-.El
-.
-.Pp
-Greek letters:
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e(*A Ta \(*A Ta Alpha
-.It \e(*B Ta \(*B Ta Beta
-.It \e(*G Ta \(*G Ta Gamma
-.It \e(*D Ta \(*D Ta Delta
-.It \e(*E Ta \(*E Ta Epsilon
-.It \e(*Z Ta \(*Z Ta Zeta
-.It \e(*Y Ta \(*Y Ta Eta
-.It \e(*H Ta \(*H Ta Theta
-.It \e(*I Ta \(*I Ta Iota
-.It \e(*K Ta \(*K Ta Kappa
-.It \e(*L Ta \(*L Ta Lambda
-.It \e(*M Ta \(*M Ta Mu
-.It \e(*N Ta \(*N Ta Nu
-.It \e(*C Ta \(*C Ta Xi
-.It \e(*O Ta \(*O Ta Omicron
-.It \e(*P Ta \(*P Ta Pi
-.It \e(*R Ta \(*R Ta Rho
-.It \e(*S Ta \(*S Ta Sigma
-.It \e(*T Ta \(*T Ta Tau
-.It \e(*U Ta \(*U Ta Upsilon
-.It \e(*F Ta \(*F Ta Phi
-.It \e(*X Ta \(*X Ta Chi
-.It \e(*Q Ta \(*Q Ta Psi
-.It \e(*W Ta \(*W Ta Omega
-.It \e(*a Ta \(*a Ta alpha
-.It \e(*b Ta \(*b Ta beta
-.It \e(*g Ta \(*g Ta gamma
-.It \e(*d Ta \(*d Ta delta
-.It \e(*e Ta \(*e Ta epsilon
-.It \e(*z Ta \(*z Ta zeta
-.It \e(*y Ta \(*y Ta eta
-.It \e(*h Ta \(*h Ta theta
-.It \e(*i Ta \(*i Ta iota
-.It \e(*k Ta \(*k Ta kappa
-.It \e(*l Ta \(*l Ta lambda
-.It \e(*m Ta \(*m Ta mu
-.It \e(*n Ta \(*n Ta nu
-.It \e(*c Ta \(*c Ta xi
-.It \e(*o Ta \(*o Ta omicron
-.It \e(*p Ta \(*p Ta pi
-.It \e(*r Ta \(*r Ta rho
-.It \e(*s Ta \(*s Ta sigma
-.It \e(*t Ta \(*t Ta tau
-.It \e(*u Ta \(*u Ta upsilon
-.It \e(*f Ta \(*f Ta phi
-.It \e(*x Ta \(*x Ta chi
-.It \e(*q Ta \(*q Ta psi
-.It \e(*w Ta \(*w Ta omega
-.It \e(+h Ta \(+h Ta theta variant
-.It \e(+f Ta \(+f Ta phi variant
-.It \e(+p Ta \(+p Ta pi variant
-.It \e(+e Ta \(+e Ta epsilon variant
-.It \e(ts Ta \(ts Ta sigma terminal
-.El
-.
-.
-.Sh PREDEFINED STRINGS
-These are not recommended for use, as they differ across
-implementations:
-.
-.Pp
-.Bl -column -compact -offset indent "Input" "Rendered" "Description"
-.It Em Input Ta Em Rendered Ta Em Description
-.It \e*(Ba Ta \*(Ba Ta vertical bar
-.It \e*(Ne Ta \*(Ne Ta not equal
-.It \e*(Ge Ta \*(Ge Ta greater-than-equal
-.It \e*(Le Ta \*(Le Ta less-than-equal
-.It \e*(Gt Ta \*(Gt Ta greater-than
-.It \e*(Lt Ta \*(Lt Ta less-than
-.It \e*(Pm Ta \*(Pm Ta plus-minus
-.It \e*(If Ta \*(If Ta infinity
-.It \e*(Pi Ta \*(Pi Ta pi
-.It \e*(Na Ta \*(Na Ta NaN
-.It \e*(Am Ta \*(Am Ta ampersand
-.It \e*R Ta \*R Ta restricted mark
-.It \e*(Tm Ta \*(Tm Ta trade mark
-.It \e*q Ta \*q Ta double-quote
-.It \e*(Rq Ta \*(Rq Ta right-double-quote
-.It \e*(Lq Ta \*(Lq Ta left-double-quote
-.It \e*(lp Ta \*(lp Ta right-parenthesis
-.It \e*(rp Ta \*(rp Ta left-parenthesis
-.It \e*(lq Ta \*(lq Ta left double-quote
-.It \e*(rq Ta \*(rq Ta right double-quote
-.It \e*(ua Ta \*(ua Ta up arrow
-.It \e*(va Ta \*(va Ta up-down arrow
-.It \e*(<= Ta \*(<= Ta less-than-equal
-.It \e*(>= Ta \*(>= Ta greater-than-equal
-.It \e*(aa Ta \*(aa Ta acute
-.It \e*(ga Ta \*(ga Ta grave
-.It \e*(-- Ta \*(-- Ta dash
-.It \e*(PI Ta \*(PI Ta pi
-.It \e*(L" Ta \*(L" Ta left double-quote
-.It \e*(R" Ta \*(R" Ta right double-quote
-.It \e*(C+ Ta \*(C+ Ta C++
-.It \e*(C` Ta \*(C` Ta left single-quote
-.It \e*(C' Ta \*(C' Ta right single-quote
-.It \e*(Aq Ta \*(Aq Ta apostrophe quote
-.It \e*^ Ta \*^ Ta up-arrow
-.It \e*, Ta \*, Ta comma
-.It \e*~ Ta \*~ Ta tilde
-.It \e*/ Ta \*/ Ta forward slash
-.It \e*: Ta \*: Ta umlaut
-.It \e*8 Ta \*8 Ta beta
-.It \e*o Ta \*o Ta degree symbol
-.It \e*(D- Ta \*(D- Ta Eth
-.It \e*(d- Ta \*(d- Ta eth
-.It \e*(TH Ta \*(TH Ta Thorn
-.It \e*(th Ta \*(th Ta thorn
-.El
-.
-.
-.Sh COMPATIBILITY
-This section documents compatibility of
-.Nm
-with older or existing versions of
-.Xr groff 1 .
-.
-.Pp
-The following render differently in
-.Fl T Ns Ar ascii
-output mode:
-.Bd -ragged -offset indent
-\e(ss, \e(nm, \e(nb, \e(nc, \e(ib, \e(ip, \e(pp, \e[sum], \e[product],
-\e[coproduct], \e(gr, \e(-h, \e(a.
-.Ed
-.
-.Pp
-The following render differently in
-.Fl T Ns Ar html
-output mode:
-.Bd -ragged -offset indent
-\e(~=, \e(nb, \e(nc
-.Ed
-.
-.Pp
-Finally, the following have been omitted by being poorly documented or
-having no known representation:
-.Bd -ragged -offset indent
-\e[radicalex], \e[sqrtex], \e(ru
-.Ed
-.
-.
-.Sh SEE ALSO
-.Xr mandoc 1
-.
-.
-.Sh AUTHORS
-The
-.Nm
-manual page was written by
-.An Kristaps Dzonsons Aq kristaps@kth.se .
+++ /dev/null
-/* $Id: arch.c,v 1.6 2010/01/01 17:14:26 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "libmdoc.h"
-
-#define LINE(x, y) \
- if (0 == strcmp(p, x)) return(y);
-
-const char *
-mdoc_a2arch(const char *p)
-{
-
-#include "arch.in"
-
- return(NULL);
-}
+++ /dev/null
-/* $Id: arch.in,v 1.7 2010/03/26 07:07:58 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file defines the architecture token of the .Dt prologue macro.
- * All architectures that your system supports (or the manuals of your
- * system) should be included here. The right-hand-side is the
- * formatted output.
- *
- * Be sure to escape strings.
- */
-
-LINE("alpha", "Alpha")
-LINE("amd64", "AMD64")
-LINE("amiga", "Amiga")
-LINE("arc", "ARC")
-LINE("arm", "ARM")
-LINE("armish", "ARMISH")
-LINE("aviion", "AViiON")
-LINE("hp300", "HP300")
-LINE("hppa", "HPPA")
-LINE("hppa64", "HPPA64")
-LINE("i386", "i386")
-LINE("landisk", "LANDISK")
-LINE("loongson", "Loongson")
-LINE("luna88k", "Luna88k")
-LINE("mac68k", "Mac68k")
-LINE("macppc", "MacPPC")
-LINE("mvme68k", "MVME68k")
-LINE("mvme88k", "MVME88k")
-LINE("mvmeppc", "MVMEPPC")
-LINE("pmax", "PMAX")
-LINE("sgi", "SGI")
-LINE("socppc", "SOCPPC")
-LINE("sparc", "SPARC")
-LINE("sparc64", "SPARC64")
-LINE("sun3", "Sun3")
-LINE("vax", "VAX")
-LINE("x86_64", "x86_64")
-LINE("zaurus", "Zaurus")
+++ /dev/null
-/* $Id: att.c,v 1.6 2010/01/01 17:14:26 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "libmdoc.h"
-
-#define LINE(x, y) \
- if (0 == strcmp(p, x)) return(y);
-
-const char *
-mdoc_a2att(const char *p)
-{
-
-#include "att.in"
-
- return(NULL);
-}
+++ /dev/null
-/* $Id: att.in,v 1.5 2009/06/10 20:18:43 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file defines the AT&T versions of the .At macro. This probably
- * isn't going to change. The right-hand side is the formatted string.
- *
- * Be sure to escape strings.
- */
-
-LINE("v1", "Version 1 AT&T UNIX")
-LINE("v2", "Version 2 AT&T UNIX")
-LINE("v3", "Version 3 AT&T UNIX")
-LINE("v4", "Version 4 AT&T UNIX")
-LINE("v5", "Version 5 AT&T UNIX")
-LINE("v6", "Version 6 AT&T UNIX")
-LINE("v7", "Version 7 AT&T UNIX")
-LINE("32v", "Version 32V AT&T UNIX")
-LINE("V", "AT&T System V UNIX")
-LINE("V.1", "AT&T System V.1 UNIX")
-LINE("V.2", "AT&T System V.2 UNIX")
-LINE("V.3", "AT&T System V.3 UNIX")
-LINE("V.4", "AT&T System V.4 UNIX")
+++ /dev/null
-/* $Id: chars.c,v 1.17 2010/03/23 13:25:01 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "chars.h"
-
-#define PRINT_HI 126
-#define PRINT_LO 32
-
-struct ln {
- struct ln *next;
- const char *code;
- const char *ascii;
- const char *html;
- size_t codesz;
- size_t asciisz;
- size_t htmlsz;
- int type;
-#define CHARS_CHAR (1 << 0)
-#define CHARS_STRING (1 << 1)
-#define CHARS_BOTH (CHARS_CHAR | CHARS_STRING)
-};
-
-#define LINES_MAX 369
-
-#define CHAR(w, x, y, z, a, b) \
- { NULL, (w), (y), (a), (x), (z), (b), CHARS_CHAR },
-#define STRING(w, x, y, z, a, b) \
- { NULL, (w), (y), (a), (x), (z), (b), CHARS_STRING },
-#define BOTH(w, x, y, z, a, b) \
- { NULL, (w), (y), (a), (x), (z), (b), CHARS_BOTH },
-
-#define CHAR_TBL_START static struct ln lines[LINES_MAX] = {
-#define CHAR_TBL_END };
-
-#include "chars.in"
-
-struct tbl {
- enum chars type;
- struct ln **htab;
-};
-
-static inline int match(const struct ln *,
- const char *, size_t, int);
-static const char *find(struct tbl *, const char *,
- size_t, size_t *, int);
-
-
-void
-chars_free(void *arg)
-{
- struct tbl *tab;
-
- tab = (struct tbl *)arg;
-
- free(tab->htab);
- free(tab);
-}
-
-
-void *
-chars_init(enum chars type)
-{
- struct tbl *tab;
- struct ln **htab;
- struct ln *pp;
- int i, hash;
-
- /*
- * Constructs a very basic chaining hashtable. The hash routine
- * is simply the integral value of the first character.
- * Subsequent entries are chained in the order they're processed
- * (they're in-line re-ordered during lookup).
- */
-
- tab = malloc(sizeof(struct tbl));
- if (NULL == tab) {
- perror(NULL);
- exit(EXIT_FAILURE);
- }
-
- htab = calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
- if (NULL == htab) {
- perror(NULL);
- exit(EXIT_FAILURE);
- }
-
- for (i = 0; i < LINES_MAX; i++) {
- hash = (int)lines[i].code[0] - PRINT_LO;
-
- if (NULL == (pp = htab[hash])) {
- htab[hash] = &lines[i];
- continue;
- }
-
- for ( ; pp->next; pp = pp->next)
- /* Scan ahead. */ ;
- pp->next = &lines[i];
- }
-
- tab->htab = htab;
- tab->type = type;
- return(tab);
-}
-
-
-const char *
-chars_a2ascii(void *arg, const char *p, size_t sz, size_t *rsz)
-{
-
- return(find((struct tbl *)arg, p, sz, rsz, CHARS_CHAR));
-}
-
-
-const char *
-chars_a2res(void *arg, const char *p, size_t sz, size_t *rsz)
-{
-
- return(find((struct tbl *)arg, p, sz, rsz, CHARS_STRING));
-}
-
-
-static const char *
-find(struct tbl *tab, const char *p, size_t sz, size_t *rsz, int type)
-{
- struct ln *pp, *prev;
- struct ln **htab;
- int hash;
-
- assert(p);
- assert(sz > 0);
-
- if (p[0] < PRINT_LO || p[0] > PRINT_HI)
- return(NULL);
-
- /*
- * Lookup the symbol in the symbol hash. See ascii2htab for the
- * hashtable specs. This dynamically re-orders the hash chain
- * to optimise for repeat hits.
- */
-
- hash = (int)p[0] - PRINT_LO;
- htab = tab->htab;
-
- if (NULL == (pp = htab[hash]))
- return(NULL);
-
- for (prev = NULL; pp; pp = pp->next) {
- if ( ! match(pp, p, sz, type)) {
- prev = pp;
- continue;
- }
-
- if (prev) {
- prev->next = pp->next;
- pp->next = htab[hash];
- htab[hash] = pp;
- }
-
- if (CHARS_HTML == tab->type) {
- *rsz = pp->htmlsz;
- return(pp->html);
- }
- *rsz = pp->asciisz;
- return(pp->ascii);
- }
-
- return(NULL);
-}
-
-
-static inline int
-match(const struct ln *ln, const char *p, size_t sz, int type)
-{
-
- if ( ! (ln->type & type))
- return(0);
- if (ln->codesz != sz)
- return(0);
- return(0 == strncmp(ln->code, p, sz));
-}
+++ /dev/null
-/* $Id: chars.h,v 1.1 2009/09/17 07:41:28 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef CHARS_H
-#define CHARS_H
-
-__BEGIN_DECLS
-
-enum chars {
- CHARS_ASCII,
- CHARS_HTML
-};
-
-void *chars_init(enum chars);
-const char *chars_a2ascii(void *, const char *, size_t, size_t *);
-const char *chars_a2res(void *, const char *, size_t, size_t *);
-void chars_free(void *);
-
-__END_DECLS
-
-#endif /*!CHARS_H*/
+++ /dev/null
-/* $Id: chars.in,v 1.21 2010/03/23 13:25:01 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * The ASCII translation tables. STRING corresponds to predefined
- * strings (cf. mdoc_samples.7 and tmac/mdoc/doc-nroff). CHAR
- * corresponds to special characters (cf. groff_char.7). BOTH contains
- * sequences that are equivalent in both STRING and CHAR.
- *
- * Either way, the left-hand side corresponds to the input sequence (\x,
- * \(xx, \*(xx and so on) whose length is listed second element. The
- * right-hand side is what's produced by the front-end, with the fourth
- * element being its length.
- *
- * XXX - C-escape strings!
- * XXX - update LINES_MAX if adding more!
- */
-
-/* Non-breaking, non-collapsing space uses unit separator. */
-static const char ascii_nbrsp[2] = { 31, 0 };
-
-CHAR_TBL_START
-
-/* Spacing. */
-CHAR("c", 1, "", 0, "", 0)
-CHAR("0", 1, " ", 1, " ", 7)
-CHAR(" ", 1, " ", 1, " ", 7)
-CHAR("~", 1, ascii_nbrsp, 1, " ", 6)
-CHAR("%", 1, "", 0, "", 0)
-CHAR("&", 1, "", 0, "", 0)
-CHAR("^", 1, "", 0, "", 0)
-CHAR("|", 1, "", 0, "", 0)
-
-/* Accents. */
-CHAR("a\"", 2, "\"", 1, "̋", 6)
-CHAR("a-", 2, "-", 1, "¯", 6)
-CHAR("a.", 2, ".", 1, "˙", 6)
-CHAR("a^", 2, "^", 1, "̂", 6)
-BOTH("\'", 1, "\'", 1, "́", 6)
-BOTH("aa", 2, "\'", 1, "́", 6)
-BOTH("ga", 2, "`", 1, "̀", 6)
-BOTH("`", 1, "`", 1, "̀", 6)
-CHAR("ab", 2, "`", 1, "̆", 6)
-CHAR("ac", 2, ",", 1, "̧", 6)
-CHAR("ad", 2, "\"", 1, "̈", 6)
-CHAR("ah", 2, "v", 1, "ˇ", 6)
-CHAR("ao", 2, "o", 1, "˚", 6)
-CHAR("a~", 2, "~", 1, "̃", 6)
-CHAR("ho", 2, ",", 1, "̨", 6)
-CHAR("ha", 2, "^", 1, "^", 1)
-CHAR("ti", 2, "~", 1, "~", 1)
-
-/* Quotes. */
-CHAR("Bq", 2, ",,", 2, "„", 7)
-CHAR("bq", 2, ",", 1, "‚", 7)
-BOTH("lq", 2, "``", 2, "“", 7)
-BOTH("rq", 2, "\'\'", 2, "”", 7)
-CHAR("oq", 2, "`", 1, "‘", 7)
-CHAR("cq", 2, "\'", 1, "’", 7)
-CHAR("aq", 2, "\'", 1, "\'", 1)
-CHAR("dq", 2, "\"", 1, "\"", 1)
-CHAR("Fo", 2, "<<", 2, "«", 6)
-CHAR("Fc", 2, ">>", 2, "»", 6)
-CHAR("fo", 2, "<", 1, "‹", 7)
-CHAR("fc", 2, ">", 1, "›", 7)
-
-/* Brackets. */
-CHAR("lB", 2, "[", 1, "[", 1)
-CHAR("rB", 2, "]", 1, "]", 1)
-CHAR("lC", 2, "{", 1, "{", 1)
-CHAR("rC", 2, "}", 1, "}", 1)
-CHAR("la", 2, "<", 1, "⟨", 8)
-CHAR("ra", 2, ">", 1, "⟩", 8)
-CHAR("bv", 2, "|", 1, "⎪", 7)
-CHAR("braceex", 7, "|", 1, "⎪", 7)
-CHAR("bracketlefttp", 13, "|", 1, "⎡", 7)
-CHAR("bracketleftbp", 13, "|", 1, "⎣", 7)
-CHAR("bracketleftex", 13, "|", 1, "⎢", 7)
-CHAR("bracketrighttp", 14, "|", 1, "⎤", 7)
-CHAR("bracketrightbp", 14, "|", 1, "⎦", 7)
-CHAR("bracketrightex", 14, "|", 1, "⎥", 7)
-CHAR("lt", 2, ",-", 2, "⎧", 7)
-CHAR("bracelefttp", 11, ",-", 2, "⎧", 7)
-CHAR("lk", 2, "{", 1, "⎨", 7)
-CHAR("braceleftmid", 12, "{", 1, "⎨", 7)
-CHAR("lb", 2, ",-", 2, "⎩", 7)
-CHAR("braceleftbp", 11, "`-", 2, "⎩", 7)
-CHAR("braceleftex", 11, "|", 1, "⎪", 7)
-CHAR("rt", 2, "-.", 2, "⎫", 7)
-CHAR("bracerighttp", 12, "-.", 2, "⎫", 7)
-CHAR("rk", 2, "}", 1, "⎬", 7)
-CHAR("bracerightmid", 13, "}", 1, "⎬", 7)
-CHAR("rb", 2, "-\'", 2, "⎭", 7)
-CHAR("bracerightbp", 12, "-\'", 2, "⎭", 7)
-CHAR("bracerightex", 12, "|", 1, "⎪", 7)
-CHAR("parenlefttp", 11, "/", 1, "⎛", 7)
-CHAR("parenleftbp", 11, "\\", 1, "⎝", 7)
-CHAR("parenleftex", 11, "|", 1, "⎜", 7)
-CHAR("parenrighttp", 12, "\\", 1, "⎞", 7)
-CHAR("parenrightbp", 12, "/", 1, "⎠", 7)
-CHAR("parenrightex", 12, "|", 1, "⎟", 7)
-
-/* Greek characters. */
-CHAR("*A", 2, "A", 1, "Α", 6)
-CHAR("*B", 2, "B", 1, "Β", 6)
-CHAR("*G", 2, "|", 1, "Γ", 6)
-CHAR("*D", 2, "/\\", 2, "Δ", 6)
-CHAR("*E", 2, "E", 1, "Ε", 6)
-CHAR("*Z", 2, "Z", 1, "Ζ", 6)
-CHAR("*Y", 2, "H", 1, "Η", 6)
-CHAR("*H", 2, "O", 1, "Θ", 6)
-CHAR("*I", 2, "I", 1, "Ι", 6)
-CHAR("*K", 2, "K", 1, "Κ", 6)
-CHAR("*L", 2, "/\\", 2, "Λ", 6)
-CHAR("*M", 2, "M", 1, "Μ", 6)
-CHAR("*N", 2, "N", 1, "Ν", 6)
-CHAR("*C", 2, "H", 1, "Ξ", 6)
-CHAR("*O", 2, "O", 1, "Ο", 6)
-CHAR("*P", 2, "TT", 2, "Π", 6)
-CHAR("*R", 2, "P", 1, "Ρ", 6)
-CHAR("*S", 2, ">", 1, "Σ", 6)
-CHAR("*T", 2, "T", 1, "Τ", 6)
-CHAR("*U", 2, "Y", 1, "Υ", 6)
-CHAR("*F", 2, "O_", 1, "Φ", 6)
-CHAR("*X", 2, "X", 1, "Χ", 6)
-CHAR("*Q", 2, "Y", 1, "Ψ", 6)
-CHAR("*W", 2, "O", 1, "Ω", 6)
-CHAR("*a", 2, "a", 1, "α", 6)
-CHAR("*b", 2, "B", 1, "β", 6)
-CHAR("*g", 2, "y", 1, "γ", 6)
-CHAR("*d", 2, "d", 1, "δ", 6)
-CHAR("*e", 2, "e", 1, "ε", 6)
-CHAR("*z", 2, "C", 1, "ζ", 6)
-CHAR("*y", 2, "n", 1, "η", 6)
-CHAR("*h", 2, "0", 1, "θ", 6)
-CHAR("*i", 2, "i", 1, "ι", 6)
-CHAR("*k", 2, "k", 1, "κ", 6)
-CHAR("*l", 2, "\\", 1, "λ", 6)
-CHAR("*m", 2, "u", 1, "μ", 6)
-CHAR("*n", 2, "v", 1, "ν", 6)
-CHAR("*c", 2, "E", 1, "ξ", 6)
-CHAR("*o", 2, "o", 1, "ο", 6)
-CHAR("*p", 2, "n", 1, "π", 6)
-CHAR("*r", 2, "p", 1, "ρ", 6)
-CHAR("*s", 2, "o", 1, "σ", 6)
-CHAR("*t", 2, "t", 1, "τ", 6)
-CHAR("*u", 2, "u", 1, "υ", 6)
-CHAR("*f", 2, "o", 1, "ϕ", 6)
-CHAR("*x", 2, "x", 1, "χ", 6)
-CHAR("*q", 2, "u", 1, "ψ", 6)
-CHAR("*w", 2, "w", 1, "ω", 6)
-CHAR("+h", 2, "0", 1, "ϑ", 6)
-CHAR("+f", 2, "o", 1, "φ", 6)
-CHAR("+p", 2, "w", 1, "ϖ", 6)
-CHAR("+e", 2, "e", 1, "ϵ", 7)
-CHAR("ts", 2, "s", 1, "ς", 6)
-
-/* Accented letters. */
-CHAR(",C", 2, "C", 1, "Ç", 6)
-CHAR(",c", 2, "c", 1, "ç", 6)
-CHAR("/L", 2, "L", 1, "Ł", 6)
-CHAR("/O", 2, "O", 1, "Ø", 6)
-CHAR("/l", 2, "l", 1, "ł", 6)
-CHAR("/o", 2, "o", 1, "ø", 6)
-CHAR("oA", 2, "A", 1, "Å", 6)
-CHAR("oa", 2, "a", 1, "å", 6)
-CHAR(":A", 2, "A", 1, "Ä", 6)
-CHAR(":E", 2, "E", 1, "Ë", 6)
-CHAR(":I", 2, "I", 1, "Ï", 6)
-CHAR(":O", 2, "O", 1, "Ö", 6)
-CHAR(":U", 2, "U", 1, "Ü", 6)
-CHAR(":a", 2, "a", 1, "ä", 6)
-CHAR(":e", 2, "e", 1, "ë", 6)
-CHAR(":i", 2, "i", 1, "ï", 6)
-CHAR(":o", 2, "o", 1, "õ", 6)
-CHAR(":u", 2, "u", 1, "ü", 6)
-CHAR(":y", 2, "y", 1, "ÿ", 6)
-CHAR("\'A", 2, "A", 1, "Á", 6)
-CHAR("\'E", 2, "E", 1, "É", 6)
-CHAR("\'I", 2, "I", 1, "Í", 6)
-CHAR("\'O", 2, "O", 1, "Ó", 6)
-CHAR("\'U", 2, "U", 1, "Ú", 6)
-CHAR("\'a", 2, "a", 1, "á", 6)
-CHAR("\'e", 2, "e", 1, "é", 6)
-CHAR("\'i", 2, "i", 1, "í", 6)
-CHAR("\'o", 2, "o", 1, "ó", 6)
-CHAR("\'u", 2, "u", 1, "ú", 6)
-CHAR("^A", 2, "A", 1, "Â", 6)
-CHAR("^E", 2, "E", 1, "Ê", 6)
-CHAR("^I", 2, "I", 1, "Î", 6)
-CHAR("^O", 2, "O", 1, "Ô", 6)
-CHAR("^U", 2, "U", 1, "Û", 6)
-CHAR("^a", 2, "a", 1, "â", 6)
-CHAR("^e", 2, "e", 1, "ê", 6)
-CHAR("^i", 2, "i", 1, "î", 6)
-CHAR("^o", 2, "o", 1, "ô", 6)
-CHAR("^u", 2, "u", 1, "û", 6)
-CHAR("`A", 2, "A", 1, "À", 6)
-CHAR("`E", 2, "E", 1, "È", 6)
-CHAR("`I", 2, "I", 1, "Ì", 6)
-CHAR("`O", 2, "O", 1, "Ò", 6)
-CHAR("`U", 2, "U", 1, "Ù", 6)
-CHAR("`a", 2, "a", 1, "à", 6)
-CHAR("`e", 2, "e", 1, "è", 6)
-CHAR("`i", 2, "i", 1, "ì", 6)
-CHAR("`o", 2, "o", 1, "ò", 6)
-CHAR("`u", 2, "u", 1, "ù", 6)
-CHAR("~A", 2, "A", 1, "Ã", 6)
-CHAR("~N", 2, "N", 1, "Ñ", 6)
-CHAR("~O", 2, "O", 1, "Õ", 6)
-CHAR("~a", 2, "a", 1, "ã", 6)
-CHAR("~n", 2, "n", 1, "ñ", 6)
-CHAR("~o", 2, "o", 1, "õ", 6)
-
-/* Arrows and lines. */
-CHAR("<-", 2, "<-", 2, "←", 7)
-CHAR("->", 2, "->", 2, "→", 7)
-CHAR("<>", 2, "<>", 2, "↔", 7)
-CHAR("da", 2, "v", 1, "↓", 7)
-BOTH("ua", 2, "^", 1, "↑", 7)
-BOTH("va", 2, "^v", 2, "↕", 7)
-CHAR("lA", 2, "<=", 2, "⇐", 7)
-CHAR("rA", 2, "=>", 2, "⇒", 7)
-CHAR("hA", 2, "<=>", 3, "⇔", 7)
-CHAR("dA", 2, "v", 1, "⇓", 7)
-CHAR("uA", 2, "^", 1, "⇑", 7)
-CHAR("vA", 2, "^=v", 3, "⇕", 7)
-
-/* Logic. */
-CHAR("AN", 2, "^", 1, "∧", 7)
-CHAR("OR", 2, "v", 1, "∨", 7)
-CHAR("no", 2, "~", 1, "¬", 6)
-CHAR("tno", 3, "~", 1, "¬", 6)
-CHAR("te", 2, "3", 1, "∃", 7)
-CHAR("fa", 2, "V", 1, "∀", 7)
-CHAR("st", 2, "-)", 2, "∋", 7)
-CHAR("tf", 2, ".:.", 3, "∴", 7)
-CHAR("3d", 2, ".:.", 3, "∴", 7)
-CHAR("or", 2, "|", 1, "|", 1)
-
-/* Mathematicals. */
-CHAR("pl", 2, "+", 1, "+", 5)
-CHAR("mi", 2, "-", 1, "−", 7)
-CHAR("-", 1, "-", 1, "-", 1)
-CHAR("-+", 2, "-+", 2, "∓", 7)
-CHAR("+-", 2, "+-", 2, "±", 6)
-CHAR("t+-", 3, "+-", 2, "±", 6)
-CHAR("pc", 2, ".", 1, "·", 6)
-CHAR("md", 2, ".", 1, "⋅", 7)
-CHAR("mu", 2, "x", 1, "×", 6)
-CHAR("tmu", 3, "x", 1, "×", 6)
-CHAR("c*", 2, "x", 1, "⊗", 7)
-CHAR("c+", 2, "+", 1, "⊕", 7)
-CHAR("di", 2, "-:-", 3, "÷", 6)
-CHAR("tdi", 3, "-:-", 3, "÷", 6)
-CHAR("f/", 2, "/", 1, "⁄", 7)
-CHAR("**", 2, "*", 1, "∗", 7)
-BOTH("<=", 2, "<=", 2, "≤", 7)
-BOTH(">=", 2, ">=", 2, "≥", 7)
-CHAR("<<", 2, "<<", 2, "≪", 7)
-CHAR(">>", 2, ">>", 2, "≫", 7)
-CHAR("eq", 2, "=", 1, "=", 5)
-CHAR("!=", 2, "!=", 2, "≠", 7)
-CHAR("==", 2, "==", 2, "≡", 7)
-CHAR("ne", 2, "!==", 3, "≢", 7)
-CHAR("=~", 2, "=~", 2, "≅", 7)
-CHAR("-~", 2, "-~", 2, "≃", 7)
-CHAR("ap", 2, "~", 1, "∼", 7)
-CHAR("~~", 2, "~~", 2, "≈", 7)
-CHAR("~=", 2, "~=", 2, "≌", 7)
-CHAR("pt", 2, "oc", 2, "∝", 7)
-CHAR("es", 2, "{}", 2, "∅", 7)
-CHAR("mo", 2, "E", 1, "∈", 7)
-CHAR("nm", 2, "!E", 2, "∉", 7)
-CHAR("sb", 2, "(=", 2, "⊂", 7)
-CHAR("nb", 2, "(!=", 3, "⊄", 7)
-CHAR("sp", 2, "=)", 2, "⊃", 7)
-CHAR("nc", 2, "!=)", 3, "⊅", 7)
-CHAR("ib", 2, "(=", 2, "⊆", 7)
-CHAR("ip", 2, "=)", 2, "⊇", 7)
-CHAR("ca", 2, "(^)", 3, "∩", 7)
-CHAR("cu", 2, "U", 1, "∪", 7)
-CHAR("/_", 2, "/_", 2, "∠", 7)
-CHAR("pp", 2, "_|_", 3, "⊥", 7)
-CHAR("is", 2, "I", 1, "∫", 7)
-CHAR("integral", 8, "I", 1, "∫", 7)
-CHAR("sum", 3, "E", 1, "∑", 7)
-CHAR("product", 7, "TT", 2, "∏", 7)
-CHAR("coproduct", 9, "U", 1, "∐", 7)
-CHAR("gr", 2, "V", 1, "∇", 7)
-CHAR("sr", 2, "\\/", 2, "√", 7)
-CHAR("sqrt", 4, "\\/", 2, "√", 7)
-CHAR("lc", 2, "|~", 2, "⌈", 7)
-CHAR("rc", 2, "~|", 2, "⌉", 7)
-CHAR("lf", 2, "|_", 2, "⌊", 7)
-CHAR("rf", 2, "_|", 2, "⌋", 7)
-CHAR("if", 2, "oo", 2, "∞", 7)
-CHAR("Ah", 2, "N", 1, "ℵ", 7)
-CHAR("Im", 2, "I", 1, "ℑ", 7)
-CHAR("Re", 2, "R", 1, "ℜ", 7)
-CHAR("pd", 2, "a", 1, "∂", 7)
-CHAR("-h", 2, "/h", 2, "ℏ", 7)
-
-/* Ligatures. */
-CHAR("ff", 2, "ff", 2, "ff", 8)
-CHAR("fi", 2, "fi", 2, "fi", 8)
-CHAR("fl", 2, "fl", 2, "fl", 8)
-CHAR("Fi", 2, "ffi", 3, "ffi", 8)
-CHAR("Fl", 2, "ffl", 3, "ffl", 8)
-BOTH("AE", 2, "AE", 2, "Æ", 6)
-BOTH("ae", 2, "ae", 2, "æ", 6)
-CHAR("OE", 2, "OE", 2, "Œ", 6)
-CHAR("oe", 2, "oe", 2, "œ", 6)
-CHAR("ss", 2, "ss", 2, "ß", 6)
-CHAR("IJ", 2, "IJ", 2, "IJ", 6)
-CHAR("ij", 2, "ij", 2, "ij", 6)
-
-/* Special letters. */
-CHAR("-D", 2, "D", 1, "Ð", 6)
-CHAR("Sd", 2, "o", 1, "ð", 6)
-CHAR("TP", 2, "b", 1, "Þ", 6)
-CHAR("Tp", 2, "b", 1, "þ", 6)
-CHAR(".i", 2, "i", 1, "ı", 6)
-CHAR(".j", 2, "j", 1, "ȷ", 6)
-
-/* Currency. */
-CHAR("Do", 2, "$", 1, "$", 1)
-CHAR("ct", 2, "c", 1, "¢", 6)
-CHAR("Eu", 2, "EUR", 3, "€", 7)
-CHAR("eu", 2, "EUR", 3, "€", 7)
-CHAR("Ye", 2, "Y", 1, "¥", 6)
-CHAR("Po", 2, "L", 1, "£", 6)
-CHAR("Cs", 2, "x", 1, "¤", 6)
-CHAR("Fn", 2, "f", 1, "ƒ", 6)
-
-/* pod2man holdovers. */
-STRING("--", 2, "--", 2, "—", 7)
-STRING("PI", 2, "pi", 2, "π", 6)
-STRING("L\"", 2, "``", 2, "“", 7)
-STRING("R\"", 2, "\'\'", 2, "”", 7)
-STRING("C+", 2, "C++", 3, "C++", 3)
-STRING("C`", 2, "`", 1, "‘", 7)
-STRING("C\'", 2, "\'", 1, "’", 7)
-STRING("Aq", 2, "\'", 1, "\'", 1)
-STRING("^", 1, "^", 1, "^", 1)
-STRING(",", 1, ",", 1, ",", 1)
-STRING("~", 1, "~", 1, "~", 1)
-STRING("/", 1, "/", 1, "/", 1)
-STRING(":", 1, "\"", 1, "̈", 6)
-STRING("8", 1, "B", 1, "β", 6)
-STRING("o", 1, "o", 1, "°", 6)
-STRING("D-", 2, "D", 1, "Ð", 6)
-STRING("d-", 2, "o", 1, "ð", 6)
-STRING("TH", 2, "b", 1, "Þ", 6)
-STRING("th", 2, "b", 1, "þ", 6)
-
-/* Old style. */
-STRING("Am", 2, "&", 1, "&", 5)
-STRING("Ba", 2, "|", 1, "|", 1)
-STRING("Ge", 2, ">=", 2, "≥", 7)
-STRING("Gt", 2, ">", 1, ">", 4)
-STRING("If", 2, "infinity", 8, "infinity", 8)
-STRING("Le", 2, "<=", 2, "≤", 7)
-STRING("Lq", 2, "``", 2, "“", 7)
-STRING("Lt", 2, "<", 1, "<", 4)
-STRING("Na", 2, "NaN", 3, "NaN", 3)
-STRING("Ne", 2, "!=", 2, "≠", 7)
-STRING("Pi", 2, "pi", 2, "π", 6)
-STRING("Pm", 2, "+-", 2, "±", 6)
-STRING("R", 1, "(R)", 3, "®", 6)
-STRING("Rq", 2, "\'\'", 2, "”", 7)
-STRING("Tm", 2, "tm", 2, "™", 7)
-STRING("left-bracket", 12, "[", 1, "[", 1)
-STRING("left-parenthesis", 16, "(", 1, "(", 1)
-STRING("left-singlequote", 16, "`", 1, "‘", 7)
-STRING("lp", 2, "(", 1, "(", 1)
-STRING("q", 1, "\"", 1, """, 6)
-STRING("quote-left", 10, "`", 1, "‘", 7)
-STRING("quote-right", 11, "\'", 1, "’", 7)
-STRING("right-bracket", 13, "]", 1, "]", 1)
-STRING("right-parenthesis", 17, ")", 1, ")", 1)
-STRING("right-singlequote", 17, "\'", 1, "’", 7)
-STRING("rp", 2, ")", 1, ")", 1)
-
-/* Lines. */
-CHAR("ba", 2, "|", 1, "|", 6)
-CHAR("br", 2, "|", 1, "│", 7)
-CHAR("ul", 2, "_", 1, "_", 5)
-CHAR("rl", 2, "-", 1, "‾", 7)
-CHAR("bb", 2, "|", 1, "¦", 6)
-CHAR("sl", 2, "/", 1, "/", 5)
-CHAR("rs", 2, "\\", 1, "\", 5)
-
-/* Text markers. */
-CHAR("ci", 2, "o", 1, "○", 7)
-CHAR("bu", 2, "o", 1, "•", 7)
-CHAR("dd", 2, "=", 1, "‡", 7)
-CHAR("dg", 2, "-", 1, "†", 7)
-CHAR("lz", 2, "<>", 2, "◊", 7)
-CHAR("sq", 2, "[]", 2, "□", 7)
-CHAR("ps", 2, "9|", 2, "¶", 6)
-CHAR("sc", 2, "S", 1, "§", 6)
-CHAR("lh", 2, "<=", 2, "☜", 7)
-CHAR("rh", 2, "=>", 2, "☞", 7)
-CHAR("at", 2, "@", 1, "@", 5)
-CHAR("sh", 2, "#", 1, "#", 5)
-CHAR("CR", 2, "_|", 2, "↵", 7)
-CHAR("OK", 2, "\\/", 2, "✓", 8)
-
-/* Legal symbols. */
-CHAR("co", 2, "(C)", 3, "©", 6)
-CHAR("rg", 2, "(R)", 3, "®", 6)
-CHAR("tm", 2, "tm", 2, "™", 7)
-
-/* Punctuation. */
-CHAR(".", 1, ".", 1, ".", 1)
-CHAR("r!", 2, "i", 1, "¡", 6)
-CHAR("r?", 2, "c", 1, "¿", 6)
-CHAR("em", 2, "--", 2, "—", 7)
-CHAR("en", 2, "-", 1, "–", 7)
-CHAR("hy", 2, "-", 1, "‐", 7)
-CHAR("e", 1, "\\", 1, "\\", 1)
-
-/* Units. */
-CHAR("de", 2, "o", 1, "°", 6)
-CHAR("%0", 2, "%o", 2, "‰", 7)
-CHAR("fm", 2, "\'", 1, "′", 7)
-CHAR("sd", 2, "\"", 1, "″", 7)
-CHAR("mc", 2, "mu", 2, "µ", 6)
-
-CHAR_TBL_END
+++ /dev/null
-/* $Id: html.c,v 1.96 2010/02/17 19:48:33 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "out.h"
-#include "chars.h"
-#include "html.h"
-#include "main.h"
-
-#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
-
-struct htmldata {
- const char *name;
- int flags;
-#define HTML_CLRLINE (1 << 0)
-#define HTML_NOSTACK (1 << 1)
-#define HTML_AUTOCLOSE (1 << 2) /* Tag has auto-closure. */
-};
-
-static const struct htmldata htmltags[TAG_MAX] = {
- {"html", HTML_CLRLINE}, /* TAG_HTML */
- {"head", HTML_CLRLINE}, /* TAG_HEAD */
- {"body", HTML_CLRLINE}, /* TAG_BODY */
- {"meta", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_META */
- {"title", HTML_CLRLINE}, /* TAG_TITLE */
- {"div", HTML_CLRLINE}, /* TAG_DIV */
- {"h1", 0}, /* TAG_H1 */
- {"h2", 0}, /* TAG_H2 */
- {"span", 0}, /* TAG_SPAN */
- {"link", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
- {"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */
- {"a", 0}, /* TAG_A */
- {"table", HTML_CLRLINE}, /* TAG_TABLE */
- {"col", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_COL */
- {"tr", HTML_CLRLINE}, /* TAG_TR */
- {"td", HTML_CLRLINE}, /* TAG_TD */
- {"li", HTML_CLRLINE}, /* TAG_LI */
- {"ul", HTML_CLRLINE}, /* TAG_UL */
- {"ol", HTML_CLRLINE}, /* TAG_OL */
-};
-
-static const char *const htmlfonts[HTMLFONT_MAX] = {
- "roman",
- "bold",
- "italic"
-};
-
-static const char *const htmlattrs[ATTR_MAX] = {
- "http-equiv",
- "content",
- "name",
- "rel",
- "href",
- "type",
- "media",
- "class",
- "style",
- "width",
- "valign",
- "target",
- "id",
- "summary",
-};
-
-static void print_spec(struct html *, const char *, size_t);
-static void print_res(struct html *, const char *, size_t);
-static void print_ctag(struct html *, enum htmltag);
-static void print_doctype(struct html *);
-static void print_xmltype(struct html *);
-static int print_encode(struct html *, const char *, int);
-static void print_metaf(struct html *, enum roffdeco);
-static void print_attr(struct html *,
- const char *, const char *);
-static void *ml_alloc(char *, enum htmltype);
-
-
-static void *
-ml_alloc(char *outopts, enum htmltype type)
-{
- struct html *h;
- const char *toks[4];
- char *v;
-
- toks[0] = "style";
- toks[1] = "man";
- toks[2] = "includes";
- toks[3] = NULL;
-
- h = calloc(1, sizeof(struct html));
- if (NULL == h) {
- perror(NULL);
- exit(EXIT_FAILURE);
- }
-
- h->type = type;
- h->tags.head = NULL;
- h->ords.head = NULL;
- h->symtab = chars_init(CHARS_HTML);
-
- while (outopts && *outopts)
- switch (getsubopt(&outopts, UNCONST(toks), &v)) {
- case (0):
- h->style = v;
- break;
- case (1):
- h->base_man = v;
- break;
- case (2):
- h->base_includes = v;
- break;
- default:
- break;
- }
-
- return(h);
-}
-
-void *
-html_alloc(char *outopts)
-{
-
- return(ml_alloc(outopts, HTML_HTML_4_01_STRICT));
-}
-
-
-void *
-xhtml_alloc(char *outopts)
-{
-
- return(ml_alloc(outopts, HTML_XHTML_1_0_STRICT));
-}
-
-
-void
-html_free(void *p)
-{
- struct tag *tag;
- struct ord *ord;
- struct html *h;
-
- h = (struct html *)p;
-
- while ((ord = h->ords.head) != NULL) {
- h->ords.head = ord->next;
- free(ord);
- }
-
- while ((tag = h->tags.head) != NULL) {
- h->tags.head = tag->next;
- free(tag);
- }
-
- if (h->symtab)
- chars_free(h->symtab);
-
- free(h);
-}
-
-
-void
-print_gen_head(struct html *h)
-{
- struct htmlpair tag[4];
-
- tag[0].key = ATTR_HTTPEQUIV;
- tag[0].val = "Content-Type";
- tag[1].key = ATTR_CONTENT;
- tag[1].val = "text/html; charset=utf-8";
- print_otag(h, TAG_META, 2, tag);
-
- tag[0].key = ATTR_NAME;
- tag[0].val = "resource-type";
- tag[1].key = ATTR_CONTENT;
- tag[1].val = "document";
- print_otag(h, TAG_META, 2, tag);
-
- if (h->style) {
- tag[0].key = ATTR_REL;
- tag[0].val = "stylesheet";
- tag[1].key = ATTR_HREF;
- tag[1].val = h->style;
- tag[2].key = ATTR_TYPE;
- tag[2].val = "text/css";
- tag[3].key = ATTR_MEDIA;
- tag[3].val = "all";
- print_otag(h, TAG_LINK, 4, tag);
- }
-}
-
-
-static void
-print_spec(struct html *h, const char *p, size_t len)
-{
- const char *rhs;
- size_t sz;
-
- rhs = chars_a2ascii(h->symtab, p, len, &sz);
-
- if (NULL == rhs)
- return;
- fwrite(rhs, 1, sz, stdout);
-}
-
-
-static void
-print_res(struct html *h, const char *p, size_t len)
-{
- const char *rhs;
- size_t sz;
-
- rhs = chars_a2res(h->symtab, p, len, &sz);
-
- if (NULL == rhs)
- return;
- fwrite(rhs, 1, sz, stdout);
-}
-
-
-struct tag *
-print_ofont(struct html *h, enum htmlfont font)
-{
- struct htmlpair tag;
-
- h->metal = h->metac;
- h->metac = font;
-
- /* FIXME: DECO_ROMAN should just close out preexisting. */
-
- if (h->metaf && h->tags.head == h->metaf)
- print_tagq(h, h->metaf);
-
- PAIR_CLASS_INIT(&tag, htmlfonts[font]);
- h->metaf = print_otag(h, TAG_SPAN, 1, &tag);
- return(h->metaf);
-}
-
-
-static void
-print_metaf(struct html *h, enum roffdeco deco)
-{
- enum htmlfont font;
-
- switch (deco) {
- case (DECO_PREVIOUS):
- font = h->metal;
- break;
- case (DECO_ITALIC):
- font = HTMLFONT_ITALIC;
- break;
- case (DECO_BOLD):
- font = HTMLFONT_BOLD;
- break;
- case (DECO_ROMAN):
- font = HTMLFONT_NONE;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- (void)print_ofont(h, font);
-}
-
-
-static int
-print_encode(struct html *h, const char *p, int norecurse)
-{
- size_t sz;
- int len, nospace;
- const char *seq;
- enum roffdeco deco;
-
- nospace = 0;
-
- for (; *p; p++) {
- sz = strcspn(p, "\\<>&");
-
- fwrite(p, 1, sz, stdout);
- p += /* LINTED */
- sz;
-
- if ('<' == *p) {
- printf("<");
- continue;
- } else if ('>' == *p) {
- printf(">");
- continue;
- } else if ('&' == *p) {
- printf("&");
- continue;
- } else if ('\0' == *p)
- break;
-
- seq = ++p;
- len = a2roffdeco(&deco, &seq, &sz);
-
- switch (deco) {
- case (DECO_RESERVED):
- print_res(h, seq, sz);
- break;
- case (DECO_SPECIAL):
- print_spec(h, seq, sz);
- break;
- case (DECO_PREVIOUS):
- /* FALLTHROUGH */
- case (DECO_BOLD):
- /* FALLTHROUGH */
- case (DECO_ITALIC):
- /* FALLTHROUGH */
- case (DECO_ROMAN):
- if (norecurse)
- break;
- print_metaf(h, deco);
- break;
- default:
- break;
- }
-
- p += len - 1;
-
- if (DECO_NOSPACE == deco && '\0' == *(p + 1))
- nospace = 1;
- }
-
- return(nospace);
-}
-
-
-static void
-print_attr(struct html *h, const char *key, const char *val)
-{
- printf(" %s=\"", key);
- (void)print_encode(h, val, 1);
- putchar('\"');
-}
-
-
-struct tag *
-print_otag(struct html *h, enum htmltag tag,
- int sz, const struct htmlpair *p)
-{
- int i;
- struct tag *t;
-
- /* Push this tags onto the stack of open scopes. */
-
- if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
- t = malloc(sizeof(struct tag));
- if (NULL == t) {
- perror(NULL);
- exit(EXIT_FAILURE);
- }
- t->tag = tag;
- t->next = h->tags.head;
- h->tags.head = t;
- } else
- t = NULL;
-
- if ( ! (HTML_NOSPACE & h->flags))
- if ( ! (HTML_CLRLINE & htmltags[tag].flags))
- putchar(' ');
-
- /* Print out the tag name and attributes. */
-
- printf("<%s", htmltags[tag].name);
- for (i = 0; i < sz; i++)
- print_attr(h, htmlattrs[p[i].key], p[i].val);
-
- /* Add non-overridable attributes. */
-
- if (TAG_HTML == tag && HTML_XHTML_1_0_STRICT == h->type) {
- print_attr(h, "xmlns", "http://www.w3.org/1999/xhtml");
- print_attr(h, "xml:lang", "en");
- print_attr(h, "lang", "en");
- }
-
- /* Accomodate for XML "well-formed" singleton escaping. */
-
- if (HTML_AUTOCLOSE & htmltags[tag].flags)
- switch (h->type) {
- case (HTML_XHTML_1_0_STRICT):
- putchar('/');
- break;
- default:
- break;
- }
-
- putchar('>');
-
- h->flags |= HTML_NOSPACE;
- return(t);
-}
-
-
-static void
-print_ctag(struct html *h, enum htmltag tag)
-{
-
- printf("</%s>", htmltags[tag].name);
- if (HTML_CLRLINE & htmltags[tag].flags) {
- h->flags |= HTML_NOSPACE;
- putchar('\n');
- }
-}
-
-
-void
-print_gen_decls(struct html *h)
-{
-
- print_xmltype(h);
- print_doctype(h);
-}
-
-
-static void
-print_xmltype(struct html *h)
-{
- const char *decl;
-
- switch (h->type) {
- case (HTML_XHTML_1_0_STRICT):
- decl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
- break;
- default:
- decl = NULL;
- break;
- }
-
- if (NULL == decl)
- return;
-
- printf("%s\n", decl);
-}
-
-
-static void
-print_doctype(struct html *h)
-{
- const char *doctype;
- const char *dtd;
- const char *name;
-
- switch (h->type) {
- case (HTML_HTML_4_01_STRICT):
- name = "HTML";
- doctype = "-//W3C//DTD HTML 4.01//EN";
- dtd = "http://www.w3.org/TR/html4/strict.dtd";
- break;
- default:
- name = "html";
- doctype = "-//W3C//DTD XHTML 1.0 Strict//EN";
- dtd = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
- break;
- }
-
- printf("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">\n",
- name, doctype, dtd);
-}
-
-
-void
-print_text(struct html *h, const char *p)
-{
-
- if (*p && 0 == *(p + 1))
- switch (*p) {
- case('.'):
- /* FALLTHROUGH */
- case(','):
- /* FALLTHROUGH */
- case(';'):
- /* FALLTHROUGH */
- case(':'):
- /* FALLTHROUGH */
- case('?'):
- /* FALLTHROUGH */
- case('!'):
- /* FALLTHROUGH */
- case(')'):
- /* FALLTHROUGH */
- case(']'):
- /* FALLTHROUGH */
- case('}'):
- if ( ! (HTML_IGNDELIM & h->flags))
- h->flags |= HTML_NOSPACE;
- break;
- default:
- break;
- }
-
- if ( ! (h->flags & HTML_NOSPACE))
- putchar(' ');
-
- assert(p);
- if ( ! print_encode(h, p, 0))
- h->flags &= ~HTML_NOSPACE;
-
- if (*p && 0 == *(p + 1))
- switch (*p) {
- case('('):
- /* FALLTHROUGH */
- case('['):
- /* FALLTHROUGH */
- case('{'):
- h->flags |= HTML_NOSPACE;
- break;
- default:
- break;
- }
-}
-
-
-void
-print_tagq(struct html *h, const struct tag *until)
-{
- struct tag *tag;
-
- while ((tag = h->tags.head) != NULL) {
- if (tag == h->metaf)
- h->metaf = NULL;
- print_ctag(h, tag->tag);
- h->tags.head = tag->next;
- free(tag);
- if (until && tag == until)
- return;
- }
-}
-
-
-void
-print_stagq(struct html *h, const struct tag *suntil)
-{
- struct tag *tag;
-
- while ((tag = h->tags.head) != NULL) {
- if (suntil && tag == suntil)
- return;
- if (tag == h->metaf)
- h->metaf = NULL;
- print_ctag(h, tag->tag);
- h->tags.head = tag->next;
- free(tag);
- }
-}
-
-
-void
-bufinit(struct html *h)
-{
-
- h->buf[0] = '\0';
- h->buflen = 0;
-}
-
-
-void
-bufcat_style(struct html *h, const char *key, const char *val)
-{
-
- bufcat(h, key);
- bufncat(h, ":", 1);
- bufcat(h, val);
- bufncat(h, ";", 1);
-}
-
-
-void
-bufcat(struct html *h, const char *p)
-{
-
- bufncat(h, p, strlen(p));
-}
-
-
-void
-buffmt(struct html *h, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- (void)vsnprintf(h->buf + (int)h->buflen,
- BUFSIZ - h->buflen - 1, fmt, ap);
- va_end(ap);
- h->buflen = strlen(h->buf);
-}
-
-
-void
-bufncat(struct html *h, const char *p, size_t sz)
-{
-
- if (h->buflen + sz > BUFSIZ - 1)
- sz = BUFSIZ - 1 - h->buflen;
-
- (void)strncat(h->buf, p, sz);
- h->buflen += sz;
-}
-
-
-void
-buffmt_includes(struct html *h, const char *name)
-{
- const char *p, *pp;
-
- pp = h->base_includes;
-
- while (NULL != (p = strchr(pp, '%'))) {
- bufncat(h, pp, (size_t)(p - pp));
- switch (*(p + 1)) {
- case('I'):
- bufcat(h, name);
- break;
- default:
- bufncat(h, p, 2);
- break;
- }
- pp = p + 2;
- }
- if (pp)
- bufcat(h, pp);
-}
-
-
-void
-buffmt_man(struct html *h,
- const char *name, const char *sec)
-{
- const char *p, *pp;
-
- pp = h->base_man;
-
- /* LINTED */
- while (NULL != (p = strchr(pp, '%'))) {
- bufncat(h, pp, (size_t)(p - pp));
- switch (*(p + 1)) {
- case('S'):
- bufcat(h, sec ? sec : "1");
- break;
- case('N'):
- buffmt(h, name);
- break;
- default:
- bufncat(h, p, 2);
- break;
- }
- pp = p + 2;
- }
- if (pp)
- bufcat(h, pp);
-}
-
-
-void
-bufcat_su(struct html *h, const char *p, const struct roffsu *su)
-{
- double v;
- const char *u;
-
- v = su->scale;
-
- switch (su->unit) {
- case (SCALE_CM):
- u = "cm";
- break;
- case (SCALE_IN):
- u = "in";
- break;
- case (SCALE_PC):
- u = "pc";
- break;
- case (SCALE_PT):
- u = "pt";
- break;
- case (SCALE_EM):
- u = "em";
- break;
- case (SCALE_MM):
- if (0 == (v /= 100))
- v = 1;
- u = "em";
- break;
- case (SCALE_EN):
- u = "ex";
- break;
- case (SCALE_BU):
- u = "ex";
- break;
- case (SCALE_VS):
- u = "em";
- break;
- default:
- u = "ex";
- break;
- }
-
- if (su->pt)
- buffmt(h, "%s: %f%s;", p, v, u);
- else
- /* LINTED */
- buffmt(h, "%s: %d%s;", p, (int)v, u);
-}
-
-
-void
-html_idcat(char *dst, const char *src, int sz)
-{
- int ssz;
-
- assert(sz);
-
- /* Cf. <http://www.w3.org/TR/html4/types.html#h-6.2>. */
-
- for ( ; *dst != '\0' && sz; dst++, sz--)
- /* Jump to end. */ ;
-
- assert(sz > 2);
-
- /* We can't start with a number (bah). */
-
- *dst++ = 'x';
- *dst = '\0';
- sz--;
-
- for ( ; *src != '\0' && sz > 1; src++) {
- ssz = snprintf(dst, (size_t)sz, "%.2x", *src);
- sz -= ssz;
- dst += ssz;
- }
-}
+++ /dev/null
-/* $Id: html.h,v 1.22 2010/01/29 14:39:38 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef HTML_H
-#define HTML_H
-
-__BEGIN_DECLS
-
-enum htmltag {
- TAG_HTML,
- TAG_HEAD,
- TAG_BODY,
- TAG_META,
- TAG_TITLE,
- TAG_DIV,
- TAG_H1,
- TAG_H2,
- TAG_SPAN,
- TAG_LINK,
- TAG_BR,
- TAG_A,
- TAG_TABLE,
- TAG_COL,
- TAG_TR,
- TAG_TD,
- TAG_LI,
- TAG_UL,
- TAG_OL,
- TAG_MAX
-};
-
-enum htmlattr {
- ATTR_HTTPEQUIV,
- ATTR_CONTENT,
- ATTR_NAME,
- ATTR_REL,
- ATTR_HREF,
- ATTR_TYPE,
- ATTR_MEDIA,
- ATTR_CLASS,
- ATTR_STYLE,
- ATTR_WIDTH,
- ATTR_VALIGN,
- ATTR_TARGET,
- ATTR_ID,
- ATTR_SUMMARY,
- ATTR_MAX
-};
-
-enum htmlfont {
- HTMLFONT_NONE = 0,
- HTMLFONT_BOLD,
- HTMLFONT_ITALIC,
- HTMLFONT_MAX
-};
-
-struct tag {
- struct tag *next;
- enum htmltag tag;
-};
-
-struct ord {
- struct ord *next;
- const void *cookie;
- int pos;
-};
-
-struct tagq {
- struct tag *head;
-};
-struct ordq {
- struct ord *head;
-};
-
-struct htmlpair {
- enum htmlattr key;
- const char *val;
-};
-
-#define PAIR_CLASS_INIT(p, v) \
- do { (p)->key = ATTR_CLASS; \
- (p)->val = (v); } while (/* CONSTCOND */ 0)
-#define PAIR_HREF_INIT(p, v) \
- do { (p)->key = ATTR_HREF; \
- (p)->val = (v); } while (/* CONSTCOND */ 0)
-#define PAIR_STYLE_INIT(p, h) \
- do { (p)->key = ATTR_STYLE; \
- (p)->val = (h)->buf; } while (/* CONSTCOND */ 0)
-#define PAIR_SUMMARY_INIT(p, v) \
- do { (p)->key = ATTR_SUMMARY; \
- (p)->val = (v); } while (/* CONSTCOND */ 0)
-
-enum htmltype {
- HTML_HTML_4_01_STRICT,
- HTML_XHTML_1_0_STRICT
-};
-
-struct html {
- int flags;
-#define HTML_NOSPACE (1 << 0)
-#define HTML_IGNDELIM (1 << 2)
- struct tagq tags;
- struct ordq ords;
- void *symtab;
- char *base;
- char *base_man;
- char *base_includes;
- char *style;
- char buf[BUFSIZ];
- size_t buflen;
- struct tag *metaf;
- enum htmlfont metal;
- enum htmlfont metac;
- enum htmltype type;
-};
-
-struct roffsu;
-
-void print_gen_decls(struct html *);
-void print_gen_head(struct html *);
-struct tag *print_ofont(struct html *, enum htmlfont);
-struct tag *print_otag(struct html *, enum htmltag,
- int, const struct htmlpair *);
-void print_tagq(struct html *, const struct tag *);
-void print_stagq(struct html *, const struct tag *);
-void print_text(struct html *, const char *);
-
-void bufcat_su(struct html *, const char *,
- const struct roffsu *);
-void buffmt_man(struct html *,
- const char *, const char *);
-void buffmt_includes(struct html *, const char *);
-void buffmt(struct html *, const char *, ...);
-void bufcat(struct html *, const char *);
-void bufcat_style(struct html *,
- const char *, const char *);
-void bufncat(struct html *, const char *, size_t);
-void bufinit(struct html *);
-
-void html_idcat(char *, const char *, int);
-
-__END_DECLS
-
-#endif /*!HTML_H*/
+++ /dev/null
-/* $Id: lib.c,v 1.6 2010/01/01 17:14:27 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "libmdoc.h"
-
-#define LINE(x, y) \
- if (0 == strcmp(p, x)) return(y);
-
-const char *
-mdoc_a2lib(const char *p)
-{
-
-#include "lib.in"
-
- return(NULL);
-}
+++ /dev/null
-/* $Id: lib.in,v 1.6 2009/11/01 07:34:22 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * These are all possible .Lb strings. When a new library is added, add
- * its short-string to the left-hand side and formatted string to the
- * right-hand side.
- *
- * Be sure to escape strings.
- */
-
-LINE("libarchive", "Reading and Writing Streaming Archives Library (libarchive, \\-larchive)")
-LINE("libarm", "ARM Architecture Library (libarm, \\-larm)")
-LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)")
-LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)")
-LINE("libc", "Standard C Library (libc, \\-lc)")
-LINE("libcdk", "Curses Development Kit Library (libcdk, \\-lcdk)")
-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("libedit", "Command Line Editor Library (libedit, \\-ledit)")
-LINE("libevent", "Event Notification Library (libevent, \\-levent)")
-LINE("libfetch", "File Transfer Library for URLs (libfetch, \\-lfetch)")
-LINE("libform", "Curses Form Library (libform, \\-lform)")
-LINE("libi386", "i386 Architecture Library (libi386, \\-li386)")
-LINE("libintl", "Internationalized Message Handling Library (libintl, \\-lintl)")
-LINE("libipsec", "IPsec Policy Control Library (libipsec, \\-lipsec)")
-LINE("libiscsi", "iSCSI protocol library (libiscsi, \\-liscsi)")
-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("libmenu", "Curses Menu Library (libmenu, \\-lmenu)")
-LINE("libnetpgp", "Netpgp signing, verification, encryption and decryption (libnetpgp, \\-lnetpgp)")
-LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
-LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
-LINE("libpcap", "Capture Library (libpcap, \\-lpcap)")
-LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)")
-LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)")
-LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)")
-LINE("libprop", "Property Container Object Library (libprop, \\-lprop)")
-LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
-LINE("libpuffs", "puffs Convenience Library (libpuffs, \\-lpuffs)")
-LINE("librefuse", "File System in Userspace Convenience Library (librefuse, \\-lrefuse)")
-LINE("libresolv", "DNS Resolver Library (libresolv, \\-lresolv)")
-LINE("librt", "POSIX Real\\-time Library (librt, -lrt)")
-LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)")
-LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)")
-LINE("libusbhid", "USB Human Interface Devices Library (libusbhid, \\-lusbhid)")
-LINE("libutil", "System Utilities Library (libutil, \\-lutil)")
-LINE("libx86_64", "x86_64 Architecture Library (libx86_64, \\-lx86_64)")
-LINE("libz", "Compression Library (libz, \\-lz)")
+++ /dev/null
-/* $Id: libman.h,v 1.30 2010/03/29 10:10:35 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef LIBMAN_H
-#define LIBMAN_H
-
-#include "man.h"
-
-enum man_next {
- MAN_NEXT_SIBLING = 0,
- MAN_NEXT_CHILD
-};
-
-struct man {
- void *data;
- struct man_cb cb;
- int pflags; /* parse flags (see man.h) */
- int svflags; /* flags saved during roff blocks */
- int flags; /* parse flags */
-#define MAN_HALT (1 << 0) /* badness happened: die */
-#define MAN_ELINE (1 << 1) /* Next-line element scope. */
-#define MAN_BLINE (1 << 2) /* Next-line block scope. */
-#define MAN_ILINE (1 << 3) /* Ignored in next-line scope. */
-#define MAN_LITERAL (1 << 4) /* Literal input. */
-#define MAN_BPLINE (1 << 5)
- enum man_next next;
- enum man_next svnext;
- struct man_node *last;
- struct man_node *first;
- struct man_meta meta;
-};
-
-enum merr {
- WNPRINT = 0,
- WMSEC,
- WDATE,
- WLNSCOPE,
- WLNSCOPE2,
- WTSPACE,
- WTQUOTE,
- WNODATA,
- WNOTITLE,
- WESCAPE,
- WNUMFMT,
- WHEADARGS,
- WBODYARGS,
- WNHEADARGS,
- WMACROFORM,
- WEXITSCOPE,
- WNOSCOPE,
- WOLITERAL,
- WNLITERAL,
- WROFFNEST,
- WROFFSCOPE,
- WTITLECASE,
- WERRMAX
-};
-
-#define MACRO_PROT_ARGS struct man *m, enum mant tok, int line, \
- int ppos, int *pos, char *buf
-
-struct man_macro {
- int (*fp)(MACRO_PROT_ARGS);
- int flags;
-#define MAN_SCOPED (1 << 0)
-#define MAN_EXPLICIT (1 << 1) /* See blk_imp(). */
-#define MAN_FSCOPED (1 << 2) /* See blk_imp(). */
-#define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */
-#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */
-};
-
-extern const struct man_macro *const man_macros;
-
-__BEGIN_DECLS
-
-#define man_perr(m, l, p, t) \
- man_err((m), (l), (p), 1, (t))
-#define man_pwarn(m, l, p, t) \
- man_err((m), (l), (p), 0, (t))
-#define man_nerr(m, n, t) \
- man_err((m), (n)->line, (n)->pos, 1, (t))
-#define man_nwarn(m, n, t) \
- man_err((m), (n)->line, (n)->pos, 0, (t))
-
-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);
-int man_body_alloc(struct man *, int, int, enum mant);
-int man_elem_alloc(struct man *, int, int, enum mant);
-void man_node_delete(struct man *, struct man_node *);
-void man_hash_init(void);
-enum mant man_hash_find(const char *);
-int man_macroend(struct man *);
-int man_args(struct man *, int, int *, char *, char **);
-#define ARGS_ERROR (-1)
-#define ARGS_EOLN (0)
-#define ARGS_WORD (1)
-#define ARGS_QWORD (1)
-int man_err(struct man *, int, int, int, enum merr);
-int man_vwarn(struct man *, int, int, const char *, ...);
-int man_verr(struct man *, int, int, const char *, ...);
-int man_valid_post(struct man *);
-int man_valid_pre(struct man *, const struct man_node *);
-int man_action_post(struct man *);
-int man_action_pre(struct man *, struct man_node *);
-int man_unscope(struct man *,
- const struct man_node *, enum merr);
-
-__END_DECLS
-
-#endif /*!LIBMAN_H*/
+++ /dev/null
-/* $Id: libmandoc.h,v 1.4 2009/11/02 06:22:45 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef LIBMANDOC_H
-#define LIBMANDOC_H
-
-__BEGIN_DECLS
-
-int mandoc_special(const char *);
-void *mandoc_calloc(size_t, size_t);
-char *mandoc_strdup(const char *);
-void *mandoc_malloc(size_t);
-void *mandoc_realloc(void *, size_t);
-time_t mandoc_a2time(int, const char *);
-#define MTIME_CANONICAL (1 << 0)
-#define MTIME_REDUCED (1 << 1)
-#define MTIME_MDOCDATE (1 << 2)
-#define MTIME_ISO_8601 (1 << 3)
-
-__END_DECLS
-
-#endif /*!LIBMANDOC_H*/
+++ /dev/null
-/* $Id: libmdoc.h,v 1.30 2009/10/30 05:58:37 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef LIBMDOC_H
-#define LIBMDOC_H
-
-#include "mdoc.h"
-
-enum mdoc_next {
- MDOC_NEXT_SIBLING = 0,
- MDOC_NEXT_CHILD
-};
-
-struct mdoc {
- void *data;
- struct mdoc_cb cb;
- int flags;
-#define MDOC_HALT (1 << 0) /* Error in parse. Halt. */
-#define MDOC_LITERAL (1 << 1) /* In a literal scope. */
-#define MDOC_PBODY (1 << 2) /* In the document body. */
- int pflags;
- enum mdoc_next next;
- struct mdoc_node *last;
- struct mdoc_node *first;
- struct mdoc_meta meta;
- enum mdoc_sec lastnamed;
- enum mdoc_sec lastsec;
-};
-
-enum merr {
- ETAILWS = 0,
- EQUOTPARM,
- EQUOTTERM,
- EARGVAL,
- EBODYPROL,
- EPROLBODY,
- ETEXTPROL,
- ENOBLANK,
- ETOOLONG,
- EESCAPE,
- EPRINT,
- ENODAT,
- ENOPROLOGUE,
- ELINE,
- EATT,
- ENAME,
- ELISTTYPE,
- EDISPTYPE,
- EMULTIDISP,
- EMULTILIST,
- ESECNAME,
- ENAMESECINC,
- EARGREP,
- EBOOL,
- ECOLMIS,
- ENESTDISP,
- EMISSWIDTH,
- EWRONGMSEC,
- ESECOOO,
- ESECREP,
- EBADSTAND,
- ENOMULTILINE,
- EMULTILINE,
- ENOLINE,
- EPROLOOO,
- EPROLREP,
- EBADMSEC,
- EBADSEC,
- EFONT,
- EBADDATE,
- ENUMFMT,
- ENOWIDTH,
- EUTSNAME,
- EOBS,
- EIMPBRK,
- EIGNE,
- EOPEN,
- EQUOTPHR,
- ENOCTX,
- ELIB,
- EBADCHILD,
- ENOTYPE,
- MERRMAX
-};
-
-#define MACRO_PROT_ARGS struct mdoc *m, int tok, int line, \
- int ppos, int *pos, char *buf
-
-struct mdoc_macro {
- int (*fp)(MACRO_PROT_ARGS);
- int flags;
-#define MDOC_CALLABLE (1 << 0)
-#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. */
-};
-
-extern const struct mdoc_macro *const mdoc_macros;
-
-__BEGIN_DECLS
-
-#define mdoc_perr(m, l, p, t) \
- mdoc_err((m), (l), (p), 1, (t))
-#define mdoc_pwarn(m, l, p, t) \
- mdoc_err((m), (l), (p), 0, (t))
-#define mdoc_nerr(m, n, t) \
- mdoc_err((m), (n)->line, (n)->pos, 1, (t))
-#define mdoc_nwarn(m, n, t) \
- mdoc_err((m), (n)->line, (n)->pos, 0, (t))
-
-int mdoc_err(struct mdoc *, int, int, int, enum merr);
-int mdoc_verr(struct mdoc *, int, int, const char *, ...);
-int mdoc_vwarn(struct mdoc *, int, int, const char *, ...);
-
-int mdoc_macro(MACRO_PROT_ARGS);
-int mdoc_word_alloc(struct mdoc *,
- int, int, const char *);
-int mdoc_elem_alloc(struct mdoc *, int, int,
- int, struct mdoc_arg *);
-int mdoc_block_alloc(struct mdoc *, int, int,
- int, struct mdoc_arg *);
-int mdoc_head_alloc(struct mdoc *, int, int, int);
-int mdoc_tail_alloc(struct mdoc *, int, int, int);
-int mdoc_body_alloc(struct mdoc *, int, int, int);
-void mdoc_node_free(struct mdoc_node *);
-void mdoc_node_freelist(struct mdoc_node *);
-void mdoc_hash_init(void);
-int mdoc_hash_find(const char *);
-int mdoc_iscdelim(char);
-int mdoc_isdelim(const char *);
-size_t mdoc_isescape(const char *);
-enum mdoc_sec mdoc_atosec(const char *);
-time_t mdoc_atotime(const char *);
-
-size_t mdoc_macro2len(int);
-const char *mdoc_a2att(const char *);
-const char *mdoc_a2lib(const char *);
-const char *mdoc_a2st(const char *);
-const char *mdoc_a2arch(const char *);
-const char *mdoc_a2vol(const char *);
-const char *mdoc_a2msec(const char *);
-int mdoc_valid_pre(struct mdoc *,
- const struct mdoc_node *);
-int mdoc_valid_post(struct mdoc *);
-int mdoc_action_pre(struct mdoc *,
- const struct mdoc_node *);
-int mdoc_action_post(struct mdoc *);
-int mdoc_argv(struct mdoc *, int, int,
- struct mdoc_arg **, int *, char *);
-#define ARGV_ERROR (-1)
-#define ARGV_EOLN (0)
-#define ARGV_ARG (1)
-#define ARGV_WORD (2)
-void mdoc_argv_free(struct mdoc_arg *);
-int mdoc_args(struct mdoc *, int,
- int *, char *, int, char **);
-int mdoc_zargs(struct mdoc *, int,
- int *, char *, int, char **);
-#define ARGS_DELIM (1 << 1) /* See args(). */
-#define ARGS_TABSEP (1 << 2) /* See args(). */
-#define ARGS_NOWARN (1 << 3) /* See args(). */
-#define ARGS_ERROR (-1)
-#define ARGS_EOLN (0)
-#define ARGS_WORD (1)
-#define ARGS_PUNCT (2)
-#define ARGS_QWORD (3)
-#define ARGS_PHRASE (4)
-int mdoc_macroend(struct mdoc *);
-
-__END_DECLS
-
-#endif /*!LIBMDOC_H*/
+++ /dev/null
-/* $Id: main.c,v 1.60 2010/03/22 20:43:00 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "mdoc.h"
-#include "man.h"
-#include "main.h"
-
-#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
-
-/* FIXME: Intel's compiler? LLVM? pcc? */
-
-#if !defined(__GNUC__) || (__GNUC__ < 2)
-# if !defined(lint)
-# define __attribute__(x)
-# endif
-#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
-
-typedef void (*out_mdoc)(void *, const struct mdoc *);
-typedef void (*out_man)(void *, const struct man *);
-typedef void (*out_free)(void *);
-
-struct buf {
- char *buf;
- size_t sz;
-};
-
-enum intt {
- INTT_AUTO,
- INTT_MDOC,
- INTT_MAN
-};
-
-enum outt {
- OUTT_ASCII = 0,
- OUTT_TREE,
- OUTT_HTML,
- OUTT_XHTML,
- OUTT_LINT
-};
-
-struct curparse {
- const char *file; /* Current parse. */
- int fd; /* Current parse. */
- int wflags;
-#define WARN_WALL (1 << 0) /* All-warnings mask. */
-#define WARN_WERR (1 << 2) /* Warnings->errors. */
- int fflags;
-#define FL_IGN_SCOPE (1 << 0) /* Ignore scope errors. */
-#define FL_NIGN_ESCAPE (1 << 1) /* Don't ignore bad escapes. */
-#define FL_NIGN_MACRO (1 << 2) /* Don't ignore bad macros. */
-#define FL_NIGN_CHARS (1 << 3) /* Don't ignore bad chars. */
-#define FL_IGN_ERRORS (1 << 4) /* Ignore failed parse. */
- enum intt inttype; /* Input parsers... */
- struct man *man;
- struct man *lastman;
- struct mdoc *mdoc;
- struct mdoc *lastmdoc;
- enum outt outtype; /* Output devices... */
- out_mdoc outmdoc;
- out_man outman;
- out_free outfree;
- void *outdata;
- char outopts[BUFSIZ];
-};
-
-#define FL_STRICT FL_NIGN_ESCAPE | \
- FL_NIGN_MACRO | \
- FL_NIGN_CHARS
-
-static int foptions(int *, char *);
-static int toptions(struct curparse *, char *);
-static int moptions(enum intt *, char *);
-static int woptions(int *, char *);
-static int merr(void *, int, int, const char *);
-static int mwarn(void *, int, int, const char *);
-static int ffile(struct buf *, struct buf *,
- const char *, struct curparse *);
-static int fdesc(struct buf *, struct buf *,
- struct curparse *);
-static int pset(const char *, int, struct curparse *,
- struct man **, struct mdoc **);
-static struct man *man_init(struct curparse *);
-static struct mdoc *mdoc_init(struct curparse *);
-static void version(void) __attribute__((noreturn));
-static void usage(void) __attribute__((noreturn));
-
-static const char *progname;
-
-
-int
-main(int argc, char *argv[])
-{
- int c, rc;
- struct buf ln, blk;
- struct curparse curp;
-
- progname = strrchr(argv[0], '/');
- if (progname == NULL)
- progname = argv[0];
- else
- ++progname;
-
- memset(&curp, 0, sizeof(struct curparse));
-
- curp.inttype = INTT_AUTO;
- curp.outtype = OUTT_ASCII;
-
- /* LINTED */
- while (-1 != (c = getopt(argc, argv, "f:m:O:T:VW:")))
- switch (c) {
- case ('f'):
- if ( ! foptions(&curp.fflags, optarg))
- return(EXIT_FAILURE);
- break;
- case ('m'):
- if ( ! moptions(&curp.inttype, optarg))
- return(EXIT_FAILURE);
- break;
- case ('O'):
- (void)strlcat(curp.outopts, optarg, BUFSIZ);
- (void)strlcat(curp.outopts, ",", BUFSIZ);
- break;
- case ('T'):
- if ( ! toptions(&curp, optarg))
- return(EXIT_FAILURE);
- break;
- case ('W'):
- if ( ! woptions(&curp.wflags, optarg))
- return(EXIT_FAILURE);
- break;
- case ('V'):
- version();
- /* NOTREACHED */
- default:
- usage();
- /* NOTREACHED */
- }
-
- argc -= optind;
- argv += optind;
-
- memset(&ln, 0, sizeof(struct buf));
- memset(&blk, 0, sizeof(struct buf));
-
- rc = 1;
-
- if (NULL == *argv) {
- curp.file = "<stdin>";
- curp.fd = STDIN_FILENO;
-
- c = fdesc(&blk, &ln, &curp);
- if ( ! (FL_IGN_ERRORS & curp.fflags))
- rc = 1 == c ? 1 : 0;
- else
- rc = -1 == c ? 0 : 1;
- }
-
- while (rc && *argv) {
- c = ffile(&blk, &ln, *argv, &curp);
- if ( ! (FL_IGN_ERRORS & curp.fflags))
- rc = 1 == c ? 1 : 0;
- else
- rc = -1 == c ? 0 : 1;
-
- argv++;
- if (*argv && rc) {
- if (curp.lastman)
- man_reset(curp.lastman);
- if (curp.lastmdoc)
- mdoc_reset(curp.lastmdoc);
- curp.lastman = NULL;
- curp.lastmdoc = NULL;
- }
- }
-
- if (blk.buf)
- free(blk.buf);
- if (ln.buf)
- free(ln.buf);
- if (curp.outfree)
- (*curp.outfree)(curp.outdata);
- if (curp.mdoc)
- mdoc_free(curp.mdoc);
- if (curp.man)
- man_free(curp.man);
-
- return(rc ? EXIT_SUCCESS : EXIT_FAILURE);
-}
-
-
-static void
-version(void)
-{
-
- (void)printf("%s %s\n", progname, VERSION);
- exit(EXIT_SUCCESS);
-}
-
-
-static void
-usage(void)
-{
-
- (void)fprintf(stderr, "usage: %s [-V] [-foption...] "
- "[-mformat] [-Ooption] [-Toutput] "
- "[-Werr...]\n", progname);
- exit(EXIT_FAILURE);
-}
-
-
-static struct man *
-man_init(struct curparse *curp)
-{
- int pflags;
- struct man_cb mancb;
-
- mancb.man_err = merr;
- mancb.man_warn = mwarn;
-
- /* Defaults from mandoc.1. */
-
- pflags = MAN_IGN_MACRO | MAN_IGN_ESCAPE | MAN_IGN_CHARS;
-
- if (curp->fflags & FL_NIGN_MACRO)
- pflags &= ~MAN_IGN_MACRO;
- if (curp->fflags & FL_NIGN_CHARS)
- pflags &= ~MAN_IGN_CHARS;
- if (curp->fflags & FL_NIGN_ESCAPE)
- pflags &= ~MAN_IGN_ESCAPE;
-
- return(man_alloc(curp, pflags, &mancb));
-}
-
-
-static struct mdoc *
-mdoc_init(struct curparse *curp)
-{
- int pflags;
- struct mdoc_cb mdoccb;
-
- mdoccb.mdoc_err = merr;
- mdoccb.mdoc_warn = mwarn;
-
- /* Defaults from mandoc.1. */
-
- pflags = MDOC_IGN_MACRO | MDOC_IGN_ESCAPE | MDOC_IGN_CHARS;
-
- if (curp->fflags & FL_IGN_SCOPE)
- pflags |= MDOC_IGN_SCOPE;
- if (curp->fflags & FL_NIGN_ESCAPE)
- pflags &= ~MDOC_IGN_ESCAPE;
- if (curp->fflags & FL_NIGN_MACRO)
- pflags &= ~MDOC_IGN_MACRO;
- if (curp->fflags & FL_NIGN_CHARS)
- pflags &= ~MDOC_IGN_CHARS;
-
- return(mdoc_alloc(curp, pflags, &mdoccb));
-}
-
-
-static int
-ffile(struct buf *blk, struct buf *ln,
- const char *file, struct curparse *curp)
-{
- int c;
-
- curp->file = file;
- if (-1 == (curp->fd = open(curp->file, O_RDONLY, 0))) {
- perror(curp->file);
- return(-1);
- }
-
- c = fdesc(blk, ln, curp);
-
- if (-1 == close(curp->fd))
- perror(curp->file);
-
- return(c);
-}
-
-
-static int
-fdesc(struct buf *blk, struct buf *ln, struct curparse *curp)
-{
- size_t sz;
- ssize_t ssz;
- struct stat st;
- int j, i, pos, lnn, comment;
- struct man *man;
- struct mdoc *mdoc;
-
- sz = BUFSIZ;
- man = NULL;
- mdoc = NULL;
-
- /*
- * Two buffers: ln and buf. buf is the input buffer optimised
- * here for each file's block size. ln is a line buffer. Both
- * growable, hence passed in by ptr-ptr.
- */
-
- if (-1 == fstat(curp->fd, &st))
- perror(curp->file);
- else if ((size_t)st.st_blksize > sz)
- sz = st.st_blksize;
-
- if (sz > blk->sz) {
- blk->buf = realloc(blk->buf, sz);
- if (NULL == blk->buf) {
- perror(NULL);
- exit(EXIT_FAILURE);
- }
- blk->sz = sz;
- }
-
- /* Fill buf with file blocksize. */
-
- for (lnn = pos = comment = 0; ; ) {
- if (-1 == (ssz = read(curp->fd, blk->buf, sz))) {
- perror(curp->file);
- return(-1);
- } else if (0 == ssz)
- break;
-
- /* Parse the read block into partial or full lines. */
-
- for (i = 0; i < (int)ssz; i++) {
- if (pos >= (int)ln->sz) {
- ln->sz += 256; /* Step-size. */
- ln->buf = realloc(ln->buf, ln->sz);
- if (NULL == ln->buf) {
- perror(NULL);
- return(EXIT_FAILURE);
- }
- }
-
- if ('\n' != blk->buf[i]) {
- if (comment)
- continue;
- ln->buf[pos++] = blk->buf[i];
-
- /* Handle in-line `\"' comments. */
-
- if (1 == pos || '\"' != ln->buf[pos - 1])
- continue;
-
- for (j = pos - 2; j >= 0; j--)
- if ('\\' != ln->buf[j])
- break;
-
- if ( ! ((pos - 2 - j) % 2))
- continue;
-
- comment = 1;
- pos -= 2;
- continue;
- }
-
- /* Handle escaped `\\n' newlines. */
-
- if (pos > 0 && 0 == comment &&
- '\\' == ln->buf[pos - 1]) {
- for (j = pos - 1; j >= 0; j--)
- if ('\\' != ln->buf[j])
- break;
- if ( ! ((pos - j) % 2)) {
- pos--;
- lnn++;
- continue;
- }
- }
-
- ln->buf[pos] = 0;
- lnn++;
-
- /* If unset, assign parser in pset(). */
-
- if ( ! (man || mdoc) && ! pset(ln->buf,
- pos, curp, &man, &mdoc))
- return(-1);
-
- pos = comment = 0;
-
- /* Pass down into parsers. */
-
- if (man && ! man_parseln(man, lnn, ln->buf))
- return(0);
- if (mdoc && ! mdoc_parseln(mdoc, lnn, ln->buf))
- return(0);
- }
- }
-
- /* NOTE a parser may not have been assigned, yet. */
-
- if ( ! (man || mdoc)) {
- fprintf(stderr, "%s: Not a manual\n", curp->file);
- return(0);
- }
-
- if (mdoc && ! mdoc_endparse(mdoc))
- return(0);
- if (man && ! man_endparse(man))
- return(0);
-
- /* If unset, allocate output dev now (if applicable). */
-
- if ( ! (curp->outman && curp->outmdoc)) {
- switch (curp->outtype) {
- case (OUTT_XHTML):
- curp->outdata = xhtml_alloc(curp->outopts);
- curp->outman = html_man;
- curp->outmdoc = html_mdoc;
- curp->outfree = html_free;
- break;
- case (OUTT_HTML):
- curp->outdata = html_alloc(curp->outopts);
- curp->outman = html_man;
- curp->outmdoc = html_mdoc;
- curp->outfree = html_free;
- break;
- case (OUTT_TREE):
- curp->outman = tree_man;
- curp->outmdoc = tree_mdoc;
- break;
- case (OUTT_LINT):
- break;
- default:
- curp->outdata = ascii_alloc();
- curp->outman = terminal_man;
- curp->outmdoc = terminal_mdoc;
- curp->outfree = terminal_free;
- break;
- }
- }
-
- /* Execute the out device, if it exists. */
-
- if (man && curp->outman)
- (*curp->outman)(curp->outdata, man);
- if (mdoc && curp->outmdoc)
- (*curp->outmdoc)(curp->outdata, mdoc);
-
- return(1);
-}
-
-
-static int
-pset(const char *buf, int pos, struct curparse *curp,
- struct man **man, struct mdoc **mdoc)
-{
- int i;
-
- /*
- * Try to intuit which kind of manual parser should be used. If
- * passed in by command-line (-man, -mdoc), then use that
- * explicitly. If passed as -mandoc, then try to guess from the
- * line: either skip dot-lines, use -mdoc when finding `.Dt', or
- * default to -man, which is more lenient.
- */
-
- if (buf[0] == '.') {
- for (i = 1; buf[i]; i++)
- if (' ' != buf[i] && '\t' != buf[i])
- break;
- if (0 == buf[i])
- return(1);
- }
-
- switch (curp->inttype) {
- case (INTT_MDOC):
- if (NULL == curp->mdoc)
- curp->mdoc = mdoc_init(curp);
- if (NULL == (*mdoc = curp->mdoc))
- return(0);
- curp->lastmdoc = *mdoc;
- return(1);
- case (INTT_MAN):
- if (NULL == curp->man)
- curp->man = man_init(curp);
- if (NULL == (*man = curp->man))
- return(0);
- curp->lastman = *man;
- return(1);
- default:
- break;
- }
-
- if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) {
- if (NULL == curp->mdoc)
- curp->mdoc = mdoc_init(curp);
- if (NULL == (*mdoc = curp->mdoc))
- return(0);
- curp->lastmdoc = *mdoc;
- return(1);
- }
-
- if (NULL == curp->man)
- curp->man = man_init(curp);
- if (NULL == (*man = curp->man))
- return(0);
- curp->lastman = *man;
- return(1);
-}
-
-
-static int
-moptions(enum intt *tflags, char *arg)
-{
-
- if (0 == strcmp(arg, "doc"))
- *tflags = INTT_MDOC;
- else if (0 == strcmp(arg, "andoc"))
- *tflags = INTT_AUTO;
- else if (0 == strcmp(arg, "an"))
- *tflags = INTT_MAN;
- else {
- fprintf(stderr, "%s: Bad argument\n", arg);
- return(0);
- }
-
- return(1);
-}
-
-
-static int
-toptions(struct curparse *curp, char *arg)
-{
-
- if (0 == strcmp(arg, "ascii"))
- curp->outtype = OUTT_ASCII;
- else if (0 == strcmp(arg, "lint")) {
- curp->outtype = OUTT_LINT;
- curp->wflags |= WARN_WALL;
- curp->fflags |= FL_STRICT;
- }
- else if (0 == strcmp(arg, "tree"))
- curp->outtype = OUTT_TREE;
- else if (0 == strcmp(arg, "html"))
- curp->outtype = OUTT_HTML;
- else if (0 == strcmp(arg, "xhtml"))
- curp->outtype = OUTT_XHTML;
- else {
- fprintf(stderr, "%s: Bad argument\n", arg);
- return(0);
- }
-
- return(1);
-}
-
-
-static int
-foptions(int *fflags, char *arg)
-{
- char *v, *o;
- const char *toks[8];
-
- toks[0] = "ign-scope";
- toks[1] = "no-ign-escape";
- toks[2] = "no-ign-macro";
- toks[3] = "no-ign-chars";
- toks[4] = "ign-errors";
- toks[5] = "strict";
- toks[6] = "ign-escape";
- toks[7] = NULL;
-
- while (*arg) {
- o = arg;
- switch (getsubopt(&arg, UNCONST(toks), &v)) {
- case (0):
- *fflags |= FL_IGN_SCOPE;
- break;
- case (1):
- *fflags |= FL_NIGN_ESCAPE;
- break;
- case (2):
- *fflags |= FL_NIGN_MACRO;
- break;
- case (3):
- *fflags |= FL_NIGN_CHARS;
- break;
- case (4):
- *fflags |= FL_IGN_ERRORS;
- break;
- case (5):
- *fflags |= FL_STRICT;
- break;
- case (6):
- *fflags &= ~FL_NIGN_ESCAPE;
- break;
- default:
- fprintf(stderr, "%s: Bad argument\n", o);
- return(0);
- }
- }
-
- return(1);
-}
-
-
-static int
-woptions(int *wflags, char *arg)
-{
- char *v, *o;
- const char *toks[3];
-
- toks[0] = "all";
- toks[1] = "error";
- toks[2] = NULL;
-
- while (*arg) {
- o = arg;
- switch (getsubopt(&arg, UNCONST(toks), &v)) {
- case (0):
- *wflags |= WARN_WALL;
- break;
- case (1):
- *wflags |= WARN_WERR;
- break;
- default:
- fprintf(stderr, "%s: Bad argument\n", o);
- return(0);
- }
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-merr(void *arg, int line, int col, const char *msg)
-{
- struct curparse *curp;
-
- curp = (struct curparse *)arg;
-
- (void)fprintf(stderr, "%s:%d:%d: error: %s\n",
- curp->file, line, col + 1, msg);
-
- return(0);
-}
-
-
-static int
-mwarn(void *arg, int line, int col, const char *msg)
-{
- struct curparse *curp;
-
- curp = (struct curparse *)arg;
-
- if ( ! (curp->wflags & WARN_WALL))
- return(1);
-
- (void)fprintf(stderr, "%s:%d:%d: warning: %s\n",
- curp->file, line, col + 1, msg);
-
- if ( ! (curp->wflags & WARN_WERR))
- return(1);
-
- return(0);
-}
+++ /dev/null
-/* $Id: main.h,v 1.2 2010/01/29 14:39:38 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef MAIN_H
-#define MAIN_H
-
-__BEGIN_DECLS
-
-struct mdoc;
-struct man;
-
-/*
- * Definitions for main.c-visible output device functions, e.g., -Thtml
- * and -Tascii. Note that ascii_alloc() is named as such in
- * anticipation of latin1_alloc() and so on, all of which map into the
- * terminal output routines with different character settings.
- */
-
-void *html_alloc(char *);
-void *xhtml_alloc(char *);
-void html_mdoc(void *, const struct mdoc *);
-void html_man(void *, const struct man *);
-void html_free(void *);
-
-void tree_mdoc(void *, const struct mdoc *);
-void tree_man(void *, const struct man *);
-
-void *ascii_alloc(void);
-void terminal_mdoc(void *, const struct mdoc *);
-void terminal_man(void *, const struct man *);
-void terminal_free(void *);
-
-__END_DECLS
-
-#endif /*!MAIN_H*/
+++ /dev/null
-.\" $Id: man.3,v 1.13 2010/03/27 10:04:56 kristaps Exp $
-.\"
-.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd March 27, 2010
-.Dt MAN 3
-.Os
-.
-.
-.Sh NAME
-.Nm man ,
-.Nm man_alloc ,
-.Nm man_parseln ,
-.Nm man_endparse ,
-.Nm man_node ,
-.Nm man_meta ,
-.Nm man_free ,
-.Nm man_reset
-.Nd man macro compiler library
-.
-.
-.Sh SYNOPSIS
-.In man.h
-.Vt extern const char * const * man_macronames;
-.Ft "struct man *"
-.Fn man_alloc "void *data" "int pflags" "const struct man_cb *cb"
-.Ft void
-.Fn man_reset "struct man *man"
-.Ft void
-.Fn man_free "struct man *man"
-.Ft int
-.Fn man_parseln "struct man *man" "int line" "char *buf"
-.Ft "const struct man_node *"
-.Fn man_node "const struct man *man"
-.Ft "const struct man_meta *"
-.Fn man_meta "const struct man *man"
-.Ft int
-.Fn man_endparse "struct man *man"
-.
-.
-.Sh DESCRIPTION
-The
-.Nm
-library parses lines of
-.Xr man 7
-input (and
-.Em only
-man) into an abstract syntax tree (AST).
-.
-.Pp
-In general, applications initiate a parsing sequence with
-.Fn man_alloc ,
-parse each line in a document with
-.Fn man_parseln ,
-close the parsing session with
-.Fn man_endparse ,
-operate over the syntax tree returned by
-.Fn man_node
-and
-.Fn man_meta ,
-then free all allocated memory with
-.Fn man_free .
-The
-.Fn man_reset
-function may be used in order to reset the parser for another input
-sequence. See the
-.Sx EXAMPLES
-section for a full example.
-.
-.Pp
-Beyond the full set of macros defined in
-.Xr man 7 ,
-the
-.Nm
-library also accepts the following macros:
-.
-.Pp
-.Bl -tag -width Ds -compact
-.It am
-.It ami
-.It de
-.It dei
-.It ig
-Instructional macros in the original roff language. Blocks begun by
-these macros end with
-.Sq ..
-and may begin anywhere, although they may not break the next-line
-scoping rules specified in
-.Xr man 7 .
-These blocks are discarded.
-.
-.It PD
-Has no effect. Handled as a current-scope line macro.
-.
-.It Sp
-A synonym for
-.Sq sp 0.5v
-.Pq part of the standard preamble for Perl documentation .
-Handled as a line macro.
-.
-.It UC
-Has no effect. Handled as a current-scope line macro.
-.
-.It Vb
-A synonym for
-.Sq nf
-.Pq part of the standard preamble for Perl documentation .
-Handled as a current-scope line macro.
-.
-.It Ve
-A synonym for
-.Sq fi ,
-closing
-.Sq Vb
-.Pq part of the standard preamble for Perl documentation .
-Handled as a current-scope line macro.
-.El
-.
-.
-.Sh REFERENCE
-This section further defines the
-.Sx Types ,
-.Sx Functions
-and
-.Sx Variables
-available to programmers. Following that, the
-.Sx Abstract Syntax Tree
-section documents the output tree.
-.
-.
-.Ss Types
-Both functions (see
-.Sx Functions )
-and variables (see
-.Sx Variables )
-may use the following types:
-.Bl -ohang
-.
-.It Vt struct man
-An opaque type defined in
-.Pa man.c .
-Its values are only used privately within the library.
-.
-.It Vt struct man_cb
-A set of message callbacks defined in
-.Pa man.h .
-.
-.It Vt struct man_node
-A parsed node. Defined in
-.Pa man.h .
-See
-.Sx Abstract Syntax Tree
-for details.
-.El
-.
-.
-.Ss Functions
-Function descriptions follow:
-.Bl -ohang
-.
-.It Fn man_alloc
-Allocates a parsing structure. The
-.Fa data
-pointer is passed to callbacks in
-.Fa cb ,
-which are documented further in the header file.
-The
-.Fa pflags
-arguments are defined in
-.Pa man.h .
-Returns NULL on failure. If non-NULL, the pointer must be freed with
-.Fn man_free .
-.
-.It Fn man_reset
-Reset the parser for another parse routine. After its use,
-.Fn man_parseln
-behaves as if invoked for the first time.
-.
-.It Fn man_free
-Free all resources of a parser. The pointer is no longer valid after
-invocation.
-.
-.It Fn man_parseln
-Parse a nil-terminated line of input. This line should not contain the
-trailing newline. Returns 0 on failure, 1 on success. The input buffer
-.Fa buf
-is modified by this function.
-.
-.It Fn man_endparse
-Signals that the parse is complete. Note that if
-.Fn man_endparse
-is called subsequent to
-.Fn man_node ,
-the resulting tree is incomplete. Returns 0 on failure, 1 on success.
-.
-.It Fn man_node
-Returns the first node of the parse. Note that if
-.Fn man_parseln
-or
-.Fn man_endparse
-return 0, the tree will be incomplete.
-.It Fn man_meta
-Returns the document's parsed meta-data. If this information has not
-yet been supplied or
-.Fn man_parseln
-or
-.Fn man_endparse
-return 0, the data will be incomplete.
-.El
-.
-.
-.Ss Variables
-The following variables are also defined:
-.Bl -ohang
-.
-.It Va man_macronames
-An array of string-ified token names.
-.El
-.
-.
-.Ss Abstract Syntax Tree
-The
-.Nm
-functions produce an abstract syntax tree (AST) describing input in a
-regular form. It may be reviewed at any time with
-.Fn man_nodes ;
-however, if called before
-.Fn man_endparse ,
-or after
-.Fn man_endparse
-or
-.Fn man_parseln
-fail, it may be incomplete.
-.
-.Pp
-This AST is governed by the ontological
-rules dictated in
-.Xr man 7
-and derives its terminology accordingly.
-.
-.Pp
-The AST is composed of
-.Vt struct man_node
-nodes with element, root and text types as declared
-by the
-.Va type
-field. Each node also provides its parse point (the
-.Va line ,
-.Va sec ,
-and
-.Va pos
-fields), its position in the tree (the
-.Va parent ,
-.Va child ,
-.Va next
-and
-.Va prev
-fields) and some type-specific data.
-.
-.Pp
-The tree itself is arranged according to the following normal form,
-where capitalised non-terminals represent nodes.
-.Pp
-.Bl -tag -width "ELEMENTXX" -compact
-.It ROOT
-\(<- mnode+
-.It mnode
-\(<- ELEMENT | TEXT | BLOCK
-.It BLOCK
-\(<- HEAD BODY
-.It HEAD
-\(<- mnode*
-.It BODY
-\(<- mnode*
-.It ELEMENT
-\(<- ELEMENT | TEXT*
-.It TEXT
-\(<- [[:alpha:]]*
-.El
-.
-.Pp
-The only elements capable of nesting other elements are those with
-next-lint scope as documented in
-.Xr man 7 .
-.
-.
-.Sh EXAMPLES
-The following example reads lines from stdin and parses them, operating
-on the finished parse tree with
-.Fn parsed .
-This example does not error-check nor free memory upon failure.
-.Bd -literal -offset indent
-struct man *man;
-struct man_node *node;
-char *buf;
-size_t len;
-int line;
-
-line = 1;
-man = man_alloc(NULL, 0, NULL);
-buf = NULL;
-alloc_len = 0;
-
-while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
- if (len && buflen[len - 1] = '\en')
- buf[len - 1] = '\e0';
- if ( ! man_parseln(man, line, buf))
- errx(1, "man_parseln");
- line++;
-}
-
-free(buf);
-
-if ( ! man_endparse(man))
- errx(1, "man_endparse");
-if (NULL == (node = man_node(man)))
- errx(1, "man_node");
-
-parsed(man, node);
-man_free(man);
-.Ed
-.
-.
-.Sh SEE ALSO
-.Xr mandoc 1 ,
-.Xr man 7
-.
-.
-.Sh AUTHORS
-The
-.Nm
-utility was written by
-.An Kristaps Dzonsons Aq kristaps@bsd.lv .
+++ /dev/null
-.\" $Id: man.7,v 1.60 2010/03/27 10:22:28 kristaps Exp $
-.\"
-.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd March 27, 2010
-.Dt MAN 7
-.Os
-.
-.
-.Sh NAME
-.Nm man
-.Nd man language reference
-.
-.
-.Sh DESCRIPTION
-The
-.Nm man
-language was historically used to format
-.Ux
-manuals. This reference document describes its syntax, structure, and
-usage.
-.
-.Pp
-.Bf -emphasis
-Do not use
-.Nm
-to write your manuals.
-.Ef
-Use the
-.Xr mdoc 7
-language, instead.
-.
-.Pp
-An
-.Nm
-document follows simple rules: lines beginning with the control
-character
-.Sq \&.
-are parsed for macros. Other lines are interpreted within the scope of
-prior macros:
-.Bd -literal -offset indent
-\&.SH Macro lines change control state.
-Other lines are interpreted within the current state.
-.Ed
-.
-.
-.Sh INPUT ENCODING
-.Nm
-documents may contain only graphable 7-bit ASCII characters, the
-space character, and the tabs character. All manuals must have
-.Ux
-line termination.
-.
-.Pp
-Blank lines are acceptable; where found, the output will assert a
-vertical space.
-.
-.
-.Ss Comments
-Text following a
-.Sq \e\*" ,
-whether in a macro or free-form text line, is ignored to the end of
-line. A macro line with only a control character and comment escape,
-.Sq \&.\e" ,
-is also ignored. Macro lines with only a control character and
-optionally whitespace are stripped from input.
-.
-.
-.Ss Special Characters
-Special characters may occur in both macro and free-form lines.
-Sequences begin with the escape character
-.Sq \e
-followed by either an open-parenthesis
-.Sq \&(
-for two-character sequences; an open-bracket
-.Sq \&[
-for n-character sequences (terminated at a close-bracket
-.Sq \&] ) ;
-or a single one-character sequence. See
-.Xr mandoc_char 7
-for a complete list. Examples include
-.Sq \e(em
-.Pq em-dash
-and
-.Sq \ee
-.Pq back-slash .
-.
-.
-.Ss Text Decoration
-Terms may be text-decorated using the
-.Sq \ef
-escape followed by an indicator: B (bold), I, (italic), R (Roman), or P
-(revert to previous mode):
-.Pp
-.D1 \efBbold\efR \efIitalic\efP
-.Pp
-A numerical representation 3, 2, or 1 (bold, italic, and Roman,
-respectively) may be used instead. A text decoration is only valid, if
-specified in free-form text, until the next macro invocation; if
-specified within a macro, it's only valid until the macro closes scope.
-Note that macros like
-.Sx \&BR
-open and close a font scope with each argument.
-.Pp
-Text may also be sized with the
-.Sq \es
-escape, whose syntax is one of
-.Sq \es+-n
-for one-digit numerals;
-.Sq \es(+-nn
-or
-.Sq \es+-(nn
-for two-digit numerals; and
-.Sq \es[+-N] ,
-.Sq \es+-[N] ,
-.Sq \es'+-N' ,
-or
-.Sq \es+-'N'
-for arbitrary-digit numerals:
-.Pp
-.D1 \es+1bigger\es-1
-.D1 \es[+10]much bigger\es[-10]
-.D1 \es+(10much bigger\es-(10
-.D1 \es+'100'much much bigger\es-'100'
-.Pp
-Both
-.Sq \es
-and
-.Sq \ef
-attributes are forgotten when entering or exiting a macro block.
-.
-.
-.Ss Whitespace
-Unless specifically escaped, consecutive blocks of whitespace are pruned
-from input. These are later re-added, if applicable, by a front-end
-utility such as
-.Xr mandoc 1 .
-.
-.
-.Ss Dates
-The
-.Sx \&TH
-macro is the only
-.Nm
-macro that requires a date. The form for this date is the ISO-8601
-standard
-.Cm YYYY-MM-DD .
-.
-.
-.Ss Scaling Widths
-Many macros support scaled widths for their arguments, such as
-stipulating a two-inch paragraph indentation with the following:
-.Bd -literal -offset indent
-\&.HP 2i
-.Ed
-.
-.Pp
-The syntax for scaled widths is
-.Sq Li [+-]?[0-9]*.[0-9]*[:unit:]? ,
-where a decimal must be preceded or proceeded by at least one digit.
-Negative numbers, while accepted, are truncated to zero. The following
-scaling units are accepted:
-.
-.Pp
-.Bl -tag -width Ds -offset indent -compact
-.It c
-centimetre
-.It i
-inch
-.It P
-pica (~1/6 inch)
-.It p
-point (~1/72 inch)
-.It f
-synonym for
-.Sq u
-.It v
-default vertical span
-.It m
-width of rendered
-.Sq m
-.Pq em
-character
-.It n
-width of rendered
-.Sq n
-.Pq en
-character
-.It u
-default horizontal span
-.It M
-mini-em (~1/100 em)
-.El
-.Pp
-Using anything other than
-.Sq m ,
-.Sq n ,
-.Sq u ,
-or
-.Sq v
-is necessarily non-portable across output media.
-.
-.Pp
-If a scaling unit is not provided, the numerical value is interpreted
-under the default rules of
-.Sq v
-for vertical spaces and
-.Sq u
-for horizontal ones.
-.Em Note :
-this differs from
-.Xr mdoc 7 ,
-which, if a unit is not provided, will instead interpret the string as
-literal text.
-.
-.
-.Sh MANUAL STRUCTURE
-Each
-.Nm
-document must contain contains at least the
-.Sx \&TH
-macro describing the document's section and title. It may occur
-anywhere in the document, although conventionally, it appears as the
-first macro.
-.
-.Pp
-Beyond
-.Sx \&TH ,
-at least one macro or text node must appear in the document. Documents
-are generally structured as follows:
-.Bd -literal -offset indent
-\&.TH FOO 1 2009-10-10
-\&.
-\&.SH NAME
-\efBfoo\efR \e(en a description goes here
-\&.\e\*q The next is for sections 2 & 3 only.
-\&.\e\*q .SH LIBRARY
-\&.
-\&.SH SYNOPSIS
-\efBfoo\efR [\efB\e-options\efR] arguments...
-\&.
-\&.SH DESCRIPTION
-The \efBfoo\efR utility processes files...
-\&.
-\&.\e\*q .SH IMPLEMENTATION NOTES
-\&.\e\*q The next is for sections 1 & 8 only.
-\&.\e\*q .SH EXIT STATUS
-\&.\e\*q The next is for sections 2, 3, & 9 only.
-\&.\e\*q .SH RETURN VALUES
-\&.\e\*q The next is for sections 1, 6, 7, & 8 only.
-\&.\e\*q .SH ENVIRONMENT
-\&.\e\*q .SH FILES
-\&.\e\*q .SH EXAMPLES
-\&.\e\*q The next is for sections 1, 4, 6, 7, & 8 only.
-\&.\e\*q .SH DIAGNOSTICS
-\&.\e\*q The next is for sections 2, 3, & 9 only.
-\&.\e\*q .SH ERRORS
-\&.\e\*q .SH SEE ALSO
-\&.\e\*q .BR foo ( 1 )
-\&.\e\*q .SH STANDARDS
-\&.\e\*q .SH HISTORY
-\&.\e\*q .SH AUTHORS
-\&.\e\*q .SH CAVEATS
-\&.\e\*q .SH BUGS
-\&.\e\*q .SH SECURITY CONSIDERATIONS
-.Ed
-.Pp
-The sections in a
-.Nm
-document are conventionally ordered as they appear above. Sections
-should be composed as follows:
-.Bl -ohang -offset indent
-.It Em NAME
-The name(s) and a short description of the documented material. The
-syntax for this is generally as follows:
-.Pp
-.D1 \efBname\efR \e(en description
-.It Em LIBRARY
-The name of the library containing the documented material, which is
-assumed to be a function in a section 2 or 3 manual. For functions in
-the C library, this may be as follows:
-.Pp
-.D1 Standard C Library (libc, -lc)
-.It Em SYNOPSIS
-Documents the utility invocation syntax, function call syntax, or device
-configuration.
-.Pp
-For the first, utilities (sections 1, 6, and 8), this is
-generally structured as follows:
-.Pp
-.D1 \efBname\efR [-\efBab\efR] [-\efBc\efR\efIarg\efR] \efBpath\efR...
-.Pp
-For the second, function calls (sections 2, 3, 9):
-.Pp
-.D1 \&.B char *name(char *\efIarg\efR);
-.Pp
-And for the third, configurations (section 4):
-.Pp
-.D1 \&.B name* at cardbus ? function ?
-.Pp
-Manuals not in these sections generally don't need a
-.Em SYNOPSIS .
-.It Em DESCRIPTION
-This expands upon the brief, one-line description in
-.Em NAME .
-It usually contains a break-down of the options (if documenting a
-command).
-.It Em IMPLEMENTATION NOTES
-Implementation-specific notes should be kept here. This is useful when
-implementing standard functions that may have side effects or notable
-algorithmic implications.
-.It Em EXIT STATUS
-Command exit status for section 1, 6, and 8 manuals. This section is
-the dual of
-.Em RETURN VALUES ,
-which is used for functions. Historically, this information was
-described in
-.Em DIAGNOSTICS ,
-a practise that is now discouraged.
-.
-.It Em RETURN VALUES
-This section is the dual of
-.Em EXIT STATUS ,
-which is used for commands. It documents the return values of functions
-in sections 2, 3, and 9.
-.
-.It Em ENVIRONMENT
-Documents any usages of environment variables, e.g.,
-.Xr environ 7 .
-.
-.It Em FILES
-Documents files used. It's helpful to document both the file and a
-short description of how the file is used (created, modified, etc.).
-.
-.It Em EXAMPLES
-Example usages. This often contains snippets of well-formed,
-well-tested invocations. Make doubly sure that your examples work
-properly!
-.
-.It Em DIAGNOSTICS
-Documents error conditions. This is most useful in section 4 manuals.
-Historically, this section was used in place of
-.Em EXIT STATUS
-for manuals in sections 1, 6, and 8; however, this practise is
-discouraged.
-.
-.It Em ERRORS
-Documents error handling in sections 2, 3, and 9.
-.
-.It Em SEE ALSO
-References other manuals with related topics. This section should exist
-for most manuals.
-.Pp
-.D1 \&.BR bar \&( 1 \&),
-.Pp
-Cross-references should conventionally be ordered
-first by section, then alphabetically.
-.
-.It Em STANDARDS
-References any standards implemented or used, such as
-.Pp
-.D1 IEEE Std 1003.2 (\e(lqPOSIX.2\e(rq)
-.Pp
-If not adhering to any standards, the
-.Em HISTORY
-section should be used.
-.
-.It Em HISTORY
-The history of any manual without a
-.Em STANDARDS
-section should be described in this section.
-.
-.It Em AUTHORS
-Credits to authors, if applicable, should appear in this section.
-Authors should generally be noted by both name and an e-mail address.
-.
-.It Em CAVEATS
-Explanations of common misuses and misunderstandings should be explained
-in this section.
-.
-.It Em BUGS
-Extant bugs should be described in this section.
-.
-.It Em SECURITY CONSIDERATIONS
-Documents any security precautions that operators should consider.
-.
-.El
-.
-.
-.Sh MACRO SYNTAX
-Macros are one to three three characters in length and begin with a
-control character ,
-.Sq \&. ,
-at the beginning of the line. The
-.Sq \(aq
-macro control character is also accepted. An arbitrary amount of
-whitespace (spaces or tabs) may sit between the control character and
-the macro name. Thus, the following are equivalent:
-.Bd -literal -offset indent
-\&.PP
-\&.\ \ \ PP
-.Ed
-.
-.Pp
-The
-.Nm
-macros are classified by scope: line scope or block scope. Line
-macros are only scoped to the current line (and, in some situations,
-the subsequent line). Block macros are scoped to the current line and
-subsequent lines until closed by another block macro.
-.
-.
-.Ss Line Macros
-Line macros are generally scoped to the current line, with the body
-consisting of zero or more arguments. If a macro is scoped to the next
-line and the line arguments are empty, the next line, which must be
-text, is used instead. Thus:
-.Bd -literal -offset indent
-\&.I
-foo
-.Ed
-.
-.Pp
-is equivalent to
-.Sq \&.I foo .
-If next-line macros are invoked consecutively, only the last is used.
-If a next-line macro is followed by a non-next-line macro, an error is
-raised (unless in the case of
-.Sx \&br ,
-.Sx \&sp ,
-.Sx \&Sp ,
-or
-.Sx \&na ) .
-.Pp
-The syntax is as follows:
-.Bd -literal -offset indent
-\&.YO \(lBbody...\(rB
-\(lBbody...\(rB
-.Ed
-.
-.Pp
-.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "ScopeXXXXX" "CompatX"
-.It Em Macro Ta Em Arguments Ta Em Scope Ta Em Notes
-.It Sx \&B Ta n Ta next-line Ta \&
-.It Sx \&BI Ta n Ta current Ta \&
-.It Sx \&BR Ta n Ta current Ta \&
-.It Sx \&DT Ta 0 Ta current Ta \&
-.It Sx \&I Ta n Ta next-line Ta \&
-.It Sx \&IB Ta n Ta current Ta \&
-.It Sx \&IR Ta n Ta current Ta \&
-.\" .It Sx \&PD Ta n Ta current Ta compat
-.It Sx \&R Ta n Ta next-line Ta \&
-.It Sx \&RB Ta n Ta current Ta \&
-.It Sx \&RI Ta n Ta current Ta \&
-.It Sx \&SB Ta n Ta next-line Ta \&
-.It Sx \&SM Ta n Ta next-line Ta \&
-.It Sx \&TH Ta >1, <6 Ta current Ta \&
-.\" .It Sx \&UC Ta n Ta current Ta compat
-.It Sx \&br Ta 0 Ta current Ta compat
-.It Sx \&fi Ta 0 Ta current Ta compat
-.It Sx \&i Ta n Ta current Ta compat
-.It Sx \&na Ta 0 Ta current Ta compat
-.It Sx \&nf Ta 0 Ta current Ta compat
-.It Sx \&r Ta 0 Ta current Ta compat
-.It Sx \&sp Ta 1 Ta current Ta compat
-.\" .It Sx \&Sp Ta 0 Ta current Ta compat
-.\" .It Sx \&Vb Ta <1 Ta current Ta compat
-.\" .It Sx \&Ve Ta 0 Ta current Ta compat
-.El
-.
-.Pp
-Macros marked as
-.Qq compat
-are included for compatibility with the significant corpus of existing
-manuals that mix dialects of roff. These macros should not be used for
-portable
-.Nm
-manuals.
-.
-.
-.Ss Block Macros
-Block macros are comprised of a head and body. Like for in-line macros,
-the head is scoped to the current line and, in one circumstance, the
-next line (the next-line stipulations as in
-.Sx Line Macros
-apply here as well).
-.Pp
-The syntax is as follows:
-.Bd -literal -offset indent
-\&.YO \(lBhead...\(rB
-\(lBhead...\(rB
-\(lBbody...\(rB
-.Ed
-.
-.Pp
-The closure of body scope may be to the section, where a macro is closed
-by
-.Sx \&SH ;
-sub-section, closed by a section or
-.Sx \&SS ;
-part, closed by a section, sub-section, or
-.Sx \&RE ;
-or paragraph, closed by a section, sub-section, part,
-.Sx \&HP ,
-.Sx \&IP ,
-.Sx \&LP ,
-.Sx \&P ,
-.Sx \&PP ,
-or
-.Sx \&TP .
-No closure refers to an explicit block closing macro.
-.
-.Pp
-As a rule, block macros may not be nested; thus, calling a block macro
-while another block macro scope is open, and the open scope is not
-implicitly closed, is syntactically incorrect.
-.
-.Pp
-.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" "compatX"
-.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes
-.It Sx \&HP Ta <2 Ta current Ta paragraph Ta \&
-.It Sx \&IP Ta <3 Ta current Ta paragraph Ta \&
-.It Sx \&LP Ta 0 Ta current Ta paragraph Ta \&
-.It Sx \&P Ta 0 Ta current Ta paragraph Ta \&
-.It Sx \&PP Ta 0 Ta current Ta paragraph Ta \&
-.It Sx \&RE Ta 0 Ta current Ta none Ta compat
-.It Sx \&RS Ta 1 Ta current Ta part Ta compat
-.It Sx \&SH Ta >0 Ta next-line Ta section Ta \&
-.It Sx \&SS Ta >0 Ta next-line Ta sub-section Ta \&
-.It Sx \&TP Ta n Ta next-line Ta paragraph Ta \&
-.El
-.Pp
-.
-Macros marked
-.Qq compat
-are as mentioned in
-.Sx Line Macros .
-.
-.Pp
-If a block macro is next-line scoped, it may only be followed by in-line
-macros for decorating text.
-.
-.
-.Sh REFERENCE
-This section is a canonical reference to all macros, arranged
-alphabetically. For the scoping of individual macros, see
-.Sx MACRO SYNTAX .
-.
-.
-.Ss \&B
-Text is rendered in bold face.
-.Pp
-See also
-.Sx \&I ,
-.Sx \&R ,
-.Sx \&b ,
-.Sx \&i ,
-and
-.Sx \&r .
-.
-.
-.Ss \&BI
-Text is rendered alternately in bold face and italic. Thus,
-.Sq .BI this word and that
-causes
-.Sq this
-and
-.Sq and
-to render in bold face, while
-.Sq word
-and
-.Sq that
-render in italics. Whitespace between arguments is omitted in output.
-.Pp
-Examples:
-.Pp
-.D1 \&.BI bold italic bold italic
-.Pp
-The output of this example will be emboldened
-.Dq bold
-and italicised
-.Dq italic ,
-with spaces stripped between arguments.
-.Pp
-See also
-.Sx \&IB ,
-.Sx \&BR ,
-.Sx \&RB ,
-.Sx \&RI ,
-and
-.Sx \&IR .
-.
-.
-.Ss \&BR
-Text is rendered alternately in bold face and roman (the default font).
-Whitespace between arguments is omitted in output.
-.Pp
-See
-.Sx \&BI
-for an equivalent example.
-.Pp
-See also
-.Sx \&BI ,
-.Sx \&IB ,
-.Sx \&RB ,
-.Sx \&RI ,
-and
-.Sx \&IR .
-.
-.
-.Ss \&DT
-Has no effect. Included for compatibility.
-.
-.
-.Ss \&HP
-Begin a paragraph whose initial output line is left-justified, but
-subsequent output lines are indented, with the following syntax:
-.Bd -filled -offset indent
-.Pf \. Sx \&HP
-.Op Cm width
-.Ed
-.Pp
-The
-.Cm width
-argument must conform to
-.Sx Scaling Widths .
-If specified, it's saved for later paragraph left-margins; if unspecified, the
-saved or default width is used.
-.Pp
-See also
-.Sx \&IP ,
-.Sx \&LP ,
-.Sx \&P ,
-.Sx \&PP ,
-and
-.Sx \&TP .
-.
-.
-.Ss \&I
-Text is rendered in italics.
-.Pp
-See also
-.Sx \&B ,
-.Sx \&R ,
-.Sx \&b ,
-.Sx \&i ,
-and
-.Sx \&r .
-.
-.
-.Ss \&IB
-Text is rendered alternately in italics and bold face. Whitespace
-between arguments is omitted in output.
-.Pp
-See
-.Sx \&BI
-for an equivalent example.
-.Pp
-See also
-.Sx \&BI ,
-.Sx \&BR ,
-.Sx \&RB ,
-.Sx \&RI ,
-and
-.Sx \&IR .
-.
-.
-.Ss \&IP
-Begin an indented paragraph with the following syntax:
-.Bd -filled -offset indent
-.Pf \. Sx \&IP
-.Op Cm head Op Cm width
-.Ed
-.Pp
-The
-.Cm width
-argument defines the width of the left margin and is defined by
-.Sx Scaling Widths ,
-It's saved for later paragraph left-margins; if unspecified, the saved or
-default width is used.
-.Pp
-The
-.Cm head
-argument is used as a leading term, flushed to the left margin. This is
-useful for bulleted paragraphs and so on.
-.Pp
-See also
-.Sx \&HP ,
-.Sx \&LP ,
-.Sx \&P ,
-.Sx \&PP ,
-and
-.Sx \&TP .
-.
-.
-.Ss \&IR
-Text is rendered alternately in italics and roman (the default font).
-Whitespace between arguments is omitted in output.
-.Pp
-See
-.Sx \&BI
-for an equivalent example.
-.Pp
-See also
-.Sx \&BI ,
-.Sx \&IB ,
-.Sx \&BR ,
-.Sx \&RB ,
-and
-.Sx \&RI .
-.
-.
-.Ss \&LP
-Begin an undecorated paragraph. The scope of a paragraph is closed by a
-subsequent paragraph, sub-section, section, or end of file. The saved
-paragraph left-margin width is re-set to the default.
-.Pp
-See also
-.Sx \&HP ,
-.Sx \&IP ,
-.Sx \&P ,
-.Sx \&PP ,
-and
-.Sx \&TP .
-.
-.
-.Ss \&P
-Synonym for
-.Sx \&LP .
-.Pp
-See also
-.Sx \&HP ,
-.Sx \&IP ,
-.Sx \&LP ,
-.Sx \&PP ,
-and
-.Sx \&TP .
-.
-.
-.Ss \&PP
-Synonym for
-.Sx \&LP .
-.Pp
-See also
-.Sx \&HP ,
-.Sx \&IP ,
-.Sx \&LP ,
-.Sx \&P ,
-and
-.Sx \&TP .
-.
-.
-.Ss \&R
-Text is rendered in roman (the default font).
-.Pp
-See also
-.Sx \&I ,
-.Sx \&B ,
-.Sx \&b ,
-.Sx \&i ,
-and
-.Sx \&r .
-.
-.
-.Ss \&RB
-Text is rendered alternately in roman (the default font) and bold face.
-Whitespace between arguments is omitted in output.
-.Pp
-See
-.Sx \&BI
-for an equivalent example.
-.Pp
-See also
-.Sx \&BI ,
-.Sx \&IB ,
-.Sx \&BR ,
-.Sx \&RI ,
-and
-.Sx \&IR .
-.
-.
-.Ss \&RE
-Explicitly close out the scope of a prior
-.Sx \&RS .
-.
-.
-.Ss \&RI
-Text is rendered alternately in roman (the default font) and italics.
-Whitespace between arguments is omitted in output.
-.Pp
-See
-.Sx \&BI
-for an equivalent example.
-.Pp
-See also
-.Sx \&BI ,
-.Sx \&IB ,
-.Sx \&BR ,
-.Sx \&RB ,
-and
-.Sx \&IR .
-.
-.
-.Ss \&RS
-Begin a part setting the left margin. The left margin controls the
-offset, following an initial indentation, to un-indented text such as
-that of
-.Sx \&PP .
-This has the following syntax:
-.Bd -filled -offset indent
-.Pf \. Sx \&Rs
-.Op Cm width
-.Ed
-.Pp
-The
-.Cm width
-argument must conform to
-.Sx Scaling Widths .
-If not specified, the saved or default width is used.
-.
-.
-.Ss \&SB
-Text is rendered in small size (one point smaller than the default font)
-bold face.
-.
-.
-.Ss \&SH
-Begin a section. The scope of a section is only closed by another
-section or the end of file. The paragraph left-margin width is re-set
-to the default.
-.
-.
-.Ss \&SM
-Text is rendered in small size (one point smaller than the default
-font).
-.
-.
-.Ss \&SS
-Begin a sub-section. The scope of a sub-section is closed by a
-subsequent sub-section, section, or end of file. The paragraph
-left-margin width is re-set to the default.
-.
-.
-.Ss \&TH
-Sets the title of the manual page with the following syntax:
-.Bd -filled -offset indent
-.Pf \. Sx \&TH
-.Cm title section
-.Op Cm date Op Cm source Op Cm volume
-.Ed
-.Pp
-At least the upper-case document title
-.Cm title
-and numeric manual section
-.Cm section
-arguments must be provided. The
-.Cm date
-argument should be formatted as described in
-.Sx Dates :
-if it does not conform, the current date is used instead. The
-.Cm source
-string specifies the organisation providing the utility. The
-.Cm volume
-string replaces the default rendered volume, which is dictated by the
-manual section.
-.Pp
-Examples:
-.Pp
-.D1 \&.TH CVS 5 "1992-02-12" GNU
-.
-.
-.Ss \&TP
-Begin a paragraph where the head, if exceeding the indentation width, is
-followed by a newline; if not, the body follows on the same line after a
-buffer to the indentation width. Subsequent output lines are indented.
-The syntax is as follows:
-.Bd -filled -offset indent
-.Pf \. Sx \&TP
-.Op Cm width
-.Ed
-.Pp
-The
-.Cm width
-argument must conform to
-.Sx Scaling Widths .
-If specified, it's saved for later paragraph left-margins; if
-unspecified, the saved or default width is used.
-.Pp
-See also
-.Sx \&HP ,
-.Sx \&IP ,
-.Sx \&LP ,
-.Sx \&P ,
-and
-.Sx \&PP .
-.\" .
-.\" .
-.\" .Ss \&PD
-.\" Has no effect. Included for compatibility.
-.\" .
-.\" .
-.\" .Ss \&UC
-.\" Has no effect. Included for compatibility.
-.
-.
-.Ss \&br
-Breaks the current line. Consecutive invocations have no further effect.
-.Pp
-See also
-.Sx \&sp .
-.
-.
-.Ss \&fi
-End literal mode begun by
-.Sx \&nf .
-.
-.
-.Ss \&i
-Italicise arguments. Synonym for
-.Sx \&I .
-.Pp
-See also
-.Sx \&B ,
-.Sx \&I ,
-.Sx \&R .
-.Sx \&b ,
-and
-.Sx \&r .
-.
-.
-.Ss \&na
-Don't align to the right margin.
-.
-.
-.Ss \&nf
-Begin literal mode: all subsequent free-form lines have their end of
-line boundaries preserved. May be ended by
-.Sx \&fi .
-.
-.
-.Ss \&r
-Fonts and styles (bold face, italics) reset to roman (default font).
-.Pp
-See also
-.Sx \&B ,
-.Sx \&I ,
-.Sx \&R ,
-.Sx \&b ,
-and
-.Sx \&i .
-.
-.
-.Ss \&sp
-Insert vertical spaces into output with the following syntax:
-.Bd -filled -offset indent
-.Pf \. Sx \&sp
-.Op Cm height
-.Ed
-.Pp
-Insert
-.Cm height
-spaces, which must conform to
-.Sx Scaling Widths .
-If 0, this is equivalent to the
-.Sx \&br
-macro. Defaults to 1, if unspecified.
-.Pp
-See also
-.Sx \&br .
-.
-.\" .Ss \&Sp
-.\" A synonym for
-.\" .Sx \&sp
-.\" .Cm 0.5v .
-.\" .
-.\" .Ss \&Vb
-.\" A synonym for
-.\" .Sx \&nf .
-.\" Accepts an argument (the height of the formatted space) which is
-.\" disregarded.
-.\" .
-.\" .Ss \&Ve
-.\" A synonym for
-.\" .Sx \&fi .
-.\" .
-.
-.Sh COMPATIBILITY
-This section documents areas of questionable portability between
-implementations of the
-.Nm
-language.
-.
-.Pp
-.Bl -dash -compact
-.It
-In quoted literals, GNU troff allowed pair-wise double-quotes to produce
-a standalone double-quote in formatted output. It is not known whether
-this behaviour is exhibited by other formatters.
-.
-.It
-Blocks of whitespace are stripped from macro and free-form text lines
-(except when in literal mode) in mandoc. This is not the case for GNU
-troff: for maximum portability, whitespace sensitive blocks should be
-enclosed in literal contexts.
-.
-.It
-The
-.Sx \&sp
-macro does not accept negative values in mandoc. In GNU troff, this
-would result in strange behaviour.
-.
-.It
-The
-.Sq \(aq
-macro control character, in GNU troff (and prior troffs) suppresses a
-newline before macro output; in mandoc, it is an alias for the standard
-.Sq \&.
-control character.
-.El
-.
-.
-.Sh SEE ALSO
-.Xr mandoc 1 ,
-.Xr mandoc_char 7
-.
-.
-.Sh AUTHORS
-The
-.Nm
-reference was written by
-.An Kristaps Dzonsons Aq kristaps@kth.se .
-.
-.
-.Sh CAVEATS
-Do not use this language. Use
-.Xr mdoc 7 ,
-instead.
-.
+++ /dev/null
-/* $Id: man.c,v 1.59 2010/03/29 10:10:35 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "libman.h"
-#include "libmandoc.h"
-
-const char *const __man_merrnames[WERRMAX] = {
- "invalid character", /* WNPRINT */
- "invalid manual section", /* WMSEC */
- "invalid date format", /* WDATE */
- "scope of prior line violated", /* WLNSCOPE */
- "over-zealous prior line scope violation", /* WLNSCOPE2 */
- "trailing whitespace", /* WTSPACE */
- "unterminated quoted parameter", /* WTQUOTE */
- "document has no body", /* WNODATA */
- "document has no title/section", /* WNOTITLE */
- "invalid escape sequence", /* WESCAPE */
- "invalid number format", /* WNUMFMT */
- "expected block head arguments", /* WHEADARGS */
- "expected block body arguments", /* WBODYARGS */
- "expected empty block head", /* WNHEADARGS */
- "ill-formed macro", /* WMACROFORM */
- "scope open on exit", /* WEXITSCOPE */
- "no scope context", /* WNOSCOPE */
- "literal context already open", /* WOLITERAL */
- "no literal context open", /* WNLITERAL */
- "invalid nesting of roff declarations", /* WROFFNEST */
- "scope in roff instructions broken", /* WROFFSCOPE */
- "document title should be uppercase", /* WTITLECASE */
-};
-
-const char *const __man_macronames[MAN_MAX] = {
- "br", "TH", "SH", "SS",
- "TP", "LP", "PP", "P",
- "IP", "HP", "SM", "SB",
- "BI", "IB", "BR", "RB",
- "R", "B", "I", "IR",
- "RI", "na", "i", "sp",
- "nf", "fi", "r", "RE",
- "RS", "DT", "UC", "PD",
- "Sp", "Vb", "Ve", "de",
- "dei", "am", "ami", "ig",
- ".",
- };
-
-const char * const *man_macronames = __man_macronames;
-
-static struct man_node *man_node_alloc(int, int,
- enum man_type, enum mant);
-static int man_node_append(struct man *,
- struct man_node *);
-static void man_node_free(struct man_node *);
-static void man_node_unlink(struct man *,
- struct man_node *);
-static int man_ptext(struct man *, int, char *);
-static int man_pmacro(struct man *, int, char *);
-static void man_free1(struct man *);
-static void man_alloc1(struct man *);
-static int pstring(struct man *, int, int,
- const char *, size_t);
-static int macrowarn(struct man *, int, const char *);
-
-
-const struct man_node *
-man_node(const struct man *m)
-{
-
- return(MAN_HALT & m->flags ? NULL : m->first);
-}
-
-
-const struct man_meta *
-man_meta(const struct man *m)
-{
-
- return(MAN_HALT & m->flags ? NULL : &m->meta);
-}
-
-
-void
-man_reset(struct man *man)
-{
-
- man_free1(man);
- man_alloc1(man);
-}
-
-
-void
-man_free(struct man *man)
-{
-
- man_free1(man);
- free(man);
-}
-
-
-struct man *
-man_alloc(void *data, int pflags, const struct man_cb *cb)
-{
- struct man *p;
-
- p = mandoc_calloc(1, sizeof(struct man));
-
- if (cb)
- memcpy(&p->cb, cb, sizeof(struct man_cb));
-
- man_hash_init();
- p->data = data;
- p->pflags = pflags;
-
- man_alloc1(p);
- return(p);
-}
-
-
-int
-man_endparse(struct man *m)
-{
-
- if (MAN_HALT & m->flags)
- return(0);
- else if (man_macroend(m))
- return(1);
- m->flags |= MAN_HALT;
- return(0);
-}
-
-
-int
-man_parseln(struct man *m, int ln, char *buf)
-{
-
- return('.' == *buf || '\'' == *buf ?
- man_pmacro(m, ln, buf) :
- man_ptext(m, ln, buf));
-}
-
-
-static void
-man_free1(struct man *man)
-{
-
- if (man->first)
- man_node_delete(man, man->first);
- if (man->meta.title)
- free(man->meta.title);
- if (man->meta.source)
- free(man->meta.source);
- if (man->meta.vol)
- free(man->meta.vol);
-}
-
-
-static void
-man_alloc1(struct man *m)
-{
-
- 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;
-}
-
-
-static int
-man_node_append(struct man *man, struct man_node *p)
-{
-
- assert(man->last);
- assert(man->first);
- assert(MAN_ROOT != p->type);
-
- switch (man->next) {
- case (MAN_NEXT_SIBLING):
- man->last->next = p;
- p->prev = man->last;
- p->parent = man->last->parent;
- break;
- case (MAN_NEXT_CHILD):
- man->last->child = p;
- p->parent = man->last;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- assert(p->parent);
- p->parent->nchild++;
-
- if ( ! man_valid_pre(man, p))
- return(0);
-
- switch (p->type) {
- case (MAN_HEAD):
- assert(MAN_BLOCK == p->parent->type);
- p->parent->head = p;
- break;
- case (MAN_BODY):
- assert(MAN_BLOCK == p->parent->type);
- p->parent->body = p;
- break;
- default:
- break;
- }
-
- man->last = p;
-
- switch (p->type) {
- case (MAN_TEXT):
- if ( ! man_valid_post(man))
- return(0);
- if ( ! man_action_post(man))
- return(0);
- break;
- default:
- break;
- }
-
- return(1);
-}
-
-
-static struct man_node *
-man_node_alloc(int line, int pos, enum man_type type, enum mant tok)
-{
- struct man_node *p;
-
- p = mandoc_calloc(1, sizeof(struct man_node));
- p->line = line;
- p->pos = pos;
- p->type = type;
- p->tok = tok;
- return(p);
-}
-
-
-int
-man_elem_alloc(struct man *m, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(line, pos, MAN_ELEM, tok);
- if ( ! man_node_append(m, p))
- return(0);
- m->next = MAN_NEXT_CHILD;
- return(1);
-}
-
-
-int
-man_head_alloc(struct man *m, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(line, pos, MAN_HEAD, tok);
- if ( ! man_node_append(m, p))
- return(0);
- m->next = MAN_NEXT_CHILD;
- return(1);
-}
-
-
-int
-man_body_alloc(struct man *m, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(line, pos, MAN_BODY, tok);
- if ( ! man_node_append(m, p))
- return(0);
- m->next = MAN_NEXT_CHILD;
- return(1);
-}
-
-
-int
-man_block_alloc(struct man *m, int line, int pos, enum mant tok)
-{
- struct man_node *p;
-
- p = man_node_alloc(line, pos, MAN_BLOCK, tok);
- if ( ! man_node_append(m, p))
- return(0);
- m->next = MAN_NEXT_CHILD;
- return(1);
-}
-
-
-static int
-pstring(struct man *m, int line, int pos,
- const char *p, size_t len)
-{
- struct man_node *n;
- size_t sv;
-
- n = man_node_alloc(line, pos, MAN_TEXT, MAN_MAX);
- n->string = mandoc_malloc(len + 1);
- sv = strlcpy(n->string, p, len + 1);
-
- /* Prohibit truncation. */
- assert(sv < len + 1);
-
- if ( ! man_node_append(m, n))
- return(0);
- m->next = MAN_NEXT_SIBLING;
- return(1);
-}
-
-
-int
-man_word_alloc(struct man *m, int line, int pos, const char *word)
-{
-
- return(pstring(m, line, pos, word, strlen(word)));
-}
-
-
-/*
- * Free all of the resources held by a node. This does NOT unlink a
- * node from its context; for that, see man_node_unlink().
- */
-static void
-man_node_free(struct man_node *p)
-{
-
- if (p->string)
- free(p->string);
- free(p);
-}
-
-
-void
-man_node_delete(struct man *m, struct man_node *p)
-{
-
- while (p->child)
- man_node_delete(m, p->child);
-
- man_node_unlink(m, p);
- man_node_free(p);
-}
-
-
-static int
-man_ptext(struct man *m, int line, char *buf)
-{
- int i, j;
- char sv;
-
- /* Literal free-form text whitespace is preserved. */
-
- if (MAN_LITERAL & m->flags) {
- if ( ! man_word_alloc(m, line, 0, buf))
- return(0);
- goto descope;
- }
-
- /* First de-chunk and allocate words. */
-
- for (i = 0; ' ' == buf[i]; i++)
- /* Skip leading whitespace. */ ;
-
- if ('\0' == buf[i]) {
- /* Trailing whitespace? */
- if (i && ' ' == buf[i - 1])
- if ( ! man_pwarn(m, line, i - 1, WTSPACE))
- return(0);
- if ( ! pstring(m, line, 0, &buf[i], 0))
- return(0);
- goto descope;
- }
-
- for (j = i; buf[i]; i++) {
- if (' ' != buf[i])
- continue;
-
- /* Escaped whitespace. */
- if (i && ' ' == buf[i] && '\\' == buf[i - 1])
- continue;
-
- sv = buf[i];
- buf[i++] = '\0';
-
- if ( ! pstring(m, line, j, &buf[j], (size_t)(i - j)))
- return(0);
-
- /* Trailing whitespace? Check at overwritten byte. */
-
- if (' ' == sv && '\0' == buf[i])
- if ( ! man_pwarn(m, line, i - 1, WTSPACE))
- return(0);
-
- for ( ; ' ' == buf[i]; i++)
- /* Skip trailing whitespace. */ ;
-
- j = i;
-
- /* Trailing whitespace? */
-
- if (' ' == buf[i - 1] && '\0' == buf[i])
- if ( ! man_pwarn(m, line, i - 1, WTSPACE))
- return(0);
-
- if ('\0' == buf[i])
- break;
- }
-
- if (j != i && ! pstring(m, line, j, &buf[j], (size_t)(i - j)))
- return(0);
-
-descope:
-
- /*
- * Co-ordinate what happens with having a next-line scope open:
- * first close out the element scope (if applicable), then close
- * out the block scope (also if applicable).
- */
-
- if (MAN_ELINE & m->flags) {
- m->flags &= ~MAN_ELINE;
- if ( ! man_unscope(m, m->last->parent, WERRMAX))
- return(0);
- }
-
- if ( ! (MAN_BLINE & m->flags))
- return(1);
- m->flags &= ~MAN_BLINE;
-
- if ( ! man_unscope(m, m->last->parent, WERRMAX))
- return(0);
- return(man_body_alloc(m, line, 0, m->last->tok));
-}
-
-
-static int
-macrowarn(struct man *m, int ln, const char *buf)
-{
- if ( ! (MAN_IGN_MACRO & m->pflags))
- return(man_verr(m, ln, 0,
- "unknown macro: %s%s",
- buf, strlen(buf) > 3 ? "..." : ""));
- return(man_vwarn(m, ln, 0, "unknown macro: %s%s",
- buf, strlen(buf) > 3 ? "..." : ""));
-}
-
-
-int
-man_pmacro(struct man *m, int ln, char *buf)
-{
- int i, j, ppos;
- enum mant tok;
- char mac[5];
- struct man_node *n;
-
- /* Comments and empties are quickly ignored. */
-
- if ('\0' == buf[1])
- return(1);
-
- i = 1;
-
- /*
- * Skip whitespace between the control character and initial
- * text. "Whitespace" is both spaces and tabs.
- */
- if (' ' == buf[i] || '\t' == buf[i]) {
- i++;
- while (buf[i] && (' ' == buf[i] || '\t' == buf[i]))
- i++;
- if ('\0' == buf[i])
- goto out;
- }
-
- ppos = i;
-
- /* Copy the first word into a nil-terminated buffer. */
-
- for (j = 0; j < 4; j++, i++) {
- if ('\0' == (mac[j] = buf[i]))
- break;
- else if (' ' == buf[i])
- break;
-
- /* Check for invalid characters. */
-
- if (isgraph((u_char)buf[i]))
- continue;
- return(man_perr(m, ln, i, WNPRINT));
- }
-
- mac[j] = '\0';
-
- if (j == 4 || j < 1) {
- if ( ! (MAN_IGN_MACRO & m->pflags)) {
- (void)man_perr(m, ln, ppos, WMACROFORM);
- goto err;
- }
- if ( ! man_pwarn(m, ln, ppos, WMACROFORM))
- goto err;
- return(1);
- }
-
- if (MAN_MAX == (tok = man_hash_find(mac))) {
- if ( ! macrowarn(m, ln, mac))
- goto err;
- return(1);
- }
-
- /* The macro is sane. Jump to the next word. */
-
- while (buf[i] && ' ' == buf[i])
- i++;
-
- /* Trailing whitespace? */
-
- if ('\0' == buf[i] && ' ' == buf[i - 1])
- if ( ! man_pwarn(m, ln, i - 1, WTSPACE))
- goto err;
-
- /*
- * Remove prior ELINE macro, as it's being clobbering by a new
- * macro. Note that NSCOPED macros do not close out ELINE
- * macros---they don't print text---so we let those slip by.
- * NOTE: we don't allow roff blocks (NOCLOSE) to be embedded
- * here because that would stipulate blocks as children of
- * elements!
- */
-
- if ( ! (MAN_NSCOPED & man_macros[tok].flags) &&
- m->flags & MAN_ELINE) {
- assert(MAN_TEXT != m->last->type);
-
- /*
- * This occurs in the following construction:
- * .B
- * .br
- * .B
- * .br
- * I hate man macros.
- * Flat-out disallow this madness.
- */
- if (MAN_NSCOPED & man_macros[m->last->tok].flags)
- return(man_perr(m, ln, ppos, WLNSCOPE));
-
- n = m->last;
-
- assert(n);
- assert(NULL == n->child);
- assert(0 == n->nchild);
-
- if ( ! man_nwarn(m, n, WLNSCOPE))
- return(0);
-
- man_node_delete(m, n);
- m->flags &= ~MAN_ELINE;
- }
-
- /*
- * Save the fact that we're in the next-line for a block. In
- * this way, embedded roff instructions can "remember" state
- * when they exit.
- */
-
- if (MAN_BLINE & m->flags)
- m->flags |= MAN_BPLINE;
-
- /* Call to handler... */
-
- assert(man_macros[tok].fp);
- if ( ! (*man_macros[tok].fp)(m, tok, ln, ppos, &i, buf))
- goto err;
-
-out:
- /*
- * We weren't in a block-line scope when entering the
- * above-parsed macro, so return.
- */
-
- if ( ! (MAN_BPLINE & m->flags)) {
- m->flags &= ~MAN_ILINE;
- return(1);
- }
- m->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;
- return(1);
- }
-
- /*
- * If we've opened a new next-line element scope, then return
- * now, as the next line will close out the block scope.
- */
-
- if (MAN_ELINE & m->flags)
- return(1);
-
- /* Close out the block scope opened in the prior line. */
-
- assert(MAN_BLINE & m->flags);
- m->flags &= ~MAN_BLINE;
-
- if ( ! man_unscope(m, m->last->parent, WERRMAX))
- return(0);
- return(man_body_alloc(m, ln, 0, m->last->tok));
-
-err: /* Error out. */
-
- m->flags |= MAN_HALT;
- return(0);
-}
-
-
-int
-man_verr(struct man *man, int ln, int pos, const char *fmt, ...)
-{
- char buf[256];
- va_list ap;
-
- if (NULL == man->cb.man_err)
- return(0);
-
- va_start(ap, fmt);
- (void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
- va_end(ap);
- return((*man->cb.man_err)(man->data, ln, pos, buf));
-}
-
-
-int
-man_vwarn(struct man *man, int ln, int pos, const char *fmt, ...)
-{
- char buf[256];
- va_list ap;
-
- if (NULL == man->cb.man_warn)
- return(0);
-
- va_start(ap, fmt);
- (void)vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
- va_end(ap);
- return((*man->cb.man_warn)(man->data, ln, pos, buf));
-}
-
-
-int
-man_err(struct man *m, int line, int pos, int iserr, enum merr type)
-{
- const char *p;
-
- p = __man_merrnames[(int)type];
- assert(p);
-
- if (iserr)
- return(man_verr(m, line, pos, p));
-
- return(man_vwarn(m, line, pos, p));
-}
-
-
-/*
- * Unlink a node from its context. If "m" is provided, the last parse
- * point will also be adjusted accordingly.
- */
-static void
-man_node_unlink(struct man *m, struct man_node *n)
-{
-
- /* Adjust siblings. */
-
- if (n->prev)
- n->prev->next = n->next;
- if (n->next)
- n->next->prev = n->prev;
-
- /* Adjust parent. */
-
- if (n->parent) {
- n->parent->nchild--;
- if (n->parent->child == n)
- n->parent->child = n->prev ? n->prev : n->next;
- }
-
- /* Adjust parse point, if applicable. */
-
- if (m && m->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;
- } else {
- m->last = n->parent;
- m->next = MAN_NEXT_CHILD;
- }
- }
-
- if (m && m->first == n)
- m->first = NULL;
-}
+++ /dev/null
-/* $Id: man.h,v 1.27 2010/03/27 10:13:16 kristaps Exp $ */
-/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef MAN_H
-#define MAN_H
-
-#include <time.h>
-
-enum mant {
- MAN_br = 0,
- MAN_TH,
- MAN_SH,
- MAN_SS,
- MAN_TP,
- MAN_LP,
- MAN_PP,
- MAN_P,
- MAN_IP,
- MAN_HP,
- MAN_SM,
- MAN_SB,
- MAN_BI,
- MAN_IB,
- MAN_BR,
- MAN_RB,
- MAN_R,
- MAN_B,
- MAN_I,
- MAN_IR,
- MAN_RI,
- MAN_na,
- MAN_i,
- MAN_sp,
- MAN_nf,
- MAN_fi,
- MAN_r,
- MAN_RE,
- MAN_RS,
- MAN_DT,
- MAN_UC,
- MAN_PD,
- MAN_Sp,
- MAN_Vb,
- MAN_Ve,
- MAN_de,
- MAN_dei,
- MAN_am,
- MAN_ami,
- MAN_ig,
- MAN_dot,
- MAN_MAX
-};
-
-enum man_type {
- MAN_TEXT,
- MAN_ELEM,
- MAN_ROOT,
- MAN_BLOCK,
- MAN_HEAD,
- MAN_BODY
-};
-
-struct man_meta {
- int msec;
- time_t date;
- char *vol;
- char *title;
- char *source;
-};
-
-struct man_node {
- struct man_node *parent;
- struct man_node *child;
- struct man_node *next;
- struct man_node *prev;
- int nchild;
- int line;
- int pos;
- enum mant tok;
- int flags;
-#define MAN_VALID (1 << 0)
-#define MAN_ACTED (1 << 1)
- enum man_type type;
- char *string;
- struct man_node *head;
- struct man_node *body;
-};
-
-#define MAN_IGN_MACRO (1 << 0)
-#define MAN_IGN_CHARS (1 << 1)
-#define MAN_IGN_ESCAPE (1 << 2)
-
-extern const char *const *man_macronames;
-
-struct man_cb {
- int (*man_warn)(void *, int, int, const char *);
- int (*man_err)(void *, int, int, const char *);
-};
-
-__BEGIN_DECLS
-
-struct man;
-
-void man_free(struct man *);
-struct man *man_alloc(void *, int, const struct man_cb *);
-void man_reset(struct man *);
-int man_parseln(struct man *, int, char *buf);
-int man_endparse(struct man *);
-
-const struct man_node *man_node(const struct man *);
-const struct man_meta *man_meta(const struct man *);
-
-__END_DECLS
-
-#endif /*!MAN_H*/
+++ /dev/null
-/* $Id: man_action.c,v 1.30 2010/03/27 10:04:56 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libman.h"
-#include "libmandoc.h"
-
-struct actions {
- int (*post)(struct man *);
-};
-
-static int post_TH(struct man *);
-static int post_de(struct man *);
-static int post_fi(struct man *);
-static int post_nf(struct man *);
-
-const struct actions man_actions[MAN_MAX] = {
- { NULL }, /* br */
- { post_TH }, /* TH */
- { NULL }, /* SH */
- { NULL }, /* SS */
- { NULL }, /* TP */
- { NULL }, /* LP */
- { NULL }, /* PP */
- { NULL }, /* P */
- { NULL }, /* IP */
- { NULL }, /* HP */
- { NULL }, /* SM */
- { NULL }, /* SB */
- { NULL }, /* BI */
- { NULL }, /* IB */
- { NULL }, /* BR */
- { NULL }, /* RB */
- { NULL }, /* R */
- { NULL }, /* B */
- { NULL }, /* I */
- { NULL }, /* IR */
- { NULL }, /* RI */
- { NULL }, /* na */
- { NULL }, /* i */
- { NULL }, /* sp */
- { post_nf }, /* nf */
- { post_fi }, /* fi */
- { NULL }, /* r */
- { NULL }, /* RE */
- { NULL }, /* RS */
- { NULL }, /* DT */
- { NULL }, /* UC */
- { NULL }, /* PD */
- { NULL }, /* Sp */
- { post_nf }, /* Vb */
- { post_fi }, /* Ve */
- { post_de }, /* de */
- { post_de }, /* dei */
- { post_de }, /* am */
- { post_de }, /* ami */
- { post_de }, /* ig */
- { NULL }, /* . */
-};
-
-
-int
-man_action_post(struct man *m)
-{
-
- if (MAN_ACTED & m->last->flags)
- return(1);
- m->last->flags |= MAN_ACTED;
-
- switch (m->last->type) {
- case (MAN_TEXT):
- /* FALLTHROUGH */
- case (MAN_ROOT):
- return(1);
- default:
- break;
- }
-
- if (NULL == man_actions[m->last->tok].post)
- return(1);
- return((*man_actions[m->last->tok].post)(m));
-}
-
-
-static int
-post_fi(struct man *m)
-{
-
- if ( ! (MAN_LITERAL & m->flags))
- if ( ! man_nwarn(m, m->last, WNLITERAL))
- return(0);
- m->flags &= ~MAN_LITERAL;
- return(1);
-}
-
-
-static int
-post_de(struct man *m)
-{
-
- /*
- * XXX: for the time being, we indiscriminately remove roff
- * instructions from the parse stream.
- */
- if (MAN_BLOCK == m->last->type)
- man_node_delete(m, m->last);
- return(1);
-}
-
-
-static int
-post_nf(struct man *m)
-{
-
- if (MAN_LITERAL & m->flags)
- if ( ! man_nwarn(m, m->last, WOLITERAL))
- return(0);
- m->flags |= MAN_LITERAL;
- return(1);
-}
-
-
-static int
-post_TH(struct man *m)
-{
- struct man_node *n;
- char *ep;
- long lval;
-
- if (m->meta.title)
- free(m->meta.title);
- if (m->meta.vol)
- free(m->meta.vol);
- if (m->meta.source)
- free(m->meta.source);
-
- m->meta.title = m->meta.vol = m->meta.source = NULL;
- m->meta.msec = 0;
- m->meta.date = 0;
-
- /* ->TITLE<- MSEC DATE SOURCE VOL */
-
- n = m->last->child;
- assert(n);
- m->meta.title = mandoc_strdup(n->string);
-
- /* TITLE ->MSEC<- DATE SOURCE VOL */
-
- n = n->next;
- assert(n);
-
- lval = strtol(n->string, &ep, 10);
- if (n->string[0] != '\0' && *ep == '\0')
- m->meta.msec = (int)lval;
- else if ( ! man_nwarn(m, n, WMSEC))
- return(0);
-
- /* TITLE MSEC ->DATE<- SOURCE VOL */
-
- n = n->next;
- if (n) {
- m->meta.date = mandoc_a2time
- (MTIME_ISO_8601, n->string);
-
- if (0 == m->meta.date) {
- if ( ! man_nwarn(m, n, WDATE))
- return(0);
- m->meta.date = time(NULL);
- }
- } else
- m->meta.date = time(NULL);
-
- /* TITLE MSEC DATE ->SOURCE<- VOL */
-
- if (n && (n = n->next))
- m->meta.source = mandoc_strdup(n->string);
-
- /* TITLE MSEC DATE SOURCE ->VOL<- */
-
- if (n && (n = n->next))
- m->meta.vol = mandoc_strdup(n->string);
-
- /*
- * Remove the `TH' node after we've processed it for our
- * meta-data.
- */
- man_node_delete(m, m->last);
- return(1);
-}
+++ /dev/null
-/* $Id: man_argv.c,v 1.2 2010/01/01 17:14:28 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libman.h"
-
-
-int
-man_args(struct man *m, int line, int *pos, char *buf, char **v)
-{
-
- assert(*pos);
- assert(' ' != buf[*pos]);
-
- if (0 == buf[*pos])
- return(ARGS_EOLN);
-
- *v = &buf[*pos];
-
- /*
- * Process a quoted literal. A quote begins with a double-quote
- * and ends with a double-quote NOT preceded by a double-quote.
- * Whitespace is NOT involved in literal termination.
- */
-
- if ('\"' == buf[*pos]) {
- *v = &buf[++(*pos)];
-
- for ( ; buf[*pos]; (*pos)++) {
- if ('\"' != buf[*pos])
- continue;
- if ('\"' != buf[*pos + 1])
- break;
- (*pos)++;
- }
-
- if (0 == buf[*pos]) {
- if ( ! man_pwarn(m, line, *pos, WTQUOTE))
- return(ARGS_ERROR);
- return(ARGS_QWORD);
- }
-
- buf[(*pos)++] = 0;
-
- if (0 == buf[*pos])
- return(ARGS_QWORD);
-
- while (' ' == buf[*pos])
- (*pos)++;
-
- if (0 == buf[*pos])
- if ( ! man_pwarn(m, line, *pos, WTSPACE))
- return(ARGS_ERROR);
-
- return(ARGS_QWORD);
- }
-
- /*
- * A non-quoted term progresses until either the end of line or
- * a non-escaped whitespace.
- */
-
- for ( ; buf[*pos]; (*pos)++)
- if (' ' == buf[*pos] && '\\' != buf[*pos - 1])
- break;
-
- if (0 == buf[*pos])
- return(ARGS_WORD);
-
- buf[(*pos)++] = 0;
-
- while (' ' == buf[*pos])
- (*pos)++;
-
- if (0 == buf[*pos])
- if ( ! man_pwarn(m, line, *pos, WTSPACE))
- return(ARGS_ERROR);
-
- return(ARGS_WORD);
-}
+++ /dev/null
-/* $Id: man_hash.c,v 1.18 2010/03/27 10:14:32 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libman.h"
-
-#define HASH_DEPTH 6
-
-#define HASH_ROW(x) do { \
- if ('.' == (x)) \
- (x) = 26; \
- else if (isupper((u_char)(x))) \
- (x) -= 65; \
- else \
- (x) -= 97; \
- (x) *= HASH_DEPTH; \
- } while (/* CONSTCOND */ 0)
-
-/*
- * Lookup table is indexed first by lower-case first letter (plus one
- * for the period, which is stored in the last row), then by lower or
- * uppercase second letter. Buckets correspond to the index of the
- * macro (the integer value of the enum stored as a char to save a bit
- * of space).
- */
-static u_char table[27 * HASH_DEPTH];
-
-/*
- * XXX - this hash has global scope, so if intended for use as a library
- * with multiple callers, it will need re-invocation protection.
- */
-void
-man_hash_init(void)
-{
- int i, j, x;
-
- memset(table, UCHAR_MAX, sizeof(table));
-
- assert(/* LINTED */
- MAN_MAX < UCHAR_MAX);
-
- for (i = 0; i < MAN_MAX; i++) {
- x = man_macronames[i][0];
-
- assert(isalpha((u_char)x) || '.' == x);
-
- HASH_ROW(x);
-
- for (j = 0; j < HASH_DEPTH; j++)
- if (UCHAR_MAX == table[x + j]) {
- table[x + j] = (u_char)i;
- break;
- }
-
- assert(j < HASH_DEPTH);
- }
-}
-
-
-enum mant
-man_hash_find(const char *tmp)
-{
- int x, y, i;
- enum mant tok;
-
- if ('\0' == (x = tmp[0]))
- return(MAN_MAX);
- if ( ! (isalpha((u_char)x) || '.' == x))
- return(MAN_MAX);
-
- HASH_ROW(x);
-
- for (i = 0; i < HASH_DEPTH; i++) {
- if (UCHAR_MAX == (y = table[x + i]))
- return(MAN_MAX);
-
- tok = (enum mant)y;
- if (0 == strcmp(tmp, man_macronames[tok]))
- return(tok);
- }
-
- return(MAN_MAX);
-}
+++ /dev/null
-/* $Id: man_html.c,v 1.30 2010/03/24 20:10:53 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "out.h"
-#include "html.h"
-#include "man.h"
-#include "main.h"
-
-/* TODO: preserve ident widths. */
-/* FIXME: have PD set the default vspace width. */
-
-#define INDENT 5
-#define HALFINDENT 3
-
-#define MAN_ARGS const struct man_meta *m, \
- const struct man_node *n, \
- struct html *h
-
-struct htmlman {
- int (*pre)(MAN_ARGS);
- int (*post)(MAN_ARGS);
-};
-
-static void print_man(MAN_ARGS);
-static void print_man_head(MAN_ARGS);
-static void print_man_nodelist(MAN_ARGS);
-static void print_man_node(MAN_ARGS);
-
-static int a2width(const struct man_node *,
- struct roffsu *);
-
-static int man_alt_pre(MAN_ARGS);
-static int man_br_pre(MAN_ARGS);
-static int man_ign_pre(MAN_ARGS);
-static void man_root_post(MAN_ARGS);
-static int man_root_pre(MAN_ARGS);
-static int man_B_pre(MAN_ARGS);
-static int man_HP_pre(MAN_ARGS);
-static int man_I_pre(MAN_ARGS);
-static int man_IP_pre(MAN_ARGS);
-static int man_PP_pre(MAN_ARGS);
-static int man_RS_pre(MAN_ARGS);
-static int man_SB_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 const struct htmlman mans[MAN_MAX] = {
- { man_br_pre, NULL }, /* br */
- { NULL, NULL }, /* TH */
- { man_SH_pre, NULL }, /* SH */
- { man_SS_pre, NULL }, /* SS */
- { man_IP_pre, NULL }, /* TP */
- { man_PP_pre, NULL }, /* LP */
- { man_PP_pre, NULL }, /* PP */
- { man_PP_pre, NULL }, /* P */
- { man_IP_pre, NULL }, /* IP */
- { man_HP_pre, NULL }, /* HP */
- { man_SM_pre, NULL }, /* SM */
- { man_SB_pre, NULL }, /* SB */
- { man_alt_pre, NULL }, /* BI */
- { man_alt_pre, NULL }, /* IB */
- { man_alt_pre, NULL }, /* BR */
- { man_alt_pre, NULL }, /* RB */
- { NULL, NULL }, /* R */
- { man_B_pre, NULL }, /* B */
- { man_I_pre, NULL }, /* I */
- { man_alt_pre, NULL }, /* IR */
- { man_alt_pre, NULL }, /* RI */
- { NULL, NULL }, /* na */
- { NULL, NULL }, /* i */
- { man_br_pre, NULL }, /* sp */
- { NULL, NULL }, /* nf */
- { NULL, NULL }, /* fi */
- { NULL, NULL }, /* r */
- { NULL, NULL }, /* RE */
- { man_RS_pre, NULL }, /* RS */
- { man_ign_pre, NULL }, /* DT */
- { man_ign_pre, NULL }, /* UC */
- { man_ign_pre, NULL }, /* PD */
- { man_br_pre, NULL }, /* Sp */
- { man_ign_pre, NULL }, /* Vb */
- { NULL, NULL }, /* Ve */
- { man_ign_pre, NULL }, /* de */
- { man_ign_pre, NULL }, /* dei */
- { man_ign_pre, NULL }, /* am */
- { man_ign_pre, NULL }, /* ami */
- { man_ign_pre, NULL }, /* ig */
- { NULL, NULL }, /* . */
-};
-
-
-void
-html_man(void *arg, const struct man *m)
-{
- struct html *h;
- struct tag *t;
-
- h = (struct html *)arg;
-
- print_gen_decls(h);
-
- t = print_otag(h, TAG_HTML, 0, NULL);
- print_man(man_meta(m), man_node(m), h);
- print_tagq(h, t);
-
- printf("\n");
-}
-
-
-static void
-print_man(MAN_ARGS)
-{
- struct tag *t;
- struct htmlpair tag;
-
- t = print_otag(h, TAG_HEAD, 0, NULL);
-
- print_man_head(m, n, h);
- print_tagq(h, t);
- t = print_otag(h, TAG_BODY, 0, NULL);
-
- tag.key = ATTR_CLASS;
- tag.val = "body";
- print_otag(h, TAG_DIV, 1, &tag);
-
- print_man_nodelist(m, n, h);
-
- print_tagq(h, t);
-}
-
-
-/* ARGSUSED */
-static void
-print_man_head(MAN_ARGS)
-{
-
- print_gen_head(h);
- bufinit(h);
- buffmt(h, "%s(%d)", m->title, m->msec);
-
- print_otag(h, TAG_TITLE, 0, NULL);
- print_text(h, h->buf);
-}
-
-
-static void
-print_man_nodelist(MAN_ARGS)
-{
-
- print_man_node(m, n, h);
- if (n->next)
- print_man_nodelist(m, n->next, h);
-}
-
-
-static void
-print_man_node(MAN_ARGS)
-{
- int child;
- struct tag *t;
-
- child = 1;
- t = h->tags.head;
-
- bufinit(h);
-
- /*
- * FIXME: embedded elements within next-line scopes (e.g., `br'
- * within an empty `B') will cause formatting to be forgotten
- * due to scope closing out.
- */
-
- switch (n->type) {
- case (MAN_ROOT):
- child = man_root_pre(m, n, h);
- break;
- case (MAN_TEXT):
- print_text(h, n->string);
- return;
- default:
- /*
- * Close out scope of font prior to opening a macro
- * scope. Assert that the metafont is on the top of the
- * stack (it's never nested).
- */
- if (h->metaf) {
- assert(h->metaf == t);
- print_tagq(h, h->metaf);
- assert(NULL == h->metaf);
- t = h->tags.head;
- }
- if (mans[n->tok].pre)
- child = (*mans[n->tok].pre)(m, n, h);
- break;
- }
-
- if (child && n->child)
- print_man_nodelist(m, n->child, h);
-
- /* This will automatically close out any font scope. */
- print_stagq(h, t);
-
- bufinit(h);
-
- switch (n->type) {
- case (MAN_ROOT):
- man_root_post(m, n, h);
- break;
- case (MAN_TEXT):
- break;
- default:
- if (mans[n->tok].post)
- (*mans[n->tok].post)(m, n, h);
- break;
- }
-}
-
-
-static int
-a2width(const struct man_node *n, struct roffsu *su)
-{
-
- if (MAN_TEXT != n->type)
- return(0);
- if (a2roffsu(n->string, su, SCALE_BU))
- return(1);
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-man_root_pre(MAN_ARGS)
-{
- struct htmlpair tag[3];
- struct tag *t, *tt;
- char b[BUFSIZ], title[BUFSIZ];
-
- b[0] = 0;
- if (m->vol)
- (void)strlcat(b, m->vol, BUFSIZ);
-
- snprintf(title, BUFSIZ - 1, "%s(%d)", m->title, m->msec);
-
- PAIR_CLASS_INIT(&tag[0], "header");
- bufcat_style(h, "width", "100%");
- PAIR_STYLE_INIT(&tag[1], h);
- PAIR_SUMMARY_INIT(&tag[2], "header");
-
- t = print_otag(h, TAG_TABLE, 3, tag);
- tt = print_otag(h, TAG_TR, 0, NULL);
-
- bufinit(h);
- bufcat_style(h, "width", "10%");
- PAIR_STYLE_INIT(&tag[0], h);
- print_otag(h, TAG_TD, 1, tag);
- print_text(h, title);
- print_stagq(h, tt);
-
- bufinit(h);
- bufcat_style(h, "width", "80%");
- bufcat_style(h, "white-space", "nowrap");
- bufcat_style(h, "text-align", "center");
- PAIR_STYLE_INIT(&tag[0], h);
- print_otag(h, TAG_TD, 1, tag);
- print_text(h, b);
- print_stagq(h, tt);
-
- bufinit(h);
- bufcat_style(h, "width", "10%");
- bufcat_style(h, "text-align", "right");
- PAIR_STYLE_INIT(&tag[0], h);
- print_otag(h, TAG_TD, 1, tag);
- print_text(h, title);
- print_tagq(h, t);
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-man_root_post(MAN_ARGS)
-{
- struct htmlpair tag[3];
- struct tag *t, *tt;
- char b[DATESIZ];
-
- time2a(m->date, b, DATESIZ);
-
- PAIR_CLASS_INIT(&tag[0], "footer");
- bufcat_style(h, "width", "100%");
- PAIR_STYLE_INIT(&tag[1], h);
- PAIR_SUMMARY_INIT(&tag[2], "footer");
-
- t = print_otag(h, TAG_TABLE, 3, tag);
- tt = print_otag(h, TAG_TR, 0, NULL);
-
- bufinit(h);
- bufcat_style(h, "width", "50%");
- PAIR_STYLE_INIT(&tag[0], h);
- print_otag(h, TAG_TD, 1, tag);
- print_text(h, b);
- print_stagq(h, tt);
-
- bufinit(h);
- bufcat_style(h, "width", "50%");
- bufcat_style(h, "text-align", "right");
- PAIR_STYLE_INIT(&tag[0], h);
- print_otag(h, TAG_TD, 1, tag);
- if (m->source)
- print_text(h, m->source);
- print_tagq(h, t);
-}
-
-
-
-/* ARGSUSED */
-static int
-man_br_pre(MAN_ARGS)
-{
- struct roffsu su;
- struct htmlpair tag;
-
- SCALE_VS_INIT(&su, 1);
-
- switch (n->tok) {
- case (MAN_Sp):
- SCALE_VS_INIT(&su, 0.5);
- break;
- case (MAN_sp):
- if (n->child)
- a2roffsu(n->child->string, &su, SCALE_VS);
- break;
- default:
- su.scale = 0;
- break;
- }
-
- bufcat_su(h, "height", &su);
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, 1, &tag);
-
- /* So the div isn't empty: */
- print_text(h, "\\~");
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-man_SH_pre(MAN_ARGS)
-{
- struct htmlpair tag[2];
- struct roffsu su;
-
- if (MAN_BODY == n->type) {
- SCALE_HS_INIT(&su, INDENT);
- bufcat_su(h, "margin-left", &su);
- PAIR_CLASS_INIT(&tag[0], "sec-body");
- PAIR_STYLE_INIT(&tag[1], h);
- print_otag(h, TAG_DIV, 2, tag);
- return(1);
- } else if (MAN_BLOCK == n->type) {
- PAIR_CLASS_INIT(&tag[0], "sec-block");
- if (n->prev && MAN_SH == n->prev->tok)
- if (NULL == n->prev->body->child) {
- print_otag(h, TAG_DIV, 1, tag);
- return(1);
- }
-
- SCALE_VS_INIT(&su, 1);
- bufcat_su(h, "margin-top", &su);
- if (NULL == n->next)
- bufcat_su(h, "margin-bottom", &su);
- PAIR_STYLE_INIT(&tag[1], h);
- print_otag(h, TAG_DIV, 2, tag);
- return(1);
- }
-
- PAIR_CLASS_INIT(&tag[0], "sec-head");
- print_otag(h, TAG_DIV, 1, tag);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_alt_pre(MAN_ARGS)
-{
- const struct man_node *nn;
- struct tag *t;
- int i;
- enum htmlfont fp;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
- switch (n->tok) {
- case (MAN_BI):
- fp = i % 2 ? HTMLFONT_ITALIC : HTMLFONT_BOLD;
- break;
- case (MAN_IB):
- fp = i % 2 ? HTMLFONT_BOLD : HTMLFONT_ITALIC;
- break;
- case (MAN_RI):
- fp = i % 2 ? HTMLFONT_ITALIC : HTMLFONT_NONE;
- break;
- case (MAN_IR):
- fp = i % 2 ? HTMLFONT_NONE : HTMLFONT_ITALIC;
- break;
- case (MAN_BR):
- fp = i % 2 ? HTMLFONT_NONE : HTMLFONT_BOLD;
- break;
- case (MAN_RB):
- fp = i % 2 ? HTMLFONT_BOLD : HTMLFONT_NONE;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- if (i)
- h->flags |= HTML_NOSPACE;
-
- /*
- * Open and close the scope with each argument, so that
- * internal \f escapes, which are common, are also
- * closed out with the scope.
- */
- t = print_ofont(h, fp);
- print_man_node(m, nn, h);
- print_tagq(h, t);
- }
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-man_SB_pre(MAN_ARGS)
-{
- struct htmlpair tag;
-
- /* FIXME: print_ofont(). */
- PAIR_CLASS_INIT(&tag, "small bold");
- print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_SM_pre(MAN_ARGS)
-{
- struct htmlpair tag;
-
- PAIR_CLASS_INIT(&tag, "small");
- print_otag(h, TAG_SPAN, 1, &tag);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_SS_pre(MAN_ARGS)
-{
- struct htmlpair tag[3];
- struct roffsu su;
-
- SCALE_VS_INIT(&su, 1);
-
- if (MAN_BODY == n->type) {
- PAIR_CLASS_INIT(&tag[0], "ssec-body");
- if (n->parent->next && n->child) {
- bufcat_su(h, "margin-bottom", &su);
- PAIR_STYLE_INIT(&tag[1], h);
- print_otag(h, TAG_DIV, 2, tag);
- return(1);
- }
-
- print_otag(h, TAG_DIV, 1, tag);
- return(1);
- } else if (MAN_BLOCK == n->type) {
- PAIR_CLASS_INIT(&tag[0], "ssec-block");
- if (n->prev && MAN_SS == n->prev->tok)
- if (n->prev->body->child) {
- bufcat_su(h, "margin-top", &su);
- PAIR_STYLE_INIT(&tag[1], h);
- print_otag(h, TAG_DIV, 2, tag);
- return(1);
- }
-
- print_otag(h, TAG_DIV, 1, tag);
- return(1);
- }
-
- SCALE_HS_INIT(&su, INDENT - HALFINDENT);
- bufcat_su(h, "margin-left", &su);
- PAIR_CLASS_INIT(&tag[0], "ssec-head");
- PAIR_STYLE_INIT(&tag[1], h);
- print_otag(h, TAG_DIV, 2, tag);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_PP_pre(MAN_ARGS)
-{
- struct htmlpair tag;
- struct roffsu su;
- int i;
-
- if (MAN_BLOCK != n->type)
- return(1);
-
- i = 0;
-
- if (MAN_ROOT == n->parent->type) {
- SCALE_HS_INIT(&su, INDENT);
- bufcat_su(h, "margin-left", &su);
- i = 1;
- }
- if (n->prev) {
- SCALE_VS_INIT(&su, 1);
- bufcat_su(h, "margin-top", &su);
- i = 1;
- }
-
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, i, &tag);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_IP_pre(MAN_ARGS)
-{
- struct roffsu su;
- struct htmlpair tag;
- const struct man_node *nn;
- int width;
-
- /*
- * This scattering of 1-BU margins and pads is to make sure that
- * when text overruns its box, the subsequent text isn't flush
- * up against it. However, the rest of the right-hand box must
- * also be adjusted in consideration of this 1-BU space.
- */
-
- if (MAN_BODY == n->type) {
- SCALE_HS_INIT(&su, INDENT);
- bufcat_su(h, "margin-left", &su);
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, 1, &tag);
- return(1);
- }
-
- nn = MAN_BLOCK == n->type ?
- n->head->child : n->parent->head->child;
-
- SCALE_HS_INIT(&su, INDENT);
- width = 0;
-
- /* Width is the last token. */
-
- if (MAN_IP == n->tok && NULL != nn)
- if (NULL != (nn = nn->next)) {
- for ( ; nn->next; nn = nn->next)
- /* Do nothing. */ ;
- width = a2width(nn, &su);
- }
-
- /* Width is the first token. */
-
- if (MAN_TP == n->tok && NULL != nn) {
- /* Skip past non-text children. */
- while (nn && MAN_TEXT != nn->type)
- nn = nn->next;
- if (nn)
- width = a2width(nn, &su);
- }
-
- if (MAN_BLOCK == n->type) {
- bufcat_su(h, "margin-left", &su);
- SCALE_VS_INIT(&su, 1);
- bufcat_su(h, "margin-top", &su);
- bufcat_style(h, "clear", "both");
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, 1, &tag);
- return(1);
- }
-
- bufcat_su(h, "min-width", &su);
- SCALE_INVERT(&su);
- bufcat_su(h, "margin-left", &su);
- SCALE_HS_INIT(&su, 1);
- bufcat_su(h, "margin-right", &su);
- bufcat_style(h, "clear", "left");
-
- if (n->next && n->next->child)
- bufcat_style(h, "float", "left");
-
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, 1, &tag);
-
- /*
- * Without a length string, we can print all of our children.
- */
-
- if ( ! width)
- return(1);
-
- /*
- * When a length has been specified, we need to carefully print
- * our child context: IP gets all children printed but the last
- * (the width), while TP gets all children printed but the first
- * (the width).
- */
-
- if (MAN_IP == n->tok)
- for (nn = n->child; nn->next; nn = nn->next)
- print_man_node(m, nn, h);
- if (MAN_TP == n->tok)
- for (nn = n->child->next; nn; nn = nn->next)
- print_man_node(m, nn, h);
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-man_HP_pre(MAN_ARGS)
-{
- const struct man_node *nn;
- struct htmlpair tag;
- struct roffsu su;
-
- if (MAN_HEAD == n->type)
- return(0);
-
- nn = MAN_BLOCK == n->type ?
- n->head->child : n->parent->head->child;
-
- SCALE_HS_INIT(&su, INDENT);
-
- if (NULL != nn)
- (void)a2width(nn, &su);
-
- if (MAN_BLOCK == n->type) {
- bufcat_su(h, "margin-left", &su);
- SCALE_VS_INIT(&su, 1);
- bufcat_su(h, "margin-top", &su);
- bufcat_style(h, "clear", "both");
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, 1, &tag);
- return(1);
- }
-
- bufcat_su(h, "margin-left", &su);
- SCALE_INVERT(&su);
- bufcat_su(h, "text-indent", &su);
-
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, 1, &tag);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_B_pre(MAN_ARGS)
-{
-
- print_ofont(h, HTMLFONT_BOLD);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_I_pre(MAN_ARGS)
-{
-
- print_ofont(h, HTMLFONT_ITALIC);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-man_ign_pre(MAN_ARGS)
-{
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-man_RS_pre(MAN_ARGS)
-{
- struct htmlpair tag;
- struct roffsu su;
-
- if (MAN_HEAD == n->type)
- return(0);
- else if (MAN_BODY == n->type)
- return(1);
-
- SCALE_HS_INIT(&su, INDENT);
- bufcat_su(h, "margin-left", &su);
-
- if (n->head->child) {
- SCALE_VS_INIT(&su, 1);
- a2width(n->head->child, &su);
- bufcat_su(h, "margin-top", &su);
- }
-
- PAIR_STYLE_INIT(&tag, h);
- print_otag(h, TAG_DIV, 1, &tag);
- return(1);
-}
+++ /dev/null
-/* $Id: man_macro.c,v 1.42 2010/03/29 10:10:35 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <assert.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libman.h"
-
-enum rew {
- REW_REWIND,
- REW_NOHALT,
- REW_HALT
-};
-
-static int blk_close(MACRO_PROT_ARGS);
-static int blk_dotted(MACRO_PROT_ARGS);
-static int blk_exp(MACRO_PROT_ARGS);
-static int blk_imp(MACRO_PROT_ARGS);
-static int in_line_eoln(MACRO_PROT_ARGS);
-
-static int rew_scope(enum man_type,
- struct man *, enum mant);
-static enum rew rew_dohalt(enum mant, enum man_type,
- const struct man_node *);
-static enum rew rew_block(enum mant, enum man_type,
- const struct man_node *);
-static int rew_warn(struct man *,
- struct man_node *, enum merr);
-
-const struct man_macro __man_macros[MAN_MAX] = {
- { in_line_eoln, MAN_NSCOPED }, /* br */
- { in_line_eoln, 0 }, /* TH */
- { blk_imp, MAN_SCOPED }, /* SH */
- { blk_imp, MAN_SCOPED }, /* SS */
- { blk_imp, MAN_SCOPED | MAN_FSCOPED }, /* TP */
- { blk_imp, 0 }, /* LP */
- { blk_imp, 0 }, /* PP */
- { blk_imp, 0 }, /* P */
- { blk_imp, 0 }, /* IP */
- { blk_imp, 0 }, /* HP */
- { in_line_eoln, MAN_SCOPED }, /* SM */
- { in_line_eoln, MAN_SCOPED }, /* SB */
- { in_line_eoln, 0 }, /* BI */
- { in_line_eoln, 0 }, /* IB */
- { in_line_eoln, 0 }, /* BR */
- { in_line_eoln, 0 }, /* RB */
- { in_line_eoln, MAN_SCOPED }, /* R */
- { in_line_eoln, MAN_SCOPED }, /* B */
- { in_line_eoln, MAN_SCOPED }, /* I */
- { in_line_eoln, 0 }, /* IR */
- { in_line_eoln, 0 }, /* RI */
- { in_line_eoln, MAN_NSCOPED }, /* na */
- { in_line_eoln, 0 }, /* i */
- { in_line_eoln, MAN_NSCOPED }, /* sp */
- { in_line_eoln, 0 }, /* nf */
- { in_line_eoln, 0 }, /* fi */
- { in_line_eoln, 0 }, /* r */
- { blk_close, 0 }, /* RE */
- { blk_exp, MAN_EXPLICIT }, /* RS */
- { in_line_eoln, 0 }, /* DT */
- { in_line_eoln, 0 }, /* UC */
- { in_line_eoln, 0 }, /* PD */
- { in_line_eoln, MAN_NSCOPED }, /* Sp */
- { in_line_eoln, 0 }, /* Vb */
- { in_line_eoln, 0 }, /* Ve */
- { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* de */
- { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* dei */
- { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* am */
- { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ami */
- { blk_exp, MAN_EXPLICIT | MAN_NOCLOSE}, /* ig */
- { blk_dotted, 0 }, /* . */
-};
-
-const struct man_macro * const man_macros = __man_macros;
-
-
-/*
- * Warn when "n" is an explicit non-roff macro.
- */
-static int
-rew_warn(struct man *m, struct man_node *n, enum merr er)
-{
-
- if (er == WERRMAX || MAN_BLOCK != n->type)
- return(1);
- if (MAN_VALID & n->flags)
- return(1);
- if ( ! (MAN_EXPLICIT & man_macros[n->tok].flags))
- return(1);
- if (MAN_NOCLOSE & man_macros[n->tok].flags)
- return(1);
- return(man_nwarn(m, n, er));
-}
-
-
-/*
- * Rewind scope. If a code "er" != WERRMAX has been provided, it will
- * be used if an explicit block scope is being closed out.
- */
-int
-man_unscope(struct man *m, const struct man_node *n, enum merr er)
-{
-
- assert(n);
-
- /* LINTED */
- while (m->last != n) {
- if ( ! rew_warn(m, m->last, er))
- return(0);
- if ( ! man_valid_post(m))
- return(0);
- if ( ! man_action_post(m))
- return(0);
- m->last = m->last->parent;
- assert(m->last);
- }
-
- if ( ! rew_warn(m, m->last, er))
- return(0);
- if ( ! man_valid_post(m))
- return(0);
- if ( ! man_action_post(m))
- return(0);
-
- m->next = MAN_ROOT == m->last->type ?
- MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
-
- return(1);
-}
-
-
-static enum rew
-rew_block(enum mant ntok, enum man_type type, const struct man_node *n)
-{
-
- if (MAN_BLOCK == type && ntok == n->parent->tok &&
- MAN_BODY == n->parent->type)
- return(REW_REWIND);
- return(ntok == n->tok ? REW_HALT : REW_NOHALT);
-}
-
-
-/*
- * There are three scope levels: scoped to the root (all), scoped to the
- * section (all less sections), and scoped to subsections (all less
- * sections and subsections).
- */
-static enum rew
-rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
-{
- enum rew c;
-
- /* We cannot progress beyond the root ever. */
- if (MAN_ROOT == n->type)
- return(REW_HALT);
-
- assert(n->parent);
-
- /* Normal nodes shouldn't go to the level of the root. */
- if (MAN_ROOT == n->parent->type)
- return(REW_REWIND);
-
- /* Already-validated nodes should be closed out. */
- if (MAN_VALID & n->flags)
- return(REW_NOHALT);
-
- /* First: rewind to ourselves. */
- if (type == n->type && tok == n->tok)
- return(REW_REWIND);
-
- /*
- * If we're a roff macro, then we can close out anything that
- * stands between us and our parent context.
- */
- if (MAN_NOCLOSE & man_macros[tok].flags)
- return(REW_NOHALT);
-
- /*
- * Don't clobber roff macros: this is a bit complicated. If the
- * current macro is a roff macro, halt immediately and don't
- * rewind. If it's not, and the parent is, then close out the
- * current scope and halt at the parent.
- */
- if (MAN_NOCLOSE & man_macros[n->tok].flags)
- return(REW_HALT);
- if (MAN_NOCLOSE & man_macros[n->parent->tok].flags)
- return(REW_REWIND);
-
- /*
- * Next follow the implicit scope-smashings as defined by man.7:
- * section, sub-section, etc.
- */
-
- switch (tok) {
- case (MAN_SH):
- break;
- case (MAN_SS):
- /* Rewind to a section, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
- return(c);
- break;
- case (MAN_RS):
- /* Rewind to a subsection, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
- return(c);
- /* Rewind to a section, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
- return(c);
- break;
- default:
- /* Rewind to an offsetter, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_RS, type, n)))
- return(c);
- /* Rewind to a subsection, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
- return(c);
- /* Rewind to a section, if a block. */
- if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
- return(c);
- break;
- }
-
- return(REW_NOHALT);
-}
-
-
-/*
- * Rewinding entails ascending the parse tree until a coherent point,
- * for example, the `SH' macro will close out any intervening `SS'
- * 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)
-{
- struct man_node *n;
- enum rew c;
-
- /* LINTED */
- for (n = m->last; n; n = n->parent) {
- /*
- * Whether we should stop immediately (REW_HALT), stop
- * and rewind until this point (REW_REWIND), or keep
- * rewinding (REW_NOHALT).
- */
- c = rew_dohalt(tok, type, n);
- if (REW_HALT == c)
- return(1);
- if (REW_REWIND == c)
- break;
- }
-
- /*
- * Rewind until the current point. Warn if we're a roff
- * instruction that's mowing over explicit scopes.
- */
- assert(n);
- if (MAN_NOCLOSE & man_macros[tok].flags)
- return(man_unscope(m, n, WROFFSCOPE));
-
- return(man_unscope(m, n, WERRMAX));
-}
-
-
-/*
- * Closure for dotted macros (de, dei, am, ami, ign). This must handle
- * any of these as the parent node, so it needs special handling.
- * Beyond this, it's the same as blk_close().
- */
-/* ARGSUSED */
-int
-blk_dotted(MACRO_PROT_ARGS)
-{
- enum mant ntok;
- struct man_node *nn;
-
- /* Check for any of the following parents... */
-
- for (nn = m->last->parent; nn; nn = nn->parent)
- if (nn->tok == MAN_de || nn->tok == MAN_dei ||
- nn->tok == MAN_am ||
- nn->tok == MAN_ami ||
- nn->tok == MAN_ig) {
- ntok = nn->tok;
- break;
- }
-
- if (NULL == nn) {
- if ( ! man_pwarn(m, line, ppos, WNOSCOPE))
- return(0);
- return(1);
- }
-
- if ( ! rew_scope(MAN_BODY, m, ntok))
- return(0);
- if ( ! rew_scope(MAN_BLOCK, m, ntok))
- return(0);
-
- /*
- * Restore flags set when we got here and also stipulate that we
- * don't post-process the line when exiting the macro op
- * function in man_pmacro(). See blk_exp().
- */
-
- m->flags = m->svflags | MAN_ILINE;
- m->next = m->svnext;
- return(1);
-}
-
-
-/*
- * Close out a generic explicit macro.
- */
-/* ARGSUSED */
-int
-blk_close(MACRO_PROT_ARGS)
-{
- enum mant ntok;
- const struct man_node *nn;
-
- switch (tok) {
- case (MAN_RE):
- ntok = MAN_RS;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- for (nn = m->last->parent; nn; nn = nn->parent)
- if (ntok == nn->tok)
- break;
-
- if (NULL == nn)
- if ( ! man_pwarn(m, line, ppos, WNOSCOPE))
- return(0);
-
- if ( ! rew_scope(MAN_BODY, m, ntok))
- return(0);
- if ( ! rew_scope(MAN_BLOCK, m, ntok))
- return(0);
-
- return(1);
-}
-
-
-int
-blk_exp(MACRO_PROT_ARGS)
-{
- int w, la;
- char *p;
-
- /*
- * Close out prior scopes. "Regular" explicit macros cannot be
- * nested, but we allow roff macros to be placed just about
- * anywhere.
- */
-
- if ( ! (MAN_NOCLOSE & man_macros[tok].flags)) {
- if ( ! rew_scope(MAN_BODY, m, tok))
- return(0);
- if ( ! rew_scope(MAN_BLOCK, m, tok))
- return(0);
- } else {
- /*
- * Save our state and next-scope indicator; we restore
- * it when exiting from the roff instruction block. See
- * blk_dotted().
- */
- m->svflags = m->flags;
- m->svnext = m->next;
-
- /* Make sure we drop any line modes. */
- m->flags = 0;
- }
-
- if ( ! man_block_alloc(m, line, ppos, tok))
- return(0);
- if ( ! man_head_alloc(m, line, ppos, tok))
- return(0);
-
- for (;;) {
- la = *pos;
- w = man_args(m, line, pos, buf, &p);
-
- if (-1 == w)
- return(0);
- if (0 == w)
- break;
-
- if ( ! man_word_alloc(m, line, la, p))
- return(0);
- }
-
- assert(m);
- assert(tok != MAN_MAX);
-
- if ( ! rew_scope(MAN_HEAD, m, tok))
- return(0);
- return(man_body_alloc(m, line, ppos, tok));
-}
-
-
-
-/*
- * Parse an implicit-block macro. These contain a MAN_HEAD and a
- * MAN_BODY contained within a MAN_BLOCK. Rules for closing out other
- * scopes, such as `SH' closing out an `SS', are defined in the rew
- * routines.
- */
-int
-blk_imp(MACRO_PROT_ARGS)
-{
- int w, la;
- char *p;
- struct man_node *n;
-
- /* Close out prior scopes. */
-
- if ( ! rew_scope(MAN_BODY, m, tok))
- return(0);
- if ( ! rew_scope(MAN_BLOCK, m, tok))
- return(0);
-
- /* Allocate new block & head scope. */
-
- if ( ! man_block_alloc(m, line, ppos, tok))
- return(0);
- if ( ! man_head_alloc(m, line, ppos, tok))
- return(0);
-
- n = m->last;
-
- /* Add line arguments. */
-
- for (;;) {
- la = *pos;
- w = man_args(m, line, pos, buf, &p);
-
- if (-1 == w)
- return(0);
- if (0 == w)
- break;
-
- if ( ! man_word_alloc(m, line, la, p))
- return(0);
- }
-
- /* Close out head and open body (unless MAN_SCOPE). */
-
- 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;
- return(1);
- } else if (n == m->last) {
- m->flags |= MAN_BLINE;
- return(1);
- }
- }
-
- if ( ! rew_scope(MAN_HEAD, m, tok))
- return(0);
- return(man_body_alloc(m, line, ppos, tok));
-}
-
-
-int
-in_line_eoln(MACRO_PROT_ARGS)
-{
- int w, la;
- char *p;
- struct man_node *n;
-
- if ( ! man_elem_alloc(m, line, ppos, tok))
- return(0);
-
- n = m->last;
-
- for (;;) {
- la = *pos;
- w = man_args(m, line, pos, buf, &p);
-
- if (-1 == w)
- return(0);
- if (0 == w)
- break;
- if ( ! man_word_alloc(m, line, la, p))
- return(0);
- }
-
- /*
- * 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) {
- assert( ! (MAN_NSCOPED & man_macros[tok].flags));
- m->flags |= MAN_ELINE;
- return(1);
- }
-
- /* Set ignorable context, if applicable. */
-
- if (MAN_NSCOPED & man_macros[tok].flags) {
- assert( ! (MAN_SCOPED & man_macros[tok].flags));
- m->flags |= MAN_ILINE;
- }
-
- /*
- * Rewind our element scope. Note that when TH is pruned, we'll
- * be back at the root, so make sure that we don't clobber as
- * its sibling.
- */
-
- for ( ; m->last; m->last = m->last->parent) {
- if (m->last == n)
- break;
- if (m->last->type == MAN_ROOT)
- break;
- if ( ! man_valid_post(m))
- return(0);
- if ( ! man_action_post(m))
- return(0);
- }
-
- assert(m->last);
-
- /*
- * Same here regarding whether we're back at the root.
- */
-
- if (m->last->type != MAN_ROOT && ! man_valid_post(m))
- return(0);
- if (m->last->type != MAN_ROOT && ! man_action_post(m))
- return(0);
-
- m->next = MAN_ROOT == m->last->type ?
- MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
-
- return(1);
-}
-
-
-int
-man_macroend(struct man *m)
-{
-
- return(man_unscope(m, m->first, WEXITSCOPE));
-}
+++ /dev/null
-/* $Id: man_term.c,v 1.59 2010/03/24 20:10:53 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "out.h"
-#include "man.h"
-#include "term.h"
-#include "chars.h"
-#include "main.h"
-
-#define INDENT 7
-#define HALFINDENT 3
-
-/* FIXME: have PD set the default vspace width. */
-
-struct mtermp {
- int fl;
-#define MANT_LITERAL (1 << 0)
- /*
- * Default amount to indent the left margin after leading text
- * has been printed (e.g., `HP' left-indent, `TP' and `IP' body
- * indent). This needs to be saved because `HP' and so on, if
- * not having a specified value, must default.
- *
- * Note that this is the indentation AFTER the left offset, so
- * the total offset is usually offset + lmargin.
- */
- size_t lmargin;
- /*
- * The default offset, i.e., the amount between any text and the
- * page boundary.
- */
- size_t offset;
-};
-
-#define DECL_ARGS struct termp *p, \
- struct mtermp *mt, \
- const struct man_node *n, \
- const struct man_meta *m
-
-struct termact {
- int (*pre)(DECL_ARGS);
- void (*post)(DECL_ARGS);
- int flags;
-#define MAN_NOTEXT (1 << 0) /* Never has text children. */
-};
-
-static int a2width(const struct man_node *);
-static int a2height(const struct man_node *);
-
-static void print_man_head(struct termp *,
- const struct man_meta *);
-static void print_man_nodelist(DECL_ARGS);
-static void print_man_node(DECL_ARGS);
-static void print_man_foot(struct termp *,
- const struct man_meta *);
-static void print_bvspace(struct termp *,
- const struct man_node *);
-
-static int pre_B(DECL_ARGS);
-static int pre_BI(DECL_ARGS);
-static int pre_HP(DECL_ARGS);
-static int pre_I(DECL_ARGS);
-static int pre_IP(DECL_ARGS);
-static int pre_PP(DECL_ARGS);
-static int pre_RB(DECL_ARGS);
-static int pre_RI(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_br(DECL_ARGS);
-static int pre_fi(DECL_ARGS);
-static int pre_ign(DECL_ARGS);
-static int pre_nf(DECL_ARGS);
-static int pre_sp(DECL_ARGS);
-
-static void post_IP(DECL_ARGS);
-static void post_HP(DECL_ARGS);
-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 const struct termact termacts[MAN_MAX] = {
- { pre_br, NULL, MAN_NOTEXT }, /* br */
- { NULL, NULL, 0 }, /* TH */
- { pre_SH, post_SH, 0 }, /* SH */
- { pre_SS, post_SS, 0 }, /* SS */
- { pre_TP, post_TP, 0 }, /* TP */
- { pre_PP, NULL, 0 }, /* LP */
- { pre_PP, NULL, 0 }, /* PP */
- { pre_PP, NULL, 0 }, /* P */
- { pre_IP, post_IP, 0 }, /* IP */
- { pre_HP, post_HP, 0 }, /* HP */
- { NULL, NULL, 0 }, /* SM */
- { pre_B, NULL, 0 }, /* SB */
- { pre_BI, NULL, 0 }, /* BI */
- { pre_BI, NULL, 0 }, /* IB */
- { pre_RB, NULL, 0 }, /* BR */
- { pre_RB, NULL, 0 }, /* RB */
- { NULL, NULL, 0 }, /* R */
- { pre_B, NULL, 0 }, /* B */
- { pre_I, NULL, 0 }, /* I */
- { pre_RI, NULL, 0 }, /* IR */
- { pre_RI, NULL, 0 }, /* RI */
- { NULL, NULL, MAN_NOTEXT }, /* na */
- { pre_I, NULL, 0 }, /* i */
- { pre_sp, NULL, MAN_NOTEXT }, /* sp */
- { pre_nf, NULL, 0 }, /* nf */
- { pre_fi, NULL, 0 }, /* fi */
- { NULL, NULL, 0 }, /* r */
- { NULL, NULL, 0 }, /* RE */
- { pre_RS, post_RS, 0 }, /* RS */
- { pre_ign, NULL, 0 }, /* DT */
- { pre_ign, NULL, 0 }, /* UC */
- { pre_ign, NULL, 0 }, /* PD */
- { pre_sp, NULL, MAN_NOTEXT }, /* Sp */
- { pre_nf, NULL, 0 }, /* Vb */
- { pre_fi, NULL, 0 }, /* Ve */
- { pre_ign, NULL, MAN_NOTEXT }, /* de */
- { pre_ign, NULL, MAN_NOTEXT }, /* dei */
- { pre_ign, NULL, MAN_NOTEXT }, /* am */
- { pre_ign, NULL, MAN_NOTEXT }, /* ami */
- { pre_ign, NULL, MAN_NOTEXT }, /* ig */
- { NULL, NULL, 0 }, /* . */
-};
-
-
-
-void
-terminal_man(void *arg, const struct man *man)
-{
- struct termp *p;
- const struct man_node *n;
- const struct man_meta *m;
- struct mtermp mt;
-
- p = (struct termp *)arg;
-
- p->overstep = 0;
- p->maxrmargin = 65;
-
- if (NULL == p->symtab)
- switch (p->enc) {
- case (TERMENC_ASCII):
- p->symtab = chars_init(CHARS_ASCII);
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- n = man_node(man);
- m = man_meta(man);
-
- print_man_head(p, m);
- p->flags |= TERMP_NOSPACE;
-
- mt.fl = 0;
- mt.lmargin = INDENT;
- mt.offset = INDENT;
-
- if (n->child)
- print_man_nodelist(p, &mt, n->child, m);
- print_man_foot(p, m);
-}
-
-
-static int
-a2height(const struct man_node *n)
-{
- struct roffsu su;
-
- assert(MAN_TEXT == n->type);
- assert(n->string);
- if ( ! a2roffsu(n->string, &su, SCALE_VS))
- SCALE_VS_INIT(&su, strlen(n->string));
-
- return((int)term_vspan(&su));
-}
-
-
-static int
-a2width(const struct man_node *n)
-{
- struct roffsu su;
-
- assert(MAN_TEXT == n->type);
- assert(n->string);
- if ( ! a2roffsu(n->string, &su, SCALE_BU))
- return(-1);
-
- return((int)term_hspan(&su));
-}
-
-
-static void
-print_bvspace(struct termp *p, const struct man_node *n)
-{
- term_newln(p);
-
- if (NULL == n->prev)
- return;
-
- if (MAN_SS == n->prev->tok)
- return;
- if (MAN_SH == n->prev->tok)
- return;
-
- term_vspace(p);
-}
-
-
-/* ARGSUSED */
-static int
-pre_ign(DECL_ARGS)
-{
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-pre_I(DECL_ARGS)
-{
-
- term_fontrepl(p, TERMFONT_UNDER);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-pre_fi(DECL_ARGS)
-{
-
- p->rmargin = p->maxrmargin = 65;
- mt->fl &= ~MANT_LITERAL;
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-pre_nf(DECL_ARGS)
-{
-
- p->rmargin = p->maxrmargin = 78;
- term_newln(p);
- mt->fl |= MANT_LITERAL;
-
- return(MAN_Vb != n->tok);
-}
-
-
-/* ARGSUSED */
-static int
-pre_RB(DECL_ARGS)
-{
- const struct man_node *nn;
- int i;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
- if (i % 2 && MAN_RB == n->tok)
- term_fontrepl(p, TERMFONT_BOLD);
- else if ( ! (i % 2) && MAN_RB != n->tok)
- term_fontrepl(p, TERMFONT_BOLD);
- else
- term_fontrepl(p, TERMFONT_NONE);
-
- if (i > 0)
- p->flags |= TERMP_NOSPACE;
-
- print_man_node(p, mt, nn, m);
- }
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-pre_RI(DECL_ARGS)
-{
- const struct man_node *nn;
- int i;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
- if (i % 2 && MAN_RI == n->tok)
- term_fontrepl(p, TERMFONT_UNDER);
- else if ( ! (i % 2) && MAN_RI != n->tok)
- term_fontrepl(p, TERMFONT_UNDER);
- else
- term_fontrepl(p, TERMFONT_NONE);
-
- if (i > 0)
- p->flags |= TERMP_NOSPACE;
-
- print_man_node(p, mt, nn, m);
- }
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-pre_BI(DECL_ARGS)
-{
- const struct man_node *nn;
- int i;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
- if (i % 2 && MAN_BI == n->tok)
- term_fontrepl(p, TERMFONT_UNDER);
- else if (i % 2)
- term_fontrepl(p, TERMFONT_BOLD);
- else if (MAN_BI == n->tok)
- term_fontrepl(p, TERMFONT_BOLD);
- else
- term_fontrepl(p, TERMFONT_UNDER);
-
- if (i)
- p->flags |= TERMP_NOSPACE;
-
- print_man_node(p, mt, nn, m);
- }
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-pre_B(DECL_ARGS)
-{
-
- term_fontrepl(p, TERMFONT_BOLD);
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-pre_sp(DECL_ARGS)
-{
- int i, len;
-
- len = n->child ? a2height(n->child) : 1;
-
- if (0 == len)
- term_newln(p);
- for (i = 0; i < len; i++)
- term_vspace(p);
-
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-pre_br(DECL_ARGS)
-{
-
- term_newln(p);
- return(0);
-}
-
-
-/* ARGSUSED */
-static int
-pre_HP(DECL_ARGS)
-{
- size_t len;
- int ival;
- const struct man_node *nn;
-
- switch (n->type) {
- case (MAN_BLOCK):
- print_bvspace(p, n);
- return(1);
- case (MAN_BODY):
- p->flags |= TERMP_NOBREAK;
- p->flags |= TERMP_TWOSPACE;
- break;
- default:
- return(0);
- }
-
- len = mt->lmargin;
- ival = -1;
-
- /* Calculate offset. */
-
- if (NULL != (nn = n->parent->head->child))
- if ((ival = a2width(nn)) >= 0)
- len = (size_t)ival;
-
- if (0 == len)
- len = 1;
-
- p->offset = mt->offset;
- p->rmargin = mt->offset + len;
-
- if (ival >= 0)
- mt->lmargin = (size_t)ival;
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-post_HP(DECL_ARGS)
-{
-
- switch (n->type) {
- case (MAN_BLOCK):
- term_flushln(p);
- break;
- case (MAN_BODY):
- term_flushln(p);
- p->flags &= ~TERMP_NOBREAK;
- p->flags &= ~TERMP_TWOSPACE;
- p->offset = mt->offset;
- p->rmargin = p->maxrmargin;
- break;
- default:
- break;
- }
-}
-
-
-/* ARGSUSED */
-static int
-pre_PP(DECL_ARGS)
-{
-
- switch (n->type) {
- case (MAN_BLOCK):
- mt->lmargin = INDENT;
- print_bvspace(p, n);
- break;
- default:
- p->offset = mt->offset;
- break;
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static int
-pre_IP(DECL_ARGS)
-{
- const struct man_node *nn;
- size_t len;
- int ival;
-
- switch (n->type) {
- case (MAN_BODY):
- p->flags |= TERMP_NOLPAD;
- p->flags |= TERMP_NOSPACE;
- break;
- case (MAN_HEAD):
- p->flags |= TERMP_NOBREAK;
- p->flags |= TERMP_TWOSPACE;
- break;
- case (MAN_BLOCK):
- print_bvspace(p, n);
- /* FALLTHROUGH */
- default:
- return(1);
- }
-
- len = mt->lmargin;
- ival = -1;
-
- /* Calculate offset. */
-
- if (NULL != (nn = n->parent->head->child))
- if (NULL != (nn = nn->next)) {
- for ( ; nn->next; nn = nn->next)
- /* Do nothing. */ ;
- if ((ival = a2width(nn)) >= 0)
- len = (size_t)ival;
- }
-
- switch (n->type) {
- case (MAN_HEAD):
- /* Handle zero-width lengths. */
- if (0 == len)
- len = 1;
-
- p->offset = mt->offset;
- p->rmargin = mt->offset + len;
- if (ival < 0)
- break;
-
- /* Set the saved left-margin. */
- mt->lmargin = (size_t)ival;
-
- /* Don't print the length value. */
- for (nn = n->child; nn->next; nn = nn->next)
- print_man_node(p, mt, nn, m);
- return(0);
- case (MAN_BODY):
- p->offset = mt->offset + len;
- p->rmargin = p->maxrmargin;
- break;
- default:
- break;
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-post_IP(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_flushln(p);
- p->flags &= ~TERMP_NOLPAD;
- break;
- default:
- break;
- }
-}
-
-
-/* ARGSUSED */
-static int
-pre_TP(DECL_ARGS)
-{
- const struct man_node *nn;
- size_t len;
- int ival;
-
- switch (n->type) {
- case (MAN_HEAD):
- p->flags |= TERMP_NOBREAK;
- p->flags |= TERMP_TWOSPACE;
- break;
- case (MAN_BODY):
- p->flags |= TERMP_NOLPAD;
- p->flags |= TERMP_NOSPACE;
- break;
- case (MAN_BLOCK):
- print_bvspace(p, n);
- /* FALLTHROUGH */
- default:
- return(1);
- }
-
- len = (size_t)mt->lmargin;
- ival = -1;
-
- /* Calculate offset. */
-
- if (NULL != (nn = n->parent->head->child)) {
- while (nn && MAN_TEXT != nn->type)
- nn = nn->next;
- if (nn && nn->next)
- if ((ival = a2width(nn)) >= 0)
- len = (size_t)ival;
- }
-
- switch (n->type) {
- case (MAN_HEAD):
- /* Handle zero-length properly. */
- if (0 == len)
- len = 1;
-
- p->offset = mt->offset;
- p->rmargin = mt->offset + len;
-
- /* 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);
-
- if (ival >= 0)
- mt->lmargin = (size_t)ival;
-
- return(0);
- case (MAN_BODY):
- p->offset = mt->offset + len;
- p->rmargin = p->maxrmargin;
- break;
- default:
- break;
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-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_flushln(p);
- p->flags &= ~TERMP_NOLPAD;
- break;
- default:
- break;
- }
-}
-
-
-/* ARGSUSED */
-static int
-pre_SS(DECL_ARGS)
-{
-
- switch (n->type) {
- case (MAN_BLOCK):
- mt->lmargin = INDENT;
- mt->offset = INDENT;
- /* If following a prior empty `SS', no vspace. */
- if (n->prev && MAN_SS == n->prev->tok)
- if (NULL == n->prev->body->child)
- break;
- if (NULL == n->prev)
- break;
- term_vspace(p);
- break;
- case (MAN_HEAD):
- term_fontrepl(p, TERMFONT_BOLD);
- p->offset = HALFINDENT;
- break;
- case (MAN_BODY):
- p->offset = mt->offset;
- break;
- default:
- break;
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-post_SS(DECL_ARGS)
-{
-
- switch (n->type) {
- case (MAN_HEAD):
- term_newln(p);
- break;
- case (MAN_BODY):
- term_newln(p);
- break;
- default:
- break;
- }
-}
-
-
-/* ARGSUSED */
-static int
-pre_SH(DECL_ARGS)
-{
-
- switch (n->type) {
- case (MAN_BLOCK):
- mt->lmargin = INDENT;
- mt->offset = INDENT;
- /* If following a prior empty `SH', no vspace. */
- if (n->prev && MAN_SH == n->prev->tok)
- if (NULL == n->prev->body->child)
- break;
- term_vspace(p);
- break;
- case (MAN_HEAD):
- term_fontrepl(p, TERMFONT_BOLD);
- p->offset = 0;
- break;
- case (MAN_BODY):
- p->offset = mt->offset;
- break;
- default:
- break;
- }
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-post_SH(DECL_ARGS)
-{
-
- switch (n->type) {
- case (MAN_HEAD):
- term_newln(p);
- break;
- case (MAN_BODY):
- term_newln(p);
- break;
- default:
- break;
- }
-}
-
-
-/* ARGSUSED */
-static int
-pre_RS(DECL_ARGS)
-{
- const struct man_node *nn;
- int ival;
-
- switch (n->type) {
- case (MAN_BLOCK):
- term_newln(p);
- return(1);
- case (MAN_HEAD):
- return(0);
- default:
- break;
- }
-
- if (NULL == (nn = n->parent->head->child)) {
- mt->offset = mt->lmargin + INDENT;
- p->offset = mt->offset;
- return(1);
- }
-
- if ((ival = a2width(nn)) < 0)
- return(1);
-
- mt->offset = INDENT + (size_t)ival;
- p->offset = mt->offset;
-
- return(1);
-}
-
-
-/* ARGSUSED */
-static void
-post_RS(DECL_ARGS)
-{
-
- switch (n->type) {
- case (MAN_BLOCK):
- mt->offset = mt->lmargin = INDENT;
- break;
- case (MAN_HEAD):
- break;
- default:
- term_newln(p);
- p->offset = INDENT;
- break;
- }
-}
-
-
-static void
-print_man_node(DECL_ARGS)
-{
- int c;
-
- c = 1;
-
- switch (n->type) {
- case(MAN_TEXT):
- if (0 == *n->string) {
- term_vspace(p);
- break;
- }
-
- term_word(p, n->string);
-
- /* FIXME: this means that macro lines are munged! */
-
- if (MANT_LITERAL & mt->fl) {
- p->flags |= TERMP_NOSPACE;
- term_flushln(p);
- }
- break;
- default:
- if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
- term_fontrepl(p, TERMFONT_NONE);
- if (termacts[n->tok].pre)
- c = (*termacts[n->tok].pre)(p, mt, n, m);
- break;
- }
-
- if (c && n->child)
- print_man_nodelist(p, mt, n->child, m);
-
- if (MAN_TEXT != n->type) {
- if (termacts[n->tok].post)
- (*termacts[n->tok].post)(p, mt, n, m);
- if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
- term_fontrepl(p, TERMFONT_NONE);
- }
-}
-
-
-static void
-print_man_nodelist(DECL_ARGS)
-{
-
- print_man_node(p, mt, n, m);
- if ( ! n->next)
- return;
- print_man_nodelist(p, mt, n->next, m);
-}
-
-
-static void
-print_man_foot(struct termp *p, const struct man_meta *meta)
-{
- char buf[DATESIZ];
-
- term_fontrepl(p, TERMFONT_NONE);
-
- time2a(meta->date, buf, DATESIZ);
-
- term_vspace(p);
-
- p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
- p->rmargin = p->maxrmargin - strlen(buf);
- p->offset = 0;
-
- if (meta->source)
- term_word(p, meta->source);
- if (meta->source)
- term_word(p, "");
- term_flushln(p);
-
- p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
- p->offset = p->rmargin;
- p->rmargin = p->maxrmargin;
- p->flags &= ~TERMP_NOBREAK;
-
- term_word(p, buf);
- term_flushln(p);
-}
-
-
-static void
-print_man_head(struct termp *p, const struct man_meta *m)
-{
- char buf[BUFSIZ], title[BUFSIZ];
- size_t buflen, titlen;
-
- p->rmargin = p->maxrmargin;
-
- p->offset = 0;
- buf[0] = title[0] = '\0';
-
- if (m->vol)
- strlcpy(buf, m->vol, BUFSIZ);
- buflen = strlen(buf);
-
- snprintf(title, BUFSIZ, "%s(%d)", m->title, m->msec);
- titlen = strlen(title);
-
- p->offset = 0;
- p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
- (p->maxrmargin - strlen(buf) + 1) / 2 :
- p->maxrmargin - buflen;
- p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
-
- term_word(p, title);
- term_flushln(p);
-
- p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
- p->offset = p->rmargin;
- p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
- p->maxrmargin - titlen : p->maxrmargin;
-
- term_word(p, buf);
- term_flushln(p);
-
- p->flags &= ~TERMP_NOBREAK;
- if (p->rmargin + titlen <= p->maxrmargin) {
- p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
- p->offset = p->rmargin;
- p->rmargin = p->maxrmargin;
- term_word(p, title);
- term_flushln(p);
- }
-
- p->rmargin = p->maxrmargin;
- p->offset = 0;
- p->flags &= ~TERMP_NOSPACE;
-}
+++ /dev/null
-/* $Id: man_validate.c,v 1.33 2010/03/29 10:10:35 kristaps Exp $ */
-/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <sys/types.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
-#include "libman.h"
-#include "libmandoc.h"
-
-#define CHKARGS struct man *m, const struct man_node *n
-
-typedef int (*v_check)(CHKARGS);
-
-struct man_valid {
- v_check *pres;
- v_check *posts;
-};
-
-static int check_bline(CHKARGS);
-static int check_eq0(CHKARGS);
-static int check_le1(CHKARGS);
-static int check_ge2(CHKARGS);
-static int check_le5(CHKARGS);
-static int check_par(CHKARGS);
-static int check_part(CHKARGS);
-static int check_roff(CHKARGS);
-static int check_root(CHKARGS);
-static int check_sec(CHKARGS);
-static int check_text(CHKARGS);
-static int check_title(CHKARGS);
-
-static v_check posts_eq0[] = { check_eq0, NULL };
-static v_check posts_th[] = { check_ge2, check_le5, check_title, NULL };
-static v_check posts_par[] = { check_par, NULL };
-static v_check posts_part[] = { check_part, NULL };
-static v_check posts_sec[] = { check_sec, NULL };
-static v_check posts_le1[] = { check_le1, NULL };
-static v_check pres_bline[] = { check_bline, NULL };
-static v_check pres_roff[] = { check_roff, NULL };
-
-static const struct man_valid man_valids[MAN_MAX] = {
- { NULL, posts_eq0 }, /* br */
- { pres_bline, posts_th }, /* TH */
- { pres_bline, posts_sec }, /* SH */
- { pres_bline, posts_sec }, /* SS */
- { pres_bline, posts_par }, /* TP */
- { pres_bline, posts_par }, /* LP */
- { pres_bline, posts_par }, /* PP */
- { pres_bline, posts_par }, /* P */
- { pres_bline, posts_par }, /* IP */
- { pres_bline, posts_par }, /* HP */
- { NULL, NULL }, /* SM */
- { NULL, NULL }, /* SB */
- { NULL, NULL }, /* BI */
- { NULL, NULL }, /* IB */
- { NULL, NULL }, /* BR */
- { NULL, NULL }, /* RB */
- { NULL, NULL }, /* R */
- { NULL, NULL }, /* B */
- { NULL, NULL }, /* I */
- { NULL, NULL }, /* IR */
- { NULL, NULL }, /* RI */
- { NULL, posts_eq0 }, /* na */
- { NULL, NULL }, /* i */
- { NULL, posts_le1 }, /* sp */
- { pres_bline, posts_eq0 }, /* nf */
- { pres_bline, posts_eq0 }, /* fi */
- { NULL, NULL }, /* r */
- { NULL, NULL }, /* RE */
- { NULL, posts_part }, /* RS */
- { NULL, NULL }, /* DT */
- { NULL, NULL }, /* UC */
- { NULL, NULL }, /* PD */
- { NULL, posts_eq0 }, /* Sp */
- { pres_bline, posts_le1 }, /* Vb */
- { pres_bline, posts_eq0 }, /* Ve */
- { pres_roff, NULL }, /* de */
- { pres_roff, NULL }, /* dei */
- { pres_roff, NULL }, /* am */
- { pres_roff, NULL }, /* ami */
- { pres_roff, NULL }, /* ig */
- { NULL, NULL }, /* . */
-};
-
-
-int
-man_valid_pre(struct man *m, const struct man_node *n)
-{
- v_check *cp;
-
- if (MAN_TEXT == n->type)
- return(1);
- if (MAN_ROOT == n->type)
- return(1);
-
- if (NULL == (cp = man_valids[n->tok].pres))
- return(1);
- for ( ; *cp; cp++)
- if ( ! (*cp)(m, n))
- return(0);
- return(1);
-}
-
-
-int
-man_valid_post(struct man *m)
-{
- v_check *cp;