Import mandoc snapshot 2017-06-08
It implements missing man(7) macros used in base by kerberos/ntp and makes them supported by mandoc. This import should have been done before the removal of groff. Reported by: gordon
This commit is contained in:
commit
a6f1e1ee5b
@ -1,11 +1,11 @@
|
||||
$Id: LICENSE,v 1.14 2017/02/08 12:24:10 schwarze Exp $
|
||||
$Id: LICENSE,v 1.15 2017/02/21 00:37:03 schwarze Exp $
|
||||
|
||||
With the exceptions noted below, all code and documentation
|
||||
contained in the mdocml toolkit is protected by the Copyright
|
||||
of the following developers:
|
||||
|
||||
Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
Copyright (c) 2014 Baptiste Daroussin <bapt@freebsd.org>
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.504 2017/02/18 15:29:39 schwarze Exp $
|
||||
# $Id: Makefile,v 1.512 2017/05/07 17:31:45 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
# Copyright (c) 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -85,7 +85,6 @@ SRCS = att.c \
|
||||
lib.c \
|
||||
main.c \
|
||||
man.c \
|
||||
man_hash.c \
|
||||
man_html.c \
|
||||
man_macro.c \
|
||||
man_term.c \
|
||||
@ -95,15 +94,14 @@ SRCS = att.c \
|
||||
mandoc_ohash.c \
|
||||
mandocd.c \
|
||||
mandocdb.c \
|
||||
manpage.c \
|
||||
manpath.c \
|
||||
mansearch.c \
|
||||
mdoc.c \
|
||||
mdoc_argv.c \
|
||||
mdoc_hash.c \
|
||||
mdoc_html.c \
|
||||
mdoc_macro.c \
|
||||
mdoc_man.c \
|
||||
mdoc_markdown.c \
|
||||
mdoc_state.c \
|
||||
mdoc_term.c \
|
||||
mdoc_validate.c \
|
||||
@ -112,6 +110,9 @@ SRCS = att.c \
|
||||
preconv.c \
|
||||
read.c \
|
||||
roff.c \
|
||||
roff_html.c \
|
||||
roff_term.c \
|
||||
roff_validate.c \
|
||||
soelim.c \
|
||||
st.c \
|
||||
tag.c \
|
||||
@ -124,6 +125,7 @@ SRCS = att.c \
|
||||
term.c \
|
||||
term_ascii.c \
|
||||
term_ps.c \
|
||||
term_tab.c \
|
||||
tree.c
|
||||
|
||||
DISTFILES = INSTALL \
|
||||
@ -198,7 +200,6 @@ DISTFILES = INSTALL \
|
||||
$(TESTSRCS)
|
||||
|
||||
LIBMAN_OBJS = man.o \
|
||||
man_hash.o \
|
||||
man_macro.o \
|
||||
man_validate.o
|
||||
|
||||
@ -206,7 +207,6 @@ LIBMDOC_OBJS = att.o \
|
||||
lib.o \
|
||||
mdoc.o \
|
||||
mdoc_argv.o \
|
||||
mdoc_hash.o \
|
||||
mdoc_macro.o \
|
||||
mdoc_state.o \
|
||||
mdoc_validate.o \
|
||||
@ -214,6 +214,7 @@ LIBMDOC_OBJS = att.o \
|
||||
|
||||
LIBROFF_OBJS = eqn.o \
|
||||
roff.o \
|
||||
roff_validate.o \
|
||||
tbl.o \
|
||||
tbl_data.o \
|
||||
tbl_layout.o \
|
||||
@ -250,16 +251,17 @@ MANDOC_HTML_OBJS = eqn_html.o \
|
||||
html.o \
|
||||
man_html.o \
|
||||
mdoc_html.o \
|
||||
roff_html.o \
|
||||
tbl_html.o
|
||||
|
||||
MANDOC_MAN_OBJS = mdoc_man.o
|
||||
|
||||
MANDOC_TERM_OBJS = eqn_term.o \
|
||||
man_term.o \
|
||||
mdoc_term.o \
|
||||
roff_term.o \
|
||||
term.o \
|
||||
term_ascii.o \
|
||||
term_ps.o \
|
||||
term_tab.o \
|
||||
tbl_term.o
|
||||
|
||||
DBM_OBJS = dbm.o \
|
||||
@ -279,6 +281,8 @@ MAIN_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
$(DBA_OBJS) \
|
||||
main.o \
|
||||
manpath.o \
|
||||
mdoc_man.o \
|
||||
mdoc_markdown.o \
|
||||
out.o \
|
||||
tag.o \
|
||||
tree.o
|
||||
@ -294,10 +298,6 @@ MANDOCD_OBJS = $(MANDOC_HTML_OBJS) \
|
||||
out.o \
|
||||
tag.o
|
||||
|
||||
MANPAGE_OBJS = $(DBM_OBJS) \
|
||||
manpage.o \
|
||||
manpath.o
|
||||
|
||||
DEMANDOC_OBJS = demandoc.o
|
||||
|
||||
SOELIM_OBJS = soelim.o \
|
||||
@ -373,7 +373,6 @@ clean:
|
||||
rm -f mandoc $(MAIN_OBJS)
|
||||
rm -f man.cgi $(CGI_OBJS)
|
||||
rm -f mandocd catman $(MANDOCD_OBJS)
|
||||
rm -f manpage $(MANPAGE_OBJS)
|
||||
rm -f demandoc $(DEMANDOC_OBJS)
|
||||
rm -f soelim $(SOELIM_OBJS)
|
||||
rm -f $(WWW_MANS) $(WWW_OBJS)
|
||||
@ -388,17 +387,16 @@ base-install: mandoc demandoc soelim
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_PROGRAM) soelim $(DESTDIR)$(BINDIR)/$(BINM_SOELIM)
|
||||
$(LN) $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_MAN)
|
||||
$(LN) $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS)
|
||||
$(LN) $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS)
|
||||
$(LN) $(DESTDIR)$(BINDIR)/mandoc \
|
||||
$(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS)
|
||||
cd $(DESTDIR)$(BINDIR) && $(LN) mandoc $(BINM_MAN)
|
||||
cd $(DESTDIR)$(BINDIR) && $(LN) mandoc $(BINM_APROPOS)
|
||||
cd $(DESTDIR)$(BINDIR) && $(LN) mandoc $(BINM_WHATIS)
|
||||
cd $(DESTDIR)$(SBINDIR) && \
|
||||
$(LN) ${BIN_FROM_SBIN}/mandoc $(BINM_MAKEWHATIS)
|
||||
$(INSTALL_MAN) mandoc.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL_MAN) soelim.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_SOELIM).1
|
||||
$(INSTALL_MAN) man.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_MAN).1
|
||||
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1
|
||||
$(LN) $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \
|
||||
$(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1
|
||||
cd $(DESTDIR)$(MANDIR)/man1 && $(LN) $(BINM_APROPOS).1 $(BINM_WHATIS).1
|
||||
$(INSTALL_MAN) man.conf.5 $(DESTDIR)$(MANDIR)/man5/$(MANM_MANCONF).5
|
||||
$(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5
|
||||
$(INSTALL_MAN) man.7 $(DESTDIR)$(MANDIR)/man7/$(MANM_MAN).7
|
||||
@ -475,7 +473,7 @@ uninstall:
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/mandoc_aux.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/mdoc.h
|
||||
rm -f $(DESTDIR)$(INCLUDEDIR)/roff.h
|
||||
rmdir $(DESTDIR)$(INCLUDEDIR)
|
||||
[ ! -e $(DESTDIR)$(INCLUDEDIR) ] || rmdir $(DESTDIR)$(INCLUDEDIR)
|
||||
|
||||
regress: all
|
||||
cd regress && ./regress.pl
|
||||
@ -493,9 +491,6 @@ libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
|
||||
mandoc: $(MAIN_OBJS) libmandoc.a
|
||||
$(CC) -o $@ $(LDFLAGS) $(MAIN_OBJS) libmandoc.a $(LDADD)
|
||||
|
||||
manpage: $(MANPAGE_OBJS) libmandoc.a
|
||||
$(CC) -o $@ $(LDFLAGS) $(MANPAGE_OBJS) libmandoc.a $(LDADD)
|
||||
|
||||
man.cgi: $(CGI_OBJS) libmandoc.a
|
||||
$(CC) $(STATIC) -o $@ $(LDFLAGS) $(CGI_OBJS) libmandoc.a $(LDADD)
|
||||
|
||||
|
@ -28,11 +28,10 @@ demandoc.o: demandoc.c config.h roff.h man.h mdoc.h mandoc.h
|
||||
eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
|
||||
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
|
||||
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
|
||||
html.o: html.c config.h mandoc.h mandoc_aux.h out.h html.h manconf.h main.h
|
||||
html.o: html.c config.h mandoc_aux.h mandoc.h roff.h out.h html.h manconf.h main.h
|
||||
lib.o: lib.c config.h roff.h mdoc.h libmdoc.h lib.in
|
||||
main.o: main.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h
|
||||
man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
man_hash.o: man_hash.c config.h mandoc.h roff.h man.h libmandoc.h libman.h
|
||||
man_html.o: man_html.c config.h mandoc_aux.h roff.h man.h out.h html.h main.h
|
||||
man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h
|
||||
man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h main.h
|
||||
@ -42,15 +41,14 @@ mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h
|
||||
mandoc_ohash.o: mandoc_ohash.c mandoc_aux.h mandoc_ohash.h compat_ohash.h
|
||||
mandocd.o: mandocd.c config.h mandoc.h roff.h mdoc.h man.h main.h manconf.h
|
||||
mandocdb.o: mandocdb.c config.h compat_fts.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mdoc.h man.h manconf.h mansearch.h dba_array.h dba.h
|
||||
manpage.o: manpage.c config.h manconf.h mansearch.h
|
||||
manpath.o: manpath.c config.h mandoc_aux.h manconf.h
|
||||
mansearch.o: mansearch.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h manconf.h mansearch.h dbm.h
|
||||
mdoc.o: mdoc.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_argv.o: mdoc_argv.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_hash.o: mdoc_hash.c config.h mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h
|
||||
mdoc_html.o: mdoc_html.c config.h mandoc_aux.h roff.h mdoc.h out.h html.h main.h
|
||||
mdoc_macro.o: mdoc_macro.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h main.h
|
||||
mdoc_markdown.o: mdoc_markdown.c mandoc_aux.h mandoc.h roff.h mdoc.h main.h
|
||||
mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h libmdoc.h
|
||||
mdoc_term.o: mdoc_term.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h out.h term.h tag.h main.h
|
||||
mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h
|
||||
@ -58,7 +56,10 @@ msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
|
||||
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
|
||||
preconv.o: preconv.c config.h mandoc.h libmandoc.h
|
||||
read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h libmandoc.h roff_int.h
|
||||
roff.o: roff.c config.h mandoc.h mandoc_aux.h roff.h libmandoc.h roff_int.h libroff.h predefs.in
|
||||
roff.o: roff.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h libmandoc.h roff_int.h libroff.h predefs.in
|
||||
roff_html.o: roff_html.c roff.h out.h html.h
|
||||
roff_term.o: roff_term.c roff.h out.h term.h
|
||||
roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h
|
||||
soelim.o: soelim.c config.h compat_stringlist.h
|
||||
st.o: st.c config.h roff.h mdoc.h libmdoc.h st.in
|
||||
tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h tag.h
|
||||
@ -71,4 +72,5 @@ tbl_term.o: tbl_term.c config.h mandoc.h out.h term.h
|
||||
term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
|
||||
term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h manconf.h main.h
|
||||
term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h manconf.h main.h
|
||||
term_tab.o: term_tab.c mandoc_aux.h out.h term.h
|
||||
tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h main.h
|
||||
|
@ -1,8 +1,8 @@
|
||||
$Id: NEWS,v 1.20 2017/02/16 14:38:12 schwarze Exp $
|
||||
$Id: NEWS,v 1.21 2017/02/21 00:37:03 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mdocml.bsd.lv distribution.
|
||||
|
||||
Changes in version 1.14.1, released on February XXX, 2017
|
||||
Changes in version 1.14.1, released on February 21, 2017
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
* apropos(1): Reimplement complete semantic search functionality
|
||||
@ -95,28 +95,32 @@ Changes in version 1.14.1, released on February XXX, 2017
|
||||
easier to use and reducing the amount of code by a few hundred lines.
|
||||
--- THANKS TO ---
|
||||
* Michael Stapelberg (Debian) for designing the new mandocd(8)
|
||||
and parts of the new catman(8), and for a number of patches
|
||||
and bug reports.
|
||||
and parts of the new catman(8), for release testing, and for a
|
||||
number of patches and bug reports.
|
||||
* Baptiste Daroussin (FreeBSD) for profiling the new makewhatis(8)
|
||||
implementation and suggesting an algorithmic improvement which
|
||||
more than doubled performance, and for a few bug reports.
|
||||
* Ed Maste (FreeBSD) for an important patch improving reproducibility
|
||||
of builds in makewhatis(8), and for a few bug reports.
|
||||
* Theo Buehler (OpenBSD) for more than ten important bug reports,
|
||||
* Theo Buehler (OpenBSD) for almost twenty important bug reports,
|
||||
most of them found by systematic afl(1) fuzzing.
|
||||
* Benny Lofgren, David Dahlberg, and in particular Vadim Zhukov
|
||||
for crucial help in getting .Bl -tag CSS formatting fixed.
|
||||
* Svyatoslav Mishyn (Crux Linux) for an initial version of the
|
||||
patch to autodetect a suitable locale for -Tutf8 mode.
|
||||
patch to autodetect a suitable locale for -Tutf8 mode
|
||||
and for release testing.
|
||||
* Jason McIntyre (OpenBSD) for multiple useful discussions
|
||||
and a number of bug reports.
|
||||
* Sevan Janiyan (NetBSD) for extensive release testing and multiple
|
||||
bug reports.
|
||||
* Thomas Klausner and Christos Zoulas (NetBSD), Yuri Pankov (illumos),
|
||||
and Leah Neukirchen (Void Linux) for release testing and bug reports.
|
||||
* Ulrich Spoerlein (FreeBSD) for release testing.
|
||||
* Alexander Bluhm, Andrew Fresh, Antoine Jacoutot, Antony Bentley,
|
||||
Christian Weisgerber, Jonathan Gray, Marc Espie, Martijn van Duren,
|
||||
Stuart Henderson, Ted Unangst, Theo de Raadt (OpenBSD), Abhinav
|
||||
Upadhyay, Christos Zoulas, Kamil Rytarowski, Sevan Janiyan,
|
||||
Thomas Klausner (NetBSD), Aaron M. Ucko, Bdale Garbee, Reiner
|
||||
Herrmann, Shane Kerr (Debian), Leah Neukirchen (Void Linux),
|
||||
Daniel Sabogal (Alpine Linux), Yuri Pankov (illumos),
|
||||
Upadhyay, Kamil Rytarowski (NetBSD), Aaron M. Ucko, Bdale Garbee,
|
||||
Reiner Herrmann, Shane Kerr (Debian), Daniel Sabogal (Alpine Linux),
|
||||
Carsten Kunze (Heirloom roff), Kristaps Dzonsons (bsd.lv),
|
||||
Anton Lindqvist, Jan Stary, Jeremy A. Mates, Mark Patruck,
|
||||
Pavan Maddamsetti, Sean Levy <attila@stalphonsos.com>, and
|
||||
|
@ -1,6 +1,6 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.234 2017/02/18 11:53:33 schwarze Exp $
|
||||
* $Id: TODO,v 1.237 2017/05/16 19:06:30 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
@ -61,18 +61,6 @@ are mere guesses, and some may be wrong.
|
||||
reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500
|
||||
loc *** exist *** algo *** size ** imp *
|
||||
|
||||
- .ta (tab settings)
|
||||
#1 most important issue naddy@ Mon, 16 Feb 2015 20:59:17 +0100
|
||||
ircbug(1) gnats(1) reported by brad@ Sat, 15 Jan 2011 15:50:51 -0500
|
||||
also Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
|
||||
also posix2time(3) Carsten Kunze Mon, 1 Dec 2014 13:03:10 +0100
|
||||
loc ** exist *** algo ** size ** imp ***
|
||||
|
||||
- .ti (temporary indent)
|
||||
found by naddy@ in xloadimage(1) [devel/libvstr] vstr(3)
|
||||
found by bentley@ in nmh(1) Mon, 23 Apr 2012 13:38:28 -0600
|
||||
loc ** exist ** algo ** size * imp ** (parser reorg helps a lot)
|
||||
|
||||
- .while and .shift
|
||||
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
|
||||
loc * exist ** algo ** size ** imp **
|
||||
@ -273,12 +261,6 @@ are mere guesses, and some may be wrong.
|
||||
- kettenis wants base roff, ms, and me Fri, 1 Jan 2010 22:13:15 +0100 (CET)
|
||||
loc ** exist ** algo ** size *** imp *
|
||||
|
||||
- Vsevolod Stakhov (FreeBSD) needs either a markdown output formatter
|
||||
for mandoc -mdoc or a markdown to mdoc converter because they
|
||||
have to maintain manuals needed both in markdown and mdoc format.
|
||||
Look at the libsoldout (markdown -> whatever)
|
||||
loc * exist * algo * size ** imp **
|
||||
|
||||
--- compatibility checks -----------------------------------------------
|
||||
|
||||
- is .Bk implemented correctly in modern groff?
|
||||
@ -566,8 +548,6 @@ are mere guesses, and some may be wrong.
|
||||
|
||||
Several areas can be cleaned up to make mandoc even faster. These are
|
||||
|
||||
- improve hashing mechanism for macros (quite important: performance)
|
||||
|
||||
- the PDF file is HUGE: this can be reduced by using relative offsets
|
||||
|
||||
************************************************************************
|
||||
@ -613,3 +593,10 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
||||
|
||||
- use uname(1) to set doc-default-operating-system at install time
|
||||
tobimensch Mon, 1 Dec 2014 00:25:07 +0100
|
||||
|
||||
- apostrophe (39), circumflex (94), grave (96), tilde (126)
|
||||
in manuals: \(aq, \(ha, \`, \(ti
|
||||
Re: [Groff] ASCII Minus Sign in man Pages.
|
||||
bentley@ 26 Apr 2017 10:02:06 -0600
|
||||
Do we need to fix existing manuals?
|
||||
Do we need to fix the definition of the mdoc(7) language?
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: apropos.1,v 1.40 2017/01/31 19:44:04 schwarze Exp $
|
||||
.\" $Id: apropos.1,v 1.45 2017/03/27 18:51:36 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 31 2017 $
|
||||
.Dd $Mdocdate: March 27 2017 $
|
||||
.Dt APROPOS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -24,7 +24,7 @@
|
||||
.Nd search manual page databases
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl acfhklw
|
||||
.Op Fl afk
|
||||
.Op Fl C Ar file
|
||||
.Op Fl M Ar path
|
||||
.Op Fl m Ar path
|
||||
@ -89,12 +89,6 @@ Specify an alternative configuration
|
||||
in
|
||||
.Xr man.conf 5
|
||||
format.
|
||||
.It Fl c
|
||||
In
|
||||
.Fl a
|
||||
mode, copy the formatted manual pages to the standard output without using
|
||||
.Xr more 1
|
||||
to paginate them.
|
||||
.It Fl f
|
||||
Search for all words in
|
||||
.Ar expression
|
||||
@ -102,37 +96,12 @@ in manual page names only.
|
||||
The search is case insensitive and matches whole words only.
|
||||
In this mode, macro keys, comparison operators, and logical operators
|
||||
are not available.
|
||||
This overrides any earlier
|
||||
.Fl k
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
.It Fl h
|
||||
Instead of showing the title lines, show the SYNOPSIS sections, just like
|
||||
.Xr man 1
|
||||
.Fl h
|
||||
would.
|
||||
.It Fl k
|
||||
Support the full
|
||||
.Ar expression
|
||||
syntax.
|
||||
This overrides any earlier
|
||||
.Fl f
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
It is the default for
|
||||
.Nm .
|
||||
.It Fl l
|
||||
An alias for
|
||||
.Xr mandoc 1
|
||||
.Fl a .
|
||||
This overrides any earlier
|
||||
.Fl f ,
|
||||
.Fl k ,
|
||||
and
|
||||
.Fl w
|
||||
options.
|
||||
.It Fl M Ar path
|
||||
Use the colon-separated path instead of the default list of paths
|
||||
searched for
|
||||
@ -162,14 +131,16 @@ By default, pages from all sections are shown.
|
||||
See
|
||||
.Xr man 1
|
||||
for a listing of sections.
|
||||
.It Fl w
|
||||
Instead of showing title lines, show the pathnames of the matching
|
||||
manual pages, just like
|
||||
.Xr man 1
|
||||
.Fl w
|
||||
would.
|
||||
.El
|
||||
.Pp
|
||||
The options
|
||||
.Fl chlw
|
||||
are also supported and are documented in
|
||||
.Xr man 1 .
|
||||
The options
|
||||
.Fl fkl
|
||||
are mutually exclusive and override each other.
|
||||
.Pp
|
||||
An
|
||||
.Ar expression
|
||||
consists of search terms joined by logical operators
|
||||
@ -237,7 +208,28 @@ is evaluated case-insensitively.
|
||||
Has no effect on substring terms.
|
||||
.El
|
||||
.Pp
|
||||
Results are sorted by manual sections and names, with output formatted as
|
||||
Results are sorted according to the following criteria:
|
||||
.Bl -enum
|
||||
.It
|
||||
The manpath directory tree the page is found in, according to the
|
||||
order specified with
|
||||
.Fl M ,
|
||||
.Fl m ,
|
||||
the
|
||||
.Ev MANPATH
|
||||
environment variable, the
|
||||
.Xr man.conf 5
|
||||
configuration file, or the default documented in
|
||||
.Xr man.conf 5 .
|
||||
.It
|
||||
The section number in ascending numerical order.
|
||||
.It
|
||||
The page name in ascending
|
||||
.Xr ascii 7
|
||||
alphabetical order, case-insensitive.
|
||||
.El
|
||||
.Pp
|
||||
Each output line is formatted as
|
||||
.Pp
|
||||
.D1 name[, name...](sec) \- description
|
||||
.Pp
|
||||
@ -341,25 +333,25 @@ Text production:
|
||||
.It Ev MANPAGER
|
||||
Any non-empty value of the environment variable
|
||||
.Ev MANPAGER
|
||||
will be used instead of the standard pagination program,
|
||||
.Xr more 1 .
|
||||
.It Ev MANPATH
|
||||
The standard search path used by
|
||||
is used instead of the standard pagination program,
|
||||
.Xr more 1 ;
|
||||
see
|
||||
.Xr man 1
|
||||
may be changed by specifying a path in the
|
||||
.Ev MANPATH
|
||||
environment variable.
|
||||
Invalid paths, or paths without manual databases, are ignored.
|
||||
for details.
|
||||
Only used if
|
||||
.Fl a
|
||||
or
|
||||
.Fl l
|
||||
is specified.
|
||||
.It Ev MANPATH
|
||||
A colon-separated list of directories to search for manual pages; see
|
||||
.Xr man 1
|
||||
for details.
|
||||
Overridden by
|
||||
.Fl M .
|
||||
If
|
||||
.Ev MANPATH
|
||||
begins with a colon, it is appended to the default list;
|
||||
if it ends with a colon, it is prepended to the default list;
|
||||
or if it contains two adjacent colons,
|
||||
the standard search path is inserted between the colons.
|
||||
If none of these conditions are met, it overrides the
|
||||
standard search path.
|
||||
.Fl M ,
|
||||
ignored if
|
||||
.Fl l
|
||||
is specified.
|
||||
.It Ev PAGER
|
||||
Specifies the pagination program to use when
|
||||
.Ev MANPAGER
|
||||
@ -367,7 +359,12 @@ is not defined.
|
||||
If neither PAGER nor MANPAGER is defined,
|
||||
.Xr more 1
|
||||
.Fl s
|
||||
will be used.
|
||||
is used.
|
||||
Only used if
|
||||
.Fl a
|
||||
or
|
||||
.Fl l
|
||||
is specified.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/man.conf" -compact
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: catman.8,v 1.7 2017/02/06 19:04:21 schwarze Exp $
|
||||
.\" $Id: catman.8,v 1.8 2017/03/18 19:56:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 6 2017 $
|
||||
.Dd $Mdocdate: March 18 2017 $
|
||||
.Dt CATMAN 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -49,7 +49,7 @@ Override the default operating system
|
||||
.Ar name
|
||||
for the
|
||||
.Xr mdoc 7
|
||||
.Ic Os
|
||||
.Ic \&Os
|
||||
and for the
|
||||
.Xr man 7
|
||||
.Ic TH
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: cgi.c,v 1.147 2017/02/08 13:34:27 schwarze Exp $ */
|
||||
/* $Id: cgi.c,v 1.154 2017/04/19 01:00:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@usta.de>
|
||||
@ -76,11 +76,12 @@ static void pg_error_badrequest(const char *);
|
||||
static void pg_error_internal(void);
|
||||
static void pg_index(const struct req *);
|
||||
static void pg_noresult(const struct req *, const char *);
|
||||
static void pg_redirect(const struct req *, const char *);
|
||||
static void pg_search(const struct req *);
|
||||
static void pg_searchres(const struct req *,
|
||||
struct manpage *, size_t);
|
||||
static void pg_show(struct req *, const char *);
|
||||
static void resp_begin_html(int, const char *);
|
||||
static void resp_begin_html(int, const char *, const char *);
|
||||
static void resp_begin_http(int, const char *);
|
||||
static void resp_catman(const struct req *, const char *);
|
||||
static void resp_copy(const char *);
|
||||
@ -345,8 +346,9 @@ resp_copy(const char *filename)
|
||||
}
|
||||
|
||||
static void
|
||||
resp_begin_html(int code, const char *msg)
|
||||
resp_begin_html(int code, const char *msg, const char *file)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
resp_begin_http(code, msg);
|
||||
|
||||
@ -356,10 +358,20 @@ resp_begin_html(int code, const char *msg)
|
||||
" <meta charset=\"UTF-8\"/>\n"
|
||||
" <link rel=\"stylesheet\" href=\"%s/mandoc.css\""
|
||||
" type=\"text/css\" media=\"all\">\n"
|
||||
" <title>%s</title>\n"
|
||||
" <title>",
|
||||
CSS_DIR);
|
||||
if (file != NULL) {
|
||||
if ((cp = strrchr(file, '/')) != NULL)
|
||||
file = cp + 1;
|
||||
if ((cp = strrchr(file, '.')) != NULL) {
|
||||
printf("%.*s(%s) - ", (int)(cp - file), file, cp + 1);
|
||||
} else
|
||||
printf("%s - ", file);
|
||||
}
|
||||
printf("%s</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n",
|
||||
CSS_DIR, CUSTOMIZE_TITLE);
|
||||
CUSTOMIZE_TITLE);
|
||||
|
||||
resp_copy(MAN_DIR "/header.html");
|
||||
}
|
||||
@ -492,7 +504,7 @@ static void
|
||||
pg_index(const struct req *req)
|
||||
{
|
||||
|
||||
resp_begin_html(200, NULL);
|
||||
resp_begin_html(200, NULL, NULL);
|
||||
resp_searchform(req, FOCUS_QUERY);
|
||||
printf("<p>\n"
|
||||
"This web interface is documented in the\n"
|
||||
@ -509,7 +521,7 @@ pg_index(const struct req *req)
|
||||
static void
|
||||
pg_noresult(const struct req *req, const char *msg)
|
||||
{
|
||||
resp_begin_html(200, NULL);
|
||||
resp_begin_html(200, NULL, NULL);
|
||||
resp_searchform(req, FOCUS_QUERY);
|
||||
puts("<p>");
|
||||
puts(msg);
|
||||
@ -521,7 +533,7 @@ static void
|
||||
pg_error_badrequest(const char *msg)
|
||||
{
|
||||
|
||||
resp_begin_html(400, "Bad Request");
|
||||
resp_begin_html(400, "Bad Request", NULL);
|
||||
puts("<h1>Bad Request</h1>\n"
|
||||
"<p>\n");
|
||||
puts(msg);
|
||||
@ -534,11 +546,28 @@ pg_error_badrequest(const char *msg)
|
||||
static void
|
||||
pg_error_internal(void)
|
||||
{
|
||||
resp_begin_html(500, "Internal Server Error");
|
||||
resp_begin_html(500, "Internal Server Error", NULL);
|
||||
puts("<p>Internal Server Error</p>");
|
||||
resp_end_html();
|
||||
}
|
||||
|
||||
static void
|
||||
pg_redirect(const struct req *req, const char *name)
|
||||
{
|
||||
printf("Status: 303 See Other\r\n"
|
||||
"Location: /");
|
||||
if (*scriptname != '\0')
|
||||
printf("%s/", scriptname);
|
||||
if (strcmp(req->q.manpath, req->p[0]))
|
||||
printf("%s/", req->q.manpath);
|
||||
if (req->q.arch != NULL)
|
||||
printf("%s/", req->q.arch);
|
||||
printf("%s", name);
|
||||
if (req->q.sec != NULL)
|
||||
printf(".%s", req->q.sec);
|
||||
printf("\r\nContent-Type: text/html; charset=utf-8\r\n\r\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pg_searchres(const struct req *req, struct manpage *r, size_t sz)
|
||||
{
|
||||
@ -562,47 +591,25 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
|
||||
* If we have just one result, then jump there now
|
||||
* without any delay.
|
||||
*/
|
||||
printf("Status: 303 See Other\r\n");
|
||||
printf("Location: http://%s/%s%s%s/%s",
|
||||
HTTP_HOST, scriptname,
|
||||
*scriptname == '\0' ? "" : "/",
|
||||
req->q.manpath, r[0].file);
|
||||
printf("\r\n"
|
||||
"Content-Type: text/html; charset=utf-8\r\n"
|
||||
"\r\n");
|
||||
printf("Status: 303 See Other\r\n"
|
||||
"Location: /");
|
||||
if (*scriptname != '\0')
|
||||
printf("%s/", scriptname);
|
||||
if (strcmp(req->q.manpath, req->p[0]))
|
||||
printf("%s/", req->q.manpath);
|
||||
printf("%s\r\n"
|
||||
"Content-Type: text/html; charset=utf-8\r\n\r\n",
|
||||
r[0].file);
|
||||
return;
|
||||
}
|
||||
|
||||
resp_begin_html(200, NULL);
|
||||
resp_searchform(req,
|
||||
req->q.equal || sz == 1 ? FOCUS_NONE : FOCUS_QUERY);
|
||||
|
||||
if (sz > 1) {
|
||||
puts("<table class=\"results\">");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf(" <tr>\n"
|
||||
" <td>"
|
||||
"<a class=\"Xr\" href=\"/%s%s%s/%s\">",
|
||||
scriptname, *scriptname == '\0' ? "" : "/",
|
||||
req->q.manpath, r[i].file);
|
||||
html_print(r[i].names);
|
||||
printf("</a></td>\n"
|
||||
" <td><span class=\"Nd\">");
|
||||
html_print(r[i].output);
|
||||
puts("</span></td>\n"
|
||||
" </tr>");
|
||||
}
|
||||
puts("</table>");
|
||||
}
|
||||
|
||||
/*
|
||||
* In man(1) mode, show one of the pages
|
||||
* even if more than one is found.
|
||||
*/
|
||||
|
||||
iuse = 0;
|
||||
if (req->q.equal || sz == 1) {
|
||||
puts("<hr>");
|
||||
iuse = 0;
|
||||
priouse = 20;
|
||||
archpriouse = 3;
|
||||
for (i = 0; i < sz; i++) {
|
||||
@ -635,6 +642,36 @@ pg_searchres(const struct req *req, struct manpage *r, size_t sz)
|
||||
priouse = prio;
|
||||
iuse = i;
|
||||
}
|
||||
resp_begin_html(200, NULL, r[iuse].file);
|
||||
} else
|
||||
resp_begin_html(200, NULL, NULL);
|
||||
|
||||
resp_searchform(req,
|
||||
req->q.equal || sz == 1 ? FOCUS_NONE : FOCUS_QUERY);
|
||||
|
||||
if (sz > 1) {
|
||||
puts("<table class=\"results\">");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf(" <tr>\n"
|
||||
" <td>"
|
||||
"<a class=\"Xr\" href=\"/");
|
||||
if (*scriptname != '\0')
|
||||
printf("%s/", scriptname);
|
||||
if (strcmp(req->q.manpath, req->p[0]))
|
||||
printf("%s/", req->q.manpath);
|
||||
printf("%s\">", r[i].file);
|
||||
html_print(r[i].names);
|
||||
printf("</a></td>\n"
|
||||
" <td><span class=\"Nd\">");
|
||||
html_print(r[i].output);
|
||||
puts("</span></td>\n"
|
||||
" </tr>");
|
||||
}
|
||||
puts("</table>");
|
||||
}
|
||||
|
||||
if (req->q.equal || sz == 1) {
|
||||
puts("<hr>");
|
||||
resp_show(req, r[iuse].file);
|
||||
}
|
||||
|
||||
@ -803,7 +840,8 @@ resp_format(const struct req *req, const char *file)
|
||||
conf.fragment = 1;
|
||||
conf.style = mandoc_strdup(CSS_DIR "/mandoc.css");
|
||||
usepath = strcmp(req->q.manpath, req->p[0]);
|
||||
mandoc_asprintf(&conf.man, "/%s%s%%N.%%S",
|
||||
mandoc_asprintf(&conf.man, "/%s%s%s%s%%N.%%S",
|
||||
scriptname, *scriptname == '\0' ? "" : "/",
|
||||
usepath ? req->q.manpath : "", usepath ? "/" : "");
|
||||
|
||||
mparse_result(mp, &man, NULL);
|
||||
@ -886,7 +924,7 @@ pg_show(struct req *req, const char *fullpath)
|
||||
return;
|
||||
}
|
||||
|
||||
resp_begin_html(200, NULL);
|
||||
resp_begin_html(200, NULL, file);
|
||||
resp_searchform(req, FOCUS_NONE);
|
||||
resp_show(req, file);
|
||||
resp_end_html();
|
||||
@ -956,9 +994,13 @@ pg_search(const struct req *req)
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == mansearch(&search, &paths, argc, argv, &res, &ressz))
|
||||
res = NULL;
|
||||
ressz = 0;
|
||||
if (req->isquery && req->q.equal && argc == 1)
|
||||
pg_redirect(req, argv[0]);
|
||||
else if (mansearch(&search, &paths, argc, argv, &res, &ressz) == 0)
|
||||
pg_noresult(req, "You entered an invalid query.");
|
||||
else if (0 == ressz)
|
||||
else if (ressz == 0)
|
||||
pg_noresult(req, "No results found.");
|
||||
else
|
||||
pg_searchres(req, res, ressz);
|
||||
@ -978,6 +1020,22 @@ main(void)
|
||||
const char *querystring;
|
||||
int i;
|
||||
|
||||
#if HAVE_PLEDGE
|
||||
/*
|
||||
* The "rpath" pledge could be revoked after mparse_readfd()
|
||||
* if the file desciptor to "/footer.html" would be opened
|
||||
* up front, but it's probably not worth the complication
|
||||
* of the code it would cause: it would require scattering
|
||||
* pledge() calls in multiple low-level resp_*() functions.
|
||||
*/
|
||||
|
||||
if (pledge("stdio rpath", NULL) == -1) {
|
||||
warn("pledge");
|
||||
pg_error_internal();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Poor man's ReDoS mitigation. */
|
||||
|
||||
itimer.it_value.tv_sec = 2;
|
||||
@ -1015,7 +1073,8 @@ main(void)
|
||||
|
||||
if (*path != '\0') {
|
||||
parse_path_info(&req, path);
|
||||
if (req.q.manpath == NULL || access(path, F_OK) == -1)
|
||||
if (req.q.manpath == NULL || req.q.sec == NULL ||
|
||||
*req.q.query == '\0' || access(path, F_OK) == -1)
|
||||
path = "";
|
||||
} else if ((querystring = getenv("QUERY_STRING")) != NULL)
|
||||
parse_query_string(&req, querystring);
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* Example compile-time configuration file for man.cgi(8). */
|
||||
|
||||
#define HTTP_HOST "mdocml.bsd.lv"
|
||||
#define SCRIPT_NAME "cgi-bin/man.cgi"
|
||||
#define MAN_DIR "/man"
|
||||
#define CSS_DIR ""
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: chars.c,v 1.69 2017/02/17 18:28:06 schwarze Exp $ */
|
||||
/* $Id: chars.c,v 1.70 2017/06/02 12:43:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -81,6 +81,10 @@ static struct ln lines[] = {
|
||||
{ "sh", "#", 0x0023 },
|
||||
{ "CR", "_|", 0x21b5 },
|
||||
{ "OK", "\\/", 0x2713 },
|
||||
{ "CL", "<club>", 0x2663 },
|
||||
{ "SP", "<spade>", 0x2660 },
|
||||
{ "HE", "<heart>", 0x2665 },
|
||||
{ "DI", "<diamond>", 0x2666 },
|
||||
|
||||
/* Legal symbols. */
|
||||
{ "co", "(C)", 0x00a9 },
|
||||
@ -161,6 +165,7 @@ static struct ln lines[] = {
|
||||
{ "uA", "=\b^", 0x21d1 },
|
||||
{ "dA", "=\bv", 0x21d3 },
|
||||
{ "vA", "^=v", 0x21d5 },
|
||||
{ "an", "-", 0x23af },
|
||||
|
||||
/* Logic. */
|
||||
{ "AN", "^", 0x2227 },
|
||||
@ -234,11 +239,20 @@ static struct ln lines[] = {
|
||||
{ "Ah", "N", 0x2135 },
|
||||
{ "Im", "I", 0x2111 },
|
||||
{ "Re", "R", 0x211c },
|
||||
{ "wp", "P", 0x2118 },
|
||||
{ "pd", "a", 0x2202 },
|
||||
{ "-h", "/h", 0x210f },
|
||||
{ "hbar", "/h", 0x210f },
|
||||
{ "12", "1/2", 0x00bd },
|
||||
{ "14", "1/4", 0x00bc },
|
||||
{ "34", "3/4", 0x00be },
|
||||
{ "18", "1/8", 0x215B },
|
||||
{ "38", "3/8", 0x215C },
|
||||
{ "58", "5/8", 0x215D },
|
||||
{ "78", "7/8", 0x215E },
|
||||
{ "S1", "1", 0x00B9 },
|
||||
{ "S2", "2", 0x00B2 },
|
||||
{ "S3", "3", 0x00B3 },
|
||||
|
||||
/* Ligatures. */
|
||||
{ "ff", "ff", 0xfb00 },
|
||||
@ -354,6 +368,8 @@ static struct ln lines[] = {
|
||||
{ "fm", "\'", 0x2032 },
|
||||
{ "sd", "''", 0x2033 },
|
||||
{ "mc", ",\bu", 0x00b5 },
|
||||
{ "Of", "_\ba", 0x00aa },
|
||||
{ "Om", "_\bo", 0x00ba },
|
||||
|
||||
/* Greek characters. */
|
||||
{ "*A", "A", 0x0391 },
|
||||
|
19
contrib/mdocml/configure
vendored
19
contrib/mdocml/configure
vendored
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: configure,v 1.61 2017/02/18 12:24:24 schwarze Exp $
|
||||
# $Id: configure,v 1.62 2017/03/04 16:36:29 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
@ -91,6 +91,7 @@ HAVE_WCHAR=
|
||||
PREFIX="/usr/local"
|
||||
BINDIR=
|
||||
SBINDIR=
|
||||
BIN_FROM_SBIN=
|
||||
INCLUDEDIR=
|
||||
LIBDIR=
|
||||
MANDIR=
|
||||
@ -458,14 +459,15 @@ echo "config.h: written" 1>&3
|
||||
|
||||
exec > Makefile.local
|
||||
|
||||
[ -z "${BINDIR}" ] && BINDIR="${PREFIX}/bin"
|
||||
[ -z "${SBINDIR}" ] && SBINDIR="${PREFIX}/sbin"
|
||||
[ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include/mandoc"
|
||||
[ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib/mandoc"
|
||||
[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man"
|
||||
[ -z "${BINDIR}" ] && BINDIR="${PREFIX}/bin"
|
||||
[ -z "${SBINDIR}" ] && SBINDIR="${PREFIX}/sbin"
|
||||
[ -z "${BIN_FROM_SBIN}" ] && BIN_FROM_SBIN="../bin"
|
||||
[ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include/mandoc"
|
||||
[ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib/mandoc"
|
||||
[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man"
|
||||
|
||||
[ -z "${HTDOCDIR}" ] && HTDOCDIR="${WWWPREFIX}/htdocs"
|
||||
[ -z "${CGIBINDIR}" ] && CGIBINDIR="${WWWPREFIX}/cgi-bin"
|
||||
[ -z "${HTDOCDIR}" ] && HTDOCDIR="${WWWPREFIX}/htdocs"
|
||||
[ -z "${CGIBINDIR}" ] && CGIBINDIR="${WWWPREFIX}/cgi-bin"
|
||||
|
||||
[ -z "${INSTALL_PROGRAM}" ] && INSTALL_PROGRAM="${INSTALL} -m 0555"
|
||||
[ -z "${INSTALL_LIB}" ] && INSTALL_LIB="${INSTALL} -m 0444"
|
||||
@ -493,6 +495,7 @@ STATIC = ${STATIC}
|
||||
PREFIX = ${PREFIX}
|
||||
BINDIR = ${BINDIR}
|
||||
SBINDIR = ${SBINDIR}
|
||||
BIN_FROM_SBIN = ${BIN_FROM_SBIN}
|
||||
INCLUDEDIR = ${INCLUDEDIR}
|
||||
LIBDIR = ${LIBDIR}
|
||||
MANDIR = ${MANDIR}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: configure.local.example,v 1.29 2017/02/18 12:24:24 schwarze Exp $
|
||||
# $Id: configure.local.example,v 1.30 2017/03/04 16:36:29 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
@ -85,6 +85,13 @@ BINDIR="${PREFIX}/bin"
|
||||
SBINDIR="${PREFIX}/sbin"
|
||||
MANDIR="${PREFIX}/man"
|
||||
|
||||
# If BINDIR and SBINDIR are not subdirectories of the same parent
|
||||
# directory or if the basename(1) of BINDIR differs from "bin",
|
||||
# the relative path from SBINDIR to BINDIR is also needed.
|
||||
# The default is:
|
||||
|
||||
BIN_FROM_SBIN="../bin"
|
||||
|
||||
# Some distributions may want to avoid naming conflicts
|
||||
# with the configuration files of other man(1) implementations.
|
||||
# This changes the name of the installed section 5 manual page as well.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: eqn.c,v 1.61 2016/01/08 00:50:45 schwarze Exp $ */
|
||||
/* $Id: eqn.c,v 1.62 2017/03/11 15:43:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -366,15 +366,19 @@ eqn_def_find(struct eqn_node *ep, const char *key, size_t sz)
|
||||
static const char *
|
||||
eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
||||
{
|
||||
static size_t last_len;
|
||||
static int lim;
|
||||
|
||||
char *start, *next;
|
||||
int q, diff, lim;
|
||||
int q, diff;
|
||||
size_t ssz, dummy;
|
||||
struct eqn_def *def;
|
||||
|
||||
if (NULL == sz)
|
||||
sz = &dummy;
|
||||
|
||||
lim = 0;
|
||||
if (ep->cur >= last_len)
|
||||
lim = 0;
|
||||
ep->rew = ep->cur;
|
||||
again:
|
||||
/* Prevent self-definitions. */
|
||||
@ -448,6 +452,7 @@ eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
|
||||
memmove(start + *sz + diff, start + *sz,
|
||||
(strlen(start) - *sz) + 1);
|
||||
memcpy(start, def->val, def->valsz);
|
||||
last_len = start - ep->data + def->valsz;
|
||||
lim++;
|
||||
goto again;
|
||||
}
|
||||
|
@ -29,21 +29,24 @@ if [ "X$1" = "X-h" ]; then
|
||||
EQN="neqn"
|
||||
ROFF="nroff"
|
||||
MOPT="-Omdoc $MOPT"
|
||||
elif [ "X$1" = "X-u" ]; then
|
||||
shift
|
||||
ROFF="groff -ket -ww -Tutf8 -P -c"
|
||||
MOPT="-Werror -Tutf8 $MOPT"
|
||||
else
|
||||
EQN="eqn -Tascii"
|
||||
ROFF="groff -ww -Tascii -P -c"
|
||||
ROFF="groff -et -ww -Tascii -P -c"
|
||||
MOPT="-Werror -Tascii $MOPT"
|
||||
fi
|
||||
MOPT="-Werror -Tascii $MOPT"
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
file=$1
|
||||
shift
|
||||
echo " ========== $file ========== "
|
||||
tbl $file | $EQN | $ROFF -mandoc 2> /tmp/roff.err > /tmp/roff.out
|
||||
$ROFF -mandoc $file 2> /tmp/roff.err > /tmp/roff.out
|
||||
${MANDOC:=mandoc} -Ios='OpenBSD ports' $MOPT $file \
|
||||
2> /tmp/mandoc.err > /tmp/mandoc.out
|
||||
for i in roff mandoc; do
|
||||
[[ -s /tmp/$i.err ]] && echo "$i errors:" && cat /tmp/$i.err
|
||||
[ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err
|
||||
done
|
||||
diff -au /tmp/roff.out /tmp/mandoc.out 2>&1
|
||||
done
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: html.c,v 1.207 2017/02/05 20:22:04 schwarze Exp $ */
|
||||
/* $Id: html.c,v 1.213 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -28,8 +28,9 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "mandoc_aux.h"
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
#include "manconf.h"
|
||||
@ -236,6 +237,28 @@ print_metaf(struct html *h, enum mandoc_esc deco)
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
html_make_id(const struct roff_node *n)
|
||||
{
|
||||
const struct roff_node *nch;
|
||||
char *buf, *cp;
|
||||
|
||||
for (nch = n->child; nch != NULL; nch = nch->next)
|
||||
if (nch->type != ROFFT_TEXT)
|
||||
return NULL;
|
||||
|
||||
buf = NULL;
|
||||
deroff(&buf, n);
|
||||
|
||||
/* http://www.w3.org/TR/html5/dom.html#the-id-attribute */
|
||||
|
||||
for (cp = buf; *cp != '\0'; cp++)
|
||||
if (*cp == ' ')
|
||||
*cp = '_';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
html_strlen(const char *cp)
|
||||
{
|
||||
@ -534,18 +557,25 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
print_byte(h, '=');
|
||||
print_byte(h, '"');
|
||||
switch (*fmt) {
|
||||
case 'M':
|
||||
print_href(h, arg1, arg2, 1);
|
||||
fmt++;
|
||||
break;
|
||||
case 'I':
|
||||
print_href(h, arg1, NULL, 0);
|
||||
fmt++;
|
||||
break;
|
||||
case 'M':
|
||||
print_href(h, arg1, arg2, 1);
|
||||
fmt++;
|
||||
break;
|
||||
case 'R':
|
||||
print_byte(h, '#');
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
fmt++;
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
case 'T':
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
print_word(h, "\" title=\"");
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
fmt++;
|
||||
break;
|
||||
default:
|
||||
print_encode(h, arg1, NULL, 1);
|
||||
break;
|
||||
@ -579,13 +609,21 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...)
|
||||
SCALE_VS_INIT(su, i);
|
||||
break;
|
||||
case 'w':
|
||||
case 'W':
|
||||
if ((arg2 = va_arg(ap, char *)) == NULL)
|
||||
break;
|
||||
su = &mysu;
|
||||
a2width(arg2, su);
|
||||
if (fmt[-1] == 'W')
|
||||
if (*fmt == '+') {
|
||||
/* Increase to make even bold text fit. */
|
||||
su->scale *= 1.2;
|
||||
/* Add padding. */
|
||||
su->scale += 3.0;
|
||||
fmt++;
|
||||
}
|
||||
if (*fmt == '-') {
|
||||
su->scale *= -1.0;
|
||||
fmt++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
@ -912,7 +950,10 @@ print_word(struct html *h, const char *cp)
|
||||
static void
|
||||
a2width(const char *p, struct roffsu *su)
|
||||
{
|
||||
if (a2roffsu(p, su, SCALE_MAX) < 2) {
|
||||
const char *end;
|
||||
|
||||
end = a2roffsu(p, su, SCALE_MAX);
|
||||
if (end == NULL || *end != '\0') {
|
||||
su->unit = SCALE_EN;
|
||||
su->scale = html_strlen(p);
|
||||
} else if (su->scale < 0.0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: html.h,v 1.83 2017/02/05 20:22:04 schwarze Exp $ */
|
||||
/* $Id: html.h,v 1.85 2017/05/04 22:16:09 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -112,9 +112,12 @@ struct html {
|
||||
};
|
||||
|
||||
|
||||
struct roff_node;
|
||||
struct tbl_span;
|
||||
struct eqn;
|
||||
|
||||
void roff_html_pre(struct html *, const struct roff_node *);
|
||||
|
||||
void print_gen_decls(struct html *);
|
||||
void print_gen_head(struct html *);
|
||||
struct tag *print_otag(struct html *, enum htmltag, const char *, ...);
|
||||
@ -127,4 +130,5 @@ void print_eqn(struct html *, const struct eqn *);
|
||||
void print_paragraph(struct html *);
|
||||
void print_endline(struct html *);
|
||||
|
||||
char *html_make_id(const struct roff_node *);
|
||||
int html_strlen(const char *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: libman.h,v 1.79 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: libman.h,v 1.81 2017/04/29 12:45:41 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#define MACRO_PROT_ARGS struct roff_man *man, \
|
||||
int tok, \
|
||||
enum roff_tok tok, \
|
||||
int line, \
|
||||
int ppos, \
|
||||
int *pos, \
|
||||
@ -35,7 +35,6 @@ struct man_macro {
|
||||
extern const struct man_macro *const man_macros;
|
||||
|
||||
|
||||
int man_hash_find(const char *);
|
||||
void man_node_validate(struct roff_man *);
|
||||
void man_state(struct roff_man *, struct roff_node *);
|
||||
void man_unscope(struct roff_man *, const struct roff_node *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: libmandoc.h,v 1.66 2017/02/18 13:43:52 schwarze Exp $ */
|
||||
/* $Id: libmandoc.h,v 1.67 2017/04/29 12:45:41 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -50,11 +50,9 @@ int mandoc_eos(const char *, size_t);
|
||||
int mandoc_strntoi(const char *, size_t, int);
|
||||
const char *mandoc_a2msec(const char*);
|
||||
|
||||
void mdoc_hash_init(void);
|
||||
int mdoc_parseln(struct roff_man *, int, char *, int);
|
||||
void mdoc_endparse(struct roff_man *);
|
||||
|
||||
void man_hash_init(void);
|
||||
int man_parseln(struct roff_man *, int, char *, int);
|
||||
void man_endparse(struct roff_man *);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: libmdoc.h,v 1.109 2017/02/16 03:00:23 schwarze Exp $ */
|
||||
/* $Id: libmdoc.h,v 1.112 2017/05/30 16:22:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#define MACRO_PROT_ARGS struct roff_man *mdoc, \
|
||||
int tok, \
|
||||
enum roff_tok tok, \
|
||||
int line, \
|
||||
int ppos, \
|
||||
int *pos, \
|
||||
@ -39,7 +39,6 @@ enum margserr {
|
||||
ARGS_EOLN, /* end-of-line */
|
||||
ARGS_WORD, /* normal word */
|
||||
ARGS_PUNCT, /* series of punctuation */
|
||||
ARGS_QWORD, /* quoted word */
|
||||
ARGS_PHRASE /* Bl -column phrase */
|
||||
};
|
||||
|
||||
@ -65,24 +64,24 @@ extern const struct mdoc_macro *const mdoc_macros;
|
||||
|
||||
void mdoc_macro(MACRO_PROT_ARGS);
|
||||
void mdoc_elem_alloc(struct roff_man *, int, int,
|
||||
int, struct mdoc_arg *);
|
||||
enum roff_tok, struct mdoc_arg *);
|
||||
struct roff_node *mdoc_block_alloc(struct roff_man *, int, int,
|
||||
int, struct mdoc_arg *);
|
||||
void mdoc_tail_alloc(struct roff_man *, int, int, int);
|
||||
struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int, int,
|
||||
struct roff_node *);
|
||||
enum roff_tok, struct mdoc_arg *);
|
||||
void mdoc_tail_alloc(struct roff_man *, int, int,
|
||||
enum roff_tok);
|
||||
struct roff_node *mdoc_endbody_alloc(struct roff_man *, int, int,
|
||||
enum roff_tok, struct roff_node *);
|
||||
void mdoc_node_relink(struct roff_man *, struct roff_node *);
|
||||
void mdoc_node_validate(struct roff_man *);
|
||||
void mdoc_state(struct roff_man *, struct roff_node *);
|
||||
void mdoc_state_reset(struct roff_man *);
|
||||
int mdoc_hash_find(const char *);
|
||||
const char *mdoc_a2arch(const char *);
|
||||
const char *mdoc_a2att(const char *);
|
||||
const char *mdoc_a2lib(const char *);
|
||||
enum roff_sec mdoc_a2sec(const char *);
|
||||
const char *mdoc_a2st(const char *);
|
||||
void mdoc_argv(struct roff_man *, int, int,
|
||||
void mdoc_argv(struct roff_man *, int, enum roff_tok,
|
||||
struct mdoc_arg **, int *, char *);
|
||||
enum margserr mdoc_args(struct roff_man *, int,
|
||||
int *, char *, int, char **);
|
||||
int *, char *, enum roff_tok, char **);
|
||||
enum mdelim mdoc_isdelim(const char *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: main.c,v 1.283 2017/02/17 14:31:52 schwarze Exp $ */
|
||||
/* $Id: main.c,v 1.292 2017/06/03 12:17:25 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -56,7 +56,6 @@ enum outmode {
|
||||
OUTMODE_FLN,
|
||||
OUTMODE_LST,
|
||||
OUTMODE_ALL,
|
||||
OUTMODE_INT,
|
||||
OUTMODE_ONE
|
||||
};
|
||||
|
||||
@ -67,6 +66,7 @@ enum outt {
|
||||
OUTT_TREE, /* -Ttree */
|
||||
OUTT_MAN, /* -Tman */
|
||||
OUTT_HTML, /* -Thtml */
|
||||
OUTT_MARKDOWN, /* -Tmarkdown */
|
||||
OUTT_LINT, /* -Tlint */
|
||||
OUTT_PS, /* -Tps */
|
||||
OUTT_PDF /* -Tpdf */
|
||||
@ -92,7 +92,7 @@ static void fs_search(const struct mansearch *,
|
||||
const struct manpaths *, int, char**,
|
||||
struct manpage **, size_t *);
|
||||
static int koptions(int *, char *);
|
||||
static int moptions(int *, char *);
|
||||
static void moptions(int *, char *);
|
||||
static void mmsg(enum mandocerr, enum mandoclevel,
|
||||
const char *, int, int, const char *);
|
||||
static void outdata_alloc(struct curparse *);
|
||||
@ -149,7 +149,7 @@ main(int argc, char *argv[])
|
||||
return mandocdb(argc, argv);
|
||||
|
||||
#if HAVE_PLEDGE
|
||||
if (pledge("stdio rpath tmppath tty proc exec flock", NULL) == -1)
|
||||
if (pledge("stdio rpath tmppath tty proc exec", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
#endif
|
||||
|
||||
@ -193,8 +193,12 @@ main(int argc, char *argv[])
|
||||
show_usage = 0;
|
||||
outmode = OUTMODE_DEF;
|
||||
|
||||
while (-1 != (c = getopt(argc, argv,
|
||||
"aC:cfhI:iK:klM:m:O:S:s:T:VW:w"))) {
|
||||
while ((c = getopt(argc, argv,
|
||||
"aC:cfhI:iK:klM:m:O:S:s:T:VW:w")) != -1) {
|
||||
if (c == 'i' && search.argmode == ARG_EXPR) {
|
||||
optind--;
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case 'a':
|
||||
outmode = OUTMODE_ALL;
|
||||
@ -224,9 +228,6 @@ main(int argc, char *argv[])
|
||||
}
|
||||
defos = mandoc_strdup(optarg + 3);
|
||||
break;
|
||||
case 'i':
|
||||
outmode = OUTMODE_INT;
|
||||
break;
|
||||
case 'K':
|
||||
if ( ! koptions(&options, optarg))
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
@ -312,7 +313,7 @@ main(int argc, char *argv[])
|
||||
|
||||
#if HAVE_PLEDGE
|
||||
if (!use_pager)
|
||||
if (pledge("stdio rpath flock", NULL) == -1)
|
||||
if (pledge("stdio rpath", NULL) == -1)
|
||||
err((int)MANDOCLEVEL_SYSERR, "pledge");
|
||||
#endif
|
||||
|
||||
@ -441,8 +442,8 @@ main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
if (search.argmode == ARG_FILE && ! moptions(&options, auxpaths))
|
||||
return (int)MANDOCLEVEL_BADARG;
|
||||
if (search.argmode == ARG_FILE)
|
||||
moptions(&options, auxpaths);
|
||||
|
||||
mchars_alloc();
|
||||
curp.mp = mparse_alloc(options, curp.wlevel, mmsg, defos);
|
||||
@ -591,24 +592,22 @@ usage(enum argmode argmode)
|
||||
|
||||
switch (argmode) {
|
||||
case ARG_FILE:
|
||||
fputs("usage: mandoc [-acfhkl] [-I os=name] "
|
||||
"[-K encoding] [-mformat] [-O option]\n"
|
||||
fputs("usage: mandoc [-ac] [-I os=name] "
|
||||
"[-K encoding] [-mdoc | -man] [-O options]\n"
|
||||
"\t [-T output] [-W level] [file ...]\n", stderr);
|
||||
break;
|
||||
case ARG_NAME:
|
||||
fputs("usage: man [-acfhklw] [-C file] [-I os=name] "
|
||||
"[-K encoding] [-M path] [-m path]\n"
|
||||
"\t [-O option=value] [-S subsection] [-s section] "
|
||||
"[-T output] [-W level]\n"
|
||||
"\t [section] name ...\n", stderr);
|
||||
fputs("usage: man [-acfhklw] [-C file] [-M path] "
|
||||
"[-m path] [-S subsection]\n"
|
||||
"\t [[-s] section] name ...\n", stderr);
|
||||
break;
|
||||
case ARG_WORD:
|
||||
fputs("usage: whatis [-acfhklw] [-C file] "
|
||||
fputs("usage: whatis [-afk] [-C file] "
|
||||
"[-M path] [-m path] [-O outkey] [-S arch]\n"
|
||||
"\t [-s section] name ...\n", stderr);
|
||||
break;
|
||||
case ARG_EXPR:
|
||||
fputs("usage: apropos [-acfhklw] [-C file] "
|
||||
fputs("usage: apropos [-afk] [-C file] "
|
||||
"[-M path] [-m path] [-O outkey] [-S arch]\n"
|
||||
"\t [-s section] expression ...\n", stderr);
|
||||
break;
|
||||
@ -766,6 +765,9 @@ parse(struct curparse *curp, int fd, const char *file)
|
||||
case OUTT_PS:
|
||||
terminal_mdoc(curp->outdata, man);
|
||||
break;
|
||||
case OUTT_MARKDOWN:
|
||||
markdown_mdoc(curp->outdata, man);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -915,24 +917,16 @@ koptions(int *options, char *arg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
moptions(int *options, char *arg)
|
||||
{
|
||||
|
||||
if (arg == NULL)
|
||||
/* nothing to do */;
|
||||
else if (0 == strcmp(arg, "doc"))
|
||||
return;
|
||||
if (strcmp(arg, "doc") == 0)
|
||||
*options |= MPARSE_MDOC;
|
||||
else if (0 == strcmp(arg, "andoc"))
|
||||
/* nothing to do */;
|
||||
else if (0 == strcmp(arg, "an"))
|
||||
else if (strcmp(arg, "an") == 0)
|
||||
*options |= MPARSE_MAN;
|
||||
else {
|
||||
warnx("-m %s: Bad argument", arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -943,19 +937,19 @@ toptions(struct curparse *curp, char *arg)
|
||||
curp->outtype = OUTT_ASCII;
|
||||
else if (0 == strcmp(arg, "lint")) {
|
||||
curp->outtype = OUTT_LINT;
|
||||
curp->wlevel = MANDOCLEVEL_WARNING;
|
||||
curp->wlevel = MANDOCLEVEL_STYLE;
|
||||
} else if (0 == strcmp(arg, "tree"))
|
||||
curp->outtype = OUTT_TREE;
|
||||
else if (0 == strcmp(arg, "man"))
|
||||
curp->outtype = OUTT_MAN;
|
||||
else if (0 == strcmp(arg, "html"))
|
||||
curp->outtype = OUTT_HTML;
|
||||
else if (0 == strcmp(arg, "markdown"))
|
||||
curp->outtype = OUTT_MARKDOWN;
|
||||
else if (0 == strcmp(arg, "utf8"))
|
||||
curp->outtype = OUTT_UTF8;
|
||||
else if (0 == strcmp(arg, "locale"))
|
||||
curp->outtype = OUTT_LOCALE;
|
||||
else if (0 == strcmp(arg, "xhtml"))
|
||||
curp->outtype = OUTT_HTML;
|
||||
else if (0 == strcmp(arg, "ps"))
|
||||
curp->outtype = OUTT_PS;
|
||||
else if (0 == strcmp(arg, "pdf"))
|
||||
@ -972,15 +966,16 @@ static int
|
||||
woptions(struct curparse *curp, char *arg)
|
||||
{
|
||||
char *v, *o;
|
||||
const char *toks[7];
|
||||
const char *toks[8];
|
||||
|
||||
toks[0] = "stop";
|
||||
toks[1] = "all";
|
||||
toks[2] = "warning";
|
||||
toks[3] = "error";
|
||||
toks[4] = "unsupp";
|
||||
toks[5] = "fatal";
|
||||
toks[6] = NULL;
|
||||
toks[2] = "style";
|
||||
toks[3] = "warning";
|
||||
toks[4] = "error";
|
||||
toks[5] = "unsupp";
|
||||
toks[6] = "fatal";
|
||||
toks[7] = NULL;
|
||||
|
||||
while (*arg) {
|
||||
o = arg;
|
||||
@ -990,15 +985,18 @@ woptions(struct curparse *curp, char *arg)
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
curp->wlevel = MANDOCLEVEL_WARNING;
|
||||
curp->wlevel = MANDOCLEVEL_STYLE;
|
||||
break;
|
||||
case 3:
|
||||
curp->wlevel = MANDOCLEVEL_ERROR;
|
||||
curp->wlevel = MANDOCLEVEL_WARNING;
|
||||
break;
|
||||
case 4:
|
||||
curp->wlevel = MANDOCLEVEL_UNSUPP;
|
||||
curp->wlevel = MANDOCLEVEL_ERROR;
|
||||
break;
|
||||
case 5:
|
||||
curp->wlevel = MANDOCLEVEL_UNSUPP;
|
||||
break;
|
||||
case 6:
|
||||
curp->wlevel = MANDOCLEVEL_BADARG;
|
||||
break;
|
||||
default:
|
||||
@ -1006,7 +1004,6 @@ woptions(struct curparse *curp, char *arg)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: main.h,v 1.26 2016/07/15 19:33:01 schwarze Exp $ */
|
||||
/* $Id: main.h,v 1.27 2017/03/03 14:23:23 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -49,3 +49,5 @@ void pspdf_free(void *);
|
||||
void terminal_mdoc(void *, const struct roff_man *);
|
||||
void terminal_man(void *, const struct roff_man *);
|
||||
void terminal_sepline(void *);
|
||||
|
||||
void markdown_mdoc(void *, const struct roff_man *);
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: makewhatis.8,v 1.4 2016/07/19 22:40:33 schwarze Exp $
|
||||
.\" $Id: makewhatis.8,v 1.6 2017/05/17 22:27:12 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 19 2016 $
|
||||
.Dd $Mdocdate: May 17 2017 $
|
||||
.Dt MAKEWHATIS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -74,6 +74,8 @@ and
|
||||
.Sm on
|
||||
in that directory.
|
||||
Existing databases are replaced.
|
||||
If a directory contains no manual pages, no database is created in that
|
||||
directory.
|
||||
If
|
||||
.Ar dir
|
||||
is not provided,
|
||||
@ -130,11 +132,22 @@ Remove
|
||||
.Ar
|
||||
from the database in
|
||||
.Ar dir .
|
||||
If that causes the database to become empty, also delete the database file.
|
||||
.El
|
||||
.Pp
|
||||
If fatal parse errors are encountered while parsing, the offending file
|
||||
is printed to stderr, omitted from the index, and the parse continues
|
||||
with the next input file.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width MANPATH
|
||||
.It Ev MANPATH
|
||||
A colon-separated list of directories to create databases in.
|
||||
Ignored if a
|
||||
.Ar dir
|
||||
argument or the
|
||||
.Fl t
|
||||
option is specified.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa mandoc.db
|
||||
|
@ -1,9 +1,9 @@
|
||||
.\" $Id: man.1,v 1.21 2017/01/31 19:44:04 schwarze Exp $
|
||||
.\" $Id: man.1,v 1.29 2017/05/17 23:23:00 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1989, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\" Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2010, 2011, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" @(#)man.1 8.2 (Berkeley) 1/2/94
|
||||
.\"
|
||||
.Dd $Mdocdate: January 31 2017 $
|
||||
.Dd $Mdocdate: May 17 2017 $
|
||||
.Dt MAN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -41,16 +41,10 @@
|
||||
.Nm man
|
||||
.Op Fl acfhklw
|
||||
.Op Fl C Ar file
|
||||
.Op Fl I Cm os Ns = Ns Ar name
|
||||
.Op Fl K Ar encoding
|
||||
.Op Fl M Ar path
|
||||
.Op Fl m Ar path
|
||||
.Op Fl O Ar option Ns = Ns Ar value
|
||||
.Op Fl S Ar subsection
|
||||
.Op Fl s Ar section
|
||||
.Op Fl T Ar output
|
||||
.Op Fl W Ar level
|
||||
.Op Ar section
|
||||
.Op Oo Fl s Oc Ar section
|
||||
.Ar name ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
@ -91,39 +85,12 @@ It searches for
|
||||
.Ar name
|
||||
in manual page names and displays the header lines from all matching pages.
|
||||
The search is case insensitive and matches whole words only.
|
||||
This overrides any earlier
|
||||
.Fl k
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
.It Fl h
|
||||
Display only the SYNOPSIS lines of the requested manual pages.
|
||||
Implies
|
||||
.Fl a
|
||||
and
|
||||
.Fl c .
|
||||
.It Fl I Cm os Ns = Ns Ar name
|
||||
Override the default operating system
|
||||
.Ar name
|
||||
for the
|
||||
.Xr mdoc 7
|
||||
.Ic \&Os
|
||||
and for the
|
||||
.Xr man 7
|
||||
.Ic \&TH
|
||||
macro.
|
||||
.It Fl K Ar encoding
|
||||
Specify the input encoding.
|
||||
The supported
|
||||
.Ar encoding
|
||||
arguments are
|
||||
.Cm us-ascii ,
|
||||
.Cm iso-8859-1 ,
|
||||
and
|
||||
.Cm utf-8 .
|
||||
By default, the encoding is automatically detected as described in the
|
||||
.Xr mandoc 1
|
||||
manual.
|
||||
.It Fl k
|
||||
A synonym for
|
||||
.Xr apropos 1 .
|
||||
@ -133,11 +100,6 @@ an expression can be provided using the syntax described in the
|
||||
.Xr apropos 1
|
||||
manual.
|
||||
By default, it displays the header lines of all matching pages.
|
||||
This overrides any earlier
|
||||
.Fl f
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
.It Fl l
|
||||
A synonym for
|
||||
.Xr mandoc 1
|
||||
@ -149,15 +111,10 @@ No search is done and
|
||||
.Ar file ,
|
||||
.Ar path ,
|
||||
.Ar section ,
|
||||
and
|
||||
.Ar subsection
|
||||
are ignored.
|
||||
This overrides any earlier
|
||||
.Fl f ,
|
||||
.Fl k ,
|
||||
.Ar subsection ,
|
||||
and
|
||||
.Fl w
|
||||
options.
|
||||
are ignored.
|
||||
.It Fl M Ar path
|
||||
Override the list of standard directories which
|
||||
.Nm
|
||||
@ -184,15 +141,8 @@ the directories specified using the
|
||||
option or the
|
||||
.Ev MANPATH
|
||||
environment variable.
|
||||
.It Fl O Ar option Ns = Ns Ar value
|
||||
Comma-separated output options.
|
||||
For each output format, the available options are described in the
|
||||
.Xr mandoc 1
|
||||
manual.
|
||||
.It Fl S Ar subsection
|
||||
Restricts the directories that
|
||||
.Nm
|
||||
will search to those of a specific
|
||||
Only show pages for the specified
|
||||
.Xr machine 1
|
||||
architecture.
|
||||
.Ar subsection
|
||||
@ -234,53 +184,23 @@ System maintenance and operation commands.
|
||||
.It 9
|
||||
Kernel internals.
|
||||
.El
|
||||
.It Fl T Ar output
|
||||
Select the output format.
|
||||
The default is
|
||||
.Cm locale .
|
||||
The other output modes
|
||||
.Cm ascii ,
|
||||
.Cm html ,
|
||||
.Cm lint ,
|
||||
.Cm man ,
|
||||
.Cm pdf ,
|
||||
.Cm ps ,
|
||||
.Cm tree ,
|
||||
and
|
||||
.Cm utf8
|
||||
are described in the
|
||||
.Xr mandoc 1
|
||||
manual.
|
||||
.It Fl W Ar level
|
||||
Specify the minimum message
|
||||
.Ar level
|
||||
to be reported on the standard error output and to affect the exit status.
|
||||
The
|
||||
.Ar level
|
||||
can be
|
||||
.Cm warning ,
|
||||
.Cm error ,
|
||||
or
|
||||
.Cm unsupp ;
|
||||
.Cm all
|
||||
is an alias for
|
||||
.Cm warning .
|
||||
By default,
|
||||
.Nm
|
||||
is silent.
|
||||
See the
|
||||
.Xr mandoc 1
|
||||
manual for details.
|
||||
.Pp
|
||||
If not specified and a match is found in more than one section,
|
||||
the first match is selected from the following list:
|
||||
1, 8, 6, 2, 3, 5, 7, 4, 9, 3p.
|
||||
.It Fl w
|
||||
List the pathnames of the manual pages which
|
||||
.Nm
|
||||
would display for the specified
|
||||
.Ar section
|
||||
and
|
||||
.Ar name
|
||||
combination.
|
||||
List the pathnames of all matching manual pages instead of displaying
|
||||
any of them.
|
||||
.El
|
||||
.Pp
|
||||
The options
|
||||
.Fl IKOTW
|
||||
are also supported and are documented in
|
||||
.Xr mandoc 1 .
|
||||
The options
|
||||
.Fl fkl
|
||||
are mutually exclusive and override each other.
|
||||
.Pp
|
||||
Guidelines for writing
|
||||
man pages can be found in
|
||||
.Xr mdoc 7 .
|
||||
@ -290,13 +210,7 @@ for example
|
||||
.Pa cat1/foo.0
|
||||
and
|
||||
.Pa man1/foo.1 ,
|
||||
exist in the same directory, and at least one of them is selected,
|
||||
only the newer one is used.
|
||||
However, if both the
|
||||
.Fl a
|
||||
and the
|
||||
.Fl w
|
||||
options are specified, both file names are printed.
|
||||
exist in the same directory, only the unformatted version is used.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width MANPATHX
|
||||
.It Ev MACHINE
|
||||
@ -318,7 +232,7 @@ is case insensitive.
|
||||
.It Ev MANPAGER
|
||||
Any non-empty value of the environment variable
|
||||
.Ev MANPAGER
|
||||
will be used instead of the standard pagination program,
|
||||
is used instead of the standard pagination program,
|
||||
.Xr more 1 .
|
||||
If
|
||||
.Xr less 1
|
||||
@ -342,13 +256,27 @@ information about the term last searched for with
|
||||
.It Ev MANPATH
|
||||
The standard search path used by
|
||||
.Nm
|
||||
may be overridden by specifying a path in the
|
||||
may be changed by specifying a path in the
|
||||
.Ev MANPATH
|
||||
environment
|
||||
variable.
|
||||
environment variable.
|
||||
The format of the path is a colon
|
||||
.Pq Ql \&:
|
||||
separated list of directories.
|
||||
Invalid paths are ignored.
|
||||
Overridden by
|
||||
.Fl M ,
|
||||
ignored if
|
||||
.Fl l
|
||||
is specified.
|
||||
.Pp
|
||||
If
|
||||
.Ev MANPATH
|
||||
begins with a colon, it is appended to the default list;
|
||||
if it ends with a colon, it is prepended to the default list;
|
||||
or if it contains two adjacent colons,
|
||||
the standard search path is inserted between the colons.
|
||||
If none of these conditions are met, it overrides the
|
||||
standard search path.
|
||||
.It Ev PAGER
|
||||
Specifies the pagination program to use when
|
||||
.Ev MANPAGER
|
||||
@ -356,7 +284,12 @@ is not defined.
|
||||
If neither PAGER nor MANPAGER is defined,
|
||||
.Xr more 1
|
||||
.Fl s
|
||||
will be used.
|
||||
is used.
|
||||
Only used if
|
||||
.Fl a
|
||||
or
|
||||
.Fl l
|
||||
is specified.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/man.conf -compact
|
||||
@ -365,10 +298,12 @@ default man configuration file
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std man
|
||||
See
|
||||
.Xr mandoc 1
|
||||
for details.
|
||||
.Sh SEE ALSO
|
||||
.Xr apropos 1 ,
|
||||
.Xr intro 1 ,
|
||||
.Xr whatis 1 ,
|
||||
.Xr whereis 1 ,
|
||||
.Xr intro 2 ,
|
||||
.Xr intro 3 ,
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: man.7,v 1.132 2015/01/29 00:33:57 schwarze Exp $
|
||||
.\" $Id: man.7,v 1.135 2017/05/07 21:44:49 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 29 2015 $
|
||||
.Dd $Mdocdate: May 7 2017 $
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -266,8 +266,6 @@ in the alphabetical reference below.
|
||||
.It Sx TP Ta tagged paragraph: Op Ar width
|
||||
.It Sx HP Ta hanged paragraph: Op Ar width
|
||||
.It Sx PD Ta set vertical paragraph distance: Op Ar height
|
||||
.It Sx \&br Ta force output line break in text mode (no arguments)
|
||||
.It Sx \&sp Ta force vertical space: Op Ar height
|
||||
.It Sx fi , nf Ta fill mode and no-fill mode (no arguments)
|
||||
.It Sx in Ta additional indent: Op Ar width
|
||||
.El
|
||||
@ -350,8 +348,12 @@ See also
|
||||
and
|
||||
.Sx \&IR .
|
||||
.Ss \&DT
|
||||
Has no effect.
|
||||
Included for compatibility.
|
||||
Restore the default tabulator positions.
|
||||
They are at intervals of 0.5 inches.
|
||||
This has no effect unless the tabulator positions were changed with the
|
||||
.Xr roff 7
|
||||
.Ic \&ta
|
||||
request.
|
||||
.Ss \&EE
|
||||
This is a non-standard GNU extension, included only for compatibility.
|
||||
In
|
||||
@ -708,12 +710,6 @@ It has the following syntax:
|
||||
link description to be shown
|
||||
.Pf \. Sx UE
|
||||
.Ed
|
||||
.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 .
|
||||
@ -736,24 +732,6 @@ Literal mode is implicitly ended by
|
||||
.Sx \&SH
|
||||
or
|
||||
.Sx \&SS .
|
||||
.Ss \&sp
|
||||
Insert vertical spaces into output with the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&sp
|
||||
.Op Ar height
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Ar height
|
||||
argument is a scaling width as described in
|
||||
.Xr roff 7 .
|
||||
If 0, this is equivalent to the
|
||||
.Sx \&br
|
||||
macro.
|
||||
Defaults to 1, if unspecified.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&br .
|
||||
.Sh MACRO SYNTAX
|
||||
The
|
||||
.Nm
|
||||
@ -777,10 +755,7 @@ 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, except for
|
||||
.Sx \&br
|
||||
and
|
||||
.Sx \&sp .
|
||||
raised.
|
||||
.Pp
|
||||
The syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
@ -808,11 +783,9 @@ The syntax is as follows:
|
||||
.It Sx \&SM Ta n Ta next-line Ta \&
|
||||
.It Sx \&TH Ta >1, <6 Ta current Ta \&
|
||||
.It Sx \&UC Ta <=1 Ta current Ta \&
|
||||
.It Sx \&br Ta 0 Ta current Ta compat
|
||||
.It Sx \&fi Ta 0 Ta current Ta compat
|
||||
.It Sx \&in Ta 1 Ta current Ta compat
|
||||
.It Sx \&nf Ta 0 Ta current Ta compat
|
||||
.It Sx \&sp Ta 1 Ta current Ta compat
|
||||
.El
|
||||
.Pp
|
||||
Macros marked as
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: man.c,v 1.167 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/* $Id: man.c,v 1.174 2017/06/03 15:55:24 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011 Joerg Sonnenberger <joerg@netbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -35,21 +35,6 @@
|
||||
#include "roff_int.h"
|
||||
#include "libman.h"
|
||||
|
||||
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", "sp", "nf",
|
||||
"fi", "RE", "RS", "DT",
|
||||
"UC", "PD", "AT", "in",
|
||||
"ft", "OP", "EX", "EE",
|
||||
"UR", "UE", "ll"
|
||||
};
|
||||
|
||||
const char * const *man_macronames = __man_macronames;
|
||||
|
||||
static void man_descope(struct roff_man *, int, int);
|
||||
static int man_ptext(struct roff_man *, int, char *, int);
|
||||
static int man_pmacro(struct roff_man *, int, char *, int);
|
||||
@ -104,15 +89,17 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
|
||||
/* Skip leading whitespace. */ ;
|
||||
|
||||
/*
|
||||
* Blank lines are ignored right after headings
|
||||
* but add a single vertical space elsewhere.
|
||||
* Blank lines are ignored in next line scope and right
|
||||
* after headings but add a single vertical space elsewhere.
|
||||
*/
|
||||
|
||||
if (buf[i] == '\0') {
|
||||
/* Allocate a blank entry. */
|
||||
if (man->last->tok != MAN_SH &&
|
||||
if (man->flags & (MAN_ELINE | MAN_BLINE))
|
||||
mandoc_msg(MANDOCERR_BLK_BLANK, man->parse,
|
||||
line, 0, NULL);
|
||||
else if (man->last->tok != MAN_SH &&
|
||||
man->last->tok != MAN_SS) {
|
||||
roff_elem_alloc(man, line, offs, MAN_sp);
|
||||
roff_elem_alloc(man, line, offs, ROFF_sp);
|
||||
man->next = ROFF_NEXT_SIBLING;
|
||||
}
|
||||
return 1;
|
||||
@ -160,26 +147,19 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *cp;
|
||||
int tok;
|
||||
int i, ppos;
|
||||
size_t sz;
|
||||
enum roff_tok tok;
|
||||
int ppos;
|
||||
int bline;
|
||||
char mac[5];
|
||||
|
||||
/* Determine the line macro. */
|
||||
|
||||
ppos = offs;
|
||||
|
||||
/*
|
||||
* Copy the first word into a nil-terminated buffer.
|
||||
* Stop when a space, tab, escape, or eoln is encountered.
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
while (i < 4 && strchr(" \t\\", buf[offs]) == NULL)
|
||||
mac[i++] = buf[offs++];
|
||||
|
||||
mac[i] = '\0';
|
||||
|
||||
tok = (i > 0 && i < 4) ? man_hash_find(mac) : TOKEN_NONE;
|
||||
|
||||
tok = TOKEN_NONE;
|
||||
for (sz = 0; sz < 4 && strchr(" \t\\", buf[offs]) == NULL; sz++)
|
||||
offs++;
|
||||
if (sz > 0 && sz < 4)
|
||||
tok = roffhash_find(man->manmac, buf + ppos, sz);
|
||||
if (tok == TOKEN_NONE) {
|
||||
mandoc_msg(MANDOCERR_MACRO, man->parse,
|
||||
ln, ppos, buf + ppos - 1);
|
||||
@ -203,7 +183,7 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
|
||||
/* Jump to the next non-whitespace word. */
|
||||
|
||||
while (buf[offs] && buf[offs] == ' ')
|
||||
while (buf[offs] == ' ')
|
||||
offs++;
|
||||
|
||||
/*
|
||||
@ -223,6 +203,20 @@ man_pmacro(struct roff_man *man, int ln, char *buf, int offs)
|
||||
man_breakscope(man, tok);
|
||||
bline = man->flags & MAN_BLINE;
|
||||
|
||||
/*
|
||||
* If the line in next-line scope ends with \c, keep the
|
||||
* next-line scope open for the subsequent input line.
|
||||
* That is not at all portable, only groff >= 1.22.4
|
||||
* does it, but *if* this weird idiom occurs in a manual
|
||||
* page, that's very likely what the author intended.
|
||||
*/
|
||||
|
||||
if (bline) {
|
||||
cp = strchr(buf + offs, '\0') - 2;
|
||||
if (cp >= buf && cp[0] == '\\' && cp[1] == 'c')
|
||||
bline = 0;
|
||||
}
|
||||
|
||||
/* Call to handler... */
|
||||
|
||||
assert(man_macros[tok].fp);
|
||||
@ -266,7 +260,7 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
* Delete the element that is being broken.
|
||||
*/
|
||||
|
||||
if (man->flags & MAN_ELINE && (tok == TOKEN_NONE ||
|
||||
if (man->flags & MAN_ELINE && (tok < MAN_TH ||
|
||||
! (man_macros[tok].flags & MAN_NSCOPED))) {
|
||||
n = man->last;
|
||||
assert(n->type != ROFFT_TEXT);
|
||||
@ -275,8 +269,7 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse,
|
||||
n->line, n->pos, "%s breaks %s",
|
||||
tok == TOKEN_NONE ? "TS" : man_macronames[tok],
|
||||
man_macronames[n->tok]);
|
||||
roff_name[tok], roff_name[n->tok]);
|
||||
|
||||
roff_node_delete(man, n);
|
||||
man->flags &= ~MAN_ELINE;
|
||||
@ -302,7 +295,7 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
* Delete the block that is being broken.
|
||||
*/
|
||||
|
||||
if (man->flags & MAN_BLINE && (tok == TOKEN_NONE ||
|
||||
if (man->flags & MAN_BLINE && (tok < MAN_TH ||
|
||||
man_macros[tok].flags & MAN_BSCOPE)) {
|
||||
n = man->last;
|
||||
if (n->type == ROFFT_TEXT)
|
||||
@ -317,8 +310,7 @@ man_breakscope(struct roff_man *man, int tok)
|
||||
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE, man->parse,
|
||||
n->line, n->pos, "%s breaks %s",
|
||||
tok == TOKEN_NONE ? "TS" : man_macronames[tok],
|
||||
man_macronames[n->tok]);
|
||||
roff_name[tok], roff_name[n->tok]);
|
||||
|
||||
roff_node_delete(man, n);
|
||||
man->flags &= ~MAN_BLINE;
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" $Id: man.cgi.3,v 1.2 2016/07/07 19:19:01 schwarze Exp $
|
||||
.\" $Id: man.cgi.3,v 1.4 2017/03/15 13:18:53 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 7 2016 $
|
||||
.Dd $Mdocdate: March 15 2017 $
|
||||
.Dt MAN.CGI 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -126,12 +126,30 @@ contains a search query in short format or when
|
||||
is empty and a
|
||||
.Ev QUERY_STRING
|
||||
is provided.
|
||||
It changes into the manpath and calls
|
||||
If possible, requests using
|
||||
.Ev QUERY_STRING
|
||||
are redirected to URIs using
|
||||
.Ev PATH_INFO
|
||||
by calling
|
||||
.Fn pg_redirect .
|
||||
Otherwise, it changes into the manpath and calls
|
||||
.Xr mansearch 3 .
|
||||
Depending on the result, it calls either
|
||||
.Fn pg_noresult
|
||||
or
|
||||
.Fn pg_searchres .
|
||||
.It Ft void Fn pg_redirect "const struct req *req" "const char *name"
|
||||
This function is special in so far as it does not print an HTML page,
|
||||
but only an HTTP 303 response with a Location: of the form:
|
||||
.Sm off
|
||||
.No http://
|
||||
.Ar host Ns /
|
||||
.Op Ar scriptname Ns /
|
||||
.Op Ar manpath Ns /
|
||||
.Op Ar arch Ns /
|
||||
.Fa name
|
||||
.Op Pf . Ar sec
|
||||
.Sm on
|
||||
.It Ft void Fn pg_noresult "const struct req *req" "const char *msg"
|
||||
This function calls
|
||||
.Fn resp_begin_html ,
|
||||
@ -219,13 +237,18 @@ and
|
||||
are used.
|
||||
The highest level result generators are:
|
||||
.Bl -tag -width 1n
|
||||
.It Ft void Fn resp_begin_html "int code" "const char *msg"
|
||||
.It Ft void Fn resp_begin_html "int code" "const char *msg" "const char *file"
|
||||
This generator calls
|
||||
.Fn resp_begin_http
|
||||
to print the HTTP headers, then prints the HTML header up to the
|
||||
opening tag of the <body> element, then copies the file
|
||||
.Pa header.html
|
||||
to the output, if it exists and is readable.
|
||||
If
|
||||
.Fa file
|
||||
is not
|
||||
.Dv NULL ,
|
||||
it is used for the <title> element.
|
||||
.It Ft void Fn resp_searchform "const struct req *req" "enum focus focus"
|
||||
This generator prints a search form, filling it with data
|
||||
from the provided request object.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: man.cgi.8,v 1.20 2016/07/11 22:48:37 schwarze Exp $
|
||||
.\" $Id: man.cgi.8,v 1.22 2017/03/18 16:48:24 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: July 11 2016 $
|
||||
.Dd $Mdocdate: March 18 2017 $
|
||||
.Dt MAN.CGI 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -186,11 +186,6 @@ Otherwise, a leading slash is needed.
|
||||
This is used in generated HTML code.
|
||||
.It Dv CUSTOMIZE_TITLE
|
||||
An ASCII string to be used for the HTML <TITLE> element.
|
||||
.It Dv HTTP_HOST
|
||||
The FQDN of the (possibly virtual) host the HTTP server is running on.
|
||||
This is used for
|
||||
.Ic Location:
|
||||
headers in HTTP 303 responses.
|
||||
.It Dv MAN_DIR
|
||||
A file system path to the
|
||||
.Nm
|
||||
@ -411,15 +406,16 @@ A version of
|
||||
based on
|
||||
.Xr mandoc 1
|
||||
first appeared in mdocml-1.12.1 (March 2012).
|
||||
The current SQLite3-based version first appeared in
|
||||
.Ox 5.6 .
|
||||
The current
|
||||
.Xr mandoc.db 5
|
||||
database format first appeared in
|
||||
.Ox 6.1 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
program was written by
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||
and ported to the SQLite3-based
|
||||
.Xr mandoc.db 5
|
||||
backend by
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
||||
and is maintained by
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org ,
|
||||
who also designed and implemented the database format.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man.h,v 1.77 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: man.h,v 1.78 2017/04/24 23:06:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,50 +16,6 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define MAN_br 0
|
||||
#define MAN_TH 1
|
||||
#define MAN_SH 2
|
||||
#define MAN_SS 3
|
||||
#define MAN_TP 4
|
||||
#define MAN_LP 5
|
||||
#define MAN_PP 6
|
||||
#define MAN_P 7
|
||||
#define MAN_IP 8
|
||||
#define MAN_HP 9
|
||||
#define MAN_SM 10
|
||||
#define MAN_SB 11
|
||||
#define MAN_BI 12
|
||||
#define MAN_IB 13
|
||||
#define MAN_BR 14
|
||||
#define MAN_RB 15
|
||||
#define MAN_R 16
|
||||
#define MAN_B 17
|
||||
#define MAN_I 18
|
||||
#define MAN_IR 19
|
||||
#define MAN_RI 20
|
||||
#define MAN_sp 21
|
||||
#define MAN_nf 22
|
||||
#define MAN_fi 23
|
||||
#define MAN_RE 24
|
||||
#define MAN_RS 25
|
||||
#define MAN_DT 26
|
||||
#define MAN_UC 27
|
||||
#define MAN_PD 28
|
||||
#define MAN_AT 29
|
||||
#define MAN_in 30
|
||||
#define MAN_ft 31
|
||||
#define MAN_OP 32
|
||||
#define MAN_EX 33
|
||||
#define MAN_EE 34
|
||||
#define MAN_UR 35
|
||||
#define MAN_UE 36
|
||||
#define MAN_ll 37
|
||||
#define MAN_MAX 38
|
||||
|
||||
/* Names of macros. */
|
||||
extern const char *const *man_macronames;
|
||||
|
||||
|
||||
struct roff_man;
|
||||
|
||||
const struct mparse *man_mparse(const struct roff_man *);
|
||||
|
@ -1,103 +0,0 @@
|
||||
/* $Id: man_hash.c,v 1.35 2016/07/15 18:03:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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 "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "man.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libman.h"
|
||||
|
||||
#define HASH_DEPTH 6
|
||||
|
||||
#define HASH_ROW(x) do { \
|
||||
if (isupper((unsigned 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 unsigned char table[26 * HASH_DEPTH];
|
||||
|
||||
|
||||
void
|
||||
man_hash_init(void)
|
||||
{
|
||||
int i, j, x;
|
||||
|
||||
if (*table != '\0')
|
||||
return;
|
||||
|
||||
memset(table, UCHAR_MAX, sizeof(table));
|
||||
|
||||
for (i = 0; i < (int)MAN_MAX; i++) {
|
||||
x = man_macronames[i][0];
|
||||
|
||||
assert(isalpha((unsigned char)x));
|
||||
|
||||
HASH_ROW(x);
|
||||
|
||||
for (j = 0; j < HASH_DEPTH; j++)
|
||||
if (UCHAR_MAX == table[x + j]) {
|
||||
table[x + j] = (unsigned char)i;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(j < HASH_DEPTH);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
man_hash_find(const char *tmp)
|
||||
{
|
||||
int x, y, i;
|
||||
int tok;
|
||||
|
||||
if ('\0' == (x = tmp[0]))
|
||||
return TOKEN_NONE;
|
||||
if ( ! (isalpha((unsigned char)x)))
|
||||
return TOKEN_NONE;
|
||||
|
||||
HASH_ROW(x);
|
||||
|
||||
for (i = 0; i < HASH_DEPTH; i++) {
|
||||
if (UCHAR_MAX == (y = table[x + i]))
|
||||
return TOKEN_NONE;
|
||||
|
||||
tok = y;
|
||||
if (0 == strcmp(tmp, man_macronames[tok]))
|
||||
return tok;
|
||||
}
|
||||
|
||||
return TOKEN_NONE;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man_html.c,v 1.133 2017/02/05 18:15:39 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.143 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -65,14 +65,12 @@ static int man_SM_pre(MAN_ARGS);
|
||||
static int man_SS_pre(MAN_ARGS);
|
||||
static int man_UR_pre(MAN_ARGS);
|
||||
static int man_alt_pre(MAN_ARGS);
|
||||
static int man_br_pre(MAN_ARGS);
|
||||
static int man_ign_pre(MAN_ARGS);
|
||||
static int man_in_pre(MAN_ARGS);
|
||||
static void man_root_post(MAN_ARGS);
|
||||
static void man_root_pre(MAN_ARGS);
|
||||
|
||||
static const struct htmlman mans[MAN_MAX] = {
|
||||
{ man_br_pre, NULL }, /* br */
|
||||
static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL }, /* TH */
|
||||
{ man_SH_pre, NULL }, /* SH */
|
||||
{ man_SS_pre, NULL }, /* SS */
|
||||
@ -93,7 +91,6 @@ static const struct htmlman mans[MAN_MAX] = {
|
||||
{ man_I_pre, NULL }, /* I */
|
||||
{ man_alt_pre, NULL }, /* IR */
|
||||
{ man_alt_pre, NULL }, /* RI */
|
||||
{ man_br_pre, NULL }, /* sp */
|
||||
{ NULL, NULL }, /* nf */
|
||||
{ NULL, NULL }, /* fi */
|
||||
{ NULL, NULL }, /* RE */
|
||||
@ -103,14 +100,13 @@ static const struct htmlman mans[MAN_MAX] = {
|
||||
{ man_ign_pre, NULL }, /* PD */
|
||||
{ man_ign_pre, NULL }, /* AT */
|
||||
{ man_in_pre, NULL }, /* in */
|
||||
{ man_ign_pre, NULL }, /* ft */
|
||||
{ man_OP_pre, NULL }, /* OP */
|
||||
{ NULL, NULL }, /* EX */
|
||||
{ NULL, NULL }, /* EE */
|
||||
{ man_UR_pre, NULL }, /* UR */
|
||||
{ NULL, NULL }, /* UE */
|
||||
{ man_ign_pre, NULL }, /* ll */
|
||||
};
|
||||
static const struct htmlman *const mans = __mans - MAN_TH;
|
||||
|
||||
|
||||
/*
|
||||
@ -255,7 +251,8 @@ print_man_node(MAN_ARGS)
|
||||
case ROFFT_TEXT:
|
||||
if (fillmode(h, want_fillmode) == MAN_fi &&
|
||||
want_fillmode == MAN_fi &&
|
||||
n->flags & NODE_LINE && *n->string == ' ')
|
||||
n->flags & NODE_LINE && *n->string == ' ' &&
|
||||
(h->flags & HTML_NONEWLINE) == 0)
|
||||
print_otag(h, TAG_BR, "");
|
||||
if (*n->string != '\0')
|
||||
break;
|
||||
@ -304,6 +301,13 @@ print_man_node(MAN_ARGS)
|
||||
print_tblclose(h);
|
||||
|
||||
t = h->tag;
|
||||
if (n->tok < ROFF_MAX) {
|
||||
roff_html_pre(h, n);
|
||||
child = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(n->tok >= MAN_TH && n->tok < MAN_MAX);
|
||||
if (mans[n->tok].pre)
|
||||
child = (*mans[n->tok].pre)(man, n, h);
|
||||
|
||||
@ -354,13 +358,9 @@ fillmode(struct html *h, int want)
|
||||
static int
|
||||
a2width(const struct roff_node *n, struct roffsu *su)
|
||||
{
|
||||
|
||||
if (n->type != ROFFT_TEXT)
|
||||
return 0;
|
||||
if (a2roffsu(n->string, su, SCALE_EN))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return a2roffsu(n->string, su, SCALE_EN) != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -409,34 +409,18 @@ man_root_post(MAN_ARGS)
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
man_br_pre(MAN_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
|
||||
SCALE_VS_INIT(&su, 1);
|
||||
|
||||
if (MAN_sp == n->tok) {
|
||||
if (NULL != (n = n->child))
|
||||
if ( ! a2roffsu(n->string, &su, SCALE_VS))
|
||||
su.scale = 1.0;
|
||||
} else
|
||||
su.scale = 0.0;
|
||||
|
||||
print_otag(h, TAG_DIV, "suh", &su);
|
||||
|
||||
/* So the div isn't empty: */
|
||||
print_text(h, "\\~");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
man_SH_pre(MAN_ARGS)
|
||||
{
|
||||
if (n->type == ROFFT_HEAD)
|
||||
print_otag(h, TAG_H1, "c", "Sh");
|
||||
char *id;
|
||||
|
||||
if (n->type == ROFFT_HEAD) {
|
||||
id = html_make_id(n);
|
||||
print_otag(h, TAG_H1, "cTi", "Sh", id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
free(id);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -498,8 +482,15 @@ man_SM_pre(MAN_ARGS)
|
||||
static int
|
||||
man_SS_pre(MAN_ARGS)
|
||||
{
|
||||
if (n->type == ROFFT_HEAD)
|
||||
print_otag(h, TAG_H2, "c", "Ss");
|
||||
char *id;
|
||||
|
||||
if (n->type == ROFFT_HEAD) {
|
||||
id = html_make_id(n);
|
||||
print_otag(h, TAG_H2, "cTi", "Ss", id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
free(id);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -656,7 +647,7 @@ man_UR_pre(MAN_ARGS)
|
||||
assert(n->type == ROFFT_HEAD);
|
||||
if (n->child != NULL) {
|
||||
assert(n->child->type == ROFFT_TEXT);
|
||||
print_otag(h, TAG_A, "ch", "Lk", n->child->string);
|
||||
print_otag(h, TAG_A, "cTh", "Lk", n->child->string);
|
||||
}
|
||||
|
||||
assert(n->next->type == ROFFT_BODY);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: man_macro.c,v 1.115 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/* $Id: man_macro.c,v 1.120 2017/05/05 15:17:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -38,10 +38,9 @@ static void blk_imp(MACRO_PROT_ARGS);
|
||||
static void in_line_eoln(MACRO_PROT_ARGS);
|
||||
static int man_args(struct roff_man *, int,
|
||||
int *, char *, char **);
|
||||
static void rew_scope(struct roff_man *, int);
|
||||
static void rew_scope(struct roff_man *, enum roff_tok);
|
||||
|
||||
const struct man_macro __man_macros[MAN_MAX] = {
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* br */
|
||||
const struct man_macro __man_macros[MAN_MAX - MAN_TH] = {
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* TH */
|
||||
{ blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SH */
|
||||
{ blk_imp, MAN_BSCOPE | MAN_SCOPED }, /* SS */
|
||||
@ -62,7 +61,6 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
||||
{ in_line_eoln, MAN_SCOPED | MAN_JOIN }, /* I */
|
||||
{ in_line_eoln, 0 }, /* IR */
|
||||
{ in_line_eoln, 0 }, /* RI */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* sp */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* nf */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* fi */
|
||||
{ blk_close, MAN_BSCOPE }, /* RE */
|
||||
@ -72,16 +70,13 @@ const struct man_macro __man_macros[MAN_MAX] = {
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* PD */
|
||||
{ in_line_eoln, 0 }, /* AT */
|
||||
{ in_line_eoln, 0 }, /* in */
|
||||
{ in_line_eoln, 0 }, /* ft */
|
||||
{ in_line_eoln, 0 }, /* OP */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EX */
|
||||
{ in_line_eoln, MAN_BSCOPE }, /* EE */
|
||||
{ blk_exp, MAN_BSCOPE }, /* UR */
|
||||
{ blk_close, MAN_BSCOPE }, /* UE */
|
||||
{ in_line_eoln, 0 }, /* ll */
|
||||
};
|
||||
|
||||
const struct man_macro * const man_macros = __man_macros;
|
||||
const struct man_macro *const man_macros = __man_macros - MAN_TH;
|
||||
|
||||
|
||||
void
|
||||
@ -100,8 +95,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
man_macros[n->tok].flags & MAN_SCOPED) {
|
||||
mandoc_vmsg(MANDOCERR_BLK_LINE,
|
||||
man->parse, n->line, n->pos,
|
||||
"EOF breaks %s",
|
||||
man_macronames[n->tok]);
|
||||
"EOF breaks %s", roff_name[n->tok]);
|
||||
if (man->flags & MAN_ELINE)
|
||||
man->flags &= ~MAN_ELINE;
|
||||
else {
|
||||
@ -118,7 +112,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
man_macros[n->tok].fp == blk_exp)
|
||||
mandoc_msg(MANDOCERR_BLK_NOEND,
|
||||
man->parse, n->line, n->pos,
|
||||
man_macronames[n->tok]);
|
||||
roff_name[n->tok]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -150,7 +144,7 @@ man_unscope(struct roff_man *man, const struct roff_node *to)
|
||||
* scopes. When a scope is closed, it must be validated and actioned.
|
||||
*/
|
||||
static void
|
||||
rew_scope(struct roff_man *man, int tok)
|
||||
rew_scope(struct roff_man *man, enum roff_tok tok)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
@ -193,7 +187,7 @@ rew_scope(struct roff_man *man, int tok)
|
||||
void
|
||||
blk_close(MACRO_PROT_ARGS)
|
||||
{
|
||||
int ntok;
|
||||
enum roff_tok ntok;
|
||||
const struct roff_node *nn;
|
||||
char *p;
|
||||
int nrew, target;
|
||||
@ -233,7 +227,7 @@ blk_close(MACRO_PROT_ARGS)
|
||||
|
||||
if (nn == NULL) {
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, man->parse,
|
||||
line, ppos, man_macronames[tok]);
|
||||
line, ppos, roff_name[tok]);
|
||||
rew_scope(man, MAN_PP);
|
||||
} else {
|
||||
line = man->last->line;
|
||||
@ -266,9 +260,8 @@ blk_exp(MACRO_PROT_ARGS)
|
||||
roff_word_alloc(man, line, la, p);
|
||||
|
||||
if (buf[*pos] != '\0')
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS,
|
||||
man->parse, line, *pos, "%s ... %s",
|
||||
man_macronames[tok], buf + *pos);
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, line,
|
||||
*pos, "%s ... %s", roff_name[tok], buf + *pos);
|
||||
|
||||
man_unscope(man, head);
|
||||
roff_body_alloc(man, line, ppos, tok);
|
||||
@ -331,18 +324,16 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
n = man->last;
|
||||
|
||||
for (;;) {
|
||||
if (buf[*pos] != '\0' && (tok == MAN_br ||
|
||||
tok == MAN_fi || tok == MAN_nf)) {
|
||||
if (buf[*pos] != '\0' && (tok == MAN_fi || tok == MAN_nf)) {
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
man->parse, line, *pos, "%s %s",
|
||||
man_macronames[tok], buf + *pos);
|
||||
roff_name[tok], buf + *pos);
|
||||
break;
|
||||
}
|
||||
if (buf[*pos] != '\0' && man->last != n &&
|
||||
(tok == MAN_PD || tok == MAN_ft || tok == MAN_sp)) {
|
||||
if (buf[*pos] != '\0' && man->last != n && tok == MAN_PD) {
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS,
|
||||
man->parse, line, *pos, "%s ... %s",
|
||||
man_macronames[tok], buf + *pos);
|
||||
roff_name[tok], buf + *pos);
|
||||
break;
|
||||
}
|
||||
la = *pos;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: man_term.c,v 1.191 2017/02/15 14:10:08 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.204 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -68,6 +68,7 @@ static void print_bvspace(struct termp *,
|
||||
const struct roff_node *, int);
|
||||
|
||||
static int pre_B(DECL_ARGS);
|
||||
static int pre_DT(DECL_ARGS);
|
||||
static int pre_HP(DECL_ARGS);
|
||||
static int pre_I(DECL_ARGS);
|
||||
static int pre_IP(DECL_ARGS);
|
||||
@ -80,12 +81,9 @@ static int pre_SS(DECL_ARGS);
|
||||
static int pre_TP(DECL_ARGS);
|
||||
static int pre_UR(DECL_ARGS);
|
||||
static int pre_alternate(DECL_ARGS);
|
||||
static int pre_ft(DECL_ARGS);
|
||||
static int pre_ign(DECL_ARGS);
|
||||
static int pre_in(DECL_ARGS);
|
||||
static int pre_literal(DECL_ARGS);
|
||||
static int pre_ll(DECL_ARGS);
|
||||
static int pre_sp(DECL_ARGS);
|
||||
|
||||
static void post_IP(DECL_ARGS);
|
||||
static void post_HP(DECL_ARGS);
|
||||
@ -95,8 +93,7 @@ static void post_SS(DECL_ARGS);
|
||||
static void post_TP(DECL_ARGS);
|
||||
static void post_UR(DECL_ARGS);
|
||||
|
||||
static const struct termact termacts[MAN_MAX] = {
|
||||
{ pre_sp, NULL, MAN_NOTEXT }, /* br */
|
||||
static const struct termact __termacts[MAN_MAX - MAN_TH] = {
|
||||
{ NULL, NULL, 0 }, /* TH */
|
||||
{ pre_SH, post_SH, 0 }, /* SH */
|
||||
{ pre_SS, post_SS, 0 }, /* SS */
|
||||
@ -117,24 +114,22 @@ static const struct termact termacts[MAN_MAX] = {
|
||||
{ pre_I, NULL, 0 }, /* I */
|
||||
{ pre_alternate, NULL, 0 }, /* IR */
|
||||
{ pre_alternate, NULL, 0 }, /* RI */
|
||||
{ pre_sp, NULL, MAN_NOTEXT }, /* sp */
|
||||
{ pre_literal, NULL, 0 }, /* nf */
|
||||
{ pre_literal, NULL, 0 }, /* fi */
|
||||
{ NULL, NULL, 0 }, /* RE */
|
||||
{ pre_RS, post_RS, 0 }, /* RS */
|
||||
{ pre_ign, NULL, 0 }, /* DT */
|
||||
{ pre_DT, NULL, 0 }, /* DT */
|
||||
{ pre_ign, NULL, MAN_NOTEXT }, /* UC */
|
||||
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
|
||||
{ pre_ign, NULL, 0 }, /* AT */
|
||||
{ pre_in, NULL, MAN_NOTEXT }, /* in */
|
||||
{ pre_ft, NULL, MAN_NOTEXT }, /* ft */
|
||||
{ pre_OP, NULL, 0 }, /* OP */
|
||||
{ pre_literal, NULL, 0 }, /* EX */
|
||||
{ pre_literal, NULL, 0 }, /* EE */
|
||||
{ pre_UR, post_UR, 0 }, /* UR */
|
||||
{ NULL, NULL, 0 }, /* UE */
|
||||
{ pre_ll, NULL, MAN_NOTEXT }, /* ll */
|
||||
};
|
||||
static const struct termact *termacts = __termacts - MAN_TH;
|
||||
|
||||
|
||||
void
|
||||
@ -146,9 +141,10 @@ terminal_man(void *arg, const struct roff_man *man)
|
||||
size_t save_defindent;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
p->overstep = 0;
|
||||
p->rmargin = p->maxrmargin = p->defrmargin;
|
||||
p->tabwidth = term_len(p, 5);
|
||||
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
|
||||
memset(&mt, 0, sizeof(struct mtermp));
|
||||
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
|
||||
@ -218,14 +214,6 @@ pre_ign(DECL_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ll(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_setwidth(p, n->child != NULL ? n->child->string : NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_I(DECL_ARGS)
|
||||
{
|
||||
@ -240,7 +228,7 @@ pre_literal(DECL_ARGS)
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (MAN_nf == n->tok || MAN_EX == n->tok)
|
||||
if (n->tok == MAN_nf || n->tok == MAN_EX)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
else
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
@ -250,9 +238,9 @@ pre_literal(DECL_ARGS)
|
||||
* So in case a second call to term_flushln() is needed,
|
||||
* indentation has to be set up explicitly.
|
||||
*/
|
||||
if (MAN_HP == n->parent->tok && p->rmargin < p->maxrmargin) {
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
if (n->parent->tok == MAN_HP && p->tcol->rmargin < p->maxrmargin) {
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -272,7 +260,7 @@ pre_PD(DECL_ARGS)
|
||||
return 0;
|
||||
}
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
if (a2roffsu(n->string, &su, SCALE_VS))
|
||||
if (a2roffsu(n->string, &su, SCALE_VS) != NULL)
|
||||
mt->pardist = term_vspan(p, &su);
|
||||
return 0;
|
||||
}
|
||||
@ -361,41 +349,6 @@ pre_OP(DECL_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ft(DECL_ARGS)
|
||||
{
|
||||
const char *cp;
|
||||
|
||||
if (NULL == n->child) {
|
||||
term_fontlast(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cp = n->child->string;
|
||||
switch (*cp) {
|
||||
case '4':
|
||||
case '3':
|
||||
case 'B':
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case '2':
|
||||
case 'I':
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
break;
|
||||
case 'P':
|
||||
term_fontlast(p);
|
||||
break;
|
||||
case '1':
|
||||
case 'C':
|
||||
case 'R':
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_in(DECL_ARGS)
|
||||
{
|
||||
@ -406,8 +359,8 @@ pre_in(DECL_ARGS)
|
||||
|
||||
term_newln(p);
|
||||
|
||||
if (NULL == n->child) {
|
||||
p->offset = mt->offset;
|
||||
if (n->child == NULL) {
|
||||
p->tcol->offset = mt->offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -421,71 +374,29 @@ pre_in(DECL_ARGS)
|
||||
else
|
||||
cp--;
|
||||
|
||||
if ( ! a2roffsu(++cp, &su, SCALE_EN))
|
||||
if (a2roffsu(++cp, &su, SCALE_EN) == NULL)
|
||||
return 0;
|
||||
|
||||
v = (term_hspan(p, &su) + 11) / 24;
|
||||
|
||||
if (less < 0)
|
||||
p->offset -= p->offset > v ? v : p->offset;
|
||||
p->tcol->offset -= p->tcol->offset > v ? v : p->tcol->offset;
|
||||
else if (less > 0)
|
||||
p->offset += v;
|
||||
p->tcol->offset += v;
|
||||
else
|
||||
p->offset = v;
|
||||
if (p->offset > SHRT_MAX)
|
||||
p->offset = term_len(p, p->defindent);
|
||||
p->tcol->offset = v;
|
||||
if (p->tcol->offset > SHRT_MAX)
|
||||
p->tcol->offset = term_len(p, p->defindent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_sp(DECL_ARGS)
|
||||
pre_DT(DECL_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
int i, len;
|
||||
|
||||
if ((NULL == n->prev && n->parent)) {
|
||||
switch (n->parent->tok) {
|
||||
case MAN_SH:
|
||||
case MAN_SS:
|
||||
case MAN_PP:
|
||||
case MAN_LP:
|
||||
case MAN_P:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (n->tok == MAN_br)
|
||||
len = 0;
|
||||
else if (n->child == NULL)
|
||||
len = 1;
|
||||
else {
|
||||
if ( ! a2roffsu(n->child->string, &su, SCALE_VS))
|
||||
su.scale = 1.0;
|
||||
len = term_vspan(p, &su);
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
term_newln(p);
|
||||
else if (len < 0)
|
||||
p->skipvsp -= len;
|
||||
else
|
||||
for (i = 0; i < len; i++)
|
||||
term_vspace(p);
|
||||
|
||||
/*
|
||||
* Handle an explicit break request in the same way
|
||||
* as an overflowing line.
|
||||
*/
|
||||
|
||||
if (p->flags & TERMP_BRIND) {
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
}
|
||||
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -514,7 +425,7 @@ pre_HP(DECL_ARGS)
|
||||
/* Calculate offset. */
|
||||
|
||||
if ((nn = n->parent->head->child) != NULL &&
|
||||
a2roffsu(nn->string, &su, SCALE_EN)) {
|
||||
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
|
||||
len = term_hspan(p, &su) / 24;
|
||||
if (len < 0 && (size_t)(-len) > mt->offset)
|
||||
len = -mt->offset;
|
||||
@ -524,8 +435,8 @@ pre_HP(DECL_ARGS)
|
||||
} else
|
||||
len = mt->lmargin[mt->lmargincur];
|
||||
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = mt->offset + len;
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -549,8 +460,8 @@ post_HP(DECL_ARGS)
|
||||
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
p->trailspace = 0;
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -567,7 +478,7 @@ pre_PP(DECL_ARGS)
|
||||
print_bvspace(p, n, mt->pardist);
|
||||
break;
|
||||
default:
|
||||
p->offset = mt->offset;
|
||||
p->tcol->offset = mt->offset;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -599,7 +510,7 @@ pre_IP(DECL_ARGS)
|
||||
/* Calculate the offset from the optional second argument. */
|
||||
if ((nn = n->parent->head->child) != NULL &&
|
||||
(nn = nn->next) != NULL &&
|
||||
a2roffsu(nn->string, &su, SCALE_EN)) {
|
||||
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
|
||||
len = term_hspan(p, &su) / 24;
|
||||
if (len < 0 && (size_t)(-len) > mt->offset)
|
||||
len = -mt->offset;
|
||||
@ -611,8 +522,8 @@ pre_IP(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = mt->offset + len;
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
|
||||
savelit = MANT_LITERAL & mt->fl;
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
@ -625,8 +536,8 @@ pre_IP(DECL_ARGS)
|
||||
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
p->offset = mt->offset + len;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = mt->offset + len;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -644,11 +555,11 @@ post_IP(DECL_ARGS)
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->trailspace = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
term_newln(p);
|
||||
p->offset = mt->offset;
|
||||
p->tcol->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -681,7 +592,7 @@ pre_TP(DECL_ARGS)
|
||||
|
||||
if ((nn = n->parent->head->child) != NULL &&
|
||||
nn->string != NULL && ! (NODE_LINE & nn->flags) &&
|
||||
a2roffsu(nn->string, &su, SCALE_EN)) {
|
||||
a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
|
||||
len = term_hspan(p, &su) / 24;
|
||||
if (len < 0 && (size_t)(-len) > mt->offset)
|
||||
len = -mt->offset;
|
||||
@ -693,8 +604,8 @@ pre_TP(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = mt->offset + len;
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = mt->offset + len;
|
||||
|
||||
savelit = MANT_LITERAL & mt->fl;
|
||||
mt->fl &= ~MANT_LITERAL;
|
||||
@ -713,8 +624,8 @@ pre_TP(DECL_ARGS)
|
||||
mt->fl |= MANT_LITERAL;
|
||||
return 0;
|
||||
case ROFFT_BODY:
|
||||
p->offset = mt->offset + len;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = mt->offset + len;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP);
|
||||
break;
|
||||
@ -735,7 +646,7 @@ post_TP(DECL_ARGS)
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
term_newln(p);
|
||||
p->offset = mt->offset;
|
||||
p->tcol->offset = mt->offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -770,14 +681,14 @@ pre_SS(DECL_ARGS)
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
p->offset = term_len(p, 3);
|
||||
p->rmargin = mt->offset;
|
||||
p->tcol->offset = term_len(p, 3);
|
||||
p->tcol->rmargin = mt->offset;
|
||||
p->trailspace = mt->offset;
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRIND;
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
break;
|
||||
@ -832,14 +743,14 @@ pre_SH(DECL_ARGS)
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
p->offset = 0;
|
||||
p->rmargin = mt->offset;
|
||||
p->tcol->offset = 0;
|
||||
p->tcol->rmargin = mt->offset;
|
||||
p->trailspace = mt->offset;
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRIND;
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
break;
|
||||
@ -885,7 +796,7 @@ pre_RS(DECL_ARGS)
|
||||
n->aux = SHRT_MAX + 1;
|
||||
if (n->child == NULL)
|
||||
n->aux = mt->lmargin[mt->lmargincur];
|
||||
else if (a2roffsu(n->child->string, &su, SCALE_EN))
|
||||
else if (a2roffsu(n->child->string, &su, SCALE_EN) != NULL)
|
||||
n->aux = term_hspan(p, &su) / 24;
|
||||
if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
|
||||
n->aux = -mt->offset;
|
||||
@ -893,8 +804,8 @@ pre_RS(DECL_ARGS)
|
||||
n->aux = term_len(p, p->defindent);
|
||||
|
||||
mt->offset += n->aux;
|
||||
p->offset = mt->offset;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = mt->offset;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
|
||||
if (++mt->lmarginsz < MAXMARGINS)
|
||||
mt->lmargincur = mt->lmarginsz;
|
||||
@ -918,7 +829,7 @@ post_RS(DECL_ARGS)
|
||||
}
|
||||
|
||||
mt->offset -= n->parent->head->aux;
|
||||
p->offset = mt->offset;
|
||||
p->tcol->offset = mt->offset;
|
||||
|
||||
if (--mt->lmarginsz < MAXMARGINS)
|
||||
mt->lmargincur = mt->lmarginsz;
|
||||
@ -951,7 +862,6 @@ post_UR(DECL_ARGS)
|
||||
static void
|
||||
print_man_node(DECL_ARGS)
|
||||
{
|
||||
size_t rm, rmax;
|
||||
int c;
|
||||
|
||||
switch (n->type) {
|
||||
@ -961,10 +871,11 @@ print_man_node(DECL_ARGS)
|
||||
* If we have a space as the first character, break
|
||||
* before printing the line's data.
|
||||
*/
|
||||
if ('\0' == *n->string) {
|
||||
if (*n->string == '\0') {
|
||||
term_vspace(p);
|
||||
return;
|
||||
} else if (' ' == *n->string && NODE_LINE & n->flags)
|
||||
} else if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(p->flags & TERMP_NONEWLINE) == 0)
|
||||
term_newln(p);
|
||||
|
||||
term_word(p, n->string);
|
||||
@ -986,6 +897,12 @@ print_man_node(DECL_ARGS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (n->tok < ROFF_MAX) {
|
||||
roff_term_pre(p, n);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(n->tok >= MAN_TH && n->tok <= MAN_MAX);
|
||||
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
|
||||
@ -1012,20 +929,17 @@ print_man_node(DECL_ARGS)
|
||||
if (mt->fl & MANT_LITERAL &&
|
||||
! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&
|
||||
(n->next == NULL || n->next->flags & NODE_LINE)) {
|
||||
rm = p->rmargin;
|
||||
rmax = p->maxrmargin;
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->flags |= TERMP_BRNEVER | TERMP_NOSPACE;
|
||||
if (n->string != NULL && *n->string != '\0')
|
||||
term_flushln(p);
|
||||
else
|
||||
term_newln(p);
|
||||
if (rm < rmax && n->parent->tok == MAN_HP) {
|
||||
p->offset = rm;
|
||||
p->rmargin = rmax;
|
||||
} else
|
||||
p->rmargin = rm;
|
||||
p->maxrmargin = rmax;
|
||||
p->flags &= ~TERMP_BRNEVER;
|
||||
if (p->tcol->rmargin < p->maxrmargin &&
|
||||
n->parent->tok == MAN_HP) {
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
}
|
||||
}
|
||||
if (NODE_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
@ -1081,8 +995,8 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
|
||||
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin > datelen ?
|
||||
p->tcol->offset = 0;
|
||||
p->tcol->rmargin = p->maxrmargin > datelen ?
|
||||
(p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0;
|
||||
|
||||
if (meta->os)
|
||||
@ -1091,9 +1005,10 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
|
||||
|
||||
/* At the bottom in the middle: manual date. */
|
||||
|
||||
p->offset = p->rmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
titlen = term_strlen(p, title);
|
||||
p->rmargin = p->maxrmargin > titlen ? p->maxrmargin - titlen : 0;
|
||||
p->tcol->rmargin = p->maxrmargin > titlen ?
|
||||
p->maxrmargin - titlen : 0;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
term_word(p, meta->date);
|
||||
@ -1104,8 +1019,8 @@ print_man_foot(struct termp *p, const struct roff_meta *meta)
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->trailspace = 0;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
@ -1132,8 +1047,8 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
|
||||
|
||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||
p->trailspace = 1;
|
||||
p->offset = 0;
|
||||
p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
||||
p->tcol->offset = 0;
|
||||
p->tcol->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
||||
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
|
||||
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
|
||||
|
||||
@ -1143,9 +1058,9 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
|
||||
/* At the top in the middle: manual volume. */
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->offset + vollen + titlen < p->maxrmargin ?
|
||||
p->maxrmargin - titlen : p->maxrmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->tcol->offset + vollen + titlen <
|
||||
p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin;
|
||||
|
||||
term_word(p, volume);
|
||||
term_flushln(p);
|
||||
@ -1154,17 +1069,17 @@ print_man_head(struct termp *p, const struct roff_meta *meta)
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->trailspace = 0;
|
||||
if (p->rmargin + titlen <= p->maxrmargin) {
|
||||
if (p->tcol->rmargin + titlen <= p->maxrmargin) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = 0;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
|
||||
/*
|
||||
* Groff prints three blank lines before the content.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $OpenBSD$ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -48,14 +48,12 @@ static void check_text(CHKARGS);
|
||||
static void post_AT(CHKARGS);
|
||||
static void post_IP(CHKARGS);
|
||||
static void post_vs(CHKARGS);
|
||||
static void post_ft(CHKARGS);
|
||||
static void post_OP(CHKARGS);
|
||||
static void post_TH(CHKARGS);
|
||||
static void post_UC(CHKARGS);
|
||||
static void post_UR(CHKARGS);
|
||||
|
||||
static v_check man_valids[MAN_MAX] = {
|
||||
post_vs, /* br */
|
||||
static const v_check __man_valids[MAN_MAX - MAN_TH] = {
|
||||
post_TH, /* TH */
|
||||
NULL, /* SH */
|
||||
NULL, /* SS */
|
||||
@ -76,7 +74,6 @@ static v_check man_valids[MAN_MAX] = {
|
||||
NULL, /* I */
|
||||
NULL, /* IR */
|
||||
NULL, /* RI */
|
||||
post_vs, /* sp */
|
||||
NULL, /* nf */
|
||||
NULL, /* fi */
|
||||
NULL, /* RE */
|
||||
@ -86,21 +83,20 @@ static v_check man_valids[MAN_MAX] = {
|
||||
NULL, /* PD */
|
||||
post_AT, /* AT */
|
||||
NULL, /* in */
|
||||
post_ft, /* ft */
|
||||
post_OP, /* OP */
|
||||
NULL, /* EX */
|
||||
NULL, /* EE */
|
||||
post_UR, /* UR */
|
||||
NULL, /* UE */
|
||||
NULL, /* ll */
|
||||
};
|
||||
static const v_check *man_valids = __man_valids - MAN_TH;
|
||||
|
||||
|
||||
void
|
||||
man_node_validate(struct roff_man *man)
|
||||
{
|
||||
struct roff_node *n;
|
||||
v_check *cp;
|
||||
const v_check *cp;
|
||||
|
||||
n = man->last;
|
||||
man->last = man->last->child;
|
||||
@ -125,6 +121,19 @@ man_node_validate(struct roff_man *man)
|
||||
case ROFFT_TBL:
|
||||
break;
|
||||
default:
|
||||
if (n->tok < ROFF_MAX) {
|
||||
switch (n->tok) {
|
||||
case ROFF_br:
|
||||
case ROFF_sp:
|
||||
post_vs(man, n);
|
||||
break;
|
||||
default:
|
||||
roff_validate(man);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
assert(n->tok >= MAN_TH && n->tok < MAN_MAX);
|
||||
cp = man_valids + n->tok;
|
||||
if (*cp)
|
||||
(*cp)(man, n);
|
||||
@ -200,54 +209,13 @@ post_UR(CHKARGS)
|
||||
check_part(man, n);
|
||||
}
|
||||
|
||||
static void
|
||||
post_ft(CHKARGS)
|
||||
{
|
||||
char *cp;
|
||||
int ok;
|
||||
|
||||
if (n->child == NULL)
|
||||
return;
|
||||
|
||||
ok = 0;
|
||||
cp = n->child->string;
|
||||
switch (*cp) {
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case 'I':
|
||||
case 'P':
|
||||
case 'R':
|
||||
if ('\0' == cp[1])
|
||||
ok = 1;
|
||||
break;
|
||||
case 'B':
|
||||
if ('\0' == cp[1] || ('I' == cp[1] && '\0' == cp[2]))
|
||||
ok = 1;
|
||||
break;
|
||||
case 'C':
|
||||
if ('W' == cp[1] && '\0' == cp[2])
|
||||
ok = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == ok) {
|
||||
mandoc_vmsg(MANDOCERR_FT_BAD, man->parse,
|
||||
n->line, n->pos, "ft %s", cp);
|
||||
*cp = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
check_part(CHKARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BODY && n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY, man->parse,
|
||||
n->line, n->pos, man_macronames[n->tok]);
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -263,14 +231,13 @@ check_par(CHKARGS)
|
||||
if (n->child == NULL)
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||
man->parse, n->line, n->pos,
|
||||
"%s empty", man_macronames[n->tok]);
|
||||
"%s empty", roff_name[n->tok]);
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
if (n->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
man->parse, n->line, n->pos,
|
||||
"%s %s%s", man_macronames[n->tok],
|
||||
n->child->string,
|
||||
man->parse, n->line, n->pos, "%s %s%s",
|
||||
roff_name[n->tok], n->child->string,
|
||||
n->child->next != NULL ? " ..." : "");
|
||||
break;
|
||||
default:
|
||||
@ -291,7 +258,7 @@ post_IP(CHKARGS)
|
||||
if (n->parent->head->child == NULL && n->child == NULL)
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||
man->parse, n->line, n->pos,
|
||||
"%s empty", man_macronames[n->tok]);
|
||||
"%s empty", roff_name[n->tok]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -478,9 +445,12 @@ post_vs(CHKARGS)
|
||||
switch (n->parent->tok) {
|
||||
case MAN_SH:
|
||||
case MAN_SS:
|
||||
case MAN_PP:
|
||||
case MAN_LP:
|
||||
case MAN_P:
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP, man->parse, n->line, n->pos,
|
||||
"%s after %s", man_macronames[n->tok],
|
||||
man_macronames[n->parent->tok]);
|
||||
"%s after %s", roff_name[n->tok],
|
||||
roff_name[n->parent->tok]);
|
||||
/* FALLTHROUGH */
|
||||
case TOKEN_NONE:
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc.1,v 1.174 2017/02/10 15:45:28 schwarze Exp $
|
||||
.\" $Id: mandoc.1,v 1.196 2017/06/08 00:23:30 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,19 +15,19 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 10 2017 $
|
||||
.Dd $Mdocdate: June 8 2017 $
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc
|
||||
.Nd format and display UNIX manuals
|
||||
.Nd format manual pages
|
||||
.Sh SYNOPSIS
|
||||
.Nm mandoc
|
||||
.Op Fl acfhkl
|
||||
.Op Fl ac
|
||||
.Op Fl I Cm os Ns = Ns Ar name
|
||||
.Op Fl K Ar encoding
|
||||
.Op Fl m Ns Ar format
|
||||
.Op Fl O Ar option
|
||||
.Op Fl mdoc | man
|
||||
.Op Fl O Ar options
|
||||
.Op Fl T Ar output
|
||||
.Op Fl W Ar level
|
||||
.Op Ar
|
||||
@ -44,9 +44,7 @@ reads
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
text from stdin, implying
|
||||
.Fl m Ns Cm andoc ,
|
||||
and produces
|
||||
text from stdin and produces
|
||||
.Fl T Cm locale
|
||||
output.
|
||||
.Pp
|
||||
@ -67,28 +65,21 @@ to paginate them.
|
||||
This is the default.
|
||||
It can be specified to override
|
||||
.Fl a .
|
||||
.It Fl f
|
||||
A synonym for
|
||||
.Xr whatis 1 .
|
||||
This overrides any earlier
|
||||
.Fl k
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
.It Fl h
|
||||
Display only the SYNOPSIS lines.
|
||||
Implies
|
||||
.Fl c .
|
||||
.It Fl I Cm os Ns = Ns Ar name
|
||||
Override the default operating system
|
||||
.Ar name
|
||||
for the
|
||||
.Xr mdoc 7
|
||||
.Sq \&Os
|
||||
.Ic \&Os
|
||||
and for the
|
||||
.Xr man 7
|
||||
.Sq \&TH
|
||||
.Ic \&TH
|
||||
macro.
|
||||
This can also be used to perform style checks according to the
|
||||
conventions of one operating system while running on a different
|
||||
operating system; see
|
||||
.Sx Style messages
|
||||
for details.
|
||||
.It Fl K Ar encoding
|
||||
Specify the input encoding.
|
||||
The supported
|
||||
@ -98,46 +89,53 @@ arguments are
|
||||
.Cm iso-8859-1 ,
|
||||
and
|
||||
.Cm utf-8 .
|
||||
If not specified, autodetection uses the first match:
|
||||
.Bl -tag -width iso-8859-1
|
||||
.It Cm utf-8
|
||||
if the first three bytes of the input file
|
||||
are the UTF-8 byte order mark (BOM, 0xefbbbf)
|
||||
.It Ar encoding
|
||||
if the first or second line of the input file matches the
|
||||
If not specified, autodetection uses the first match in the following
|
||||
list:
|
||||
.Bl -enum
|
||||
.It
|
||||
If the first three bytes of the input file are the UTF-8 byte order
|
||||
mark (BOM, 0xefbbbf), input is interpreted as
|
||||
.Cm utf-8 .
|
||||
.It
|
||||
If the first or second line of the input file matches the
|
||||
.Sy emacs
|
||||
mode line format
|
||||
.Pp
|
||||
.D1 .\e" -*- Oo ...; Oc coding: Ar encoding ; No -*-
|
||||
.It Cm utf-8
|
||||
if the first non-ASCII byte in the file introduces a valid UTF-8 sequence
|
||||
.It Cm iso-8859-1
|
||||
otherwise
|
||||
.Pp
|
||||
then input is interpreted according to
|
||||
.Ar encoding .
|
||||
.It
|
||||
If the first non-ASCII byte in the file introduces a valid UTF-8
|
||||
sequence, input is interpreted as
|
||||
.Cm utf-8 .
|
||||
.It
|
||||
Otherwise, input is interpreted as
|
||||
.Cm iso-8859-1 .
|
||||
.El
|
||||
.It Fl k
|
||||
A synonym for
|
||||
.Xr apropos 1 .
|
||||
This overrides any earlier
|
||||
.Fl f
|
||||
and
|
||||
.Fl l
|
||||
options.
|
||||
.It Fl l
|
||||
A synonym for
|
||||
.Fl a .
|
||||
Also reverts any earlier
|
||||
.Fl f
|
||||
and
|
||||
.Fl k
|
||||
options.
|
||||
.It Fl m Ns Ar format
|
||||
Input format.
|
||||
See
|
||||
.Sx Input Formats
|
||||
for available formats.
|
||||
Defaults to
|
||||
.Fl m Ns Cm andoc .
|
||||
.It Fl O Ar option
|
||||
.It Fl mdoc | man
|
||||
With
|
||||
.Fl mdoc ,
|
||||
all input files are interpreted as
|
||||
.Xr mdoc 7 .
|
||||
With
|
||||
.Fl man ,
|
||||
all input files are interpreted as
|
||||
.Xr man 7 .
|
||||
By default, the input language is automatically detected for each file:
|
||||
if the the first macro is
|
||||
.Ic \&Dd
|
||||
or
|
||||
.Ic \&Dt ,
|
||||
the
|
||||
.Xr mdoc 7
|
||||
parser is used; otherwise, the
|
||||
.Xr man 7
|
||||
parser is used.
|
||||
With other arguments,
|
||||
.Fl m
|
||||
is silently ignored.
|
||||
.It Fl O Ar options
|
||||
Comma-separated output options.
|
||||
.It Fl T Ar output
|
||||
Output format.
|
||||
@ -153,13 +151,14 @@ to be reported on the standard error output and to affect the exit status.
|
||||
The
|
||||
.Ar level
|
||||
can be
|
||||
.Cm style ,
|
||||
.Cm warning ,
|
||||
.Cm error ,
|
||||
or
|
||||
.Cm unsupp ;
|
||||
.Cm all
|
||||
is an alias for
|
||||
.Cm warning .
|
||||
.Cm style .
|
||||
By default,
|
||||
.Nm
|
||||
is silent.
|
||||
@ -190,6 +189,9 @@ If multiple files are specified,
|
||||
will halt with the first failed parse.
|
||||
.El
|
||||
.Pp
|
||||
The options
|
||||
.Fl fhklw
|
||||
are also supported and are documented in man(1).
|
||||
In
|
||||
.Fl f
|
||||
and
|
||||
@ -197,60 +199,20 @@ and
|
||||
mode,
|
||||
.Nm
|
||||
also supports the options
|
||||
.Fl CMmOSsw
|
||||
.Fl CMmOSs
|
||||
described in the
|
||||
.Xr apropos 1
|
||||
manual.
|
||||
.Ss Input Formats
|
||||
The
|
||||
.Nm
|
||||
utility accepts
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
input with
|
||||
.Fl m Ns Cm doc
|
||||
and
|
||||
.Fl m Ns Cm an ,
|
||||
respectively.
|
||||
The
|
||||
.Xr mdoc 7
|
||||
format is
|
||||
.Em strongly
|
||||
recommended;
|
||||
.Xr man 7
|
||||
should only be used for legacy manuals.
|
||||
.Pp
|
||||
A third option,
|
||||
.Fl m Ns Cm andoc ,
|
||||
which is also the default, determines encoding on-the-fly: if the first
|
||||
non-comment macro is
|
||||
.Sq \&Dd
|
||||
or
|
||||
.Sq \&Dt ,
|
||||
the
|
||||
.Xr mdoc 7
|
||||
parser is used; otherwise, the
|
||||
.Xr man 7
|
||||
parser is used.
|
||||
.Pp
|
||||
If multiple
|
||||
files are specified with
|
||||
.Fl m Ns Cm andoc ,
|
||||
each has its file-type determined this way.
|
||||
If multiple files are
|
||||
specified and
|
||||
.Fl m Ns Cm doc
|
||||
or
|
||||
.Fl m Ns Cm an
|
||||
is specified, then this format is used exclusively.
|
||||
The options
|
||||
.Fl fkl
|
||||
are mutually exclusive and override each other.
|
||||
.Ss Output Formats
|
||||
The
|
||||
.Nm
|
||||
utility accepts the following
|
||||
.Fl T
|
||||
arguments, which correspond to output modes:
|
||||
.Bl -tag -width "-T locale"
|
||||
.Bl -tag -width "-T markdown"
|
||||
.It Fl T Cm ascii
|
||||
Produce 7-bit ASCII output.
|
||||
See
|
||||
@ -262,7 +224,7 @@ See
|
||||
.It Fl T Cm lint
|
||||
Parse only: produce no output.
|
||||
Implies
|
||||
.Fl W Cm warning .
|
||||
.Fl W Cm style .
|
||||
.It Fl T Cm locale
|
||||
Encode output using the current locale.
|
||||
This is the default.
|
||||
@ -274,6 +236,12 @@ Produce
|
||||
format output.
|
||||
See
|
||||
.Sx Man Output .
|
||||
.It Fl T Cm markdown
|
||||
Produce output in
|
||||
.Sy markdown
|
||||
format.
|
||||
See
|
||||
.Sx Markdown Output .
|
||||
.It Fl T Cm pdf
|
||||
Produce PDF output.
|
||||
See
|
||||
@ -290,9 +258,6 @@ See
|
||||
Encode output in the UTF\-8 multi-byte format.
|
||||
See
|
||||
.Sx UTF\-8 Output .
|
||||
.It Fl T Cm xhtml
|
||||
This is a synonym for
|
||||
.Fl T Cm html .
|
||||
.El
|
||||
.Pp
|
||||
If multiple input files are specified, these will be processed by the
|
||||
@ -377,7 +342,7 @@ The string
|
||||
for example,
|
||||
.Ar ../src/%I.html ,
|
||||
is used as a template for linked header files (usually via the
|
||||
.Sq \&In
|
||||
.Ic \&In
|
||||
macro).
|
||||
Instances of
|
||||
.Sq \&%I
|
||||
@ -390,7 +355,7 @@ The string
|
||||
for example,
|
||||
.Ar ../html%S/%N.%S.html ,
|
||||
is used as a template for linked manuals (usually via the
|
||||
.Sq \&Xr
|
||||
.Ic \&Xr
|
||||
macro).
|
||||
Instances of
|
||||
.Sq \&%N
|
||||
@ -436,13 +401,47 @@ If the input format is
|
||||
.Xr man 7 ,
|
||||
the input is copied to the output, expanding any
|
||||
.Xr roff 7
|
||||
.Sq so
|
||||
.Ic so
|
||||
requests.
|
||||
The parser is also run, and as usual, the
|
||||
.Fl W
|
||||
level controls which
|
||||
.Sx DIAGNOSTICS
|
||||
are displayed before copying the input to the output.
|
||||
.Ss Markdown Output
|
||||
Translate
|
||||
.Xr mdoc 7
|
||||
input to the
|
||||
.Sy markdown
|
||||
format conforming to
|
||||
.Lk http://daringfireball.net/projects/markdown/syntax.text\
|
||||
"John Gruber's 2004 specification" .
|
||||
The output also almost conforms to the
|
||||
.Lk http://commonmark.org/ CommonMark
|
||||
specification.
|
||||
.Pp
|
||||
The character set used for the markdown output is ASCII.
|
||||
Non-ASCII characters are encoded as HTML entities.
|
||||
Since that is not possible in literal font contexts, because these
|
||||
are rendered as code spans and code blocks in the markdown output,
|
||||
non-ASCII characters are transliterated to ASCII approximations in
|
||||
these contexts.
|
||||
.Pp
|
||||
Markdown is a very weak markup language, so all semantic markup is
|
||||
lost, and even part of the presentational markup may be lost.
|
||||
Do not use this as an intermediate step in converting to HTML;
|
||||
instead, use
|
||||
.Fl T Cm html
|
||||
directly.
|
||||
.Pp
|
||||
The
|
||||
.Xr man 7 ,
|
||||
.Xr tbl 7 ,
|
||||
and
|
||||
.Xr eqn 7
|
||||
input languages are not supported by
|
||||
.Fl T Cm markdown
|
||||
output mode.
|
||||
.Ss PDF Output
|
||||
PDF-1.1 output may be generated by
|
||||
.Fl T Cm pdf .
|
||||
@ -563,8 +562,16 @@ Meta data is not available in this case.
|
||||
.It Ev MANPAGER
|
||||
Any non-empty value of the environment variable
|
||||
.Ev MANPAGER
|
||||
will be used instead of the standard pagination program,
|
||||
.Xr more 1 .
|
||||
is used instead of the standard pagination program,
|
||||
.Xr more 1 ;
|
||||
see
|
||||
.Xr man 1
|
||||
for details.
|
||||
Only used if
|
||||
.Fl a
|
||||
or
|
||||
.Fl l
|
||||
is specified.
|
||||
.It Ev PAGER
|
||||
Specifies the pagination program to use when
|
||||
.Ev MANPAGER
|
||||
@ -572,7 +579,12 @@ is not defined.
|
||||
If neither PAGER nor MANPAGER is defined,
|
||||
.Xr more 1
|
||||
.Fl s
|
||||
will be used.
|
||||
is used.
|
||||
Only used if
|
||||
.Fl a
|
||||
or
|
||||
.Fl l
|
||||
is specified.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
@ -585,27 +597,32 @@ option:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.It 0
|
||||
No warnings or errors occurred, or those that did were ignored because
|
||||
they were lower than the requested
|
||||
No style suggestions, warnings or errors occurred, or those that
|
||||
did were ignored because they were lower than the requested
|
||||
.Ar level .
|
||||
.It 1
|
||||
At least one style suggestion occurred, but no warning or error, and
|
||||
.Fl W Cm style
|
||||
was specified.
|
||||
.It 2
|
||||
At least one warning occurred, but no error, and
|
||||
.Fl W Cm warning
|
||||
or
|
||||
.Fl W Cm style
|
||||
was specified.
|
||||
.It 3
|
||||
At least one parsing error occurred,
|
||||
but no unsupported feature was encountered, and
|
||||
.Fl W Cm error
|
||||
or
|
||||
.Fl W Cm warning
|
||||
was specified.
|
||||
or a lower
|
||||
.Ar level
|
||||
was requested.
|
||||
.It 4
|
||||
At least one unsupported feature was encountered, and
|
||||
.Fl W Cm unsupp ,
|
||||
.Fl W Cm error
|
||||
or
|
||||
.Fl W Cm warning
|
||||
was specified.
|
||||
.Fl W Cm unsupp
|
||||
or a lower
|
||||
.Ar level
|
||||
was requested.
|
||||
.It 5
|
||||
Invalid command line arguments were specified.
|
||||
No input files have been read.
|
||||
@ -620,12 +637,11 @@ to exit at once, possibly in the middle of parsing or formatting a file.
|
||||
Note that selecting
|
||||
.Fl T Cm lint
|
||||
output mode implies
|
||||
.Fl W Cm warning .
|
||||
.Fl W Cm style .
|
||||
.Sh EXAMPLES
|
||||
To page manuals to the terminal:
|
||||
.Pp
|
||||
.Dl $ mandoc \-W all,stop mandoc.1 2\*(Gt&1 | less
|
||||
.Dl $ mandoc mandoc.1 mdoc.3 mdoc.7 | less
|
||||
.Dl $ mandoc -l mandoc.1 man.1 apropos.1 makewhatis.8
|
||||
.Pp
|
||||
To produce HTML manuals with
|
||||
.Pa mandoc.css
|
||||
@ -705,9 +721,22 @@ rendering can be produced.
|
||||
Documents causing warnings may render poorly when using other
|
||||
formatting tools instead of
|
||||
.Nm .
|
||||
.It Cm style
|
||||
An input file uses dubious or discouraged style.
|
||||
This is not a complaint about the syntax, and probably neither
|
||||
formatting nor portability are in danger.
|
||||
While great care is taken to avoid false positives on the higher
|
||||
message levels, the
|
||||
.Cm style
|
||||
level tries to reduce the probability that issues go unnoticed,
|
||||
so it may occasionally issue bogus suggestions.
|
||||
Please use your good judgement to decide whether any particular
|
||||
.Cm style
|
||||
suggestion really justifies a change to the input file.
|
||||
.El
|
||||
.Pp
|
||||
Messages of the
|
||||
.Cm style ,
|
||||
.Cm warning ,
|
||||
.Cm error ,
|
||||
and
|
||||
@ -718,6 +747,58 @@ are hidden unless their level, or a lower level, is requested using a
|
||||
option or
|
||||
.Fl T Cm lint
|
||||
output mode.
|
||||
.Ss Style messages
|
||||
As indicated below, some style checks are only performed if a
|
||||
specific operating system name occurs in the arguments of the
|
||||
.Ic \&Os
|
||||
macro, of the
|
||||
.Fl Ios
|
||||
command line option, or, if neither are present, in the return value
|
||||
of the
|
||||
.Xr uname 3
|
||||
function.
|
||||
.Bl -ohang
|
||||
.It Sy "useless macro"
|
||||
.Pq mdoc
|
||||
A
|
||||
.Ic \&Bt ,
|
||||
.Ic \&Tn ,
|
||||
or
|
||||
.Ic \&Ud
|
||||
macro was found.
|
||||
Simply delete it: it serves no useful purpose.
|
||||
.It Sy "consider using OS macro"
|
||||
.Pq mdoc
|
||||
A string was found in plain text or in a
|
||||
.Ic \&Bx
|
||||
macro that could be represented using
|
||||
.Ic \&Ox ,
|
||||
.Ic \&Nx ,
|
||||
.Ic \&Fx ,
|
||||
or
|
||||
.Ic \&Dx .
|
||||
.It Sy "errnos out of order"
|
||||
.Pq mdoc, Nx
|
||||
The
|
||||
.Ic \&Er
|
||||
items in a
|
||||
.Ic \&Bl
|
||||
list are not in alphabetical order.
|
||||
.It Sy "duplicate errno"
|
||||
.Pq mdoc, Nx
|
||||
A
|
||||
.Ic \&Bl
|
||||
list contains two consecutive
|
||||
.Ic \&It
|
||||
entries describing the same
|
||||
.Ic \&Er
|
||||
number.
|
||||
.It Sy "description line ends with a full stop"
|
||||
.Pq mdoc
|
||||
Do not use punctuation at the end of an
|
||||
.Ic \&Nd
|
||||
block.
|
||||
.El
|
||||
.Ss Warnings related to the document prologue
|
||||
.Bl -ohang
|
||||
.It Sy "missing manual title, using UNTITLED"
|
||||
@ -870,6 +951,14 @@ The
|
||||
.Ic \&Nd
|
||||
macro lacks the required argument.
|
||||
The title line of the manual will end after the dash.
|
||||
.It Sy "description line outside NAME section"
|
||||
.Pq mdoc
|
||||
An
|
||||
.Ic \&Nd
|
||||
macro appears outside the NAME section.
|
||||
The arguments are printed anyway and the following text is used for
|
||||
.Xr apropos 1 ,
|
||||
but none of that behaviour is portable.
|
||||
.It Sy "sections out of conventional order"
|
||||
.Pq mdoc
|
||||
A standard section occurs after another section it usually precedes.
|
||||
@ -1088,7 +1177,7 @@ or
|
||||
.Ic \&Bl
|
||||
.Fl offset
|
||||
or
|
||||
.Fl width.
|
||||
.Fl width .
|
||||
.It Sy "missing display type, using -ragged"
|
||||
.Pq mdoc
|
||||
The
|
||||
@ -1310,6 +1399,12 @@ or
|
||||
.Ic \&Fn
|
||||
macro contains an opening or closing parenthesis; that's probably wrong,
|
||||
parentheses are added automatically.
|
||||
.It Sy "unknown library name"
|
||||
.Pq mdoc, not on Ox
|
||||
An
|
||||
.Ic \&Lb
|
||||
macro has an unknown name argument and will be rendered as
|
||||
.Qq library Dq Ar name .
|
||||
.It Sy "invalid content in Rs block"
|
||||
.Pq mdoc
|
||||
An
|
||||
@ -1657,6 +1752,11 @@ whatever mode was active before the block.
|
||||
A
|
||||
.Ic \&Bl
|
||||
macro fails to specify the list type.
|
||||
.It Sy "argument is not numeric, using 1"
|
||||
.Pq roff
|
||||
The argument of a
|
||||
.Ic \&ce
|
||||
request is not a number.
|
||||
.It Sy "missing manual name, using \(dq\(dq"
|
||||
.Pq mdoc
|
||||
The first call to
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc.3,v 1.38 2017/01/09 01:37:03 schwarze Exp $
|
||||
.\" $Id: mandoc.3,v 1.39 2017/05/17 23:39:31 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 9 2017 $
|
||||
.Dd $Mdocdate: May 17 2017 $
|
||||
.Dt MANDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -669,11 +669,9 @@ Using badly-nested blocks is
|
||||
.Em strongly discouraged ;
|
||||
for example, the
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml
|
||||
front-ends to
|
||||
front-end to
|
||||
.Xr mandoc 1
|
||||
are unable to render them in any meaningful way.
|
||||
is unable to render them in any meaningful way.
|
||||
Furthermore, behaviour when encountering badly-nested blocks is not
|
||||
consistent across troff implementations, especially when using multiple
|
||||
levels of badly-nested blocks.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mandoc.c,v 1.98 2015/11/12 22:44:27 schwarze Exp $ */
|
||||
/* $Id: mandoc.c,v 1.100 2017/06/02 19:21:23 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -175,7 +175,17 @@ mandoc_escape(const char **end, const char **start, int *sz)
|
||||
++*end;
|
||||
return ESCAPE_ERROR;
|
||||
}
|
||||
gly = ESCAPE_IGNORE;
|
||||
switch ((*start)[-1]) {
|
||||
case 'h':
|
||||
gly = ESCAPE_HORIZ;
|
||||
break;
|
||||
case 'l':
|
||||
gly = ESCAPE_HLINE;
|
||||
break;
|
||||
default:
|
||||
gly = ESCAPE_IGNORE;
|
||||
break;
|
||||
}
|
||||
term = **start;
|
||||
*start = ++*end;
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.css,v 1.17 2017/02/05 21:00:43 schwarze Exp $ */
|
||||
/* $Id: mandoc.css,v 1.18 2017/03/13 20:22:18 schwarze Exp $ */
|
||||
/*
|
||||
* Standard style sheet for mandoc(1) -Thtml and man.cgi(8).
|
||||
*/
|
||||
@ -14,6 +14,11 @@ ul, ol, dl { margin-top: 0em;
|
||||
margin-bottom: 0em; }
|
||||
li, dt { margin-top: 1em; }
|
||||
|
||||
a.selflink { border-bottom: thin dotted;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
text-decoration: inherit; }
|
||||
|
||||
/* Search form and search results. */
|
||||
|
||||
fieldset { border: thin solid silver;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mandoc.h,v 1.214 2017/01/28 23:30:08 schwarze Exp $ */
|
||||
/* $Id: mandoc.h,v 1.226 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -28,7 +28,7 @@
|
||||
*/
|
||||
enum mandoclevel {
|
||||
MANDOCLEVEL_OK = 0,
|
||||
MANDOCLEVEL_RESERVED,
|
||||
MANDOCLEVEL_STYLE, /* style suggestions */
|
||||
MANDOCLEVEL_WARNING, /* warnings: syntax, whitespace, etc. */
|
||||
MANDOCLEVEL_ERROR, /* input has been thrown away */
|
||||
MANDOCLEVEL_UNSUPP, /* input needs unimplemented features */
|
||||
@ -44,6 +44,14 @@ enum mandoclevel {
|
||||
enum mandocerr {
|
||||
MANDOCERR_OK,
|
||||
|
||||
MANDOCERR_STYLE, /* ===== start of style suggestions ===== */
|
||||
|
||||
MANDOCERR_MACRO_USELESS, /* useless macro: macro */
|
||||
MANDOCERR_BX, /* consider using OS macro: macro */
|
||||
MANDOCERR_ER_ORDER, /* errnos out of order: Er ... */
|
||||
MANDOCERR_ER_REP, /* duplicate errno: Er ... */
|
||||
MANDOCERR_ND_DOT, /* description line ends with a full stop */
|
||||
|
||||
MANDOCERR_WARNING, /* ===== start of warnings ===== */
|
||||
|
||||
/* related to the prologue */
|
||||
@ -71,6 +79,7 @@ enum mandocerr {
|
||||
MANDOCERR_NAMESEC_BAD, /* bad NAME section content: macro */
|
||||
MANDOCERR_NAMESEC_PUNCT, /* missing comma before name: Nm name */
|
||||
MANDOCERR_ND_EMPTY, /* missing description line, using "" */
|
||||
MANDOCERR_ND_LATE, /* description line outside NAME section */
|
||||
MANDOCERR_SEC_ORDER, /* sections out of conventional order: Sh title */
|
||||
MANDOCERR_SEC_REP, /* duplicate section title: Sh title */
|
||||
MANDOCERR_SEC_MSEC, /* unexpected section: Sh title for ... only */
|
||||
@ -90,6 +99,7 @@ enum mandocerr {
|
||||
MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */
|
||||
MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */
|
||||
MANDOCERR_BLK_LINE, /* line scope broken: macro breaks macro */
|
||||
MANDOCERR_BLK_BLANK, /* skipping blank line in line scope */
|
||||
|
||||
/* related to missing arguments */
|
||||
MANDOCERR_REQ_EMPTY, /* skipping empty request: request */
|
||||
@ -125,6 +135,7 @@ enum mandocerr {
|
||||
MANDOCERR_AT_BAD, /* unknown AT&T UNIX version: At version */
|
||||
MANDOCERR_FA_COMMA, /* comma in function argument: arg */
|
||||
MANDOCERR_FN_PAREN, /* parenthesis in function name: arg */
|
||||
MANDOCERR_LB_BAD, /* unknown library name: Lb ... */
|
||||
MANDOCERR_RS_BAD, /* invalid content in Rs block: macro */
|
||||
MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */
|
||||
MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */
|
||||
@ -177,6 +188,7 @@ enum mandocerr {
|
||||
MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */
|
||||
MANDOCERR_BD_NOARG, /* skipping display without arguments: Bd */
|
||||
MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
|
||||
MANDOCERR_CE_NONUM, /* argument is not numeric, using 1: ce ... */
|
||||
MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
|
||||
MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
|
||||
MANDOCERR_ST_BAD, /* unknown standard specifier: St standard */
|
||||
@ -234,9 +246,10 @@ enum tbl_cellt {
|
||||
*/
|
||||
struct tbl_cell {
|
||||
struct tbl_cell *next;
|
||||
char *wstr; /* min width represented as a string */
|
||||
size_t width; /* minimum column width */
|
||||
size_t spacing; /* to the right of the column */
|
||||
int vert; /* width of subsequent vertical line */
|
||||
enum tbl_cellt pos;
|
||||
size_t spacing;
|
||||
int col; /* column number, starting from 0 */
|
||||
int flags;
|
||||
#define TBL_CELL_TALIGN (1 << 0) /* t, T */
|
||||
@ -247,6 +260,7 @@ struct tbl_cell {
|
||||
#define TBL_CELL_UP (1 << 5) /* u, U */
|
||||
#define TBL_CELL_WIGN (1 << 6) /* z, Z */
|
||||
#define TBL_CELL_WMAX (1 << 7) /* x, X */
|
||||
enum tbl_cellt pos;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -274,9 +288,10 @@ enum tbl_datt {
|
||||
*/
|
||||
struct tbl_dat {
|
||||
struct tbl_cell *layout; /* layout cell */
|
||||
int spans; /* how many spans follow */
|
||||
struct tbl_dat *next;
|
||||
char *string; /* data (NULL if not TBL_DATA_DATA) */
|
||||
int spans; /* how many spans follow */
|
||||
int block; /* T{ text block T} */
|
||||
enum tbl_datt pos;
|
||||
};
|
||||
|
||||
@ -404,6 +419,8 @@ enum mandoc_esc {
|
||||
ESCAPE_NUMBERED, /* a numbered glyph */
|
||||
ESCAPE_UNICODE, /* a unicode codepoint */
|
||||
ESCAPE_NOSPACE, /* suppress space if the last on a line */
|
||||
ESCAPE_HORIZ, /* horizontal movement */
|
||||
ESCAPE_HLINE, /* horizontal line drawing */
|
||||
ESCAPE_SKIPCHAR, /* skip the next character */
|
||||
ESCAPE_OVERSTRIKE /* overstrike all chars in the argument */
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
.\" $Id: mandoc_char.7,v 1.64 2017/02/05 21:41:21 schwarze Exp $
|
||||
.\" $Id: mandoc_char.7,v 1.66 2017/06/02 12:43:52 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2011, 2013, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2011, 2013, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 5 2017 $
|
||||
.Dd $Mdocdate: June 2 2017 $
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -169,6 +169,8 @@ even on request and macro lines.
|
||||
.Ss Accents
|
||||
In output modes supporting such special output characters, for example
|
||||
.Fl T Cm pdf ,
|
||||
and sometimes less consistently in
|
||||
.Fl T Cm utf8 ,
|
||||
some
|
||||
.Xr roff 7
|
||||
formatters convert the following ASCII input characters to the
|
||||
@ -177,6 +179,7 @@ following Unicode special output characters:
|
||||
.It \(ga Ta U+2018 Ta left single quotation mark
|
||||
.It \(aq Ta U+2019 Ta right single quotation mark
|
||||
.It \(ti Ta U+02DC Ta small tilde
|
||||
.It \(ha Ta U+02C6 Ta modifier letter circumflex
|
||||
.El
|
||||
.Pp
|
||||
In prose, this automatic substitution is often desirable;
|
||||
@ -187,6 +190,7 @@ escaping to render as follows:
|
||||
.It \e(ga Ta U+0060 Ta grave accent
|
||||
.It \e(aq Ta U+0027 Ta apostrophe
|
||||
.It \e(ti Ta U+007E Ta tilde
|
||||
.It \e(ha Ta U+005E Ta circumflex accent
|
||||
.El
|
||||
.Ss Periods
|
||||
The period
|
||||
@ -279,6 +283,10 @@ Text markers:
|
||||
.It \e(sh Ta \(sh Ta hash (pound)
|
||||
.It \e(CR Ta \(CR Ta carriage return
|
||||
.It \e(OK Ta \(OK Ta check mark
|
||||
.It \e(CL Ta \(CL Ta club suit
|
||||
.It \e(SP Ta \(SP Ta spade suit
|
||||
.It \e(HE Ta \(HE Ta heart suit
|
||||
.It \e(DI Ta \(DI Ta diamond suit
|
||||
.El
|
||||
.Pp
|
||||
Legal symbols:
|
||||
@ -372,6 +380,7 @@ Arrows:
|
||||
.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
|
||||
.It \e(an Ta \(an Ta horizontal arrow extension
|
||||
.El
|
||||
.Pp
|
||||
Logical:
|
||||
@ -450,11 +459,20 @@ Mathematical:
|
||||
.It \e(Ah Ta \(Ah Ta aleph
|
||||
.It \e(Im Ta \(Im Ta imaginary
|
||||
.It \e(Re Ta \(Re Ta real
|
||||
.It \e(wp Ta \(wp Ta Weierstrass p
|
||||
.It \e(pd Ta \(pd Ta partial differential
|
||||
.It \e(-h Ta \(-h Ta Planck constant over 2\(*p
|
||||
.It \e[12] Ta \[12] Ta one-half
|
||||
.It \e[14] Ta \[14] Ta one-fourth
|
||||
.It \e[34] Ta \[34] Ta three-fourths
|
||||
.It \e[hbar] Ta \[hbar] Ta Planck constant over 2\(*p
|
||||
.It \e(12 Ta \(12 Ta one-half
|
||||
.It \e(14 Ta \(14 Ta one-fourth
|
||||
.It \e(34 Ta \(34 Ta three-fourths
|
||||
.It \e(18 Ta \(18 Ta one-eighth
|
||||
.It \e(38 Ta \(38 Ta three-eighths
|
||||
.It \e(58 Ta \(58 Ta five-eighths
|
||||
.It \e(78 Ta \(78 Ta seven-eighths
|
||||
.It \e(S1 Ta \(S1 Ta superscript 1
|
||||
.It \e(S2 Ta \(S2 Ta superscript 2
|
||||
.It \e(S3 Ta \(S3 Ta superscript 3
|
||||
.El
|
||||
.Pp
|
||||
Ligatures:
|
||||
@ -588,6 +606,8 @@ Units:
|
||||
.It \e(fm Ta \(fm Ta minute
|
||||
.It \e(sd Ta \(sd Ta second
|
||||
.It \e(mc Ta \(mc Ta micro
|
||||
.It \e(Of Ta \(Of Ta Spanish female ordinal
|
||||
.It \e(Om Ta \(Om Ta Spanish masculine ordinal
|
||||
.El
|
||||
.Pp
|
||||
Greek letters:
|
||||
@ -748,9 +768,7 @@ the
|
||||
differently between mandoc and groff.
|
||||
.It
|
||||
In
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml ,
|
||||
.Fl T Ns Cm html ,
|
||||
the \e(\(ti=, \e(nb, and \e(nc special characters render differently
|
||||
between mandoc and groff.
|
||||
.It
|
||||
|
@ -60,9 +60,19 @@ Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t .
|
||||
.Pp
|
||||
Provides the utility functions documented in
|
||||
.Xr mandoc_malloc 3 .
|
||||
.It Qq Pa mandoc_ohash.h
|
||||
Requires
|
||||
.In stddef.h
|
||||
for
|
||||
.Vt ptrdiff_t
|
||||
and
|
||||
.In stdint.h
|
||||
for
|
||||
.Vt uint32_t .
|
||||
.Pp
|
||||
Includes
|
||||
.In ohash.h
|
||||
and provides
|
||||
@ -113,17 +123,30 @@ from
|
||||
.Pa roff.h
|
||||
as an opaque type for function prototypes.
|
||||
.It Qq Pa roff.h
|
||||
Requires
|
||||
.Qq Pa mandoc_ohash.h
|
||||
for
|
||||
.Vt struct ohash .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt enum mdoc_endbody ,
|
||||
.Vt enum roff_macroset ,
|
||||
.Vt enum roff_next ,
|
||||
.Vt enum roff_sec ,
|
||||
.Vt enum roff_tok ,
|
||||
.Vt enum roff_type ,
|
||||
.Vt struct roff_man ,
|
||||
.Vt struct roff_meta ,
|
||||
.Vt struct roff_node ,
|
||||
and the function
|
||||
.Fn deroff .
|
||||
the constant array
|
||||
.Va roff_name
|
||||
and the functions
|
||||
.Fn deroff ,
|
||||
.Fn roffhash_alloc ,
|
||||
.Fn roffhash_find ,
|
||||
.Fn roffhash_free ,
|
||||
and
|
||||
.Fn roff_validate .
|
||||
.Pp
|
||||
Uses pointers to the types
|
||||
.Vt struct mdoc_arg
|
||||
@ -198,9 +221,10 @@ or
|
||||
.El
|
||||
.Ss Parser internals
|
||||
The following headers require inclusion of a parser interface header
|
||||
before they can be included. All parser interface headers should
|
||||
precede all parser internal headers. When any parser internal headers
|
||||
are included, the same file should not include any formatter headers.
|
||||
before they can be included.
|
||||
All parser interface headers should precede all parser internal headers.
|
||||
When any parser internal headers are included, the same file should
|
||||
not include any formatter headers.
|
||||
.Bl -tag -width Ds
|
||||
.It Qq Pa libmandoc.h
|
||||
Requires
|
||||
@ -271,6 +295,10 @@ from
|
||||
as opaque types for function prototypes.
|
||||
.It Qq Pa libmdoc.h
|
||||
Requires
|
||||
.Qq Pa roff.h
|
||||
for
|
||||
.Vt enum roff_tok
|
||||
and
|
||||
.Qq Pa mdoc.h
|
||||
for
|
||||
.Vt enum mdoc_*
|
||||
@ -303,6 +331,11 @@ When this header is included, the same file should not include
|
||||
or
|
||||
.Pa libroff.h .
|
||||
.It Qq Pa libman.h
|
||||
Requires
|
||||
.Qq Pa roff.h
|
||||
for
|
||||
.Vt enum roff_tok .
|
||||
.Pp
|
||||
Provides
|
||||
.Vt struct man_macro
|
||||
and some functions internal to the
|
||||
@ -405,6 +438,7 @@ Provides
|
||||
.Vt enum termtype ,
|
||||
.Vt struct termp_tbl ,
|
||||
.Vt struct termp ,
|
||||
.Fn roff_term_pre ,
|
||||
and many terminal formatting functions.
|
||||
.Pp
|
||||
Uses the opaque type
|
||||
@ -419,6 +453,8 @@ from
|
||||
.Pa mandoc.h
|
||||
and
|
||||
.Vt struct roff_meta
|
||||
and
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
as opaque types for function prototypes.
|
||||
@ -431,10 +467,7 @@ or
|
||||
Requires
|
||||
.In sys/types.h
|
||||
for
|
||||
.Vt size_t ,
|
||||
.In stdio.h
|
||||
for
|
||||
.Dv BUFSIZ ,
|
||||
.Vt size_t
|
||||
and
|
||||
.Qq Pa out.h
|
||||
for
|
||||
@ -450,8 +483,21 @@ Provides
|
||||
.Vt struct tagq ,
|
||||
.Vt struct htmlpair ,
|
||||
.Vt struct html ,
|
||||
.Fn roff_html_pre ,
|
||||
and many HTML formatting functions.
|
||||
.Pp
|
||||
Uses
|
||||
.Vt struct tbl_span
|
||||
and
|
||||
.Vt struct eqn
|
||||
from
|
||||
.Pa mandoc.h
|
||||
and
|
||||
.Vt struct roff_node
|
||||
from
|
||||
.Pa roff.h
|
||||
as opaque types for function prototypes.
|
||||
.Pp
|
||||
When this header is included, the same file should not include
|
||||
.Pa term.h
|
||||
or
|
||||
@ -506,8 +552,7 @@ Provides
|
||||
.Vt struct manpage ,
|
||||
.Vt struct mansearch ,
|
||||
and the functions
|
||||
.Fn mansearch_setup ,
|
||||
.Fn mansearch ,
|
||||
.Fn mansearch
|
||||
and
|
||||
.Fn mansearch_free .
|
||||
.Pp
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandoc_html.3,v 1.5 2017/01/28 22:36:38 schwarze Exp $
|
||||
.\" $Id: mandoc_html.3,v 1.8 2017/05/12 17:58:21 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 28 2017 $
|
||||
.Dd $Mdocdate: May 12 2017 $
|
||||
.Dt MANDOC_HTML 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -48,6 +48,14 @@
|
||||
.Fa "struct html *h"
|
||||
.Fa "const char *word"
|
||||
.Fc
|
||||
.Ft char *
|
||||
.Fo html_make_id
|
||||
.Fa "const struct roff_node *n"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo html_strlen
|
||||
.Fa "const char *cp"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The mandoc HTML formatter is not a formal library.
|
||||
However, as it is compiled into more than one program, in particular
|
||||
@ -145,6 +153,11 @@ the respective attribute is not written.
|
||||
Print a
|
||||
.Cm class
|
||||
attribute.
|
||||
This attribute letter can optionally be followed by the modifier letter
|
||||
.Cm T .
|
||||
In that case, a
|
||||
.Cm title
|
||||
attribute with the same value is also printed.
|
||||
.It Cm h
|
||||
Print a
|
||||
.Cm href
|
||||
@ -191,7 +204,7 @@ Instead, the rest of the format string consists of pairs of
|
||||
argument type letters and style name letters.
|
||||
.El
|
||||
.Pp
|
||||
Argument type letters each require on argument as follows:
|
||||
Argument type letters each require one argument as follows:
|
||||
.Bl -tag -width 1n -offset indent
|
||||
.It Cm h
|
||||
Requires one
|
||||
@ -220,10 +233,18 @@ width specifier.
|
||||
If the argument is
|
||||
.Dv NULL ,
|
||||
nothing is printed for this pair.
|
||||
.It Cm W
|
||||
Similar to
|
||||
.Cm w ,
|
||||
but makes the width negative by multiplying it with \(mi1.
|
||||
.Pp
|
||||
The
|
||||
.Cm w
|
||||
argument type letter can optionally be followed by one or two
|
||||
modifier letters.
|
||||
The modifier
|
||||
.Cm +
|
||||
increases the width by 10% to make even bold text fit
|
||||
and adds two units for padding between columns.
|
||||
The modifier
|
||||
.Cm \-
|
||||
makes the width negative by multiplying it with \-1.
|
||||
.El
|
||||
.Pp
|
||||
Style name letters decide what to do with the preceding argument:
|
||||
@ -301,8 +322,27 @@ and
|
||||
.Fn print_tagq
|
||||
functions.
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_make_id
|
||||
takes a node containing one or more text children
|
||||
and returns a newly allocated string containing the concatenation
|
||||
of the child strings, with blanks replaced by underscores.
|
||||
If the node
|
||||
.Fa n
|
||||
contains any non-text child node,
|
||||
.Fn html_make_id
|
||||
returns
|
||||
.Dv NULL
|
||||
instead.
|
||||
The caller is responsible for freeing the returned string.
|
||||
.Pp
|
||||
The function
|
||||
.Fn html_strlen
|
||||
counts the number of characters in
|
||||
.Fa cp .
|
||||
It is used as a crude estimate of the width needed to display a string.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn html_strlen ,
|
||||
.Fn print_eqn ,
|
||||
.Fn print_tbl ,
|
||||
and
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mandocd.8,v 1.1 2017/02/06 19:04:21 schwarze Exp $
|
||||
.\" $Id: mandocd.8,v 1.2 2017/03/18 19:56:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 6 2017 $
|
||||
.Dd $Mdocdate: March 18 2017 $
|
||||
.Dt MANDOCD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -85,7 +85,7 @@ Override the default operating system
|
||||
.Ar name
|
||||
for the
|
||||
.Xr mdoc 7
|
||||
.Ic Os
|
||||
.Ic \&Os
|
||||
and for the
|
||||
.Xr man 7
|
||||
.Ic TH
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mandocdb.c,v 1.244 2017/02/17 14:45:55 schwarze Exp $ */
|
||||
/* $Id: mandocdb.c,v 1.250 2017/05/17 22:27:12 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -183,8 +183,7 @@ static struct ohash names; /* table of all names */
|
||||
static struct ohash strings; /* table of all strings */
|
||||
static uint64_t name_mask;
|
||||
|
||||
static const struct mdoc_handler mdocs[MDOC_MAX] = {
|
||||
{ NULL, 0, 0 }, /* Ap */
|
||||
static const struct mdoc_handler __mdocs[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, 0, NODE_NOPRT }, /* Dd */
|
||||
{ NULL, 0, NODE_NOPRT }, /* Dt */
|
||||
{ NULL, 0, NODE_NOPRT }, /* Os */
|
||||
@ -200,6 +199,7 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
|
||||
{ NULL, 0, 0 }, /* It */
|
||||
{ NULL, 0, 0 }, /* Ad */
|
||||
{ NULL, TYPE_An, 0 }, /* An */
|
||||
{ NULL, 0, 0 }, /* Ap */
|
||||
{ NULL, TYPE_Ar, 0 }, /* Ar */
|
||||
{ NULL, TYPE_Cd, 0 }, /* Cd */
|
||||
{ NULL, TYPE_Cm, 0 }, /* Cm */
|
||||
@ -302,12 +302,10 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
|
||||
{ NULL, 0, 0 }, /* En */
|
||||
{ NULL, TYPE_Dx, NODE_NOSRC }, /* Dx */
|
||||
{ NULL, 0, 0 }, /* %Q */
|
||||
{ NULL, 0, 0 }, /* br */
|
||||
{ NULL, 0, 0 }, /* sp */
|
||||
{ NULL, 0, 0 }, /* %U */
|
||||
{ NULL, 0, 0 }, /* Ta */
|
||||
{ NULL, 0, 0 }, /* ll */
|
||||
};
|
||||
static const struct mdoc_handler *const mdocs = __mdocs - MDOC_Dd;
|
||||
|
||||
|
||||
int
|
||||
@ -1211,7 +1209,7 @@ mpages_merge(struct dba *dba, struct mparse *mp)
|
||||
} else if (man != NULL && man->macroset == MACROSET_MAN) {
|
||||
man_validate(man);
|
||||
if (*man->meta.msec != '\0' ||
|
||||
*man->meta.msec != '\0') {
|
||||
*man->meta.title != '\0') {
|
||||
mpage->form = FORM_SRC;
|
||||
mpage->sec = mandoc_strdup(man->meta.msec);
|
||||
mpage->arch = mandoc_strdup(mlink->arch);
|
||||
@ -1545,25 +1543,26 @@ parse_mdoc(struct mpage *mpage, const struct roff_meta *meta,
|
||||
const struct roff_node *n)
|
||||
{
|
||||
|
||||
assert(NULL != n);
|
||||
for (n = n->child; NULL != n; n = n->next) {
|
||||
if (n->flags & mdocs[n->tok].taboo)
|
||||
for (n = n->child; n != NULL; n = n->next) {
|
||||
if (n->tok == TOKEN_NONE ||
|
||||
n->tok < ROFF_MAX ||
|
||||
n->flags & mdocs[n->tok].taboo)
|
||||
continue;
|
||||
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
|
||||
switch (n->type) {
|
||||
case ROFFT_ELEM:
|
||||
case ROFFT_BLOCK:
|
||||
case ROFFT_HEAD:
|
||||
case ROFFT_BODY:
|
||||
case ROFFT_TAIL:
|
||||
if (NULL != mdocs[n->tok].fp)
|
||||
if (0 == (*mdocs[n->tok].fp)(mpage, meta, n))
|
||||
break;
|
||||
if (mdocs[n->tok].fp != NULL &&
|
||||
(*mdocs[n->tok].fp)(mpage, meta, n) == 0)
|
||||
break;
|
||||
if (mdocs[n->tok].mask)
|
||||
putmdockey(mpage, n->child,
|
||||
mdocs[n->tok].mask, mdocs[n->tok].taboo);
|
||||
break;
|
||||
default:
|
||||
assert(n->type != ROFFT_ROOT);
|
||||
continue;
|
||||
}
|
||||
if (NULL != n->child)
|
||||
@ -2123,6 +2122,23 @@ dbwrite(struct dba *dba)
|
||||
int status;
|
||||
pid_t child;
|
||||
|
||||
/*
|
||||
* Do not write empty databases, and delete existing ones
|
||||
* when makewhatis -u causes them to become empty.
|
||||
*/
|
||||
|
||||
dba_array_start(dba->pages);
|
||||
if (dba_array_next(dba->pages) == NULL) {
|
||||
if (unlink(MANDOC_DB) == -1)
|
||||
say(MANDOC_DB, "&unlink");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the database in a temporary file,
|
||||
* then atomically move it into place.
|
||||
*/
|
||||
|
||||
if (dba_write(MANDOC_DB "~", dba) != -1) {
|
||||
if (rename(MANDOC_DB "~", MANDOC_DB) == -1) {
|
||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
||||
@ -2132,6 +2148,11 @@ dbwrite(struct dba *dba)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We lack write permission and cannot replace the database
|
||||
* file, but let's at least check whether the data changed.
|
||||
*/
|
||||
|
||||
(void)strlcpy(tfn, "/tmp/mandocdb.XXXXXXXX", sizeof(tfn));
|
||||
if (mkdtemp(tfn) == NULL) {
|
||||
exitcode = (int)MANDOCLEVEL_SYSERR;
|
||||
|
@ -1,195 +0,0 @@
|
||||
/* $Id: manpage.c,v 1.14 2016/07/09 15:24:19 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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 "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "manconf.h"
|
||||
#include "mansearch.h"
|
||||
|
||||
static void show(const char *, const char *);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, term;
|
||||
size_t i, sz, linesz;
|
||||
ssize_t len;
|
||||
struct mansearch search;
|
||||
struct manpage *res;
|
||||
char *conf_file, *defpaths, *auxpaths, *line;
|
||||
char buf[PATH_MAX];
|
||||
const char *cmd;
|
||||
struct manconf conf;
|
||||
char *progname;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
term = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO);
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
++progname;
|
||||
|
||||
auxpaths = defpaths = conf_file = NULL;
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
memset(&search, 0, sizeof(struct mansearch));
|
||||
|
||||
while (-1 != (ch = getopt(argc, argv, "C:M:m:S:s:")))
|
||||
switch (ch) {
|
||||
case ('C'):
|
||||
conf_file = optarg;
|
||||
break;
|
||||
case ('M'):
|
||||
defpaths = optarg;
|
||||
break;
|
||||
case ('m'):
|
||||
auxpaths = optarg;
|
||||
break;
|
||||
case ('S'):
|
||||
search.arch = optarg;
|
||||
break;
|
||||
case ('s'):
|
||||
search.sec = optarg;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (0 == argc)
|
||||
goto usage;
|
||||
|
||||
search.outkey = "Nd";
|
||||
search.argmode = ARG_EXPR;
|
||||
|
||||
manconf_parse(&conf, conf_file, defpaths, auxpaths);
|
||||
ch = mansearch(&search, &conf.manpath, argc, argv, &res, &sz);
|
||||
manconf_free(&conf);
|
||||
|
||||
if (0 == ch)
|
||||
goto usage;
|
||||
|
||||
if (0 == sz) {
|
||||
free(res);
|
||||
return EXIT_FAILURE;
|
||||
} else if (1 == sz && term) {
|
||||
i = 1;
|
||||
goto show;
|
||||
} else if (NULL == res)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf("%6zu %s: %s\n",
|
||||
i + 1, res[i].names, res[i].output);
|
||||
free(res[i].names);
|
||||
free(res[i].output);
|
||||
}
|
||||
|
||||
if (0 == term) {
|
||||
for (i = 0; i < sz; i++)
|
||||
free(res[i].file);
|
||||
free(res);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
i = 1;
|
||||
printf("Enter a choice [1]: ");
|
||||
fflush(stdout);
|
||||
|
||||
line = NULL;
|
||||
linesz = 0;
|
||||
if ((len = getline(&line, &linesz, stdin)) != -1) {
|
||||
if ('\n' == line[--len] && len > 0) {
|
||||
line[len] = '\0';
|
||||
if ((i = atoi(line)) < 1 || i > sz)
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
|
||||
if (0 == i) {
|
||||
for (i = 0; i < sz; i++)
|
||||
free(res[i].file);
|
||||
free(res);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
show:
|
||||
cmd = res[i - 1].form ? "mandoc" : "cat";
|
||||
strlcpy(buf, res[i - 1].file, PATH_MAX);
|
||||
for (i = 0; i < sz; i++)
|
||||
free(res[i].file);
|
||||
free(res);
|
||||
|
||||
show(cmd, buf);
|
||||
/* NOTREACHED */
|
||||
usage:
|
||||
fprintf(stderr, "usage: %s [-C conf] "
|
||||
"[-M paths] "
|
||||
"[-m paths] "
|
||||
"[-S arch] "
|
||||
"[-s section] "
|
||||
"expr ...\n",
|
||||
progname);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static void
|
||||
show(const char *cmd, const char *file)
|
||||
{
|
||||
int fds[2];
|
||||
pid_t pid;
|
||||
|
||||
if (-1 == pipe(fds)) {
|
||||
perror(NULL);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (-1 == (pid = fork())) {
|
||||
perror(NULL);
|
||||
exit(EXIT_FAILURE);
|
||||
} else if (pid > 0) {
|
||||
dup2(fds[0], STDIN_FILENO);
|
||||
close(fds[1]);
|
||||
cmd = NULL != getenv("MANPAGER") ?
|
||||
getenv("MANPAGER") :
|
||||
(NULL != getenv("PAGER") ?
|
||||
getenv("PAGER") : "more");
|
||||
execlp(cmd, cmd, (char *)NULL);
|
||||
perror(cmd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
dup2(fds[1], STDOUT_FILENO);
|
||||
close(fds[0]);
|
||||
execlp(cmd, cmd, file, (char *)NULL);
|
||||
perror(cmd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mansearch.3,v 1.4 2015/03/27 17:37:25 schwarze Exp $
|
||||
.\" $Id: mansearch.3,v 1.5 2017/03/30 22:22:05 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
@ -14,28 +14,22 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: March 27 2015 $
|
||||
.Dd $Mdocdate: March 30 2017 $
|
||||
.Dt MANSEARCH 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mansearch ,
|
||||
.Nm mansearch_setup
|
||||
.Nm mansearch
|
||||
.Nd search manual page databases
|
||||
.Sh SYNOPSIS
|
||||
.In stdint.h
|
||||
.In manconf.h
|
||||
.In mansearch.h
|
||||
.Ft int
|
||||
.Fo mansearch_setup
|
||||
.Fa "int start"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo mansearch
|
||||
.Fa "const struct mansearch *search"
|
||||
.Fa "const struct manpaths *paths"
|
||||
.Fa "int argc"
|
||||
.Fa "char *argv[]"
|
||||
.Fa "const char *outkey"
|
||||
.Fa "struct manpage **res"
|
||||
.Fa "size_t *sz"
|
||||
.Fc
|
||||
@ -44,7 +38,7 @@ The
|
||||
.Fn mansearch
|
||||
function returns information about manuals matching a search query from a
|
||||
.Xr mandoc.db 5
|
||||
SQLite3 database.
|
||||
database.
|
||||
.Pp
|
||||
The query arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
@ -58,18 +52,6 @@ Directories to be searched, defined in
|
||||
Search criteria, usually taken from the command line.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fa "const char *outkey"
|
||||
selects which data to return in the
|
||||
.Va output
|
||||
field of the
|
||||
.Fa res
|
||||
structures.
|
||||
It takes any of the macro keys defined in
|
||||
.Pa mansearch_const.c
|
||||
and described in
|
||||
.Xr apropos 1 .
|
||||
.Pp
|
||||
The output arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fa "struct manpage **res"
|
||||
@ -89,19 +71,6 @@ array itself.
|
||||
Returns the number of result structures contained in
|
||||
.Fa res .
|
||||
.El
|
||||
.Pp
|
||||
To speed up searches, the
|
||||
.Fn mansearch_setup
|
||||
function can optionally be called with a
|
||||
.Fa start
|
||||
argument of 1 before
|
||||
.Fn mansearch
|
||||
to set up an SQLite3 pagecache.
|
||||
If it was called, it has to be called again with a
|
||||
.Fa start
|
||||
argument of 0 after the last call to
|
||||
.Fn mansearch
|
||||
to release the memory used for the pagecache.
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
For each manual page tree, the search is done in two steps.
|
||||
In the first step, a list of pages matching the search criteria is built.
|
||||
@ -112,103 +81,26 @@ array.
|
||||
.Pp
|
||||
All function mentioned here are defined in the file
|
||||
.Pa mansearch.c .
|
||||
No functions except
|
||||
.Fn mansearch
|
||||
and
|
||||
.Fn sql_statement
|
||||
build any SQL code, and no functions except
|
||||
.Fn mansearch ,
|
||||
.Fn buildnames ,
|
||||
and
|
||||
.Fn buildoutput
|
||||
execute it.
|
||||
.Ss Finding matches
|
||||
The query is built using the following grammar:
|
||||
.Bd -literal -offset indent
|
||||
<query> ::= "SELECT * FROM mpages WHERE" <condition>
|
||||
<condition> ::= "(" <condition> ")" |
|
||||
<condition> "OR" <condition> |
|
||||
<condition> "AND" <condition> |
|
||||
"desc" <operator> "?" |
|
||||
"id IN (SELECT pageid FROM" <subquery> ")"
|
||||
<subquery> ::= "names WHERE name" <operator> "?" |
|
||||
"keys WHERE key" <operator> "? AND bits & ?"
|
||||
<operator> ::= "MATCH" | "REGEXP"
|
||||
.Ed
|
||||
.Pp
|
||||
The MATCH and REGEXP operators are implemented by the functions
|
||||
.Fn sql_match
|
||||
and
|
||||
.Fn sql_regexp ,
|
||||
respectively.
|
||||
This is required because SQLite3 natively neither supports
|
||||
case-insensitive substring matching nor regular expression matching,
|
||||
but only string identity, shell globbing, and the weird home-brewed
|
||||
LIKE operator.
|
||||
.Pp
|
||||
Command line parsing is done by the function
|
||||
.Fn exprcomp
|
||||
building a singly linked list of
|
||||
.Vt expr
|
||||
structures, using the helper functions
|
||||
.Fn exprterm
|
||||
.Fn expr_and
|
||||
and
|
||||
.Fn exprspec .
|
||||
The resulting SQL statement is assembled by the function
|
||||
.Fn sql_statement
|
||||
and evaluated in the main loop of the
|
||||
.Fn mansearch
|
||||
function.
|
||||
.Fn exprterm .
|
||||
.Ss Assembling the results
|
||||
The names, sections, and architectures of the manuals found
|
||||
are assembled into the
|
||||
.Va names
|
||||
field of the result structure by the function
|
||||
.Fn buildnames ,
|
||||
using the following query:
|
||||
.Pp
|
||||
.Dl "SELECT * FROM mlinks WHERE pageid=? ORDER BY sec, arch, name"
|
||||
.Pp
|
||||
If the
|
||||
.Fa outkey
|
||||
differs from
|
||||
.Qq Ic \&Nd ,
|
||||
the requested output data is assembled into the
|
||||
.Va output
|
||||
field of the result structure by the function
|
||||
.Fn buildoutput ,
|
||||
using the following query:
|
||||
.Pp
|
||||
.Dl "SELECT * FROM keys WHERE pageid=? AND bits & ?"
|
||||
.Fn buildnames .
|
||||
.Sh FILES
|
||||
.Bl -tag -width mandoc.db -compact
|
||||
.It Pa mandoc.db
|
||||
The manual page database.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The simplest invocation
|
||||
.Pp
|
||||
.Dl apropos keyword
|
||||
.Pp
|
||||
results in the following SQL query:
|
||||
.Bd -literal
|
||||
SELECT * FROM mpages WHERE (
|
||||
id IN (SELECT pageid FROM names WHERE name MATCH 'keyword') OR
|
||||
desc MATCH 'keyword'
|
||||
);
|
||||
.Ed
|
||||
.Pp
|
||||
A more complicated request like
|
||||
.Pp
|
||||
.Dl apropos -s 2 Nm,Xr=getuid
|
||||
.Pp
|
||||
results in:
|
||||
.Bd -literal
|
||||
SELECT * FROM mpages WHERE (
|
||||
id IN (SELECT pageid FROM names WHERE name MATCH 'getuid') OR
|
||||
id IN (SELECT pageid FROM keys WHERE key MATCH 'getuid' AND bits & 4)
|
||||
) AND id IN (SELECT pageid FROM keys WHERE key REGEXP '^2$' AND bits & 2);
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr apropos 1 ,
|
||||
.Xr mandoc.db 5 ,
|
||||
@ -223,6 +115,6 @@ subsystem first appeared in
|
||||
A module to search manual page databases was first written by
|
||||
.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
|
||||
in 2011, at first using the Berkeley DB;
|
||||
he rewrote it for SQLite3 in 2012.
|
||||
The current version received major changes from
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
|
||||
he rewrote it for SQLite3 in 2012, and
|
||||
.An Ingo Schwarze Aq Mt schwarze@openbsd.org
|
||||
removed the dependency on SQLite3 in 2016.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $OpenBSD: mansearch.c,v 1.50 2016/07/09 15:23:36 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -67,9 +67,9 @@ static struct ohash *manmerge_term(struct expr *, struct ohash *);
|
||||
static struct ohash *manmerge_or(struct expr *, struct ohash *);
|
||||
static struct ohash *manmerge_and(struct expr *, struct ohash *);
|
||||
static char *buildnames(const struct dbm_page *);
|
||||
static char *buildoutput(size_t, int32_t);
|
||||
static size_t lstlen(const char *);
|
||||
static void lstcat(char *, size_t *, const char *);
|
||||
static char *buildoutput(size_t, struct dbm_page *);
|
||||
static size_t lstlen(const char *, size_t);
|
||||
static void lstcat(char *, size_t *, const char *, const char *);
|
||||
static int lstmatch(const char *, const char *);
|
||||
static struct expr *exprcomp(const struct mansearch *,
|
||||
int, char *[], int *);
|
||||
@ -155,7 +155,8 @@ mansearch(const struct mansearch *search,
|
||||
chdir_status = 1;
|
||||
|
||||
if (dbm_open(MANDOC_DB) == -1) {
|
||||
warn("%s/%s", paths->paths[i], MANDOC_DB);
|
||||
if (errno != ENOENT)
|
||||
warn("%s/%s", paths->paths[i], MANDOC_DB);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -181,9 +182,7 @@ mansearch(const struct mansearch *search,
|
||||
mandoc_asprintf(&mpage->file, "%s/%s",
|
||||
paths->paths[i], page->file + 1);
|
||||
mpage->names = buildnames(page);
|
||||
mpage->output = (int)outkey == KEY_Nd ?
|
||||
mandoc_strdup(page->desc) :
|
||||
buildoutput(outkey, page->addr);
|
||||
mpage->output = buildoutput(outkey, page);
|
||||
mpage->ipath = i;
|
||||
mpage->bits = rp->bits;
|
||||
mpage->sec = *page->sect - '0';
|
||||
@ -404,16 +403,16 @@ buildnames(const struct dbm_page *page)
|
||||
char *buf;
|
||||
size_t i, sz;
|
||||
|
||||
sz = lstlen(page->name) + 1 + lstlen(page->sect) +
|
||||
(page->arch == NULL ? 0 : 1 + lstlen(page->arch)) + 2;
|
||||
sz = lstlen(page->name, 2) + 1 + lstlen(page->sect, 2) +
|
||||
(page->arch == NULL ? 0 : 1 + lstlen(page->arch, 2)) + 2;
|
||||
buf = mandoc_malloc(sz);
|
||||
i = 0;
|
||||
lstcat(buf, &i, page->name);
|
||||
lstcat(buf, &i, page->name, ", ");
|
||||
buf[i++] = '(';
|
||||
lstcat(buf, &i, page->sect);
|
||||
lstcat(buf, &i, page->sect, ", ");
|
||||
if (page->arch != NULL) {
|
||||
buf[i++] = '/';
|
||||
lstcat(buf, &i, page->arch);
|
||||
lstcat(buf, &i, page->arch, ", ");
|
||||
}
|
||||
buf[i++] = ')';
|
||||
buf[i++] = '\0';
|
||||
@ -423,11 +422,11 @@ buildnames(const struct dbm_page *page)
|
||||
|
||||
/*
|
||||
* Count the buffer space needed to print the NUL-terminated
|
||||
* list of NUL-terminated strings, when printing two separator
|
||||
* list of NUL-terminated strings, when printing sep separator
|
||||
* characters between strings.
|
||||
*/
|
||||
static size_t
|
||||
lstlen(const char *cp)
|
||||
lstlen(const char *cp, size_t sep)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
@ -435,7 +434,7 @@ lstlen(const char *cp)
|
||||
if (cp[0] == '\0') {
|
||||
if (cp[1] == '\0')
|
||||
break;
|
||||
sz++;
|
||||
sz += sep - 1;
|
||||
} else if (cp[0] < ' ')
|
||||
sz--;
|
||||
cp++;
|
||||
@ -445,17 +444,20 @@ lstlen(const char *cp)
|
||||
|
||||
/*
|
||||
* Print the NUL-terminated list of NUL-terminated strings
|
||||
* into the buffer, seperating strings with a comma and a blank.
|
||||
* into the buffer, seperating strings with sep.
|
||||
*/
|
||||
static void
|
||||
lstcat(char *buf, size_t *i, const char *cp)
|
||||
lstcat(char *buf, size_t *i, const char *cp, const char *sep)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
for (;;) {
|
||||
if (cp[0] == '\0') {
|
||||
if (cp[1] == '\0')
|
||||
break;
|
||||
buf[(*i)++] = ',';
|
||||
buf[(*i)++] = ' ';
|
||||
s = sep;
|
||||
while (*s != '\0')
|
||||
buf[(*i)++] = *s++;
|
||||
} else if (cp[0] >= ' ')
|
||||
buf[(*i)++] = cp[0];
|
||||
cp++;
|
||||
@ -482,17 +484,46 @@ lstmatch(const char *want, const char *have)
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a list of values taken by the macro im
|
||||
* in the manual page with big-endian address addr.
|
||||
* Build a list of values taken by the macro im in the manual page.
|
||||
*/
|
||||
static char *
|
||||
buildoutput(size_t im, int32_t addr)
|
||||
buildoutput(size_t im, struct dbm_page *page)
|
||||
{
|
||||
const char *oldoutput, *sep;
|
||||
const char *oldoutput, *sep, *input;
|
||||
char *output, *newoutput, *value;
|
||||
size_t sz, i;
|
||||
|
||||
switch (im) {
|
||||
case KEY_Nd:
|
||||
return mandoc_strdup(page->desc);
|
||||
case KEY_Nm:
|
||||
input = page->name;
|
||||
break;
|
||||
case KEY_sec:
|
||||
input = page->sect;
|
||||
break;
|
||||
case KEY_arch:
|
||||
input = page->arch;
|
||||
if (input == NULL)
|
||||
input = "all\0";
|
||||
break;
|
||||
default:
|
||||
input = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (input != NULL) {
|
||||
sz = lstlen(input, 3) + 1;
|
||||
output = mandoc_malloc(sz);
|
||||
i = 0;
|
||||
lstcat(output, &i, input, " # ");
|
||||
output[i++] = '\0';
|
||||
assert(i == sz);
|
||||
return output;
|
||||
}
|
||||
|
||||
output = NULL;
|
||||
dbm_macro_bypage(im - 2, addr);
|
||||
dbm_macro_bypage(im - 2, page->addr);
|
||||
while ((value = dbm_macro_next()) != NULL) {
|
||||
if (output == NULL) {
|
||||
oldoutput = "";
|
||||
@ -642,6 +673,12 @@ exprterm(const struct mansearch *search, int argc, char *argv[], int *argi)
|
||||
return e;
|
||||
}
|
||||
|
||||
if (strcmp("-i", argv[*argi]) == 0 && *argi + 1 < argc) {
|
||||
cs = 0;
|
||||
++*argi;
|
||||
} else
|
||||
cs = 1;
|
||||
|
||||
e = mandoc_calloc(1, sizeof(*e));
|
||||
e->type = EXPR_TERM;
|
||||
e->bits = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mansearch.h,v 1.27 2016/08/01 12:31:00 schwarze Exp $ */
|
||||
/* $Id: mansearch.h,v 1.28 2017/04/17 20:05:08 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2013, 2014, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -21,6 +21,9 @@
|
||||
#define MANDOCDB_VERSION 1
|
||||
|
||||
#define MACRO_MAX 36
|
||||
#define KEY_arch 0
|
||||
#define KEY_sec 1
|
||||
#define KEY_Nm 38
|
||||
#define KEY_Nd 39
|
||||
#define KEY_MAX 40
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: mdoc.7,v 1.262 2017/02/16 14:38:12 schwarze Exp $
|
||||
.\" $Id: mdoc.7,v 1.264 2017/05/05 15:54:59 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010, 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 16 2017 $
|
||||
.Dd $Mdocdate: May 5 2017 $
|
||||
.Dt MDOC 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -476,8 +476,6 @@ in the alphabetical
|
||||
.It Sx \&Ap Ta apostrophe without surrounding whitespace (no arguments)
|
||||
.It Sx \&Sm Ta switch horizontal spacing mode: Op Cm on | off
|
||||
.It Sx \&Bk , \&Ek Ta keep block: Fl words
|
||||
.It Sx \&br Ta force output line break in text mode (no arguments)
|
||||
.It Sx \&sp Ta force vertical space: Op Ar height
|
||||
.El
|
||||
.Ss Semantic markup for command line utilities:
|
||||
.Bl -column "Brq, Bro, Brc" description
|
||||
@ -2736,29 +2734,6 @@ Examples:
|
||||
.Dl \&.Xr mandoc 1
|
||||
.Dl \&.Xr mandoc 1 \&;
|
||||
.Dl \&.Xr mandoc 1 \&Ns s behaviour
|
||||
.Ss \&br
|
||||
Emits a line-break.
|
||||
This macro should not be used; it is implemented for compatibility with
|
||||
historical manuals.
|
||||
.Pp
|
||||
Consider using
|
||||
.Sx \&Pp
|
||||
in the event of natural paragraph breaks.
|
||||
.Ss \&sp
|
||||
Emits vertical space.
|
||||
This macro should not be used; it is implemented for compatibility with
|
||||
historical manuals.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Sx \&sp Op Ar height
|
||||
.Pp
|
||||
The
|
||||
.Ar height
|
||||
argument is a scaling width as described in
|
||||
.Xr roff 7 .
|
||||
If unspecified,
|
||||
.Sx \&sp
|
||||
asserts a single vertical space.
|
||||
.Sh MACRO SYNTAX
|
||||
The syntax of a macro depends on its classification.
|
||||
In this section,
|
||||
@ -3043,8 +3018,6 @@ then the macro accepts an arbitrary number of arguments.
|
||||
.It Sx \&Va Ta Yes Ta Yes Ta n
|
||||
.It Sx \&Vt Ta Yes Ta Yes Ta >0
|
||||
.It Sx \&Xr Ta Yes Ta Yes Ta 2
|
||||
.It Sx \&br Ta \&No Ta \&No Ta 0
|
||||
.It Sx \&sp Ta \&No Ta \&No Ta 1
|
||||
.El
|
||||
.Ss Delimiters
|
||||
When a macro argument consists of one single input character
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc.c,v 1.260 2017/02/16 03:00:23 schwarze Exp $ */
|
||||
/* $Id: mdoc.c,v 1.266 2017/06/07 20:58:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -35,41 +35,6 @@
|
||||
#include "roff_int.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
const char *const __mdoc_macronames[MDOC_MAX + 1] = {
|
||||
"text",
|
||||
"Ap", "Dd", "Dt", "Os",
|
||||
"Sh", "Ss", "Pp", "D1",
|
||||
"Dl", "Bd", "Ed", "Bl",
|
||||
"El", "It", "Ad", "An",
|
||||
"Ar", "Cd", "Cm", "Dv",
|
||||
"Er", "Ev", "Ex", "Fa",
|
||||
"Fd", "Fl", "Fn", "Ft",
|
||||
"Ic", "In", "Li", "Nd",
|
||||
"Nm", "Op", "Ot", "Pa",
|
||||
"Rv", "St", "Va", "Vt",
|
||||
"Xr", "%A", "%B", "%D",
|
||||
"%I", "%J", "%N", "%O",
|
||||
"%P", "%R", "%T", "%V",
|
||||
"Ac", "Ao", "Aq", "At",
|
||||
"Bc", "Bf", "Bo", "Bq",
|
||||
"Bsx", "Bx", "Db", "Dc",
|
||||
"Do", "Dq", "Ec", "Ef",
|
||||
"Em", "Eo", "Fx", "Ms",
|
||||
"No", "Ns", "Nx", "Ox",
|
||||
"Pc", "Pf", "Po", "Pq",
|
||||
"Qc", "Ql", "Qo", "Qq",
|
||||
"Re", "Rs", "Sc", "So",
|
||||
"Sq", "Sm", "Sx", "Sy",
|
||||
"Tn", "Ux", "Xc", "Xo",
|
||||
"Fo", "Fc", "Oo", "Oc",
|
||||
"Bk", "Ek", "Bt", "Hf",
|
||||
"Fr", "Ud", "Lb", "Lp",
|
||||
"Lk", "Mt", "Brq", "Bro",
|
||||
"Brc", "%C", "Es", "En",
|
||||
"Dx", "%Q", "br", "sp",
|
||||
"%U", "Ta", "ll",
|
||||
};
|
||||
|
||||
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
|
||||
"split", "nosplit", "ragged",
|
||||
"unfilled", "literal", "file",
|
||||
@ -80,9 +45,7 @@ const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
|
||||
"width", "compact", "std",
|
||||
"filled", "words", "emphasis",
|
||||
"symbolic", "nested", "centered"
|
||||
};
|
||||
|
||||
const char * const *mdoc_macronames = __mdoc_macronames + 1;
|
||||
};
|
||||
const char * const *mdoc_argnames = __mdoc_argnames;
|
||||
|
||||
static int mdoc_ptext(struct roff_man *, int, char *, int);
|
||||
@ -119,13 +82,12 @@ mdoc_parseln(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
void
|
||||
mdoc_macro(MACRO_PROT_ARGS)
|
||||
{
|
||||
assert(tok > TOKEN_NONE && tok < MDOC_MAX);
|
||||
|
||||
assert(tok >= MDOC_Dd && tok < MDOC_MAX);
|
||||
(*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf);
|
||||
}
|
||||
|
||||
void
|
||||
mdoc_tail_alloc(struct roff_man *mdoc, int line, int pos, int tok)
|
||||
mdoc_tail_alloc(struct roff_man *mdoc, int line, int pos, enum roff_tok tok)
|
||||
{
|
||||
struct roff_node *p;
|
||||
|
||||
@ -135,8 +97,8 @@ mdoc_tail_alloc(struct roff_man *mdoc, int line, int pos, int tok)
|
||||
}
|
||||
|
||||
struct roff_node *
|
||||
mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos, int tok,
|
||||
struct roff_node *body)
|
||||
mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos,
|
||||
enum roff_tok tok, struct roff_node *body)
|
||||
{
|
||||
struct roff_node *p;
|
||||
|
||||
@ -153,7 +115,7 @@ mdoc_endbody_alloc(struct roff_man *mdoc, int line, int pos, int tok,
|
||||
|
||||
struct roff_node *
|
||||
mdoc_block_alloc(struct roff_man *mdoc, int line, int pos,
|
||||
int tok, struct mdoc_arg *args)
|
||||
enum roff_tok tok, struct mdoc_arg *args)
|
||||
{
|
||||
struct roff_node *p;
|
||||
|
||||
@ -180,7 +142,7 @@ mdoc_block_alloc(struct roff_man *mdoc, int line, int pos,
|
||||
|
||||
void
|
||||
mdoc_elem_alloc(struct roff_man *mdoc, int line, int pos,
|
||||
int tok, struct mdoc_arg *args)
|
||||
enum roff_tok tok, struct mdoc_arg *args)
|
||||
{
|
||||
struct roff_node *p;
|
||||
|
||||
@ -291,7 +253,7 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
* blank lines aren't allowed, but enough manuals assume this
|
||||
* behaviour that we want to work around it.
|
||||
*/
|
||||
roff_elem_alloc(mdoc, line, offs, MDOC_sp);
|
||||
roff_elem_alloc(mdoc, line, offs, ROFF_sp);
|
||||
mdoc->last->flags |= NODE_VALID | NODE_ENDED;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
return 1;
|
||||
@ -316,14 +278,20 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
|
||||
for (c = buf + offs; c != NULL; c = strchr(c + 1, '.')) {
|
||||
if (c - buf < offs + 2)
|
||||
continue;
|
||||
if (end - c < 4)
|
||||
if (end - c < 3)
|
||||
break;
|
||||
if (isalpha((unsigned char)c[-2]) &&
|
||||
isalpha((unsigned char)c[-1]) &&
|
||||
c[1] == ' ' &&
|
||||
isupper((unsigned char)(c[2] == ' ' ? c[3] : c[2])) &&
|
||||
(c[-2] != 'n' || c[-1] != 'c') &&
|
||||
(c[-2] != 'v' || c[-1] != 's'))
|
||||
if (c[1] != ' ' ||
|
||||
isalpha((unsigned char)c[-2]) == 0 ||
|
||||
isalpha((unsigned char)c[-1]) == 0 ||
|
||||
(c[-2] == 'n' && c[-1] == 'c') ||
|
||||
(c[-2] == 'v' && c[-1] == 's'))
|
||||
continue;
|
||||
c += 2;
|
||||
if (*c == ' ')
|
||||
c++;
|
||||
if (*c == ' ')
|
||||
c++;
|
||||
if (isupper((unsigned char)(*c)))
|
||||
mandoc_msg(MANDOCERR_EOS, mdoc->parse,
|
||||
line, (int)(c - buf), NULL);
|
||||
}
|
||||
@ -340,25 +308,18 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
{
|
||||
struct roff_node *n;
|
||||
const char *cp;
|
||||
int tok;
|
||||
int i, sv;
|
||||
char mac[5];
|
||||
size_t sz;
|
||||
enum roff_tok tok;
|
||||
int sv;
|
||||
|
||||
/* Determine the line macro. */
|
||||
|
||||
sv = offs;
|
||||
|
||||
/*
|
||||
* Copy the first word into a nil-terminated buffer.
|
||||
* Stop when a space, tab, escape, or eoln is encountered.
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
while (i < 4 && strchr(" \t\\", buf[offs]) == NULL)
|
||||
mac[i++] = buf[offs++];
|
||||
|
||||
mac[i] = '\0';
|
||||
|
||||
tok = (i > 1 && i < 4) ? mdoc_hash_find(mac) : TOKEN_NONE;
|
||||
|
||||
tok = TOKEN_NONE;
|
||||
for (sz = 0; sz < 4 && strchr(" \t\\", buf[offs]) == NULL; sz++)
|
||||
offs++;
|
||||
if (sz == 2 || sz == 3)
|
||||
tok = roffhash_find(mdoc->mdocmac, buf + sv, sz);
|
||||
if (tok == TOKEN_NONE) {
|
||||
mandoc_msg(MANDOCERR_MACRO, mdoc->parse,
|
||||
ln, sv, buf + sv - 1);
|
||||
@ -382,7 +343,7 @@ mdoc_pmacro(struct roff_man *mdoc, int ln, char *buf, int offs)
|
||||
|
||||
/* Jump to the next non-whitespace word. */
|
||||
|
||||
while (buf[offs] && ' ' == buf[offs])
|
||||
while (buf[offs] == ' ')
|
||||
offs++;
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc.h,v 1.144 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: mdoc.h,v 1.145 2017/04/24 23:06:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,131 +16,6 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define MDOC_Ap 0
|
||||
#define MDOC_Dd 1
|
||||
#define MDOC_Dt 2
|
||||
#define MDOC_Os 3
|
||||
#define MDOC_Sh 4
|
||||
#define MDOC_Ss 5
|
||||
#define MDOC_Pp 6
|
||||
#define MDOC_D1 7
|
||||
#define MDOC_Dl 8
|
||||
#define MDOC_Bd 9
|
||||
#define MDOC_Ed 10
|
||||
#define MDOC_Bl 11
|
||||
#define MDOC_El 12
|
||||
#define MDOC_It 13
|
||||
#define MDOC_Ad 14
|
||||
#define MDOC_An 15
|
||||
#define MDOC_Ar 16
|
||||
#define MDOC_Cd 17
|
||||
#define MDOC_Cm 18
|
||||
#define MDOC_Dv 19
|
||||
#define MDOC_Er 20
|
||||
#define MDOC_Ev 21
|
||||
#define MDOC_Ex 22
|
||||
#define MDOC_Fa 23
|
||||
#define MDOC_Fd 24
|
||||
#define MDOC_Fl 25
|
||||
#define MDOC_Fn 26
|
||||
#define MDOC_Ft 27
|
||||
#define MDOC_Ic 28
|
||||
#define MDOC_In 29
|
||||
#define MDOC_Li 30
|
||||
#define MDOC_Nd 31
|
||||
#define MDOC_Nm 32
|
||||
#define MDOC_Op 33
|
||||
#define MDOC_Ot 34
|
||||
#define MDOC_Pa 35
|
||||
#define MDOC_Rv 36
|
||||
#define MDOC_St 37
|
||||
#define MDOC_Va 38
|
||||
#define MDOC_Vt 39
|
||||
#define MDOC_Xr 40
|
||||
#define MDOC__A 41
|
||||
#define MDOC__B 42
|
||||
#define MDOC__D 43
|
||||
#define MDOC__I 44
|
||||
#define MDOC__J 45
|
||||
#define MDOC__N 46
|
||||
#define MDOC__O 47
|
||||
#define MDOC__P 48
|
||||
#define MDOC__R 49
|
||||
#define MDOC__T 50
|
||||
#define MDOC__V 51
|
||||
#define MDOC_Ac 52
|
||||
#define MDOC_Ao 53
|
||||
#define MDOC_Aq 54
|
||||
#define MDOC_At 55
|
||||
#define MDOC_Bc 56
|
||||
#define MDOC_Bf 57
|
||||
#define MDOC_Bo 58
|
||||
#define MDOC_Bq 59
|
||||
#define MDOC_Bsx 60
|
||||
#define MDOC_Bx 61
|
||||
#define MDOC_Db 62
|
||||
#define MDOC_Dc 63
|
||||
#define MDOC_Do 64
|
||||
#define MDOC_Dq 65
|
||||
#define MDOC_Ec 66
|
||||
#define MDOC_Ef 67
|
||||
#define MDOC_Em 68
|
||||
#define MDOC_Eo 69
|
||||
#define MDOC_Fx 70
|
||||
#define MDOC_Ms 71
|
||||
#define MDOC_No 72
|
||||
#define MDOC_Ns 73
|
||||
#define MDOC_Nx 74
|
||||
#define MDOC_Ox 75
|
||||
#define MDOC_Pc 76
|
||||
#define MDOC_Pf 77
|
||||
#define MDOC_Po 78
|
||||
#define MDOC_Pq 79
|
||||
#define MDOC_Qc 80
|
||||
#define MDOC_Ql 81
|
||||
#define MDOC_Qo 82
|
||||
#define MDOC_Qq 83
|
||||
#define MDOC_Re 84
|
||||
#define MDOC_Rs 85
|
||||
#define MDOC_Sc 86
|
||||
#define MDOC_So 87
|
||||
#define MDOC_Sq 88
|
||||
#define MDOC_Sm 89
|
||||
#define MDOC_Sx 90
|
||||
#define MDOC_Sy 91
|
||||
#define MDOC_Tn 92
|
||||
#define MDOC_Ux 93
|
||||
#define MDOC_Xc 94
|
||||
#define MDOC_Xo 95
|
||||
#define MDOC_Fo 96
|
||||
#define MDOC_Fc 97
|
||||
#define MDOC_Oo 98
|
||||
#define MDOC_Oc 99
|
||||
#define MDOC_Bk 100
|
||||
#define MDOC_Ek 101
|
||||
#define MDOC_Bt 102
|
||||
#define MDOC_Hf 103
|
||||
#define MDOC_Fr 104
|
||||
#define MDOC_Ud 105
|
||||
#define MDOC_Lb 106
|
||||
#define MDOC_Lp 107
|
||||
#define MDOC_Lk 108
|
||||
#define MDOC_Mt 109
|
||||
#define MDOC_Brq 110
|
||||
#define MDOC_Bro 111
|
||||
#define MDOC_Brc 112
|
||||
#define MDOC__C 113
|
||||
#define MDOC_Es 114
|
||||
#define MDOC_En 115
|
||||
#define MDOC_Dx 116
|
||||
#define MDOC__Q 117
|
||||
#define MDOC_br 118
|
||||
#define MDOC_sp 119
|
||||
#define MDOC__U 120
|
||||
#define MDOC_Ta 121
|
||||
#define MDOC_ll 122
|
||||
#define MDOC_MAX 123
|
||||
|
||||
enum mdocargt {
|
||||
MDOC_Split, /* -split */
|
||||
MDOC_Nosplit, /* -nospli */
|
||||
@ -274,11 +149,7 @@ union mdoc_data {
|
||||
struct mdoc_rs Rs;
|
||||
};
|
||||
|
||||
/* Names of macros. */
|
||||
extern const char *const *mdoc_macronames;
|
||||
|
||||
/* Names of macro args. Index is enum mdocargt. */
|
||||
extern const char *const *mdoc_argnames;
|
||||
|
||||
|
||||
void mdoc_validate(struct roff_man *);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: mdoc_argv.c,v 1.109 2016/08/28 16:15:12 schwarze Exp $ */
|
||||
/* $Id: mdoc_argv.c,v 1.115 2017/05/30 16:22:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -144,8 +144,7 @@ static const enum mdocargt args_Bl[] = {
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_DELIM, NULL }, /* Ap */
|
||||
static const struct mdocarg __mdocargs[MDOC_MAX - MDOC_Dd] = {
|
||||
{ ARGSFL_NONE, NULL }, /* Dd */
|
||||
{ ARGSFL_NONE, NULL }, /* Dt */
|
||||
{ ARGSFL_NONE, NULL }, /* Os */
|
||||
@ -161,6 +160,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_NONE, NULL }, /* It */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ad */
|
||||
{ ARGSFL_DELIM, args_An }, /* An */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ap */
|
||||
{ ARGSFL_DELIM, NULL }, /* Ar */
|
||||
{ ARGSFL_DELIM, NULL }, /* Cd */
|
||||
{ ARGSFL_DELIM, NULL }, /* Cm */
|
||||
@ -263,12 +263,10 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
{ ARGSFL_DELIM, NULL }, /* En */
|
||||
{ ARGSFL_DELIM, NULL }, /* Dx */
|
||||
{ ARGSFL_NONE, NULL }, /* %Q */
|
||||
{ ARGSFL_NONE, NULL }, /* br */
|
||||
{ ARGSFL_NONE, NULL }, /* sp */
|
||||
{ ARGSFL_NONE, NULL }, /* %U */
|
||||
{ ARGSFL_NONE, NULL }, /* Ta */
|
||||
{ ARGSFL_NONE, NULL }, /* ll */
|
||||
};
|
||||
static const struct mdocarg *const mdocargs = __mdocargs - MDOC_Dd;
|
||||
|
||||
|
||||
/*
|
||||
@ -277,7 +275,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
|
||||
* Some flags take no argument, some one, some multiple.
|
||||
*/
|
||||
void
|
||||
mdoc_argv(struct roff_man *mdoc, int line, int tok,
|
||||
mdoc_argv(struct roff_man *mdoc, int line, enum roff_tok tok,
|
||||
struct mdoc_arg **reta, int *pos, char *buf)
|
||||
{
|
||||
struct mdoc_argv tmpv;
|
||||
@ -291,6 +289,7 @@ mdoc_argv(struct roff_man *mdoc, int line, int tok,
|
||||
|
||||
/* Which flags does this macro support? */
|
||||
|
||||
assert(tok >= MDOC_Dd && tok < MDOC_MAX);
|
||||
argtable = mdocargs[tok].argvs;
|
||||
if (argtable == NULL)
|
||||
return;
|
||||
@ -415,7 +414,7 @@ argn_free(struct mdoc_arg *p, int iarg)
|
||||
|
||||
enum margserr
|
||||
mdoc_args(struct roff_man *mdoc, int line, int *pos,
|
||||
char *buf, int tok, char **v)
|
||||
char *buf, enum roff_tok tok, char **v)
|
||||
{
|
||||
struct roff_node *n;
|
||||
char *v_local;
|
||||
@ -424,8 +423,6 @@ mdoc_args(struct roff_man *mdoc, int line, int *pos,
|
||||
if (v == NULL)
|
||||
v = &v_local;
|
||||
fl = tok == TOKEN_NONE ? ARGSFL_NONE : mdocargs[tok].flags;
|
||||
if (tok != MDOC_It)
|
||||
return args(mdoc, line, pos, buf, fl, v);
|
||||
|
||||
/*
|
||||
* We know that we're in an `It', so it's reasonable to expect
|
||||
@ -434,12 +431,15 @@ mdoc_args(struct roff_man *mdoc, int line, int *pos,
|
||||
* safe fall-back into the default behaviour.
|
||||
*/
|
||||
|
||||
for (n = mdoc->last; n; n = n->parent)
|
||||
if (MDOC_Bl == n->tok)
|
||||
if (LIST_column == n->norm->Bl.type) {
|
||||
if (tok == MDOC_It) {
|
||||
for (n = mdoc->last; n != NULL; n = n->parent) {
|
||||
if (n->tok != MDOC_Bl)
|
||||
continue;
|
||||
if (n->norm->Bl.type == LIST_column)
|
||||
fl = ARGSFL_TABSEP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return args(mdoc, line, pos, buf, fl, v);
|
||||
}
|
||||
@ -555,14 +555,14 @@ args(struct roff_man *mdoc, int line, int *pos,
|
||||
if ( ! (mdoc->flags & MDOC_PHRASE))
|
||||
mandoc_msg(MANDOCERR_ARG_QUOTE,
|
||||
mdoc->parse, line, *pos, NULL);
|
||||
return ARGS_QWORD;
|
||||
return ARGS_WORD;
|
||||
}
|
||||
|
||||
mdoc->flags &= ~MDOC_PHRASELIT;
|
||||
buf[(*pos)++] = '\0';
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
return ARGS_QWORD;
|
||||
return ARGS_WORD;
|
||||
|
||||
while (' ' == buf[*pos])
|
||||
(*pos)++;
|
||||
@ -571,7 +571,7 @@ args(struct roff_man *mdoc, int line, int *pos,
|
||||
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
|
||||
line, *pos, NULL);
|
||||
|
||||
return ARGS_QWORD;
|
||||
return ARGS_WORD;
|
||||
}
|
||||
|
||||
p = &buf[*pos];
|
||||
|
@ -1,95 +0,0 @@
|
||||
/* $Id: mdoc_hash.c,v 1.27 2016/07/15 18:03:45 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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 "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "mdoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
static unsigned char table[27 * 12];
|
||||
|
||||
|
||||
void
|
||||
mdoc_hash_init(void)
|
||||
{
|
||||
int i, j, major;
|
||||
const char *p;
|
||||
|
||||
if (*table != '\0')
|
||||
return;
|
||||
|
||||
memset(table, UCHAR_MAX, sizeof(table));
|
||||
|
||||
for (i = 0; i < (int)MDOC_MAX; i++) {
|
||||
p = mdoc_macronames[i];
|
||||
|
||||
if (isalpha((unsigned char)p[1]))
|
||||
major = 12 * (tolower((unsigned char)p[1]) - 97);
|
||||
else
|
||||
major = 12 * 26;
|
||||
|
||||
for (j = 0; j < 12; j++)
|
||||
if (UCHAR_MAX == table[major + j]) {
|
||||
table[major + j] = (unsigned char)i;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(j < 12);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
mdoc_hash_find(const char *p)
|
||||
{
|
||||
int major, i, j;
|
||||
|
||||
if (0 == p[0])
|
||||
return TOKEN_NONE;
|
||||
if ( ! isalpha((unsigned char)p[0]) && '%' != p[0])
|
||||
return TOKEN_NONE;
|
||||
|
||||
if (isalpha((unsigned char)p[1]))
|
||||
major = 12 * (tolower((unsigned char)p[1]) - 97);
|
||||
else if ('1' == p[1])
|
||||
major = 12 * 26;
|
||||
else
|
||||
return TOKEN_NONE;
|
||||
|
||||
if (p[2] && p[3])
|
||||
return TOKEN_NONE;
|
||||
|
||||
for (j = 0; j < 12; j++) {
|
||||
if (UCHAR_MAX == (i = table[major + j]))
|
||||
break;
|
||||
if (0 == strcmp(p, mdoc_macronames[i]))
|
||||
return i;
|
||||
}
|
||||
|
||||
return TOKEN_NONE;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_html.c,v 1.271 2017/02/16 03:00:23 schwarze Exp $ */
|
||||
/* $Id: mdoc_html.c,v 1.289 2017/05/30 16:31:29 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -48,7 +48,7 @@ struct htmlmdoc {
|
||||
void (*post)(MDOC_ARGS);
|
||||
};
|
||||
|
||||
static char *make_id(const struct roff_node *);
|
||||
static char *cond_id(const struct roff_node *);
|
||||
static void print_mdoc_head(MDOC_ARGS);
|
||||
static void print_mdoc_node(MDOC_ARGS);
|
||||
static void print_mdoc_nodelist(MDOC_ARGS);
|
||||
@ -108,7 +108,6 @@ static int mdoc_rs_pre(MDOC_ARGS);
|
||||
static int mdoc_sh_pre(MDOC_ARGS);
|
||||
static int mdoc_skip_pre(MDOC_ARGS);
|
||||
static int mdoc_sm_pre(MDOC_ARGS);
|
||||
static int mdoc_sp_pre(MDOC_ARGS);
|
||||
static int mdoc_ss_pre(MDOC_ARGS);
|
||||
static int mdoc_st_pre(MDOC_ARGS);
|
||||
static int mdoc_sx_pre(MDOC_ARGS);
|
||||
@ -118,8 +117,7 @@ static int mdoc_vt_pre(MDOC_ARGS);
|
||||
static int mdoc_xr_pre(MDOC_ARGS);
|
||||
static int mdoc_xx_pre(MDOC_ARGS);
|
||||
|
||||
static const struct htmlmdoc mdocs[MDOC_MAX] = {
|
||||
{mdoc_ap_pre, NULL}, /* Ap */
|
||||
static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_Dd] = {
|
||||
{NULL, NULL}, /* Dd */
|
||||
{NULL, NULL}, /* Dt */
|
||||
{NULL, NULL}, /* Os */
|
||||
@ -135,6 +133,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
|
||||
{mdoc_it_pre, NULL}, /* It */
|
||||
{mdoc_ad_pre, NULL}, /* Ad */
|
||||
{mdoc_an_pre, NULL}, /* An */
|
||||
{mdoc_ap_pre, NULL}, /* Ap */
|
||||
{mdoc_ar_pre, NULL}, /* Ar */
|
||||
{mdoc_cd_pre, NULL}, /* Cd */
|
||||
{mdoc_cm_pre, NULL}, /* Cm */
|
||||
@ -237,12 +236,10 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
|
||||
{mdoc_quote_pre, mdoc_quote_post}, /* En */
|
||||
{mdoc_xx_pre, NULL}, /* Dx */
|
||||
{mdoc__x_pre, mdoc__x_post}, /* %Q */
|
||||
{mdoc_sp_pre, NULL}, /* br */
|
||||
{mdoc_sp_pre, NULL}, /* sp */
|
||||
{mdoc__x_pre, mdoc__x_post}, /* %U */
|
||||
{NULL, NULL}, /* Ta */
|
||||
{mdoc_skip_pre, NULL}, /* ll */
|
||||
};
|
||||
static const struct htmlmdoc *const mdocs = __mdocs - MDOC_Dd;
|
||||
|
||||
|
||||
/*
|
||||
@ -362,9 +359,9 @@ print_mdoc_node(MDOC_ARGS)
|
||||
* Make sure that if we're in a literal mode already
|
||||
* (i.e., within a <PRE>) don't print the newline.
|
||||
*/
|
||||
if (' ' == *n->string && NODE_LINE & n->flags)
|
||||
if ( ! (HTML_LITERAL & h->flags))
|
||||
print_otag(h, TAG_BR, "");
|
||||
if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(h->flags & (HTML_LITERAL | HTML_NONEWLINE)) == 0)
|
||||
print_otag(h, TAG_BR, "");
|
||||
if (NODE_DELIMC & n->flags)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, n->string);
|
||||
@ -393,7 +390,14 @@ print_mdoc_node(MDOC_ARGS)
|
||||
t = h->tag;
|
||||
}
|
||||
assert(h->tblt == NULL);
|
||||
if (mdocs[n->tok].pre && (n->end == ENDBODY_NOT || n->child))
|
||||
if (n->tok < ROFF_MAX) {
|
||||
roff_html_pre(h, n);
|
||||
child = 0;
|
||||
break;
|
||||
}
|
||||
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
|
||||
if (mdocs[n->tok].pre != NULL &&
|
||||
(n->end == ENDBODY_NOT || n->child != NULL))
|
||||
child = (*mdocs[n->tok].pre)(meta, n, h);
|
||||
break;
|
||||
}
|
||||
@ -412,7 +416,9 @@ print_mdoc_node(MDOC_ARGS)
|
||||
case ROFFT_EQN:
|
||||
break;
|
||||
default:
|
||||
if ( ! mdocs[n->tok].post || n->flags & NODE_ENDED)
|
||||
if (n->tok < ROFF_MAX ||
|
||||
mdocs[n->tok].post == NULL ||
|
||||
n->flags & NODE_ENDED)
|
||||
break;
|
||||
(*mdocs[n->tok].post)(meta, n, h);
|
||||
if (n->end != ENDBODY_NOT)
|
||||
@ -477,25 +483,19 @@ mdoc_root_pre(MDOC_ARGS)
|
||||
}
|
||||
|
||||
static char *
|
||||
make_id(const struct roff_node *n)
|
||||
cond_id(const struct roff_node *n)
|
||||
{
|
||||
const struct roff_node *nch;
|
||||
char *buf, *cp;
|
||||
|
||||
for (nch = n->child; nch != NULL; nch = nch->next)
|
||||
if (nch->type != ROFFT_TEXT)
|
||||
return NULL;
|
||||
|
||||
buf = NULL;
|
||||
deroff(&buf, n);
|
||||
|
||||
/* http://www.w3.org/TR/html5/dom.html#the-id-attribute */
|
||||
|
||||
for (cp = buf; *cp != '\0'; cp++)
|
||||
if (*cp == ' ')
|
||||
*cp = '_';
|
||||
|
||||
return buf;
|
||||
if (n->child != NULL &&
|
||||
n->child->type == ROFFT_TEXT &&
|
||||
(n->prev == NULL ||
|
||||
(n->prev->type == ROFFT_TEXT &&
|
||||
strcmp(n->prev->string, "|") == 0)) &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Xo &&
|
||||
n->parent->parent->prev == NULL &&
|
||||
n->parent->parent->parent->tok == MDOC_It)))
|
||||
return html_make_id(n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -505,8 +505,10 @@ mdoc_sh_pre(MDOC_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
id = make_id(n);
|
||||
print_otag(h, TAG_H1, "ci", "Sh", id);
|
||||
id = html_make_id(n);
|
||||
print_otag(h, TAG_H1, "cTi", "Sh", id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
free(id);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
@ -527,8 +529,10 @@ mdoc_ss_pre(MDOC_ARGS)
|
||||
if (n->type != ROFFT_HEAD)
|
||||
return 1;
|
||||
|
||||
id = make_id(n);
|
||||
print_otag(h, TAG_H2, "ci", "Ss", id);
|
||||
id = html_make_id(n);
|
||||
print_otag(h, TAG_H2, "cTi", "Ss", id);
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
@ -536,9 +540,14 @@ mdoc_ss_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_fl_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_B, "c", "Fl");
|
||||
print_text(h, "\\-");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_B, "cTi", "Fl", id);
|
||||
free(id);
|
||||
|
||||
print_text(h, "\\-");
|
||||
if (!(n->child == NULL &&
|
||||
(n->next == NULL ||
|
||||
n->next->type == ROFFT_TEXT ||
|
||||
@ -551,7 +560,12 @@ mdoc_fl_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_cm_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_B, "c", "Cm");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_B, "cTi", "Cm", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -564,22 +578,19 @@ mdoc_nd_pre(MDOC_ARGS)
|
||||
/* XXX: this tag in theory can contain block elements. */
|
||||
|
||||
print_text(h, "\\(em");
|
||||
print_otag(h, TAG_SPAN, "c", "Nd");
|
||||
print_otag(h, TAG_SPAN, "cT", "Nd");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_nm_pre(MDOC_ARGS)
|
||||
{
|
||||
struct tag *t;
|
||||
int len;
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_HEAD:
|
||||
print_otag(h, TAG_TD, "");
|
||||
/* FALLTHROUGH */
|
||||
case ROFFT_ELEM:
|
||||
print_otag(h, TAG_B, "c", "Nm");
|
||||
print_otag(h, TAG_B, "cT", "Nm");
|
||||
return 1;
|
||||
case ROFFT_BODY:
|
||||
print_otag(h, TAG_TD, "");
|
||||
@ -587,21 +598,8 @@ mdoc_nm_pre(MDOC_ARGS)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
synopsis_pre(h, n);
|
||||
print_otag(h, TAG_TABLE, "c", "Nm");
|
||||
|
||||
for (len = 0, n = n->head->child; n; n = n->next)
|
||||
if (n->type == ROFFT_TEXT)
|
||||
len += html_strlen(n->string);
|
||||
|
||||
if (len == 0 && meta->name != NULL)
|
||||
len = html_strlen(meta->name);
|
||||
|
||||
t = print_otag(h, TAG_COLGROUP, "");
|
||||
print_otag(h, TAG_COL, "shw", len);
|
||||
print_otag(h, TAG_COL, "");
|
||||
print_tagq(h, t);
|
||||
print_otag(h, TAG_TR, "");
|
||||
return 1;
|
||||
}
|
||||
@ -613,11 +611,11 @@ mdoc_xr_pre(MDOC_ARGS)
|
||||
return 0;
|
||||
|
||||
if (h->base_man)
|
||||
print_otag(h, TAG_A, "chM", "Xr",
|
||||
print_otag(h, TAG_A, "cThM", "Xr",
|
||||
n->child->string, n->child->next == NULL ?
|
||||
NULL : n->child->next->string);
|
||||
else
|
||||
print_otag(h, TAG_A, "c", "Xr");
|
||||
print_otag(h, TAG_A, "cT", "Xr");
|
||||
|
||||
n = n->child;
|
||||
print_text(h, n->string);
|
||||
@ -646,7 +644,7 @@ mdoc_ns_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_ar_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_VAR, "c", "Ar");
|
||||
print_otag(h, TAG_VAR, "cT", "Ar");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -666,7 +664,7 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
enum mdoc_list type;
|
||||
|
||||
bl = n->parent;
|
||||
while (bl != NULL && bl->tok != MDOC_Bl)
|
||||
while (bl->tok != MDOC_Bl)
|
||||
bl = bl->parent;
|
||||
type = bl->norm->Bl.type;
|
||||
|
||||
@ -751,8 +749,9 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
case ROFFT_HEAD:
|
||||
if (h->style != NULL && !bl->norm->Bl.comp &&
|
||||
(n->parent->prev == NULL ||
|
||||
n->parent->prev->body == NULL ||
|
||||
n->parent->prev->body->child != NULL)) {
|
||||
t = print_otag(h, TAG_DT, "csWl",
|
||||
t = print_otag(h, TAG_DT, "csw+-l",
|
||||
cattr, bl->norm->Bl.width);
|
||||
print_text(h, "\\ ");
|
||||
print_tagq(h, t);
|
||||
@ -760,7 +759,7 @@ mdoc_it_pre(MDOC_ARGS)
|
||||
print_text(h, "\\ ");
|
||||
print_tagq(h, t);
|
||||
}
|
||||
print_otag(h, TAG_DT, "csWl", cattr,
|
||||
print_otag(h, TAG_DT, "csw+-l", cattr,
|
||||
bl->norm->Bl.width);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
@ -823,7 +822,7 @@ mdoc_bl_pre(MDOC_ARGS)
|
||||
|
||||
t = print_otag(h, TAG_COLGROUP, "");
|
||||
for (i = 0; i < bl->ncols - 1; i++)
|
||||
print_otag(h, TAG_COL, "sww", bl->cols[i]);
|
||||
print_otag(h, TAG_COL, "sw+w", bl->cols[i]);
|
||||
print_otag(h, TAG_COL, "swW", bl->cols[i]);
|
||||
print_tagq(h, t);
|
||||
return 0;
|
||||
@ -870,7 +869,7 @@ mdoc_bl_pre(MDOC_ARGS)
|
||||
cattr = "Bl-tag";
|
||||
if (bl->offs)
|
||||
print_otag(h, TAG_DIV, "cswl", cattr, bl->offs);
|
||||
print_otag(h, TAG_DL, "cswl", cattr, bl->width);
|
||||
print_otag(h, TAG_DL, "csw+l", cattr, bl->width);
|
||||
return 1;
|
||||
case LIST_column:
|
||||
elemtype = TAG_TABLE;
|
||||
@ -894,14 +893,14 @@ mdoc_ex_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_st_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_SPAN, "c", "St");
|
||||
print_otag(h, TAG_SPAN, "cT", "St");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_em_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_I, "c", "Em");
|
||||
print_otag(h, TAG_I, "cT", "Em");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -924,8 +923,8 @@ mdoc_sx_pre(MDOC_ARGS)
|
||||
{
|
||||
char *id;
|
||||
|
||||
id = make_id(n);
|
||||
print_otag(h, TAG_A, "chR", "Sx", id);
|
||||
id = html_make_id(n);
|
||||
print_otag(h, TAG_A, "cThR", "Sx", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
@ -991,9 +990,9 @@ mdoc_bd_pre(MDOC_ARGS)
|
||||
* anyway, so don't sweat it.
|
||||
*/
|
||||
switch (nn->tok) {
|
||||
case ROFF_br:
|
||||
case ROFF_sp:
|
||||
case MDOC_Sm:
|
||||
case MDOC_br:
|
||||
case MDOC_sp:
|
||||
case MDOC_Bl:
|
||||
case MDOC_D1:
|
||||
case MDOC_Dl:
|
||||
@ -1021,7 +1020,7 @@ mdoc_bd_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_pa_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_I, "c", "Pa");
|
||||
print_otag(h, TAG_I, "cT", "Pa");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1052,7 +1051,7 @@ mdoc_an_pre(MDOC_ARGS)
|
||||
if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT))
|
||||
h->flags |= HTML_SPLIT;
|
||||
|
||||
print_otag(h, TAG_SPAN, "c", "An");
|
||||
print_otag(h, TAG_SPAN, "cT", "An");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1060,28 +1059,49 @@ static int
|
||||
mdoc_cd_pre(MDOC_ARGS)
|
||||
{
|
||||
synopsis_pre(h, n);
|
||||
print_otag(h, TAG_B, "c", "Cd");
|
||||
print_otag(h, TAG_B, "cT", "Cd");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_dv_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_CODE, "c", "Dv");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_CODE, "cTi", "Dv", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_ev_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_CODE, "c", "Ev");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_CODE, "cTi", "Ev", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_er_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_CODE, "c", "Er");
|
||||
char *id;
|
||||
|
||||
id = n->sec == SEC_ERRORS &&
|
||||
(n->parent->tok == MDOC_It ||
|
||||
(n->parent->tok == MDOC_Bq &&
|
||||
n->parent->parent->parent->tok == MDOC_It)) ?
|
||||
html_make_id(n) : NULL;
|
||||
|
||||
if (id != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_CODE, "cTi", "Er", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1092,12 +1112,12 @@ mdoc_fa_pre(MDOC_ARGS)
|
||||
struct tag *t;
|
||||
|
||||
if (n->parent->tok != MDOC_Fo) {
|
||||
print_otag(h, TAG_VAR, "c", "Fa");
|
||||
print_otag(h, TAG_VAR, "cT", "Fa");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
t = print_otag(h, TAG_VAR, "c", "Fa");
|
||||
t = print_otag(h, TAG_VAR, "cT", "Fa");
|
||||
print_text(h, nn->string);
|
||||
print_tagq(h, t);
|
||||
if (nn->next) {
|
||||
@ -1128,11 +1148,11 @@ mdoc_fd_pre(MDOC_ARGS)
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
|
||||
if (strcmp(n->string, "#include")) {
|
||||
print_otag(h, TAG_B, "c", "Fd");
|
||||
print_otag(h, TAG_B, "cT", "Fd");
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_otag(h, TAG_B, "c", "In");
|
||||
print_otag(h, TAG_B, "cT", "In");
|
||||
print_text(h, n->string);
|
||||
|
||||
if (NULL != (n = n->next)) {
|
||||
@ -1146,10 +1166,10 @@ mdoc_fd_pre(MDOC_ARGS)
|
||||
cp = strchr(buf, '\0') - 1;
|
||||
if (cp >= buf && (*cp == '>' || *cp == '"'))
|
||||
*cp = '\0';
|
||||
t = print_otag(h, TAG_A, "chI", "In", buf);
|
||||
t = print_otag(h, TAG_A, "cThI", "In", buf);
|
||||
free(buf);
|
||||
} else
|
||||
t = print_otag(h, TAG_A, "c", "In");
|
||||
t = print_otag(h, TAG_A, "cT", "In");
|
||||
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
@ -1176,7 +1196,7 @@ mdoc_vt_pre(MDOC_ARGS)
|
||||
} else if (n->type == ROFFT_HEAD)
|
||||
return 0;
|
||||
|
||||
print_otag(h, TAG_VAR, "c", "Vt");
|
||||
print_otag(h, TAG_VAR, "cT", "Vt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1184,7 +1204,7 @@ static int
|
||||
mdoc_ft_pre(MDOC_ARGS)
|
||||
{
|
||||
synopsis_pre(h, n);
|
||||
print_otag(h, TAG_VAR, "c", "Ft");
|
||||
print_otag(h, TAG_VAR, "cT", "Ft");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1205,7 +1225,7 @@ mdoc_fn_pre(MDOC_ARGS)
|
||||
|
||||
ep = strchr(sp, ' ');
|
||||
if (NULL != ep) {
|
||||
t = print_otag(h, TAG_VAR, "c", "Ft");
|
||||
t = print_otag(h, TAG_VAR, "cT", "Ft");
|
||||
|
||||
while (ep) {
|
||||
sz = MIN((int)(ep - sp), BUFSIZ - 1);
|
||||
@ -1218,7 +1238,7 @@ mdoc_fn_pre(MDOC_ARGS)
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
t = print_otag(h, TAG_B, "c", "Fn");
|
||||
t = print_otag(h, TAG_B, "cT", "Fn");
|
||||
|
||||
if (sp)
|
||||
print_text(h, sp);
|
||||
@ -1231,10 +1251,10 @@ mdoc_fn_pre(MDOC_ARGS)
|
||||
|
||||
for (n = n->child->next; n; n = n->next) {
|
||||
if (NODE_SYNPRETTY & n->flags)
|
||||
t = print_otag(h, TAG_VAR, "css?", "Fa",
|
||||
t = print_otag(h, TAG_VAR, "cTss?", "Fa",
|
||||
"white-space", "nowrap");
|
||||
else
|
||||
t = print_otag(h, TAG_VAR, "c", "Fa");
|
||||
t = print_otag(h, TAG_VAR, "cT", "Fa");
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
if (n->next) {
|
||||
@ -1286,48 +1306,36 @@ mdoc_pp_pre(MDOC_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_sp_pre(MDOC_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
|
||||
SCALE_VS_INIT(&su, 1);
|
||||
|
||||
if (MDOC_sp == n->tok) {
|
||||
if (NULL != (n = n->child)) {
|
||||
if ( ! a2roffsu(n->string, &su, SCALE_VS))
|
||||
su.scale = 1.0;
|
||||
else if (su.scale < 0.0)
|
||||
su.scale = 0.0;
|
||||
}
|
||||
} else
|
||||
su.scale = 0.0;
|
||||
|
||||
print_otag(h, TAG_DIV, "suh", &su);
|
||||
|
||||
/* So the div isn't empty: */
|
||||
print_text(h, "\\~");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_lk_pre(MDOC_ARGS)
|
||||
{
|
||||
if (NULL == (n = n->child))
|
||||
const struct roff_node *link, *descr, *punct;
|
||||
struct tag *t;
|
||||
|
||||
if ((link = n->child) == NULL)
|
||||
return 0;
|
||||
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
/* Find beginning of trailing punctuation. */
|
||||
punct = n->last;
|
||||
while (punct != link && punct->flags & NODE_DELIMC)
|
||||
punct = punct->prev;
|
||||
punct = punct->next;
|
||||
|
||||
print_otag(h, TAG_A, "ch", "Lk", n->string);
|
||||
|
||||
if (NULL == n->next)
|
||||
print_text(h, n->string);
|
||||
|
||||
for (n = n->next; n; n = n->next)
|
||||
print_text(h, n->string);
|
||||
/* Link target and link text. */
|
||||
t = print_otag(h, TAG_A, "cTh", "Lk", link->string);
|
||||
for (descr = link->next; descr != punct; descr = descr->next) {
|
||||
if (descr->flags & (NODE_DELIMC | NODE_DELIMO))
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, descr->string);
|
||||
}
|
||||
print_tagq(h, t);
|
||||
|
||||
/* Trailing punctuation. */
|
||||
while (punct != NULL) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
print_text(h, punct->string);
|
||||
punct = punct->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1341,7 +1349,7 @@ mdoc_mt_pre(MDOC_ARGS)
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
|
||||
mandoc_asprintf(&cp, "mailto:%s", n->string);
|
||||
t = print_otag(h, TAG_A, "ch", "Mt", cp);
|
||||
t = print_otag(h, TAG_A, "cTh", "Mt", cp);
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
free(cp);
|
||||
@ -1369,7 +1377,7 @@ mdoc_fo_pre(MDOC_ARGS)
|
||||
return 0;
|
||||
|
||||
assert(n->child->string);
|
||||
t = print_otag(h, TAG_B, "c", "Fn");
|
||||
t = print_otag(h, TAG_B, "cT", "Fn");
|
||||
print_text(h, n->child->string);
|
||||
print_tagq(h, t);
|
||||
return 0;
|
||||
@ -1393,7 +1401,7 @@ mdoc_in_pre(MDOC_ARGS)
|
||||
struct tag *t;
|
||||
|
||||
synopsis_pre(h, n);
|
||||
print_otag(h, TAG_B, "c", "In");
|
||||
print_otag(h, TAG_B, "cT", "In");
|
||||
|
||||
/*
|
||||
* The first argument of the `In' gets special treatment as
|
||||
@ -1412,9 +1420,9 @@ mdoc_in_pre(MDOC_ARGS)
|
||||
assert(n->type == ROFFT_TEXT);
|
||||
|
||||
if (h->base_includes)
|
||||
t = print_otag(h, TAG_A, "chI", "In", n->string);
|
||||
t = print_otag(h, TAG_A, "cThI", "In", n->string);
|
||||
else
|
||||
t = print_otag(h, TAG_A, "c", "In");
|
||||
t = print_otag(h, TAG_A, "cT", "In");
|
||||
print_text(h, n->string);
|
||||
print_tagq(h, t);
|
||||
|
||||
@ -1435,14 +1443,19 @@ mdoc_in_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_ic_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_B, "c", "Ic");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_B, "cTi", "Ic", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_va_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_VAR, "c", "Va");
|
||||
print_otag(h, TAG_VAR, "cT", "Va");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1487,7 +1500,12 @@ mdoc_bf_pre(MDOC_ARGS)
|
||||
static int
|
||||
mdoc_ms_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_B, "c", "Ms");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_B, "cTi", "Ms", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1516,28 +1534,38 @@ mdoc_rs_pre(MDOC_ARGS)
|
||||
if (n->prev && SEC_SEE_ALSO == n->sec)
|
||||
print_paragraph(h);
|
||||
|
||||
print_otag(h, TAG_CITE, "c", "Rs");
|
||||
print_otag(h, TAG_CITE, "cT", "Rs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_no_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_SPAN, "c", "No");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_SPAN, "ci", "No", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_li_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_CODE, "c", "Li");
|
||||
char *id;
|
||||
|
||||
if ((id = cond_id(n)) != NULL)
|
||||
print_otag(h, TAG_A, "chR", "selflink", id);
|
||||
print_otag(h, TAG_CODE, "ci", "Li", id);
|
||||
free(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_sy_pre(MDOC_ARGS)
|
||||
{
|
||||
print_otag(h, TAG_B, "c", "Sy");
|
||||
print_otag(h, TAG_B, "cT", "Sy");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1547,7 +1575,7 @@ mdoc_lb_pre(MDOC_ARGS)
|
||||
if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags && n->prev)
|
||||
print_otag(h, TAG_BR, "");
|
||||
|
||||
print_otag(h, TAG_SPAN, "c", "Lb");
|
||||
print_otag(h, TAG_SPAN, "cT", "Lb");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_macro.c,v 1.217 2017/02/16 09:47:31 schwarze Exp $ */
|
||||
/* $Id: mdoc_macro.c,v 1.224 2017/05/30 16:22:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -46,21 +46,21 @@ static void phrase_ta(MACRO_PROT_ARGS);
|
||||
static void append_delims(struct roff_man *, int, int *, char *);
|
||||
static void dword(struct roff_man *, int, int, const char *,
|
||||
enum mdelim, int);
|
||||
static int find_pending(struct roff_man *, int, int, int,
|
||||
struct roff_node *);
|
||||
static int find_pending(struct roff_man *, enum roff_tok,
|
||||
int, int, struct roff_node *);
|
||||
static int lookup(struct roff_man *, int, int, int, const char *);
|
||||
static int macro_or_word(MACRO_PROT_ARGS, int);
|
||||
static void break_intermediate(struct roff_node *,
|
||||
struct roff_node *);
|
||||
static int parse_rest(struct roff_man *, int, int, int *, char *);
|
||||
static int rew_alt(int);
|
||||
static void rew_elem(struct roff_man *, int);
|
||||
struct roff_node *);
|
||||
static int parse_rest(struct roff_man *, enum roff_tok,
|
||||
int, int *, char *);
|
||||
static enum roff_tok rew_alt(enum roff_tok);
|
||||
static void rew_elem(struct roff_man *, enum roff_tok);
|
||||
static void rew_last(struct roff_man *, const struct roff_node *);
|
||||
static void rew_pending(struct roff_man *,
|
||||
const struct roff_node *);
|
||||
|
||||
const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
||||
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ap */
|
||||
const struct mdoc_macro __mdoc_macros[MDOC_MAX - MDOC_Dd] = {
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Dd */
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Dt */
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* Os */
|
||||
@ -76,6 +76,8 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
||||
{ blk_full, MDOC_PARSED | MDOC_JOIN }, /* It */
|
||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
|
||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* An */
|
||||
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED |
|
||||
MDOC_IGNDELIM | MDOC_JOIN }, /* Ap */
|
||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
|
||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Cd */
|
||||
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
|
||||
@ -196,14 +198,10 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
|
||||
{ blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* En */
|
||||
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
|
||||
{ in_line_eoln, MDOC_JOIN }, /* %Q */
|
||||
{ in_line_eoln, 0 }, /* br */
|
||||
{ in_line_eoln, 0 }, /* sp */
|
||||
{ in_line_eoln, 0 }, /* %U */
|
||||
{ phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */
|
||||
{ in_line_eoln, MDOC_PROLOGUE }, /* ll */
|
||||
};
|
||||
|
||||
const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
|
||||
const struct mdoc_macro *const mdoc_macros = __mdoc_macros - MDOC_Dd;
|
||||
|
||||
|
||||
/*
|
||||
@ -225,7 +223,7 @@ mdoc_endparse(struct roff_man *mdoc)
|
||||
if (n->type == ROFFT_BLOCK &&
|
||||
mdoc_macros[n->tok].flags & MDOC_EXPLICIT)
|
||||
mandoc_msg(MANDOCERR_BLK_NOEND, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
|
||||
/* Rewind to the first. */
|
||||
|
||||
@ -240,20 +238,19 @@ mdoc_endparse(struct roff_man *mdoc)
|
||||
static int
|
||||
lookup(struct roff_man *mdoc, int from, int line, int ppos, const char *p)
|
||||
{
|
||||
int res;
|
||||
enum roff_tok res;
|
||||
|
||||
if (mdoc->flags & MDOC_PHRASEQF) {
|
||||
mdoc->flags &= ~MDOC_PHRASEQF;
|
||||
return TOKEN_NONE;
|
||||
}
|
||||
if (from == TOKEN_NONE || mdoc_macros[from].flags & MDOC_PARSED) {
|
||||
res = mdoc_hash_find(p);
|
||||
res = roffhash_find(mdoc->mdocmac, p, 0);
|
||||
if (res != TOKEN_NONE) {
|
||||
if (mdoc_macros[res].flags & MDOC_CALLABLE)
|
||||
return res;
|
||||
if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)
|
||||
mandoc_msg(MANDOCERR_MACRO_CALL,
|
||||
mdoc->parse, line, ppos, p);
|
||||
mandoc_msg(MANDOCERR_MACRO_CALL,
|
||||
mdoc->parse, line, ppos, p);
|
||||
}
|
||||
}
|
||||
return TOKEN_NONE;
|
||||
@ -324,8 +321,8 @@ rew_pending(struct roff_man *mdoc, const struct roff_node *n)
|
||||
* For a block closing macro, return the corresponding opening one.
|
||||
* Otherwise, return the macro itself.
|
||||
*/
|
||||
static int
|
||||
rew_alt(int tok)
|
||||
static enum roff_tok
|
||||
rew_alt(enum roff_tok tok)
|
||||
{
|
||||
switch (tok) {
|
||||
case MDOC_Ac:
|
||||
@ -366,7 +363,7 @@ rew_alt(int tok)
|
||||
}
|
||||
|
||||
static void
|
||||
rew_elem(struct roff_man *mdoc, int tok)
|
||||
rew_elem(struct roff_man *mdoc, enum roff_tok tok)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
@ -398,7 +395,7 @@ break_intermediate(struct roff_node *n, struct roff_node *breaker)
|
||||
* the rew_pending() call closing out the sub-block.
|
||||
*/
|
||||
static int
|
||||
find_pending(struct roff_man *mdoc, int tok, int line, int ppos,
|
||||
find_pending(struct roff_man *mdoc, enum roff_tok tok, int line, int ppos,
|
||||
struct roff_node *target)
|
||||
{
|
||||
struct roff_node *n;
|
||||
@ -420,8 +417,8 @@ find_pending(struct roff_man *mdoc, int tok, int line, int ppos,
|
||||
else if ( ! (target->flags & NODE_ENDED)) {
|
||||
mandoc_vmsg(MANDOCERR_BLK_NEST,
|
||||
mdoc->parse, line, ppos,
|
||||
"%s breaks %s", mdoc_macronames[tok],
|
||||
mdoc_macronames[n->tok]);
|
||||
"%s breaks %s", roff_name[tok],
|
||||
roff_name[n->tok]);
|
||||
mdoc_endbody_alloc(mdoc, line, ppos,
|
||||
tok, target);
|
||||
}
|
||||
@ -524,7 +521,8 @@ macro_or_word(MACRO_PROT_ARGS, int parsed)
|
||||
mdoc_macros[tok].flags & MDOC_JOIN);
|
||||
return 0;
|
||||
} else {
|
||||
if (mdoc_macros[tok].fp == in_line_eoln)
|
||||
if (tok != TOKEN_NONE &&
|
||||
mdoc_macros[tok].fp == in_line_eoln)
|
||||
rew_elem(mdoc, tok);
|
||||
mdoc_macro(mdoc, ntok, line, ppos, pos, buf);
|
||||
if (tok == TOKEN_NONE)
|
||||
@ -548,7 +546,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
|
||||
int j, lastarg, maxargs, nl, pending;
|
||||
enum margserr ac;
|
||||
int atok, ntok;
|
||||
enum roff_tok atok, ntok;
|
||||
char *p;
|
||||
|
||||
nl = MDOC_NEWLINE & mdoc->flags;
|
||||
@ -633,8 +631,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
|
||||
mandoc_vmsg(MANDOCERR_BLK_NEST, mdoc->parse,
|
||||
line, ppos, "%s breaks %s",
|
||||
mdoc_macronames[atok],
|
||||
mdoc_macronames[later->tok]);
|
||||
roff_name[atok], roff_name[later->tok]);
|
||||
|
||||
endbody = mdoc_endbody_alloc(mdoc, line, ppos,
|
||||
atok, body);
|
||||
@ -676,14 +673,14 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
|
||||
if (body == NULL) {
|
||||
mandoc_msg(MANDOCERR_BLK_NOTOPEN, mdoc->parse,
|
||||
line, ppos, mdoc_macronames[tok]);
|
||||
line, ppos, roff_name[tok]);
|
||||
if (maxargs && endbody == NULL) {
|
||||
/*
|
||||
* Stray .Ec without previous .Eo:
|
||||
* Break the output line, keep the arguments.
|
||||
*/
|
||||
roff_elem_alloc(mdoc, line, ppos, MDOC_br);
|
||||
rew_elem(mdoc, MDOC_br);
|
||||
roff_elem_alloc(mdoc, line, ppos, ROFF_br);
|
||||
rew_elem(mdoc, ROFF_br);
|
||||
}
|
||||
} else if (endbody == NULL) {
|
||||
rew_last(mdoc, body);
|
||||
@ -695,7 +692,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
if (buf[*pos] != '\0')
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
mdoc->parse, line, ppos,
|
||||
"%s %s", mdoc_macronames[tok],
|
||||
"%s %s", roff_name[tok],
|
||||
buf + *pos);
|
||||
if (endbody == NULL && n != NULL)
|
||||
rew_pending(mdoc, n);
|
||||
@ -716,8 +713,7 @@ blk_exp_close(MACRO_PROT_ARGS)
|
||||
if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
|
||||
break;
|
||||
|
||||
ntok = ac == ARGS_QWORD ? TOKEN_NONE :
|
||||
lookup(mdoc, tok, line, lastarg, p);
|
||||
ntok = lookup(mdoc, tok, line, lastarg, p);
|
||||
|
||||
if (ntok == TOKEN_NONE) {
|
||||
dword(mdoc, line, lastarg, p, DELIM_MAX,
|
||||
@ -752,7 +748,7 @@ static void
|
||||
in_line(MACRO_PROT_ARGS)
|
||||
{
|
||||
int la, scope, cnt, firstarg, mayopen, nc, nl;
|
||||
int ntok;
|
||||
enum roff_tok ntok;
|
||||
enum margserr ac;
|
||||
enum mdelim d;
|
||||
struct mdoc_arg *arg;
|
||||
@ -813,7 +809,7 @@ in_line(MACRO_PROT_ARGS)
|
||||
break;
|
||||
}
|
||||
|
||||
ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ?
|
||||
ntok = (tok == MDOC_Fn && !cnt) ?
|
||||
TOKEN_NONE : lookup(mdoc, tok, line, la, p);
|
||||
|
||||
/*
|
||||
@ -833,7 +829,7 @@ in_line(MACRO_PROT_ARGS)
|
||||
mdoc_argv_free(arg);
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY,
|
||||
mdoc->parse, line, ppos,
|
||||
mdoc_macronames[tok]);
|
||||
roff_name[tok]);
|
||||
}
|
||||
mdoc_macro(mdoc, ntok, line, la, pos, buf);
|
||||
if (nl)
|
||||
@ -842,14 +838,11 @@ in_line(MACRO_PROT_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-quote-enclosed punctuation. Set up our scope, if
|
||||
* a word; rewind the scope, if a delimiter; then append
|
||||
* the word.
|
||||
* Handle punctuation. Set up our scope, if a word;
|
||||
* rewind the scope, if a delimiter; then append the word.
|
||||
*/
|
||||
|
||||
d = ac == ARGS_QWORD ? DELIM_NONE : mdoc_isdelim(p);
|
||||
|
||||
if (DELIM_NONE != d) {
|
||||
if ((d = mdoc_isdelim(p)) != DELIM_NONE) {
|
||||
/*
|
||||
* If we encounter closing punctuation, no word
|
||||
* has been emitted, no scope is open, and we're
|
||||
@ -869,11 +862,12 @@ in_line(MACRO_PROT_ARGS)
|
||||
* Close out our scope, if one is open, before
|
||||
* any punctuation.
|
||||
*/
|
||||
if (scope)
|
||||
if (scope && tok != MDOC_Lk) {
|
||||
rew_elem(mdoc, tok);
|
||||
scope = 0;
|
||||
if (tok == MDOC_Fn)
|
||||
mayopen = 0;
|
||||
scope = 0;
|
||||
if (tok == MDOC_Fn)
|
||||
mayopen = 0;
|
||||
}
|
||||
} else if (mayopen && !scope) {
|
||||
mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
|
||||
scope = 1;
|
||||
@ -881,7 +875,7 @@ in_line(MACRO_PROT_ARGS)
|
||||
}
|
||||
|
||||
dword(mdoc, line, la, p, d,
|
||||
MDOC_JOIN & mdoc_macros[tok].flags);
|
||||
mdoc_macros[tok].flags & MDOC_JOIN);
|
||||
|
||||
/*
|
||||
* If the first argument is a closing delimiter,
|
||||
@ -903,8 +897,10 @@ in_line(MACRO_PROT_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
if (scope)
|
||||
if (scope && tok != MDOC_Lk) {
|
||||
rew_elem(mdoc, tok);
|
||||
scope = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no elements have been collected and we're allowed to have
|
||||
@ -919,11 +915,13 @@ in_line(MACRO_PROT_ARGS)
|
||||
} else {
|
||||
mdoc_argv_free(arg);
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
|
||||
line, ppos, mdoc_macronames[tok]);
|
||||
line, ppos, roff_name[tok]);
|
||||
}
|
||||
}
|
||||
if (nl)
|
||||
append_delims(mdoc, line, pos, buf);
|
||||
if (scope)
|
||||
rew_elem(mdoc, tok);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -942,7 +940,7 @@ blk_full(MACRO_PROT_ARGS)
|
||||
|
||||
if (buf[*pos] == '\0' && (tok == MDOC_Sh || tok == MDOC_Ss)) {
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
|
||||
line, ppos, mdoc_macronames[tok]);
|
||||
line, ppos, roff_name[tok]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -965,7 +963,7 @@ blk_full(MACRO_PROT_ARGS)
|
||||
mandoc_vmsg(MANDOCERR_BLK_BROKEN,
|
||||
mdoc->parse, line, ppos,
|
||||
"It breaks %s",
|
||||
mdoc_macronames[blk->tok]);
|
||||
roff_name[blk->tok]);
|
||||
rew_pending(mdoc, blk);
|
||||
}
|
||||
break;
|
||||
@ -977,9 +975,8 @@ blk_full(MACRO_PROT_ARGS)
|
||||
case MDOC_Ss:
|
||||
mandoc_vmsg(MANDOCERR_BLK_BROKEN,
|
||||
mdoc->parse, line, ppos,
|
||||
"%s breaks %s",
|
||||
mdoc_macronames[tok],
|
||||
mdoc_macronames[n->tok]);
|
||||
"%s breaks %s", roff_name[tok],
|
||||
roff_name[n->tok]);
|
||||
rew_pending(mdoc, n);
|
||||
n = mdoc->last;
|
||||
continue;
|
||||
@ -1005,8 +1002,7 @@ blk_full(MACRO_PROT_ARGS)
|
||||
if (blk != NULL) {
|
||||
mandoc_vmsg(MANDOCERR_BLK_BROKEN,
|
||||
mdoc->parse, line, ppos,
|
||||
"It breaks %s",
|
||||
mdoc_macronames[blk->tok]);
|
||||
"It breaks %s", roff_name[blk->tok]);
|
||||
rew_pending(mdoc, blk);
|
||||
blk = NULL;
|
||||
}
|
||||
@ -1021,8 +1017,8 @@ blk_full(MACRO_PROT_ARGS)
|
||||
if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {
|
||||
mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,
|
||||
line, ppos, "It %s", buf + *pos);
|
||||
roff_elem_alloc(mdoc, line, ppos, MDOC_br);
|
||||
rew_elem(mdoc, MDOC_br);
|
||||
roff_elem_alloc(mdoc, line, ppos, ROFF_br);
|
||||
rew_elem(mdoc, ROFF_br);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1099,7 +1095,7 @@ blk_full(MACRO_PROT_ARGS)
|
||||
if (tok == MDOC_Bd || tok == MDOC_Bk) {
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS,
|
||||
mdoc->parse, line, la, "%s ... %s",
|
||||
mdoc_macronames[tok], buf + la);
|
||||
roff_name[tok], buf + la);
|
||||
break;
|
||||
}
|
||||
if (tok == MDOC_Rs) {
|
||||
@ -1117,7 +1113,6 @@ blk_full(MACRO_PROT_ARGS)
|
||||
|
||||
if (head == NULL &&
|
||||
ac != ARGS_PHRASE &&
|
||||
ac != ARGS_QWORD &&
|
||||
mdoc_isdelim(p) == DELIM_OPEN) {
|
||||
dword(mdoc, line, la, p, DELIM_OPEN, 0);
|
||||
continue;
|
||||
@ -1214,8 +1209,7 @@ blk_part_imp(MACRO_PROT_ARGS)
|
||||
if (ac == ARGS_EOLN || ac == ARGS_PUNCT)
|
||||
break;
|
||||
|
||||
if (body == NULL && ac != ARGS_QWORD &&
|
||||
mdoc_isdelim(p) == DELIM_OPEN) {
|
||||
if (body == NULL && mdoc_isdelim(p) == DELIM_OPEN) {
|
||||
dword(mdoc, line, la, p, DELIM_OPEN, 0);
|
||||
continue;
|
||||
}
|
||||
@ -1271,8 +1265,7 @@ blk_part_exp(MACRO_PROT_ARGS)
|
||||
|
||||
/* Flush out leading punctuation. */
|
||||
|
||||
if (head == NULL && ac != ARGS_QWORD &&
|
||||
mdoc_isdelim(p) == DELIM_OPEN) {
|
||||
if (head == NULL && mdoc_isdelim(p) == DELIM_OPEN) {
|
||||
dword(mdoc, line, la, p, DELIM_OPEN, 0);
|
||||
continue;
|
||||
}
|
||||
@ -1307,7 +1300,7 @@ in_line_argn(MACRO_PROT_ARGS)
|
||||
struct mdoc_arg *arg;
|
||||
char *p;
|
||||
enum margserr ac;
|
||||
int ntok;
|
||||
enum roff_tok ntok;
|
||||
int state; /* arg#; -1: not yet open; -2: closed */
|
||||
int la, maxargs, nl;
|
||||
|
||||
@ -1371,7 +1364,7 @@ in_line_argn(MACRO_PROT_ARGS)
|
||||
state = -2;
|
||||
}
|
||||
|
||||
ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && state == 0)) ?
|
||||
ntok = (tok == MDOC_Pf && state == 0) ?
|
||||
TOKEN_NONE : lookup(mdoc, tok, line, la, p);
|
||||
|
||||
if (ntok != TOKEN_NONE) {
|
||||
@ -1383,8 +1376,7 @@ in_line_argn(MACRO_PROT_ARGS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ac == ARGS_QWORD ||
|
||||
mdoc_macros[tok].flags & MDOC_IGNDELIM ||
|
||||
if (mdoc_macros[tok].flags & MDOC_IGNDELIM ||
|
||||
mdoc_isdelim(p) == DELIM_NONE) {
|
||||
if (state == -1) {
|
||||
mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
|
||||
@ -1397,12 +1389,12 @@ in_line_argn(MACRO_PROT_ARGS)
|
||||
}
|
||||
|
||||
dword(mdoc, line, la, p, DELIM_MAX,
|
||||
MDOC_JOIN & mdoc_macros[tok].flags);
|
||||
mdoc_macros[tok].flags & MDOC_JOIN);
|
||||
}
|
||||
|
||||
if (state == -1) {
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
|
||||
line, ppos, mdoc_macronames[tok]);
|
||||
line, ppos, roff_name[tok]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1430,9 +1422,9 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
}
|
||||
|
||||
if (buf[*pos] == '\0' &&
|
||||
(tok == MDOC_Fd || mdoc_macronames[tok][0] == '%')) {
|
||||
(tok == MDOC_Fd || *roff_name[tok] == '%')) {
|
||||
mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse,
|
||||
line, ppos, mdoc_macronames[tok]);
|
||||
line, ppos, roff_name[tok]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1449,7 +1441,8 @@ in_line_eoln(MACRO_PROT_ARGS)
|
||||
* or until the next macro, call that macro, and return 1.
|
||||
*/
|
||||
static int
|
||||
parse_rest(struct roff_man *mdoc, int tok, int line, int *pos, char *buf)
|
||||
parse_rest(struct roff_man *mdoc, enum roff_tok tok,
|
||||
int line, int *pos, char *buf)
|
||||
{
|
||||
int la;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_man.c,v 1.104 2017/02/17 19:15:41 schwarze Exp $ */
|
||||
/* $Id: mdoc_man.c,v 1.119 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
@ -32,10 +33,13 @@
|
||||
|
||||
#define DECL_ARGS const struct roff_meta *meta, struct roff_node *n
|
||||
|
||||
typedef int (*int_fp)(DECL_ARGS);
|
||||
typedef void (*void_fp)(DECL_ARGS);
|
||||
|
||||
struct manact {
|
||||
int (*cond)(DECL_ARGS); /* DON'T run actions */
|
||||
int (*pre)(DECL_ARGS); /* pre-node action */
|
||||
void (*post)(DECL_ARGS); /* post-node action */
|
||||
int_fp cond; /* DON'T run actions */
|
||||
int_fp pre; /* pre-node action */
|
||||
void_fp post; /* post-node action */
|
||||
const char *prefix; /* pre-node string constant */
|
||||
const char *suffix; /* post-node string constant */
|
||||
};
|
||||
@ -44,6 +48,7 @@ static int cond_body(DECL_ARGS);
|
||||
static int cond_head(DECL_ARGS);
|
||||
static void font_push(char);
|
||||
static void font_pop(void);
|
||||
static int man_strlen(const char *);
|
||||
static void mid_it(void);
|
||||
static void post__t(DECL_ARGS);
|
||||
static void post_aq(DECL_ARGS);
|
||||
@ -68,7 +73,6 @@ static void post_nm(DECL_ARGS);
|
||||
static void post_percent(DECL_ARGS);
|
||||
static void post_pf(DECL_ARGS);
|
||||
static void post_sect(DECL_ARGS);
|
||||
static void post_sp(DECL_ARGS);
|
||||
static void post_vt(DECL_ARGS);
|
||||
static int pre__t(DECL_ARGS);
|
||||
static int pre_an(DECL_ARGS);
|
||||
@ -78,7 +82,7 @@ static int pre_bd(DECL_ARGS);
|
||||
static int pre_bf(DECL_ARGS);
|
||||
static int pre_bk(DECL_ARGS);
|
||||
static int pre_bl(DECL_ARGS);
|
||||
static int pre_br(DECL_ARGS);
|
||||
static void pre_br(DECL_ARGS);
|
||||
static int pre_dl(DECL_ARGS);
|
||||
static int pre_en(DECL_ARGS);
|
||||
static int pre_enc(DECL_ARGS);
|
||||
@ -91,22 +95,24 @@ static int pre_fd(DECL_ARGS);
|
||||
static int pre_fl(DECL_ARGS);
|
||||
static int pre_fn(DECL_ARGS);
|
||||
static int pre_fo(DECL_ARGS);
|
||||
static int pre_ft(DECL_ARGS);
|
||||
static void pre_ft(DECL_ARGS);
|
||||
static int pre_Ft(DECL_ARGS);
|
||||
static int pre_in(DECL_ARGS);
|
||||
static int pre_it(DECL_ARGS);
|
||||
static int pre_lk(DECL_ARGS);
|
||||
static int pre_li(DECL_ARGS);
|
||||
static int pre_ll(DECL_ARGS);
|
||||
static int pre_nm(DECL_ARGS);
|
||||
static int pre_no(DECL_ARGS);
|
||||
static int pre_ns(DECL_ARGS);
|
||||
static void pre_onearg(DECL_ARGS);
|
||||
static int pre_pp(DECL_ARGS);
|
||||
static int pre_rs(DECL_ARGS);
|
||||
static int pre_sm(DECL_ARGS);
|
||||
static int pre_sp(DECL_ARGS);
|
||||
static void pre_sp(DECL_ARGS);
|
||||
static int pre_sect(DECL_ARGS);
|
||||
static int pre_sy(DECL_ARGS);
|
||||
static void pre_syn(const struct roff_node *);
|
||||
static void pre_ta(DECL_ARGS);
|
||||
static int pre_vt(DECL_ARGS);
|
||||
static int pre_xr(DECL_ARGS);
|
||||
static void print_word(const char *);
|
||||
@ -118,8 +124,18 @@ static void print_width(const struct mdoc_bl *,
|
||||
static void print_count(int *);
|
||||
static void print_node(DECL_ARGS);
|
||||
|
||||
static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
|
||||
static const void_fp roff_manacts[ROFF_MAX] = {
|
||||
pre_br,
|
||||
pre_onearg,
|
||||
pre_ft,
|
||||
pre_onearg,
|
||||
pre_onearg,
|
||||
pre_sp,
|
||||
pre_ta,
|
||||
pre_onearg,
|
||||
};
|
||||
|
||||
static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dd */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dt */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Os */
|
||||
@ -135,6 +151,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, pre_it, post_it, NULL, NULL }, /* It */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Ad */
|
||||
{ NULL, pre_an, NULL, NULL, NULL }, /* An */
|
||||
{ NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Ar */
|
||||
{ NULL, pre_sy, post_font, NULL, NULL }, /* Cd */
|
||||
{ NULL, pre_sy, post_font, NULL, NULL }, /* Cm */
|
||||
@ -146,14 +163,14 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */
|
||||
{ NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */
|
||||
{ NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */
|
||||
{ NULL, pre_ft, post_font, NULL, NULL }, /* Ft */
|
||||
{ NULL, pre_Ft, post_font, NULL, NULL }, /* Ft */
|
||||
{ NULL, pre_sy, post_font, NULL, NULL }, /* Ic */
|
||||
{ NULL, pre_in, post_in, NULL, NULL }, /* In */
|
||||
{ NULL, pre_li, post_font, NULL, NULL }, /* Li */
|
||||
{ cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
|
||||
{ NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
|
||||
{ cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
|
||||
{ NULL, pre_ft, post_font, NULL, NULL }, /* Ot */
|
||||
{ NULL, pre_Ft, post_font, NULL, NULL }, /* Ot */
|
||||
{ NULL, pre_em, post_font, NULL, NULL }, /* Pa */
|
||||
{ NULL, pre_ex, NULL, NULL, NULL }, /* Rv */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* St */
|
||||
@ -237,13 +254,10 @@ static const struct manact manacts[MDOC_MAX + 1] = {
|
||||
{ cond_body, pre_en, post_en, NULL, NULL }, /* En */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Dx */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
|
||||
{ NULL, pre_br, NULL, NULL, NULL }, /* br */
|
||||
{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
|
||||
{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
|
||||
{ NULL, pre_ll, post_sp, NULL, NULL }, /* ll */
|
||||
{ NULL, NULL, NULL, NULL, NULL }, /* ROOT */
|
||||
};
|
||||
static const struct manact *const manacts = __manacts - MDOC_Dd;
|
||||
|
||||
static int outflags;
|
||||
#define MMAN_spc (1 << 0) /* blank character before next word */
|
||||
@ -274,6 +288,49 @@ static struct {
|
||||
} fontqueue;
|
||||
|
||||
|
||||
static int
|
||||
man_strlen(const char *cp)
|
||||
{
|
||||
size_t rsz;
|
||||
int skip, sz;
|
||||
|
||||
sz = 0;
|
||||
skip = 0;
|
||||
for (;;) {
|
||||
rsz = strcspn(cp, "\\");
|
||||
if (rsz) {
|
||||
cp += rsz;
|
||||
if (skip) {
|
||||
skip = 0;
|
||||
rsz--;
|
||||
}
|
||||
sz += rsz;
|
||||
}
|
||||
if ('\0' == *cp)
|
||||
break;
|
||||
cp++;
|
||||
switch (mandoc_escape(&cp, NULL, NULL)) {
|
||||
case ESCAPE_ERROR:
|
||||
return sz;
|
||||
case ESCAPE_UNICODE:
|
||||
case ESCAPE_NUMBERED:
|
||||
case ESCAPE_SPECIAL:
|
||||
case ESCAPE_OVERSTRIKE:
|
||||
if (skip)
|
||||
skip = 0;
|
||||
else
|
||||
sz++;
|
||||
break;
|
||||
case ESCAPE_SKIPCHAR:
|
||||
skip = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void
|
||||
font_push(char newfont)
|
||||
{
|
||||
@ -391,7 +448,6 @@ static void
|
||||
print_line(const char *s, int newflags)
|
||||
{
|
||||
|
||||
outflags &= ~MMAN_br;
|
||||
outflags |= MMAN_nl;
|
||||
print_word(s);
|
||||
outflags |= newflags;
|
||||
@ -420,6 +476,7 @@ print_offs(const char *v, int keywords)
|
||||
{
|
||||
char buf[24];
|
||||
struct roffsu su;
|
||||
const char *end;
|
||||
int sz;
|
||||
|
||||
print_line(".RS", MMAN_Bk_susp);
|
||||
@ -431,8 +488,11 @@ print_offs(const char *v, int keywords)
|
||||
sz = 6;
|
||||
else if (keywords && !strcmp(v, "indent-two"))
|
||||
sz = 12;
|
||||
else if (a2roffsu(v, &su, SCALE_EN) > 1) {
|
||||
if (SCALE_EN == su.unit)
|
||||
else {
|
||||
end = a2roffsu(v, &su, SCALE_EN);
|
||||
if (end == NULL || *end != '\0')
|
||||
sz = man_strlen(v);
|
||||
else if (SCALE_EN == su.unit)
|
||||
sz = su.scale;
|
||||
else {
|
||||
/*
|
||||
@ -446,8 +506,7 @@ print_offs(const char *v, int keywords)
|
||||
outflags |= MMAN_nl;
|
||||
return;
|
||||
}
|
||||
} else
|
||||
sz = strlen(v);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are inside an enclosing list.
|
||||
@ -469,6 +528,7 @@ print_width(const struct mdoc_bl *bl, const struct roff_node *child)
|
||||
{
|
||||
char buf[24];
|
||||
struct roffsu su;
|
||||
const char *end;
|
||||
int numeric, remain, sz, chsz;
|
||||
|
||||
numeric = 1;
|
||||
@ -477,21 +537,23 @@ print_width(const struct mdoc_bl *bl, const struct roff_node *child)
|
||||
/* Convert the width into a number (of characters). */
|
||||
if (bl->width == NULL)
|
||||
sz = (bl->type == LIST_hang) ? 6 : 0;
|
||||
else if (a2roffsu(bl->width, &su, SCALE_MAX) > 1) {
|
||||
if (SCALE_EN == su.unit)
|
||||
else {
|
||||
end = a2roffsu(bl->width, &su, SCALE_MAX);
|
||||
if (end == NULL || *end != '\0')
|
||||
sz = man_strlen(bl->width);
|
||||
else if (SCALE_EN == su.unit)
|
||||
sz = su.scale;
|
||||
else {
|
||||
sz = 0;
|
||||
numeric = 0;
|
||||
}
|
||||
} else
|
||||
sz = strlen(bl->width);
|
||||
}
|
||||
|
||||
/* XXX Rough estimation, might have multiple parts. */
|
||||
if (bl->type == LIST_enum)
|
||||
chsz = (bl->count > 8) + 1;
|
||||
else if (child != NULL && child->type == ROFFT_TEXT)
|
||||
chsz = strlen(child->string);
|
||||
chsz = man_strlen(child->string);
|
||||
else
|
||||
chsz = 0;
|
||||
|
||||
@ -607,7 +669,11 @@ print_node(DECL_ARGS)
|
||||
outflags &= ~(MMAN_spc | MMAN_spc_force);
|
||||
else if (outflags & MMAN_Sm)
|
||||
outflags |= MMAN_spc;
|
||||
} else if (n->tok < ROFF_MAX) {
|
||||
(*roff_manacts[n->tok])(meta, n);
|
||||
return;
|
||||
} else {
|
||||
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
|
||||
/*
|
||||
* Conditionally run the pre-node action handler for a
|
||||
* node.
|
||||
@ -715,8 +781,7 @@ static int
|
||||
pre__t(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
n->parent->norm->Rs.quote_T) {
|
||||
if (n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) {
|
||||
print_word("\\(lq");
|
||||
outflags &= ~MMAN_spc;
|
||||
} else
|
||||
@ -728,8 +793,7 @@ static void
|
||||
post__t(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->parent && MDOC_Rs == n->parent->tok &&
|
||||
n->parent->norm->Rs.quote_T) {
|
||||
if (n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) {
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word("\\(rq");
|
||||
} else
|
||||
@ -1013,12 +1077,10 @@ post_bl(DECL_ARGS)
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
pre_br(DECL_ARGS)
|
||||
{
|
||||
|
||||
outflags |= MMAN_br;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1263,7 +1325,7 @@ post_fo(DECL_ARGS)
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ft(DECL_ARGS)
|
||||
pre_Ft(DECL_ARGS)
|
||||
{
|
||||
|
||||
pre_syn(n);
|
||||
@ -1271,6 +1333,14 @@ pre_ft(DECL_ARGS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pre_ft(DECL_ARGS)
|
||||
{
|
||||
print_line(".ft", 0);
|
||||
print_word(n->child->string);
|
||||
outflags |= MMAN_nl;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_in(DECL_ARGS)
|
||||
{
|
||||
@ -1465,33 +1535,63 @@ post_lb(DECL_ARGS)
|
||||
static int
|
||||
pre_lk(DECL_ARGS)
|
||||
{
|
||||
const struct roff_node *link, *descr;
|
||||
const struct roff_node *link, *descr, *punct;
|
||||
int display;
|
||||
|
||||
if (NULL == (link = n->child))
|
||||
if ((link = n->child) == NULL)
|
||||
return 0;
|
||||
|
||||
if (NULL != (descr = link->next)) {
|
||||
/* Find beginning of trailing punctuation. */
|
||||
punct = n->last;
|
||||
while (punct != link && punct->flags & NODE_DELIMC)
|
||||
punct = punct->prev;
|
||||
punct = punct->next;
|
||||
|
||||
/* Link text. */
|
||||
if ((descr = link->next) != NULL && descr != punct) {
|
||||
font_push('I');
|
||||
while (NULL != descr) {
|
||||
while (descr != punct) {
|
||||
print_word(descr->string);
|
||||
descr = descr->next;
|
||||
}
|
||||
print_word(":");
|
||||
font_pop();
|
||||
print_word(":");
|
||||
}
|
||||
|
||||
/* Link target. */
|
||||
display = man_strlen(link->string) >= 26;
|
||||
if (display) {
|
||||
print_line(".RS", MMAN_Bk_susp);
|
||||
print_word("6n");
|
||||
outflags |= MMAN_nl;
|
||||
}
|
||||
font_push('B');
|
||||
print_word(link->string);
|
||||
font_pop();
|
||||
|
||||
/* Trailing punctuation. */
|
||||
while (punct != NULL) {
|
||||
print_word(punct->string);
|
||||
punct = punct->next;
|
||||
}
|
||||
if (display)
|
||||
print_line(".RE", MMAN_nl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ll(DECL_ARGS)
|
||||
static void
|
||||
pre_onearg(DECL_ARGS)
|
||||
{
|
||||
|
||||
print_line(".ll", 0);
|
||||
return 1;
|
||||
outflags |= MMAN_nl;
|
||||
print_word(".");
|
||||
outflags &= ~MMAN_spc;
|
||||
print_word(roff_name[n->tok]);
|
||||
if (n->child != NULL)
|
||||
print_word(n->child->string);
|
||||
outflags |= MMAN_nl;
|
||||
if (n->tok == ROFF_ce)
|
||||
for (n = n->child->next; n != NULL; n = n->next)
|
||||
print_node(meta, n);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1520,7 +1620,7 @@ pre_nm(DECL_ARGS)
|
||||
if (NULL == n->parent->prev)
|
||||
outflags |= MMAN_sp;
|
||||
print_block(".HP", 0);
|
||||
printf(" %zun", strlen(name) + 1);
|
||||
printf(" %dn", man_strlen(name) + 1);
|
||||
outflags |= MMAN_nl;
|
||||
}
|
||||
font_push('B');
|
||||
@ -1615,22 +1715,17 @@ pre_sm(DECL_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
pre_sp(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (MMAN_PP & outflags) {
|
||||
if (outflags & MMAN_PP) {
|
||||
outflags &= ~MMAN_PP;
|
||||
print_line(".PP", 0);
|
||||
} else
|
||||
} else {
|
||||
print_line(".sp", 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
post_sp(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->child != NULL)
|
||||
print_word(n->child->string);
|
||||
}
|
||||
outflags |= MMAN_nl;
|
||||
}
|
||||
|
||||
@ -1642,6 +1737,15 @@ pre_sy(DECL_ARGS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pre_ta(DECL_ARGS)
|
||||
{
|
||||
print_line(".ta", 0);
|
||||
for (n = n->child; n != NULL; n = n->next)
|
||||
print_word(n->string);
|
||||
outflags |= MMAN_nl;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_vt(DECL_ARGS)
|
||||
{
|
||||
|
1558
contrib/mdocml/mdoc_markdown.c
Normal file
1558
contrib/mdocml/mdoc_markdown.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/* $Id: mdoc_state.c,v 1.4 2017/01/10 13:47:00 schwarze Exp $ */
|
||||
/* $Id: mdoc_state.c,v 1.8 2017/05/05 15:17:32 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,6 +16,7 @@
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -35,8 +36,7 @@ static void state_dl(STATE_ARGS);
|
||||
static void state_sh(STATE_ARGS);
|
||||
static void state_sm(STATE_ARGS);
|
||||
|
||||
static const state_handler state_handlers[MDOC_MAX] = {
|
||||
NULL, /* Ap */
|
||||
static const state_handler __state_handlers[MDOC_MAX - MDOC_Dd] = {
|
||||
NULL, /* Dd */
|
||||
NULL, /* Dt */
|
||||
NULL, /* Os */
|
||||
@ -52,6 +52,7 @@ static const state_handler state_handlers[MDOC_MAX] = {
|
||||
NULL, /* It */
|
||||
NULL, /* Ad */
|
||||
NULL, /* An */
|
||||
NULL, /* Ap */
|
||||
NULL, /* Ar */
|
||||
NULL, /* Cd */
|
||||
NULL, /* Cm */
|
||||
@ -154,12 +155,10 @@ static const state_handler state_handlers[MDOC_MAX] = {
|
||||
NULL, /* En */
|
||||
NULL, /* Dx */
|
||||
NULL, /* %Q */
|
||||
NULL, /* br */
|
||||
NULL, /* sp */
|
||||
NULL, /* %U */
|
||||
NULL, /* Ta */
|
||||
NULL, /* ll */
|
||||
};
|
||||
static const state_handler *const state_handlers = __state_handlers - MDOC_Dd;
|
||||
|
||||
|
||||
void
|
||||
@ -167,9 +166,10 @@ mdoc_state(struct roff_man *mdoc, struct roff_node *n)
|
||||
{
|
||||
state_handler handler;
|
||||
|
||||
if (n->tok == TOKEN_NONE)
|
||||
if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
|
||||
return;
|
||||
|
||||
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
|
||||
if ( ! (mdoc_macros[n->tok].flags & MDOC_PROLOGUE))
|
||||
mdoc->flags |= MDOC_PBODY;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_term.c,v 1.346 2017/02/17 19:15:41 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.363 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -106,7 +106,6 @@ static int termp_ft_pre(DECL_ARGS);
|
||||
static int termp_in_pre(DECL_ARGS);
|
||||
static int termp_it_pre(DECL_ARGS);
|
||||
static int termp_li_pre(DECL_ARGS);
|
||||
static int termp_ll_pre(DECL_ARGS);
|
||||
static int termp_lk_pre(DECL_ARGS);
|
||||
static int termp_nd_pre(DECL_ARGS);
|
||||
static int termp_nm_pre(DECL_ARGS);
|
||||
@ -116,7 +115,7 @@ static int termp_rs_pre(DECL_ARGS);
|
||||
static int termp_sh_pre(DECL_ARGS);
|
||||
static int termp_skip_pre(DECL_ARGS);
|
||||
static int termp_sm_pre(DECL_ARGS);
|
||||
static int termp_sp_pre(DECL_ARGS);
|
||||
static int termp_pp_pre(DECL_ARGS);
|
||||
static int termp_ss_pre(DECL_ARGS);
|
||||
static int termp_sy_pre(DECL_ARGS);
|
||||
static int termp_tag_pre(DECL_ARGS);
|
||||
@ -125,14 +124,13 @@ static int termp_vt_pre(DECL_ARGS);
|
||||
static int termp_xr_pre(DECL_ARGS);
|
||||
static int termp_xx_pre(DECL_ARGS);
|
||||
|
||||
static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_ap_pre, NULL }, /* Ap */
|
||||
static const struct termact __termacts[MDOC_MAX - MDOC_Dd] = {
|
||||
{ NULL, NULL }, /* Dd */
|
||||
{ NULL, NULL }, /* Dt */
|
||||
{ NULL, NULL }, /* Os */
|
||||
{ termp_sh_pre, termp_sh_post }, /* Sh */
|
||||
{ termp_ss_pre, termp_ss_post }, /* Ss */
|
||||
{ termp_sp_pre, NULL }, /* Pp */
|
||||
{ termp_pp_pre, NULL }, /* Pp */
|
||||
{ termp_d1_pre, termp_bl_post }, /* D1 */
|
||||
{ termp_d1_pre, termp_bl_post }, /* Dl */
|
||||
{ termp_bd_pre, termp_bd_post }, /* Bd */
|
||||
@ -142,6 +140,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_it_pre, termp_it_post }, /* It */
|
||||
{ termp_under_pre, NULL }, /* Ad */
|
||||
{ termp_an_pre, NULL }, /* An */
|
||||
{ termp_ap_pre, NULL }, /* Ap */
|
||||
{ termp_under_pre, NULL }, /* Ar */
|
||||
{ termp_cd_pre, NULL }, /* Cd */
|
||||
{ termp_bold_pre, NULL }, /* Cm */
|
||||
@ -233,7 +232,7 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_under_pre, NULL }, /* Fr */
|
||||
{ NULL, NULL }, /* Ud */
|
||||
{ NULL, termp_lb_post }, /* Lb */
|
||||
{ termp_sp_pre, NULL }, /* Lp */
|
||||
{ termp_pp_pre, NULL }, /* Lp */
|
||||
{ termp_lk_pre, NULL }, /* Lk */
|
||||
{ termp_under_pre, NULL }, /* Mt */
|
||||
{ termp_quote_pre, termp_quote_post }, /* Brq */
|
||||
@ -244,15 +243,14 @@ static const struct termact termacts[MDOC_MAX] = {
|
||||
{ termp_quote_pre, termp_quote_post }, /* En */
|
||||
{ termp_xx_pre, termp_xx_post }, /* Dx */
|
||||
{ NULL, termp____post }, /* %Q */
|
||||
{ termp_sp_pre, NULL }, /* br */
|
||||
{ termp_sp_pre, NULL }, /* sp */
|
||||
{ NULL, termp____post }, /* %U */
|
||||
{ NULL, NULL }, /* Ta */
|
||||
{ termp_ll_pre, NULL }, /* ll */
|
||||
};
|
||||
static const struct termact *const termacts = __termacts - MDOC_Dd;
|
||||
|
||||
static int fn_prio;
|
||||
|
||||
|
||||
void
|
||||
terminal_mdoc(void *arg, const struct roff_man *mdoc)
|
||||
{
|
||||
@ -261,9 +259,10 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc)
|
||||
size_t save_defindent;
|
||||
|
||||
p = (struct termp *)arg;
|
||||
p->overstep = 0;
|
||||
p->rmargin = p->maxrmargin = p->defrmargin;
|
||||
p->tabwidth = term_len(p, 5);
|
||||
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
|
||||
n = mdoc->first->child;
|
||||
if (p->synopsisonly) {
|
||||
@ -317,8 +316,8 @@ print_mdoc_node(DECL_ARGS)
|
||||
return;
|
||||
|
||||
chld = 1;
|
||||
offset = p->offset;
|
||||
rmargin = p->rmargin;
|
||||
offset = p->tcol->offset;
|
||||
rmargin = p->tcol->rmargin;
|
||||
n->flags &= ~NODE_ENDED;
|
||||
n->prev_font = p->fonti;
|
||||
|
||||
@ -342,7 +341,8 @@ print_mdoc_node(DECL_ARGS)
|
||||
|
||||
switch (n->type) {
|
||||
case ROFFT_TEXT:
|
||||
if (' ' == *n->string && NODE_LINE & n->flags)
|
||||
if (*n->string == ' ' && n->flags & NODE_LINE &&
|
||||
(p->flags & TERMP_NONEWLINE) == 0)
|
||||
term_newln(p);
|
||||
if (NODE_DELIMC & n->flags)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -363,7 +363,12 @@ print_mdoc_node(DECL_ARGS)
|
||||
term_tbl(p, n->span);
|
||||
break;
|
||||
default:
|
||||
if (termacts[n->tok].pre &&
|
||||
if (n->tok < ROFF_MAX) {
|
||||
roff_term_pre(p, n);
|
||||
return;
|
||||
}
|
||||
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
|
||||
if (termacts[n->tok].pre != NULL &&
|
||||
(n->end == ENDBODY_NOT || n->child != NULL))
|
||||
chld = (*termacts[n->tok].pre)
|
||||
(p, &npair, meta, n);
|
||||
@ -384,7 +389,7 @@ print_mdoc_node(DECL_ARGS)
|
||||
case ROFFT_EQN:
|
||||
break;
|
||||
default:
|
||||
if ( ! termacts[n->tok].post || NODE_ENDED & n->flags)
|
||||
if (termacts[n->tok].post == NULL || n->flags & NODE_ENDED)
|
||||
break;
|
||||
(void)(*termacts[n->tok].post)(p, &npair, meta, n);
|
||||
|
||||
@ -401,10 +406,9 @@ print_mdoc_node(DECL_ARGS)
|
||||
if (NODE_EOS & n->flags)
|
||||
p->flags |= TERMP_SENTENCE;
|
||||
|
||||
if (MDOC_ll != n->tok) {
|
||||
p->offset = offset;
|
||||
p->rmargin = rmargin;
|
||||
}
|
||||
if (n->type != ROFFT_TEXT)
|
||||
p->tcol->offset = offset;
|
||||
p->tcol->rmargin = rmargin;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -424,9 +428,9 @@ print_mdoc_foot(struct termp *p, const struct roff_meta *meta)
|
||||
|
||||
term_vspace(p);
|
||||
|
||||
p->offset = 0;
|
||||
p->tcol->offset = 0;
|
||||
sz = term_strlen(p, meta->date);
|
||||
p->rmargin = p->maxrmargin > sz ?
|
||||
p->tcol->rmargin = p->maxrmargin > sz ?
|
||||
(p->maxrmargin + term_len(p, 1) - sz) / 2 : 0;
|
||||
p->trailspace = 1;
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
|
||||
@ -434,16 +438,16 @@ print_mdoc_foot(struct termp *p, const struct roff_meta *meta)
|
||||
term_word(p, meta->os);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = p->rmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
sz = term_strlen(p, meta->os);
|
||||
p->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0;
|
||||
p->tcol->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
term_word(p, meta->date);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->trailspace = 0;
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -451,8 +455,8 @@ print_mdoc_foot(struct termp *p, const struct roff_meta *meta)
|
||||
term_word(p, meta->os);
|
||||
term_flushln(p);
|
||||
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = 0;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->flags = 0;
|
||||
}
|
||||
|
||||
@ -492,8 +496,8 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)
|
||||
|
||||
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
|
||||
p->trailspace = 1;
|
||||
p->offset = 0;
|
||||
p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
||||
p->tcol->offset = 0;
|
||||
p->tcol->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?
|
||||
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
|
||||
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
|
||||
|
||||
@ -501,26 +505,26 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)
|
||||
term_flushln(p);
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->offset + vollen + titlen < p->maxrmargin ?
|
||||
p->maxrmargin - titlen : p->maxrmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->tcol->offset + vollen + titlen <
|
||||
p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin;
|
||||
|
||||
term_word(p, volume);
|
||||
term_flushln(p);
|
||||
|
||||
p->flags &= ~TERMP_NOBREAK;
|
||||
p->trailspace = 0;
|
||||
if (p->rmargin + titlen <= p->maxrmargin) {
|
||||
if (p->tcol->rmargin + titlen <= p->maxrmargin) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
term_word(p, title);
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
p->offset = 0;
|
||||
p->rmargin = p->maxrmargin;
|
||||
p->tcol->offset = 0;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
free(title);
|
||||
free(volume);
|
||||
}
|
||||
@ -529,8 +533,10 @@ static int
|
||||
a2width(const struct termp *p, const char *v)
|
||||
{
|
||||
struct roffsu su;
|
||||
const char *end;
|
||||
|
||||
if (a2roffsu(v, &su, SCALE_MAX) < 2) {
|
||||
end = a2roffsu(v, &su, SCALE_MAX);
|
||||
if (end == NULL || *end != '\0') {
|
||||
SCALE_HS_INIT(&su, term_strlen(p, v));
|
||||
su.scale /= term_strlen(p, "0");
|
||||
}
|
||||
@ -595,14 +601,6 @@ print_bvspace(struct termp *p,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
termp_ll_pre(DECL_ARGS)
|
||||
{
|
||||
|
||||
term_setwidth(p, n->child != NULL ? n->child->string : NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
termp_it_pre(DECL_ARGS)
|
||||
{
|
||||
@ -653,8 +651,8 @@ termp_it_pre(DECL_ARGS)
|
||||
|
||||
if (bl->norm->Bl.offs != NULL) {
|
||||
offset = a2width(p, bl->norm->Bl.offs);
|
||||
if (offset < 0 && (size_t)(-offset) > p->offset)
|
||||
offset = -p->offset;
|
||||
if (offset < 0 && (size_t)(-offset) > p->tcol->offset)
|
||||
offset = -p->tcol->offset;
|
||||
else if (offset > SHRT_MAX)
|
||||
offset = 0;
|
||||
}
|
||||
@ -718,8 +716,8 @@ termp_it_pre(DECL_ARGS)
|
||||
* handling for column for how this changes.
|
||||
*/
|
||||
width = a2width(p, bl->norm->Bl.width) + term_len(p, 2);
|
||||
if (width < 0 && (size_t)(-width) > p->offset)
|
||||
width = -p->offset;
|
||||
if (width < 0 && (size_t)(-width) > p->tcol->offset)
|
||||
width = -p->tcol->offset;
|
||||
else if (width > SHRT_MAX)
|
||||
width = 0;
|
||||
break;
|
||||
@ -768,33 +766,15 @@ termp_it_pre(DECL_ARGS)
|
||||
case LIST_bullet:
|
||||
case LIST_dash:
|
||||
case LIST_hyphen:
|
||||
/*
|
||||
* Weird special case.
|
||||
* Some very narrow lists actually hang.
|
||||
*/
|
||||
if (width <= (int)term_len(p, 2))
|
||||
p->flags |= TERMP_HANG;
|
||||
if (n->type != ROFFT_HEAD)
|
||||
break;
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
p->trailspace = 1;
|
||||
if (n->type == ROFFT_HEAD) {
|
||||
p->flags |= TERMP_NOBREAK | TERMP_HANG;
|
||||
p->trailspace = 1;
|
||||
} else if (width <= (int)term_len(p, 2))
|
||||
p->flags |= TERMP_NOPAD;
|
||||
break;
|
||||
case LIST_hang:
|
||||
if (n->type != ROFFT_HEAD)
|
||||
break;
|
||||
|
||||
/*
|
||||
* This is ugly. If `-hang' is specified and the body
|
||||
* is a `Bl' or `Bd', then we want basically to nullify
|
||||
* the "overstep" effect in term_flushln() and treat
|
||||
* this as a `-ohang' list instead.
|
||||
*/
|
||||
if (NULL != n->next &&
|
||||
NULL != n->next->child &&
|
||||
(MDOC_Bl == n->next->child->tok ||
|
||||
MDOC_Bd == n->next->child->tok))
|
||||
break;
|
||||
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG;
|
||||
p->trailspace = 1;
|
||||
break;
|
||||
@ -806,7 +786,7 @@ termp_it_pre(DECL_ARGS)
|
||||
p->trailspace = 2;
|
||||
|
||||
if (NULL == n->next || NULL == n->next->child)
|
||||
p->flags |= TERMP_DANGLE;
|
||||
p->flags |= TERMP_HANG;
|
||||
break;
|
||||
case LIST_column:
|
||||
if (n->type == ROFFT_HEAD)
|
||||
@ -837,43 +817,31 @@ termp_it_pre(DECL_ARGS)
|
||||
* necessarily lengthened. Everybody gets the offset.
|
||||
*/
|
||||
|
||||
p->offset += offset;
|
||||
p->tcol->offset += offset;
|
||||
|
||||
switch (type) {
|
||||
case LIST_hang:
|
||||
/*
|
||||
* Same stipulation as above, regarding `-hang'. We
|
||||
* don't want to recalculate rmargin and offsets when
|
||||
* using `Bd' or `Bl' within `-hang' overstep lists.
|
||||
*/
|
||||
if (n->type == ROFFT_HEAD &&
|
||||
NULL != n->next &&
|
||||
NULL != n->next->child &&
|
||||
(MDOC_Bl == n->next->child->tok ||
|
||||
MDOC_Bd == n->next->child->tok))
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case LIST_bullet:
|
||||
case LIST_dash:
|
||||
case LIST_enum:
|
||||
case LIST_hyphen:
|
||||
case LIST_hang:
|
||||
case LIST_tag:
|
||||
if (n->type == ROFFT_HEAD)
|
||||
p->rmargin = p->offset + width;
|
||||
p->tcol->rmargin = p->tcol->offset + width;
|
||||
else
|
||||
p->offset += width;
|
||||
p->tcol->offset += width;
|
||||
break;
|
||||
case LIST_column:
|
||||
assert(width);
|
||||
p->rmargin = p->offset + width;
|
||||
p->tcol->rmargin = p->tcol->offset + width;
|
||||
/*
|
||||
* XXX - this behaviour is not documented: the
|
||||
* right-most column is filled to the right margin.
|
||||
*/
|
||||
if (n->type == ROFFT_HEAD)
|
||||
break;
|
||||
if (NULL == n->next && p->rmargin < p->maxrmargin)
|
||||
p->rmargin = p->maxrmargin;
|
||||
if (n->next == NULL && p->tcol->rmargin < p->maxrmargin)
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -923,6 +891,7 @@ termp_it_pre(DECL_ARGS)
|
||||
case LIST_column:
|
||||
if (n->type == ROFFT_HEAD)
|
||||
return 0;
|
||||
p->minbl = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -963,8 +932,7 @@ termp_it_post(DECL_ARGS)
|
||||
* has munged them in the meanwhile.
|
||||
*/
|
||||
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP | TERMP_BRIND |
|
||||
TERMP_DANGLE | TERMP_HANG);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP | TERMP_BRIND | TERMP_HANG);
|
||||
p->trailspace = 0;
|
||||
}
|
||||
|
||||
@ -979,7 +947,7 @@ termp_nm_pre(DECL_ARGS)
|
||||
}
|
||||
|
||||
if (n->type == ROFFT_BODY) {
|
||||
if (NULL == n->child)
|
||||
if (n->child == NULL)
|
||||
return 0;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
cp = NULL;
|
||||
@ -988,9 +956,10 @@ termp_nm_pre(DECL_ARGS)
|
||||
if (cp == NULL)
|
||||
cp = meta->name;
|
||||
if (cp == NULL)
|
||||
p->offset += term_len(p, 6);
|
||||
p->tcol->offset += term_len(p, 6);
|
||||
else
|
||||
p->offset += term_len(p, 1) + term_strlen(p, cp);
|
||||
p->tcol->offset += term_len(p, 1) +
|
||||
term_strlen(p, cp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1001,18 +970,18 @@ termp_nm_pre(DECL_ARGS)
|
||||
synopsis_pre(p, n->parent);
|
||||
|
||||
if (n->type == ROFFT_HEAD &&
|
||||
NULL != n->next && NULL != n->next->child) {
|
||||
n->next != NULL && n->next->child != NULL) {
|
||||
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_BRIND;
|
||||
p->trailspace = 1;
|
||||
p->rmargin = p->offset + term_len(p, 1);
|
||||
if (NULL == n->child) {
|
||||
p->rmargin += term_strlen(p, meta->name);
|
||||
} else if (n->child->type == ROFFT_TEXT) {
|
||||
p->rmargin += term_strlen(p, n->child->string);
|
||||
if (n->child->next)
|
||||
p->tcol->rmargin = p->tcol->offset + term_len(p, 1);
|
||||
if (n->child == NULL)
|
||||
p->tcol->rmargin += term_strlen(p, meta->name);
|
||||
else if (n->child->type == ROFFT_TEXT) {
|
||||
p->tcol->rmargin += term_strlen(p, n->child->string);
|
||||
if (n->child->next != NULL)
|
||||
p->flags |= TERMP_HANG;
|
||||
} else {
|
||||
p->rmargin += term_len(p, 5);
|
||||
p->tcol->rmargin += term_len(p, 5);
|
||||
p->flags |= TERMP_HANG;
|
||||
}
|
||||
}
|
||||
@ -1135,8 +1104,14 @@ static void
|
||||
termp_bl_post(DECL_ARGS)
|
||||
{
|
||||
|
||||
if (n->type == ROFFT_BLOCK)
|
||||
term_newln(p);
|
||||
if (n->type != ROFFT_BLOCK)
|
||||
return;
|
||||
term_newln(p);
|
||||
if (n->tok != MDOC_Bl || n->norm->Bl.type != LIST_column)
|
||||
return;
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1278,7 +1253,10 @@ termp_sh_pre(DECL_ARGS)
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
p->offset = term_len(p, p->defindent);
|
||||
p->tcol->offset = term_len(p, p->defindent);
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
switch (n->sec) {
|
||||
case SEC_DESCRIPTION:
|
||||
fn_prio = 0;
|
||||
@ -1306,7 +1284,7 @@ termp_sh_post(DECL_ARGS)
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
term_newln(p);
|
||||
p->offset = 0;
|
||||
p->tcol->offset = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1328,7 +1306,10 @@ termp_d1_pre(DECL_ARGS)
|
||||
if (n->type != ROFFT_BLOCK)
|
||||
return 1;
|
||||
term_newln(p);
|
||||
p->offset += term_len(p, p->defindent + 1);
|
||||
p->tcol->offset += term_len(p, p->defindent + 1);
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1356,8 +1337,8 @@ termp_fn_pre(DECL_ARGS)
|
||||
return 0;
|
||||
|
||||
if (pretty) {
|
||||
rmargin = p->rmargin;
|
||||
p->rmargin = p->offset + term_len(p, 4);
|
||||
rmargin = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->tcol->offset + term_len(p, 4);
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG;
|
||||
}
|
||||
|
||||
@ -1372,8 +1353,9 @@ termp_fn_pre(DECL_ARGS)
|
||||
if (pretty) {
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = rmargin;
|
||||
p->flags |= TERMP_NOPAD;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = rmargin;
|
||||
}
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
@ -1434,7 +1416,7 @@ termp_fa_pre(DECL_ARGS)
|
||||
static int
|
||||
termp_bd_pre(DECL_ARGS)
|
||||
{
|
||||
size_t tabwidth, lm, len, rm, rmax;
|
||||
size_t lm, len;
|
||||
struct roff_node *nn;
|
||||
int offset;
|
||||
|
||||
@ -1450,15 +1432,15 @@ termp_bd_pre(DECL_ARGS)
|
||||
! strcmp(n->norm->Bd.offs, "left"))
|
||||
/* nothing */;
|
||||
else if ( ! strcmp(n->norm->Bd.offs, "indent"))
|
||||
p->offset += term_len(p, p->defindent + 1);
|
||||
p->tcol->offset += term_len(p, p->defindent + 1);
|
||||
else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
|
||||
p->offset += term_len(p, (p->defindent + 1) * 2);
|
||||
p->tcol->offset += term_len(p, (p->defindent + 1) * 2);
|
||||
else {
|
||||
offset = a2width(p, n->norm->Bd.offs);
|
||||
if (offset < 0 && (size_t)(-offset) > p->offset)
|
||||
p->offset = 0;
|
||||
if (offset < 0 && (size_t)(-offset) > p->tcol->offset)
|
||||
p->tcol->offset = 0;
|
||||
else if (offset < SHRT_MAX)
|
||||
p->offset += offset;
|
||||
p->tcol->offset += offset;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1469,29 +1451,29 @@ termp_bd_pre(DECL_ARGS)
|
||||
* lines are allowed.
|
||||
*/
|
||||
|
||||
if (DISP_literal != n->norm->Bd.type &&
|
||||
DISP_unfilled != n->norm->Bd.type &&
|
||||
DISP_centered != n->norm->Bd.type)
|
||||
if (n->norm->Bd.type != DISP_literal &&
|
||||
n->norm->Bd.type != DISP_unfilled &&
|
||||
n->norm->Bd.type != DISP_centered)
|
||||
return 1;
|
||||
|
||||
tabwidth = p->tabwidth;
|
||||
if (DISP_literal == n->norm->Bd.type)
|
||||
p->tabwidth = term_len(p, 8);
|
||||
if (n->norm->Bd.type == DISP_literal) {
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, "8n");
|
||||
}
|
||||
|
||||
lm = p->offset;
|
||||
rm = p->rmargin;
|
||||
rmax = p->maxrmargin;
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
|
||||
for (nn = n->child; nn; nn = nn->next) {
|
||||
if (DISP_centered == n->norm->Bd.type) {
|
||||
lm = p->tcol->offset;
|
||||
p->flags |= TERMP_BRNEVER;
|
||||
for (nn = n->child; nn != NULL; nn = nn->next) {
|
||||
if (n->norm->Bd.type == DISP_centered) {
|
||||
if (nn->type == ROFFT_TEXT) {
|
||||
len = term_strlen(p, nn->string);
|
||||
p->offset = len >= rm ? 0 :
|
||||
lm + len >= rm ? rm - len :
|
||||
(lm + rm - len) / 2;
|
||||
p->tcol->offset = len >= p->tcol->rmargin ?
|
||||
0 : lm + len >= p->tcol->rmargin ?
|
||||
p->tcol->rmargin - len :
|
||||
(lm + p->tcol->rmargin - len) / 2;
|
||||
} else
|
||||
p->offset = lm;
|
||||
p->tcol->offset = lm;
|
||||
}
|
||||
print_mdoc_node(p, pair, meta, nn);
|
||||
/*
|
||||
@ -1500,10 +1482,10 @@ termp_bd_pre(DECL_ARGS)
|
||||
* notion of selective eoln whitespace is pretty dumb
|
||||
* anyway, so don't sweat it.
|
||||
*/
|
||||
if (nn->tok < ROFF_MAX)
|
||||
continue;
|
||||
switch (nn->tok) {
|
||||
case MDOC_Sm:
|
||||
case MDOC_br:
|
||||
case MDOC_sp:
|
||||
case MDOC_Bl:
|
||||
case MDOC_D1:
|
||||
case MDOC_Dl:
|
||||
@ -1519,33 +1501,21 @@ termp_bd_pre(DECL_ARGS)
|
||||
term_flushln(p);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
p->tabwidth = tabwidth;
|
||||
p->rmargin = rm;
|
||||
p->maxrmargin = rmax;
|
||||
p->flags &= ~TERMP_BRNEVER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
termp_bd_post(DECL_ARGS)
|
||||
{
|
||||
size_t rm, rmax;
|
||||
|
||||
if (n->type != ROFFT_BODY)
|
||||
return;
|
||||
|
||||
rm = p->rmargin;
|
||||
rmax = p->maxrmargin;
|
||||
|
||||
if (DISP_literal == n->norm->Bd.type ||
|
||||
DISP_unfilled == n->norm->Bd.type)
|
||||
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
|
||||
|
||||
p->flags |= TERMP_BRNEVER;
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_newln(p);
|
||||
|
||||
p->rmargin = rm;
|
||||
p->maxrmargin = rmax;
|
||||
p->flags &= ~TERMP_BRNEVER;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1587,10 +1557,13 @@ termp_ss_pre(DECL_ARGS)
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
p->offset = term_len(p, (p->defindent+1)/2);
|
||||
p->tcol->offset = term_len(p, (p->defindent+1)/2);
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
p->offset = term_len(p, p->defindent);
|
||||
p->tcol->offset = term_len(p, p->defindent);
|
||||
term_tab_set(p, NULL);
|
||||
term_tab_set(p, "T");
|
||||
term_tab_set(p, ".5i");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1650,37 +1623,10 @@ termp_in_post(DECL_ARGS)
|
||||
}
|
||||
|
||||
static int
|
||||
termp_sp_pre(DECL_ARGS)
|
||||
termp_pp_pre(DECL_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
int i, len;
|
||||
|
||||
switch (n->tok) {
|
||||
case MDOC_sp:
|
||||
if (n->child) {
|
||||
if ( ! a2roffsu(n->child->string, &su, SCALE_VS))
|
||||
su.scale = 1.0;
|
||||
len = term_vspan(p, &su);
|
||||
} else
|
||||
len = 1;
|
||||
break;
|
||||
case MDOC_br:
|
||||
len = 0;
|
||||
break;
|
||||
default:
|
||||
len = 1;
|
||||
fn_prio = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == len)
|
||||
term_newln(p);
|
||||
else if (len < 0)
|
||||
p->skipvsp -= len;
|
||||
else
|
||||
for (i = 0; i < len; i++)
|
||||
term_vspace(p);
|
||||
|
||||
fn_prio = 0;
|
||||
term_vspace(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1861,8 +1807,8 @@ termp_fo_pre(DECL_ARGS)
|
||||
return 1;
|
||||
} else if (n->type == ROFFT_BODY) {
|
||||
if (pretty) {
|
||||
rmargin = p->rmargin;
|
||||
p->rmargin = p->offset + term_len(p, 4);
|
||||
rmargin = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->tcol->offset + term_len(p, 4);
|
||||
p->flags |= TERMP_NOBREAK | TERMP_BRIND |
|
||||
TERMP_HANG;
|
||||
}
|
||||
@ -1873,8 +1819,9 @@ termp_fo_pre(DECL_ARGS)
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND |
|
||||
TERMP_HANG);
|
||||
p->offset = p->rmargin;
|
||||
p->rmargin = rmargin;
|
||||
p->flags |= TERMP_NOPAD;
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = rmargin;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1992,26 +1939,50 @@ termp_li_pre(DECL_ARGS)
|
||||
static int
|
||||
termp_lk_pre(DECL_ARGS)
|
||||
{
|
||||
const struct roff_node *link, *descr;
|
||||
const struct roff_node *link, *descr, *punct;
|
||||
int display;
|
||||
|
||||
if (NULL == (link = n->child))
|
||||
if ((link = n->child) == NULL)
|
||||
return 0;
|
||||
|
||||
if (NULL != (descr = link->next)) {
|
||||
/* Find beginning of trailing punctuation. */
|
||||
punct = n->last;
|
||||
while (punct != link && punct->flags & NODE_DELIMC)
|
||||
punct = punct->prev;
|
||||
punct = punct->next;
|
||||
|
||||
/* Link text. */
|
||||
if ((descr = link->next) != NULL && descr != punct) {
|
||||
term_fontpush(p, TERMFONT_UNDER);
|
||||
while (NULL != descr) {
|
||||
while (descr != punct) {
|
||||
if (descr->flags & (NODE_DELIMC | NODE_DELIMO))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, descr->string);
|
||||
descr = descr->next;
|
||||
}
|
||||
term_fontpop(p);
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, ":");
|
||||
term_fontpop(p);
|
||||
}
|
||||
|
||||
/* Link target. */
|
||||
display = term_strlen(p, link->string) >= 26;
|
||||
if (display) {
|
||||
term_newln(p);
|
||||
p->tcol->offset += term_len(p, p->defindent + 1);
|
||||
}
|
||||
term_fontpush(p, TERMFONT_BOLD);
|
||||
term_word(p, link->string);
|
||||
term_fontpop(p);
|
||||
|
||||
/* Trailing punctuation. */
|
||||
while (punct != NULL) {
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_word(p, punct->string);
|
||||
punct = punct->next;
|
||||
}
|
||||
if (display)
|
||||
term_newln(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_validate.c,v 1.318 2017/02/06 03:44:58 schwarze Exp $ */
|
||||
/* $Id: mdoc_validate.c,v 1.332 2017/06/08 00:23:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -53,12 +53,13 @@ typedef void (*v_post)(POST_ARGS);
|
||||
|
||||
static int build_list(struct roff_man *, int);
|
||||
static void check_text(struct roff_man *, int, int, char *);
|
||||
static void check_bsd(struct roff_man *, int, int, char *);
|
||||
static void check_argv(struct roff_man *,
|
||||
struct roff_node *, struct mdoc_argv *);
|
||||
static void check_args(struct roff_man *, struct roff_node *);
|
||||
static int child_an(const struct roff_node *);
|
||||
static size_t macro2len(int);
|
||||
static void rewrite_macro2len(char **);
|
||||
static size_t macro2len(enum roff_tok);
|
||||
static void rewrite_macro2len(struct roff_man *, char **);
|
||||
|
||||
static void post_an(POST_ARGS);
|
||||
static void post_an_norm(POST_ARGS);
|
||||
@ -105,11 +106,11 @@ static void post_sh_authors(POST_ARGS);
|
||||
static void post_sm(POST_ARGS);
|
||||
static void post_st(POST_ARGS);
|
||||
static void post_std(POST_ARGS);
|
||||
static void post_useless(POST_ARGS);
|
||||
static void post_xr(POST_ARGS);
|
||||
static void post_xx(POST_ARGS);
|
||||
|
||||
static v_post mdoc_valids[MDOC_MAX] = {
|
||||
NULL, /* Ap */
|
||||
static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = {
|
||||
post_dd, /* Dd */
|
||||
post_dt, /* Dt */
|
||||
post_os, /* Os */
|
||||
@ -125,6 +126,7 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
post_it, /* It */
|
||||
NULL, /* Ad */
|
||||
post_an, /* An */
|
||||
NULL, /* Ap */
|
||||
post_defaults, /* Ar */
|
||||
NULL, /* Cd */
|
||||
NULL, /* Cm */
|
||||
@ -201,7 +203,7 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
post_sm, /* Sm */
|
||||
post_hyph, /* Sx */
|
||||
NULL, /* Sy */
|
||||
NULL, /* Tn */
|
||||
post_useless, /* Tn */
|
||||
post_xx, /* Ux */
|
||||
NULL, /* Xc */
|
||||
NULL, /* Xo */
|
||||
@ -227,16 +229,14 @@ static v_post mdoc_valids[MDOC_MAX] = {
|
||||
post_en, /* En */
|
||||
post_xx, /* Dx */
|
||||
NULL, /* %Q */
|
||||
post_par, /* br */
|
||||
post_par, /* sp */
|
||||
NULL, /* %U */
|
||||
NULL, /* Ta */
|
||||
NULL, /* ll */
|
||||
};
|
||||
static const v_post *const mdoc_valids = __mdoc_valids - MDOC_Dd;
|
||||
|
||||
#define RSORD_MAX 14 /* Number of `Rs' blocks. */
|
||||
|
||||
static const int rsord[RSORD_MAX] = {
|
||||
static const enum roff_tok rsord[RSORD_MAX] = {
|
||||
MDOC__A,
|
||||
MDOC__T,
|
||||
MDOC__B,
|
||||
@ -284,7 +284,7 @@ void
|
||||
mdoc_node_validate(struct roff_man *mdoc)
|
||||
{
|
||||
struct roff_node *n;
|
||||
v_post *p;
|
||||
const v_post *p;
|
||||
|
||||
n = mdoc->last;
|
||||
mdoc->last = mdoc->last->child;
|
||||
@ -303,6 +303,10 @@ mdoc_node_validate(struct roff_man *mdoc)
|
||||
if (n->sec != SEC_SYNOPSIS ||
|
||||
(n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd))
|
||||
check_text(mdoc, n->line, n->pos, n->string);
|
||||
if (n->parent->tok == MDOC_Sh ||
|
||||
n->parent->tok == MDOC_Ss ||
|
||||
n->parent->tok == MDOC_It)
|
||||
check_bsd(mdoc, n->line, n->pos, n->string);
|
||||
break;
|
||||
case ROFFT_EQN:
|
||||
case ROFFT_TBL:
|
||||
@ -326,6 +330,20 @@ mdoc_node_validate(struct roff_man *mdoc)
|
||||
|
||||
/* Call the macro's postprocessor. */
|
||||
|
||||
if (n->tok < ROFF_MAX) {
|
||||
switch(n->tok) {
|
||||
case ROFF_br:
|
||||
case ROFF_sp:
|
||||
post_par(mdoc);
|
||||
break;
|
||||
default:
|
||||
roff_validate(mdoc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
|
||||
p = mdoc_valids + n->tok;
|
||||
if (*p)
|
||||
(*p)(mdoc);
|
||||
@ -370,6 +388,25 @@ check_text(struct roff_man *mdoc, int ln, int pos, char *p)
|
||||
ln, pos + (int)(p - cp), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
check_bsd(struct roff_man *mdoc, int ln, int pos, char *p)
|
||||
{
|
||||
const char *cp;
|
||||
|
||||
if ((cp = strstr(p, "OpenBSD")) != NULL)
|
||||
mandoc_msg(MANDOCERR_BX, mdoc->parse,
|
||||
ln, pos + (cp - p), "Ox");
|
||||
if ((cp = strstr(p, "NetBSD")) != NULL)
|
||||
mandoc_msg(MANDOCERR_BX, mdoc->parse,
|
||||
ln, pos + (cp - p), "Nx");
|
||||
if ((cp = strstr(p, "FreeBSD")) != NULL)
|
||||
mandoc_msg(MANDOCERR_BX, mdoc->parse,
|
||||
ln, pos + (cp - p), "Fx");
|
||||
if ((cp = strstr(p, "DragonFly")) != NULL)
|
||||
mandoc_msg(MANDOCERR_BX, mdoc->parse,
|
||||
ln, pos + (cp - p), "Dx");
|
||||
}
|
||||
|
||||
static void
|
||||
post_bl_norm(POST_ARGS)
|
||||
{
|
||||
@ -450,7 +487,7 @@ post_bl_norm(POST_ARGS)
|
||||
mdoc->parse, argv->line,
|
||||
argv->pos, "Bl -width %s",
|
||||
argv->value[0]);
|
||||
rewrite_macro2len(argv->value);
|
||||
rewrite_macro2len(mdoc, argv->value);
|
||||
n->norm->Bl.width = argv->value[0];
|
||||
break;
|
||||
case MDOC_Offset:
|
||||
@ -465,7 +502,7 @@ post_bl_norm(POST_ARGS)
|
||||
mdoc->parse, argv->line,
|
||||
argv->pos, "Bl -offset %s",
|
||||
argv->value[0]);
|
||||
rewrite_macro2len(argv->value);
|
||||
rewrite_macro2len(mdoc, argv->value);
|
||||
n->norm->Bl.offs = argv->value[0];
|
||||
break;
|
||||
default:
|
||||
@ -592,7 +629,7 @@ post_bd(POST_ARGS)
|
||||
mdoc->parse, argv->line,
|
||||
argv->pos, "Bd -offset %s",
|
||||
argv->value[0]);
|
||||
rewrite_macro2len(argv->value);
|
||||
rewrite_macro2len(mdoc, argv->value);
|
||||
n->norm->Bd.offs = argv->value[0];
|
||||
break;
|
||||
case MDOC_Compact:
|
||||
@ -659,11 +696,11 @@ post_eoln(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
post_useless(mdoc);
|
||||
n = mdoc->last;
|
||||
if (n->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse,
|
||||
n->line, n->pos, "%s %s",
|
||||
mdoc_macronames[n->tok], n->child->string);
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse, n->line,
|
||||
n->pos, "%s %s", roff_name[n->tok], n->child->string);
|
||||
|
||||
while (n->child != NULL)
|
||||
roff_node_delete(mdoc, n->child);
|
||||
@ -757,6 +794,9 @@ post_lb(POST_ARGS)
|
||||
return;
|
||||
}
|
||||
|
||||
mandoc_vmsg(MANDOCERR_LB_BAD, mdoc->parse, n->child->line,
|
||||
n->child->pos, "Lb %s", n->child->string);
|
||||
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "library");
|
||||
mdoc->last->flags = NODE_NOSRC;
|
||||
roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq");
|
||||
@ -817,7 +857,7 @@ post_std(POST_ARGS)
|
||||
return;
|
||||
|
||||
mandoc_msg(MANDOCERR_ARG_STD, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -852,7 +892,17 @@ post_obsolete(POST_ARGS)
|
||||
n = mdoc->last;
|
||||
if (n->type == ROFFT_ELEM || n->type == ROFFT_BLOCK)
|
||||
mandoc_msg(MANDOCERR_MACRO_OBS, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
}
|
||||
|
||||
static void
|
||||
post_useless(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
n = mdoc->last;
|
||||
mandoc_msg(MANDOCERR_MACRO_USELESS, mdoc->parse,
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1029,15 +1079,25 @@ static void
|
||||
post_nd(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n;
|
||||
size_t sz;
|
||||
|
||||
n = mdoc->last;
|
||||
|
||||
if (n->type != ROFFT_BODY)
|
||||
return;
|
||||
|
||||
if (n->sec != SEC_NAME)
|
||||
mandoc_msg(MANDOCERR_ND_LATE, mdoc->parse,
|
||||
n->line, n->pos, "Nd");
|
||||
|
||||
if (n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_ND_EMPTY, mdoc->parse,
|
||||
n->line, n->pos, "Nd");
|
||||
else if (n->last->type == ROFFT_TEXT &&
|
||||
(sz = strlen(n->last->string)) != 0 &&
|
||||
n->last->string[sz - 1] == '.')
|
||||
mandoc_msg(MANDOCERR_ND_DOT, mdoc->parse,
|
||||
n->last->line, n->last->pos + sz - 1, NULL);
|
||||
|
||||
post_hyph(mdoc);
|
||||
}
|
||||
@ -1056,7 +1116,7 @@ post_display(POST_ARGS)
|
||||
roff_node_delete(mdoc, n);
|
||||
} else if (n->child == NULL)
|
||||
mandoc_msg(MANDOCERR_BLK_EMPTY, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
else if (n->tok == MDOC_D1)
|
||||
post_hyph(mdoc);
|
||||
break;
|
||||
@ -1079,7 +1139,7 @@ post_display(POST_ARGS)
|
||||
if (np->type == ROFFT_BLOCK && np->tok == MDOC_Bd) {
|
||||
mandoc_vmsg(MANDOCERR_BD_NEST,
|
||||
mdoc->parse, n->line, n->pos,
|
||||
"%s in Bd", mdoc_macronames[n->tok]);
|
||||
"%s in Bd", roff_name[n->tok]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1265,10 +1325,10 @@ post_it(POST_ARGS)
|
||||
/* FALLTHROUGH */
|
||||
case LIST_item:
|
||||
if ((nch = nit->head->child) != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
mdoc->parse, nit->line, nit->pos,
|
||||
"It %s", nch->string == NULL ?
|
||||
mdoc_macronames[nch->tok] : nch->string);
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse,
|
||||
nit->line, nit->pos, "It %s",
|
||||
nch->string == NULL ? roff_name[nch->tok] :
|
||||
nch->string);
|
||||
break;
|
||||
case LIST_column:
|
||||
cols = (int)nbl->norm->Bl.ncols;
|
||||
@ -1306,7 +1366,7 @@ post_bl_block(POST_ARGS)
|
||||
switch (nc->tok) {
|
||||
case MDOC_Pp:
|
||||
case MDOC_Lp:
|
||||
case MDOC_br:
|
||||
case ROFF_br:
|
||||
break;
|
||||
default:
|
||||
nc = NULL;
|
||||
@ -1315,14 +1375,13 @@ post_bl_block(POST_ARGS)
|
||||
if (ni->next == NULL) {
|
||||
mandoc_msg(MANDOCERR_PAR_MOVE,
|
||||
mdoc->parse, nc->line, nc->pos,
|
||||
mdoc_macronames[nc->tok]);
|
||||
roff_name[nc->tok]);
|
||||
mdoc_node_relink(mdoc, nc);
|
||||
} else if (n->norm->Bl.comp == 0 &&
|
||||
n->norm->Bl.type != LIST_column) {
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||
mdoc->parse, nc->line, nc->pos,
|
||||
"%s before It",
|
||||
mdoc_macronames[nc->tok]);
|
||||
"%s before It", roff_name[nc->tok]);
|
||||
roff_node_delete(mdoc, nc);
|
||||
} else
|
||||
break;
|
||||
@ -1335,17 +1394,17 @@ post_bl_block(POST_ARGS)
|
||||
* If the argument of -offset or -width is a macro,
|
||||
* replace it with the associated default width.
|
||||
*/
|
||||
void
|
||||
rewrite_macro2len(char **arg)
|
||||
static void
|
||||
rewrite_macro2len(struct roff_man *mdoc, char **arg)
|
||||
{
|
||||
size_t width;
|
||||
int tok;
|
||||
enum roff_tok tok;
|
||||
|
||||
if (*arg == NULL)
|
||||
return;
|
||||
else if ( ! strcmp(*arg, "Ds"))
|
||||
width = 6;
|
||||
else if ((tok = mdoc_hash_find(*arg)) == TOKEN_NONE)
|
||||
else if ((tok = roffhash_find(mdoc->mdocmac, *arg, 0)) == TOKEN_NONE)
|
||||
return;
|
||||
else
|
||||
width = macro2len(tok);
|
||||
@ -1423,6 +1482,8 @@ post_bl(POST_ARGS)
|
||||
struct roff_node *nparent, *nprev; /* of the Bl block */
|
||||
struct roff_node *nblock, *nbody; /* of the Bl */
|
||||
struct roff_node *nchild, *nnext; /* of the Bl body */
|
||||
const char *prev_Er;
|
||||
int order;
|
||||
|
||||
nbody = mdoc->last;
|
||||
switch (nbody->type) {
|
||||
@ -1486,8 +1547,7 @@ post_bl(POST_ARGS)
|
||||
}
|
||||
|
||||
mandoc_msg(MANDOCERR_BL_MOVE, mdoc->parse,
|
||||
nchild->line, nchild->pos,
|
||||
mdoc_macronames[nchild->tok]);
|
||||
nchild->line, nchild->pos, roff_name[nchild->tok]);
|
||||
|
||||
/*
|
||||
* Move the node out of the Bl block.
|
||||
@ -1524,6 +1584,34 @@ post_bl(POST_ARGS)
|
||||
|
||||
nchild = nnext;
|
||||
}
|
||||
|
||||
if (mdoc->meta.os_e != MDOC_OS_NETBSD)
|
||||
return;
|
||||
|
||||
prev_Er = NULL;
|
||||
for (nchild = nbody->child; nchild != NULL; nchild = nchild->next) {
|
||||
if (nchild->tok != MDOC_It)
|
||||
continue;
|
||||
if ((nnext = nchild->head->child) == NULL)
|
||||
continue;
|
||||
if (nnext->type == ROFFT_BLOCK)
|
||||
nnext = nnext->body->child;
|
||||
if (nnext == NULL || nnext->tok != MDOC_Er)
|
||||
continue;
|
||||
nnext = nnext->child;
|
||||
if (prev_Er != NULL) {
|
||||
order = strcmp(prev_Er, nnext->string);
|
||||
if (order > 0)
|
||||
mandoc_vmsg(MANDOCERR_ER_ORDER,
|
||||
mdoc->parse, nnext->line, nnext->pos,
|
||||
"Er %s %s", prev_Er, nnext->string);
|
||||
else if (order == 0)
|
||||
mandoc_vmsg(MANDOCERR_ER_REP,
|
||||
mdoc->parse, nnext->line, nnext->pos,
|
||||
"Er %s", prev_Er);
|
||||
}
|
||||
prev_Er = nnext->string;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1565,7 +1653,7 @@ post_sm(POST_ARGS)
|
||||
|
||||
mandoc_vmsg(MANDOCERR_SM_BAD,
|
||||
mdoc->parse, nch->line, nch->pos,
|
||||
"%s %s", mdoc_macronames[mdoc->last->tok], nch->string);
|
||||
"%s %s", roff_name[mdoc->last->tok], nch->string);
|
||||
mdoc_node_relink(mdoc, nch);
|
||||
return;
|
||||
}
|
||||
@ -1608,7 +1696,7 @@ post_root(POST_ARGS)
|
||||
mandoc_msg(MANDOCERR_DOC_EMPTY, mdoc->parse, 0, 0, NULL);
|
||||
else if (n->tok != MDOC_Sh)
|
||||
mandoc_msg(MANDOCERR_SEC_BEFORE, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1642,9 +1730,8 @@ post_rs(POST_ARGS)
|
||||
break;
|
||||
|
||||
if (i == RSORD_MAX) {
|
||||
mandoc_msg(MANDOCERR_RS_BAD,
|
||||
mdoc->parse, nch->line, nch->pos,
|
||||
mdoc_macronames[nch->tok]);
|
||||
mandoc_msg(MANDOCERR_RS_BAD, mdoc->parse,
|
||||
nch->line, nch->pos, roff_name[nch->tok]);
|
||||
i = -1;
|
||||
} else if (nch->tok == MDOC__J || nch->tok == MDOC__B)
|
||||
np->norm->Rs.quote_T++;
|
||||
@ -1797,7 +1884,7 @@ post_sh_name(POST_ARGS)
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
mandoc_msg(MANDOCERR_NAMESEC_BAD, mdoc->parse,
|
||||
n->line, n->pos, mdoc_macronames[n->tok]);
|
||||
n->line, n->pos, roff_name[n->tok]);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -1867,7 +1954,7 @@ post_sh_see_also(POST_ARGS)
|
||||
if (isalpha((const unsigned char)*name))
|
||||
return;
|
||||
lastpunct = n->string;
|
||||
if (n->next == NULL)
|
||||
if (n->next == NULL || n->next->tok == MDOC_Rs)
|
||||
mandoc_vmsg(MANDOCERR_XR_PUNCT, mdoc->parse,
|
||||
n->line, n->pos, "%s after %s(%s)",
|
||||
lastpunct, lastname, lastsec);
|
||||
@ -1918,7 +2005,7 @@ post_sh_head(POST_ARGS)
|
||||
sec != SEC_CUSTOM ? secnames[sec] :
|
||||
(nch = mdoc->last->child) == NULL ? "" :
|
||||
nch->type == ROFFT_TEXT ? nch->string :
|
||||
mdoc_macronames[nch->tok]);
|
||||
roff_name[nch->tok]);
|
||||
|
||||
/* The SYNOPSIS gets special attention in other areas. */
|
||||
|
||||
@ -2014,6 +2101,9 @@ post_ignpar(POST_ARGS)
|
||||
struct roff_node *np;
|
||||
|
||||
switch (mdoc->last->type) {
|
||||
case ROFFT_BLOCK:
|
||||
post_prevpar(mdoc);
|
||||
return;
|
||||
case ROFFT_HEAD:
|
||||
post_hyph(mdoc);
|
||||
return;
|
||||
@ -2027,8 +2117,8 @@ post_ignpar(POST_ARGS)
|
||||
if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) {
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP,
|
||||
mdoc->parse, np->line, np->pos,
|
||||
"%s after %s", mdoc_macronames[np->tok],
|
||||
mdoc_macronames[mdoc->last->tok]);
|
||||
"%s after %s", roff_name[np->tok],
|
||||
roff_name[mdoc->last->tok]);
|
||||
roff_node_delete(mdoc, np);
|
||||
}
|
||||
|
||||
@ -2036,8 +2126,8 @@ post_ignpar(POST_ARGS)
|
||||
if (np->tok == MDOC_Pp || np->tok == MDOC_Lp) {
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse,
|
||||
np->line, np->pos, "%s at the end of %s",
|
||||
mdoc_macronames[np->tok],
|
||||
mdoc_macronames[mdoc->last->tok]);
|
||||
roff_name[np->tok],
|
||||
roff_name[mdoc->last->tok]);
|
||||
roff_node_delete(mdoc, np);
|
||||
}
|
||||
}
|
||||
@ -2060,7 +2150,7 @@ post_prevpar(POST_ARGS)
|
||||
|
||||
if (n->prev->tok != MDOC_Pp &&
|
||||
n->prev->tok != MDOC_Lp &&
|
||||
n->prev->tok != MDOC_br)
|
||||
n->prev->tok != ROFF_br)
|
||||
return;
|
||||
if (n->tok == MDOC_Bl && n->norm->Bl.comp)
|
||||
return;
|
||||
@ -2070,9 +2160,8 @@ post_prevpar(POST_ARGS)
|
||||
return;
|
||||
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse,
|
||||
n->prev->line, n->prev->pos,
|
||||
"%s before %s", mdoc_macronames[n->prev->tok],
|
||||
mdoc_macronames[n->tok]);
|
||||
n->prev->line, n->prev->pos, "%s before %s",
|
||||
roff_name[n->prev->tok], roff_name[n->tok]);
|
||||
roff_node_delete(mdoc, n->prev);
|
||||
}
|
||||
|
||||
@ -2082,10 +2171,10 @@ post_par(POST_ARGS)
|
||||
struct roff_node *np;
|
||||
|
||||
np = mdoc->last;
|
||||
if (np->tok != MDOC_br && np->tok != MDOC_sp)
|
||||
if (np->tok != ROFF_br && np->tok != ROFF_sp)
|
||||
post_prevpar(mdoc);
|
||||
|
||||
if (np->tok == MDOC_sp) {
|
||||
if (np->tok == ROFF_sp) {
|
||||
if (np->child != NULL && np->child->next != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_EXCESS, mdoc->parse,
|
||||
np->child->next->line, np->child->next->pos,
|
||||
@ -2093,21 +2182,20 @@ post_par(POST_ARGS)
|
||||
} else if (np->child != NULL)
|
||||
mandoc_vmsg(MANDOCERR_ARG_SKIP,
|
||||
mdoc->parse, np->line, np->pos, "%s %s",
|
||||
mdoc_macronames[np->tok], np->child->string);
|
||||
roff_name[np->tok], np->child->string);
|
||||
|
||||
if ((np = mdoc->last->prev) == NULL) {
|
||||
np = mdoc->last->parent;
|
||||
if (np->tok != MDOC_Sh && np->tok != MDOC_Ss)
|
||||
return;
|
||||
} else if (np->tok != MDOC_Pp && np->tok != MDOC_Lp &&
|
||||
(mdoc->last->tok != MDOC_br ||
|
||||
(np->tok != MDOC_sp && np->tok != MDOC_br)))
|
||||
(mdoc->last->tok != ROFF_br ||
|
||||
(np->tok != ROFF_sp && np->tok != ROFF_br)))
|
||||
return;
|
||||
|
||||
mandoc_vmsg(MANDOCERR_PAR_SKIP, mdoc->parse,
|
||||
mdoc->last->line, mdoc->last->pos,
|
||||
"%s after %s", mdoc_macronames[mdoc->last->tok],
|
||||
mdoc_macronames[np->tok]);
|
||||
mdoc->last->line, mdoc->last->pos, "%s after %s",
|
||||
roff_name[mdoc->last->tok], roff_name[np->tok]);
|
||||
roff_node_delete(mdoc, mdoc->last);
|
||||
}
|
||||
|
||||
@ -2251,11 +2339,19 @@ static void
|
||||
post_bx(POST_ARGS)
|
||||
{
|
||||
struct roff_node *n, *nch;
|
||||
const char *macro;
|
||||
|
||||
n = mdoc->last;
|
||||
nch = n->child;
|
||||
|
||||
if (nch != NULL) {
|
||||
macro = !strcmp(nch->string, "Open") ? "Ox" :
|
||||
!strcmp(nch->string, "Net") ? "Nx" :
|
||||
!strcmp(nch->string, "Free") ? "Fx" :
|
||||
!strcmp(nch->string, "DragonFly") ? "Dx" : NULL;
|
||||
if (macro != NULL)
|
||||
mandoc_msg(MANDOCERR_BX, mdoc->parse,
|
||||
n->line, n->pos, macro);
|
||||
mdoc->last = nch;
|
||||
nch = nch->next;
|
||||
mdoc->next = ROFF_NEXT_SIBLING;
|
||||
@ -2322,11 +2418,11 @@ post_os(POST_ARGS)
|
||||
mdoc->meta.os = NULL;
|
||||
deroff(&mdoc->meta.os, n);
|
||||
if (mdoc->meta.os)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
if (mdoc->defos) {
|
||||
mdoc->meta.os = mandoc_strdup(mdoc->defos);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef OSNAME
|
||||
@ -2343,6 +2439,10 @@ post_os(POST_ARGS)
|
||||
}
|
||||
mdoc->meta.os = mandoc_strdup(defbuf);
|
||||
#endif /*!OSNAME*/
|
||||
|
||||
out: mdoc->meta.os_e = strstr(mdoc->meta.os, "OpenBSD") != NULL ?
|
||||
MDOC_OS_OPENBSD : strstr(mdoc->meta.os, "NetBSD") != NULL ?
|
||||
MDOC_OS_NETBSD : MDOC_OS_OTHER;
|
||||
}
|
||||
|
||||
enum roff_sec
|
||||
@ -2358,7 +2458,7 @@ mdoc_a2sec(const char *p)
|
||||
}
|
||||
|
||||
static size_t
|
||||
macro2len(int macro)
|
||||
macro2len(enum roff_tok macro)
|
||||
{
|
||||
|
||||
switch (macro) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: out.c,v 1.62 2015/10/12 00:08:16 schwarze Exp $ */
|
||||
/* $Id: out.c,v 1.65 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -29,9 +29,10 @@
|
||||
#include "out.h"
|
||||
|
||||
static void tblcalc_data(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl_opts *, const struct tbl_dat *);
|
||||
const struct tbl_opts *, const struct tbl_dat *,
|
||||
size_t);
|
||||
static void tblcalc_literal(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl_dat *);
|
||||
const struct tbl_dat *, size_t);
|
||||
static void tblcalc_number(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl_opts *, const struct tbl_dat *);
|
||||
|
||||
@ -40,10 +41,10 @@ static void tblcalc_number(struct rofftbl *, struct roffcol *,
|
||||
* Parse the *src string and store a scaling unit into *dst.
|
||||
* If the string doesn't specify the unit, use the default.
|
||||
* If no default is specified, fail.
|
||||
* Return 2 on complete success, 1 when a conversion was done,
|
||||
* but there was trailing garbage, and 0 on total failure.
|
||||
* Return a pointer to the byte after the last byte used,
|
||||
* or NULL on total failure.
|
||||
*/
|
||||
int
|
||||
const char *
|
||||
a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
{
|
||||
char *endptr;
|
||||
@ -51,7 +52,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
dst->unit = def == SCALE_MAX ? SCALE_BU : def;
|
||||
dst->scale = strtod(src, &endptr);
|
||||
if (endptr == src)
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
switch (*endptr++) {
|
||||
case 'c':
|
||||
@ -89,12 +90,11 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (SCALE_MAX == def)
|
||||
return 0;
|
||||
return NULL;
|
||||
dst->unit = def;
|
||||
break;
|
||||
}
|
||||
|
||||
return *endptr == '\0' ? 2 : 1;
|
||||
return endptr;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -107,6 +107,7 @@ void
|
||||
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
size_t totalwidth)
|
||||
{
|
||||
struct roffsu su;
|
||||
const struct tbl_opts *opts;
|
||||
const struct tbl_dat *dp;
|
||||
struct roffcol *col;
|
||||
@ -147,7 +148,16 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
col->flags |= dp->layout->flags;
|
||||
if (dp->layout->flags & TBL_CELL_WIGN)
|
||||
continue;
|
||||
tblcalc_data(tbl, col, opts, dp);
|
||||
if (dp->layout->wstr != NULL &&
|
||||
dp->layout->width == 0 &&
|
||||
a2roffsu(dp->layout->wstr, &su, SCALE_EN)
|
||||
!= NULL)
|
||||
dp->layout->width =
|
||||
(*tbl->sulen)(&su, tbl->arg);
|
||||
if (col->width < dp->layout->width)
|
||||
col->width = dp->layout->width;
|
||||
tblcalc_data(tbl, col, opts, dp, dp->block ?
|
||||
totalwidth / (sp->opts->cols + 1) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,9 +207,12 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
*/
|
||||
|
||||
if (nxcol && totalwidth) {
|
||||
xwidth = totalwidth - xwidth - 3*maxcol -
|
||||
xwidth += 3*maxcol +
|
||||
(opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ?
|
||||
2 : !!opts->lvert + !!opts->rvert);
|
||||
if (xwidth >= totalwidth)
|
||||
return;
|
||||
xwidth = totalwidth - xwidth;
|
||||
|
||||
/*
|
||||
* Emulate a bug in GNU tbl width calculation that
|
||||
@ -232,7 +245,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
|
||||
|
||||
static void
|
||||
tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl_opts *opts, const struct tbl_dat *dp)
|
||||
const struct tbl_opts *opts, const struct tbl_dat *dp, size_t mw)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
@ -249,7 +262,7 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
case TBL_CELL_CENTRE:
|
||||
case TBL_CELL_LEFT:
|
||||
case TBL_CELL_RIGHT:
|
||||
tblcalc_literal(tbl, col, dp);
|
||||
tblcalc_literal(tbl, col, dp, mw);
|
||||
break;
|
||||
case TBL_CELL_NUMBER:
|
||||
tblcalc_number(tbl, col, opts, dp);
|
||||
@ -263,16 +276,29 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
|
||||
static void
|
||||
tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl_dat *dp)
|
||||
const struct tbl_dat *dp, size_t mw)
|
||||
{
|
||||
size_t sz;
|
||||
const char *str;
|
||||
const char *str; /* Beginning of the first line. */
|
||||
const char *beg; /* Beginning of the current line. */
|
||||
char *end; /* End of the current line. */
|
||||
size_t sz; /* Length of the current line. */
|
||||
|
||||
str = dp->string ? dp->string : "";
|
||||
sz = (*tbl->slen)(str, tbl->arg);
|
||||
|
||||
if (col->width < sz)
|
||||
col->width = sz;
|
||||
if (dp->string == NULL || *dp->string == '\0')
|
||||
return;
|
||||
str = mw ? mandoc_strdup(dp->string) : dp->string;
|
||||
for (beg = str; beg != NULL && *beg != '\0'; beg = end) {
|
||||
end = mw ? strchr(beg, ' ') : NULL;
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
while (*end == ' ')
|
||||
end++;
|
||||
}
|
||||
sz = (*tbl->slen)(beg, tbl->arg);
|
||||
if (col->width < sz)
|
||||
col->width = sz;
|
||||
}
|
||||
if (mw)
|
||||
free((void *)str);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* $Id: out.h,v 1.27 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: out.h,v 1.29 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -40,14 +41,16 @@ struct roffsu {
|
||||
double scale;
|
||||
};
|
||||
|
||||
typedef size_t (*tbl_sulen)(const struct roffsu *, void *);
|
||||
typedef size_t (*tbl_strlen)(const char *, void *);
|
||||
typedef size_t (*tbl_len)(size_t, void *);
|
||||
|
||||
struct rofftbl {
|
||||
tbl_sulen sulen; /* calculate scaling unit length */
|
||||
tbl_strlen slen; /* calculate string length */
|
||||
tbl_len len; /* produce width of empty space */
|
||||
struct roffcol *cols; /* master column specifiers */
|
||||
void *arg; /* passed to slen and len */
|
||||
void *arg; /* passed to sulen, slen, and len */
|
||||
};
|
||||
|
||||
#define SCALE_VS_INIT(p, v) \
|
||||
@ -63,6 +66,6 @@ struct rofftbl {
|
||||
|
||||
struct tbl_span;
|
||||
|
||||
int a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||
const char *a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||
void tblcalc(struct rofftbl *tbl,
|
||||
const struct tbl_span *, size_t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: read.c,v 1.161 2017/02/18 17:29:28 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.173 2017/06/08 00:23:30 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -66,7 +66,7 @@ struct mparse {
|
||||
|
||||
static void choose_parser(struct mparse *);
|
||||
static void resize_buf(struct buf *, size_t);
|
||||
static void mparse_buf_r(struct mparse *, struct buf, size_t, int);
|
||||
static int mparse_buf_r(struct mparse *, struct buf, size_t, int);
|
||||
static int read_whole_file(struct mparse *, const char *, int,
|
||||
struct buf *, int *);
|
||||
static void mparse_end(struct mparse *);
|
||||
@ -75,7 +75,7 @@ static void mparse_parse_buffer(struct mparse *, struct buf,
|
||||
|
||||
static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = {
|
||||
MANDOCERR_OK,
|
||||
MANDOCERR_WARNING,
|
||||
MANDOCERR_STYLE,
|
||||
MANDOCERR_WARNING,
|
||||
MANDOCERR_ERROR,
|
||||
MANDOCERR_UNSUPP,
|
||||
@ -86,6 +86,14 @@ static const enum mandocerr mandoclimits[MANDOCLEVEL_MAX] = {
|
||||
static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"ok",
|
||||
|
||||
"generic style suggestion",
|
||||
|
||||
"useless macro",
|
||||
"consider using OS macro",
|
||||
"errnos out of order",
|
||||
"duplicate errno",
|
||||
"description line ends with a full stop",
|
||||
|
||||
"generic warning",
|
||||
|
||||
/* related to the prologue */
|
||||
@ -113,6 +121,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"bad NAME section content",
|
||||
"missing comma before name",
|
||||
"missing description line, using \"\"",
|
||||
"description line outside NAME section",
|
||||
"sections out of conventional order",
|
||||
"duplicate section title",
|
||||
"unexpected section",
|
||||
@ -132,6 +141,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"fill mode already enabled, skipping",
|
||||
"fill mode already disabled, skipping",
|
||||
"line scope broken",
|
||||
"skipping blank line in line scope",
|
||||
|
||||
/* related to missing macro arguments */
|
||||
"skipping empty request",
|
||||
@ -167,6 +177,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"unknown AT&T UNIX version",
|
||||
"comma in function argument",
|
||||
"parenthesis in function name",
|
||||
"unknown library name",
|
||||
"invalid content in Rs block",
|
||||
"invalid Boolean argument",
|
||||
"unknown font, skipping request",
|
||||
@ -219,6 +230,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
"NOT IMPLEMENTED: Bd -file",
|
||||
"skipping display without arguments",
|
||||
"missing list type, using -item",
|
||||
"argument is not numeric, using 1",
|
||||
"missing manual name, using \"\"",
|
||||
"uname(3) system call failed, using UNKNOWN",
|
||||
"unknown standard specifier",
|
||||
@ -240,7 +252,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
|
||||
|
||||
static const char * const mandoclevels[MANDOCLEVEL_MAX] = {
|
||||
"SUCCESS",
|
||||
"RESERVED",
|
||||
"STYLE",
|
||||
"WARNING",
|
||||
"ERROR",
|
||||
"UNSUPP",
|
||||
@ -292,14 +304,15 @@ choose_parser(struct mparse *curp)
|
||||
}
|
||||
|
||||
if (format == MPARSE_MDOC) {
|
||||
mdoc_hash_init();
|
||||
curp->man->macroset = MACROSET_MDOC;
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
if (curp->man->mdocmac == NULL)
|
||||
curp->man->mdocmac = roffhash_alloc(MDOC_Dd, MDOC_MAX);
|
||||
} else {
|
||||
man_hash_init();
|
||||
curp->man->macroset = MACROSET_MAN;
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
if (curp->man->manmac == NULL)
|
||||
curp->man->manmac = roffhash_alloc(MAN_TH, MAN_MAX);
|
||||
}
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -309,7 +322,7 @@ choose_parser(struct mparse *curp)
|
||||
* macros, inline equations, and input line traps)
|
||||
* and indirectly (for .so file inclusion).
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
{
|
||||
const struct tbl_span *span;
|
||||
@ -317,7 +330,6 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
const char *save_file;
|
||||
char *cp;
|
||||
size_t pos; /* byte number in the ln buffer */
|
||||
size_t j; /* auxiliary byte number in the blk buffer */
|
||||
enum rofferr rr;
|
||||
int of;
|
||||
int lnn; /* line number in the real file */
|
||||
@ -399,79 +411,14 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Trailing backslash = a plain char. */
|
||||
|
||||
if (blk.buf[i] != '\\' || i + 1 == blk.sz) {
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Found escape and at least one other character.
|
||||
* When it's a newline character, skip it.
|
||||
* When there is a carriage return in between,
|
||||
* skip that one as well.
|
||||
*/
|
||||
|
||||
if ('\r' == blk.buf[i + 1] && i + 2 < blk.sz &&
|
||||
'\n' == blk.buf[i + 2])
|
||||
++i;
|
||||
if ('\n' == blk.buf[i + 1]) {
|
||||
i += 2;
|
||||
++lnn;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('"' == blk.buf[i + 1] || '#' == blk.buf[i + 1]) {
|
||||
j = i;
|
||||
i += 2;
|
||||
/* Comment, skip to end of line */
|
||||
for (; i < blk.sz; ++i) {
|
||||
if (blk.buf[i] != '\n')
|
||||
continue;
|
||||
if (blk.buf[i - 1] == ' ' ||
|
||||
blk.buf[i - 1] == '\t')
|
||||
mandoc_msg(
|
||||
MANDOCERR_SPACE_EOL,
|
||||
curp, curp->line,
|
||||
pos + i-1 - j, NULL);
|
||||
++i;
|
||||
++lnn;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Backout trailing whitespaces */
|
||||
for (; pos > 0; --pos) {
|
||||
if (ln.buf[pos - 1] != ' ')
|
||||
break;
|
||||
if (pos > 2 && ln.buf[pos - 2] == '\\')
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Catch escaped bogus characters. */
|
||||
|
||||
c = (unsigned char) blk.buf[i+1];
|
||||
|
||||
if ( ! (isascii(c) &&
|
||||
(isgraph(c) || isblank(c)))) {
|
||||
mandoc_vmsg(MANDOCERR_CHAR_BAD, curp,
|
||||
curp->line, pos, "0x%x", c);
|
||||
i += 2;
|
||||
ln.buf[pos++] = '?';
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Some other escape sequence, copy & cont. */
|
||||
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
ln.buf[pos++] = blk.buf[i++];
|
||||
}
|
||||
|
||||
if (pos >= ln.sz)
|
||||
if (pos + 1 >= ln.sz)
|
||||
resize_buf(&ln, 256);
|
||||
|
||||
if (i == blk.sz || blk.buf[i] == '\0')
|
||||
ln.buf[pos++] = '\n';
|
||||
ln.buf[pos] = '\0';
|
||||
|
||||
/*
|
||||
@ -510,13 +457,16 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
|
||||
switch (rr) {
|
||||
case ROFF_REPARSE:
|
||||
if (REPARSE_LIMIT >= ++curp->reparse_count)
|
||||
mparse_buf_r(curp, ln, of, 0);
|
||||
else
|
||||
if (++curp->reparse_count > REPARSE_LIMIT)
|
||||
mandoc_msg(MANDOCERR_ROFFLOOP, curp,
|
||||
curp->line, pos, NULL);
|
||||
pos = 0;
|
||||
continue;
|
||||
else if (mparse_buf_r(curp, ln, of, 0) == 1 ||
|
||||
start == 1) {
|
||||
pos = 0;
|
||||
continue;
|
||||
}
|
||||
free(ln.buf);
|
||||
return 0;
|
||||
case ROFF_APPEND:
|
||||
pos = strlen(ln.buf);
|
||||
continue;
|
||||
@ -530,7 +480,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
(i >= blk.sz || blk.buf[i] == '\0')) {
|
||||
curp->sodest = mandoc_strdup(ln.buf + of);
|
||||
free(ln.buf);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* We remove `so' clauses from our lookaside
|
||||
@ -596,6 +546,7 @@ mparse_buf_r(struct mparse *curp, struct buf blk, size_t i, int start)
|
||||
}
|
||||
|
||||
free(ln.buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -813,11 +764,13 @@ mparse_alloc(int options, enum mandoclevel wlevel, mandocmsg mmsg,
|
||||
curp->man = roff_man_alloc( curp->roff, curp, curp->defos,
|
||||
curp->options & MPARSE_QUICK ? 1 : 0);
|
||||
if (curp->options & MPARSE_MDOC) {
|
||||
mdoc_hash_init();
|
||||
curp->man->macroset = MACROSET_MDOC;
|
||||
if (curp->man->mdocmac == NULL)
|
||||
curp->man->mdocmac = roffhash_alloc(MDOC_Dd, MDOC_MAX);
|
||||
} else if (curp->options & MPARSE_MAN) {
|
||||
man_hash_init();
|
||||
curp->man->macroset = MACROSET_MAN;
|
||||
if (curp->man->manmac == NULL)
|
||||
curp->man->manmac = roffhash_alloc(MAN_TH, MAN_MAX);
|
||||
}
|
||||
curp->man->first->tok = TOKEN_NONE;
|
||||
return curp;
|
||||
@ -843,6 +796,8 @@ void
|
||||
mparse_free(struct mparse *curp)
|
||||
{
|
||||
|
||||
roffhash_free(curp->man->mdocmac);
|
||||
roffhash_free(curp->man->manmac);
|
||||
roff_man_free(curp->man);
|
||||
roff_free(curp->roff);
|
||||
if (curp->secondary)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $Id: roff.h,v 1.40 2017/02/16 03:00:23 schwarze Exp $ */
|
||||
/* $Id: roff.h,v 1.52 2017/06/07 23:29:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -16,6 +16,7 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct ohash;
|
||||
struct mdoc_arg;
|
||||
union mdoc_data;
|
||||
|
||||
@ -25,6 +26,12 @@ enum roff_macroset {
|
||||
MACROSET_MAN
|
||||
};
|
||||
|
||||
enum mdoc_os {
|
||||
MDOC_OS_OTHER = 0,
|
||||
MDOC_OS_NETBSD,
|
||||
MDOC_OS_OPENBSD
|
||||
};
|
||||
|
||||
enum roff_sec {
|
||||
SEC_NONE = 0,
|
||||
SEC_NAME,
|
||||
@ -64,6 +71,411 @@ enum roff_type {
|
||||
ROFFT_EQN
|
||||
};
|
||||
|
||||
enum roff_tok {
|
||||
ROFF_br = 0,
|
||||
ROFF_ce,
|
||||
ROFF_ft,
|
||||
ROFF_ll,
|
||||
ROFF_mc,
|
||||
ROFF_sp,
|
||||
ROFF_ta,
|
||||
ROFF_ti,
|
||||
ROFF_MAX,
|
||||
ROFF_ab,
|
||||
ROFF_ad,
|
||||
ROFF_af,
|
||||
ROFF_aln,
|
||||
ROFF_als,
|
||||
ROFF_am,
|
||||
ROFF_am1,
|
||||
ROFF_ami,
|
||||
ROFF_ami1,
|
||||
ROFF_as,
|
||||
ROFF_as1,
|
||||
ROFF_asciify,
|
||||
ROFF_backtrace,
|
||||
ROFF_bd,
|
||||
ROFF_bleedat,
|
||||
ROFF_blm,
|
||||
ROFF_box,
|
||||
ROFF_boxa,
|
||||
ROFF_bp,
|
||||
ROFF_BP,
|
||||
ROFF_break,
|
||||
ROFF_breakchar,
|
||||
ROFF_brnl,
|
||||
ROFF_brp,
|
||||
ROFF_brpnl,
|
||||
ROFF_c2,
|
||||
ROFF_cc,
|
||||
ROFF_cf,
|
||||
ROFF_cflags,
|
||||
ROFF_ch,
|
||||
ROFF_char,
|
||||
ROFF_chop,
|
||||
ROFF_class,
|
||||
ROFF_close,
|
||||
ROFF_CL,
|
||||
ROFF_color,
|
||||
ROFF_composite,
|
||||
ROFF_continue,
|
||||
ROFF_cp,
|
||||
ROFF_cropat,
|
||||
ROFF_cs,
|
||||
ROFF_cu,
|
||||
ROFF_da,
|
||||
ROFF_dch,
|
||||
ROFF_Dd,
|
||||
ROFF_de,
|
||||
ROFF_de1,
|
||||
ROFF_defcolor,
|
||||
ROFF_dei,
|
||||
ROFF_dei1,
|
||||
ROFF_device,
|
||||
ROFF_devicem,
|
||||
ROFF_di,
|
||||
ROFF_do,
|
||||
ROFF_ds,
|
||||
ROFF_ds1,
|
||||
ROFF_dwh,
|
||||
ROFF_dt,
|
||||
ROFF_ec,
|
||||
ROFF_ecr,
|
||||
ROFF_ecs,
|
||||
ROFF_el,
|
||||
ROFF_em,
|
||||
ROFF_EN,
|
||||
ROFF_eo,
|
||||
ROFF_EP,
|
||||
ROFF_EQ,
|
||||
ROFF_errprint,
|
||||
ROFF_ev,
|
||||
ROFF_evc,
|
||||
ROFF_ex,
|
||||
ROFF_fallback,
|
||||
ROFF_fam,
|
||||
ROFF_fc,
|
||||
ROFF_fchar,
|
||||
ROFF_fcolor,
|
||||
ROFF_fdeferlig,
|
||||
ROFF_feature,
|
||||
/* MAN_fi; ignored in mdoc(7) */
|
||||
ROFF_fkern,
|
||||
ROFF_fl,
|
||||
ROFF_flig,
|
||||
ROFF_fp,
|
||||
ROFF_fps,
|
||||
ROFF_fschar,
|
||||
ROFF_fspacewidth,
|
||||
ROFF_fspecial,
|
||||
ROFF_ftr,
|
||||
ROFF_fzoom,
|
||||
ROFF_gcolor,
|
||||
ROFF_hc,
|
||||
ROFF_hcode,
|
||||
ROFF_hidechar,
|
||||
ROFF_hla,
|
||||
ROFF_hlm,
|
||||
ROFF_hpf,
|
||||
ROFF_hpfa,
|
||||
ROFF_hpfcode,
|
||||
ROFF_hw,
|
||||
ROFF_hy,
|
||||
ROFF_hylang,
|
||||
ROFF_hylen,
|
||||
ROFF_hym,
|
||||
ROFF_hypp,
|
||||
ROFF_hys,
|
||||
ROFF_ie,
|
||||
ROFF_if,
|
||||
ROFF_ig,
|
||||
/* MAN_in; ignored in mdoc(7) */
|
||||
ROFF_index,
|
||||
ROFF_it,
|
||||
ROFF_itc,
|
||||
ROFF_IX,
|
||||
ROFF_kern,
|
||||
ROFF_kernafter,
|
||||
ROFF_kernbefore,
|
||||
ROFF_kernpair,
|
||||
ROFF_lc,
|
||||
ROFF_lc_ctype,
|
||||
ROFF_lds,
|
||||
ROFF_length,
|
||||
ROFF_letadj,
|
||||
ROFF_lf,
|
||||
ROFF_lg,
|
||||
ROFF_lhang,
|
||||
ROFF_linetabs,
|
||||
ROFF_lnr,
|
||||
ROFF_lnrf,
|
||||
ROFF_lpfx,
|
||||
ROFF_ls,
|
||||
ROFF_lsm,
|
||||
ROFF_lt,
|
||||
ROFF_mediasize,
|
||||
ROFF_minss,
|
||||
ROFF_mk,
|
||||
ROFF_mso,
|
||||
ROFF_na,
|
||||
ROFF_ne,
|
||||
/* MAN_nf; ignored in mdoc(7) */
|
||||
ROFF_nh,
|
||||
ROFF_nhychar,
|
||||
ROFF_nm,
|
||||
ROFF_nn,
|
||||
ROFF_nop,
|
||||
ROFF_nr,
|
||||
ROFF_nrf,
|
||||
ROFF_nroff,
|
||||
ROFF_ns,
|
||||
ROFF_nx,
|
||||
ROFF_open,
|
||||
ROFF_opena,
|
||||
ROFF_os,
|
||||
ROFF_output,
|
||||
ROFF_padj,
|
||||
ROFF_papersize,
|
||||
ROFF_pc,
|
||||
ROFF_pev,
|
||||
ROFF_pi,
|
||||
ROFF_PI,
|
||||
ROFF_pl,
|
||||
ROFF_pm,
|
||||
ROFF_pn,
|
||||
ROFF_pnr,
|
||||
ROFF_po,
|
||||
ROFF_ps,
|
||||
ROFF_psbb,
|
||||
ROFF_pshape,
|
||||
ROFF_pso,
|
||||
ROFF_ptr,
|
||||
ROFF_pvs,
|
||||
ROFF_rchar,
|
||||
ROFF_rd,
|
||||
ROFF_recursionlimit,
|
||||
ROFF_return,
|
||||
ROFF_rfschar,
|
||||
ROFF_rhang,
|
||||
ROFF_rj,
|
||||
ROFF_rm,
|
||||
ROFF_rn,
|
||||
ROFF_rnn,
|
||||
ROFF_rr,
|
||||
ROFF_rs,
|
||||
ROFF_rt,
|
||||
ROFF_schar,
|
||||
ROFF_sentchar,
|
||||
ROFF_shc,
|
||||
ROFF_shift,
|
||||
ROFF_sizes,
|
||||
ROFF_so,
|
||||
ROFF_spacewidth,
|
||||
ROFF_special,
|
||||
ROFF_spreadwarn,
|
||||
ROFF_ss,
|
||||
ROFF_sty,
|
||||
ROFF_substring,
|
||||
ROFF_sv,
|
||||
ROFF_sy,
|
||||
ROFF_T_,
|
||||
ROFF_tc,
|
||||
ROFF_TE,
|
||||
ROFF_TH,
|
||||
ROFF_tkf,
|
||||
ROFF_tl,
|
||||
ROFF_tm,
|
||||
ROFF_tm1,
|
||||
ROFF_tmc,
|
||||
ROFF_tr,
|
||||
ROFF_track,
|
||||
ROFF_transchar,
|
||||
ROFF_trf,
|
||||
ROFF_trimat,
|
||||
ROFF_trin,
|
||||
ROFF_trnt,
|
||||
ROFF_troff,
|
||||
ROFF_TS,
|
||||
ROFF_uf,
|
||||
ROFF_ul,
|
||||
ROFF_unformat,
|
||||
ROFF_unwatch,
|
||||
ROFF_unwatchn,
|
||||
ROFF_vpt,
|
||||
ROFF_vs,
|
||||
ROFF_warn,
|
||||
ROFF_warnscale,
|
||||
ROFF_watch,
|
||||
ROFF_watchlength,
|
||||
ROFF_watchn,
|
||||
ROFF_wh,
|
||||
ROFF_while,
|
||||
ROFF_write,
|
||||
ROFF_writec,
|
||||
ROFF_writem,
|
||||
ROFF_xflag,
|
||||
ROFF_cblock,
|
||||
ROFF_RENAMED,
|
||||
ROFF_USERDEF,
|
||||
TOKEN_NONE,
|
||||
MDOC_Dd,
|
||||
MDOC_Dt,
|
||||
MDOC_Os,
|
||||
MDOC_Sh,
|
||||
MDOC_Ss,
|
||||
MDOC_Pp,
|
||||
MDOC_D1,
|
||||
MDOC_Dl,
|
||||
MDOC_Bd,
|
||||
MDOC_Ed,
|
||||
MDOC_Bl,
|
||||
MDOC_El,
|
||||
MDOC_It,
|
||||
MDOC_Ad,
|
||||
MDOC_An,
|
||||
MDOC_Ap,
|
||||
MDOC_Ar,
|
||||
MDOC_Cd,
|
||||
MDOC_Cm,
|
||||
MDOC_Dv,
|
||||
MDOC_Er,
|
||||
MDOC_Ev,
|
||||
MDOC_Ex,
|
||||
MDOC_Fa,
|
||||
MDOC_Fd,
|
||||
MDOC_Fl,
|
||||
MDOC_Fn,
|
||||
MDOC_Ft,
|
||||
MDOC_Ic,
|
||||
MDOC_In,
|
||||
MDOC_Li,
|
||||
MDOC_Nd,
|
||||
MDOC_Nm,
|
||||
MDOC_Op,
|
||||
MDOC_Ot,
|
||||
MDOC_Pa,
|
||||
MDOC_Rv,
|
||||
MDOC_St,
|
||||
MDOC_Va,
|
||||
MDOC_Vt,
|
||||
MDOC_Xr,
|
||||
MDOC__A,
|
||||
MDOC__B,
|
||||
MDOC__D,
|
||||
MDOC__I,
|
||||
MDOC__J,
|
||||
MDOC__N,
|
||||
MDOC__O,
|
||||
MDOC__P,
|
||||
MDOC__R,
|
||||
MDOC__T,
|
||||
MDOC__V,
|
||||
MDOC_Ac,
|
||||
MDOC_Ao,
|
||||
MDOC_Aq,
|
||||
MDOC_At,
|
||||
MDOC_Bc,
|
||||
MDOC_Bf,
|
||||
MDOC_Bo,
|
||||
MDOC_Bq,
|
||||
MDOC_Bsx,
|
||||
MDOC_Bx,
|
||||
MDOC_Db,
|
||||
MDOC_Dc,
|
||||
MDOC_Do,
|
||||
MDOC_Dq,
|
||||
MDOC_Ec,
|
||||
MDOC_Ef,
|
||||
MDOC_Em,
|
||||
MDOC_Eo,
|
||||
MDOC_Fx,
|
||||
MDOC_Ms,
|
||||
MDOC_No,
|
||||
MDOC_Ns,
|
||||
MDOC_Nx,
|
||||
MDOC_Ox,
|
||||
MDOC_Pc,
|
||||
MDOC_Pf,
|
||||
MDOC_Po,
|
||||
MDOC_Pq,
|
||||
MDOC_Qc,
|
||||
MDOC_Ql,
|
||||
MDOC_Qo,
|
||||
MDOC_Qq,
|
||||
MDOC_Re,
|
||||
MDOC_Rs,
|
||||
MDOC_Sc,
|
||||
MDOC_So,
|
||||
MDOC_Sq,
|
||||
MDOC_Sm,
|
||||
MDOC_Sx,
|
||||
MDOC_Sy,
|
||||
MDOC_Tn,
|
||||
MDOC_Ux,
|
||||
MDOC_Xc,
|
||||
MDOC_Xo,
|
||||
MDOC_Fo,
|
||||
MDOC_Fc,
|
||||
MDOC_Oo,
|
||||
MDOC_Oc,
|
||||
MDOC_Bk,
|
||||
MDOC_Ek,
|
||||
MDOC_Bt,
|
||||
MDOC_Hf,
|
||||
MDOC_Fr,
|
||||
MDOC_Ud,
|
||||
MDOC_Lb,
|
||||
MDOC_Lp,
|
||||
MDOC_Lk,
|
||||
MDOC_Mt,
|
||||
MDOC_Brq,
|
||||
MDOC_Bro,
|
||||
MDOC_Brc,
|
||||
MDOC__C,
|
||||
MDOC_Es,
|
||||
MDOC_En,
|
||||
MDOC_Dx,
|
||||
MDOC__Q,
|
||||
MDOC__U,
|
||||
MDOC_Ta,
|
||||
MDOC_MAX,
|
||||
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_nf,
|
||||
MAN_fi,
|
||||
MAN_RE,
|
||||
MAN_RS,
|
||||
MAN_DT,
|
||||
MAN_UC,
|
||||
MAN_PD,
|
||||
MAN_AT,
|
||||
MAN_in,
|
||||
MAN_OP,
|
||||
MAN_EX,
|
||||
MAN_EE,
|
||||
MAN_UR,
|
||||
MAN_UE,
|
||||
MAN_MAX
|
||||
};
|
||||
|
||||
enum roff_next {
|
||||
ROFF_NEXT_SIBLING = 0,
|
||||
ROFF_NEXT_CHILD
|
||||
@ -94,8 +506,6 @@ struct roff_node {
|
||||
const struct eqn *eqn; /* EQN */
|
||||
int line; /* Input file line number. */
|
||||
int pos; /* Input file column number. */
|
||||
int tok; /* Request or macro ID. */
|
||||
#define TOKEN_NONE (-1) /* No request or macro. */
|
||||
int flags;
|
||||
#define NODE_VALID (1 << 0) /* Has been validated. */
|
||||
#define NODE_ENDED (1 << 1) /* Gone past body end mark. */
|
||||
@ -109,6 +519,7 @@ struct roff_node {
|
||||
#define NODE_NOPRT (1 << 9) /* Shall not print anything. */
|
||||
int prev_font; /* Before entering this node. */
|
||||
int aux; /* Decoded node data, type-dependent. */
|
||||
enum roff_tok tok; /* Request or macro ID. */
|
||||
enum roff_type type; /* AST node type. */
|
||||
enum roff_sec sec; /* Current named section. */
|
||||
enum mdoc_endbody end; /* BODY */
|
||||
@ -123,12 +534,15 @@ struct roff_meta {
|
||||
char *name; /* Leading manual name. */
|
||||
char *date; /* Normalized date. */
|
||||
int hasbody; /* Document is not empty. */
|
||||
enum mdoc_os os_e; /* Operating system. */
|
||||
};
|
||||
|
||||
struct roff_man {
|
||||
struct roff_meta meta; /* Document meta-data. */
|
||||
struct mparse *parse; /* Parse pointer. */
|
||||
struct roff *roff; /* Roff parser state data. */
|
||||
struct ohash *mdocmac; /* Mdoc macro lookup table. */
|
||||
struct ohash *manmac; /* Man macro lookup table. */
|
||||
const char *defos; /* Default operating system. */
|
||||
struct roff_node *first; /* The first node parsed. */
|
||||
struct roff_node *last; /* The last node parsed. */
|
||||
@ -158,5 +572,11 @@ struct roff_man {
|
||||
enum roff_next next; /* Where to put the next node. */
|
||||
};
|
||||
|
||||
extern const char *const *roff_name;
|
||||
|
||||
|
||||
void deroff(char **, const struct roff_node *);
|
||||
struct ohash *roffhash_alloc(enum roff_tok, enum roff_tok);
|
||||
enum roff_tok roffhash_find(struct ohash *, const char *, size_t);
|
||||
void roffhash_free(struct ohash *);
|
||||
void roff_validate(struct roff_man *);
|
||||
|
93
contrib/mdocml/roff_html.c
Normal file
93
contrib/mdocml/roff_html.c
Normal file
@ -0,0 +1,93 @@
|
||||
/* $Id: roff_html.c,v 1.8 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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 <stddef.h>
|
||||
|
||||
#include "roff.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
|
||||
#define ROFF_HTML_ARGS struct html *h, const struct roff_node *n
|
||||
|
||||
typedef void (*roff_html_pre_fp)(ROFF_HTML_ARGS);
|
||||
|
||||
static void roff_html_pre_br(ROFF_HTML_ARGS);
|
||||
static void roff_html_pre_ce(ROFF_HTML_ARGS);
|
||||
static void roff_html_pre_sp(ROFF_HTML_ARGS);
|
||||
|
||||
static const roff_html_pre_fp roff_html_pre_acts[ROFF_MAX] = {
|
||||
roff_html_pre_br, /* br */
|
||||
roff_html_pre_ce, /* ce */
|
||||
NULL, /* ft */
|
||||
NULL, /* ll */
|
||||
NULL, /* mc */
|
||||
roff_html_pre_sp, /* sp */
|
||||
NULL, /* ta */
|
||||
NULL, /* ti */
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
roff_html_pre(struct html *h, const struct roff_node *n)
|
||||
{
|
||||
assert(n->tok < ROFF_MAX);
|
||||
if (roff_html_pre_acts[n->tok] != NULL)
|
||||
(*roff_html_pre_acts[n->tok])(h, n);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_html_pre_br(ROFF_HTML_ARGS)
|
||||
{
|
||||
struct tag *t;
|
||||
|
||||
t = print_otag(h, TAG_DIV, "");
|
||||
print_text(h, "\\~"); /* So the div isn't empty. */
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_html_pre_ce(ROFF_HTML_ARGS)
|
||||
{
|
||||
for (n = n->child->next; n != NULL; n = n->next) {
|
||||
if (n->type == ROFFT_TEXT) {
|
||||
if (n->flags & NODE_LINE)
|
||||
roff_html_pre_br(h, n);
|
||||
print_text(h, n->string);
|
||||
} else
|
||||
roff_html_pre(h, n);
|
||||
}
|
||||
roff_html_pre_br(h, n);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_html_pre_sp(ROFF_HTML_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
|
||||
SCALE_VS_INIT(&su, 1);
|
||||
if ((n = n->child) != NULL) {
|
||||
if (a2roffsu(n->string, &su, SCALE_VS) == NULL)
|
||||
su.scale = 1.0;
|
||||
else if (su.scale < 0.0)
|
||||
su.scale = 0.0;
|
||||
}
|
||||
print_otag(h, TAG_DIV, "suh", &su);
|
||||
print_text(h, "\\~"); /* So the div isn't empty. */
|
||||
}
|
221
contrib/mdocml/roff_term.c
Normal file
221
contrib/mdocml/roff_term.c
Normal file
@ -0,0 +1,221 @@
|
||||
/* $Id: roff_term.c,v 1.10 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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 <stddef.h>
|
||||
|
||||
#include "roff.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
|
||||
#define ROFF_TERM_ARGS struct termp *p, const struct roff_node *n
|
||||
|
||||
typedef void (*roff_term_pre_fp)(ROFF_TERM_ARGS);
|
||||
|
||||
static void roff_term_pre_br(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ce(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ft(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ll(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_mc(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_sp(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ta(ROFF_TERM_ARGS);
|
||||
static void roff_term_pre_ti(ROFF_TERM_ARGS);
|
||||
|
||||
static const roff_term_pre_fp roff_term_pre_acts[ROFF_MAX] = {
|
||||
roff_term_pre_br, /* br */
|
||||
roff_term_pre_ce, /* ce */
|
||||
roff_term_pre_ft, /* ft */
|
||||
roff_term_pre_ll, /* ll */
|
||||
roff_term_pre_mc, /* mc */
|
||||
roff_term_pre_sp, /* sp */
|
||||
roff_term_pre_ta, /* ta */
|
||||
roff_term_pre_ti, /* ti */
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
roff_term_pre(struct termp *p, const struct roff_node *n)
|
||||
{
|
||||
assert(n->tok < ROFF_MAX);
|
||||
(*roff_term_pre_acts[n->tok])(p, n);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_br(ROFF_TERM_ARGS)
|
||||
{
|
||||
term_newln(p);
|
||||
if (p->flags & TERMP_BRIND) {
|
||||
p->tcol->offset = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin;
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_ce(ROFF_TERM_ARGS)
|
||||
{
|
||||
const struct roff_node *nch;
|
||||
size_t len, lm;
|
||||
|
||||
roff_term_pre_br(p, n);
|
||||
lm = p->tcol->offset;
|
||||
n = n->child->next;
|
||||
while (n != NULL) {
|
||||
nch = n;
|
||||
len = 0;
|
||||
do {
|
||||
if (n->type == ROFFT_TEXT) {
|
||||
if (len)
|
||||
len++;
|
||||
len += term_strlen(p, nch->string);
|
||||
}
|
||||
nch = nch->next;
|
||||
} while (nch != NULL && (n->type != ROFFT_TEXT ||
|
||||
(n->flags & NODE_LINE) == 0));
|
||||
p->tcol->offset = len >= p->tcol->rmargin ? 0 :
|
||||
lm + len >= p->tcol->rmargin ? p->tcol->rmargin - len :
|
||||
(lm + p->tcol->rmargin - len) / 2;
|
||||
while (n != nch) {
|
||||
if (n->type == ROFFT_TEXT)
|
||||
term_word(p, n->string);
|
||||
else
|
||||
roff_term_pre(p, n);
|
||||
n = n->next;
|
||||
}
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
term_flushln(p);
|
||||
}
|
||||
p->tcol->offset = lm;
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_ft(ROFF_TERM_ARGS)
|
||||
{
|
||||
switch (*n->child->string) {
|
||||
case '4':
|
||||
case '3':
|
||||
case 'B':
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case '2':
|
||||
case 'I':
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
break;
|
||||
case 'P':
|
||||
term_fontlast(p);
|
||||
break;
|
||||
case '1':
|
||||
case 'C':
|
||||
case 'R':
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_ll(ROFF_TERM_ARGS)
|
||||
{
|
||||
term_setwidth(p, n->child != NULL ? n->child->string : NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_mc(ROFF_TERM_ARGS)
|
||||
{
|
||||
if (p->col) {
|
||||
p->flags |= TERMP_NOBREAK;
|
||||
term_flushln(p);
|
||||
p->flags &= ~(TERMP_NOBREAK | TERMP_NOSPACE);
|
||||
}
|
||||
if (n->child != NULL) {
|
||||
p->mc = n->child->string;
|
||||
p->flags |= TERMP_NEWMC;
|
||||
} else
|
||||
p->flags |= TERMP_ENDMC;
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_sp(ROFF_TERM_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
int len;
|
||||
|
||||
if (n->child != NULL) {
|
||||
if (a2roffsu(n->child->string, &su, SCALE_VS) == NULL)
|
||||
su.scale = 1.0;
|
||||
len = term_vspan(p, &su);
|
||||
} else
|
||||
len = 1;
|
||||
|
||||
if (len < 0)
|
||||
p->skipvsp -= len;
|
||||
else
|
||||
while (len--)
|
||||
term_vspace(p);
|
||||
|
||||
roff_term_pre_br(p, n);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_ta(ROFF_TERM_ARGS)
|
||||
{
|
||||
term_tab_set(p, NULL);
|
||||
for (n = n->child; n != NULL; n = n->next)
|
||||
term_tab_set(p, n->string);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_term_pre_ti(ROFF_TERM_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
const char *cp;
|
||||
int len, sign;
|
||||
|
||||
roff_term_pre_br(p, n);
|
||||
|
||||
if (n->child == NULL)
|
||||
return;
|
||||
cp = n->child->string;
|
||||
if (*cp == '+') {
|
||||
sign = 1;
|
||||
cp++;
|
||||
} else if (*cp == '-') {
|
||||
sign = -1;
|
||||
cp++;
|
||||
} else
|
||||
sign = 0;
|
||||
|
||||
if (a2roffsu(cp, &su, SCALE_EM) == NULL)
|
||||
return;
|
||||
len = term_hspan(p, &su) / 24;
|
||||
|
||||
if (sign == 0) {
|
||||
p->ti = len - p->tcol->offset;
|
||||
p->tcol->offset = len;
|
||||
} else if (sign == 1) {
|
||||
p->ti = len;
|
||||
p->tcol->offset += len;
|
||||
} else if ((size_t)len < p->tcol->offset) {
|
||||
p->ti = -len;
|
||||
p->tcol->offset -= len;
|
||||
} else {
|
||||
p->ti = -p->tcol->offset;
|
||||
p->tcol->offset = 0;
|
||||
}
|
||||
}
|
95
contrib/mdocml/roff_validate.c
Normal file
95
contrib/mdocml/roff_validate.c
Normal file
@ -0,0 +1,95 @@
|
||||
/* $Id: roff_validate.c,v 1.7 2017/06/06 15:01:04 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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 <stddef.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "libmandoc.h"
|
||||
#include "roff_int.h"
|
||||
|
||||
#define ROFF_VALID_ARGS struct roff_man *man, struct roff_node *n
|
||||
|
||||
typedef void (*roff_valid_fp)(ROFF_VALID_ARGS);
|
||||
|
||||
static void roff_valid_ft(ROFF_VALID_ARGS);
|
||||
|
||||
static const roff_valid_fp roff_valids[ROFF_MAX] = {
|
||||
NULL, /* br */
|
||||
NULL, /* ce */
|
||||
roff_valid_ft, /* ft */
|
||||
NULL, /* ll */
|
||||
NULL, /* mc */
|
||||
NULL, /* sp */
|
||||
NULL, /* ta */
|
||||
NULL, /* ti */
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
roff_validate(struct roff_man *man)
|
||||
{
|
||||
struct roff_node *n;
|
||||
|
||||
n = man->last;
|
||||
assert(n->tok < ROFF_MAX);
|
||||
if (roff_valids[n->tok] != NULL)
|
||||
(*roff_valids[n->tok])(man, n);
|
||||
}
|
||||
|
||||
static void
|
||||
roff_valid_ft(ROFF_VALID_ARGS)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (n->child == NULL) {
|
||||
man->next = ROFF_NEXT_CHILD;
|
||||
roff_word_alloc(man, n->line, n->pos, "P");
|
||||
man->last = n;
|
||||
return;
|
||||
}
|
||||
|
||||
cp = n->child->string;
|
||||
switch (*cp) {
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case 'I':
|
||||
case 'P':
|
||||
case 'R':
|
||||
if (cp[1] == '\0')
|
||||
return;
|
||||
break;
|
||||
case 'B':
|
||||
if (cp[1] == '\0' || (cp[1] == 'I' && cp[2] == '\0'))
|
||||
return;
|
||||
break;
|
||||
case 'C':
|
||||
if (cp[1] == 'W' && cp[2] == '\0')
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mandoc_vmsg(MANDOCERR_FT_BAD, man->parse,
|
||||
n->line, n->pos, "ft %s", cp);
|
||||
roff_node_delete(man, n);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: soelim.1,v 1.3 2015/05/20 22:59:12 schwarze Exp $
|
||||
.\" $Id: soelim.1,v 1.4 2017/03/18 19:56:01 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2014 Baptiste Daroussin <bapt@FreeBSD.org>
|
||||
.\" All rights reserved.
|
||||
@ -24,7 +24,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 20 2015 $
|
||||
.Dd $Mdocdate: March 18 2017 $
|
||||
.Dt SOELIM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -69,8 +69,8 @@ This option specify directories where
|
||||
searches for files (both those on the command line and those named in
|
||||
.Dq .so
|
||||
directive.)
|
||||
This options may be specified multiple times. The directories will be searched
|
||||
in the order specified.
|
||||
This options may be specified multiple times.
|
||||
The directories will be searched in the order specified.
|
||||
.El
|
||||
.Pp
|
||||
The files are always searched first in the current directory.
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: tbl.7,v 1.26 2015/01/29 00:33:57 schwarze Exp $
|
||||
.\" $Id: tbl.7,v 1.27 2017/06/08 18:11:22 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\" Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 29 2015 $
|
||||
.Dd $Mdocdate: June 8 2017 $
|
||||
.Dt TBL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -245,7 +245,7 @@ Emit a double-vertical bar instead of data.
|
||||
.Pp
|
||||
Keys may be followed by a set of modifiers.
|
||||
A modifier is either a modifier key or a natural number for specifying
|
||||
the minimum width of a column.
|
||||
the spacing to the right of the column.
|
||||
The following case-insensitive modifier keys are available:
|
||||
.Bl -tag -width 2n
|
||||
.It Cm b
|
||||
@ -284,8 +284,7 @@ Currently ignored.
|
||||
Move cell content up by half a table line.
|
||||
Currently ignored.
|
||||
.It Cm w
|
||||
Specify minimum column width.
|
||||
Currently ignored.
|
||||
Specify the minimum column width.
|
||||
.It Cm x
|
||||
After determining the width of all other columns, distribute the
|
||||
rest of the line length among all columns having the
|
||||
@ -300,7 +299,7 @@ minimum width 10, followed by vertical bar, followed by a left-justified
|
||||
column of minimum width 10, another vertical bar, then a column using
|
||||
bold font justified about the decimal point in numbers:
|
||||
.Pp
|
||||
.Dl c10 | l10 | nfB
|
||||
.Dl cw10 | lw10 | nfB
|
||||
.Ss Data
|
||||
The data section follows the last layout row.
|
||||
By default, cells in a data section are delimited by a tab.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl.c,v 1.40 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/* $Id: tbl.c,v 1.41 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -114,6 +114,7 @@ tbl_free(struct tbl_node *tbl)
|
||||
while (rp->first != NULL) {
|
||||
cp = rp->first;
|
||||
rp->first = cp->next;
|
||||
free(cp->wstr);
|
||||
free(cp);
|
||||
}
|
||||
free(rp);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: tbl_data.c,v 1.41 2015/10/06 18:32:20 schwarze Exp $ */
|
||||
/* $Id: tbl_data.c,v 1.42 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -144,6 +144,7 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos)
|
||||
}
|
||||
|
||||
dat->pos = TBL_DATA_DATA;
|
||||
dat->block = 1;
|
||||
|
||||
if (dat->string != NULL) {
|
||||
sz = strlen(p + pos) + strlen(dat->string) + 2;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_html.c,v 1.20 2017/02/05 18:15:39 schwarze Exp $ */
|
||||
/* $Id: tbl_html.c,v 1.21 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -31,22 +31,48 @@
|
||||
static void html_tblopen(struct html *, const struct tbl_span *);
|
||||
static size_t html_tbl_len(size_t, void *);
|
||||
static size_t html_tbl_strlen(const char *, void *);
|
||||
static size_t html_tbl_sulen(const struct roffsu *, void *);
|
||||
|
||||
|
||||
static size_t
|
||||
html_tbl_len(size_t sz, void *arg)
|
||||
{
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static size_t
|
||||
html_tbl_strlen(const char *p, void *arg)
|
||||
{
|
||||
|
||||
return strlen(p);
|
||||
}
|
||||
|
||||
static size_t
|
||||
html_tbl_sulen(const struct roffsu *su, void *arg)
|
||||
{
|
||||
switch (su->unit) {
|
||||
case SCALE_FS: /* 2^16 basic units */
|
||||
return su->scale * 65536.0 / 24.0;
|
||||
case SCALE_IN: /* 10 characters per inch */
|
||||
return su->scale * 10.0;
|
||||
case SCALE_CM: /* 2.54 cm per inch */
|
||||
return su->scale * 10.0 / 2.54;
|
||||
case SCALE_PC: /* 6 pica per inch */
|
||||
case SCALE_VS:
|
||||
return su->scale * 10.0 / 6.0;
|
||||
case SCALE_EN:
|
||||
case SCALE_EM:
|
||||
return su->scale;
|
||||
case SCALE_PT: /* 12 points per pica */
|
||||
return su->scale * 10.0 / 6.0 / 12.0;
|
||||
case SCALE_BU: /* 24 basic units per character */
|
||||
return su->scale / 24.0;
|
||||
case SCALE_MM: /* 1/1000 inch */
|
||||
return su->scale / 100.0;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
html_tblopen(struct html *h, const struct tbl_span *sp)
|
||||
{
|
||||
@ -56,6 +82,7 @@ html_tblopen(struct html *h, const struct tbl_span *sp)
|
||||
if (h->tbl.cols == NULL) {
|
||||
h->tbl.len = html_tbl_len;
|
||||
h->tbl.slen = html_tbl_strlen;
|
||||
h->tbl.sulen = html_tbl_sulen;
|
||||
tblcalc(&h->tbl, sp, 0);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: tbl_layout.c,v 1.41 2015/10/12 00:08:16 schwarze Exp $ */
|
||||
/* $Id: tbl_layout.c,v 1.42 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2012, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -62,6 +62,7 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||
int ln, const char *p, int *pos)
|
||||
{
|
||||
char *endptr;
|
||||
size_t sz;
|
||||
|
||||
mod:
|
||||
while (p[*pos] == ' ' || p[*pos] == '\t')
|
||||
@ -127,7 +128,22 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||
case 'u':
|
||||
cp->flags |= TBL_CELL_UP;
|
||||
goto mod;
|
||||
case 'w': /* XXX for now, ignore minimal column width */
|
||||
case 'w':
|
||||
sz = 0;
|
||||
if (p[*pos] == '(') {
|
||||
(*pos)++;
|
||||
while (p[*pos + sz] != '\0' && p[*pos + sz] != ')')
|
||||
sz++;
|
||||
} else
|
||||
while (isdigit((unsigned char)p[*pos + sz]))
|
||||
sz++;
|
||||
if (sz) {
|
||||
free(cp->wstr);
|
||||
cp->wstr = mandoc_strndup(p + *pos, sz);
|
||||
*pos += sz;
|
||||
if (p[*pos] == ')')
|
||||
(*pos)++;
|
||||
}
|
||||
goto mod;
|
||||
case 'x':
|
||||
cp->flags |= TBL_CELL_WMAX;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: tbl_term.c,v 1.43 2015/10/12 00:08:16 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.46 2017/06/08 18:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011,2012,2014,2015,2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
static size_t term_tbl_len(size_t, void *);
|
||||
static size_t term_tbl_strlen(const char *, void *);
|
||||
static size_t term_tbl_sulen(const struct roffsu *, void *);
|
||||
static void tbl_char(struct termp *, char, size_t);
|
||||
static void tbl_data(struct termp *, const struct tbl_opts *,
|
||||
const struct tbl_dat *,
|
||||
@ -43,17 +44,21 @@ static void tbl_hrule(struct termp *, const struct tbl_span *, int);
|
||||
static void tbl_word(struct termp *, const struct tbl_dat *);
|
||||
|
||||
|
||||
static size_t
|
||||
term_tbl_sulen(const struct roffsu *su, void *arg)
|
||||
{
|
||||
return term_hspan((const struct termp *)arg, su) / 24;
|
||||
}
|
||||
|
||||
static size_t
|
||||
term_tbl_strlen(const char *p, void *arg)
|
||||
{
|
||||
|
||||
return term_strlen((const struct termp *)arg, p);
|
||||
}
|
||||
|
||||
static size_t
|
||||
term_tbl_len(size_t sz, void *arg)
|
||||
{
|
||||
|
||||
return term_len((const struct termp *)arg, sz);
|
||||
}
|
||||
|
||||
@ -63,18 +68,12 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
const struct tbl_cell *cp;
|
||||
const struct tbl_dat *dp;
|
||||
static size_t offset;
|
||||
size_t rmargin, maxrmargin, tsz;
|
||||
size_t tsz;
|
||||
int ic, horiz, spans, vert;
|
||||
|
||||
rmargin = tp->rmargin;
|
||||
maxrmargin = tp->maxrmargin;
|
||||
|
||||
tp->rmargin = tp->maxrmargin = TERM_MAXMARGIN;
|
||||
|
||||
/* Inhibit printing of spaces: we do padding ourselves. */
|
||||
|
||||
tp->flags |= TERMP_NONOSPACE;
|
||||
tp->flags |= TERMP_NOSPACE;
|
||||
tp->flags |= TERMP_NOSPACE | TERMP_NONOSPACE | TERMP_BRNEVER;
|
||||
|
||||
/*
|
||||
* The first time we're invoked for a given table block,
|
||||
@ -84,23 +83,24 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
if (tp->tbl.cols == NULL) {
|
||||
tp->tbl.len = term_tbl_len;
|
||||
tp->tbl.slen = term_tbl_strlen;
|
||||
tp->tbl.sulen = term_tbl_sulen;
|
||||
tp->tbl.arg = tp;
|
||||
|
||||
tblcalc(&tp->tbl, sp, rmargin - tp->offset);
|
||||
tblcalc(&tp->tbl, sp, tp->tcol->rmargin - tp->tcol->offset);
|
||||
|
||||
/* Center the table as a whole. */
|
||||
|
||||
offset = tp->offset;
|
||||
offset = tp->tcol->offset;
|
||||
if (sp->opts->opts & TBL_OPT_CENTRE) {
|
||||
tsz = sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)
|
||||
? 2 : !!sp->opts->lvert + !!sp->opts->rvert;
|
||||
for (ic = 0; ic < sp->opts->cols; ic++)
|
||||
tsz += tp->tbl.cols[ic].width + 3;
|
||||
tsz -= 3;
|
||||
if (offset + tsz > rmargin)
|
||||
if (offset + tsz > tp->tcol->rmargin)
|
||||
tsz -= 1;
|
||||
tp->offset = (offset + rmargin > tsz) ?
|
||||
(offset + rmargin - tsz) / 2 : 0;
|
||||
tp->tcol->offset = offset + tp->tcol->rmargin > tsz ?
|
||||
(offset + tp->tcol->rmargin - tsz) / 2 : 0;
|
||||
}
|
||||
|
||||
/* Horizontal frame at the start of boxed tables. */
|
||||
@ -199,12 +199,9 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
assert(tp->tbl.cols);
|
||||
free(tp->tbl.cols);
|
||||
tp->tbl.cols = NULL;
|
||||
tp->offset = offset;
|
||||
tp->tcol->offset = offset;
|
||||
}
|
||||
|
||||
tp->flags &= ~TERMP_NONOSPACE;
|
||||
tp->rmargin = rmargin;
|
||||
tp->maxrmargin = maxrmargin;
|
||||
tp->flags &= ~(TERMP_NONOSPACE | TERMP_BRNEVER);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: term.c,v 1.259 2017/01/08 18:16:58 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.268 2017/06/08 12:54:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -32,17 +32,19 @@
|
||||
#include "main.h"
|
||||
|
||||
static size_t cond_width(const struct termp *, int, int *);
|
||||
static void adjbuf(struct termp *p, size_t);
|
||||
static void adjbuf(struct termp_col *, size_t);
|
||||
static void bufferc(struct termp *, char);
|
||||
static void encode(struct termp *, const char *, size_t);
|
||||
static void encode1(struct termp *, int);
|
||||
static void endline(struct termp *);
|
||||
|
||||
|
||||
void
|
||||
term_free(struct termp *p)
|
||||
{
|
||||
|
||||
free(p->buf);
|
||||
for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++)
|
||||
free(p->tcol->buf);
|
||||
free(p->tcols);
|
||||
free(p->fontq);
|
||||
free(p);
|
||||
}
|
||||
@ -84,69 +86,53 @@ term_end(struct termp *p)
|
||||
* to be broken, start the next line at the right margin instead
|
||||
* of at the offset. Used together with TERMP_NOBREAK for the tags
|
||||
* in various kinds of tagged lists.
|
||||
* - TERMP_DANGLE: Do not break the output line at the right margin,
|
||||
* - TERMP_HANG: Do not break the output line at the right margin,
|
||||
* append the next chunk after it even if this one is too long.
|
||||
* To be used together with TERMP_NOBREAK.
|
||||
* - TERMP_HANG: Like TERMP_DANGLE, and also suppress padding before
|
||||
* the next chunk if this column is not full.
|
||||
* - TERMP_NOPAD: Start writing at the current position,
|
||||
* do not pad with blank characters up to the offset.
|
||||
*/
|
||||
void
|
||||
term_flushln(struct termp *p)
|
||||
{
|
||||
size_t i; /* current input position in p->buf */
|
||||
int ntab; /* number of tabs to prepend */
|
||||
size_t vis; /* current visual position on output */
|
||||
size_t vbl; /* number of blanks to prepend to output */
|
||||
size_t vend; /* end of word visual position on output */
|
||||
size_t bp; /* visual right border position */
|
||||
size_t dv; /* temporary for visual pos calculations */
|
||||
size_t j; /* temporary loop index for p->buf */
|
||||
size_t j; /* temporary loop index for p->tcol->buf */
|
||||
size_t jhy; /* last hyph before overflow w/r/t j */
|
||||
size_t maxvis; /* output position of visible boundary */
|
||||
int ntab; /* number of tabs to prepend */
|
||||
|
||||
/*
|
||||
* First, establish the maximum columns of "visible" content.
|
||||
* This is usually the difference between the right-margin and
|
||||
* an indentation, but can be, for tagged lists or columns, a
|
||||
* small set of values.
|
||||
*
|
||||
* The following unsigned-signed subtractions look strange,
|
||||
* but they are actually correct. If the int p->overstep
|
||||
* is negative, it gets sign extended. Subtracting that
|
||||
* very large size_t effectively adds a small number to dv.
|
||||
*/
|
||||
dv = p->rmargin > p->offset ? p->rmargin - p->offset : 0;
|
||||
maxvis = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
|
||||
|
||||
if (p->flags & TERMP_NOBREAK) {
|
||||
dv = p->maxrmargin > p->offset ?
|
||||
p->maxrmargin - p->offset : 0;
|
||||
bp = (int)dv > p->overstep ?
|
||||
dv - (size_t)p->overstep : 0;
|
||||
} else
|
||||
bp = maxvis;
|
||||
|
||||
/*
|
||||
* Calculate the required amount of padding.
|
||||
*/
|
||||
vbl = p->offset + p->overstep > p->viscol ?
|
||||
p->offset + p->overstep - p->viscol : 0;
|
||||
|
||||
vbl = (p->flags & TERMP_NOPAD) || p->tcol->offset < p->viscol ?
|
||||
0 : p->tcol->offset - p->viscol;
|
||||
if (p->minbl && vbl < p->minbl)
|
||||
vbl = p->minbl;
|
||||
maxvis = p->tcol->rmargin > p->viscol + vbl ?
|
||||
p->tcol->rmargin - p->viscol - vbl : 0;
|
||||
bp = !(p->flags & TERMP_NOBREAK) ? maxvis :
|
||||
p->maxrmargin > p->viscol + vbl ?
|
||||
p->maxrmargin - p->viscol - vbl : 0;
|
||||
vis = vend = 0;
|
||||
i = 0;
|
||||
|
||||
while (i < p->col) {
|
||||
if (p->lasttcol == 0)
|
||||
p->tcol->col = 0;
|
||||
while (p->tcol->col < p->lastcol) {
|
||||
|
||||
/*
|
||||
* Handle literal tab characters: collapse all
|
||||
* subsequent tabs into a single huge set of spaces.
|
||||
*/
|
||||
|
||||
ntab = 0;
|
||||
while (i < p->col && '\t' == p->buf[i]) {
|
||||
vend = (vis / p->tabwidth + 1) * p->tabwidth;
|
||||
while (p->tcol->col < p->lastcol &&
|
||||
p->tcol->buf[p->tcol->col] == '\t') {
|
||||
vend = term_tab_next(vis);
|
||||
vbl += vend - vis;
|
||||
vis = vend;
|
||||
ntab++;
|
||||
i++;
|
||||
p->tcol->col++;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -156,84 +142,90 @@ term_flushln(struct termp *p)
|
||||
* space is printed according to regular spacing rules).
|
||||
*/
|
||||
|
||||
for (j = i, jhy = 0; j < p->col; j++) {
|
||||
if (' ' == p->buf[j] || '\t' == p->buf[j])
|
||||
jhy = 0;
|
||||
for (j = p->tcol->col; j < p->lastcol; j++) {
|
||||
if (p->tcol->buf[j] == ' ' || p->tcol->buf[j] == '\t')
|
||||
break;
|
||||
|
||||
/* Back over the last printed character. */
|
||||
if (8 == p->buf[j]) {
|
||||
if (p->tcol->buf[j] == '\b') {
|
||||
assert(j);
|
||||
vend -= (*p->width)(p, p->buf[j - 1]);
|
||||
vend -= (*p->width)(p, p->tcol->buf[j - 1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Regular word. */
|
||||
/* Break at the hyphen point if we overrun. */
|
||||
if (vend > vis && vend < bp &&
|
||||
(ASCII_HYPH == p->buf[j] ||
|
||||
ASCII_BREAK == p->buf[j]))
|
||||
(p->tcol->buf[j] == ASCII_HYPH||
|
||||
p->tcol->buf[j] == ASCII_BREAK))
|
||||
jhy = j;
|
||||
|
||||
/*
|
||||
* Hyphenation now decided, put back a real
|
||||
* hyphen such that we get the correct width.
|
||||
*/
|
||||
if (ASCII_HYPH == p->buf[j])
|
||||
p->buf[j] = '-';
|
||||
if (p->tcol->buf[j] == ASCII_HYPH)
|
||||
p->tcol->buf[j] = '-';
|
||||
|
||||
vend += (*p->width)(p, p->buf[j]);
|
||||
vend += (*p->width)(p, p->tcol->buf[j]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out whether we would exceed the right margin.
|
||||
* If so, break to the next line.
|
||||
*/
|
||||
if (vend > bp && 0 == jhy && vis > 0) {
|
||||
|
||||
if (vend > bp && jhy == 0 && vis > 0 &&
|
||||
(p->flags & TERMP_BRNEVER) == 0) {
|
||||
if (p->lasttcol)
|
||||
return;
|
||||
|
||||
endline(p);
|
||||
vend -= vis;
|
||||
(*p->endline)(p);
|
||||
p->viscol = 0;
|
||||
if (TERMP_BRIND & p->flags) {
|
||||
vbl = p->rmargin;
|
||||
vend += p->rmargin;
|
||||
vend -= p->offset;
|
||||
} else
|
||||
vbl = p->offset;
|
||||
|
||||
/* use pending tabs on the new line */
|
||||
/* Use pending tabs on the new line. */
|
||||
|
||||
if (0 < ntab)
|
||||
vbl += ntab * p->tabwidth;
|
||||
vbl = 0;
|
||||
while (ntab--)
|
||||
vbl = term_tab_next(vbl);
|
||||
|
||||
/*
|
||||
* Remove the p->overstep width.
|
||||
* Again, if p->overstep is negative,
|
||||
* sign extension does the right thing.
|
||||
*/
|
||||
/* Re-establish indentation. */
|
||||
|
||||
bp += (size_t)p->overstep;
|
||||
p->overstep = 0;
|
||||
if (p->flags & TERMP_BRIND)
|
||||
vbl += p->tcol->rmargin;
|
||||
else
|
||||
vbl += p->tcol->offset;
|
||||
maxvis = p->tcol->rmargin > vbl ?
|
||||
p->tcol->rmargin - vbl : 0;
|
||||
bp = !(p->flags & TERMP_NOBREAK) ? maxvis :
|
||||
p->maxrmargin > vbl ? p->maxrmargin - vbl : 0;
|
||||
}
|
||||
|
||||
/* Write out the [remaining] word. */
|
||||
for ( ; i < p->col; i++) {
|
||||
if (vend > bp && jhy > 0 && i > jhy)
|
||||
/*
|
||||
* Write out the rest of the word.
|
||||
*/
|
||||
|
||||
for ( ; p->tcol->col < p->lastcol; p->tcol->col++) {
|
||||
if (vend > bp && jhy > 0 && p->tcol->col > jhy)
|
||||
break;
|
||||
if ('\t' == p->buf[i])
|
||||
if (p->tcol->buf[p->tcol->col] == '\t')
|
||||
break;
|
||||
if (' ' == p->buf[i]) {
|
||||
j = i;
|
||||
while (i < p->col && ' ' == p->buf[i])
|
||||
i++;
|
||||
dv = (i - j) * (*p->width)(p, ' ');
|
||||
if (p->tcol->buf[p->tcol->col] == ' ') {
|
||||
j = p->tcol->col;
|
||||
while (p->tcol->col < p->lastcol &&
|
||||
p->tcol->buf[p->tcol->col] == ' ')
|
||||
p->tcol->col++;
|
||||
dv = (p->tcol->col - j) * (*p->width)(p, ' ');
|
||||
vbl += dv;
|
||||
vend += dv;
|
||||
break;
|
||||
}
|
||||
if (ASCII_NBRSP == p->buf[i]) {
|
||||
if (p->tcol->buf[p->tcol->col] == ASCII_NBRSP) {
|
||||
vbl += (*p->width)(p, ' ');
|
||||
continue;
|
||||
}
|
||||
if (ASCII_BREAK == p->buf[i])
|
||||
if (p->tcol->buf[p->tcol->col] == ASCII_BREAK)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -247,11 +239,13 @@ term_flushln(struct termp *p)
|
||||
vbl = 0;
|
||||
}
|
||||
|
||||
(*p->letter)(p, p->buf[i]);
|
||||
if (8 == p->buf[i])
|
||||
p->viscol -= (*p->width)(p, p->buf[i-1]);
|
||||
(*p->letter)(p, p->tcol->buf[p->tcol->col]);
|
||||
if (p->tcol->buf[p->tcol->col] == '\b')
|
||||
p->viscol -= (*p->width)(p,
|
||||
p->tcol->buf[p->tcol->col - 1]);
|
||||
else
|
||||
p->viscol += (*p->width)(p, p->buf[i]);
|
||||
p->viscol += (*p->width)(p,
|
||||
p->tcol->buf[p->tcol->col]);
|
||||
}
|
||||
vis = vend;
|
||||
}
|
||||
@ -260,48 +254,45 @@ term_flushln(struct termp *p)
|
||||
* If there was trailing white space, it was not printed;
|
||||
* so reset the cursor position accordingly.
|
||||
*/
|
||||
|
||||
if (vis > vbl)
|
||||
vis -= vbl;
|
||||
else
|
||||
vis = 0;
|
||||
|
||||
p->col = 0;
|
||||
p->overstep = 0;
|
||||
p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE);
|
||||
|
||||
if ( ! (TERMP_NOBREAK & p->flags)) {
|
||||
p->viscol = 0;
|
||||
(*p->endline)(p);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TERMP_HANG & p->flags) {
|
||||
p->overstep += (int)(p->offset + vis - p->rmargin +
|
||||
p->trailspace * (*p->width)(p, ' '));
|
||||
|
||||
/*
|
||||
* If we have overstepped the margin, temporarily move
|
||||
* it to the right and flag the rest of the line to be
|
||||
* shorter.
|
||||
* If there is a request to keep the columns together,
|
||||
* allow negative overstep when the column is not full.
|
||||
*/
|
||||
if (p->trailspace && p->overstep < 0)
|
||||
p->overstep = 0;
|
||||
return;
|
||||
|
||||
} else if (TERMP_DANGLE & p->flags)
|
||||
return;
|
||||
p->col = p->lastcol = 0;
|
||||
p->minbl = p->trailspace;
|
||||
p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE | TERMP_NOPAD);
|
||||
|
||||
/* Trailing whitespace is significant in some columns. */
|
||||
|
||||
if (vis && vbl && (TERMP_BRTRSP & p->flags))
|
||||
vis += vbl;
|
||||
|
||||
/* If the column was overrun, break the line. */
|
||||
if (maxvis < vis + p->trailspace * (*p->width)(p, ' ')) {
|
||||
(*p->endline)(p);
|
||||
p->viscol = 0;
|
||||
if ((p->flags & TERMP_NOBREAK) == 0 ||
|
||||
((p->flags & TERMP_HANG) == 0 &&
|
||||
vis + p->trailspace * (*p->width)(p, ' ') > maxvis))
|
||||
endline(p);
|
||||
}
|
||||
|
||||
static void
|
||||
endline(struct termp *p)
|
||||
{
|
||||
if ((p->flags & (TERMP_NEWMC | TERMP_ENDMC)) == TERMP_ENDMC) {
|
||||
p->mc = NULL;
|
||||
p->flags &= ~TERMP_ENDMC;
|
||||
}
|
||||
if (p->mc != NULL) {
|
||||
if (p->viscol && p->maxrmargin >= p->viscol)
|
||||
(*p->advance)(p, p->maxrmargin - p->viscol + 1);
|
||||
p->flags |= TERMP_NOBUF | TERMP_NOSPACE;
|
||||
term_word(p, p->mc);
|
||||
p->flags &= ~(TERMP_NOBUF | TERMP_NEWMC);
|
||||
}
|
||||
p->viscol = 0;
|
||||
p->minbl = 0;
|
||||
(*p->endline)(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -314,7 +305,7 @@ term_newln(struct termp *p)
|
||||
{
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (p->col || p->viscol)
|
||||
if (p->lastcol || p->viscol)
|
||||
term_flushln(p);
|
||||
}
|
||||
|
||||
@ -330,6 +321,7 @@ term_vspace(struct termp *p)
|
||||
|
||||
term_newln(p);
|
||||
p->viscol = 0;
|
||||
p->minbl = 0;
|
||||
if (0 < p->skipvsp)
|
||||
p->skipvsp--;
|
||||
else
|
||||
@ -397,30 +389,31 @@ term_fontpop(struct termp *p)
|
||||
void
|
||||
term_word(struct termp *p, const char *word)
|
||||
{
|
||||
struct roffsu su;
|
||||
const char nbrsp[2] = { ASCII_NBRSP, 0 };
|
||||
const char *seq, *cp;
|
||||
int sz, uc;
|
||||
size_t ssz;
|
||||
size_t csz, lsz, ssz;
|
||||
enum mandoc_esc esc;
|
||||
|
||||
if ( ! (TERMP_NOSPACE & p->flags)) {
|
||||
if ( ! (TERMP_KEEP & p->flags)) {
|
||||
bufferc(p, ' ');
|
||||
if (TERMP_SENTENCE & p->flags)
|
||||
if ((p->flags & TERMP_NOBUF) == 0) {
|
||||
if ((p->flags & TERMP_NOSPACE) == 0) {
|
||||
if ((p->flags & TERMP_KEEP) == 0) {
|
||||
bufferc(p, ' ');
|
||||
} else
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
if (p->flags & TERMP_SENTENCE)
|
||||
bufferc(p, ' ');
|
||||
} else
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
}
|
||||
if (p->flags & TERMP_PREKEEP)
|
||||
p->flags |= TERMP_KEEP;
|
||||
if (p->flags & TERMP_NONOSPACE)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
else
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
p->flags &= ~(TERMP_SENTENCE | TERMP_NONEWLINE);
|
||||
p->skipvsp = 0;
|
||||
}
|
||||
if (TERMP_PREKEEP & p->flags)
|
||||
p->flags |= TERMP_KEEP;
|
||||
|
||||
if ( ! (p->flags & TERMP_NONOSPACE))
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
else
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
p->flags &= ~(TERMP_SENTENCE | TERMP_NONEWLINE);
|
||||
p->skipvsp = 0;
|
||||
|
||||
while ('\0' != *word) {
|
||||
if ('\\' != *word) {
|
||||
@ -485,6 +478,74 @@ term_word(struct termp *p, const char *word)
|
||||
else if (*word == '\0')
|
||||
p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE);
|
||||
continue;
|
||||
case ESCAPE_HORIZ:
|
||||
if (a2roffsu(seq, &su, SCALE_EM) == NULL)
|
||||
continue;
|
||||
uc = term_hspan(p, &su) / 24;
|
||||
if (uc > 0)
|
||||
while (uc-- > 0)
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
else if (p->col > (size_t)(-uc))
|
||||
p->col += uc;
|
||||
else {
|
||||
uc += p->col;
|
||||
p->col = 0;
|
||||
if (p->tcol->offset > (size_t)(-uc)) {
|
||||
p->ti += uc;
|
||||
p->tcol->offset += uc;
|
||||
} else {
|
||||
p->ti -= p->tcol->offset;
|
||||
p->tcol->offset = 0;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case ESCAPE_HLINE:
|
||||
if ((seq = a2roffsu(seq, &su, SCALE_EM)) == NULL)
|
||||
continue;
|
||||
uc = term_hspan(p, &su) / 24;
|
||||
if (uc <= 0) {
|
||||
if (p->tcol->rmargin <= p->tcol->offset)
|
||||
continue;
|
||||
lsz = p->tcol->rmargin - p->tcol->offset;
|
||||
} else
|
||||
lsz = uc;
|
||||
if (*seq == '\0')
|
||||
uc = -1;
|
||||
else if (*seq == '\\') {
|
||||
seq++;
|
||||
esc = mandoc_escape(&seq, &cp, &sz);
|
||||
switch (esc) {
|
||||
case ESCAPE_UNICODE:
|
||||
uc = mchars_num2uc(cp + 1, sz - 1);
|
||||
break;
|
||||
case ESCAPE_NUMBERED:
|
||||
uc = mchars_num2char(cp, sz);
|
||||
break;
|
||||
case ESCAPE_SPECIAL:
|
||||
uc = mchars_spec2cp(cp, sz);
|
||||
break;
|
||||
default:
|
||||
uc = -1;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
uc = *seq;
|
||||
if (uc < 0x20 || (uc > 0x7E && uc < 0xA0))
|
||||
uc = '_';
|
||||
if (p->enc == TERMENC_ASCII) {
|
||||
cp = ascii_uc2str(uc);
|
||||
csz = term_strlen(p, cp);
|
||||
ssz = strlen(cp);
|
||||
} else
|
||||
csz = (*p->width)(p, uc);
|
||||
while (lsz >= csz) {
|
||||
if (p->enc == TERMENC_ASCII)
|
||||
encode(p, cp, ssz);
|
||||
else
|
||||
encode1(p, uc);
|
||||
lsz -= csz;
|
||||
}
|
||||
continue;
|
||||
case ESCAPE_SKIPCHAR:
|
||||
p->flags |= TERMP_BACKAFTER;
|
||||
continue;
|
||||
@ -504,10 +565,12 @@ term_word(struct termp *p, const char *word)
|
||||
}
|
||||
}
|
||||
/* Trim trailing backspace/blank pair. */
|
||||
if (p->col > 2 &&
|
||||
(p->buf[p->col - 1] == ' ' ||
|
||||
p->buf[p->col - 1] == '\t'))
|
||||
p->col -= 2;
|
||||
if (p->lastcol > 2 &&
|
||||
(p->tcol->buf[p->lastcol - 1] == ' ' ||
|
||||
p->tcol->buf[p->lastcol - 1] == '\t'))
|
||||
p->lastcol -= 2;
|
||||
if (p->col > p->lastcol)
|
||||
p->col = p->lastcol;
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
@ -532,25 +595,28 @@ term_word(struct termp *p, const char *word)
|
||||
}
|
||||
|
||||
static void
|
||||
adjbuf(struct termp *p, size_t sz)
|
||||
adjbuf(struct termp_col *c, size_t sz)
|
||||
{
|
||||
|
||||
if (0 == p->maxcols)
|
||||
p->maxcols = 1024;
|
||||
while (sz >= p->maxcols)
|
||||
p->maxcols <<= 2;
|
||||
|
||||
p->buf = mandoc_reallocarray(p->buf, p->maxcols, sizeof(int));
|
||||
if (c->maxcols == 0)
|
||||
c->maxcols = 1024;
|
||||
while (c->maxcols <= sz)
|
||||
c->maxcols <<= 2;
|
||||
c->buf = mandoc_reallocarray(c->buf, c->maxcols, sizeof(*c->buf));
|
||||
}
|
||||
|
||||
static void
|
||||
bufferc(struct termp *p, char c)
|
||||
{
|
||||
|
||||
if (p->col + 1 >= p->maxcols)
|
||||
adjbuf(p, p->col + 1);
|
||||
|
||||
p->buf[p->col++] = c;
|
||||
if (p->flags & TERMP_NOBUF) {
|
||||
(*p->letter)(p, c);
|
||||
return;
|
||||
}
|
||||
if (p->col + 1 >= p->tcol->maxcols)
|
||||
adjbuf(p->tcol, p->col + 1);
|
||||
if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
|
||||
p->tcol->buf[p->col] = c;
|
||||
if (p->lastcol < ++p->col)
|
||||
p->lastcol = p->col;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -563,31 +629,40 @@ encode1(struct termp *p, int c)
|
||||
{
|
||||
enum termfont f;
|
||||
|
||||
if (p->col + 7 >= p->maxcols)
|
||||
adjbuf(p, p->col + 7);
|
||||
if (p->flags & TERMP_NOBUF) {
|
||||
(*p->letter)(p, c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->col + 7 >= p->tcol->maxcols)
|
||||
adjbuf(p->tcol, p->col + 7);
|
||||
|
||||
f = (c == ASCII_HYPH || c > 127 || isgraph(c)) ?
|
||||
p->fontq[p->fonti] : TERMFONT_NONE;
|
||||
|
||||
if (p->flags & TERMP_BACKBEFORE) {
|
||||
if (p->buf[p->col - 1] == ' ' || p->buf[p->col - 1] == '\t')
|
||||
if (p->tcol->buf[p->col - 1] == ' ' ||
|
||||
p->tcol->buf[p->col - 1] == '\t')
|
||||
p->col--;
|
||||
else
|
||||
p->buf[p->col++] = 8;
|
||||
p->tcol->buf[p->col++] = '\b';
|
||||
p->flags &= ~TERMP_BACKBEFORE;
|
||||
}
|
||||
if (TERMFONT_UNDER == f || TERMFONT_BI == f) {
|
||||
p->buf[p->col++] = '_';
|
||||
p->buf[p->col++] = 8;
|
||||
if (f == TERMFONT_UNDER || f == TERMFONT_BI) {
|
||||
p->tcol->buf[p->col++] = '_';
|
||||
p->tcol->buf[p->col++] = '\b';
|
||||
}
|
||||
if (TERMFONT_BOLD == f || TERMFONT_BI == f) {
|
||||
if (ASCII_HYPH == c)
|
||||
p->buf[p->col++] = '-';
|
||||
if (f == TERMFONT_BOLD || f == TERMFONT_BI) {
|
||||
if (c == ASCII_HYPH)
|
||||
p->tcol->buf[p->col++] = '-';
|
||||
else
|
||||
p->buf[p->col++] = c;
|
||||
p->buf[p->col++] = 8;
|
||||
p->tcol->buf[p->col++] = c;
|
||||
p->tcol->buf[p->col++] = '\b';
|
||||
}
|
||||
p->buf[p->col++] = c;
|
||||
if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
|
||||
p->tcol->buf[p->col] = c;
|
||||
if (p->lastcol < ++p->col)
|
||||
p->lastcol = p->col;
|
||||
if (p->flags & TERMP_BACKAFTER) {
|
||||
p->flags |= TERMP_BACKBEFORE;
|
||||
p->flags &= ~TERMP_BACKAFTER;
|
||||
@ -599,15 +674,24 @@ encode(struct termp *p, const char *word, size_t sz)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (p->col + 2 + (sz * 5) >= p->maxcols)
|
||||
adjbuf(p, p->col + 2 + (sz * 5));
|
||||
if (p->flags & TERMP_NOBUF) {
|
||||
for (i = 0; i < sz; i++)
|
||||
(*p->letter)(p, word[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->col + 2 + (sz * 5) >= p->tcol->maxcols)
|
||||
adjbuf(p->tcol, p->col + 2 + (sz * 5));
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
if (ASCII_HYPH == word[i] ||
|
||||
isgraph((unsigned char)word[i]))
|
||||
encode1(p, word[i]);
|
||||
else {
|
||||
p->buf[p->col++] = word[i];
|
||||
if (p->lastcol <= p->col ||
|
||||
(word[i] != ' ' && word[i] != ASCII_NBRSP))
|
||||
p->tcol->buf[p->col] = word[i];
|
||||
p->col++;
|
||||
|
||||
/*
|
||||
* Postpone the effect of \z while handling
|
||||
@ -621,6 +705,8 @@ encode(struct termp *p, const char *word, size_t sz)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p->lastcol < p->col)
|
||||
p->lastcol = p->col;
|
||||
}
|
||||
|
||||
void
|
||||
@ -644,7 +730,7 @@ term_setwidth(struct termp *p, const char *wstr)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (a2roffsu(wstr, &su, SCALE_MAX))
|
||||
if (a2roffsu(wstr, &su, SCALE_MAX) != NULL)
|
||||
width = term_hspan(p, &su);
|
||||
else
|
||||
iop = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: term.h,v 1.118 2015/11/07 14:01:16 schwarze Exp $ */
|
||||
/* $Id: term.h,v 1.126 2017/06/07 20:01:19 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -36,9 +36,10 @@ enum termfont {
|
||||
TERMFONT__MAX
|
||||
};
|
||||
|
||||
#define TERM_MAXMARGIN 100000 /* FIXME */
|
||||
|
||||
struct eqn;
|
||||
struct roff_meta;
|
||||
struct roff_node;
|
||||
struct tbl_span;
|
||||
struct termp;
|
||||
|
||||
typedef void (*term_margin)(struct termp *, const struct roff_meta *);
|
||||
@ -48,24 +49,33 @@ struct termp_tbl {
|
||||
int decimal; /* decimal point position */
|
||||
};
|
||||
|
||||
struct termp_col {
|
||||
int *buf; /* Output buffer. */
|
||||
size_t maxcols; /* Allocated bytes in buf. */
|
||||
size_t col; /* Byte in buf to be written. */
|
||||
size_t rmargin; /* Current right margin. */
|
||||
size_t offset; /* Current left margin. */
|
||||
};
|
||||
|
||||
struct termp {
|
||||
enum termtype type;
|
||||
struct rofftbl tbl; /* table configuration */
|
||||
int synopsisonly; /* print the synopsis only */
|
||||
int mdocstyle; /* imitate mdoc(7) output */
|
||||
struct rofftbl tbl; /* Table configuration. */
|
||||
struct termp_col *tcols; /* Array of table columns. */
|
||||
struct termp_col *tcol; /* Current table column. */
|
||||
size_t maxtcol; /* Allocated table columns. */
|
||||
size_t lasttcol; /* Last column currently used. */
|
||||
size_t line; /* Current output line number. */
|
||||
size_t defindent; /* Default indent for text. */
|
||||
size_t defrmargin; /* Right margin of the device. */
|
||||
size_t lastrmargin; /* Right margin before the last ll. */
|
||||
size_t rmargin; /* Current right margin. */
|
||||
size_t maxrmargin; /* Max right margin. */
|
||||
size_t maxcols; /* Max size of buf. */
|
||||
size_t offset; /* Margin offest. */
|
||||
size_t tabwidth; /* Distance of tab positions. */
|
||||
size_t col; /* Bytes in buf. */
|
||||
size_t col; /* Byte position in buf. */
|
||||
size_t lastcol; /* Bytes in buf. */
|
||||
size_t viscol; /* Chars on current line. */
|
||||
size_t trailspace; /* See termp_flushln(). */
|
||||
int overstep; /* See termp_flushln(). */
|
||||
size_t trailspace; /* See term_flushln(). */
|
||||
size_t minbl; /* Minimum blanks before next field. */
|
||||
int synopsisonly; /* Print the synopsis only. */
|
||||
int mdocstyle; /* Imitate mdoc(7) output. */
|
||||
int ti; /* Temporary indent for one line. */
|
||||
int skipvsp; /* Vertical space to skip. */
|
||||
int flags;
|
||||
#define TERMP_SENTENCE (1 << 0) /* Space before a sentence. */
|
||||
@ -79,12 +89,16 @@ struct termp {
|
||||
#define TERMP_NOBREAK (1 << 8) /* See term_flushln(). */
|
||||
#define TERMP_BRTRSP (1 << 9) /* See term_flushln(). */
|
||||
#define TERMP_BRIND (1 << 10) /* See term_flushln(). */
|
||||
#define TERMP_DANGLE (1 << 11) /* See term_flushln(). */
|
||||
#define TERMP_HANG (1 << 12) /* See term_flushln(). */
|
||||
#define TERMP_HANG (1 << 11) /* See term_flushln(). */
|
||||
#define TERMP_NOPAD (1 << 12) /* See term_flushln(). */
|
||||
#define TERMP_NOSPLIT (1 << 13) /* Do not break line before .An. */
|
||||
#define TERMP_SPLIT (1 << 14) /* Break line before .An. */
|
||||
#define TERMP_NONEWLINE (1 << 15) /* No line break in nofill mode. */
|
||||
int *buf; /* Output buffer. */
|
||||
#define TERMP_BRNEVER (1 << 16) /* Don't even break at maxrmargin. */
|
||||
#define TERMP_NOBUF (1 << 17) /* Bypass output buffer. */
|
||||
#define TERMP_NEWMC (1 << 18) /* No .mc printed yet. */
|
||||
#define TERMP_ENDMC (1 << 19) /* Next break ends .mc mode. */
|
||||
enum termtype type; /* Terminal, PS, or PDF. */
|
||||
enum termenc enc; /* Type of encoding. */
|
||||
enum termfont fontl; /* Last font set. */
|
||||
enum termfont *fontq; /* Symmetric fonts. */
|
||||
@ -102,15 +116,15 @@ struct termp {
|
||||
int (*hspan)(const struct termp *,
|
||||
const struct roffsu *);
|
||||
const void *argf; /* arg for headf/footf */
|
||||
const char *mc; /* Margin character. */
|
||||
struct termp_ps *ps;
|
||||
};
|
||||
|
||||
|
||||
struct tbl_span;
|
||||
struct eqn;
|
||||
|
||||
const char *ascii_uc2str(int);
|
||||
|
||||
void roff_term_pre(struct termp *, const struct roff_node *);
|
||||
|
||||
void term_eqn(struct termp *, const struct eqn *);
|
||||
void term_tbl(struct termp *, const struct tbl_span *);
|
||||
void term_free(struct termp *);
|
||||
@ -128,6 +142,9 @@ int term_vspan(const struct termp *, const struct roffsu *);
|
||||
size_t term_strlen(const struct termp *, const char *);
|
||||
size_t term_len(const struct termp *, size_t);
|
||||
|
||||
void term_tab_set(const struct termp *, const char *);
|
||||
size_t term_tab_next(size_t);
|
||||
|
||||
void term_fontpush(struct termp *, enum termfont);
|
||||
void term_fontpop(struct termp *);
|
||||
void term_fontpopq(struct termp *, int);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: term_ascii.c,v 1.54 2016/07/31 09:29:13 schwarze Exp $ */
|
||||
/* $Id: term_ascii.c,v 1.57 2017/06/07 17:38:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -65,13 +65,14 @@ ascii_init(enum termenc enc, const struct manoutput *outopts)
|
||||
#endif
|
||||
struct termp *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct termp));
|
||||
p = mandoc_calloc(1, sizeof(*p));
|
||||
p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol));
|
||||
p->maxtcol = 1;
|
||||
|
||||
p->line = 1;
|
||||
p->tabwidth = 5;
|
||||
p->defrmargin = p->lastrmargin = 78;
|
||||
p->fontq = mandoc_reallocarray(NULL,
|
||||
(p->fontsz = 8), sizeof(enum termfont));
|
||||
(p->fontsz = 8), sizeof(*p->fontq));
|
||||
p->fontq[0] = p->fontl = TERMFONT_NONE;
|
||||
|
||||
p->begin = ascii_begin;
|
||||
@ -149,7 +150,7 @@ ascii_setwidth(struct termp *p, int iop, int width)
|
||||
{
|
||||
|
||||
width /= 24;
|
||||
p->rmargin = p->defrmargin;
|
||||
p->tcol->rmargin = p->defrmargin;
|
||||
if (iop > 0)
|
||||
p->defrmargin += width;
|
||||
else if (iop == 0)
|
||||
@ -158,8 +159,8 @@ ascii_setwidth(struct termp *p, int iop, int width)
|
||||
p->defrmargin -= width;
|
||||
else
|
||||
p->defrmargin = 0;
|
||||
p->lastrmargin = p->rmargin;
|
||||
p->rmargin = p->maxrmargin = p->defrmargin;
|
||||
p->lastrmargin = p->tcol->rmargin;
|
||||
p->tcol->rmargin = p->maxrmargin = p->defrmargin;
|
||||
}
|
||||
|
||||
void
|
||||
@ -216,6 +217,8 @@ ascii_endline(struct termp *p)
|
||||
{
|
||||
|
||||
p->line++;
|
||||
p->tcol->offset -= p->ti;
|
||||
p->ti = 0;
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
@ -370,6 +373,8 @@ locale_endline(struct termp *p)
|
||||
{
|
||||
|
||||
p->line++;
|
||||
p->tcol->offset -= p->ti;
|
||||
p->ti = 0;
|
||||
putwchar(L'\n');
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: term_ps.c,v 1.83 2017/02/17 14:31:52 schwarze Exp $ */
|
||||
/* $Id: term_ps.c,v 1.85 2017/06/07 17:38:26 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
|
||||
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -538,12 +538,15 @@ pspdf_alloc(const struct manoutput *outopts)
|
||||
size_t marginx, marginy, lineheight;
|
||||
const char *pp;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct termp));
|
||||
p = mandoc_calloc(1, sizeof(*p));
|
||||
p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol));
|
||||
p->maxtcol = 1;
|
||||
|
||||
p->enc = TERMENC_ASCII;
|
||||
p->fontq = mandoc_reallocarray(NULL,
|
||||
(p->fontsz = 8), sizeof(enum termfont));
|
||||
(p->fontsz = 8), sizeof(*p->fontq));
|
||||
p->fontq[0] = p->fontl = TERMFONT_NONE;
|
||||
p->ps = mandoc_calloc(1, sizeof(struct termp_ps));
|
||||
p->ps = mandoc_calloc(1, sizeof(*p->ps));
|
||||
|
||||
p->advance = ps_advance;
|
||||
p->begin = ps_begin;
|
||||
@ -1219,6 +1222,9 @@ ps_endline(struct termp *p)
|
||||
}
|
||||
|
||||
ps_closepage(p);
|
||||
|
||||
p->tcol->offset -= p->ti;
|
||||
p->ti = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
117
contrib/mdocml/term_tab.c
Normal file
117
contrib/mdocml/term_tab.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* $OpenBSD: term.c,v 1.119 2017/01/08 18:08:44 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* 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 <stddef.h>
|
||||
|
||||
#include "mandoc_aux.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
|
||||
struct tablist {
|
||||
size_t *t; /* Allocated array of tab positions. */
|
||||
size_t s; /* Allocated number of positions. */
|
||||
size_t n; /* Currently used number of positions. */
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct tablist a; /* All tab positions for lookup. */
|
||||
struct tablist p; /* Periodic tab positions to add. */
|
||||
size_t d; /* Default tab width in units of n. */
|
||||
} tabs;
|
||||
|
||||
|
||||
void
|
||||
term_tab_set(const struct termp *p, const char *arg)
|
||||
{
|
||||
static int recording_period;
|
||||
|
||||
struct roffsu su;
|
||||
struct tablist *tl;
|
||||
size_t pos;
|
||||
int add;
|
||||
|
||||
/* Special arguments: clear all tabs or switch lists. */
|
||||
|
||||
if (arg == NULL) {
|
||||
tabs.a.n = tabs.p.n = 0;
|
||||
recording_period = 0;
|
||||
if (tabs.d == 0) {
|
||||
a2roffsu(".8i", &su, SCALE_IN);
|
||||
tabs.d = term_hspan(p, &su) / 24;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (arg[0] == 'T' && arg[1] == '\0') {
|
||||
recording_period = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse the sign, the number, and the unit. */
|
||||
|
||||
if (*arg == '+') {
|
||||
add = 1;
|
||||
arg++;
|
||||
} else
|
||||
add = 0;
|
||||
if (a2roffsu(arg, &su, SCALE_EM) == NULL)
|
||||
return;
|
||||
|
||||
/* Select the list, and extend it if it is full. */
|
||||
|
||||
tl = recording_period ? &tabs.p : &tabs.a;
|
||||
if (tl->n >= tl->s) {
|
||||
tl->s += 8;
|
||||
tl->t = mandoc_reallocarray(tl->t, tl->s, sizeof(*tl->t));
|
||||
}
|
||||
|
||||
/* Append the new position. */
|
||||
|
||||
pos = term_hspan(p, &su);
|
||||
tl->t[tl->n] = pos;
|
||||
if (add && tl->n)
|
||||
tl->t[tl->n] += tl->t[tl->n - 1];
|
||||
tl->n++;
|
||||
}
|
||||
|
||||
size_t
|
||||
term_tab_next(size_t prev)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (i == tabs.a.n) {
|
||||
if (tabs.p.n == 0)
|
||||
return prev;
|
||||
/*
|
||||
return i ? prev :
|
||||
(prev / tabs.d + 1) * tabs.d;
|
||||
*/
|
||||
tabs.a.n += tabs.p.n;
|
||||
if (tabs.a.s < tabs.a.n) {
|
||||
tabs.a.s = tabs.a.n;
|
||||
tabs.a.t = mandoc_reallocarray(tabs.a.t,
|
||||
tabs.a.s, sizeof(*tabs.a.t));
|
||||
}
|
||||
for (j = 0; j < tabs.p.n; j++)
|
||||
tabs.a.t[i + j] = tabs.p.t[j] +
|
||||
(i ? tabs.a.t[i - 1] : 0);
|
||||
}
|
||||
if (prev < tabs.a.t[i] / 24)
|
||||
return tabs.a.t[i] / 24;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tree.c,v 1.73 2017/02/10 15:45:28 schwarze Exp $ */
|
||||
/* $Id: tree.c,v 1.74 2017/04/24 23:06:18 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@ -129,23 +129,23 @@ print_mdoc(const struct roff_node *n, int indent)
|
||||
p = n->string;
|
||||
break;
|
||||
case ROFFT_BODY:
|
||||
p = mdoc_macronames[n->tok];
|
||||
p = roff_name[n->tok];
|
||||
break;
|
||||
case ROFFT_HEAD:
|
||||
p = mdoc_macronames[n->tok];
|
||||
p = roff_name[n->tok];
|
||||
break;
|
||||
case ROFFT_TAIL:
|
||||
p = mdoc_macronames[n->tok];
|
||||
p = roff_name[n->tok];
|
||||
break;
|
||||
case ROFFT_ELEM:
|
||||
p = mdoc_macronames[n->tok];
|
||||
p = roff_name[n->tok];
|
||||
if (n->args) {
|
||||
argv = n->args->argv;
|
||||
argc = n->args->argc;
|
||||
}
|
||||
break;
|
||||
case ROFFT_BLOCK:
|
||||
p = mdoc_macronames[n->tok];
|
||||
p = roff_name[n->tok];
|
||||
if (n->args) {
|
||||
argv = n->args->argv;
|
||||
argc = n->args->argc;
|
||||
@ -257,7 +257,7 @@ print_man(const struct roff_node *n, int indent)
|
||||
case ROFFT_BLOCK:
|
||||
case ROFFT_HEAD:
|
||||
case ROFFT_BODY:
|
||||
p = man_macronames[n->tok];
|
||||
p = roff_name[n->tok];
|
||||
break;
|
||||
case ROFFT_ROOT:
|
||||
p = "root";
|
||||
|
@ -17,7 +17,6 @@ LINKS= ${BINDIR}/mandoc ${BINDIR}/whatis \
|
||||
.endif
|
||||
|
||||
LIBMAN_SRCS= man.c \
|
||||
man_hash.c \
|
||||
man_macro.c \
|
||||
man_validate.c
|
||||
|
||||
@ -25,14 +24,17 @@ LIBMDOC_SRCS= att.c \
|
||||
lib.c \
|
||||
mdoc.c \
|
||||
mdoc_argv.c \
|
||||
mdoc_hash.c \
|
||||
mdoc_macro.c \
|
||||
mdoc_markdown.c \
|
||||
mdoc_state.c \
|
||||
mdoc_validate.c \
|
||||
st.c \
|
||||
|
||||
LIBROFF_SRCS= eqn.c \
|
||||
roff.c \
|
||||
roff_html.c \
|
||||
roff_term.c \
|
||||
roff_validate.c \
|
||||
tbl.c \
|
||||
tbl_data.c \
|
||||
tbl_layout.c \
|
||||
@ -63,6 +65,7 @@ TERM_SRCS= eqn_term.c \
|
||||
term.c \
|
||||
term_ascii.c \
|
||||
term_ps.c \
|
||||
term_tab.c \
|
||||
tbl_term.c
|
||||
|
||||
DBM_SRCS= dbm.c \
|
||||
|
Loading…
Reference in New Issue
Block a user