imported code harmonisation
. common/include/arch/i386 is not actually an imported sys/arch/i386/include but leftover Minix files; remove and move to include/ . move include/ufs to sys/ufs, where it came from, now that we have a sys/ hierarchy . move mdocml/ to external/bsd/, now we have that . single sys/arch/i386/stand/ import for boot stuff
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
.include <bsd.own.mk>
|
||||
|
||||
# NetBSD imports
|
||||
SUBDIR= indent m4 stat tic sed mkdep uniq seq du man mdocml \
|
||||
SUBDIR= indent m4 stat tic sed mkdep uniq seq du man \
|
||||
apropos chpass newgrp passwd bzip2 bzip2recover gzip
|
||||
|
||||
# Non-NetBSD imports
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.1 2009/10/21 18:04:52 joerg Exp $
|
||||
|
||||
SUBDIR= lib .WAIT bin man
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
@@ -1,25 +0,0 @@
|
||||
# $NetBSD: Makefile.inc,v 1.12 2010/07/25 19:16:18 joerg Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
.include "../Makefile.inc"
|
||||
|
||||
VERSION!= cd ${.PARSEDIR}/dist && ${MAKE} -V VERSION
|
||||
|
||||
CPPFLAGS+= -DVERSION=\"${VERSION}\" -DUGLY
|
||||
CPPFLAGS+= -DOSNAME=\"Minix\"
|
||||
|
||||
.if (${HOSTPROG:U} == "")
|
||||
CPPFLAGE+= -DHAVE_STRLCAT -DHAVE_STRLCPY
|
||||
.endif
|
||||
|
||||
|
||||
DISTDIR:= ${.PARSEDIR}/dist
|
||||
|
||||
.PATH: ${DISTDIR}
|
||||
|
||||
.for _LIB in man mdoc roff
|
||||
MDOCMLOBJDIR.${_LIB} != cd ${.PARSEDIR}/lib/lib${_LIB} && ${PRINTOBJDIR}
|
||||
MDOCMLLIB.${_LIB}= ${MDOCMLOBJDIR.${_LIB}}/lib${_LIB}.a
|
||||
.endfor
|
||||
|
||||
WARNS?= 4
|
||||
@@ -1,5 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.1 2009/10/21 18:04:52 joerg Exp $
|
||||
|
||||
SUBDIR= mandoc
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
@@ -1,5 +0,0 @@
|
||||
# $NetBSD: Makefile.inc,v 1.2 2009/10/21 22:33:12 joerg Exp $
|
||||
|
||||
BINDIR?= /usr/bin
|
||||
|
||||
.include "${.PARSEDIR}/../Makefile.inc"
|
||||
@@ -1,24 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.4 2011/01/12 23:02:21 joerg Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= mandoc
|
||||
|
||||
SRCS= main.c mdoc_term.c chars.c term.c term_ascii.c term_ps.c \
|
||||
tbl_term.c tbl_html.c tree.c compat.c \
|
||||
man_term.c html.c mdoc_html.c man_html.c out.c
|
||||
|
||||
.ifndef HOSTPROG
|
||||
DPADD+= ${MDOCMLLIB.man} ${MDOCMLLIB.mdoc} ${MDOCMLLIB.roff}
|
||||
LDADD+= -L${MDOCMLOBJDIR.man} -lman \
|
||||
-L${MDOCMLOBJDIR.mdoc} -lmdoc \
|
||||
-L${MDOCMLOBJDIR.roff} -lroff
|
||||
.else
|
||||
SRCS.libman!= cd ${.PARSEDIR}/../../lib/libman && ${MAKE} -V '$${SRCS}'
|
||||
SRCS.libmdoc!= cd ${.PARSEDIR}/../../lib/libmdoc && ${MAKE} -V '$${SRCS}'
|
||||
SRCS.libroff!= cd ${.PARSEDIR}/../../lib/libroff && ${MAKE} -V '$${SRCS}'
|
||||
|
||||
SRCS+= ${SRCS.libman} ${SRCS.libmdoc:Nmandoc.c} ${SRCS.libroff}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
346
usr.bin/mdocml/dist/Makefile
vendored
346
usr.bin/mdocml/dist/Makefile
vendored
@@ -1,346 +0,0 @@
|
||||
.SUFFIXES: .html .xml .sgml .1 .3 .7 .md5 .tar.gz
|
||||
.SUFFIXES: .1.txt .3.txt .7.txt
|
||||
.SUFFIXES: .1.xhtml .3.xhtml .7.xhtml
|
||||
.SUFFIXES: .1.sgml .3.sgml .7.sgml
|
||||
.SUFFIXES: .h .h.html
|
||||
.SUFFIXES: .1.ps .3.ps .7.ps
|
||||
.SUFFIXES: .1.pdf .3.pdf .7.pdf
|
||||
|
||||
PREFIX = /usr/local
|
||||
BINDIR = $(PREFIX)/bin
|
||||
INCLUDEDIR = $(PREFIX)/include
|
||||
LIBDIR = $(PREFIX)/lib
|
||||
MANDIR = $(PREFIX)/man
|
||||
EXAMPLEDIR = $(PREFIX)/share/examples/mandoc
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = $(INSTALL) -m 0755
|
||||
INSTALL_DATA = $(INSTALL) -m 0444
|
||||
INSTALL_LIB = $(INSTALL) -m 0644
|
||||
INSTALL_MAN = $(INSTALL_DATA)
|
||||
|
||||
VERSION = 1.10.9
|
||||
VDATE = 07 January 2010
|
||||
|
||||
VFLAGS = -DVERSION="\"$(VERSION)\""
|
||||
WFLAGS = -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings
|
||||
CFLAGS += -g $(WFLAGS) $(VFLAGS) -DHAVE_CONFIG_H
|
||||
|
||||
# Specify this if you want to hard-code the operating system to appear
|
||||
# in the lower-left hand corner of -mdoc manuals.
|
||||
# CFLAGS += -DOSNAME="\"OpenBSD 4.5\""
|
||||
CFLAGS += -DOSNAME="\"Minix\""
|
||||
|
||||
LINTFLAGS += $(VFLAGS)
|
||||
|
||||
ROFFLNS = roff.ln tbl.ln tbl_opts.ln tbl_layout.ln tbl_data.ln
|
||||
|
||||
ROFFSRCS = roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c
|
||||
|
||||
ROFFOBJS = roff.o tbl.o tbl_opts.o tbl_layout.o tbl_data.o
|
||||
|
||||
MANDOCLNS = mandoc.ln
|
||||
|
||||
MANDOCSRCS = mandoc.c
|
||||
|
||||
MANDOCOBJS = mandoc.o
|
||||
|
||||
MDOCLNS = mdoc_macro.ln mdoc.ln mdoc_hash.ln mdoc_strings.ln \
|
||||
mdoc_argv.ln mdoc_validate.ln \
|
||||
lib.ln att.ln arch.ln vol.ln msec.ln st.ln
|
||||
|
||||
MDOCOBJS = mdoc_macro.o mdoc.o mdoc_hash.o mdoc_strings.o \
|
||||
mdoc_argv.o mdoc_validate.o lib.o att.o \
|
||||
arch.o vol.o msec.o st.o
|
||||
|
||||
MDOCSRCS = mdoc_macro.c mdoc.c mdoc_hash.c mdoc_strings.c \
|
||||
mdoc_argv.c mdoc_validate.c lib.c att.c \
|
||||
arch.c vol.c msec.c st.c
|
||||
|
||||
MANLNS = man_macro.ln man.ln man_hash.ln man_validate.ln \
|
||||
man_argv.ln
|
||||
|
||||
MANOBJS = man_macro.o man.o man_hash.o man_validate.o \
|
||||
man_argv.o
|
||||
MANSRCS = man_macro.c man.c man_hash.c man_validate.c \
|
||||
man_argv.c
|
||||
|
||||
MAINLNS = main.ln mdoc_term.ln chars.ln term.ln tree.ln \
|
||||
compat.ln man_term.ln html.ln mdoc_html.ln \
|
||||
man_html.ln out.ln term_ps.ln term_ascii.ln \
|
||||
tbl_term.ln tbl_html.ln
|
||||
|
||||
MAINOBJS = main.o mdoc_term.o chars.o term.o tree.o compat.o \
|
||||
man_term.o html.o mdoc_html.o man_html.o out.o \
|
||||
term_ps.o term_ascii.o tbl_term.o tbl_html.o
|
||||
|
||||
MAINSRCS = main.c mdoc_term.c chars.c term.c tree.c compat.c \
|
||||
man_term.c html.c mdoc_html.c man_html.c out.c \
|
||||
term_ps.c term_ascii.c tbl_term.c tbl_html.c
|
||||
|
||||
LLNS = llib-llibmdoc.ln llib-llibman.ln llib-lmandoc.ln \
|
||||
llib-llibmandoc.ln llib-llibroff.ln
|
||||
|
||||
LNS = $(MAINLNS) $(MDOCLNS) $(MANLNS) \
|
||||
$(MANDOCLNS) $(ROFFLNS)
|
||||
|
||||
LIBS = libmdoc.a libman.a libmandoc.a libroff.a
|
||||
|
||||
OBJS = $(MDOCOBJS) $(MAINOBJS) $(MANOBJS) \
|
||||
$(MANDOCOBJS) $(ROFFOBJS)
|
||||
|
||||
SRCS = $(MDOCSRCS) $(MAINSRCS) $(MANSRCS) \
|
||||
$(MANDOCSRCS) $(ROFFSRCS)
|
||||
|
||||
DATAS = arch.in att.in lib.in msec.in st.in \
|
||||
vol.in chars.in
|
||||
|
||||
HEADS = mdoc.h libmdoc.h man.h libman.h term.h \
|
||||
libmandoc.h html.h chars.h out.h main.h roff.h \
|
||||
mandoc.h libroff.h
|
||||
|
||||
GSGMLS = mandoc.1.sgml mdoc.3.sgml mdoc.7.sgml \
|
||||
mandoc_char.7.sgml man.7.sgml man.3.sgml roff.7.sgml \
|
||||
roff.3.sgml tbl.7.sgml
|
||||
|
||||
SGMLS = index.sgml
|
||||
|
||||
XHTMLS = mandoc.1.xhtml mdoc.3.xhtml \
|
||||
man.3.xhtml mdoc.7.xhtml man.7.xhtml mandoc_char.7.xhtml \
|
||||
roff.7.xhtml roff.3.xhtml tbl.7.xhtml
|
||||
|
||||
HTMLS = ChangeLog.html index.html man.h.html mdoc.h.html \
|
||||
mandoc.h.html roff.h.html mandoc.1.html mdoc.3.html \
|
||||
man.3.html mdoc.7.html man.7.html mandoc_char.7.html \
|
||||
roff.7.html roff.3.html tbl.7.html
|
||||
|
||||
PSS = mandoc.1.ps mdoc.3.ps man.3.ps mdoc.7.ps man.7.ps \
|
||||
mandoc_char.7.ps roff.7.ps roff.3.ps tbl.7.ps
|
||||
|
||||
PDFS = mandoc.1.pdf mdoc.3.pdf man.3.pdf mdoc.7.pdf man.7.pdf \
|
||||
mandoc_char.7.pdf roff.7.pdf roff.3.pdf tbl.7.pdf
|
||||
|
||||
XSLS = ChangeLog.xsl
|
||||
|
||||
TEXTS = mandoc.1.txt mdoc.3.txt man.3.txt mdoc.7.txt man.7.txt \
|
||||
mandoc_char.7.txt ChangeLog.txt \
|
||||
roff.7.txt roff.3.txt tbl.7.txt
|
||||
|
||||
EXAMPLES = example.style.css
|
||||
|
||||
XMLS = ChangeLog.xml
|
||||
|
||||
STATICS = index.css style.css external.png
|
||||
|
||||
MD5S = mdocml-$(VERSION).md5
|
||||
|
||||
TARGZS = mdocml-$(VERSION).tar.gz
|
||||
|
||||
MANS = mandoc.1 mdoc.3 mdoc.7 mandoc_char.7 man.7 \
|
||||
man.3 roff.7 roff.3 tbl.7
|
||||
|
||||
BINS = mandoc
|
||||
|
||||
TESTS = test-strlcat.c test-strlcpy.c
|
||||
|
||||
CONFIGS = config.h.pre config.h.post
|
||||
|
||||
DOCLEAN = $(BINS) $(LNS) $(LLNS) $(LIBS) $(OBJS) $(HTMLS) \
|
||||
$(TARGZS) tags $(MD5S) $(XMLS) $(TEXTS) $(GSGMLS) \
|
||||
config.h config.log $(PSS) $(PDFS) $(XHTMLS)
|
||||
|
||||
DOINSTALL = $(SRCS) $(HEADS) Makefile $(MANS) $(SGMLS) $(STATICS) \
|
||||
$(DATAS) $(XSLS) $(EXAMPLES) $(TESTS) $(CONFIGS)
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
lint: $(LLNS)
|
||||
|
||||
clean:
|
||||
rm -f $(DOCLEAN)
|
||||
|
||||
dist: mdocml-$(VERSION).tar.gz
|
||||
|
||||
www: all $(GSGMLS) $(HTMLS) $(XHTMLS) $(TEXTS) $(MD5S) $(TARGZS) $(PSS) $(PDFS)
|
||||
|
||||
ps: $(PSS)
|
||||
|
||||
pdf: $(PDFS)
|
||||
|
||||
installwww: www
|
||||
$(INSTALL_DATA) $(HTMLS) $(XHTMLS) $(PSS) $(PDFS) $(TEXTS) $(STATICS) $(DESTDIR)$(PREFIX)/
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).tar.gz $(DESTDIR)$(PREFIX)/snapshots/
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).md5 $(DESTDIR)$(PREFIX)/snapshots/
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).tar.gz $(DESTDIR)$(PREFIX)/snapshots/mdocml.tar.gz
|
||||
$(INSTALL_DATA) mdocml-$(VERSION).md5 $(DESTDIR)$(PREFIX)/snapshots/mdocml.md5
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)$(BINDIR)
|
||||
mkdir -p $(DESTDIR)$(EXAMPLEDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man7
|
||||
$(INSTALL_PROGRAM) mandoc $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL_MAN) mandoc.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL_MAN) man.7 mdoc.7 roff.7 tbl.7 mandoc_char.7 $(DESTDIR)$(MANDIR)/man7
|
||||
$(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR)
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(BINDIR)/mandoc
|
||||
rm -f $(DESTDIR)$(MANDIR)/man1/mandoc.1
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/mdoc.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/roff.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/tbl.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/man.7
|
||||
rm -f $(DESTDIR)$(MANDIR)/man7/mandoc_char.7
|
||||
rm -f $(DESTDIR)$(EXAMPLEDIR)/example.style.css
|
||||
|
||||
$(OBJS): config.h
|
||||
|
||||
$(LNS): config.h
|
||||
|
||||
man_macro.ln man_macro.o: man_macro.c libman.h
|
||||
|
||||
lib.ln lib.o: lib.c lib.in libmdoc.h
|
||||
|
||||
att.ln att.o: att.c att.in libmdoc.h
|
||||
|
||||
arch.ln arch.o: arch.c arch.in libmdoc.h
|
||||
|
||||
vol.ln vol.o: vol.c vol.in libmdoc.h
|
||||
|
||||
chars.ln chars.o: chars.c chars.in chars.h
|
||||
|
||||
msec.ln msec.o: msec.c msec.in libmdoc.h
|
||||
|
||||
st.ln st.o: st.c st.in libmdoc.h
|
||||
|
||||
mdoc_macro.ln mdoc_macro.o: mdoc_macro.c libmdoc.h
|
||||
|
||||
mdoc_term.ln mdoc_term.o: mdoc_term.c term.h mdoc.h
|
||||
|
||||
mdoc_strings.ln mdoc_strings.o: mdoc_strings.c libmdoc.h
|
||||
|
||||
man_hash.ln man_hash.o: man_hash.c libman.h
|
||||
|
||||
mdoc_hash.ln mdoc_hash.o: mdoc_hash.c libmdoc.h
|
||||
|
||||
mdoc.ln mdoc.o: mdoc.c libmdoc.h
|
||||
|
||||
man.ln man.o: man.c libman.h
|
||||
|
||||
main.ln main.o: main.c mdoc.h man.h roff.h
|
||||
|
||||
compat.ln compat.o: compat.c
|
||||
|
||||
term.ln term.o: term.c term.h man.h mdoc.h chars.h
|
||||
|
||||
term_ps.ln term_ps.o: term_ps.c term.h main.h
|
||||
|
||||
term_ascii.ln term_ascii.o: term_ascii.c term.h main.h
|
||||
|
||||
html.ln html.o: html.c html.h chars.h
|
||||
|
||||
mdoc_html.ln mdoc_html.o: mdoc_html.c html.h mdoc.h
|
||||
|
||||
man_html.ln man_html.o: man_html.c html.h man.h out.h
|
||||
|
||||
out.ln out.o: out.c out.h
|
||||
|
||||
mandoc.ln mandoc.o: mandoc.c libmandoc.h
|
||||
|
||||
tree.ln tree.o: tree.c man.h mdoc.h
|
||||
|
||||
mdoc_argv.ln mdoc_argv.o: mdoc_argv.c libmdoc.h
|
||||
|
||||
man_argv.ln man_argv.o: man_argv.c libman.h
|
||||
|
||||
man_validate.ln man_validate.o: man_validate.c libman.h
|
||||
|
||||
mdoc_validate.ln mdoc_validate.o: mdoc_validate.c libmdoc.h
|
||||
|
||||
libmdoc.h: mdoc.h
|
||||
|
||||
ChangeLog.xml:
|
||||
cvs2cl --xml --xml-encoding iso-8859-15 -t --noxmlns -f $@
|
||||
|
||||
ChangeLog.txt:
|
||||
cvs2cl -t -f $@
|
||||
|
||||
ChangeLog.html: ChangeLog.xml ChangeLog.xsl
|
||||
xsltproc -o $@ ChangeLog.xsl ChangeLog.xml
|
||||
|
||||
mdocml-$(VERSION).tar.gz: $(DOINSTALL)
|
||||
mkdir -p .dist/mdocml/mdocml-$(VERSION)/
|
||||
cp -f $(DOINSTALL) .dist/mdocml/mdocml-$(VERSION)/
|
||||
( cd .dist/mdocml/ && tar zcf ../../$@ mdocml-$(VERSION)/ )
|
||||
rm -rf .dist/
|
||||
|
||||
llib-llibmdoc.ln: $(MDOCLNS)
|
||||
$(LINT) -Clibmdoc $(MDOCLNS)
|
||||
|
||||
llib-llibman.ln: $(MANLNS)
|
||||
$(LINT) -Clibman $(MANLNS)
|
||||
|
||||
llib-llibmandoc.ln: $(MANDOCLNS)
|
||||
$(LINT) -Clibmandoc $(MANDOCLNS)
|
||||
|
||||
llib-llibroff.ln: $(ROFFLNS)
|
||||
$(LINT) -Clibroff $(ROFFLNS)
|
||||
|
||||
llib-lmandoc.ln: $(MAINLNS) llib-llibmdoc.ln llib-llibman.ln llib-llibmandoc.ln llib-llibroff.ln
|
||||
$(LINT) -Cmandoc $(MAINLNS) llib-llibmdoc.ln llib-llibman.ln llib-llibmandoc.ln llib-llibroff.ln
|
||||
|
||||
libmdoc.a: $(MDOCOBJS)
|
||||
$(AR) rs $@ $(MDOCOBJS)
|
||||
|
||||
libman.a: $(MANOBJS)
|
||||
$(AR) rs $@ $(MANOBJS)
|
||||
|
||||
libmandoc.a: $(MANDOCOBJS)
|
||||
$(AR) rs $@ $(MANDOCOBJS)
|
||||
|
||||
libroff.a: $(ROFFOBJS)
|
||||
$(AR) rs $@ $(ROFFOBJS)
|
||||
|
||||
mandoc: $(MAINOBJS) libroff.a libmdoc.a libman.a libmandoc.a
|
||||
$(CC) $(CFLAGS) -o $@ $(MAINOBJS) libroff.a libmdoc.a libman.a libmandoc.a
|
||||
|
||||
.sgml.html:
|
||||
validate --warn $<
|
||||
sed -e "s!@VERSION@!$(VERSION)!" -e "s!@VDATE@!$(VDATE)!" $< > $@
|
||||
|
||||
.1.1.txt .3.3.txt .7.7.txt:
|
||||
./mandoc -Tascii -Wall,stop $< | col -b > $@
|
||||
|
||||
.1.1.sgml .3.3.sgml .7.7.sgml:
|
||||
./mandoc -Thtml -Wall,stop -Ostyle=style.css,man=%N.%S.html,includes=%I.html $< > $@
|
||||
|
||||
.1.1.ps .3.3.ps .7.7.ps:
|
||||
./mandoc -Tps -Wall,stop $< > $@
|
||||
|
||||
.1.1.xhtml .3.3.xhtml .7.7.xhtml:
|
||||
./mandoc -Txhtml -Wall,stop -Ostyle=style.css,man=%N.%S.xhtml,includes=%I.html $< > $@
|
||||
|
||||
.1.1.pdf .3.3.pdf .7.7.pdf:
|
||||
./mandoc -Tpdf -Wall,stop $< > $@
|
||||
|
||||
.tar.gz.md5:
|
||||
md5 $< > $@
|
||||
|
||||
.h.h.html:
|
||||
highlight -I $< >$@
|
||||
|
||||
config.h: config.h.pre config.h.post
|
||||
rm -f config.log
|
||||
( cat config.h.pre; \
|
||||
echo; \
|
||||
if $(CC) $(CFLAGS) -Werror -c test-strlcat.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_STRLCAT'; \
|
||||
rm test-strlcat.o; \
|
||||
fi; \
|
||||
if $(CC) $(CFLAGS) -Werror -c test-strlcpy.c >> config.log 2>&1; then \
|
||||
echo '#define HAVE_STRLCPY'; \
|
||||
rm test-strlcpy.o; \
|
||||
fi; \
|
||||
echo; \
|
||||
cat config.h.post \
|
||||
) > $@
|
||||
38
usr.bin/mdocml/dist/arch.c
vendored
38
usr.bin/mdocml/dist/arch.c
vendored
@@ -1,38 +0,0 @@
|
||||
/* $Vendor-Id: arch.c,v 1.8 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
if (0 == strcmp(p, x)) return(y);
|
||||
|
||||
const char *
|
||||
mdoc_a2arch(const char *p)
|
||||
{
|
||||
|
||||
#include "arch.in"
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
56
usr.bin/mdocml/dist/arch.in
vendored
56
usr.bin/mdocml/dist/arch.in
vendored
@@ -1,56 +0,0 @@
|
||||
/* $Vendor-Id: arch.in,v 1.10 2010/09/27 06:56:44 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines the architecture token of the .Dt prologue macro.
|
||||
* All architectures that your system supports (or the manuals of your
|
||||
* system) should be included here. The right-hand-side is the
|
||||
* formatted output.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
*
|
||||
* REMEMBER TO ADD NEW ARCHITECTURES TO MDOC.7!
|
||||
*/
|
||||
|
||||
LINE("alpha", "Alpha")
|
||||
LINE("amd64", "AMD64")
|
||||
LINE("amiga", "Amiga")
|
||||
LINE("arc", "ARC")
|
||||
LINE("arm", "ARM")
|
||||
LINE("armish", "ARMISH")
|
||||
LINE("aviion", "AViiON")
|
||||
LINE("hp300", "HP300")
|
||||
LINE("hppa", "HPPA")
|
||||
LINE("hppa64", "HPPA64")
|
||||
LINE("i386", "i386")
|
||||
LINE("landisk", "LANDISK")
|
||||
LINE("loongson", "Loongson")
|
||||
LINE("luna88k", "Luna88k")
|
||||
LINE("mac68k", "Mac68k")
|
||||
LINE("macppc", "MacPPC")
|
||||
LINE("mips64", "MIPS64")
|
||||
LINE("mvme68k", "MVME68k")
|
||||
LINE("mvme88k", "MVME88k")
|
||||
LINE("mvmeppc", "MVMEPPC")
|
||||
LINE("pmax", "PMAX")
|
||||
LINE("sgi", "SGI")
|
||||
LINE("socppc", "SOCPPC")
|
||||
LINE("sparc", "SPARC")
|
||||
LINE("sparc64", "SPARC64")
|
||||
LINE("sun3", "Sun3")
|
||||
LINE("vax", "VAX")
|
||||
LINE("zaurus", "Zaurus")
|
||||
38
usr.bin/mdocml/dist/att.c
vendored
38
usr.bin/mdocml/dist/att.c
vendored
@@ -1,38 +0,0 @@
|
||||
/* $Vendor-Id: att.c,v 1.8 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
if (0 == strcmp(p, x)) return(y);
|
||||
|
||||
const char *
|
||||
mdoc_a2att(const char *p)
|
||||
{
|
||||
|
||||
#include "att.in"
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
37
usr.bin/mdocml/dist/att.in
vendored
37
usr.bin/mdocml/dist/att.in
vendored
@@ -1,37 +0,0 @@
|
||||
/* $Vendor-Id: att.in,v 1.6 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines the AT&T versions of the .At macro. This probably
|
||||
* isn't going to change. The right-hand side is the formatted string.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
*/
|
||||
|
||||
LINE("v1", "Version 1 AT&T UNIX")
|
||||
LINE("v2", "Version 2 AT&T UNIX")
|
||||
LINE("v3", "Version 3 AT&T UNIX")
|
||||
LINE("v4", "Version 4 AT&T UNIX")
|
||||
LINE("v5", "Version 5 AT&T UNIX")
|
||||
LINE("v6", "Version 6 AT&T UNIX")
|
||||
LINE("v7", "Version 7 AT&T UNIX")
|
||||
LINE("32v", "Version 32V AT&T UNIX")
|
||||
LINE("V", "AT&T System V UNIX")
|
||||
LINE("V.1", "AT&T System V.1 UNIX")
|
||||
LINE("V.2", "AT&T System V.2 UNIX")
|
||||
LINE("V.3", "AT&T System V.3 UNIX")
|
||||
LINE("V.4", "AT&T System V.4 UNIX")
|
||||
243
usr.bin/mdocml/dist/chars.c
vendored
243
usr.bin/mdocml/dist/chars.c
vendored
@@ -1,243 +0,0 @@
|
||||
/* $Vendor-Id: chars.c,v 1.31 2011/01/02 10:10:57 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "chars.h"
|
||||
|
||||
#define PRINT_HI 126
|
||||
#define PRINT_LO 32
|
||||
|
||||
struct ln {
|
||||
struct ln *next;
|
||||
const char *code;
|
||||
const char *ascii;
|
||||
int unicode;
|
||||
int type;
|
||||
#define CHARS_CHAR (1 << 0)
|
||||
#define CHARS_STRING (1 << 1)
|
||||
#define CHARS_BOTH (CHARS_CHAR | CHARS_STRING)
|
||||
};
|
||||
|
||||
#define LINES_MAX 351
|
||||
|
||||
#define CHAR(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code), CHARS_CHAR },
|
||||
#define STRING(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code), CHARS_STRING },
|
||||
#define BOTH(in, ch, code) \
|
||||
{ NULL, (in), (ch), (code), CHARS_BOTH },
|
||||
|
||||
#define CHAR_TBL_START static struct ln lines[LINES_MAX] = {
|
||||
#define CHAR_TBL_END };
|
||||
|
||||
#include "chars.in"
|
||||
|
||||
struct ctab {
|
||||
enum chars type;
|
||||
struct ln **htab;
|
||||
};
|
||||
|
||||
static inline int match(const struct ln *,
|
||||
const char *, size_t, int);
|
||||
static const struct ln *find(struct ctab *, const char *, size_t, int);
|
||||
|
||||
|
||||
void
|
||||
chars_free(void *arg)
|
||||
{
|
||||
struct ctab *tab;
|
||||
|
||||
tab = (struct ctab *)arg;
|
||||
|
||||
free(tab->htab);
|
||||
free(tab);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
chars_init(enum chars type)
|
||||
{
|
||||
struct ctab *tab;
|
||||
struct ln **htab;
|
||||
struct ln *pp;
|
||||
int i, hash;
|
||||
|
||||
/*
|
||||
* Constructs a very basic chaining hashtable. The hash routine
|
||||
* is simply the integral value of the first character.
|
||||
* Subsequent entries are chained in the order they're processed
|
||||
* (they're in-line re-ordered during lookup).
|
||||
*/
|
||||
|
||||
tab = malloc(sizeof(struct ctab));
|
||||
if (NULL == tab) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
htab = calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
|
||||
if (NULL == htab) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
for (i = 0; i < LINES_MAX; i++) {
|
||||
hash = (int)lines[i].code[0] - PRINT_LO;
|
||||
|
||||
if (NULL == (pp = htab[hash])) {
|
||||
htab[hash] = &lines[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( ; pp->next; pp = pp->next)
|
||||
/* Scan ahead. */ ;
|
||||
pp->next = &lines[i];
|
||||
}
|
||||
|
||||
tab->htab = htab;
|
||||
tab->type = type;
|
||||
return(tab);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Special character to Unicode codepoint.
|
||||
*/
|
||||
int
|
||||
chars_spec2cp(void *arg, const char *p, size_t sz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_CHAR);
|
||||
if (NULL == ln)
|
||||
return(-1);
|
||||
return(ln->unicode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reserved word to Unicode codepoint.
|
||||
*/
|
||||
int
|
||||
chars_res2cp(void *arg, const char *p, size_t sz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_STRING);
|
||||
if (NULL == ln)
|
||||
return(-1);
|
||||
return(ln->unicode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Special character to string array.
|
||||
*/
|
||||
const char *
|
||||
chars_spec2str(void *arg, const char *p, size_t sz, size_t *rsz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_CHAR);
|
||||
if (NULL == ln)
|
||||
return(NULL);
|
||||
|
||||
*rsz = strlen(ln->ascii);
|
||||
return(ln->ascii);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reserved word to string array.
|
||||
*/
|
||||
const char *
|
||||
chars_res2str(void *arg, const char *p, size_t sz, size_t *rsz)
|
||||
{
|
||||
const struct ln *ln;
|
||||
|
||||
ln = find((struct ctab *)arg, p, sz, CHARS_STRING);
|
||||
if (NULL == ln)
|
||||
return(NULL);
|
||||
|
||||
*rsz = strlen(ln->ascii);
|
||||
return(ln->ascii);
|
||||
}
|
||||
|
||||
|
||||
static const struct ln *
|
||||
find(struct ctab *tab, const char *p, size_t sz, int type)
|
||||
{
|
||||
struct ln *pp, *prev;
|
||||
struct ln **htab;
|
||||
int hash;
|
||||
|
||||
assert(p);
|
||||
if (0 == sz)
|
||||
return(NULL);
|
||||
|
||||
if (p[0] < PRINT_LO || p[0] > PRINT_HI)
|
||||
return(NULL);
|
||||
|
||||
/*
|
||||
* Lookup the symbol in the symbol hash. See ascii2htab for the
|
||||
* hashtable specs. This dynamically re-orders the hash chain
|
||||
* to optimise for repeat hits.
|
||||
*/
|
||||
|
||||
hash = (int)p[0] - PRINT_LO;
|
||||
htab = tab->htab;
|
||||
|
||||
if (NULL == (pp = htab[hash]))
|
||||
return(NULL);
|
||||
|
||||
for (prev = NULL; pp; pp = pp->next) {
|
||||
if ( ! match(pp, p, sz, type)) {
|
||||
prev = pp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
prev->next = pp->next;
|
||||
pp->next = htab[hash];
|
||||
htab[hash] = pp;
|
||||
}
|
||||
|
||||
return(pp);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
match(const struct ln *ln, const char *p, size_t sz, int type)
|
||||
{
|
||||
|
||||
if ( ! (ln->type & type))
|
||||
return(0);
|
||||
if (strncmp(ln->code, p, sz))
|
||||
return(0);
|
||||
return('\0' == ln->code[(int)sz]);
|
||||
}
|
||||
36
usr.bin/mdocml/dist/chars.h
vendored
36
usr.bin/mdocml/dist/chars.h
vendored
@@ -1,36 +0,0 @@
|
||||
/* $Vendor-Id: chars.h,v 1.6 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef CHARS_H
|
||||
#define CHARS_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
enum chars {
|
||||
CHARS_ASCII,
|
||||
CHARS_HTML
|
||||
};
|
||||
|
||||
void *chars_init(enum chars);
|
||||
const char *chars_spec2str(void *, const char *, size_t, size_t *);
|
||||
int chars_spec2cp(void *, const char *, size_t);
|
||||
const char *chars_res2str(void *, const char *, size_t, size_t *);
|
||||
int chars_res2cp(void *, const char *, size_t);
|
||||
void chars_free(void *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!CHARS_H*/
|
||||
425
usr.bin/mdocml/dist/chars.in
vendored
425
usr.bin/mdocml/dist/chars.in
vendored
@@ -1,425 +0,0 @@
|
||||
/* $Vendor-Id: chars.in,v 1.35 2010/09/15 13:10:30 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The ASCII translation tables. STRING corresponds to predefined
|
||||
* strings (cf. mdoc_samples.7 and tmac/mdoc/doc-nroff). CHAR
|
||||
* corresponds to special characters (cf. groff_char.7). BOTH contains
|
||||
* sequences that are equivalent in both STRING and CHAR.
|
||||
*
|
||||
* Either way, the left-hand side corresponds to the input sequence (\x,
|
||||
* \(xx, \*(xx and so on) whose length is listed second element. The
|
||||
* right-hand side is what's produced by the front-end, with the fourth
|
||||
* element being its length.
|
||||
*
|
||||
* XXX - C-escape strings!
|
||||
* XXX - update LINES_MAX if adding more!
|
||||
*/
|
||||
|
||||
/* Non-breaking, non-collapsing space uses unit separator. */
|
||||
static const char ascii_nbrsp[2] = { ASCII_NBRSP, '\0' };
|
||||
|
||||
CHAR_TBL_START
|
||||
|
||||
/* Spacing. */
|
||||
CHAR("c", "", 0)
|
||||
CHAR("0", " ", 8194)
|
||||
CHAR(" ", ascii_nbrsp, 160)
|
||||
CHAR("~", ascii_nbrsp, 160)
|
||||
CHAR("%", "", 0)
|
||||
CHAR("&", "", 0)
|
||||
CHAR("^", "", 0)
|
||||
CHAR("|", "", 0)
|
||||
CHAR("}", "", 0)
|
||||
|
||||
/* Accents. */
|
||||
CHAR("a\"", "\"", 779)
|
||||
CHAR("a-", "-", 175)
|
||||
CHAR("a.", ".", 729)
|
||||
CHAR("a^", "^", 770)
|
||||
BOTH("\'", "\'", 769)
|
||||
BOTH("aa", "\'", 769)
|
||||
BOTH("ga", "`", 768)
|
||||
BOTH("`", "`", 768)
|
||||
CHAR("ab", "`", 774)
|
||||
CHAR("ac", ",", 807)
|
||||
CHAR("ad", "\"", 776)
|
||||
CHAR("ah", "v", 711)
|
||||
CHAR("ao", "o", 730)
|
||||
CHAR("a~", "~", 771)
|
||||
CHAR("ho", ",", 808)
|
||||
CHAR("ha", "^", 94)
|
||||
CHAR("ti", "~", 126)
|
||||
|
||||
/* Quotes. */
|
||||
CHAR("Bq", ",,", 8222)
|
||||
CHAR("bq", ",", 8218)
|
||||
BOTH("lq", "``", 8220)
|
||||
BOTH("rq", "\'\'", 8221)
|
||||
CHAR("oq", "`", 8216)
|
||||
CHAR("cq", "\'", 8217)
|
||||
CHAR("aq", "\'", 39)
|
||||
CHAR("dq", "\"", 34)
|
||||
CHAR("Fo", "<<", 171)
|
||||
CHAR("Fc", ">>", 187)
|
||||
CHAR("fo", "<", 8249)
|
||||
CHAR("fc", ">", 8250)
|
||||
|
||||
/* Brackets. */
|
||||
CHAR("lB", "[", 91)
|
||||
CHAR("rB", "]", 93)
|
||||
CHAR("lC", "{", 123)
|
||||
CHAR("rC", "}", 125)
|
||||
CHAR("la", "<", 60)
|
||||
CHAR("ra", ">", 62)
|
||||
CHAR("bv", "|", 9130)
|
||||
CHAR("braceex", "|", 9130)
|
||||
CHAR("bracketlefttp", "|", 9121)
|
||||
CHAR("bracketleftbp", "|", 9123)
|
||||
CHAR("bracketleftex", "|", 9122)
|
||||
CHAR("bracketrighttp", "|", 9124)
|
||||
CHAR("bracketrightbp", "|", 9126)
|
||||
CHAR("bracketrightex", "|", 9125)
|
||||
CHAR("lt", ",-", 9127)
|
||||
CHAR("bracelefttp", ",-", 9127)
|
||||
CHAR("lk", "{", 9128)
|
||||
CHAR("braceleftmid", "{", 9128)
|
||||
CHAR("lb", ",-", 9129)
|
||||
CHAR("braceleftbp", "`-", 9129)
|
||||
CHAR("braceleftex", "|", 9130)
|
||||
CHAR("rt", "-.", 9131)
|
||||
CHAR("bracerighttp", "-.", 9131)
|
||||
CHAR("rk", "}", 9132)
|
||||
CHAR("bracerightmid", "}", 9132)
|
||||
CHAR("rb", "-\'", 9133)
|
||||
CHAR("bracerightbp", "-\'", 9133)
|
||||
CHAR("bracerightex", "|", 9130)
|
||||
CHAR("parenlefttp", "/", 9115)
|
||||
CHAR("parenleftbp", "\\", 9117)
|
||||
CHAR("parenleftex", "|", 9116)
|
||||
CHAR("parenrighttp", "\\", 9118)
|
||||
CHAR("parenrightbp", "/", 9120)
|
||||
CHAR("parenrightex", "|", 9119)
|
||||
|
||||
/* Greek characters. */
|
||||
CHAR("*A", "A", 913)
|
||||
CHAR("*B", "B", 914)
|
||||
CHAR("*G", "|", 915)
|
||||
CHAR("*D", "/\\", 916)
|
||||
CHAR("*E", "E", 917)
|
||||
CHAR("*Z", "Z", 918)
|
||||
CHAR("*Y", "H", 919)
|
||||
CHAR("*H", "O", 920)
|
||||
CHAR("*I", "I", 921)
|
||||
CHAR("*K", "K", 922)
|
||||
CHAR("*L", "/\\", 923)
|
||||
CHAR("*M", "M", 924)
|
||||
CHAR("*N", "N", 925)
|
||||
CHAR("*C", "H", 926)
|
||||
CHAR("*O", "O", 927)
|
||||
CHAR("*P", "TT", 928)
|
||||
CHAR("*R", "P", 929)
|
||||
CHAR("*S", ">", 931)
|
||||
CHAR("*T", "T", 932)
|
||||
CHAR("*U", "Y", 933)
|
||||
CHAR("*F", "O_", 934)
|
||||
CHAR("*X", "X", 935)
|
||||
CHAR("*Q", "Y", 936)
|
||||
CHAR("*W", "O", 937)
|
||||
CHAR("*a", "a", 945)
|
||||
CHAR("*b", "B", 946)
|
||||
CHAR("*g", "y", 947)
|
||||
CHAR("*d", "d", 948)
|
||||
CHAR("*e", "e", 949)
|
||||
CHAR("*z", "C", 950)
|
||||
CHAR("*y", "n", 951)
|
||||
CHAR("*h", "0", 952)
|
||||
CHAR("*i", "i", 953)
|
||||
CHAR("*k", "k", 954)
|
||||
CHAR("*l", "\\", 955)
|
||||
CHAR("*m", "u", 956)
|
||||
CHAR("*n", "v", 957)
|
||||
CHAR("*c", "E", 958)
|
||||
CHAR("*o", "o", 959)
|
||||
CHAR("*p", "n", 960)
|
||||
CHAR("*r", "p", 961)
|
||||
CHAR("*s", "o", 963)
|
||||
CHAR("*t", "t", 964)
|
||||
CHAR("*u", "u", 965)
|
||||
CHAR("*f", "o", 981)
|
||||
CHAR("*x", "x", 967)
|
||||
CHAR("*q", "u", 968)
|
||||
CHAR("*w", "w", 969)
|
||||
CHAR("+h", "0", 977)
|
||||
CHAR("+f", "o", 966)
|
||||
CHAR("+p", "w", 982)
|
||||
CHAR("+e", "e", 1013)
|
||||
CHAR("ts", "s", 962)
|
||||
|
||||
/* Accented letters. */
|
||||
CHAR(",C", "C", 199)
|
||||
CHAR(",c", "c", 231)
|
||||
CHAR("/L", "L", 321)
|
||||
CHAR("/O", "O", 216)
|
||||
CHAR("/l", "l", 322)
|
||||
CHAR("/o", "o", 248)
|
||||
CHAR("oA", "A", 197)
|
||||
CHAR("oa", "a", 229)
|
||||
CHAR(":A", "A", 196)
|
||||
CHAR(":E", "E", 203)
|
||||
CHAR(":I", "I", 207)
|
||||
CHAR(":O", "O", 214)
|
||||
CHAR(":U", "U", 220)
|
||||
CHAR(":a", "a", 228)
|
||||
CHAR(":e", "e", 235)
|
||||
CHAR(":i", "i", 239)
|
||||
CHAR(":o", "o", 245)
|
||||
CHAR(":u", "u", 252)
|
||||
CHAR(":y", "y", 255)
|
||||
CHAR("\'A", "A", 193)
|
||||
CHAR("\'E", "E", 201)
|
||||
CHAR("\'I", "I", 205)
|
||||
CHAR("\'O", "O", 211)
|
||||
CHAR("\'U", "U", 218)
|
||||
CHAR("\'a", "a", 225)
|
||||
CHAR("\'e", "e", 233)
|
||||
CHAR("\'i", "i", 237)
|
||||
CHAR("\'o", "o", 243)
|
||||
CHAR("\'u", "u", 250)
|
||||
CHAR("^A", "A", 194)
|
||||
CHAR("^E", "E", 202)
|
||||
CHAR("^I", "I", 206)
|
||||
CHAR("^O", "O", 212)
|
||||
CHAR("^U", "U", 219)
|
||||
CHAR("^a", "a", 226)
|
||||
CHAR("^e", "e", 234)
|
||||
CHAR("^i", "i", 238)
|
||||
CHAR("^o", "o", 244)
|
||||
CHAR("^u", "u", 251)
|
||||
CHAR("`A", "A", 192)
|
||||
CHAR("`E", "E", 200)
|
||||
CHAR("`I", "I", 204)
|
||||
CHAR("`O", "O", 210)
|
||||
CHAR("`U", "U", 217)
|
||||
CHAR("`a", "a", 224)
|
||||
CHAR("`e", "e", 232)
|
||||
CHAR("`i", "i", 236)
|
||||
CHAR("`o", "o", 242)
|
||||
CHAR("`u", "u", 249)
|
||||
CHAR("~A", "A", 195)
|
||||
CHAR("~N", "N", 209)
|
||||
CHAR("~O", "O", 213)
|
||||
CHAR("~a", "a", 227)
|
||||
CHAR("~n", "n", 241)
|
||||
CHAR("~o", "o", 245)
|
||||
|
||||
/* Arrows and lines. */
|
||||
CHAR("<-", "<-", 8592)
|
||||
CHAR("->", "->", 8594)
|
||||
CHAR("<>", "<>", 8596)
|
||||
CHAR("da", "v", 8595)
|
||||
BOTH("ua", "^", 8593)
|
||||
BOTH("va", "^v", 8597)
|
||||
CHAR("lA", "<=", 8656)
|
||||
CHAR("rA", "=>", 8658)
|
||||
CHAR("hA", "<=>", 8660)
|
||||
CHAR("dA", "v", 8659)
|
||||
CHAR("uA", "^", 8657)
|
||||
CHAR("vA", "^=v", 8661)
|
||||
|
||||
/* Logic. */
|
||||
CHAR("AN", "^", 8743)
|
||||
CHAR("OR", "v", 8744)
|
||||
CHAR("no", "~", 172)
|
||||
CHAR("tno", "~", 172)
|
||||
CHAR("te", "3", 8707)
|
||||
CHAR("fa", "V", 8704)
|
||||
CHAR("st", "-)", 8715)
|
||||
CHAR("tf", ".:.", 8756)
|
||||
CHAR("3d", ".:.", 8756)
|
||||
CHAR("or", "|", 124)
|
||||
|
||||
/* Mathematicals. */
|
||||
CHAR("pl", "+", 43)
|
||||
CHAR("mi", "-", 8722)
|
||||
CHAR("-", "-", 45)
|
||||
CHAR("-+", "-+", 8723)
|
||||
CHAR("+-", "+-", 177)
|
||||
CHAR("t+-", "+-", 177)
|
||||
CHAR("pc", ".", 183)
|
||||
CHAR("md", ".", 8901)
|
||||
CHAR("mu", "x", 215)
|
||||
CHAR("tmu", "x", 215)
|
||||
CHAR("c*", "x", 8855)
|
||||
CHAR("c+", "+", 8853)
|
||||
CHAR("di", "-:-", 247)
|
||||
CHAR("tdi", "-:-", 247)
|
||||
CHAR("f/", "/", 8260)
|
||||
CHAR("**", "*", 8727)
|
||||
BOTH("<=", "<=", 8804)
|
||||
BOTH(">=", ">=", 8805)
|
||||
CHAR("<<", "<<", 8810)
|
||||
CHAR(">>", ">>", 8811)
|
||||
CHAR("eq", "=", 61)
|
||||
CHAR("!=", "!=", 8800)
|
||||
CHAR("==", "==", 8801)
|
||||
CHAR("ne", "!==", 8802)
|
||||
CHAR("=~", "=~", 8773)
|
||||
CHAR("-~", "-~", 8771)
|
||||
CHAR("ap", "~", 8764)
|
||||
CHAR("~~", "~~", 8776)
|
||||
CHAR("~=", "~=", 8780)
|
||||
CHAR("pt", "oc", 8733)
|
||||
CHAR("es", "{}", 8709)
|
||||
CHAR("mo", "E", 8712)
|
||||
CHAR("nm", "!E", 8713)
|
||||
CHAR("sb", "(=", 8834)
|
||||
CHAR("nb", "(!=", 8836)
|
||||
CHAR("sp", "=)", 8835)
|
||||
CHAR("nc", "!=)", 8837)
|
||||
CHAR("ib", "(=", 8838)
|
||||
CHAR("ip", "=)", 8839)
|
||||
CHAR("ca", "(^)", 8745)
|
||||
CHAR("cu", "U", 8746)
|
||||
CHAR("/_", "/_", 8736)
|
||||
CHAR("pp", "_|_", 8869)
|
||||
CHAR("is", "I", 8747)
|
||||
CHAR("integral", "I", 8747)
|
||||
CHAR("sum", "E", 8721)
|
||||
CHAR("product", "TT", 8719)
|
||||
CHAR("coproduct", "U", 8720)
|
||||
CHAR("gr", "V", 8711)
|
||||
CHAR("sr", "\\/", 8730)
|
||||
CHAR("sqrt", "\\/", 8730)
|
||||
CHAR("lc", "|~", 8968)
|
||||
CHAR("rc", "~|", 8969)
|
||||
CHAR("lf", "|_", 8970)
|
||||
CHAR("rf", "_|", 8971)
|
||||
CHAR("if", "oo", 8734)
|
||||
CHAR("Ah", "N", 8501)
|
||||
CHAR("Im", "I", 8465)
|
||||
CHAR("Re", "R", 8476)
|
||||
CHAR("pd", "a", 8706)
|
||||
CHAR("-h", "/h", 8463)
|
||||
|
||||
/* Ligatures. */
|
||||
CHAR("ff", "ff", 64256)
|
||||
CHAR("fi", "fi", 64257)
|
||||
CHAR("fl", "fl", 64258)
|
||||
CHAR("Fi", "ffi", 64259)
|
||||
CHAR("Fl", "ffl", 64260)
|
||||
CHAR("AE", "AE", 198)
|
||||
CHAR("ae", "ae", 230)
|
||||
CHAR("OE", "OE", 338)
|
||||
CHAR("oe", "oe", 339)
|
||||
CHAR("ss", "ss", 223)
|
||||
CHAR("IJ", "IJ", 306)
|
||||
CHAR("ij", "ij", 307)
|
||||
|
||||
/* Special letters. */
|
||||
CHAR("-D", "D", 208)
|
||||
CHAR("Sd", "o", 240)
|
||||
CHAR("TP", "b", 222)
|
||||
CHAR("Tp", "b", 254)
|
||||
CHAR(".i", "i", 305)
|
||||
CHAR(".j", "j", 567)
|
||||
|
||||
/* Currency. */
|
||||
CHAR("Do", "$", 36)
|
||||
CHAR("ct", "c", 162)
|
||||
CHAR("Eu", "EUR", 8364)
|
||||
CHAR("eu", "EUR", 8364)
|
||||
CHAR("Ye", "Y", 165)
|
||||
CHAR("Po", "L", 163)
|
||||
CHAR("Cs", "x", 164)
|
||||
CHAR("Fn", "f", 402)
|
||||
|
||||
/* Old style. */
|
||||
STRING("Am", "&", 38)
|
||||
STRING("Ba", "|", 124)
|
||||
STRING("Ge", ">=", 8805)
|
||||
STRING("Gt", ">", 62)
|
||||
STRING("If", "infinity", 0)
|
||||
STRING("Le", "<=", 8804)
|
||||
STRING("Lq", "``", 8220)
|
||||
STRING("Lt", "<", 60)
|
||||
STRING("Na", "NaN", 0)
|
||||
STRING("Ne", "!=", 8800)
|
||||
STRING("Pi", "pi", 960)
|
||||
STRING("Pm", "+-", 177)
|
||||
STRING("Rq", "\'\'", 8221)
|
||||
STRING("left-bracket", "[", 91)
|
||||
STRING("left-parenthesis", "(", 40)
|
||||
STRING("left-singlequote", "`", 8216)
|
||||
STRING("lp", "(", 40)
|
||||
STRING("q", "\"", 34)
|
||||
STRING("quote-left", "`", 8216)
|
||||
STRING("quote-right", "\'", 8217)
|
||||
STRING("R", "(R)", 174)
|
||||
STRING("right-bracket", "]", 93)
|
||||
STRING("right-parenthesis", ")", 41)
|
||||
STRING("right-singlequote", "\'", 8217)
|
||||
STRING("rp", ")", 41)
|
||||
STRING("Tm", "(Tm)", 8482)
|
||||
|
||||
/* Lines. */
|
||||
CHAR("ba", "|", 124)
|
||||
CHAR("br", "|", 9474)
|
||||
CHAR("ul", "_", 95)
|
||||
CHAR("rl", "-", 8254)
|
||||
CHAR("bb", "|", 166)
|
||||
CHAR("sl", "/", 47)
|
||||
CHAR("rs", "\\", 92)
|
||||
|
||||
/* Text markers. */
|
||||
CHAR("ci", "o", 9675)
|
||||
CHAR("bu", "o", 8226)
|
||||
CHAR("dd", "=", 8225)
|
||||
CHAR("dg", "-", 8224)
|
||||
CHAR("lz", "<>", 9674)
|
||||
CHAR("sq", "[]", 9633)
|
||||
CHAR("ps", "9|", 182)
|
||||
CHAR("sc", "S", 167)
|
||||
CHAR("lh", "<=", 9756)
|
||||
CHAR("rh", "=>", 9758)
|
||||
CHAR("at", "@", 64)
|
||||
CHAR("sh", "#", 35)
|
||||
CHAR("CR", "_|", 8629)
|
||||
CHAR("OK", "\\/", 10003)
|
||||
|
||||
/* Legal symbols. */
|
||||
CHAR("co", "(C)", 169)
|
||||
CHAR("rg", "(R)", 174)
|
||||
CHAR("tm", "tm", 8482)
|
||||
|
||||
/* Punctuation. */
|
||||
CHAR(".", ".", 46)
|
||||
CHAR("r!", "i", 161)
|
||||
CHAR("r?", "c", 191)
|
||||
CHAR("em", "--", 8212)
|
||||
CHAR("en", "-", 8211)
|
||||
CHAR("hy", "-", 8208)
|
||||
CHAR("e", "\\", 92)
|
||||
|
||||
/* Units. */
|
||||
CHAR("de", "o", 176)
|
||||
CHAR("%0", "%o", 8240)
|
||||
CHAR("fm", "\'", 8242)
|
||||
CHAR("sd", "\"", 8243)
|
||||
CHAR("mc", "mu", 181)
|
||||
|
||||
CHAR_TBL_END
|
||||
95
usr.bin/mdocml/dist/compat.c
vendored
95
usr.bin/mdocml/dist/compat.c
vendored
@@ -1,95 +0,0 @@
|
||||
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
int dummy; /* To prevent an empty object file */
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0) {
|
||||
while (--n != 0) {
|
||||
if ((*d++ = *s++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
#endif
|
||||
25
usr.bin/mdocml/dist/config.h.post
vendored
25
usr.bin/mdocml/dist/config.h.post
vendored
@@ -1,25 +0,0 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(__BEGIN_DECLS)
|
||||
# ifdef __cplusplus
|
||||
# define __BEGIN_DECLS extern "C" {
|
||||
# else
|
||||
# define __BEGIN_DECLS
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(__END_DECLS)
|
||||
# ifdef __cplusplus
|
||||
# define __END_DECLS }
|
||||
# else
|
||||
# define __END_DECLS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
extern size_t strlcat(char *, const char *, size_t);
|
||||
#endif
|
||||
#ifndef HAVE_STRLCPY
|
||||
extern size_t strlcpy(char *, const char *, size_t);
|
||||
#endif
|
||||
|
||||
#endif /* MANDOC_CONFIG_H */
|
||||
6
usr.bin/mdocml/dist/config.h.pre
vendored
6
usr.bin/mdocml/dist/config.h.pre
vendored
@@ -1,6 +0,0 @@
|
||||
#ifndef MANDOC_CONFIG_H
|
||||
#define MANDOC_CONFIG_H
|
||||
|
||||
#if defined(__linux__) || defined(__MINT__)
|
||||
# define _GNU_SOURCE /* strptime(), getsubopt() */
|
||||
#endif
|
||||
146
usr.bin/mdocml/dist/example.style.css
vendored
146
usr.bin/mdocml/dist/example.style.css
vendored
@@ -1,146 +0,0 @@
|
||||
/* $Vendor-Id: example.style.css,v 1.41 2011/01/05 13:00:11 kristaps Exp $ */
|
||||
|
||||
/*
|
||||
* This is an example style-sheet provided for mandoc(1) and the -Thtml
|
||||
* or -Txhtml output mode.
|
||||
*
|
||||
* It mimics the appearance of the traditional cvsweb output.
|
||||
*
|
||||
* See mdoc(7) and man(7) for macro explanations.
|
||||
*/
|
||||
|
||||
html { min-width: 580px; width: 580px; }
|
||||
body { font-family: monospace; }
|
||||
|
||||
/* Preamble structure. */
|
||||
|
||||
table.foot { width: 100%; } /* Document footer. */
|
||||
td.foot-date { width: 50%; } /* Document footer: date. */
|
||||
td.foot-os { width: 50%; text-align: right; } /* Document footer: OS/source. */
|
||||
table.head { width: 100%; } /* Document header. */
|
||||
td.head-ltitle { width: 10%; } /* Document header: left-title. */
|
||||
td.head-vol { width: 80%; text-align: center; } /* Document header: volume. */
|
||||
td.head-rtitle { width: 10%; text-align: right; } /* Document header: right-title. */
|
||||
|
||||
/* Sections. */
|
||||
|
||||
h1 { margin-bottom: 0px; font-size: medium; margin-left: -4ex; } /* Section header (Sh, SH). */
|
||||
h2 { margin-bottom: 0px; font-size: medium; margin-left: -2ex; } /* Sub-section header (Ss, SS). */
|
||||
div.section { margin-bottom: 2ex; margin-left: 4ex; } /* Sections (Sh, SH). */
|
||||
div.subsection { } /* Sub-sections (Ss, SS). */
|
||||
table.synopsis { } /* SYNOPSIS section table. */
|
||||
|
||||
/* Vertical spacing. */
|
||||
|
||||
p { } /* Paragraph: Pp, Lp. */
|
||||
blockquote { margin-top: 0px; margin-bottom: 0px; }
|
||||
table { margin-top: 0px; margin-bottom: 0px; }
|
||||
td { vertical-align: top; }
|
||||
|
||||
/* General font modes. */
|
||||
|
||||
i { } /* Italic: BI, IB, I, (implicit). */
|
||||
.emph { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */
|
||||
b { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */
|
||||
.symb { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */
|
||||
small { } /* Small: SB, SM. */
|
||||
|
||||
/* Block modes. */
|
||||
|
||||
.display { } /* Top of all Bd, D1, Dl. */
|
||||
.list { } /* Top of all Bl. */
|
||||
|
||||
/* Context-specific modes. */
|
||||
|
||||
i.addr { font-weight: normal; } /* Address (Ad). */
|
||||
i.arg { font-weight: normal; } /* Command argument (Ar). */
|
||||
span.author { } /* Author name (An). */
|
||||
b.cmd { font-style: normal; } /* Command (Cm). */
|
||||
b.config { font-style: normal; } /* Config statement (Cd). */
|
||||
span.define { } /* Defines (Dv). */
|
||||
span.desc { } /* Nd. After em-dash. */
|
||||
b.diag { font-style: normal; } /* Diagnostic (Bl -diag). */
|
||||
span.env { } /* Environment variables (Ev). */
|
||||
span.errno { } /* Error string (Er). */
|
||||
i.farg { font-weight: normal; } /* Function argument (Fa, Fn). */
|
||||
i.file { font-weight: normal; } /* File (Pa). */
|
||||
b.flag { font-style: normal; } /* Flag (Fl, Cm). */
|
||||
b.fname { font-style: normal; } /* Function name (Fa, Fn, Rv). */
|
||||
i.ftype { font-weight: normal; } /* Function types (Ft, Fn). */
|
||||
b.includes { font-style: normal; } /* Header includes (In). */
|
||||
span.lib { } /* Library (Lb). */
|
||||
i.link-sec { font-weight: normal; } /* Section links (Sx). */
|
||||
code.lit { font-style: normal; font-weight: normal; } /* Literal: Dl, Li, Bf -literal, Bl -literal, Bl -unfilled. */
|
||||
b.macro { font-style: normal; } /* Macro-ish thing (Fd). */
|
||||
b.name { font-style: normal; } /* Name of utility (Nm). */
|
||||
span.opt { } /* Options (Op, Oo/Oc). */
|
||||
span.ref { } /* Citations (Rs). */
|
||||
span.ref-auth { } /* Reference author (%A). */
|
||||
i.ref-book { font-weight: normal; } /* Reference book (%B). */
|
||||
span.ref-city { } /* Reference city (%C). */
|
||||
span.ref-date { } /* Reference date (%D). */
|
||||
i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */
|
||||
i.ref-jrnl { font-weight: normal; } /* Reference journal (%J). */
|
||||
span.ref-num { } /* Reference number (%N). */
|
||||
span.ref-opt { } /* Reference optionals (%O). */
|
||||
span.ref-page { } /* Reference page (%P). */
|
||||
span.ref-corp { } /* Reference corporate/foreign author (%Q). */
|
||||
span.ref-rep { } /* Reference report (%R). */
|
||||
span.ref-title { text-decoration: underline; } /* Reference title (%T). */
|
||||
span.ref-vol { } /* Reference volume (%V). */
|
||||
span.type { font-style: italic; font-weight: normal; } /* Variable types (Vt). */
|
||||
span.unix { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */
|
||||
b.utility { font-style: normal; } /* Name of utility (Ex). */
|
||||
b.var { font-style: normal; } /* Variables (Rv). */
|
||||
|
||||
a.link-ext { } /* Off-site link (Lk). */
|
||||
a.link-includes { } /* Include-file link (In). */
|
||||
a.link-mail { } /* Mailto links (Mt). */
|
||||
a.link-man { } /* Manual links (Xr). */
|
||||
a.link-ref { } /* Reference section links (%Q). */
|
||||
a.link-sec { } /* Section links (Sx). */
|
||||
|
||||
/* Formatting for lists. See mdoc(7). */
|
||||
|
||||
dl.list-diag { }
|
||||
dt.list-diag { }
|
||||
dd.list-diag { }
|
||||
|
||||
dl.list-hang { }
|
||||
dt.list-hang { }
|
||||
dd.list-hang { }
|
||||
|
||||
dl.list-inset { }
|
||||
dt.list-inset { }
|
||||
dd.list-inset { }
|
||||
|
||||
dl.list-ohang { }
|
||||
dt.list-ohang { }
|
||||
dd.list-ohang { margin-left: 0em; }
|
||||
|
||||
dl.list-tag { }
|
||||
dt.list-tag { }
|
||||
dd.list-tag { }
|
||||
|
||||
table.list-col { }
|
||||
tr.list-col { }
|
||||
td.list-col { }
|
||||
|
||||
ul.list-bul { list-style-type: disc; padding-left: 1em; }
|
||||
li.list-bul { }
|
||||
|
||||
ul.list-dash { list-style-type: none; padding-left: 0em; }
|
||||
li.list-dash:before { content: "\2014 "; }
|
||||
|
||||
ul.list-hyph { list-style-type: none; padding-left: 0em; }
|
||||
li.list-hyph:before { content: "\2013 "; }
|
||||
|
||||
ul.list-item { list-style-type: none; padding-left: 0em; }
|
||||
li.list-item { }
|
||||
|
||||
ol.list-enum { padding-left: 2em; }
|
||||
li.list-enum { }
|
||||
|
||||
/* Table modes. See tbl(7). */
|
||||
|
||||
table.tbl { }
|
||||
7
usr.bin/mdocml/dist/external.png.uu
vendored
7
usr.bin/mdocml/dist/external.png.uu
vendored
@@ -1,7 +0,0 @@
|
||||
begin 644 external.png
|
||||
MB5!.1PT*&@H````-24A$4@````H````*"`,```"Z[#^/````%5!,5$5FF<PS
|
||||
MF<R9S/\`9LP`9O________]$Z@B5````!W123E/_______\`&DL#1@```#A)
|
||||
M1$%4&%<ERT$2`$`$`T$BZ_]/WL$<5!\DFKP%RGBT;.>RR#IR])3+$:.A0J[.
|
||||
>G@?Y%>,A'2_X`5GL`9N;Q#5F`````$E%3D2N0F""
|
||||
`
|
||||
end
|
||||
798
usr.bin/mdocml/dist/html.c
vendored
798
usr.bin/mdocml/dist/html.c
vendored
@@ -1,798 +0,0 @@
|
||||
/* $Vendor-Id: html.c,v 1.124 2010/12/27 21:41:05 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "chars.h"
|
||||
#include "html.h"
|
||||
#include "main.h"
|
||||
|
||||
struct htmldata {
|
||||
const char *name;
|
||||
int flags;
|
||||
#define HTML_CLRLINE (1 << 0)
|
||||
#define HTML_NOSTACK (1 << 1)
|
||||
#define HTML_AUTOCLOSE (1 << 2) /* Tag has auto-closure. */
|
||||
};
|
||||
|
||||
static const struct htmldata htmltags[TAG_MAX] = {
|
||||
{"html", HTML_CLRLINE}, /* TAG_HTML */
|
||||
{"head", HTML_CLRLINE}, /* TAG_HEAD */
|
||||
{"body", HTML_CLRLINE}, /* TAG_BODY */
|
||||
{"meta", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_META */
|
||||
{"title", HTML_CLRLINE}, /* TAG_TITLE */
|
||||
{"div", HTML_CLRLINE}, /* TAG_DIV */
|
||||
{"h1", 0}, /* TAG_H1 */
|
||||
{"h2", 0}, /* TAG_H2 */
|
||||
{"span", 0}, /* TAG_SPAN */
|
||||
{"link", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_LINK */
|
||||
{"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */
|
||||
{"a", 0}, /* TAG_A */
|
||||
{"table", HTML_CLRLINE}, /* TAG_TABLE */
|
||||
{"tbody", HTML_CLRLINE}, /* TAG_TBODY */
|
||||
{"col", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_COL */
|
||||
{"tr", HTML_CLRLINE}, /* TAG_TR */
|
||||
{"td", HTML_CLRLINE}, /* TAG_TD */
|
||||
{"li", HTML_CLRLINE}, /* TAG_LI */
|
||||
{"ul", HTML_CLRLINE}, /* TAG_UL */
|
||||
{"ol", HTML_CLRLINE}, /* TAG_OL */
|
||||
{"dl", HTML_CLRLINE}, /* TAG_DL */
|
||||
{"dt", HTML_CLRLINE}, /* TAG_DT */
|
||||
{"dd", HTML_CLRLINE}, /* TAG_DD */
|
||||
{"blockquote", HTML_CLRLINE}, /* TAG_BLOCKQUOTE */
|
||||
{"p", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_P */
|
||||
{"pre", HTML_CLRLINE }, /* TAG_PRE */
|
||||
{"b", 0 }, /* TAG_B */
|
||||
{"i", 0 }, /* TAG_I */
|
||||
{"code", 0 }, /* TAG_CODE */
|
||||
{"small", 0 }, /* TAG_SMALL */
|
||||
};
|
||||
|
||||
static const char *const htmlattrs[ATTR_MAX] = {
|
||||
"http-equiv", /* ATTR_HTTPEQUIV */
|
||||
"content", /* ATTR_CONTENT */
|
||||
"name", /* ATTR_NAME */
|
||||
"rel", /* ATTR_REL */
|
||||
"href", /* ATTR_HREF */
|
||||
"type", /* ATTR_TYPE */
|
||||
"media", /* ATTR_MEDIA */
|
||||
"class", /* ATTR_CLASS */
|
||||
"style", /* ATTR_STYLE */
|
||||
"width", /* ATTR_WIDTH */
|
||||
"id", /* ATTR_ID */
|
||||
"summary", /* ATTR_SUMMARY */
|
||||
"align", /* ATTR_ALIGN */
|
||||
};
|
||||
|
||||
static void print_spec(struct html *, enum roffdeco,
|
||||
const char *, size_t);
|
||||
static void print_res(struct html *, const char *, size_t);
|
||||
static void print_ctag(struct html *, enum htmltag);
|
||||
static void print_doctype(struct html *);
|
||||
static void print_xmltype(struct html *);
|
||||
static int print_encode(struct html *, const char *, int);
|
||||
static void print_metaf(struct html *, enum roffdeco);
|
||||
static void print_attr(struct html *,
|
||||
const char *, const char *);
|
||||
static void *ml_alloc(char *, enum htmltype);
|
||||
|
||||
|
||||
static void *
|
||||
ml_alloc(char *outopts, enum htmltype type)
|
||||
{
|
||||
struct html *h;
|
||||
const char *toks[4];
|
||||
char *v;
|
||||
|
||||
toks[0] = "style";
|
||||
toks[1] = "man";
|
||||
toks[2] = "includes";
|
||||
toks[3] = NULL;
|
||||
|
||||
h = calloc(1, sizeof(struct html));
|
||||
if (NULL == h) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
h->type = type;
|
||||
h->tags.head = NULL;
|
||||
h->symtab = chars_init(CHARS_HTML);
|
||||
|
||||
while (outopts && *outopts)
|
||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||
case (0):
|
||||
h->style = v;
|
||||
break;
|
||||
case (1):
|
||||
h->base_man = v;
|
||||
break;
|
||||
case (2):
|
||||
h->base_includes = v;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(h);
|
||||
}
|
||||
|
||||
void *
|
||||
html_alloc(char *outopts)
|
||||
{
|
||||
|
||||
return(ml_alloc(outopts, HTML_HTML_4_01_STRICT));
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
xhtml_alloc(char *outopts)
|
||||
{
|
||||
|
||||
return(ml_alloc(outopts, HTML_XHTML_1_0_STRICT));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
html_free(void *p)
|
||||
{
|
||||
struct tag *tag;
|
||||
struct html *h;
|
||||
|
||||
h = (struct html *)p;
|
||||
|
||||
while ((tag = h->tags.head) != NULL) {
|
||||
h->tags.head = tag->next;
|
||||
free(tag);
|
||||
}
|
||||
|
||||
if (h->symtab)
|
||||
chars_free(h->symtab);
|
||||
|
||||
free(h);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_gen_head(struct html *h)
|
||||
{
|
||||
struct htmlpair tag[4];
|
||||
|
||||
tag[0].key = ATTR_HTTPEQUIV;
|
||||
tag[0].val = "Content-Type";
|
||||
tag[1].key = ATTR_CONTENT;
|
||||
tag[1].val = "text/html; charset=utf-8";
|
||||
print_otag(h, TAG_META, 2, tag);
|
||||
|
||||
tag[0].key = ATTR_NAME;
|
||||
tag[0].val = "resource-type";
|
||||
tag[1].key = ATTR_CONTENT;
|
||||
tag[1].val = "document";
|
||||
print_otag(h, TAG_META, 2, tag);
|
||||
|
||||
if (h->style) {
|
||||
tag[0].key = ATTR_REL;
|
||||
tag[0].val = "stylesheet";
|
||||
tag[1].key = ATTR_HREF;
|
||||
tag[1].val = h->style;
|
||||
tag[2].key = ATTR_TYPE;
|
||||
tag[2].val = "text/css";
|
||||
tag[3].key = ATTR_MEDIA;
|
||||
tag[3].val = "all";
|
||||
print_otag(h, TAG_LINK, 4, tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_spec(struct html *h, enum roffdeco d, const char *p, size_t len)
|
||||
{
|
||||
int cp;
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
if ((cp = chars_spec2cp(h->symtab, p, len)) > 0) {
|
||||
printf("&#%d;", cp);
|
||||
return;
|
||||
} else if (-1 == cp && DECO_SSPECIAL == d) {
|
||||
fwrite(p, 1, len, stdout);
|
||||
return;
|
||||
} else if (-1 == cp)
|
||||
return;
|
||||
|
||||
if (NULL != (rhs = chars_spec2str(h->symtab, p, len, &sz)))
|
||||
fwrite(rhs, 1, sz, stdout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_res(struct html *h, const char *p, size_t len)
|
||||
{
|
||||
int cp;
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
if ((cp = chars_res2cp(h->symtab, p, len)) > 0) {
|
||||
printf("&#%d;", cp);
|
||||
return;
|
||||
} else if (-1 == cp)
|
||||
return;
|
||||
|
||||
if (NULL != (rhs = chars_res2str(h->symtab, p, len, &sz)))
|
||||
fwrite(rhs, 1, sz, stdout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_metaf(struct html *h, enum roffdeco deco)
|
||||
{
|
||||
enum htmlfont font;
|
||||
|
||||
switch (deco) {
|
||||
case (DECO_PREVIOUS):
|
||||
font = h->metal;
|
||||
break;
|
||||
case (DECO_ITALIC):
|
||||
font = HTMLFONT_ITALIC;
|
||||
break;
|
||||
case (DECO_BOLD):
|
||||
font = HTMLFONT_BOLD;
|
||||
break;
|
||||
case (DECO_ROMAN):
|
||||
font = HTMLFONT_NONE;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (h->metaf) {
|
||||
print_tagq(h, h->metaf);
|
||||
h->metaf = NULL;
|
||||
}
|
||||
|
||||
h->metal = h->metac;
|
||||
h->metac = font;
|
||||
|
||||
if (HTMLFONT_NONE != font)
|
||||
h->metaf = HTMLFONT_BOLD == font ?
|
||||
print_otag(h, TAG_B, 0, NULL) :
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
print_encode(struct html *h, const char *p, int norecurse)
|
||||
{
|
||||
size_t sz;
|
||||
int len, nospace;
|
||||
const char *seq;
|
||||
enum roffdeco deco;
|
||||
static const char rejs[6] = { '\\', '<', '>', '&', ASCII_HYPH, '\0' };
|
||||
|
||||
nospace = 0;
|
||||
|
||||
for (; *p; p++) {
|
||||
sz = strcspn(p, rejs);
|
||||
|
||||
fwrite(p, 1, sz, stdout);
|
||||
p += /* LINTED */
|
||||
sz;
|
||||
|
||||
if ('<' == *p) {
|
||||
printf("<");
|
||||
continue;
|
||||
} else if ('>' == *p) {
|
||||
printf(">");
|
||||
continue;
|
||||
} else if ('&' == *p) {
|
||||
printf("&");
|
||||
continue;
|
||||
} else if (ASCII_HYPH == *p) {
|
||||
/*
|
||||
* Note: "soft hyphens" aren't graphically
|
||||
* displayed when not breaking the text; we want
|
||||
* them to be displayed.
|
||||
*/
|
||||
/*printf("­");*/
|
||||
putchar('-');
|
||||
continue;
|
||||
} else if ('\0' == *p)
|
||||
break;
|
||||
|
||||
seq = ++p;
|
||||
len = a2roffdeco(&deco, &seq, &sz);
|
||||
|
||||
switch (deco) {
|
||||
case (DECO_RESERVED):
|
||||
print_res(h, seq, sz);
|
||||
break;
|
||||
case (DECO_SSPECIAL):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_SPECIAL):
|
||||
print_spec(h, deco, seq, sz);
|
||||
break;
|
||||
case (DECO_PREVIOUS):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_BOLD):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_ITALIC):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_ROMAN):
|
||||
if (norecurse)
|
||||
break;
|
||||
print_metaf(h, deco);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p += len - 1;
|
||||
|
||||
if (DECO_NOSPACE == deco && '\0' == *(p + 1))
|
||||
nospace = 1;
|
||||
}
|
||||
|
||||
return(nospace);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_attr(struct html *h, const char *key, const char *val)
|
||||
{
|
||||
printf(" %s=\"", key);
|
||||
(void)print_encode(h, val, 1);
|
||||
putchar('\"');
|
||||
}
|
||||
|
||||
|
||||
struct tag *
|
||||
print_otag(struct html *h, enum htmltag tag,
|
||||
int sz, const struct htmlpair *p)
|
||||
{
|
||||
int i;
|
||||
struct tag *t;
|
||||
|
||||
/* Push this tags onto the stack of open scopes. */
|
||||
|
||||
if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
|
||||
t = malloc(sizeof(struct tag));
|
||||
if (NULL == t) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
t->tag = tag;
|
||||
t->next = h->tags.head;
|
||||
h->tags.head = t;
|
||||
} else
|
||||
t = NULL;
|
||||
|
||||
if ( ! (HTML_NOSPACE & h->flags))
|
||||
if ( ! (HTML_CLRLINE & htmltags[tag].flags)) {
|
||||
/* Manage keeps! */
|
||||
if ( ! (HTML_KEEP & h->flags)) {
|
||||
if (HTML_PREKEEP & h->flags)
|
||||
h->flags |= HTML_KEEP;
|
||||
putchar(' ');
|
||||
} else
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
if ( ! (h->flags & HTML_NONOSPACE))
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
else
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
/* Print out the tag name and attributes. */
|
||||
|
||||
printf("<%s", htmltags[tag].name);
|
||||
for (i = 0; i < sz; i++)
|
||||
print_attr(h, htmlattrs[p[i].key], p[i].val);
|
||||
|
||||
/* Add non-overridable attributes. */
|
||||
|
||||
if (TAG_HTML == tag && HTML_XHTML_1_0_STRICT == h->type) {
|
||||
print_attr(h, "xmlns", "http://www.w3.org/1999/xhtml");
|
||||
print_attr(h, "xml:lang", "en");
|
||||
print_attr(h, "lang", "en");
|
||||
}
|
||||
|
||||
/* Accomodate for XML "well-formed" singleton escaping. */
|
||||
|
||||
if (HTML_AUTOCLOSE & htmltags[tag].flags)
|
||||
switch (h->type) {
|
||||
case (HTML_XHTML_1_0_STRICT):
|
||||
putchar('/');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
putchar('>');
|
||||
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
if ((HTML_AUTOCLOSE | HTML_CLRLINE) & htmltags[tag].flags)
|
||||
putchar('\n');
|
||||
|
||||
return(t);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_ctag(struct html *h, enum htmltag tag)
|
||||
{
|
||||
|
||||
printf("</%s>", htmltags[tag].name);
|
||||
if (HTML_CLRLINE & htmltags[tag].flags) {
|
||||
h->flags |= HTML_NOSPACE;
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_gen_decls(struct html *h)
|
||||
{
|
||||
|
||||
print_xmltype(h);
|
||||
print_doctype(h);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_xmltype(struct html *h)
|
||||
{
|
||||
|
||||
if (HTML_XHTML_1_0_STRICT == h->type)
|
||||
puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_doctype(struct html *h)
|
||||
{
|
||||
const char *doctype;
|
||||
const char *dtd;
|
||||
const char *name;
|
||||
|
||||
switch (h->type) {
|
||||
case (HTML_HTML_4_01_STRICT):
|
||||
name = "HTML";
|
||||
doctype = "-//W3C//DTD HTML 4.01//EN";
|
||||
dtd = "http://www.w3.org/TR/html4/strict.dtd";
|
||||
break;
|
||||
default:
|
||||
name = "html";
|
||||
doctype = "-//W3C//DTD XHTML 1.0 Strict//EN";
|
||||
dtd = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
|
||||
break;
|
||||
}
|
||||
|
||||
printf("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">\n",
|
||||
name, doctype, dtd);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_text(struct html *h, const char *word)
|
||||
{
|
||||
|
||||
if (word[0] && '\0' == word[1])
|
||||
switch (word[0]) {
|
||||
case('.'):
|
||||
/* FALLTHROUGH */
|
||||
case(','):
|
||||
/* FALLTHROUGH */
|
||||
case(';'):
|
||||
/* FALLTHROUGH */
|
||||
case(':'):
|
||||
/* FALLTHROUGH */
|
||||
case('?'):
|
||||
/* FALLTHROUGH */
|
||||
case('!'):
|
||||
/* FALLTHROUGH */
|
||||
case(')'):
|
||||
/* FALLTHROUGH */
|
||||
case(']'):
|
||||
if ( ! (HTML_IGNDELIM & h->flags))
|
||||
h->flags |= HTML_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! (HTML_NOSPACE & h->flags)) {
|
||||
/* Manage keeps! */
|
||||
if ( ! (HTML_KEEP & h->flags)) {
|
||||
if (HTML_PREKEEP & h->flags)
|
||||
h->flags |= HTML_KEEP;
|
||||
putchar(' ');
|
||||
} else
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
assert(NULL == h->metaf);
|
||||
if (HTMLFONT_NONE != h->metac)
|
||||
h->metaf = HTMLFONT_BOLD == h->metac ?
|
||||
print_otag(h, TAG_B, 0, NULL) :
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
|
||||
assert(word);
|
||||
if ( ! print_encode(h, word, 0))
|
||||
if ( ! (h->flags & HTML_NONOSPACE))
|
||||
h->flags &= ~HTML_NOSPACE;
|
||||
|
||||
if (h->metaf) {
|
||||
print_tagq(h, h->metaf);
|
||||
h->metaf = NULL;
|
||||
}
|
||||
|
||||
h->flags &= ~HTML_IGNDELIM;
|
||||
|
||||
/*
|
||||
* Note that we don't process the pipe: the parser sees it as
|
||||
* punctuation, but we don't in terms of typography.
|
||||
*/
|
||||
if (word[0] && '\0' == word[1])
|
||||
switch (word[0]) {
|
||||
case('('):
|
||||
/* FALLTHROUGH */
|
||||
case('['):
|
||||
h->flags |= HTML_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_tagq(struct html *h, const struct tag *until)
|
||||
{
|
||||
struct tag *tag;
|
||||
|
||||
while ((tag = h->tags.head) != NULL) {
|
||||
if (tag == h->metaf)
|
||||
h->metaf = NULL;
|
||||
print_ctag(h, tag->tag);
|
||||
h->tags.head = tag->next;
|
||||
free(tag);
|
||||
if (until && tag == until)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_stagq(struct html *h, const struct tag *suntil)
|
||||
{
|
||||
struct tag *tag;
|
||||
|
||||
while ((tag = h->tags.head) != NULL) {
|
||||
if (suntil && tag == suntil)
|
||||
return;
|
||||
if (tag == h->metaf)
|
||||
h->metaf = NULL;
|
||||
print_ctag(h, tag->tag);
|
||||
h->tags.head = tag->next;
|
||||
free(tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufinit(struct html *h)
|
||||
{
|
||||
|
||||
h->buf[0] = '\0';
|
||||
h->buflen = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufcat_style(struct html *h, const char *key, const char *val)
|
||||
{
|
||||
|
||||
bufcat(h, key);
|
||||
bufncat(h, ":", 1);
|
||||
bufcat(h, val);
|
||||
bufncat(h, ";", 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufcat(struct html *h, const char *p)
|
||||
{
|
||||
|
||||
bufncat(h, p, strlen(p));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
buffmt(struct html *h, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void)vsnprintf(h->buf + (int)h->buflen,
|
||||
BUFSIZ - h->buflen - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
h->buflen = strlen(h->buf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufncat(struct html *h, const char *p, size_t sz)
|
||||
{
|
||||
|
||||
if (h->buflen + sz > BUFSIZ - 1)
|
||||
sz = BUFSIZ - 1 - h->buflen;
|
||||
|
||||
(void)strncat(h->buf, p, sz);
|
||||
h->buflen += sz;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
buffmt_includes(struct html *h, const char *name)
|
||||
{
|
||||
const char *p, *pp;
|
||||
|
||||
pp = h->base_includes;
|
||||
|
||||
while (NULL != (p = strchr(pp, '%'))) {
|
||||
bufncat(h, pp, (size_t)(p - pp));
|
||||
switch (*(p + 1)) {
|
||||
case('I'):
|
||||
bufcat(h, name);
|
||||
break;
|
||||
default:
|
||||
bufncat(h, p, 2);
|
||||
break;
|
||||
}
|
||||
pp = p + 2;
|
||||
}
|
||||
if (pp)
|
||||
bufcat(h, pp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
buffmt_man(struct html *h,
|
||||
const char *name, const char *sec)
|
||||
{
|
||||
const char *p, *pp;
|
||||
|
||||
pp = h->base_man;
|
||||
|
||||
/* LINTED */
|
||||
while (NULL != (p = strchr(pp, '%'))) {
|
||||
bufncat(h, pp, (size_t)(p - pp));
|
||||
switch (*(p + 1)) {
|
||||
case('S'):
|
||||
bufcat(h, sec ? sec : "1");
|
||||
break;
|
||||
case('N'):
|
||||
buffmt(h, name);
|
||||
break;
|
||||
default:
|
||||
bufncat(h, p, 2);
|
||||
break;
|
||||
}
|
||||
pp = p + 2;
|
||||
}
|
||||
if (pp)
|
||||
bufcat(h, pp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bufcat_su(struct html *h, const char *p, const struct roffsu *su)
|
||||
{
|
||||
double v;
|
||||
const char *u;
|
||||
|
||||
v = su->scale;
|
||||
|
||||
switch (su->unit) {
|
||||
case (SCALE_CM):
|
||||
u = "cm";
|
||||
break;
|
||||
case (SCALE_IN):
|
||||
u = "in";
|
||||
break;
|
||||
case (SCALE_PC):
|
||||
u = "pc";
|
||||
break;
|
||||
case (SCALE_PT):
|
||||
u = "pt";
|
||||
break;
|
||||
case (SCALE_EM):
|
||||
u = "em";
|
||||
break;
|
||||
case (SCALE_MM):
|
||||
if (0 == (v /= 100))
|
||||
v = 1;
|
||||
u = "em";
|
||||
break;
|
||||
case (SCALE_EN):
|
||||
u = "ex";
|
||||
break;
|
||||
case (SCALE_BU):
|
||||
u = "ex";
|
||||
break;
|
||||
case (SCALE_VS):
|
||||
u = "em";
|
||||
break;
|
||||
default:
|
||||
u = "ex";
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: the CSS spec isn't clear as to which types accept
|
||||
* integer or real numbers, so we just make them all decimals.
|
||||
*/
|
||||
buffmt(h, "%s: %.2f%s;", p, v, u);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
html_idcat(char *dst, const char *src, int sz)
|
||||
{
|
||||
int ssz;
|
||||
|
||||
assert(sz > 2);
|
||||
|
||||
/* Cf. <http://www.w3.org/TR/html4/types.html#h-6.2>. */
|
||||
|
||||
/* We can't start with a number (bah). */
|
||||
|
||||
if ('#' == *dst) {
|
||||
dst++;
|
||||
sz--;
|
||||
}
|
||||
if ('\0' == *dst) {
|
||||
*dst++ = 'x';
|
||||
*dst = '\0';
|
||||
sz--;
|
||||
}
|
||||
|
||||
for ( ; *dst != '\0' && sz; dst++, sz--)
|
||||
/* Jump to end. */ ;
|
||||
|
||||
for ( ; *src != '\0' && sz > 1; src++) {
|
||||
ssz = snprintf(dst, (size_t)sz, "%.2x", *src);
|
||||
sz -= ssz;
|
||||
dst += ssz;
|
||||
}
|
||||
}
|
||||
157
usr.bin/mdocml/dist/html.h
vendored
157
usr.bin/mdocml/dist/html.h
vendored
@@ -1,157 +0,0 @@
|
||||
/* $Vendor-Id: html.h,v 1.38 2011/01/06 11:55:39 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef HTML_H
|
||||
#define HTML_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
enum htmltag {
|
||||
TAG_HTML,
|
||||
TAG_HEAD,
|
||||
TAG_BODY,
|
||||
TAG_META,
|
||||
TAG_TITLE,
|
||||
TAG_DIV,
|
||||
TAG_H1,
|
||||
TAG_H2,
|
||||
TAG_SPAN,
|
||||
TAG_LINK,
|
||||
TAG_BR,
|
||||
TAG_A,
|
||||
TAG_TABLE,
|
||||
TAG_TBODY,
|
||||
TAG_COL,
|
||||
TAG_TR,
|
||||
TAG_TD,
|
||||
TAG_LI,
|
||||
TAG_UL,
|
||||
TAG_OL,
|
||||
TAG_DL,
|
||||
TAG_DT,
|
||||
TAG_DD,
|
||||
TAG_BLOCKQUOTE,
|
||||
TAG_P,
|
||||
TAG_PRE,
|
||||
TAG_B,
|
||||
TAG_I,
|
||||
TAG_CODE,
|
||||
TAG_SMALL,
|
||||
TAG_MAX
|
||||
};
|
||||
|
||||
enum htmlattr {
|
||||
ATTR_HTTPEQUIV,
|
||||
ATTR_CONTENT,
|
||||
ATTR_NAME,
|
||||
ATTR_REL,
|
||||
ATTR_HREF,
|
||||
ATTR_TYPE,
|
||||
ATTR_MEDIA,
|
||||
ATTR_CLASS,
|
||||
ATTR_STYLE,
|
||||
ATTR_WIDTH,
|
||||
ATTR_ID,
|
||||
ATTR_SUMMARY,
|
||||
ATTR_ALIGN,
|
||||
ATTR_MAX
|
||||
};
|
||||
|
||||
enum htmlfont {
|
||||
HTMLFONT_NONE = 0,
|
||||
HTMLFONT_BOLD,
|
||||
HTMLFONT_ITALIC,
|
||||
HTMLFONT_MAX
|
||||
};
|
||||
|
||||
struct tag {
|
||||
struct tag *next;
|
||||
enum htmltag tag;
|
||||
};
|
||||
|
||||
struct tagq {
|
||||
struct tag *head;
|
||||
};
|
||||
|
||||
struct htmlpair {
|
||||
enum htmlattr key;
|
||||
const char *val;
|
||||
};
|
||||
|
||||
#define PAIR_INIT(p, t, v) \
|
||||
do { \
|
||||
(p)->key = (t); \
|
||||
(p)->val = (v); \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
#define PAIR_ID_INIT(p, v) PAIR_INIT(p, ATTR_ID, v)
|
||||
#define PAIR_CLASS_INIT(p, v) PAIR_INIT(p, ATTR_CLASS, v)
|
||||
#define PAIR_HREF_INIT(p, v) PAIR_INIT(p, ATTR_HREF, v)
|
||||
#define PAIR_STYLE_INIT(p, h) PAIR_INIT(p, ATTR_STYLE, (h)->buf)
|
||||
#define PAIR_SUMMARY_INIT(p, v) PAIR_INIT(p, ATTR_SUMMARY, v)
|
||||
|
||||
enum htmltype {
|
||||
HTML_HTML_4_01_STRICT,
|
||||
HTML_XHTML_1_0_STRICT
|
||||
};
|
||||
|
||||
struct html {
|
||||
int flags;
|
||||
#define HTML_NOSPACE (1 << 0)
|
||||
#define HTML_IGNDELIM (1 << 1)
|
||||
#define HTML_KEEP (1 << 2)
|
||||
#define HTML_PREKEEP (1 << 3)
|
||||
#define HTML_NONOSPACE (1 << 4)
|
||||
struct tagq tags; /* stack of open tags */
|
||||
struct rofftbl tbl; /* current table */
|
||||
void *symtab; /* character-escapes */
|
||||
char *base_man; /* base for manpage href */
|
||||
char *base_includes; /* base for include href */
|
||||
char *style; /* style-sheet URI */
|
||||
char buf[BUFSIZ]; /* see bufcat and friends */
|
||||
size_t buflen;
|
||||
struct tag *metaf; /* current open font scope */
|
||||
enum htmlfont metal; /* last used font */
|
||||
enum htmlfont metac; /* current font mode */
|
||||
enum htmltype type;
|
||||
};
|
||||
|
||||
void print_gen_decls(struct html *);
|
||||
void print_gen_head(struct html *);
|
||||
struct tag *print_otag(struct html *, enum htmltag,
|
||||
int, const struct htmlpair *);
|
||||
void print_tagq(struct html *, const struct tag *);
|
||||
void print_stagq(struct html *, const struct tag *);
|
||||
void print_text(struct html *, const char *);
|
||||
void print_tbl(struct html *, const struct tbl_span *);
|
||||
|
||||
void bufcat_su(struct html *, const char *,
|
||||
const struct roffsu *);
|
||||
void buffmt_man(struct html *,
|
||||
const char *, const char *);
|
||||
void buffmt_includes(struct html *, const char *);
|
||||
void buffmt(struct html *, const char *, ...);
|
||||
void bufcat(struct html *, const char *);
|
||||
void bufcat_style(struct html *,
|
||||
const char *, const char *);
|
||||
void bufncat(struct html *, const char *, size_t);
|
||||
void bufinit(struct html *);
|
||||
|
||||
void html_idcat(char *, const char *, int);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!HTML_H*/
|
||||
38
usr.bin/mdocml/dist/lib.c
vendored
38
usr.bin/mdocml/dist/lib.c
vendored
@@ -1,38 +0,0 @@
|
||||
/* $Vendor-Id: lib.c,v 1.8 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
if (0 == strcmp(p, x)) return(y);
|
||||
|
||||
const char *
|
||||
mdoc_a2lib(const char *p)
|
||||
{
|
||||
|
||||
#include "lib.in"
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
94
usr.bin/mdocml/dist/lib.in
vendored
94
usr.bin/mdocml/dist/lib.in
vendored
@@ -1,94 +0,0 @@
|
||||
/* $Vendor-Id: lib.in,v 1.9 2010/06/19 20:46:27 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These are all possible .Lb strings. When a new library is added, add
|
||||
* its short-string to the left-hand side and formatted string to the
|
||||
* right-hand side.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
*/
|
||||
|
||||
LINE("libarchive", "Reading and Writing Streaming Archives Library (libarchive, \\-larchive)")
|
||||
LINE("libarm", "ARM Architecture Library (libarm, \\-larm)")
|
||||
LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)")
|
||||
LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)")
|
||||
LINE("libbsm", "Basic Security Module User Library (libbsm, \\-lbsm)")
|
||||
LINE("libc", "Standard C Library (libc, \\-lc)")
|
||||
LINE("libc_r", "Reentrant C\\~Library (libc_r, \\-lc_r)")
|
||||
LINE("libcalendar", "Calendar Arithmetic Library (libcalendar, \\-lcalendar)")
|
||||
LINE("libcam", "Common Access Method User Library (libcam, \\-lcam)")
|
||||
LINE("libcdk", "Curses Development Kit Library (libcdk, \\-lcdk)")
|
||||
LINE("libcipher", "FreeSec Crypt Library (libcipher, \\-lcipher)")
|
||||
LINE("libcompat", "Compatibility Library (libcompat, \\-lcompat)")
|
||||
LINE("libcrypt", "Crypt Library (libcrypt, \\-lcrypt)")
|
||||
LINE("libcurses", "Curses Library (libcurses, \\-lcurses)")
|
||||
LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)")
|
||||
LINE("libdevstat", "Device Statistics Library (libdevstat, \\-ldevstat)")
|
||||
LINE("libdisk", "Interface to Slice and Partition Labels Library (libdisk, \\-ldisk)")
|
||||
LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)")
|
||||
LINE("libelf", "ELF Parsing Library (libelf, \\-lelf)")
|
||||
LINE("libevent", "Event Notification Library (libevent, \\-levent)")
|
||||
LINE("libfetch", "File Transfer Library for URLs (libfetch, \\-lfetch)")
|
||||
LINE("libform", "Curses Form Library (libform, \\-lform)")
|
||||
LINE("libgeom", "Userland API Library for kernel GEOM subsystem (libgeom, \\-lgeom)")
|
||||
LINE("libgpib", "General-Purpose Instrument Bus (GPIB) library (libgpib, \\-lgpib)")
|
||||
LINE("libi386", "i386 Architecture Library (libi386, \\-li386)")
|
||||
LINE("libintl", "Internationalized Message Handling Library (libintl, \\-lintl)")
|
||||
LINE("libipsec", "IPsec Policy Control Library (libipsec, \\-lipsec)")
|
||||
LINE("libipx", "IPX Address Conversion Support Library (libipx, \\-lipx)")
|
||||
LINE("libiscsi", "iSCSI protocol library (libiscsi, \\-liscsi)")
|
||||
LINE("libisns", "Internet Storage Name Service Library (libisns, \\-lisns)")
|
||||
LINE("libjail", "Jail Library (libjail, \\-ljail)")
|
||||
LINE("libkiconv", "Kernel side iconv library (libkiconv, \\-lkiconv)")
|
||||
LINE("libkse", "N:M Threading Library (libkse, \\-lkse)")
|
||||
LINE("libkvm", "Kernel Data Access Library (libkvm, \\-lkvm)")
|
||||
LINE("libm", "Math Library (libm, \\-lm)")
|
||||
LINE("libm68k", "m68k Architecture Library (libm68k, \\-lm68k)")
|
||||
LINE("libmagic", "Magic Number Recognition Library (libmagic, \\-lmagic)")
|
||||
LINE("libmd", "Message Digest (MD4, MD5, etc.) Support Library (libmd, \\-lmd)")
|
||||
LINE("libmemstat", "Kernel Memory Allocator Statistics Library (libmemstat, \\-lmemstat)")
|
||||
LINE("libmenu", "Curses Menu Library (libmenu, \\-lmenu)")
|
||||
LINE("libnetgraph", "Netgraph User Library (libnetgraph, \\-lnetgraph)")
|
||||
LINE("libnetpgp", "Netpgp signing, verification, encryption and decryption (libnetpgp, \\-lnetpgp)")
|
||||
LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
|
||||
LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
|
||||
LINE("libpcap", "Capture Library (libpcap, \\-lpcap)")
|
||||
LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)")
|
||||
LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)")
|
||||
LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)")
|
||||
LINE("libprop", "Property Container Object Library (libprop, \\-lprop)")
|
||||
LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)")
|
||||
LINE("libpuffs", "puffs Convenience Library (libpuffs, \\-lpuffs)")
|
||||
LINE("librefuse", "File System in Userspace Convenience Library (librefuse, \\-lrefuse)")
|
||||
LINE("libresolv", "DNS Resolver Library (libresolv, \\-lresolv)")
|
||||
LINE("librpcsec_gss", "RPC GSS-API Authentication Library (librpcsec_gss, \\-lrpcsec_gss)")
|
||||
LINE("librpcsvc", "RPC Service Library (librpcsvc, \\-lrpcsvc)")
|
||||
LINE("librt", "POSIX Real\\-time Library (librt, -lrt)")
|
||||
LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)")
|
||||
LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)")
|
||||
LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)")
|
||||
LINE("libterminfo", "Terminal Information Library (libterminfo, \\-lterminfo)")
|
||||
LINE("libthr", "1:1 Threading Library (libthr, \\-lthr)")
|
||||
LINE("libufs", "UFS File System Access Library (libufs, \\-lufs)")
|
||||
LINE("libugidfw", "File System Firewall Interface Library (libugidfw, \\-lugidfw)")
|
||||
LINE("libulog", "User Login Record Library (libulog, \\-lulog)")
|
||||
LINE("libusbhid", "USB Human Interface Devices Library (libusbhid, \\-lusbhid)")
|
||||
LINE("libutil", "System Utilities Library (libutil, \\-lutil)")
|
||||
LINE("libvgl", "Video Graphics Library (libvgl, \\-lvgl)")
|
||||
LINE("libx86_64", "x86_64 Architecture Library (libx86_64, \\-lx86_64)")
|
||||
LINE("libz", "Compression Library (libz, \\-lz)")
|
||||
92
usr.bin/mdocml/dist/libman.h
vendored
92
usr.bin/mdocml/dist/libman.h
vendored
@@ -1,92 +0,0 @@
|
||||
/* $Vendor-Id: libman.h,v 1.44 2010/11/30 15:36:28 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef LIBMAN_H
|
||||
#define LIBMAN_H
|
||||
|
||||
#include "man.h"
|
||||
|
||||
enum man_next {
|
||||
MAN_NEXT_SIBLING = 0,
|
||||
MAN_NEXT_CHILD
|
||||
};
|
||||
|
||||
struct man {
|
||||
void *data; /* private application data */
|
||||
mandocmsg msg; /* output message handler */
|
||||
int flags; /* parse flags */
|
||||
#define MAN_HALT (1 << 0) /* badness happened: die */
|
||||
#define MAN_ELINE (1 << 1) /* Next-line element scope. */
|
||||
#define MAN_BLINE (1 << 2) /* Next-line block scope. */
|
||||
#define MAN_ILINE (1 << 3) /* Ignored in next-line scope. */
|
||||
#define MAN_LITERAL (1 << 4) /* Literal input. */
|
||||
#define MAN_BPLINE (1 << 5)
|
||||
enum man_next next; /* where to put the next node */
|
||||
struct man_node *last; /* the last parsed node */
|
||||
struct man_node *first; /* the first parsed node */
|
||||
struct man_meta meta; /* document meta-data */
|
||||
struct regset *regs; /* registers */
|
||||
};
|
||||
|
||||
#define MACRO_PROT_ARGS struct man *m, \
|
||||
enum mant tok, \
|
||||
int line, \
|
||||
int ppos, \
|
||||
int *pos, \
|
||||
char *buf
|
||||
|
||||
struct man_macro {
|
||||
int (*fp)(MACRO_PROT_ARGS);
|
||||
int flags;
|
||||
#define MAN_SCOPED (1 << 0)
|
||||
#define MAN_EXPLICIT (1 << 1) /* See blk_imp(). */
|
||||
#define MAN_FSCOPED (1 << 2) /* See blk_imp(). */
|
||||
#define MAN_NSCOPED (1 << 3) /* See in_line_eoln(). */
|
||||
#define MAN_NOCLOSE (1 << 4) /* See blk_exp(). */
|
||||
};
|
||||
|
||||
extern const struct man_macro *const man_macros;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define man_pmsg(m, l, p, t) \
|
||||
(*(m)->msg)((t), (m)->data, (l), (p), NULL)
|
||||
#define man_nmsg(m, n, t) \
|
||||
(*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL)
|
||||
int man_word_alloc(struct man *, int, int, const char *);
|
||||
int man_block_alloc(struct man *, int, int, enum mant);
|
||||
int man_head_alloc(struct man *, int, int, enum mant);
|
||||
int man_body_alloc(struct man *, int, int, enum mant);
|
||||
int man_elem_alloc(struct man *, int, int, enum mant);
|
||||
void man_node_delete(struct man *, struct man_node *);
|
||||
void man_hash_init(void);
|
||||
enum mant man_hash_find(const char *);
|
||||
int man_macroend(struct man *);
|
||||
int man_args(struct man *, int, int *, char *, char **);
|
||||
#define ARGS_ERROR (-1)
|
||||
#define ARGS_EOLN (0)
|
||||
#define ARGS_WORD (1)
|
||||
#define ARGS_QWORD (1)
|
||||
int man_vmsg(struct man *, enum mandocerr,
|
||||
int, int, const char *, ...);
|
||||
int man_valid_post(struct man *);
|
||||
int man_valid_pre(struct man *, struct man_node *);
|
||||
int man_unscope(struct man *,
|
||||
const struct man_node *, enum mandocerr);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!LIBMAN_H*/
|
||||
38
usr.bin/mdocml/dist/libmandoc.h
vendored
38
usr.bin/mdocml/dist/libmandoc.h
vendored
@@ -1,38 +0,0 @@
|
||||
/* $Vendor-Id: libmandoc.h,v 1.10 2011/01/03 22:42:37 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef LIBMANDOC_H
|
||||
#define LIBMANDOC_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
int mandoc_special(char *);
|
||||
void *mandoc_calloc(size_t, size_t);
|
||||
char *mandoc_strdup(const char *);
|
||||
void *mandoc_malloc(size_t);
|
||||
void *mandoc_realloc(void *, size_t);
|
||||
char *mandoc_getarg(char **, mandocmsg, void *, int, int *);
|
||||
time_t mandoc_a2time(int, const char *);
|
||||
#define MTIME_CANONICAL (1 << 0)
|
||||
#define MTIME_REDUCED (1 << 1)
|
||||
#define MTIME_MDOCDATE (1 << 2)
|
||||
#define MTIME_ISO_8601 (1 << 3)
|
||||
int mandoc_eos(const char *, size_t, int);
|
||||
int mandoc_hyph(const char *, const char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!LIBMANDOC_H*/
|
||||
147
usr.bin/mdocml/dist/libmdoc.h
vendored
147
usr.bin/mdocml/dist/libmdoc.h
vendored
@@ -1,147 +0,0 @@
|
||||
/* $Vendor-Id: libmdoc.h,v 1.63 2010/11/30 13:04:14 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef LIBMDOC_H
|
||||
#define LIBMDOC_H
|
||||
|
||||
#include "mdoc.h"
|
||||
|
||||
enum mdoc_next {
|
||||
MDOC_NEXT_SIBLING = 0,
|
||||
MDOC_NEXT_CHILD
|
||||
};
|
||||
|
||||
struct mdoc {
|
||||
void *data; /* private application data */
|
||||
mandocmsg msg; /* message callback */
|
||||
int flags;
|
||||
#define MDOC_HALT (1 << 0) /* error in parse: halt */
|
||||
#define MDOC_LITERAL (1 << 1) /* in a literal scope */
|
||||
#define MDOC_PBODY (1 << 2) /* in the document body */
|
||||
#define MDOC_NEWLINE (1 << 3) /* first macro/text in a line */
|
||||
#define MDOC_PHRASELIT (1 << 4) /* literal within a partila phrase */
|
||||
#define MDOC_PPHRASE (1 << 5) /* within a partial phrase */
|
||||
#define MDOC_FREECOL (1 << 6) /* `It' invocation should close */
|
||||
#define MDOC_SYNOPSIS (1 << 7) /* SYNOPSIS-style formatting */
|
||||
enum mdoc_next next; /* where to put the next node */
|
||||
struct mdoc_node *last; /* the last node parsed */
|
||||
struct mdoc_node *first; /* the first node parsed */
|
||||
struct mdoc_meta meta; /* document meta-data */
|
||||
enum mdoc_sec lastnamed;
|
||||
enum mdoc_sec lastsec;
|
||||
struct regset *regs; /* registers */
|
||||
};
|
||||
|
||||
#define MACRO_PROT_ARGS struct mdoc *m, \
|
||||
enum mdoct tok, \
|
||||
int line, \
|
||||
int ppos, \
|
||||
int *pos, \
|
||||
char *buf
|
||||
|
||||
struct mdoc_macro {
|
||||
int (*fp)(MACRO_PROT_ARGS);
|
||||
int flags;
|
||||
#define MDOC_CALLABLE (1 << 0)
|
||||
#define MDOC_PARSED (1 << 1)
|
||||
#define MDOC_EXPLICIT (1 << 2)
|
||||
#define MDOC_PROLOGUE (1 << 3)
|
||||
#define MDOC_IGNDELIM (1 << 4)
|
||||
/* Reserved words in arguments treated as text. */
|
||||
};
|
||||
|
||||
enum margserr {
|
||||
ARGS_ERROR,
|
||||
ARGS_EOLN,
|
||||
ARGS_WORD,
|
||||
ARGS_PUNCT,
|
||||
ARGS_QWORD,
|
||||
ARGS_PHRASE,
|
||||
ARGS_PPHRASE,
|
||||
ARGS_PEND
|
||||
};
|
||||
|
||||
enum margverr {
|
||||
ARGV_ERROR,
|
||||
ARGV_EOLN,
|
||||
ARGV_ARG,
|
||||
ARGV_WORD
|
||||
};
|
||||
|
||||
enum mdelim {
|
||||
DELIM_NONE = 0,
|
||||
DELIM_OPEN,
|
||||
DELIM_MIDDLE,
|
||||
DELIM_CLOSE
|
||||
};
|
||||
|
||||
extern const struct mdoc_macro *const mdoc_macros;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define mdoc_pmsg(m, l, p, t) \
|
||||
(*(m)->msg)((t), (m)->data, (l), (p), NULL)
|
||||
#define mdoc_nmsg(m, n, t) \
|
||||
(*(m)->msg)((t), (m)->data, (n)->line, (n)->pos, NULL)
|
||||
int mdoc_vmsg(struct mdoc *, enum mandocerr,
|
||||
int, int, const char *, ...);
|
||||
int mdoc_macro(MACRO_PROT_ARGS);
|
||||
int mdoc_word_alloc(struct mdoc *,
|
||||
int, int, const char *);
|
||||
int mdoc_elem_alloc(struct mdoc *, int, int,
|
||||
enum mdoct, struct mdoc_arg *);
|
||||
int mdoc_block_alloc(struct mdoc *, int, int,
|
||||
enum mdoct, struct mdoc_arg *);
|
||||
int mdoc_head_alloc(struct mdoc *, int, int, enum mdoct);
|
||||
int mdoc_tail_alloc(struct mdoc *, int, int, enum mdoct);
|
||||
int mdoc_body_alloc(struct mdoc *, int, int, enum mdoct);
|
||||
int mdoc_endbody_alloc(struct mdoc *m, int line, int pos,
|
||||
enum mdoct tok, struct mdoc_node *body,
|
||||
enum mdoc_endbody end);
|
||||
void mdoc_node_delete(struct mdoc *, struct mdoc_node *);
|
||||
void mdoc_hash_init(void);
|
||||
enum mdoct mdoc_hash_find(const char *);
|
||||
enum mdelim mdoc_iscdelim(char);
|
||||
enum mdelim mdoc_isdelim(const char *);
|
||||
size_t mdoc_isescape(const char *);
|
||||
enum mdoc_sec mdoc_str2sec(const char *);
|
||||
time_t mdoc_atotime(const char *);
|
||||
size_t mdoc_macro2len(enum mdoct);
|
||||
const char *mdoc_a2att(const char *);
|
||||
const char *mdoc_a2lib(const char *);
|
||||
const char *mdoc_a2st(const char *);
|
||||
const char *mdoc_a2arch(const char *);
|
||||
const char *mdoc_a2vol(const char *);
|
||||
const char *mdoc_a2msec(const char *);
|
||||
int mdoc_valid_pre(struct mdoc *, struct mdoc_node *);
|
||||
int mdoc_valid_post(struct mdoc *);
|
||||
enum margverr mdoc_argv(struct mdoc *, int, enum mdoct,
|
||||
struct mdoc_arg **, int *, char *);
|
||||
void mdoc_argv_free(struct mdoc_arg *);
|
||||
void mdoc_argn_free(struct mdoc_arg *, int);
|
||||
enum margserr mdoc_args(struct mdoc *, int,
|
||||
int *, char *, enum mdoct, char **);
|
||||
enum margserr mdoc_zargs(struct mdoc *, int,
|
||||
int *, char *, int, char **);
|
||||
#define ARGS_DELIM (1 << 1)
|
||||
#define ARGS_TABSEP (1 << 2)
|
||||
#define ARGS_NOWARN (1 << 3)
|
||||
|
||||
int mdoc_macroend(struct mdoc *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!LIBMDOC_H*/
|
||||
62
usr.bin/mdocml/dist/libroff.h
vendored
62
usr.bin/mdocml/dist/libroff.h
vendored
@@ -1,62 +0,0 @@
|
||||
/* $Vendor-Id: libroff.h,v 1.16 2011/01/04 15:02:00 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef LIBROFF_H
|
||||
#define LIBROFF_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
enum tbl_part {
|
||||
TBL_PART_OPTS, /* in options (first line) */
|
||||
TBL_PART_LAYOUT, /* describing layout */
|
||||
TBL_PART_DATA, /* creating data rows */
|
||||
TBL_PART_CDATA /* continue previous row */
|
||||
};
|
||||
|
||||
struct tbl_node {
|
||||
mandocmsg msg; /* status messages */
|
||||
void *data; /* privdata for messages */
|
||||
int pos; /* invocation column */
|
||||
int line; /* invocation line */
|
||||
enum tbl_part part;
|
||||
struct tbl opts;
|
||||
struct tbl_row *first_row;
|
||||
struct tbl_row *last_row;
|
||||
struct tbl_span *first_span;
|
||||
struct tbl_span *last_span;
|
||||
struct tbl_head *first_head;
|
||||
struct tbl_head *last_head;
|
||||
struct tbl_node *next;
|
||||
};
|
||||
|
||||
#define TBL_MSG(tblp, type, line, col) \
|
||||
(*(tblp)->msg)((type), (tblp)->data, (line), (col), NULL)
|
||||
|
||||
struct tbl_node *tbl_alloc(int, int, void *, mandocmsg);
|
||||
void tbl_restart(int, int, struct tbl_node *);
|
||||
void tbl_free(struct tbl_node *);
|
||||
void tbl_reset(struct tbl_node *);
|
||||
enum rofferr tbl_read(struct tbl_node *, int, const char *, int);
|
||||
int tbl_option(struct tbl_node *, int, const char *);
|
||||
int tbl_layout(struct tbl_node *, int, const char *);
|
||||
int tbl_data(struct tbl_node *, int, const char *);
|
||||
int tbl_cdata(struct tbl_node *, int, const char *);
|
||||
const struct tbl_span *tbl_span(const struct tbl_node *);
|
||||
void tbl_end(struct tbl_node *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*LIBROFF_H*/
|
||||
1046
usr.bin/mdocml/dist/main.c
vendored
1046
usr.bin/mdocml/dist/main.c
vendored
File diff suppressed because it is too large
Load Diff
56
usr.bin/mdocml/dist/main.h
vendored
56
usr.bin/mdocml/dist/main.h
vendored
@@ -1,56 +0,0 @@
|
||||
/* $Vendor-Id: main.h,v 1.10 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct mdoc;
|
||||
struct man;
|
||||
|
||||
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for main.c-visible output device functions, e.g., -Thtml
|
||||
* and -Tascii. Note that ascii_alloc() is named as such in
|
||||
* anticipation of latin1_alloc() and so on, all of which map into the
|
||||
* terminal output routines with different character settings.
|
||||
*/
|
||||
|
||||
void *html_alloc(char *);
|
||||
void *xhtml_alloc(char *);
|
||||
void html_mdoc(void *, const struct mdoc *);
|
||||
void html_man(void *, const struct man *);
|
||||
void html_free(void *);
|
||||
|
||||
void tree_mdoc(void *, const struct mdoc *);
|
||||
void tree_man(void *, const struct man *);
|
||||
|
||||
void *ascii_alloc(char *);
|
||||
void ascii_free(void *);
|
||||
|
||||
void *pdf_alloc(char *);
|
||||
void *ps_alloc(char *);
|
||||
void pspdf_free(void *);
|
||||
|
||||
void terminal_mdoc(void *, const struct mdoc *);
|
||||
void terminal_man(void *, const struct man *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!MAIN_H*/
|
||||
272
usr.bin/mdocml/dist/man.3
vendored
272
usr.bin/mdocml/dist/man.3
vendored
@@ -1,272 +0,0 @@
|
||||
.\" $Vendor-Id: man.3,v 1.29 2011/01/03 11:31:26 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 3, 2011
|
||||
.Dt MAN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm man ,
|
||||
.Nm man_alloc ,
|
||||
.Nm man_endparse ,
|
||||
.Nm man_free ,
|
||||
.Nm man_meta ,
|
||||
.Nm man_node ,
|
||||
.Nm man_parseln ,
|
||||
.Nm man_reset
|
||||
.Nd man macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In mandoc.h
|
||||
.In man.h
|
||||
.Vt extern const char * const * man_macronames;
|
||||
.Ft int
|
||||
.Fo man_addspan
|
||||
.Fa "struct man *man"
|
||||
.Fa "const struct tbl_span *span"
|
||||
.Fc
|
||||
.Ft "struct man *"
|
||||
.Fo man_alloc
|
||||
.Fa "struct regset *regs"
|
||||
.Fa "void *data"
|
||||
.Fa "mandocmsg msgs"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn man_endparse "struct man *man"
|
||||
.Ft void
|
||||
.Fn man_free "struct man *man"
|
||||
.Ft "const struct man_meta *"
|
||||
.Fn man_meta "const struct man *man"
|
||||
.Ft "const struct man_node *"
|
||||
.Fn man_node "const struct man *man"
|
||||
.Ft int
|
||||
.Fo man_parseln
|
||||
.Fa "struct man *man"
|
||||
.Fa "int line"
|
||||
.Fa "char *buf"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn man_reset "struct man *man"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
library parses lines of
|
||||
.Xr man 7
|
||||
input into an abstract syntax tree (AST).
|
||||
.Pp
|
||||
In general, applications initiate a parsing sequence with
|
||||
.Fn man_alloc ,
|
||||
parse each line in a document with
|
||||
.Fn man_parseln ,
|
||||
close the parsing session with
|
||||
.Fn man_endparse ,
|
||||
operate over the syntax tree returned by
|
||||
.Fn man_node
|
||||
and
|
||||
.Fn man_meta ,
|
||||
then free all allocated memory with
|
||||
.Fn man_free .
|
||||
The
|
||||
.Fn man_reset
|
||||
function may be used in order to reset the parser for another input
|
||||
sequence.
|
||||
.Pp
|
||||
Beyond the full set of macros defined in
|
||||
.Xr man 7 ,
|
||||
the
|
||||
.Nm
|
||||
library also accepts the following macro:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.It PD
|
||||
Has no effect.
|
||||
Handled as a current-scope line macro.
|
||||
.El
|
||||
.Ss Types
|
||||
.Bl -ohang
|
||||
.It Vt struct man
|
||||
An opaque type.
|
||||
Its values are only used privately within the library.
|
||||
.It Vt struct man_node
|
||||
A parsed node.
|
||||
See
|
||||
.Sx Abstract Syntax Tree
|
||||
for details.
|
||||
.El
|
||||
.Ss Functions
|
||||
If
|
||||
.Fn man_addspan ,
|
||||
.Fn man_parseln ,
|
||||
or
|
||||
.Fn man_endparse
|
||||
return 0, calls to any function but
|
||||
.Fn man_reset
|
||||
or
|
||||
.Fn man_free
|
||||
will raise an assertion.
|
||||
.Bl -ohang
|
||||
.It Fn man_addspan
|
||||
Add a table span to the parsing stream.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn man_alloc
|
||||
Allocates a parsing structure.
|
||||
The
|
||||
.Fa data
|
||||
pointer is passed to
|
||||
.Fa msgs .
|
||||
Always returns a valid pointer.
|
||||
The pointer must be freed with
|
||||
.Fn man_free .
|
||||
.It Fn man_reset
|
||||
Reset the parser for another parse routine.
|
||||
After its use,
|
||||
.Fn man_parseln
|
||||
behaves as if invoked for the first time.
|
||||
.It Fn man_free
|
||||
Free all resources of a parser.
|
||||
The pointer is no longer valid after invocation.
|
||||
.It Fn man_parseln
|
||||
Parse a nil-terminated line of input.
|
||||
This line should not contain the trailing newline.
|
||||
Returns 0 on failure, 1 on success.
|
||||
The input buffer
|
||||
.Fa buf
|
||||
is modified by this function.
|
||||
.It Fn man_endparse
|
||||
Signals that the parse is complete.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn man_node
|
||||
Returns the first node of the parse.
|
||||
.It Fn man_meta
|
||||
Returns the document's parsed meta-data.
|
||||
.El
|
||||
.Ss Variables
|
||||
The following variables are also defined:
|
||||
.Bl -ohang
|
||||
.It Va man_macronames
|
||||
An array of string-ified token names.
|
||||
.El
|
||||
.Ss Abstract Syntax Tree
|
||||
The
|
||||
.Nm
|
||||
functions produce an abstract syntax tree (AST) describing input in a
|
||||
regular form.
|
||||
It may be reviewed at any time with
|
||||
.Fn man_nodes ;
|
||||
however, if called before
|
||||
.Fn man_endparse ,
|
||||
or after
|
||||
.Fn man_endparse
|
||||
or
|
||||
.Fn man_parseln
|
||||
fail, it may be incomplete.
|
||||
.Pp
|
||||
This AST is governed by the ontological rules dictated in
|
||||
.Xr man 7
|
||||
and derives its terminology accordingly.
|
||||
.Pp
|
||||
The AST is composed of
|
||||
.Vt struct man_node
|
||||
nodes with element, root and text types as declared by the
|
||||
.Va type
|
||||
field.
|
||||
Each node also provides its parse point (the
|
||||
.Va line ,
|
||||
.Va sec ,
|
||||
and
|
||||
.Va pos
|
||||
fields), its position in the tree (the
|
||||
.Va parent ,
|
||||
.Va child ,
|
||||
.Va next
|
||||
and
|
||||
.Va prev
|
||||
fields) and some type-specific data.
|
||||
.Pp
|
||||
The tree itself is arranged according to the following normal form,
|
||||
where capitalised non-terminals represent nodes.
|
||||
.Pp
|
||||
.Bl -tag -width "ELEMENTXX" -compact
|
||||
.It ROOT
|
||||
\(<- mnode+
|
||||
.It mnode
|
||||
\(<- ELEMENT | TEXT | BLOCK
|
||||
.It BLOCK
|
||||
\(<- HEAD BODY
|
||||
.It HEAD
|
||||
\(<- mnode*
|
||||
.It BODY
|
||||
\(<- mnode*
|
||||
.It ELEMENT
|
||||
\(<- ELEMENT | TEXT*
|
||||
.It TEXT
|
||||
\(<- [[:alpha:]]*
|
||||
.El
|
||||
.Pp
|
||||
The only elements capable of nesting other elements are those with
|
||||
next-lint scope as documented in
|
||||
.Xr man 7 .
|
||||
.Sh EXAMPLES
|
||||
The following example reads lines from stdin and parses them, operating
|
||||
on the finished parse tree with
|
||||
.Fn parsed .
|
||||
This example does not error-check nor free memory upon failure.
|
||||
.Bd -literal -offset indent
|
||||
struct regset regs;
|
||||
struct man *man;
|
||||
struct man_node *node;
|
||||
char *buf;
|
||||
size_t len;
|
||||
int line;
|
||||
|
||||
bzero(®s, sizeof(struct regset));
|
||||
line = 1;
|
||||
man = man_alloc(®s, NULL, NULL);
|
||||
buf = NULL;
|
||||
alloc_len = 0;
|
||||
|
||||
while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
|
||||
if (len && buflen[len - 1] = '\en')
|
||||
buf[len - 1] = '\e0';
|
||||
if ( ! man_parseln(man, line, buf))
|
||||
errx(1, "man_parseln");
|
||||
line++;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
if ( ! man_endparse(man))
|
||||
errx(1, "man_endparse");
|
||||
if (NULL == (node = man_node(man)))
|
||||
errx(1, "man_node");
|
||||
|
||||
parsed(man, node);
|
||||
man_free(man);
|
||||
.Ed
|
||||
.Pp
|
||||
To compile this, execute
|
||||
.Pp
|
||||
.Dl % cc main.c libman.a libmandoc.a
|
||||
.Pp
|
||||
where
|
||||
.Pa main.c
|
||||
is the example file.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
939
usr.bin/mdocml/dist/man.7
vendored
939
usr.bin/mdocml/dist/man.7
vendored
@@ -1,939 +0,0 @@
|
||||
.\" $Vendor-Id: man.7,v 1.94 2011/01/04 23:32:21 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 4, 2011
|
||||
.Dt MAN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm man
|
||||
.Nd man language reference
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm man
|
||||
language was historically used to format
|
||||
.Ux
|
||||
manuals.
|
||||
This reference document describes its syntax, structure, and usage.
|
||||
.Pp
|
||||
.Bf -emphasis
|
||||
Do not use
|
||||
.Nm
|
||||
to write your manuals.
|
||||
.Ef
|
||||
Use the
|
||||
.Xr mdoc 7
|
||||
language, instead.
|
||||
.Pp
|
||||
A
|
||||
.Nm
|
||||
document follows simple rules: lines beginning with the control
|
||||
character
|
||||
.Sq \&.
|
||||
are parsed for macros.
|
||||
Other lines are interpreted within the scope of
|
||||
prior macros:
|
||||
.Bd -literal -offset indent
|
||||
\&.SH Macro lines change control state.
|
||||
Other lines are interpreted within the current state.
|
||||
.Ed
|
||||
.Sh INPUT ENCODING
|
||||
.Nm
|
||||
documents may contain only graphable 7-bit ASCII characters, the
|
||||
space character, and the tab character.
|
||||
All manuals must have
|
||||
.Ux
|
||||
line termination.
|
||||
.Pp
|
||||
Blank lines are acceptable; where found, the output will assert a
|
||||
vertical space.
|
||||
.Ss Comments
|
||||
Text following a
|
||||
.Sq \e\*q ,
|
||||
whether in a macro or free-form text line, is ignored to the end of
|
||||
line.
|
||||
A macro line with only a control character and comment escape,
|
||||
.Sq \&.\e\*q ,
|
||||
is also ignored.
|
||||
Macro lines with only a control character and optionally whitespace are
|
||||
stripped from input.
|
||||
.Ss Special Characters
|
||||
Special characters may occur in both macro and free-form lines.
|
||||
Sequences begin with the escape character
|
||||
.Sq \e
|
||||
followed by either an open-parenthesis
|
||||
.Sq \&(
|
||||
for two-character sequences; an open-bracket
|
||||
.Sq \&[
|
||||
for n-character sequences (terminated at a close-bracket
|
||||
.Sq \&] ) ;
|
||||
or a single one-character sequence.
|
||||
See
|
||||
.Xr mandoc_char 7
|
||||
for a complete list.
|
||||
Examples include
|
||||
.Sq \e(em
|
||||
.Pq em-dash
|
||||
and
|
||||
.Sq \ee
|
||||
.Pq back-slash .
|
||||
.Ss Text Decoration
|
||||
Terms may be text-decorated using the
|
||||
.Sq \ef
|
||||
escape followed by an indicator: B (bold), I (italic), R (Roman), or P
|
||||
(revert to previous mode):
|
||||
.Pp
|
||||
.D1 \efBbold\efR \efIitalic\efP
|
||||
.Pp
|
||||
A numerical representation 3, 2, or 1 (bold, italic, and Roman,
|
||||
respectively) may be used instead.
|
||||
A text decoration is only valid, if specified in free-form text, until
|
||||
the next macro invocation; if specified within a macro, it's only valid
|
||||
until the macro closes scope.
|
||||
Note that macros like
|
||||
.Sx \&BR
|
||||
open and close a font scope with each argument.
|
||||
.Pp
|
||||
The
|
||||
.Sq \ef
|
||||
attribute is forgotten when entering or exiting a macro block.
|
||||
.Ss Whitespace
|
||||
Whitespace consists of the space character.
|
||||
In free-form lines, whitespace is preserved within a line; unescaped
|
||||
trailing spaces are stripped from input (unless in a literal context).
|
||||
Blank free-form lines, which may include spaces, are permitted and
|
||||
rendered as an empty line.
|
||||
.Pp
|
||||
In macro lines, whitespace delimits arguments and is discarded.
|
||||
If arguments are quoted, whitespace within the quotes is retained.
|
||||
.Ss Dates
|
||||
The
|
||||
.Sx \&TH
|
||||
macro is the only
|
||||
.Nm
|
||||
macro that requires a date.
|
||||
The form for this date is the ISO-8601
|
||||
standard
|
||||
.Cm YYYY-MM-DD .
|
||||
.Ss Scaling Widths
|
||||
Many macros support scaled widths for their arguments, such as
|
||||
stipulating a two-inch paragraph indentation with the following:
|
||||
.Bd -literal -offset indent
|
||||
\&.HP 2i
|
||||
.Ed
|
||||
.Pp
|
||||
The syntax for scaled widths is
|
||||
.Sq Li [+-]?[0-9]*.[0-9]*[:unit:]? ,
|
||||
where a decimal must be preceded or proceeded by at least one digit.
|
||||
Negative numbers, while accepted, are truncated to zero.
|
||||
The following scaling units are accepted:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It c
|
||||
centimetre
|
||||
.It i
|
||||
inch
|
||||
.It P
|
||||
pica (~1/6 inch)
|
||||
.It p
|
||||
point (~1/72 inch)
|
||||
.It f
|
||||
synonym for
|
||||
.Sq u
|
||||
.It v
|
||||
default vertical span
|
||||
.It m
|
||||
width of rendered
|
||||
.Sq m
|
||||
.Pq em
|
||||
character
|
||||
.It n
|
||||
width of rendered
|
||||
.Sq n
|
||||
.Pq en
|
||||
character
|
||||
.It u
|
||||
default horizontal span
|
||||
.It M
|
||||
mini-em (~1/100 em)
|
||||
.El
|
||||
.Pp
|
||||
Using anything other than
|
||||
.Sq m ,
|
||||
.Sq n ,
|
||||
.Sq u ,
|
||||
or
|
||||
.Sq v
|
||||
is necessarily non-portable across output media.
|
||||
.Pp
|
||||
If a scaling unit is not provided, the numerical value is interpreted
|
||||
under the default rules of
|
||||
.Sq v
|
||||
for vertical spaces and
|
||||
.Sq u
|
||||
for horizontal ones.
|
||||
.Em Note :
|
||||
this differs from
|
||||
.Xr mdoc 7 ,
|
||||
which, if a unit is not provided, will instead interpret the string as
|
||||
literal text.
|
||||
.Ss Sentence Spacing
|
||||
When composing a manual, make sure that sentences end at the end of
|
||||
a line.
|
||||
By doing so, front-ends will be able to apply the proper amount of
|
||||
spacing after the end of sentence (unescaped) period, exclamation mark,
|
||||
or question mark followed by zero or more non-sentence closing
|
||||
delimiters
|
||||
.Po
|
||||
.Sq \&) ,
|
||||
.Sq \&] ,
|
||||
.Sq \&' ,
|
||||
.Sq \&"
|
||||
.Pc .
|
||||
.Sh MANUAL STRUCTURE
|
||||
Each
|
||||
.Nm
|
||||
document must contain the
|
||||
.Sx \&TH
|
||||
macro describing the document's section and title.
|
||||
It may occur anywhere in the document, although conventionally it
|
||||
appears as the first macro.
|
||||
.Pp
|
||||
Beyond
|
||||
.Sx \&TH ,
|
||||
at least one macro or text node must appear in the document.
|
||||
Documents are generally structured as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.TH FOO 1 2009-10-10
|
||||
\&.SH NAME
|
||||
\efBfoo\efR \e(en a description goes here
|
||||
\&.\e\*q .SH LIBRARY
|
||||
\&.\e\*q For sections 2 & 3 only.
|
||||
\&.\e\*q Not used in OpenBSD.
|
||||
\&.SH SYNOPSIS
|
||||
\efBfoo\efR [\efB\e-options\efR] arguments...
|
||||
\&.SH DESCRIPTION
|
||||
The \efBfoo\efR utility processes files...
|
||||
\&.\e\*q .SH IMPLEMENTATION NOTES
|
||||
\&.\e\*q Not used in OpenBSD.
|
||||
\&.\e\*q .SH RETURN VALUES
|
||||
\&.\e\*q For sections 2, 3, & 9 only.
|
||||
\&.\e\*q .SH ENVIRONMENT
|
||||
\&.\e\*q For sections 1, 6, 7, & 8 only.
|
||||
\&.\e\*q .SH FILES
|
||||
\&.\e\*q .SH EXIT STATUS
|
||||
\&.\e\*q For sections 1, 6, & 8 only.
|
||||
\&.\e\*q .SH EXAMPLES
|
||||
\&.\e\*q .SH DIAGNOSTICS
|
||||
\&.\e\*q For sections 1, 4, 6, 7, & 8 only.
|
||||
\&.\e\*q .SH ERRORS
|
||||
\&.\e\*q For sections 2, 3, & 9 only.
|
||||
\&.\e\*q .SH SEE ALSO
|
||||
\&.\e\*q .BR foo ( 1 )
|
||||
\&.\e\*q .SH STANDARDS
|
||||
\&.\e\*q .SH HISTORY
|
||||
\&.\e\*q .SH AUTHORS
|
||||
\&.\e\*q .SH CAVEATS
|
||||
\&.\e\*q .SH BUGS
|
||||
\&.\e\*q .SH SECURITY CONSIDERATIONS
|
||||
\&.\e\*q Not used in OpenBSD.
|
||||
.Ed
|
||||
.Pp
|
||||
The sections in a
|
||||
.Nm
|
||||
document are conventionally ordered as they appear above.
|
||||
Sections should be composed as follows:
|
||||
.Bl -ohang -offset indent
|
||||
.It Em NAME
|
||||
The name(s) and a short description of the documented material.
|
||||
The syntax for this is generally as follows:
|
||||
.Pp
|
||||
.D1 \efBname\efR \e(en description
|
||||
.It Em LIBRARY
|
||||
The name of the library containing the documented material, which is
|
||||
assumed to be a function in a section 2 or 3 manual.
|
||||
For functions in the C library, this may be as follows:
|
||||
.Pp
|
||||
.D1 Standard C Library (libc, -lc)
|
||||
.It Em SYNOPSIS
|
||||
Documents the utility invocation syntax, function call syntax, or device
|
||||
configuration.
|
||||
.Pp
|
||||
For the first, utilities (sections 1, 6, and 8), this is
|
||||
generally structured as follows:
|
||||
.Pp
|
||||
.D1 \efBname\efR [-\efBab\efR] [-\efBc\efR\efIarg\efR] \efBpath\efR...
|
||||
.Pp
|
||||
For the second, function calls (sections 2, 3, 9):
|
||||
.Pp
|
||||
.D1 \&.B char *name(char *\efIarg\efR);
|
||||
.Pp
|
||||
And for the third, configurations (section 4):
|
||||
.Pp
|
||||
.D1 \&.B name* at cardbus ? function ?
|
||||
.Pp
|
||||
Manuals not in these sections generally don't need a
|
||||
.Em SYNOPSIS .
|
||||
.It Em DESCRIPTION
|
||||
This expands upon the brief, one-line description in
|
||||
.Em NAME .
|
||||
It usually contains a break-down of the options (if documenting a
|
||||
command).
|
||||
.It Em IMPLEMENTATION NOTES
|
||||
Implementation-specific notes should be kept here.
|
||||
This is useful when implementing standard functions that may have side
|
||||
effects or notable algorithmic implications.
|
||||
.It Em RETURN VALUES
|
||||
This section documents the return values of functions in sections 2, 3, and 9.
|
||||
.It Em ENVIRONMENT
|
||||
Documents any usages of environment variables, e.g.,
|
||||
.Xr environ 7 .
|
||||
.It Em FILES
|
||||
Documents files used.
|
||||
It's helpful to document both the file name and a short description of how
|
||||
the file is used (created, modified, etc.).
|
||||
.It Em EXIT STATUS
|
||||
This section documents the command exit status for
|
||||
section 1, 6, and 8 utilities.
|
||||
Historically, this information was described in
|
||||
.Em DIAGNOSTICS ,
|
||||
a practise that is now discouraged.
|
||||
.It Em EXAMPLES
|
||||
Example usages.
|
||||
This often contains snippets of well-formed,
|
||||
well-tested invocations.
|
||||
Make sure that examples work properly!
|
||||
.It Em DIAGNOSTICS
|
||||
Documents error conditions.
|
||||
This is most useful in section 4 manuals.
|
||||
Historically, this section was used in place of
|
||||
.Em EXIT STATUS
|
||||
for manuals in sections 1, 6, and 8; however, this practise is
|
||||
discouraged.
|
||||
.It Em ERRORS
|
||||
Documents error handling in sections 2, 3, and 9.
|
||||
.It Em SEE ALSO
|
||||
References other manuals with related topics.
|
||||
This section should exist for most manuals.
|
||||
.Pp
|
||||
.D1 \&.BR bar \&( 1 \&),
|
||||
.Pp
|
||||
Cross-references should conventionally be ordered
|
||||
first by section, then alphabetically.
|
||||
.It Em STANDARDS
|
||||
References any standards implemented or used, such as
|
||||
.Pp
|
||||
.D1 IEEE Std 1003.2 (\e(lqPOSIX.2\e(rq)
|
||||
.Pp
|
||||
If not adhering to any standards, the
|
||||
.Em HISTORY
|
||||
section should be used.
|
||||
.It Em HISTORY
|
||||
A brief history of the subject, including where support first appeared.
|
||||
.It Em AUTHORS
|
||||
Credits to the person or persons who wrote the code and/or documentation.
|
||||
Authors should generally be noted by both name and email address.
|
||||
.It Em CAVEATS
|
||||
Common misuses and misunderstandings should be explained
|
||||
in this section.
|
||||
.It Em BUGS
|
||||
Known bugs, limitations, and work-arounds should be described
|
||||
in this section.
|
||||
.It Em SECURITY CONSIDERATIONS
|
||||
Documents any security precautions that operators should consider.
|
||||
.El
|
||||
.Sh MACRO SYNTAX
|
||||
Macros are one to three characters in length and begin with a
|
||||
control character,
|
||||
.Sq \&. ,
|
||||
at the beginning of the line.
|
||||
The
|
||||
.Sq \(aq
|
||||
macro control character is also accepted.
|
||||
An arbitrary amount of whitespace (spaces or tabs) may sit between the
|
||||
control character and the macro name.
|
||||
Thus, the following are equivalent:
|
||||
.Bd -literal -offset indent
|
||||
\&.PP
|
||||
\&.\ \ \ PP
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
macros are classified by scope: line scope or block scope.
|
||||
Line macros are only scoped to the current line (and, in some
|
||||
situations, the subsequent line).
|
||||
Block macros are scoped to the current line and subsequent lines until
|
||||
closed by another block macro.
|
||||
.Ss Line Macros
|
||||
Line macros are generally scoped to the current line, with the body
|
||||
consisting of zero or more arguments.
|
||||
If a macro is scoped to the next line and the line arguments are empty,
|
||||
the next line, which must be text, is used instead.
|
||||
Thus:
|
||||
.Bd -literal -offset indent
|
||||
\&.I
|
||||
foo
|
||||
.Ed
|
||||
.Pp
|
||||
is equivalent to
|
||||
.Sq \&.I foo .
|
||||
If next-line macros are invoked consecutively, only the last is used.
|
||||
If a next-line macro is followed by a non-next-line macro, an error is
|
||||
raised, except for
|
||||
.Sx \&br ,
|
||||
.Sx \&sp ,
|
||||
and
|
||||
.Sx \&na .
|
||||
.Pp
|
||||
The syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.YO \(lBbody...\(rB
|
||||
\(lBbody...\(rB
|
||||
.Ed
|
||||
.Pp
|
||||
.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "ScopeXXXXX" "CompatX"
|
||||
.It Em Macro Ta Em Arguments Ta Em Scope Ta Em Notes
|
||||
.It Sx \&AT Ta <=1 Ta current Ta \&
|
||||
.It Sx \&B Ta n Ta next-line Ta \&
|
||||
.It Sx \&BI Ta n Ta current Ta \&
|
||||
.It Sx \&BR Ta n Ta current Ta \&
|
||||
.It Sx \&DT Ta 0 Ta current Ta \&
|
||||
.It Sx \&I Ta n Ta next-line Ta \&
|
||||
.It Sx \&IB Ta n Ta current Ta \&
|
||||
.It Sx \&IR Ta n Ta current Ta \&
|
||||
.It Sx \&R Ta n Ta next-line Ta \&
|
||||
.It Sx \&RB Ta n Ta current Ta \&
|
||||
.It Sx \&RI Ta n Ta current Ta \&
|
||||
.It Sx \&SB Ta n Ta next-line Ta \&
|
||||
.It Sx \&SM Ta n Ta next-line Ta \&
|
||||
.It Sx \&TH Ta >1, <6 Ta current Ta \&
|
||||
.It Sx \&UC Ta <=1 Ta current Ta \&
|
||||
.It Sx \&br Ta 0 Ta current Ta compat
|
||||
.It Sx \&fi Ta 0 Ta current Ta compat
|
||||
.It Sx \&ft Ta 1 Ta current Ta compat
|
||||
.It Sx \&in Ta 1 Ta current Ta compat
|
||||
.It Sx \&na Ta 0 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
|
||||
.Qq compat
|
||||
are included for compatibility with the significant corpus of existing
|
||||
manuals that mix dialects of roff.
|
||||
These macros should not be used for portable
|
||||
.Nm
|
||||
manuals.
|
||||
.Ss Block Macros
|
||||
Block macros comprise a head and body.
|
||||
As with in-line macros, the head is scoped to the current line and, in
|
||||
one circumstance, the next line (the next-line stipulations as in
|
||||
.Sx Line Macros
|
||||
apply here as well).
|
||||
.Pp
|
||||
The syntax is as follows:
|
||||
.Bd -literal -offset indent
|
||||
\&.YO \(lBhead...\(rB
|
||||
\(lBhead...\(rB
|
||||
\(lBbody...\(rB
|
||||
.Ed
|
||||
.Pp
|
||||
The closure of body scope may be to the section, where a macro is closed
|
||||
by
|
||||
.Sx \&SH ;
|
||||
sub-section, closed by a section or
|
||||
.Sx \&SS ;
|
||||
part, closed by a section, sub-section, or
|
||||
.Sx \&RE ;
|
||||
or paragraph, closed by a section, sub-section, part,
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
.Sx \&PP ,
|
||||
or
|
||||
.Sx \&TP .
|
||||
No closure refers to an explicit block closing macro.
|
||||
.Pp
|
||||
As a rule, block macros may not be nested; thus, calling a block macro
|
||||
while another block macro scope is open, and the open scope is not
|
||||
implicitly closed, is syntactically incorrect.
|
||||
.Pp
|
||||
.Bl -column -compact -offset indent "MacroX" "ArgumentsX" "Head ScopeX" "sub-sectionX" "compatX"
|
||||
.It Em Macro Ta Em Arguments Ta Em Head Scope Ta Em Body Scope Ta Em Notes
|
||||
.It Sx \&HP Ta <2 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&IP Ta <3 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&LP Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&P Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&PP Ta 0 Ta current Ta paragraph Ta \&
|
||||
.It Sx \&RE Ta 0 Ta current Ta none Ta compat
|
||||
.It Sx \&RS Ta 1 Ta current Ta part Ta compat
|
||||
.It Sx \&SH Ta >0 Ta next-line Ta section Ta \&
|
||||
.It Sx \&SS Ta >0 Ta next-line Ta sub-section Ta \&
|
||||
.It Sx \&TP Ta n Ta next-line Ta paragraph Ta \&
|
||||
.El
|
||||
.Pp
|
||||
Macros marked
|
||||
.Qq compat
|
||||
are as mentioned in
|
||||
.Sx Line Macros .
|
||||
.Pp
|
||||
If a block macro is next-line scoped, it may only be followed by in-line
|
||||
macros for decorating text.
|
||||
.Sh REFERENCE
|
||||
This section is a canonical reference to all macros, arranged
|
||||
alphabetically.
|
||||
For the scoping of individual macros, see
|
||||
.Sx MACRO SYNTAX .
|
||||
.Ss \&AT
|
||||
Sets the volume for the footer for compatibility with man pages from
|
||||
.Tn AT&T UNIX
|
||||
releases.
|
||||
The optional arguments specify which release it is from.
|
||||
.Ss \&B
|
||||
Text is rendered in bold face.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&I
|
||||
and
|
||||
.Sx \&R .
|
||||
.Ss \&BI
|
||||
Text is rendered alternately in bold face and italic.
|
||||
Thus,
|
||||
.Sq .BI this word and that
|
||||
causes
|
||||
.Sq this
|
||||
and
|
||||
.Sq and
|
||||
to render in bold face, while
|
||||
.Sq word
|
||||
and
|
||||
.Sq that
|
||||
render in italics.
|
||||
Whitespace between arguments is omitted in output.
|
||||
.Pp
|
||||
Examples:
|
||||
.Pp
|
||||
.Dl \&.BI bold italic bold italic
|
||||
.Pp
|
||||
The output of this example will be emboldened
|
||||
.Dq bold
|
||||
and italicised
|
||||
.Dq italic ,
|
||||
with spaces stripped between arguments.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&IB ,
|
||||
.Sx \&BR ,
|
||||
.Sx \&RB ,
|
||||
.Sx \&RI ,
|
||||
and
|
||||
.Sx \&IR .
|
||||
.Ss \&BR
|
||||
Text is rendered alternately in bold face and roman (the default font).
|
||||
Whitespace between arguments is omitted in output.
|
||||
.Pp
|
||||
See
|
||||
.Sx \&BI
|
||||
for an equivalent example.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&BI ,
|
||||
.Sx \&IB ,
|
||||
.Sx \&RB ,
|
||||
.Sx \&RI ,
|
||||
and
|
||||
.Sx \&IR .
|
||||
.Ss \&DT
|
||||
Has no effect.
|
||||
Included for compatibility.
|
||||
.Ss \&HP
|
||||
Begin a paragraph whose initial output line is left-justified, but
|
||||
subsequent output lines are indented, with the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&HP
|
||||
.Op Cm width
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument must conform to
|
||||
.Sx Scaling Widths .
|
||||
If specified, it's saved for later paragraph left-margins; if unspecified, the
|
||||
saved or default width is used.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
.Sx \&PP ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&I
|
||||
Text is rendered in italics.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&B
|
||||
and
|
||||
.Sx \&R .
|
||||
.Ss \&IB
|
||||
Text is rendered alternately in italics and bold face.
|
||||
Whitespace between arguments is omitted in output.
|
||||
.Pp
|
||||
See
|
||||
.Sx \&BI
|
||||
for an equivalent example.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&BI ,
|
||||
.Sx \&BR ,
|
||||
.Sx \&RB ,
|
||||
.Sx \&RI ,
|
||||
and
|
||||
.Sx \&IR .
|
||||
.Ss \&IP
|
||||
Begin an indented paragraph with the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&IP
|
||||
.Op Cm head Op Cm width
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument defines the width of the left margin and is defined by
|
||||
.Sx Scaling Widths .
|
||||
It's saved for later paragraph left-margins; if unspecified, the saved or
|
||||
default width is used.
|
||||
.Pp
|
||||
The
|
||||
.Cm head
|
||||
argument is used as a leading term, flushed to the left margin.
|
||||
This is useful for bulleted paragraphs and so on.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&HP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
.Sx \&PP ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&IR
|
||||
Text is rendered alternately in italics and roman (the default font).
|
||||
Whitespace between arguments is omitted in output.
|
||||
.Pp
|
||||
See
|
||||
.Sx \&BI
|
||||
for an equivalent example.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&BI ,
|
||||
.Sx \&IB ,
|
||||
.Sx \&BR ,
|
||||
.Sx \&RB ,
|
||||
and
|
||||
.Sx \&RI .
|
||||
.Ss \&LP
|
||||
Begin an undecorated paragraph.
|
||||
The scope of a paragraph is closed by a subsequent paragraph,
|
||||
sub-section, section, or end of file.
|
||||
The saved paragraph left-margin width is reset to the default.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&P ,
|
||||
.Sx \&PP ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&P
|
||||
Synonym for
|
||||
.Sx \&LP .
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&PP ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&PP
|
||||
Synonym for
|
||||
.Sx \&LP .
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
and
|
||||
.Sx \&TP .
|
||||
.Ss \&R
|
||||
Text is rendered in roman (the default font).
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&I
|
||||
and
|
||||
.Sx \&B .
|
||||
.Ss \&RB
|
||||
Text is rendered alternately in roman (the default font) and bold face.
|
||||
Whitespace between arguments is omitted in output.
|
||||
.Pp
|
||||
See
|
||||
.Sx \&BI
|
||||
for an equivalent example.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&BI ,
|
||||
.Sx \&IB ,
|
||||
.Sx \&BR ,
|
||||
.Sx \&RI ,
|
||||
and
|
||||
.Sx \&IR .
|
||||
.Ss \&RE
|
||||
Explicitly close out the scope of a prior
|
||||
.Sx \&RS .
|
||||
.Ss \&RI
|
||||
Text is rendered alternately in roman (the default font) and italics.
|
||||
Whitespace between arguments is omitted in output.
|
||||
.Pp
|
||||
See
|
||||
.Sx \&BI
|
||||
for an equivalent example.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&BI ,
|
||||
.Sx \&IB ,
|
||||
.Sx \&BR ,
|
||||
.Sx \&RB ,
|
||||
and
|
||||
.Sx \&IR .
|
||||
.Ss \&RS
|
||||
Begin a part setting the left margin.
|
||||
The left margin controls the offset, following an initial indentation,
|
||||
to un-indented text such as that of
|
||||
.Sx \&PP .
|
||||
This has the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&Rs
|
||||
.Op Cm width
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument must conform to
|
||||
.Sx Scaling Widths .
|
||||
If not specified, the saved or default width is used.
|
||||
.Ss \&SB
|
||||
Text is rendered in small size (one point smaller than the default font)
|
||||
bold face.
|
||||
.Ss \&SH
|
||||
Begin a section.
|
||||
The scope of a section is only closed by another section or the end of
|
||||
file.
|
||||
The paragraph left-margin width is reset to the default.
|
||||
.Ss \&SM
|
||||
Text is rendered in small size (one point smaller than the default
|
||||
font).
|
||||
.Ss \&SS
|
||||
Begin a sub-section.
|
||||
The scope of a sub-section is closed by a subsequent sub-section,
|
||||
section, or end of file.
|
||||
The paragraph left-margin width is reset to the default.
|
||||
.Ss \&TH
|
||||
Sets the title of the manual page with the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&TH
|
||||
.Cm title section
|
||||
.Op Cm date Op Cm source Op Cm volume
|
||||
.Ed
|
||||
.Pp
|
||||
At least the upper-case document
|
||||
.Cm title
|
||||
and the manual
|
||||
.Cm section
|
||||
arguments must be provided.
|
||||
The
|
||||
.Cm date
|
||||
argument should be formatted as described in
|
||||
.Sx Dates ,
|
||||
but will be printed verbatim if it is not.
|
||||
If the date is not specified, the current date is used.
|
||||
The
|
||||
.Cm source
|
||||
string specifies the organisation providing the utility.
|
||||
The
|
||||
.Cm volume
|
||||
string replaces the default rendered volume, which is dictated by the
|
||||
manual section.
|
||||
.Pp
|
||||
Examples:
|
||||
.Pp
|
||||
.Dl \&.TH CVS 5 "1992-02-12" GNU
|
||||
.Ss \&TP
|
||||
Begin a paragraph where the head, if exceeding the indentation width, is
|
||||
followed by a newline; if not, the body follows on the same line after a
|
||||
buffer to the indentation width.
|
||||
Subsequent output lines are indented.
|
||||
The syntax is as follows:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&TP
|
||||
.Op Cm width
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Cm width
|
||||
argument must conform to
|
||||
.Sx Scaling Widths .
|
||||
If specified, it's saved for later paragraph left-margins; if
|
||||
unspecified, the saved or default width is used.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&HP ,
|
||||
.Sx \&IP ,
|
||||
.Sx \&LP ,
|
||||
.Sx \&P ,
|
||||
and
|
||||
.Sx \&PP .
|
||||
.Ss \&UC
|
||||
Sets the volume for the footer for compatibility with man pages from
|
||||
BSD releases.
|
||||
The optional first argument specifies which release it is from.
|
||||
.Ss \&br
|
||||
Breaks the current line.
|
||||
Consecutive invocations have no further effect.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&sp .
|
||||
.Ss \&fi
|
||||
End literal mode begun by
|
||||
.Sx \&nf .
|
||||
.Ss \&ft
|
||||
Change the current font mode.
|
||||
See
|
||||
.Sx Text Decoration
|
||||
for a listing of available font modes.
|
||||
.Ss \&in
|
||||
Indent relative to the current indentation:
|
||||
.Pp
|
||||
.D1 Pf \. Sx \&in Op Cm width
|
||||
.Pp
|
||||
If
|
||||
.Cm width
|
||||
is signed, the new offset is relative.
|
||||
Otherwise, it is absolute.
|
||||
This value is reset upon the next paragraph, section, or sub-section.
|
||||
.Ss \&na
|
||||
Don't align to the right margin.
|
||||
.Ss \&nf
|
||||
Begin literal mode: all subsequent free-form lines have their end of
|
||||
line boundaries preserved.
|
||||
May be ended by
|
||||
.Sx \&fi .
|
||||
.Ss \&sp
|
||||
Insert vertical spaces into output with the following syntax:
|
||||
.Bd -filled -offset indent
|
||||
.Pf \. Sx \&sp
|
||||
.Op Cm height
|
||||
.Ed
|
||||
.Pp
|
||||
Insert
|
||||
.Cm height
|
||||
spaces, which must conform to
|
||||
.Sx Scaling Widths .
|
||||
If 0, this is equivalent to the
|
||||
.Sx \&br
|
||||
macro.
|
||||
Defaults to 1, if unspecified.
|
||||
.Pp
|
||||
See also
|
||||
.Sx \&br .
|
||||
.Sh COMPATIBILITY
|
||||
This section documents areas of questionable portability between
|
||||
implementations of the
|
||||
.Nm
|
||||
language.
|
||||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
In quoted literals, GNU troff allowed pair-wise double-quotes to produce
|
||||
a standalone double-quote in formatted output.
|
||||
It is not known whether this behaviour is exhibited by other formatters.
|
||||
.It
|
||||
troff suppresses a newline before
|
||||
.Sq \(aq
|
||||
macro output; in mandoc, it is an alias for the standard
|
||||
.Sq \&.
|
||||
control character.
|
||||
.It
|
||||
The
|
||||
.Sq \eh
|
||||
.Pq horizontal position ,
|
||||
.Sq \ev
|
||||
.Pq vertical position ,
|
||||
.Sq \em
|
||||
.Pq text colour ,
|
||||
.Sq \eM
|
||||
.Pq text filling colour ,
|
||||
.Sq \ez
|
||||
.Pq zero-length character ,
|
||||
.Sq \ew
|
||||
.Pq string length ,
|
||||
.Sq \ek
|
||||
.Pq horizontal position marker ,
|
||||
.Sq \eo
|
||||
.Pq text overstrike ,
|
||||
and
|
||||
.Sq \es
|
||||
.Pq text size
|
||||
escape sequences are all discarded in mandoc.
|
||||
.It
|
||||
The
|
||||
.Sq \ef
|
||||
scaling unit is accepted by mandoc, but rendered as the default unit.
|
||||
.It
|
||||
The
|
||||
.Sx \&sp
|
||||
macro does not accept negative values in mandoc.
|
||||
In GNU troff, this would result in strange behaviour.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr man 1 ,
|
||||
.Xr mandoc 1 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr roff 7 ,
|
||||
.Xr tbl 7
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
language first appeared as a macro package for the roff typesetting
|
||||
system in
|
||||
.At v7 .
|
||||
It was later rewritten by James Clark as a macro package for groff.
|
||||
The stand-alone implementation that is part of the
|
||||
.Xr mandoc 1
|
||||
utility written by Kristaps Dzonsons appeared in
|
||||
.Ox 4.6 .
|
||||
.Sh AUTHORS
|
||||
This
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
Do not use this language.
|
||||
Use
|
||||
.Xr mdoc 7 ,
|
||||
instead.
|
||||
666
usr.bin/mdocml/dist/man.c
vendored
666
usr.bin/mdocml/dist/man.c
vendored
@@ -1,666 +0,0 @@
|
||||
/* $Vendor-Id: man.c,v 1.96 2011/01/03 11:31:26 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
#include "libmandoc.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", "na", "sp", "nf",
|
||||
"fi", "RE", "RS", "DT",
|
||||
"UC", "PD", "AT", "in",
|
||||
"ft"
|
||||
};
|
||||
|
||||
const char * const *man_macronames = __man_macronames;
|
||||
|
||||
static struct man_node *man_node_alloc(int, int,
|
||||
enum man_type, enum mant);
|
||||
static int man_node_append(struct man *,
|
||||
struct man_node *);
|
||||
static int man_span_alloc(struct man *,
|
||||
const struct tbl_span *);
|
||||
static void man_node_free(struct man_node *);
|
||||
static void man_node_unlink(struct man *,
|
||||
struct man_node *);
|
||||
static int man_ptext(struct man *, int, char *, int);
|
||||
static int man_pmacro(struct man *, int, char *, int);
|
||||
static void man_free1(struct man *);
|
||||
static void man_alloc1(struct man *);
|
||||
static int man_descope(struct man *, int, int);
|
||||
|
||||
|
||||
const struct man_node *
|
||||
man_node(const struct man *m)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
return(m->first);
|
||||
}
|
||||
|
||||
|
||||
const struct man_meta *
|
||||
man_meta(const struct man *m)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
return(&m->meta);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
man_reset(struct man *man)
|
||||
{
|
||||
|
||||
man_free1(man);
|
||||
man_alloc1(man);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
man_free(struct man *man)
|
||||
{
|
||||
|
||||
man_free1(man);
|
||||
free(man);
|
||||
}
|
||||
|
||||
|
||||
struct man *
|
||||
man_alloc(struct regset *regs, void *data, mandocmsg msg)
|
||||
{
|
||||
struct man *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct man));
|
||||
|
||||
man_hash_init();
|
||||
p->data = data;
|
||||
p->msg = msg;
|
||||
p->regs = regs;
|
||||
|
||||
man_alloc1(p);
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_endparse(struct man *m)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
if (man_macroend(m))
|
||||
return(1);
|
||||
m->flags |= MAN_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_parseln(struct man *m, int ln, char *buf, int offs)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
return(('.' == buf[offs] || '\'' == buf[offs]) ?
|
||||
man_pmacro(m, ln, buf, offs) :
|
||||
man_ptext(m, ln, buf, offs));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
man_free1(struct man *man)
|
||||
{
|
||||
|
||||
if (man->first)
|
||||
man_node_delete(man, man->first);
|
||||
if (man->meta.title)
|
||||
free(man->meta.title);
|
||||
if (man->meta.source)
|
||||
free(man->meta.source);
|
||||
if (man->meta.rawdate)
|
||||
free(man->meta.rawdate);
|
||||
if (man->meta.vol)
|
||||
free(man->meta.vol);
|
||||
if (man->meta.msec)
|
||||
free(man->meta.msec);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
man_alloc1(struct man *m)
|
||||
{
|
||||
|
||||
memset(&m->meta, 0, sizeof(struct man_meta));
|
||||
m->flags = 0;
|
||||
m->last = mandoc_calloc(1, sizeof(struct man_node));
|
||||
m->first = m->last;
|
||||
m->last->type = MAN_ROOT;
|
||||
m->last->tok = MAN_MAX;
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
man_node_append(struct man *man, struct man_node *p)
|
||||
{
|
||||
|
||||
assert(man->last);
|
||||
assert(man->first);
|
||||
assert(MAN_ROOT != p->type);
|
||||
|
||||
switch (man->next) {
|
||||
case (MAN_NEXT_SIBLING):
|
||||
man->last->next = p;
|
||||
p->prev = man->last;
|
||||
p->parent = man->last->parent;
|
||||
break;
|
||||
case (MAN_NEXT_CHILD):
|
||||
man->last->child = p;
|
||||
p->parent = man->last;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
assert(p->parent);
|
||||
p->parent->nchild++;
|
||||
|
||||
if ( ! man_valid_pre(man, p))
|
||||
return(0);
|
||||
|
||||
switch (p->type) {
|
||||
case (MAN_HEAD):
|
||||
assert(MAN_BLOCK == p->parent->type);
|
||||
p->parent->head = p;
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
assert(MAN_BLOCK == p->parent->type);
|
||||
p->parent->body = p;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
man->last = p;
|
||||
|
||||
switch (p->type) {
|
||||
case (MAN_TBL):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TEXT):
|
||||
if ( ! man_valid_post(man))
|
||||
return(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static struct man_node *
|
||||
man_node_alloc(int line, int pos, enum man_type type, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct man_node));
|
||||
p->line = line;
|
||||
p->pos = pos;
|
||||
p->type = type;
|
||||
p->tok = tok;
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_elem_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_ELEM, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_head_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_HEAD, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_body_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_BODY, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_block_alloc(struct man *m, int line, int pos, enum mant tok)
|
||||
{
|
||||
struct man_node *p;
|
||||
|
||||
p = man_node_alloc(line, pos, MAN_BLOCK, tok);
|
||||
if ( ! man_node_append(m, p))
|
||||
return(0);
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
man_span_alloc(struct man *m, const struct tbl_span *span)
|
||||
{
|
||||
struct man_node *n;
|
||||
|
||||
/* FIXME: grab from span */
|
||||
n = man_node_alloc(0, 0, MAN_TBL, MAN_MAX);
|
||||
n->span = span;
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
man_word_alloc(struct man *m, int line, int pos, const char *word)
|
||||
{
|
||||
struct man_node *n;
|
||||
size_t sv, len;
|
||||
|
||||
len = strlen(word);
|
||||
|
||||
n = man_node_alloc(line, pos, MAN_TEXT, MAN_MAX);
|
||||
n->string = mandoc_malloc(len + 1);
|
||||
sv = strlcpy(n->string, word, len + 1);
|
||||
|
||||
/* Prohibit truncation. */
|
||||
assert(sv < len + 1);
|
||||
|
||||
if ( ! man_node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free all of the resources held by a node. This does NOT unlink a
|
||||
* node from its context; for that, see man_node_unlink().
|
||||
*/
|
||||
static void
|
||||
man_node_free(struct man_node *p)
|
||||
{
|
||||
|
||||
if (p->string)
|
||||
free(p->string);
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
man_node_delete(struct man *m, struct man_node *p)
|
||||
{
|
||||
|
||||
while (p->child)
|
||||
man_node_delete(m, p->child);
|
||||
|
||||
man_node_unlink(m, p);
|
||||
man_node_free(p);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_addspan(struct man *m, const struct tbl_span *sp)
|
||||
{
|
||||
|
||||
assert( ! (MAN_HALT & m->flags));
|
||||
if ( ! man_span_alloc(m, sp))
|
||||
return(0);
|
||||
return(man_descope(m, 0, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
man_descope(struct man *m, int line, int offs)
|
||||
{
|
||||
/*
|
||||
* Co-ordinate what happens with having a next-line scope open:
|
||||
* first close out the element scope (if applicable), then close
|
||||
* out the block scope (also if applicable).
|
||||
*/
|
||||
|
||||
if (MAN_ELINE & m->flags) {
|
||||
m->flags &= ~MAN_ELINE;
|
||||
if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ( ! (MAN_BLINE & m->flags))
|
||||
return(1);
|
||||
m->flags &= ~MAN_BLINE;
|
||||
|
||||
if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
|
||||
return(0);
|
||||
return(man_body_alloc(m, line, offs, m->last->tok));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
man_ptext(struct man *m, int line, char *buf, int offs)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Ignore bogus comments. */
|
||||
|
||||
if ('\\' == buf[offs] &&
|
||||
'.' == buf[offs + 1] &&
|
||||
'"' == buf[offs + 2]) {
|
||||
man_pmsg(m, line, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Literal free-form text whitespace is preserved. */
|
||||
|
||||
if (MAN_LITERAL & m->flags) {
|
||||
if ( ! man_word_alloc(m, line, offs, buf + offs))
|
||||
return(0);
|
||||
return(man_descope(m, line, offs));
|
||||
}
|
||||
|
||||
/* Pump blank lines directly into the backend. */
|
||||
|
||||
for (i = offs; ' ' == buf[i]; i++)
|
||||
/* Skip leading whitespace. */ ;
|
||||
|
||||
if ('\0' == buf[i]) {
|
||||
/* Allocate a blank entry. */
|
||||
if ( ! man_word_alloc(m, line, offs, ""))
|
||||
return(0);
|
||||
return(man_descope(m, line, offs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Warn if the last un-escaped character is whitespace. Then
|
||||
* strip away the remaining spaces (tabs stay!).
|
||||
*/
|
||||
|
||||
i = (int)strlen(buf);
|
||||
assert(i);
|
||||
|
||||
if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
|
||||
if (i > 1 && '\\' != buf[i - 2])
|
||||
man_pmsg(m, line, i - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
for (--i; i && ' ' == buf[i]; i--)
|
||||
/* Spin back to non-space. */ ;
|
||||
|
||||
/* Jump ahead of escaped whitespace. */
|
||||
i += '\\' == buf[i] ? 2 : 1;
|
||||
|
||||
buf[i] = '\0';
|
||||
}
|
||||
|
||||
if ( ! man_word_alloc(m, line, offs, buf + offs))
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* End-of-sentence check. If the last character is an unescaped
|
||||
* EOS character, then flag the node as being the end of a
|
||||
* sentence. The front-end will know how to interpret this.
|
||||
*/
|
||||
|
||||
assert(i);
|
||||
if (mandoc_eos(buf, (size_t)i, 0))
|
||||
m->last->flags |= MAN_EOS;
|
||||
|
||||
return(man_descope(m, line, offs));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
man_pmacro(struct man *m, int ln, char *buf, int offs)
|
||||
{
|
||||
int i, j, ppos;
|
||||
enum mant tok;
|
||||
char mac[5];
|
||||
struct man_node *n;
|
||||
|
||||
/* Comments and empties are quickly ignored. */
|
||||
|
||||
offs++;
|
||||
|
||||
if ('\0' == buf[offs])
|
||||
return(1);
|
||||
|
||||
i = offs;
|
||||
|
||||
/*
|
||||
* Skip whitespace between the control character and initial
|
||||
* text. "Whitespace" is both spaces and tabs.
|
||||
*/
|
||||
|
||||
if (' ' == buf[i] || '\t' == buf[i]) {
|
||||
i++;
|
||||
while (buf[i] && (' ' == buf[i] || '\t' == buf[i]))
|
||||
i++;
|
||||
if ('\0' == buf[i])
|
||||
goto out;
|
||||
}
|
||||
|
||||
ppos = i;
|
||||
|
||||
/*
|
||||
* Copy the first word into a nil-terminated buffer.
|
||||
* Stop copying when a tab, space, or eoln is encountered.
|
||||
*/
|
||||
|
||||
j = 0;
|
||||
while (j < 4 && '\0' != buf[i] && ' ' != buf[i] && '\t' != buf[i])
|
||||
mac[j++] = buf[i++];
|
||||
mac[j] = '\0';
|
||||
|
||||
tok = (j > 0 && j < 4) ? man_hash_find(mac) : MAN_MAX;
|
||||
if (MAN_MAX == tok) {
|
||||
man_vmsg(m, MANDOCERR_MACRO, ln, ppos, "%s", buf + ppos - 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* The macro is sane. Jump to the next word. */
|
||||
|
||||
while (buf[i] && ' ' == buf[i])
|
||||
i++;
|
||||
|
||||
/*
|
||||
* Trailing whitespace. Note that tabs are allowed to be passed
|
||||
* into the parser as "text", so we only warn about spaces here.
|
||||
*/
|
||||
|
||||
if ('\0' == buf[i] && ' ' == buf[i - 1])
|
||||
man_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
/*
|
||||
* Remove prior ELINE macro, as it's being clobbered by a new
|
||||
* macro. Note that NSCOPED macros do not close out ELINE
|
||||
* macros---they don't print text---so we let those slip by.
|
||||
*/
|
||||
|
||||
if ( ! (MAN_NSCOPED & man_macros[tok].flags) &&
|
||||
m->flags & MAN_ELINE) {
|
||||
n = m->last;
|
||||
assert(MAN_TEXT != n->type);
|
||||
|
||||
/* Remove repeated NSCOPED macros causing ELINE. */
|
||||
|
||||
if (MAN_NSCOPED & man_macros[n->tok].flags)
|
||||
n = n->parent;
|
||||
|
||||
man_vmsg(m, MANDOCERR_LINESCOPE, n->line, n->pos,
|
||||
"%s", man_macronames[n->tok]);
|
||||
|
||||
man_node_delete(m, n);
|
||||
m->flags &= ~MAN_ELINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the fact that we're in the next-line for a block. In
|
||||
* this way, embedded roff instructions can "remember" state
|
||||
* when they exit.
|
||||
*/
|
||||
|
||||
if (MAN_BLINE & m->flags)
|
||||
m->flags |= MAN_BPLINE;
|
||||
|
||||
/* Call to handler... */
|
||||
|
||||
assert(man_macros[tok].fp);
|
||||
if ( ! (*man_macros[tok].fp)(m, tok, ln, ppos, &i, buf))
|
||||
goto err;
|
||||
|
||||
out:
|
||||
/*
|
||||
* We weren't in a block-line scope when entering the
|
||||
* above-parsed macro, so return.
|
||||
*/
|
||||
|
||||
if ( ! (MAN_BPLINE & m->flags)) {
|
||||
m->flags &= ~MAN_ILINE;
|
||||
return(1);
|
||||
}
|
||||
m->flags &= ~MAN_BPLINE;
|
||||
|
||||
/*
|
||||
* If we're in a block scope, then allow this macro to slip by
|
||||
* without closing scope around it.
|
||||
*/
|
||||
|
||||
if (MAN_ILINE & m->flags) {
|
||||
m->flags &= ~MAN_ILINE;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we've opened a new next-line element scope, then return
|
||||
* now, as the next line will close out the block scope.
|
||||
*/
|
||||
|
||||
if (MAN_ELINE & m->flags)
|
||||
return(1);
|
||||
|
||||
/* Close out the block scope opened in the prior line. */
|
||||
|
||||
assert(MAN_BLINE & m->flags);
|
||||
m->flags &= ~MAN_BLINE;
|
||||
|
||||
if ( ! man_unscope(m, m->last->parent, MANDOCERR_MAX))
|
||||
return(0);
|
||||
return(man_body_alloc(m, ln, offs, m->last->tok));
|
||||
|
||||
err: /* Error out. */
|
||||
|
||||
m->flags |= MAN_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_vmsg(struct man *man, enum mandocerr t,
|
||||
int ln, int pos, const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
return((*man->msg)(t, man->data, ln, pos, buf));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unlink a node from its context. If "m" is provided, the last parse
|
||||
* point will also be adjusted accordingly.
|
||||
*/
|
||||
static void
|
||||
man_node_unlink(struct man *m, struct man_node *n)
|
||||
{
|
||||
|
||||
/* Adjust siblings. */
|
||||
|
||||
if (n->prev)
|
||||
n->prev->next = n->next;
|
||||
if (n->next)
|
||||
n->next->prev = n->prev;
|
||||
|
||||
/* Adjust parent. */
|
||||
|
||||
if (n->parent) {
|
||||
n->parent->nchild--;
|
||||
if (n->parent->child == n)
|
||||
n->parent->child = n->prev ? n->prev : n->next;
|
||||
}
|
||||
|
||||
/* Adjust parse point, if applicable. */
|
||||
|
||||
if (m && m->last == n) {
|
||||
/*XXX: this can occur when bailing from validation. */
|
||||
/*assert(NULL == n->next);*/
|
||||
if (n->prev) {
|
||||
m->last = n->prev;
|
||||
m->next = MAN_NEXT_SIBLING;
|
||||
} else {
|
||||
m->last = n->parent;
|
||||
m->next = MAN_NEXT_CHILD;
|
||||
}
|
||||
}
|
||||
|
||||
if (m && m->first == n)
|
||||
m->first = NULL;
|
||||
}
|
||||
130
usr.bin/mdocml/dist/man.h
vendored
130
usr.bin/mdocml/dist/man.h
vendored
@@ -1,130 +0,0 @@
|
||||
/* $Vendor-Id: man.h,v 1.50 2011/01/01 12:59:17 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef MAN_H
|
||||
#define MAN_H
|
||||
|
||||
/*
|
||||
* What follows is a list of ALL possible macros.
|
||||
*/
|
||||
enum mant {
|
||||
MAN_br = 0,
|
||||
MAN_TH,
|
||||
MAN_SH,
|
||||
MAN_SS,
|
||||
MAN_TP,
|
||||
MAN_LP,
|
||||
MAN_PP,
|
||||
MAN_P,
|
||||
MAN_IP,
|
||||
MAN_HP,
|
||||
MAN_SM,
|
||||
MAN_SB,
|
||||
MAN_BI,
|
||||
MAN_IB,
|
||||
MAN_BR,
|
||||
MAN_RB,
|
||||
MAN_R,
|
||||
MAN_B,
|
||||
MAN_I,
|
||||
MAN_IR,
|
||||
MAN_RI,
|
||||
MAN_na,
|
||||
MAN_sp,
|
||||
MAN_nf,
|
||||
MAN_fi,
|
||||
MAN_RE,
|
||||
MAN_RS,
|
||||
MAN_DT,
|
||||
MAN_UC,
|
||||
MAN_PD,
|
||||
MAN_AT,
|
||||
MAN_in,
|
||||
MAN_ft,
|
||||
MAN_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Type of a syntax node.
|
||||
*/
|
||||
enum man_type {
|
||||
MAN_TEXT,
|
||||
MAN_ELEM,
|
||||
MAN_ROOT,
|
||||
MAN_BLOCK,
|
||||
MAN_HEAD,
|
||||
MAN_BODY,
|
||||
MAN_TBL
|
||||
};
|
||||
|
||||
/*
|
||||
* Information from prologue.
|
||||
*/
|
||||
struct man_meta {
|
||||
char *msec; /* `TH' section (1, 3p, etc.) */
|
||||
time_t date; /* `TH' normalised date */
|
||||
char *rawdate; /* raw `TH' date */
|
||||
char *vol; /* `TH' volume */
|
||||
char *title; /* `TH' title (e.g., FOO) */
|
||||
char *source; /* `TH' source (e.g., GNU) */
|
||||
};
|
||||
|
||||
/*
|
||||
* Single node in tree-linked AST.
|
||||
*/
|
||||
struct man_node {
|
||||
struct man_node *parent; /* parent AST node */
|
||||
struct man_node *child; /* first child AST node */
|
||||
struct man_node *next; /* sibling AST node */
|
||||
struct man_node *prev; /* prior sibling AST node */
|
||||
int nchild; /* number children */
|
||||
int line;
|
||||
int pos;
|
||||
enum mant tok; /* tok or MAN__MAX if none */
|
||||
int flags;
|
||||
#define MAN_VALID (1 << 0) /* has been validated */
|
||||
#define MAN_EOS (1 << 2) /* at sentence boundary */
|
||||
enum man_type type; /* AST node type */
|
||||
char *string; /* TEXT node argument */
|
||||
struct man_node *head; /* BLOCK node HEAD ptr */
|
||||
struct man_node *body; /* BLOCK node BODY ptr */
|
||||
const struct tbl_span *span; /* TBL */
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of macros. Index is enum mant. Indexing into this returns
|
||||
* the normalised name, e.g., man_macronames[MAN_SH] -> "SH".
|
||||
*/
|
||||
extern const char *const *man_macronames;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct man;
|
||||
|
||||
void man_free(struct man *);
|
||||
struct man *man_alloc(struct regset *, void *, mandocmsg);
|
||||
void man_reset(struct man *);
|
||||
int man_parseln(struct man *, int, char *, int);
|
||||
int man_endparse(struct man *);
|
||||
int man_addspan(struct man *,
|
||||
const struct tbl_span *);
|
||||
|
||||
const struct man_node *man_node(const struct man *);
|
||||
const struct man_meta *man_meta(const struct man *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!MAN_H*/
|
||||
44
usr.bin/mdocml/dist/man_argv.c
vendored
44
usr.bin/mdocml/dist/man_argv.c
vendored
@@ -1,44 +0,0 @@
|
||||
/* $Vendor-Id: man_argv.c,v 1.5 2011/01/03 22:42:37 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
|
||||
int
|
||||
man_args(struct man *m, int line, int *pos, char *buf, char **v)
|
||||
{
|
||||
char *start;
|
||||
|
||||
assert(*pos);
|
||||
*v = start = buf + *pos;
|
||||
assert(' ' != *start);
|
||||
|
||||
if ('\0' == *start)
|
||||
return(ARGS_EOLN);
|
||||
|
||||
*v = mandoc_getarg(v, m->msg, m->data, line, pos);
|
||||
return('"' == *start ? ARGS_QWORD : ARGS_WORD);
|
||||
}
|
||||
106
usr.bin/mdocml/dist/man_hash.c
vendored
106
usr.bin/mdocml/dist/man_hash.c
vendored
@@ -1,106 +0,0 @@
|
||||
/* $Vendor-Id: man_hash.c,v 1.23 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
|
||||
#define HASH_DEPTH 6
|
||||
|
||||
#define HASH_ROW(x) do { \
|
||||
if (isupper((u_char)(x))) \
|
||||
(x) -= 65; \
|
||||
else \
|
||||
(x) -= 97; \
|
||||
(x) *= HASH_DEPTH; \
|
||||
} while (/* CONSTCOND */ 0)
|
||||
|
||||
/*
|
||||
* Lookup table is indexed first by lower-case first letter (plus one
|
||||
* for the period, which is stored in the last row), then by lower or
|
||||
* uppercase second letter. Buckets correspond to the index of the
|
||||
* macro (the integer value of the enum stored as a char to save a bit
|
||||
* of space).
|
||||
*/
|
||||
static u_char table[26 * HASH_DEPTH];
|
||||
|
||||
/*
|
||||
* XXX - this hash has global scope, so if intended for use as a library
|
||||
* with multiple callers, it will need re-invocation protection.
|
||||
*/
|
||||
void
|
||||
man_hash_init(void)
|
||||
{
|
||||
int i, j, x;
|
||||
|
||||
memset(table, UCHAR_MAX, sizeof(table));
|
||||
|
||||
assert(/* LINTED */
|
||||
MAN_MAX < UCHAR_MAX);
|
||||
|
||||
for (i = 0; i < (int)MAN_MAX; i++) {
|
||||
x = man_macronames[i][0];
|
||||
|
||||
assert(isalpha((u_char)x));
|
||||
|
||||
HASH_ROW(x);
|
||||
|
||||
for (j = 0; j < HASH_DEPTH; j++)
|
||||
if (UCHAR_MAX == table[x + j]) {
|
||||
table[x + j] = (u_char)i;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(j < HASH_DEPTH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum mant
|
||||
man_hash_find(const char *tmp)
|
||||
{
|
||||
int x, y, i;
|
||||
enum mant tok;
|
||||
|
||||
if ('\0' == (x = tmp[0]))
|
||||
return(MAN_MAX);
|
||||
if ( ! (isalpha((u_char)x)))
|
||||
return(MAN_MAX);
|
||||
|
||||
HASH_ROW(x);
|
||||
|
||||
for (i = 0; i < HASH_DEPTH; i++) {
|
||||
if (UCHAR_MAX == (y = table[x + i]))
|
||||
return(MAN_MAX);
|
||||
|
||||
tok = (enum mant)y;
|
||||
if (0 == strcmp(tmp, man_macronames[tok]))
|
||||
return(tok);
|
||||
}
|
||||
|
||||
return(MAN_MAX);
|
||||
}
|
||||
684
usr.bin/mdocml/dist/man_html.c
vendored
684
usr.bin/mdocml/dist/man_html.c
vendored
@@ -1,684 +0,0 @@
|
||||
/* $Vendor-Id: man_html.c,v 1.62 2011/01/07 13:20:58 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
#include "man.h"
|
||||
#include "main.h"
|
||||
|
||||
/* TODO: preserve ident widths. */
|
||||
/* FIXME: have PD set the default vspace width. */
|
||||
|
||||
#define INDENT 5
|
||||
#define HALFINDENT 3
|
||||
|
||||
#define MAN_ARGS const struct man_meta *m, \
|
||||
const struct man_node *n, \
|
||||
struct mhtml *mh, \
|
||||
struct html *h
|
||||
|
||||
struct mhtml {
|
||||
int fl;
|
||||
#define MANH_LITERAL (1 << 0) /* literal context */
|
||||
};
|
||||
|
||||
struct htmlman {
|
||||
int (*pre)(MAN_ARGS);
|
||||
int (*post)(MAN_ARGS);
|
||||
};
|
||||
|
||||
static void print_man(MAN_ARGS);
|
||||
static void print_man_head(MAN_ARGS);
|
||||
static void print_man_nodelist(MAN_ARGS);
|
||||
static void print_man_node(MAN_ARGS);
|
||||
|
||||
static int a2width(const struct man_node *,
|
||||
struct roffsu *);
|
||||
|
||||
static int man_alt_pre(MAN_ARGS);
|
||||
static int man_br_pre(MAN_ARGS);
|
||||
static int man_ign_pre(MAN_ARGS);
|
||||
static int man_in_pre(MAN_ARGS);
|
||||
static int man_literal_pre(MAN_ARGS);
|
||||
static void man_root_post(MAN_ARGS);
|
||||
static int man_root_pre(MAN_ARGS);
|
||||
static int man_B_pre(MAN_ARGS);
|
||||
static int man_HP_pre(MAN_ARGS);
|
||||
static int man_I_pre(MAN_ARGS);
|
||||
static int man_IP_pre(MAN_ARGS);
|
||||
static int man_PP_pre(MAN_ARGS);
|
||||
static int man_RS_pre(MAN_ARGS);
|
||||
static int man_SH_pre(MAN_ARGS);
|
||||
static int man_SM_pre(MAN_ARGS);
|
||||
static int man_SS_pre(MAN_ARGS);
|
||||
|
||||
static const struct htmlman mans[MAN_MAX] = {
|
||||
{ man_br_pre, NULL }, /* br */
|
||||
{ NULL, NULL }, /* TH */
|
||||
{ man_SH_pre, NULL }, /* SH */
|
||||
{ man_SS_pre, NULL }, /* SS */
|
||||
{ man_IP_pre, NULL }, /* TP */
|
||||
{ man_PP_pre, NULL }, /* LP */
|
||||
{ man_PP_pre, NULL }, /* PP */
|
||||
{ man_PP_pre, NULL }, /* P */
|
||||
{ man_IP_pre, NULL }, /* IP */
|
||||
{ man_HP_pre, NULL }, /* HP */
|
||||
{ man_SM_pre, NULL }, /* SM */
|
||||
{ man_SM_pre, NULL }, /* SB */
|
||||
{ man_alt_pre, NULL }, /* BI */
|
||||
{ man_alt_pre, NULL }, /* IB */
|
||||
{ man_alt_pre, NULL }, /* BR */
|
||||
{ man_alt_pre, NULL }, /* RB */
|
||||
{ NULL, NULL }, /* R */
|
||||
{ man_B_pre, NULL }, /* B */
|
||||
{ man_I_pre, NULL }, /* I */
|
||||
{ man_alt_pre, NULL }, /* IR */
|
||||
{ man_alt_pre, NULL }, /* RI */
|
||||
{ NULL, NULL }, /* na */
|
||||
{ man_br_pre, NULL }, /* sp */
|
||||
{ man_literal_pre, NULL }, /* nf */
|
||||
{ man_literal_pre, NULL }, /* fi */
|
||||
{ NULL, NULL }, /* RE */
|
||||
{ man_RS_pre, NULL }, /* RS */
|
||||
{ man_ign_pre, NULL }, /* DT */
|
||||
{ man_ign_pre, NULL }, /* UC */
|
||||
{ man_ign_pre, NULL }, /* PD */
|
||||
{ man_ign_pre, NULL }, /* AT */
|
||||
{ man_in_pre, NULL }, /* in */
|
||||
{ man_ign_pre, NULL }, /* ft */
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
html_man(void *arg, const struct man *m)
|
||||
{
|
||||
struct html *h;
|
||||
struct tag *t;
|
||||
struct mhtml mh;
|
||||
|
||||
h = (struct html *)arg;
|
||||
|
||||
print_gen_decls(h);
|
||||
|
||||
memset(&mh, 0, sizeof(struct mhtml));
|
||||
|
||||
t = print_otag(h, TAG_HTML, 0, NULL);
|
||||
print_man(man_meta(m), man_node(m), &mh, h);
|
||||
print_tagq(h, t);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_man(MAN_ARGS)
|
||||
{
|
||||
struct tag *t;
|
||||
|
||||
t = print_otag(h, TAG_HEAD, 0, NULL);
|
||||
print_man_head(m, n, mh, h);
|
||||
print_tagq(h, t);
|
||||
|
||||
t = print_otag(h, TAG_BODY, 0, NULL);
|
||||
print_man_nodelist(m, n, mh, h);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
print_man_head(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_gen_head(h);
|
||||
bufinit(h);
|
||||
buffmt(h, "%s(%s)", m->title, m->msec);
|
||||
|
||||
print_otag(h, TAG_TITLE, 0, NULL);
|
||||
print_text(h, h->buf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_man_nodelist(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_man_node(m, n, mh, h);
|
||||
if (n->next)
|
||||
print_man_nodelist(m, n->next, mh, h);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_man_node(MAN_ARGS)
|
||||
{
|
||||
int child;
|
||||
struct tag *t;
|
||||
|
||||
child = 1;
|
||||
t = h->tags.head;
|
||||
|
||||
bufinit(h);
|
||||
|
||||
/*
|
||||
* FIXME: embedded elements within next-line scopes (e.g., `br'
|
||||
* within an empty `B') will cause formatting to be forgotten
|
||||
* due to scope closing out.
|
||||
*/
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_ROOT):
|
||||
child = man_root_pre(m, n, mh, h);
|
||||
break;
|
||||
case (MAN_TEXT):
|
||||
print_text(h, n->string);
|
||||
if (MANH_LITERAL & mh->fl)
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
return;
|
||||
case (MAN_TBL):
|
||||
print_tbl(h, n->span);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Close out scope of font prior to opening a macro
|
||||
* scope. Assert that the metafont is on the top of the
|
||||
* stack (it's never nested).
|
||||
*/
|
||||
if (HTMLFONT_NONE != h->metac) {
|
||||
h->metal = h->metac;
|
||||
h->metac = HTMLFONT_NONE;
|
||||
}
|
||||
if (mans[n->tok].pre)
|
||||
child = (*mans[n->tok].pre)(m, n, mh, h);
|
||||
break;
|
||||
}
|
||||
|
||||
if (child && n->child)
|
||||
print_man_nodelist(m, n->child, mh, h);
|
||||
|
||||
/* This will automatically close out any font scope. */
|
||||
print_stagq(h, t);
|
||||
|
||||
bufinit(h);
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_ROOT):
|
||||
man_root_post(m, n, mh, h);
|
||||
break;
|
||||
case (MAN_TBL):
|
||||
break;
|
||||
default:
|
||||
if (mans[n->tok].post)
|
||||
(*mans[n->tok].post)(m, n, mh, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
a2width(const struct man_node *n, struct roffsu *su)
|
||||
{
|
||||
|
||||
if (MAN_TEXT != n->type)
|
||||
return(0);
|
||||
if (a2roffsu(n->string, su, SCALE_BU))
|
||||
return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_root_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag[3];
|
||||
struct tag *t, *tt;
|
||||
char b[BUFSIZ], title[BUFSIZ];
|
||||
|
||||
b[0] = 0;
|
||||
if (m->vol)
|
||||
(void)strlcat(b, m->vol, BUFSIZ);
|
||||
|
||||
snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec);
|
||||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
|
||||
PAIR_CLASS_INIT(&tag[1], "head");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_TABLE, 2, tag);
|
||||
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-ltitle");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, title);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-vol");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, b);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "head-rtitle");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, title);
|
||||
print_tagq(h, t);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
man_root_post(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag[3];
|
||||
struct tag *t, *tt;
|
||||
char b[DATESIZ];
|
||||
|
||||
if (m->rawdate)
|
||||
strlcpy(b, m->rawdate, DATESIZ);
|
||||
else
|
||||
time2a(m->date, b, DATESIZ);
|
||||
|
||||
PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
|
||||
PAIR_CLASS_INIT(&tag[1], "foot");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
|
||||
t = print_otag(h, TAG_TABLE, 3, tag);
|
||||
PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
print_otag(h, TAG_COL, 1, tag);
|
||||
} else
|
||||
t = print_otag(h, TAG_TABLE, 2, tag);
|
||||
|
||||
tt = print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-date");
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
print_text(h, b);
|
||||
print_stagq(h, tt);
|
||||
|
||||
PAIR_CLASS_INIT(&tag[0], "foot-os");
|
||||
if (NULL == h->style) {
|
||||
PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
|
||||
print_otag(h, TAG_TD, 2, tag);
|
||||
} else
|
||||
print_otag(h, TAG_TD, 1, tag);
|
||||
|
||||
if (m->source)
|
||||
print_text(h, m->source);
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_br_pre(MAN_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
struct htmlpair tag;
|
||||
|
||||
SCALE_VS_INIT(&su, 1);
|
||||
|
||||
if (MAN_sp == n->tok) {
|
||||
if (n->child)
|
||||
a2roffsu(n->child->string, &su, SCALE_VS);
|
||||
} else
|
||||
su.scale = 0;
|
||||
|
||||
bufcat_su(h, "height", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
|
||||
/* So the div isn't empty: */
|
||||
print_text(h, "\\~");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_SH_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
|
||||
if (MAN_BLOCK == n->type) {
|
||||
PAIR_CLASS_INIT(&tag, "section");
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
return(1);
|
||||
} else if (MAN_BODY == n->type)
|
||||
return(1);
|
||||
|
||||
print_otag(h, TAG_H1, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_alt_pre(MAN_ARGS)
|
||||
{
|
||||
const struct man_node *nn;
|
||||
int i;
|
||||
enum htmltag fp;
|
||||
struct tag *t;
|
||||
|
||||
for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
|
||||
t = NULL;
|
||||
switch (n->tok) {
|
||||
case (MAN_BI):
|
||||
fp = i % 2 ? TAG_I : TAG_B;
|
||||
break;
|
||||
case (MAN_IB):
|
||||
fp = i % 2 ? TAG_B : TAG_I;
|
||||
break;
|
||||
case (MAN_RI):
|
||||
fp = i % 2 ? TAG_I : TAG_MAX;
|
||||
break;
|
||||
case (MAN_IR):
|
||||
fp = i % 2 ? TAG_MAX : TAG_I;
|
||||
break;
|
||||
case (MAN_BR):
|
||||
fp = i % 2 ? TAG_MAX : TAG_B;
|
||||
break;
|
||||
case (MAN_RB):
|
||||
fp = i % 2 ? TAG_B : TAG_MAX;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (i)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
if (TAG_MAX != fp)
|
||||
t = print_otag(h, fp, 0, NULL);
|
||||
|
||||
print_man_node(m, nn, mh, h);
|
||||
|
||||
if (t)
|
||||
print_tagq(h, t);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_SM_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_SMALL, 0, NULL);
|
||||
if (MAN_SB == n->tok)
|
||||
print_otag(h, TAG_B, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_SS_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
|
||||
if (MAN_BLOCK == n->type) {
|
||||
PAIR_CLASS_INIT(&tag, "subsection");
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
return(1);
|
||||
} else if (MAN_BODY == n->type)
|
||||
return(1);
|
||||
|
||||
print_otag(h, TAG_H2, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_PP_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
if (MAN_HEAD == n->type)
|
||||
return(0);
|
||||
else if (MAN_BODY == n->type && n->prev)
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_IP_pre(MAN_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
struct htmlpair tag;
|
||||
const struct man_node *nn;
|
||||
|
||||
/*
|
||||
* This scattering of 1-BU margins and pads is to make sure that
|
||||
* when text overruns its box, the subsequent text isn't flush
|
||||
* up against it. However, the rest of the right-hand box must
|
||||
* also be adjusted in consideration of this 1-BU space.
|
||||
*/
|
||||
|
||||
if (MAN_BODY == n->type) {
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
nn = MAN_BLOCK == n->type ?
|
||||
n->head->child : n->parent->head->child;
|
||||
|
||||
SCALE_HS_INIT(&su, INDENT);
|
||||
|
||||
/* Width is the second token. */
|
||||
|
||||
if (MAN_IP == n->tok && NULL != nn)
|
||||
if (NULL != (nn = nn->next))
|
||||
a2width(nn, &su);
|
||||
|
||||
/* Width is the first token. */
|
||||
|
||||
if (MAN_TP == n->tok && NULL != nn) {
|
||||
/* Skip past non-text children. */
|
||||
while (nn && MAN_TEXT != nn->type)
|
||||
nn = nn->next;
|
||||
if (nn)
|
||||
a2width(nn, &su);
|
||||
}
|
||||
|
||||
if (MAN_BLOCK == n->type) {
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
print_otag(h, TAG_TABLE, 0, NULL);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_COL, 1, &tag);
|
||||
print_otag(h, TAG_COL, 0, NULL);
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
print_otag(h, TAG_TR, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
|
||||
/* For IP, only print the first header element. */
|
||||
|
||||
if (MAN_IP == n->tok && n->child)
|
||||
print_man_node(m, n->child, mh, h);
|
||||
|
||||
/* For TP, only print next-line header elements. */
|
||||
|
||||
if (MAN_TP == n->tok)
|
||||
for (nn = n->child; nn; nn = nn->next)
|
||||
if (nn->line > n->line)
|
||||
print_man_node(m, nn, mh, h);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_HP_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct roffsu su;
|
||||
const struct man_node *np;
|
||||
|
||||
np = MAN_BLOCK == n->type ?
|
||||
n->head->child :
|
||||
n->parent->head->child;
|
||||
|
||||
if (NULL == np || ! a2width(np, &su))
|
||||
SCALE_HS_INIT(&su, INDENT);
|
||||
|
||||
if (MAN_HEAD == n->type) {
|
||||
print_otag(h, TAG_TD, 0, NULL);
|
||||
return(0);
|
||||
} else if (MAN_BLOCK == n->type) {
|
||||
print_otag(h, TAG_P, 0, NULL);
|
||||
print_otag(h, TAG_TABLE, 0, NULL);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_COL, 1, &tag);
|
||||
print_otag(h, TAG_COL, 0, NULL);
|
||||
print_otag(h, TAG_TBODY, 0, NULL);
|
||||
print_otag(h, TAG_TR, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
su.scale = -su.scale;
|
||||
bufcat_su(h, "text-indent", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_TD, 1, &tag);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_B_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_B, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_I_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_I, 0, NULL);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_literal_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
if (MAN_nf == n->tok) {
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
mh->fl |= MANH_LITERAL;
|
||||
} else
|
||||
mh->fl &= ~MANH_LITERAL;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_in_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
print_otag(h, TAG_BR, 0, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_ign_pre(MAN_ARGS)
|
||||
{
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
man_RS_pre(MAN_ARGS)
|
||||
{
|
||||
struct htmlpair tag;
|
||||
struct roffsu su;
|
||||
|
||||
if (MAN_HEAD == n->type)
|
||||
return(0);
|
||||
else if (MAN_BODY == n->type)
|
||||
return(1);
|
||||
|
||||
SCALE_HS_INIT(&su, INDENT);
|
||||
if (n->head->child)
|
||||
a2width(n->head->child, &su);
|
||||
|
||||
bufcat_su(h, "margin-left", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
print_otag(h, TAG_DIV, 1, &tag);
|
||||
return(1);
|
||||
}
|
||||
477
usr.bin/mdocml/dist/man_macro.c
vendored
477
usr.bin/mdocml/dist/man_macro.c
vendored
@@ -1,477 +0,0 @@
|
||||
/* $Vendor-Id: man_macro.c,v 1.54 2010/12/08 10:58:22 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
|
||||
enum rew {
|
||||
REW_REWIND,
|
||||
REW_NOHALT,
|
||||
REW_HALT
|
||||
};
|
||||
|
||||
static int blk_close(MACRO_PROT_ARGS);
|
||||
static int blk_exp(MACRO_PROT_ARGS);
|
||||
static int blk_imp(MACRO_PROT_ARGS);
|
||||
static int in_line_eoln(MACRO_PROT_ARGS);
|
||||
|
||||
static int rew_scope(enum man_type,
|
||||
struct man *, enum mant);
|
||||
static enum rew rew_dohalt(enum mant, enum man_type,
|
||||
const struct man_node *);
|
||||
static enum rew rew_block(enum mant, enum man_type,
|
||||
const struct man_node *);
|
||||
static int rew_warn(struct man *,
|
||||
struct man_node *, enum mandocerr);
|
||||
|
||||
const struct man_macro __man_macros[MAN_MAX] = {
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* br */
|
||||
{ in_line_eoln, 0 }, /* TH */
|
||||
{ blk_imp, MAN_SCOPED }, /* SH */
|
||||
{ blk_imp, MAN_SCOPED }, /* SS */
|
||||
{ blk_imp, MAN_SCOPED | MAN_FSCOPED }, /* TP */
|
||||
{ blk_imp, 0 }, /* LP */
|
||||
{ blk_imp, 0 }, /* PP */
|
||||
{ blk_imp, 0 }, /* P */
|
||||
{ blk_imp, 0 }, /* IP */
|
||||
{ blk_imp, 0 }, /* HP */
|
||||
{ in_line_eoln, MAN_SCOPED }, /* SM */
|
||||
{ in_line_eoln, MAN_SCOPED }, /* SB */
|
||||
{ in_line_eoln, 0 }, /* BI */
|
||||
{ in_line_eoln, 0 }, /* IB */
|
||||
{ in_line_eoln, 0 }, /* BR */
|
||||
{ in_line_eoln, 0 }, /* RB */
|
||||
{ in_line_eoln, MAN_SCOPED }, /* R */
|
||||
{ in_line_eoln, MAN_SCOPED }, /* B */
|
||||
{ in_line_eoln, MAN_SCOPED }, /* I */
|
||||
{ in_line_eoln, 0 }, /* IR */
|
||||
{ in_line_eoln, 0 }, /* RI */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* na */
|
||||
{ in_line_eoln, MAN_NSCOPED }, /* sp */
|
||||
{ in_line_eoln, 0 }, /* nf */
|
||||
{ in_line_eoln, 0 }, /* fi */
|
||||
{ blk_close, 0 }, /* RE */
|
||||
{ blk_exp, MAN_EXPLICIT }, /* RS */
|
||||
{ in_line_eoln, 0 }, /* DT */
|
||||
{ in_line_eoln, 0 }, /* UC */
|
||||
{ in_line_eoln, 0 }, /* PD */
|
||||
{ in_line_eoln, 0 }, /* AT */
|
||||
{ in_line_eoln, 0 }, /* in */
|
||||
{ in_line_eoln, 0 }, /* ft */
|
||||
};
|
||||
|
||||
const struct man_macro * const man_macros = __man_macros;
|
||||
|
||||
|
||||
/*
|
||||
* Warn when "n" is an explicit non-roff macro.
|
||||
*/
|
||||
static int
|
||||
rew_warn(struct man *m, struct man_node *n, enum mandocerr er)
|
||||
{
|
||||
|
||||
if (er == MANDOCERR_MAX || MAN_BLOCK != n->type)
|
||||
return(1);
|
||||
if (MAN_VALID & n->flags)
|
||||
return(1);
|
||||
if ( ! (MAN_EXPLICIT & man_macros[n->tok].flags))
|
||||
return(1);
|
||||
return(man_nmsg(m, n, er));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rewind scope. If a code "er" != MANDOCERR_MAX has been provided, it
|
||||
* will be used if an explicit block scope is being closed out.
|
||||
*/
|
||||
int
|
||||
man_unscope(struct man *m, const struct man_node *n,
|
||||
enum mandocerr er)
|
||||
{
|
||||
|
||||
assert(n);
|
||||
|
||||
/* LINTED */
|
||||
while (m->last != n) {
|
||||
if ( ! rew_warn(m, m->last, er))
|
||||
return(0);
|
||||
if ( ! man_valid_post(m))
|
||||
return(0);
|
||||
m->last = m->last->parent;
|
||||
assert(m->last);
|
||||
}
|
||||
|
||||
if ( ! rew_warn(m, m->last, er))
|
||||
return(0);
|
||||
if ( ! man_valid_post(m))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_ROOT == m->last->type ?
|
||||
MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static enum rew
|
||||
rew_block(enum mant ntok, enum man_type type, const struct man_node *n)
|
||||
{
|
||||
|
||||
if (MAN_BLOCK == type && ntok == n->parent->tok &&
|
||||
MAN_BODY == n->parent->type)
|
||||
return(REW_REWIND);
|
||||
return(ntok == n->tok ? REW_HALT : REW_NOHALT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* There are three scope levels: scoped to the root (all), scoped to the
|
||||
* section (all less sections), and scoped to subsections (all less
|
||||
* sections and subsections).
|
||||
*/
|
||||
static enum rew
|
||||
rew_dohalt(enum mant tok, enum man_type type, const struct man_node *n)
|
||||
{
|
||||
enum rew c;
|
||||
|
||||
/* We cannot progress beyond the root ever. */
|
||||
if (MAN_ROOT == n->type)
|
||||
return(REW_HALT);
|
||||
|
||||
assert(n->parent);
|
||||
|
||||
/* Normal nodes shouldn't go to the level of the root. */
|
||||
if (MAN_ROOT == n->parent->type)
|
||||
return(REW_REWIND);
|
||||
|
||||
/* Already-validated nodes should be closed out. */
|
||||
if (MAN_VALID & n->flags)
|
||||
return(REW_NOHALT);
|
||||
|
||||
/* First: rewind to ourselves. */
|
||||
if (type == n->type && tok == n->tok)
|
||||
return(REW_REWIND);
|
||||
|
||||
/*
|
||||
* Next follow the implicit scope-smashings as defined by man.7:
|
||||
* section, sub-section, etc.
|
||||
*/
|
||||
|
||||
switch (tok) {
|
||||
case (MAN_SH):
|
||||
break;
|
||||
case (MAN_SS):
|
||||
/* Rewind to a section, if a block. */
|
||||
if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
|
||||
return(c);
|
||||
break;
|
||||
case (MAN_RS):
|
||||
/* Rewind to a subsection, if a block. */
|
||||
if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
|
||||
return(c);
|
||||
/* Rewind to a section, if a block. */
|
||||
if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
|
||||
return(c);
|
||||
break;
|
||||
default:
|
||||
/* Rewind to an offsetter, if a block. */
|
||||
if (REW_NOHALT != (c = rew_block(MAN_RS, type, n)))
|
||||
return(c);
|
||||
/* Rewind to a subsection, if a block. */
|
||||
if (REW_NOHALT != (c = rew_block(MAN_SS, type, n)))
|
||||
return(c);
|
||||
/* Rewind to a section, if a block. */
|
||||
if (REW_NOHALT != (c = rew_block(MAN_SH, type, n)))
|
||||
return(c);
|
||||
break;
|
||||
}
|
||||
|
||||
return(REW_NOHALT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Rewinding entails ascending the parse tree until a coherent point,
|
||||
* for example, the `SH' macro will close out any intervening `SS'
|
||||
* scopes. When a scope is closed, it must be validated and actioned.
|
||||
*/
|
||||
static int
|
||||
rew_scope(enum man_type type, struct man *m, enum mant tok)
|
||||
{
|
||||
struct man_node *n;
|
||||
enum rew c;
|
||||
|
||||
/* LINTED */
|
||||
for (n = m->last; n; n = n->parent) {
|
||||
/*
|
||||
* Whether we should stop immediately (REW_HALT), stop
|
||||
* and rewind until this point (REW_REWIND), or keep
|
||||
* rewinding (REW_NOHALT).
|
||||
*/
|
||||
c = rew_dohalt(tok, type, n);
|
||||
if (REW_HALT == c)
|
||||
return(1);
|
||||
if (REW_REWIND == c)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind until the current point. Warn if we're a roff
|
||||
* instruction that's mowing over explicit scopes.
|
||||
*/
|
||||
assert(n);
|
||||
|
||||
return(man_unscope(m, n, MANDOCERR_MAX));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Close out a generic explicit macro.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
blk_close(MACRO_PROT_ARGS)
|
||||
{
|
||||
enum mant ntok;
|
||||
const struct man_node *nn;
|
||||
|
||||
switch (tok) {
|
||||
case (MAN_RE):
|
||||
ntok = MAN_RS;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
for (nn = m->last->parent; nn; nn = nn->parent)
|
||||
if (ntok == nn->tok)
|
||||
break;
|
||||
|
||||
if (NULL == nn)
|
||||
if ( ! man_pmsg(m, line, ppos, MANDOCERR_NOSCOPE))
|
||||
return(0);
|
||||
|
||||
if ( ! rew_scope(MAN_BODY, m, ntok))
|
||||
return(0);
|
||||
if ( ! rew_scope(MAN_BLOCK, m, ntok))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
blk_exp(MACRO_PROT_ARGS)
|
||||
{
|
||||
int w, la;
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* Close out prior scopes. "Regular" explicit macros cannot be
|
||||
* nested, but we allow roff macros to be placed just about
|
||||
* anywhere.
|
||||
*/
|
||||
|
||||
if ( ! rew_scope(MAN_BODY, m, tok))
|
||||
return(0);
|
||||
if ( ! rew_scope(MAN_BLOCK, m, tok))
|
||||
return(0);
|
||||
|
||||
if ( ! man_block_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
if ( ! man_head_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
w = man_args(m, line, pos, buf, &p);
|
||||
|
||||
if (-1 == w)
|
||||
return(0);
|
||||
if (0 == w)
|
||||
break;
|
||||
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
||||
assert(m);
|
||||
assert(tok != MAN_MAX);
|
||||
|
||||
if ( ! rew_scope(MAN_HEAD, m, tok))
|
||||
return(0);
|
||||
return(man_body_alloc(m, line, ppos, tok));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Parse an implicit-block macro. These contain a MAN_HEAD and a
|
||||
* MAN_BODY contained within a MAN_BLOCK. Rules for closing out other
|
||||
* scopes, such as `SH' closing out an `SS', are defined in the rew
|
||||
* routines.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
blk_imp(MACRO_PROT_ARGS)
|
||||
{
|
||||
int w, la;
|
||||
char *p;
|
||||
struct man_node *n;
|
||||
|
||||
/* Close out prior scopes. */
|
||||
|
||||
if ( ! rew_scope(MAN_BODY, m, tok))
|
||||
return(0);
|
||||
if ( ! rew_scope(MAN_BLOCK, m, tok))
|
||||
return(0);
|
||||
|
||||
/* Allocate new block & head scope. */
|
||||
|
||||
if ( ! man_block_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
if ( ! man_head_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
|
||||
n = m->last;
|
||||
|
||||
/* Add line arguments. */
|
||||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
w = man_args(m, line, pos, buf, &p);
|
||||
|
||||
if (-1 == w)
|
||||
return(0);
|
||||
if (0 == w)
|
||||
break;
|
||||
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Close out head and open body (unless MAN_SCOPE). */
|
||||
|
||||
if (MAN_SCOPED & man_macros[tok].flags) {
|
||||
/* If we're forcing scope (`TP'), keep it open. */
|
||||
if (MAN_FSCOPED & man_macros[tok].flags) {
|
||||
m->flags |= MAN_BLINE;
|
||||
return(1);
|
||||
} else if (n == m->last) {
|
||||
m->flags |= MAN_BLINE;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! rew_scope(MAN_HEAD, m, tok))
|
||||
return(0);
|
||||
return(man_body_alloc(m, line, ppos, tok));
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
in_line_eoln(MACRO_PROT_ARGS)
|
||||
{
|
||||
int w, la;
|
||||
char *p;
|
||||
struct man_node *n;
|
||||
|
||||
if ( ! man_elem_alloc(m, line, ppos, tok))
|
||||
return(0);
|
||||
|
||||
n = m->last;
|
||||
|
||||
for (;;) {
|
||||
la = *pos;
|
||||
w = man_args(m, line, pos, buf, &p);
|
||||
|
||||
if (-1 == w)
|
||||
return(0);
|
||||
if (0 == w)
|
||||
break;
|
||||
if ( ! man_word_alloc(m, line, la, p))
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no arguments are specified and this is MAN_SCOPED (i.e.,
|
||||
* next-line scoped), then set our mode to indicate that we're
|
||||
* waiting for terms to load into our context.
|
||||
*/
|
||||
|
||||
if (n == m->last && MAN_SCOPED & man_macros[tok].flags) {
|
||||
assert( ! (MAN_NSCOPED & man_macros[tok].flags));
|
||||
m->flags |= MAN_ELINE;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Set ignorable context, if applicable. */
|
||||
|
||||
if (MAN_NSCOPED & man_macros[tok].flags) {
|
||||
assert( ! (MAN_SCOPED & man_macros[tok].flags));
|
||||
m->flags |= MAN_ILINE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind our element scope. Note that when TH is pruned, we'll
|
||||
* be back at the root, so make sure that we don't clobber as
|
||||
* its sibling.
|
||||
*/
|
||||
|
||||
for ( ; m->last; m->last = m->last->parent) {
|
||||
if (m->last == n)
|
||||
break;
|
||||
if (m->last->type == MAN_ROOT)
|
||||
break;
|
||||
if ( ! man_valid_post(m))
|
||||
return(0);
|
||||
}
|
||||
|
||||
assert(m->last);
|
||||
|
||||
/*
|
||||
* Same here regarding whether we're back at the root.
|
||||
*/
|
||||
|
||||
if (m->last->type != MAN_ROOT && ! man_valid_post(m))
|
||||
return(0);
|
||||
|
||||
m->next = MAN_ROOT == m->last->type ?
|
||||
MAN_NEXT_CHILD : MAN_NEXT_SIBLING;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_macroend(struct man *m)
|
||||
{
|
||||
|
||||
return(man_unscope(m, m->first, MANDOCERR_SCOPEEXIT));
|
||||
}
|
||||
|
||||
1031
usr.bin/mdocml/dist/man_term.c
vendored
1031
usr.bin/mdocml/dist/man_term.c
vendored
File diff suppressed because it is too large
Load Diff
577
usr.bin/mdocml/dist/man_validate.c
vendored
577
usr.bin/mdocml/dist/man_validate.c
vendored
@@ -1,577 +0,0 @@
|
||||
/* $Vendor-Id: man_validate.c,v 1.57 2011/01/01 12:59:17 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libman.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
#define CHKARGS struct man *m, struct man_node *n
|
||||
|
||||
typedef int (*v_check)(CHKARGS);
|
||||
|
||||
struct man_valid {
|
||||
v_check *pres;
|
||||
v_check *posts;
|
||||
};
|
||||
|
||||
static int check_bline(CHKARGS);
|
||||
static int check_eq0(CHKARGS);
|
||||
static int check_ft(CHKARGS);
|
||||
static int check_le1(CHKARGS);
|
||||
static int check_ge2(CHKARGS);
|
||||
static int check_le5(CHKARGS);
|
||||
static int check_par(CHKARGS);
|
||||
static int check_part(CHKARGS);
|
||||
static int check_root(CHKARGS);
|
||||
static int check_sec(CHKARGS);
|
||||
static int check_text(CHKARGS);
|
||||
static int check_title(CHKARGS);
|
||||
|
||||
static int post_AT(CHKARGS);
|
||||
static int post_fi(CHKARGS);
|
||||
static int post_nf(CHKARGS);
|
||||
static int post_TH(CHKARGS);
|
||||
static int post_UC(CHKARGS);
|
||||
|
||||
static v_check posts_at[] = { post_AT, NULL };
|
||||
static v_check posts_eq0[] = { check_eq0, NULL };
|
||||
static v_check posts_fi[] = { check_eq0, post_fi, NULL };
|
||||
static v_check posts_le1[] = { check_le1, NULL };
|
||||
static v_check posts_ft[] = { check_ft, NULL };
|
||||
static v_check posts_nf[] = { check_eq0, post_nf, NULL };
|
||||
static v_check posts_par[] = { check_par, NULL };
|
||||
static v_check posts_part[] = { check_part, NULL };
|
||||
static v_check posts_sec[] = { check_sec, NULL };
|
||||
static v_check posts_th[] = { check_ge2, check_le5, check_title, post_TH, NULL };
|
||||
static v_check posts_uc[] = { post_UC, NULL };
|
||||
static v_check pres_bline[] = { check_bline, NULL };
|
||||
|
||||
|
||||
static const struct man_valid man_valids[MAN_MAX] = {
|
||||
{ NULL, posts_eq0 }, /* br */
|
||||
{ pres_bline, posts_th }, /* TH */
|
||||
{ pres_bline, posts_sec }, /* SH */
|
||||
{ pres_bline, posts_sec }, /* SS */
|
||||
{ pres_bline, posts_par }, /* TP */
|
||||
{ pres_bline, posts_par }, /* LP */
|
||||
{ pres_bline, posts_par }, /* PP */
|
||||
{ pres_bline, posts_par }, /* P */
|
||||
{ pres_bline, posts_par }, /* IP */
|
||||
{ pres_bline, posts_par }, /* HP */
|
||||
{ NULL, NULL }, /* SM */
|
||||
{ NULL, NULL }, /* SB */
|
||||
{ NULL, NULL }, /* BI */
|
||||
{ NULL, NULL }, /* IB */
|
||||
{ NULL, NULL }, /* BR */
|
||||
{ NULL, NULL }, /* RB */
|
||||
{ NULL, NULL }, /* R */
|
||||
{ NULL, NULL }, /* B */
|
||||
{ NULL, NULL }, /* I */
|
||||
{ NULL, NULL }, /* IR */
|
||||
{ NULL, NULL }, /* RI */
|
||||
{ NULL, posts_eq0 }, /* na */ /* FIXME: should warn only. */
|
||||
{ NULL, posts_le1 }, /* sp */ /* FIXME: should warn only. */
|
||||
{ pres_bline, posts_nf }, /* nf */
|
||||
{ pres_bline, posts_fi }, /* fi */
|
||||
{ NULL, NULL }, /* RE */
|
||||
{ NULL, posts_part }, /* RS */
|
||||
{ NULL, NULL }, /* DT */
|
||||
{ NULL, posts_uc }, /* UC */
|
||||
{ NULL, NULL }, /* PD */
|
||||
{ NULL, posts_at }, /* AT */
|
||||
{ NULL, NULL }, /* in */
|
||||
{ NULL, posts_ft }, /* ft */
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
man_valid_pre(struct man *m, struct man_node *n)
|
||||
{
|
||||
v_check *cp;
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_TEXT):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_ROOT):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TBL):
|
||||
return(1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL == (cp = man_valids[n->tok].pres))
|
||||
return(1);
|
||||
for ( ; *cp; cp++)
|
||||
if ( ! (*cp)(m, n))
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
man_valid_post(struct man *m)
|
||||
{
|
||||
v_check *cp;
|
||||
|
||||
if (MAN_VALID & m->last->flags)
|
||||
return(1);
|
||||
m->last->flags |= MAN_VALID;
|
||||
|
||||
switch (m->last->type) {
|
||||
case (MAN_TEXT):
|
||||
return(check_text(m, m->last));
|
||||
case (MAN_ROOT):
|
||||
return(check_root(m, m->last));
|
||||
case (MAN_TBL):
|
||||
return(1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL == (cp = man_valids[m->last->tok].posts))
|
||||
return(1);
|
||||
for ( ; *cp; cp++)
|
||||
if ( ! (*cp)(m, m->last))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_root(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BLINE & m->flags)
|
||||
man_nmsg(m, n, MANDOCERR_SCOPEEXIT);
|
||||
else if (MAN_ELINE & m->flags)
|
||||
man_nmsg(m, n, MANDOCERR_SCOPEEXIT);
|
||||
|
||||
m->flags &= ~MAN_BLINE;
|
||||
m->flags &= ~MAN_ELINE;
|
||||
|
||||
if (NULL == m->first->child) {
|
||||
man_nmsg(m, n, MANDOCERR_NODOCBODY);
|
||||
return(0);
|
||||
} else if (NULL == m->meta.title) {
|
||||
man_nmsg(m, n, MANDOCERR_NOTITLE);
|
||||
|
||||
/*
|
||||
* If a title hasn't been set, do so now (by
|
||||
* implication, date and section also aren't set).
|
||||
*/
|
||||
|
||||
m->meta.title = mandoc_strdup("unknown");
|
||||
m->meta.date = time(NULL);
|
||||
m->meta.msec = mandoc_strdup("1");
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_title(CHKARGS)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
assert(n->child);
|
||||
/* FIXME: is this sufficient? */
|
||||
if ('\0' == *n->child->string) {
|
||||
man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (p = n->child->string; '\0' != *p; p++)
|
||||
/* Only warn about this once... */
|
||||
if (isalpha((u_char)*p) && ! isupper((u_char)*p)) {
|
||||
man_nmsg(m, n, MANDOCERR_UPPERCASE);
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_text(CHKARGS)
|
||||
{
|
||||
char *p;
|
||||
int pos, c;
|
||||
size_t sz;
|
||||
|
||||
for (p = n->string, pos = n->pos + 1; *p; p++, pos++) {
|
||||
sz = strcspn(p, "\t\\");
|
||||
p += (int)sz;
|
||||
|
||||
if ('\0' == *p)
|
||||
break;
|
||||
|
||||
pos += (int)sz;
|
||||
|
||||
if ('\t' == *p) {
|
||||
if (MAN_LITERAL & m->flags)
|
||||
continue;
|
||||
if (man_pmsg(m, n->line, pos, MANDOCERR_BADTAB))
|
||||
continue;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Check the special character. */
|
||||
|
||||
c = mandoc_special(p);
|
||||
if (c) {
|
||||
p += c - 1;
|
||||
pos += c - 1;
|
||||
} else
|
||||
man_pmsg(m, n->line, pos, MANDOCERR_BADESCAPE);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
#define INEQ_DEFINE(x, ineq, name) \
|
||||
static int \
|
||||
check_##name(CHKARGS) \
|
||||
{ \
|
||||
if (n->nchild ineq (x)) \
|
||||
return(1); \
|
||||
man_vmsg(m, MANDOCERR_SYNTARGCOUNT, n->line, n->pos, \
|
||||
"line arguments %s %d (have %d)", \
|
||||
#ineq, (x), n->nchild); \
|
||||
return(0); \
|
||||
}
|
||||
|
||||
INEQ_DEFINE(0, ==, eq0)
|
||||
INEQ_DEFINE(1, <=, le1)
|
||||
INEQ_DEFINE(2, >=, ge2)
|
||||
INEQ_DEFINE(5, <=, le5)
|
||||
|
||||
static int
|
||||
check_ft(CHKARGS)
|
||||
{
|
||||
char *cp;
|
||||
int ok;
|
||||
|
||||
if (0 == n->nchild)
|
||||
return(1);
|
||||
|
||||
ok = 0;
|
||||
cp = n->child->string;
|
||||
switch (*cp) {
|
||||
case ('1'):
|
||||
/* FALLTHROUGH */
|
||||
case ('2'):
|
||||
/* FALLTHROUGH */
|
||||
case ('3'):
|
||||
/* FALLTHROUGH */
|
||||
case ('4'):
|
||||
/* FALLTHROUGH */
|
||||
case ('I'):
|
||||
/* FALLTHROUGH */
|
||||
case ('P'):
|
||||
/* FALLTHROUGH */
|
||||
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) {
|
||||
man_vmsg(m, MANDOCERR_BADFONT,
|
||||
n->line, n->pos, "%s", cp);
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
if (1 < n->nchild)
|
||||
man_vmsg(m, MANDOCERR_ARGCOUNT, n->line, n->pos,
|
||||
"want one child (have %d)", n->nchild);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
check_sec(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_HEAD == n->type && 0 == n->nchild) {
|
||||
man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
|
||||
return(0);
|
||||
} else if (MAN_BODY == n->type && 0 == n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_NOBODY);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_part(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BODY == n->type && 0 == n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_NOBODY);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_par(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_BODY == n->type)
|
||||
switch (n->tok) {
|
||||
case (MAN_IP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_HP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_TP):
|
||||
/* Body-less lists are ok. */
|
||||
break;
|
||||
default:
|
||||
if (0 == n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_NOBODY);
|
||||
break;
|
||||
}
|
||||
if (MAN_HEAD == n->type)
|
||||
switch (n->tok) {
|
||||
case (MAN_PP):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_P):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_LP):
|
||||
if (n->nchild)
|
||||
man_nmsg(m, n, MANDOCERR_ARGSLOST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_bline(CHKARGS)
|
||||
{
|
||||
|
||||
assert( ! (MAN_ELINE & m->flags));
|
||||
if (MAN_BLINE & m->flags) {
|
||||
man_nmsg(m, n, MANDOCERR_SYNTLINESCOPE);
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_TH(CHKARGS)
|
||||
{
|
||||
|
||||
if (m->meta.title)
|
||||
free(m->meta.title);
|
||||
if (m->meta.vol)
|
||||
free(m->meta.vol);
|
||||
if (m->meta.source)
|
||||
free(m->meta.source);
|
||||
if (m->meta.msec)
|
||||
free(m->meta.msec);
|
||||
if (m->meta.rawdate)
|
||||
free(m->meta.rawdate);
|
||||
|
||||
m->meta.title = m->meta.vol = m->meta.rawdate =
|
||||
m->meta.msec = m->meta.source = NULL;
|
||||
m->meta.date = 0;
|
||||
|
||||
/* ->TITLE<- MSEC DATE SOURCE VOL */
|
||||
|
||||
n = n->child;
|
||||
assert(n);
|
||||
m->meta.title = mandoc_strdup(n->string);
|
||||
|
||||
/* TITLE ->MSEC<- DATE SOURCE VOL */
|
||||
|
||||
n = n->next;
|
||||
assert(n);
|
||||
m->meta.msec = mandoc_strdup(n->string);
|
||||
|
||||
/* TITLE MSEC ->DATE<- SOURCE VOL */
|
||||
|
||||
/*
|
||||
* Try to parse the date. If this works, stash the epoch (this
|
||||
* is optimal because we can reformat it in the canonical form).
|
||||
* If it doesn't parse, isn't specified at all, or is an empty
|
||||
* string, then use the current date.
|
||||
*/
|
||||
|
||||
n = n->next;
|
||||
if (n && n->string && *n->string) {
|
||||
m->meta.date = mandoc_a2time
|
||||
(MTIME_ISO_8601, n->string);
|
||||
if (0 == m->meta.date) {
|
||||
man_nmsg(m, n, MANDOCERR_BADDATE);
|
||||
m->meta.rawdate = mandoc_strdup(n->string);
|
||||
}
|
||||
} else
|
||||
m->meta.date = time(NULL);
|
||||
|
||||
/* TITLE MSEC DATE ->SOURCE<- VOL */
|
||||
|
||||
if (n && (n = n->next))
|
||||
m->meta.source = mandoc_strdup(n->string);
|
||||
|
||||
/* TITLE MSEC DATE SOURCE ->VOL<- */
|
||||
|
||||
if (n && (n = n->next))
|
||||
m->meta.vol = mandoc_strdup(n->string);
|
||||
|
||||
/*
|
||||
* Remove the `TH' node after we've processed it for our
|
||||
* meta-data.
|
||||
*/
|
||||
man_node_delete(m, m->last);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_nf(CHKARGS)
|
||||
{
|
||||
|
||||
if (MAN_LITERAL & m->flags)
|
||||
man_nmsg(m, n, MANDOCERR_SCOPEREP);
|
||||
|
||||
m->flags |= MAN_LITERAL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_fi(CHKARGS)
|
||||
{
|
||||
|
||||
if ( ! (MAN_LITERAL & m->flags))
|
||||
man_nmsg(m, n, MANDOCERR_NOSCOPE);
|
||||
|
||||
m->flags &= ~MAN_LITERAL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_UC(CHKARGS)
|
||||
{
|
||||
static const char * const bsd_versions[] = {
|
||||
"3rd Berkeley Distribution",
|
||||
"4th Berkeley Distribution",
|
||||
"4.2 Berkeley Distribution",
|
||||
"4.3 Berkeley Distribution",
|
||||
"4.4 Berkeley Distribution",
|
||||
};
|
||||
|
||||
const char *p, *s;
|
||||
|
||||
n = n->child;
|
||||
n = m->last->child;
|
||||
|
||||
if (NULL == n || MAN_TEXT != n->type)
|
||||
p = bsd_versions[0];
|
||||
else {
|
||||
s = n->string;
|
||||
if (0 == strcmp(s, "3"))
|
||||
p = bsd_versions[0];
|
||||
else if (0 == strcmp(s, "4"))
|
||||
p = bsd_versions[1];
|
||||
else if (0 == strcmp(s, "5"))
|
||||
p = bsd_versions[2];
|
||||
else if (0 == strcmp(s, "6"))
|
||||
p = bsd_versions[3];
|
||||
else if (0 == strcmp(s, "7"))
|
||||
p = bsd_versions[4];
|
||||
else
|
||||
p = bsd_versions[0];
|
||||
}
|
||||
|
||||
if (m->meta.source)
|
||||
free(m->meta.source);
|
||||
|
||||
m->meta.source = mandoc_strdup(p);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
post_AT(CHKARGS)
|
||||
{
|
||||
static const char * const unix_versions[] = {
|
||||
"7th Edition",
|
||||
"System III",
|
||||
"System V",
|
||||
"System V Release 2",
|
||||
};
|
||||
|
||||
const char *p, *s;
|
||||
struct man_node *nn;
|
||||
|
||||
n = n->child;
|
||||
|
||||
if (NULL == n || MAN_TEXT != n->type)
|
||||
p = unix_versions[0];
|
||||
else {
|
||||
s = n->string;
|
||||
if (0 == strcmp(s, "3"))
|
||||
p = unix_versions[0];
|
||||
else if (0 == strcmp(s, "4"))
|
||||
p = unix_versions[1];
|
||||
else if (0 == strcmp(s, "5")) {
|
||||
nn = n->next;
|
||||
if (nn && MAN_TEXT == nn->type && nn->string[0])
|
||||
p = unix_versions[3];
|
||||
else
|
||||
p = unix_versions[2];
|
||||
} else
|
||||
p = unix_versions[0];
|
||||
}
|
||||
|
||||
if (m->meta.source)
|
||||
free(m->meta.source);
|
||||
|
||||
m->meta.source = mandoc_strdup(p);
|
||||
return(1);
|
||||
}
|
||||
BIN
usr.bin/mdocml/dist/mandoc
vendored
BIN
usr.bin/mdocml/dist/mandoc
vendored
Binary file not shown.
569
usr.bin/mdocml/dist/mandoc.1
vendored
569
usr.bin/mdocml/dist/mandoc.1
vendored
@@ -1,569 +0,0 @@
|
||||
.\" $Vendor-Id: mandoc.1,v 1.84 2011/01/04 23:32:21 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 4, 2011
|
||||
.Dt MANDOC 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc
|
||||
.Nd format and display UNIX manuals
|
||||
.Sh SYNOPSIS
|
||||
.Nm mandoc
|
||||
.Op Fl V
|
||||
.Op Fl m Ns Ar format
|
||||
.Op Fl O Ns Ar option
|
||||
.Op Fl T Ns Ar output
|
||||
.Op Fl W Ns Ar level
|
||||
.Op Ar file...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility formats
|
||||
.Ux
|
||||
manual pages for display.
|
||||
The arguments are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.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 Ns Ar option
|
||||
Comma-separated output options.
|
||||
.It Fl T Ns Ar output
|
||||
Output format.
|
||||
See
|
||||
.Sx Output Formats
|
||||
for available formats.
|
||||
Defaults to
|
||||
.Fl T Ns Cm ascii .
|
||||
.It Fl V
|
||||
Print version and exit.
|
||||
.It Fl W Ns 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 fatal .
|
||||
The default is
|
||||
.Fl W Ns Cm fatal ;
|
||||
.Fl W Ns Cm all
|
||||
is an alias for
|
||||
.Fl W Ns Cm warning .
|
||||
See
|
||||
.Sx EXIT STATUS
|
||||
and
|
||||
.Sx DIAGNOSTICS
|
||||
for details.
|
||||
.Pp
|
||||
The special option
|
||||
.Fl W Ns Cm stop
|
||||
tells
|
||||
.Nm
|
||||
to exit after parsing a file that causes warnings or errors of at least
|
||||
the requested level.
|
||||
No formatted output will be produced from that file.
|
||||
If both a
|
||||
.Ar level
|
||||
and
|
||||
.Cm stop
|
||||
are requested, they can be joined with a comma, for example
|
||||
.Fl W Ns Cm error , Ns Cm stop .
|
||||
.It Ar file
|
||||
Read input from zero or more files.
|
||||
If unspecified, reads from stdin.
|
||||
If multiple files are specified,
|
||||
.Nm
|
||||
will halt with the first failed parse.
|
||||
.El
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
reads
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
text from stdin, implying
|
||||
.Fl m Ns Cm andoc ,
|
||||
and produces
|
||||
.Fl T Ns Cm ascii
|
||||
output.
|
||||
.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.
|
||||
.Ss Output Formats
|
||||
The
|
||||
.Nm
|
||||
utility accepts the following
|
||||
.Fl T
|
||||
arguments, which correspond to output modes:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl T Ns Cm ascii
|
||||
Produce 7-bit ASCII output.
|
||||
This is the default.
|
||||
See
|
||||
.Sx ASCII Output .
|
||||
.It Fl T Ns Cm html
|
||||
Produce strict CSS1/HTML-4.01 output.
|
||||
See
|
||||
.Sx HTML Output .
|
||||
.It Fl T Ns Cm lint
|
||||
Parse only: produce no output.
|
||||
Implies
|
||||
.Fl W Ns Cm warning .
|
||||
.It Fl T Ns Cm pdf
|
||||
Produce PDF output.
|
||||
See
|
||||
.Sx PDF Output .
|
||||
.It Fl T Ns Cm ps
|
||||
Produce PostScript output.
|
||||
See
|
||||
.Sx PostScript Output .
|
||||
.It Fl T Ns Cm tree
|
||||
Produce an indented parse tree.
|
||||
.It Fl T Ns Cm xhtml
|
||||
Produce strict CSS1/XHTML-1.0 output.
|
||||
See
|
||||
.Sx XHTML Output .
|
||||
.El
|
||||
.Pp
|
||||
If multiple input files are specified, these will be processed by the
|
||||
corresponding filter in-order.
|
||||
.Ss ASCII Output
|
||||
Output produced by
|
||||
.Fl T Ns Cm ascii ,
|
||||
which is the default, is rendered in standard 7-bit ASCII documented in
|
||||
.Xr ascii 7 .
|
||||
.Pp
|
||||
Font styles are applied by using back-spaced encoding such that an
|
||||
underlined character
|
||||
.Sq c
|
||||
is rendered as
|
||||
.Sq _ Ns \e[bs] Ns c ,
|
||||
where
|
||||
.Sq \e[bs]
|
||||
is the back-space character number 8.
|
||||
Emboldened characters are rendered as
|
||||
.Sq c Ns \e[bs] Ns c .
|
||||
.Pp
|
||||
The special characters documented in
|
||||
.Xr mandoc_char 7
|
||||
are rendered best-effort in an ASCII equivalent.
|
||||
.Pp
|
||||
Output width is limited to 78 visible columns unless literal input lines
|
||||
exceed this limit.
|
||||
.Pp
|
||||
The following
|
||||
.Fl O
|
||||
arguments are accepted:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm width Ns = Ns Ar width
|
||||
The output width is set to
|
||||
.Ar width ,
|
||||
which will normalise to \(>=60.
|
||||
.El
|
||||
.Ss HTML Output
|
||||
Output produced by
|
||||
.Fl T Ns Cm html
|
||||
conforms to HTML-4.01 strict.
|
||||
.Pp
|
||||
The
|
||||
.Pa example.style.css
|
||||
file documents style-sheet classes available for customising output.
|
||||
If a style-sheet is not specified with
|
||||
.Fl O Ns Ar style ,
|
||||
.Fl T Ns Cm html
|
||||
defaults to simple output readable in any graphical or text-based web
|
||||
browser.
|
||||
.Pp
|
||||
Special characters are rendered in decimal-encoded UTF-8.
|
||||
.Pp
|
||||
The following
|
||||
.Fl O
|
||||
arguments are accepted:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm includes Ns = Ns Ar fmt
|
||||
The string
|
||||
.Ar fmt ,
|
||||
for example,
|
||||
.Ar ../src/%I.html ,
|
||||
is used as a template for linked header files (usually via the
|
||||
.Sq \&In
|
||||
macro).
|
||||
Instances of
|
||||
.Sq \&%I
|
||||
are replaced with the include filename.
|
||||
The default is not to present a
|
||||
hyperlink.
|
||||
.It Cm man Ns = Ns Ar fmt
|
||||
The string
|
||||
.Ar fmt ,
|
||||
for example,
|
||||
.Ar ../html%S/%N.%S.html ,
|
||||
is used as a template for linked manuals (usually via the
|
||||
.Sq \&Xr
|
||||
macro).
|
||||
Instances of
|
||||
.Sq \&%N
|
||||
and
|
||||
.Sq %S
|
||||
are replaced with the linked manual's name and section, respectively.
|
||||
If no section is included, section 1 is assumed.
|
||||
The default is not to
|
||||
present a hyperlink.
|
||||
.It Cm style Ns = Ns Ar style.css
|
||||
The file
|
||||
.Ar style.css
|
||||
is used for an external style-sheet.
|
||||
This must be a valid absolute or
|
||||
relative URI.
|
||||
.El
|
||||
.Ss PostScript Output
|
||||
PostScript
|
||||
.Qq Adobe-3.0
|
||||
Level-2 pages may be generated by
|
||||
.Fl T Ns Cm ps .
|
||||
Output pages default to letter sized and are rendered in the Times font
|
||||
family, 11-point.
|
||||
Margins are calculated as 1/9 the page length and width.
|
||||
Line-height is 1.4m.
|
||||
.Pp
|
||||
Special characters are rendered as in
|
||||
.Sx ASCII Output .
|
||||
.Pp
|
||||
The following
|
||||
.Fl O
|
||||
arguments are accepted:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm paper Ns = Ns Ar name
|
||||
The paper size
|
||||
.Ar name
|
||||
may be one of
|
||||
.Ar a3 ,
|
||||
.Ar a4 ,
|
||||
.Ar a5 ,
|
||||
.Ar legal ,
|
||||
or
|
||||
.Ar letter .
|
||||
You may also manually specify dimensions as
|
||||
.Ar NNxNN ,
|
||||
width by height in millimetres.
|
||||
If an unknown value is encountered,
|
||||
.Ar letter
|
||||
is used.
|
||||
.El
|
||||
.Ss PDF Output
|
||||
PDF-1.1 output may be generated by
|
||||
.Fl T Ns Cm pdf .
|
||||
See
|
||||
.Sx PostScript Output
|
||||
for
|
||||
.Fl O
|
||||
arguments and defaults.
|
||||
.Ss XHTML Output
|
||||
Output produced by
|
||||
.Fl T Ns Cm xhtml
|
||||
conforms to XHTML-1.0 strict.
|
||||
.Pp
|
||||
See
|
||||
.Sx HTML Output
|
||||
for details; beyond generating XHTML tags instead of HTML tags, these
|
||||
output modes are identical.
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm
|
||||
utility exits with one of the following values, controlled by the message
|
||||
.Ar level
|
||||
associated with the
|
||||
.Fl W
|
||||
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
|
||||
.Ar level .
|
||||
.It 2
|
||||
At least one warning occurred, but no error, and
|
||||
.Fl W Ns Cm warning
|
||||
was specified.
|
||||
.It 3
|
||||
At least one parsing error occurred, but no fatal error, and
|
||||
.Fl W Ns Cm error
|
||||
or
|
||||
.Fl W Ns Cm warning
|
||||
was specified.
|
||||
.It 4
|
||||
A fatal parsing error occurred.
|
||||
.It 5
|
||||
Invalid command line arguments were specified.
|
||||
No input files have been read.
|
||||
.It 6
|
||||
An operating system error occurred, for example memory exhaustion or an
|
||||
error accessing input files.
|
||||
Such errors cause
|
||||
.Nm
|
||||
to exit at once, possibly in the middle of parsing or formatting a file.
|
||||
.El
|
||||
.Pp
|
||||
Note that selecting
|
||||
.Fl T Ns Cm lint
|
||||
output mode implies
|
||||
.Fl W Ns Cm warning .
|
||||
.Sh EXAMPLES
|
||||
To page manuals to the terminal:
|
||||
.Pp
|
||||
.Dl $ mandoc \-Wall,stop mandoc.1 2\*(Gt&1 | less
|
||||
.Dl $ mandoc mandoc.1 mdoc.3 mdoc.7 | less
|
||||
.Pp
|
||||
To produce HTML manuals with
|
||||
.Ar style.css
|
||||
as the style-sheet:
|
||||
.Pp
|
||||
.Dl $ mandoc \-Thtml -Ostyle=style.css mdoc.7 \*(Gt mdoc.7.html
|
||||
.Pp
|
||||
To check over a large set of manuals:
|
||||
.Pp
|
||||
.Dl $ mandoc \-Tlint `find /usr/src -name \e*\e.[1-9]`
|
||||
.Pp
|
||||
To produce a series of PostScript manuals for A4 paper:
|
||||
.Pp
|
||||
.Dl $ mandoc \-Tps \-Opaper=a4 mdoc.7 man.7 \*(Gt manuals.ps
|
||||
.Sh DIAGNOSTICS
|
||||
Standard error messages reporting parsing errors are prefixed by
|
||||
.Pp
|
||||
.Sm off
|
||||
.D1 Ar file : line : column : \ level :
|
||||
.Sm on
|
||||
.Pp
|
||||
where the fields have the following meanings:
|
||||
.Bl -tag -width "column"
|
||||
.It Ar file
|
||||
The name of the input file causing the message.
|
||||
.It Ar line
|
||||
The line number in that input file.
|
||||
Line numbering starts at 1.
|
||||
.It Ar column
|
||||
The column number in that input file.
|
||||
Column numbering starts at 1.
|
||||
If the issue is caused by a word, the column number usually
|
||||
points to the first character of the word.
|
||||
.It Ar level
|
||||
The message level, printed in capital letters.
|
||||
.El
|
||||
.Pp
|
||||
Message levels have the following meanings:
|
||||
.Bl -tag -width "warning"
|
||||
.It Cm fatal
|
||||
The parser is unable to parse a given input file at all.
|
||||
No formatted output is produced from that input file.
|
||||
.It Cm error
|
||||
An input file contains syntax that cannot be safely interpreted,
|
||||
either because it is invalid or because
|
||||
.Nm
|
||||
does not implement it yet.
|
||||
By discarding part of the input or inserting missing tokens,
|
||||
the parser is able to continue, and the error does not prevent
|
||||
generation of formatted output, but typically, preparing that
|
||||
output involves information loss, broken document structure
|
||||
or unintended formatting.
|
||||
.It Cm warning
|
||||
An input file uses obsolete, discouraged or non-portable syntax.
|
||||
All the same, the meaning of the input is unambiguous and a correct
|
||||
rendering can be produced.
|
||||
Documents causing warnings may render poorly when using other
|
||||
formatting tools instead of
|
||||
.Nm .
|
||||
.El
|
||||
.Pp
|
||||
Messages of the
|
||||
.Cm warning
|
||||
and
|
||||
.Cm error
|
||||
levels are hidden unless their level, or a lower level, is requested using a
|
||||
.Fl W
|
||||
option or
|
||||
.Fl T Ns Cm lint
|
||||
output mode.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility may also print messages related to invalid command line arguments
|
||||
or operating system errors, for example when memory is exhausted or
|
||||
input files cannot be read.
|
||||
Such messages do not carry the prefix described above.
|
||||
.Sh COMPATIBILITY
|
||||
This section summarises
|
||||
.Nm
|
||||
compatibility with GNU troff.
|
||||
Each input and output format is separately noted.
|
||||
.Ss ASCII Compatibility
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
The
|
||||
.Sq \&Bd \-literal
|
||||
and
|
||||
.Sq \&Bd \-unfilled
|
||||
macros of
|
||||
.Xr mdoc 7
|
||||
in
|
||||
.Fl T Ns Cm ascii
|
||||
are synonyms, as are \-filled and \-ragged.
|
||||
.It
|
||||
In GNU troff, the
|
||||
.Sq \&Pa
|
||||
.Xr mdoc 7
|
||||
macro does not underline when scoped under an
|
||||
.Sq \&It
|
||||
in the FILES section.
|
||||
This behaves correctly in
|
||||
.Nm .
|
||||
.It
|
||||
A list or display following the
|
||||
.Sq \&Ss
|
||||
.Xr mdoc 7
|
||||
macro in
|
||||
.Fl T Ns Cm ascii
|
||||
does not assert a prior vertical break, just as it doesn't with
|
||||
.Sq \&Sh .
|
||||
.It
|
||||
The
|
||||
.Sq \&na
|
||||
.Xr man 7
|
||||
macro in
|
||||
.Fl T Ns Cm ascii
|
||||
has no effect.
|
||||
.It
|
||||
Words aren't hyphenated.
|
||||
.It
|
||||
Sentences are unilaterally monospaced.
|
||||
.El
|
||||
.Ss HTML/XHTML Compatibility
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
The
|
||||
.Sq \efP
|
||||
escape will revert the font to the previous
|
||||
.Sq \ef
|
||||
escape, not to the last rendered decoration, which is now dictated by
|
||||
CSS instead of hard-coded.
|
||||
It also will not span past the current scope,
|
||||
for the same reason.
|
||||
Note that in
|
||||
.Sx ASCII Output
|
||||
mode, this will work fine.
|
||||
.It
|
||||
The
|
||||
.Xr mdoc 7
|
||||
.Sq \&Bl \-hang
|
||||
and
|
||||
.Sq \&Bl \-tag
|
||||
list types render similarly (no break following overreached left-hand
|
||||
side) due to the expressive constraints of HTML.
|
||||
.It
|
||||
The
|
||||
.Xr man 7
|
||||
.Sq IP
|
||||
and
|
||||
.Sq TP
|
||||
lists render similarly.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr man 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr roff 7 ,
|
||||
.Xr tbl 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
In
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml ,
|
||||
the maximum size of an element attribute is determined by
|
||||
.Dv BUFSIZ ,
|
||||
which is usually 1024 bytes.
|
||||
Be aware of this when setting long link
|
||||
formats such as
|
||||
.Fl O Ns Cm style Ns = Ns Ar really/long/link .
|
||||
.Pp
|
||||
Nesting elements within next-line element scopes of
|
||||
.Fl m Ns Cm an ,
|
||||
such as
|
||||
.Sq br
|
||||
within an empty
|
||||
.Sq B ,
|
||||
will confuse
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml
|
||||
and cause them to forget the formatting of the prior next-line scope.
|
||||
.Pp
|
||||
The
|
||||
.Sq \(aq
|
||||
control character is an alias for the standard macro control character
|
||||
and does not emit a line-break as stipulated in GNU troff.
|
||||
487
usr.bin/mdocml/dist/mandoc.c
vendored
487
usr.bin/mdocml/dist/mandoc.c
vendored
@@ -1,487 +0,0 @@
|
||||
/* $Vendor-Id: mandoc.c,v 1.36 2011/01/03 22:42:37 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011 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 AUTHORS DISCLAIM ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
static int a2time(time_t *, const char *, const char *);
|
||||
|
||||
|
||||
int
|
||||
mandoc_special(char *p)
|
||||
{
|
||||
int len, i;
|
||||
char term;
|
||||
char *sv;
|
||||
|
||||
len = 0;
|
||||
term = '\0';
|
||||
sv = p;
|
||||
|
||||
assert('\\' == *p);
|
||||
p++;
|
||||
|
||||
switch (*p++) {
|
||||
#if 0
|
||||
case ('Z'):
|
||||
/* FALLTHROUGH */
|
||||
case ('X'):
|
||||
/* FALLTHROUGH */
|
||||
case ('x'):
|
||||
/* FALLTHROUGH */
|
||||
case ('S'):
|
||||
/* FALLTHROUGH */
|
||||
case ('R'):
|
||||
/* FALLTHROUGH */
|
||||
case ('N'):
|
||||
/* FALLTHROUGH */
|
||||
case ('l'):
|
||||
/* FALLTHROUGH */
|
||||
case ('L'):
|
||||
/* FALLTHROUGH */
|
||||
case ('H'):
|
||||
/* FALLTHROUGH */
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('D'):
|
||||
/* FALLTHROUGH */
|
||||
case ('C'):
|
||||
/* FALLTHROUGH */
|
||||
case ('b'):
|
||||
/* FALLTHROUGH */
|
||||
case ('B'):
|
||||
/* FALLTHROUGH */
|
||||
case ('a'):
|
||||
/* FALLTHROUGH */
|
||||
case ('A'):
|
||||
if (*p++ != '\'')
|
||||
return(0);
|
||||
term = '\'';
|
||||
break;
|
||||
#endif
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('v'):
|
||||
/* FALLTHROUGH */
|
||||
case ('s'):
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
|
||||
i = 0;
|
||||
if ('+' == *p || '-' == *p) {
|
||||
p++;
|
||||
i = 1;
|
||||
}
|
||||
|
||||
switch (*p++) {
|
||||
case ('('):
|
||||
len = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
case ('\''):
|
||||
term = '\'';
|
||||
break;
|
||||
case ('0'):
|
||||
i = 1;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
len = 1;
|
||||
p--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
if ('+' == *p || '-' == *p) {
|
||||
if (i)
|
||||
return(0);
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Handle embedded numerical subexp or escape. */
|
||||
|
||||
if ('(' == *p) {
|
||||
while (*p && ')' != *p)
|
||||
if ('\\' == *p++) {
|
||||
i = mandoc_special(--p);
|
||||
if (0 == i)
|
||||
return(0);
|
||||
p += i;
|
||||
}
|
||||
|
||||
if (')' == *p++)
|
||||
break;
|
||||
|
||||
return(0);
|
||||
} else if ('\\' == *p) {
|
||||
if (0 == (i = mandoc_special(p)))
|
||||
return(0);
|
||||
p += i;
|
||||
}
|
||||
|
||||
break;
|
||||
#if 0
|
||||
case ('Y'):
|
||||
/* FALLTHROUGH */
|
||||
case ('V'):
|
||||
/* FALLTHROUGH */
|
||||
case ('$'):
|
||||
/* FALLTHROUGH */
|
||||
case ('n'):
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case ('k'):
|
||||
/* FALLTHROUGH */
|
||||
case ('M'):
|
||||
/* FALLTHROUGH */
|
||||
case ('m'):
|
||||
/* FALLTHROUGH */
|
||||
case ('f'):
|
||||
/* FALLTHROUGH */
|
||||
case ('F'):
|
||||
/* FALLTHROUGH */
|
||||
case ('*'):
|
||||
switch (*p++) {
|
||||
case ('('):
|
||||
len = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
default:
|
||||
len = 1;
|
||||
p--;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ('('):
|
||||
len = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
case ('z'):
|
||||
len = 1;
|
||||
if ('\\' == *p) {
|
||||
if (0 == (i = mandoc_special(p)))
|
||||
return(0);
|
||||
p += i;
|
||||
return(*p ? (int)(p - sv) : 0);
|
||||
}
|
||||
break;
|
||||
case ('o'):
|
||||
/* FALLTHROUGH */
|
||||
case ('w'):
|
||||
if ('\'' == *p++) {
|
||||
term = '\'';
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
len = 1;
|
||||
p--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (term) {
|
||||
for ( ; *p && term != *p; p++)
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
return(*p ? (int)(p - sv) : 0);
|
||||
}
|
||||
|
||||
for (i = 0; *p && i < len; i++, p++)
|
||||
if (ASCII_HYPH == *p)
|
||||
*p = '-';
|
||||
return(i == len ? (int)(p - sv) : 0);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
mandoc_calloc(size_t num, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = calloc(num, size);
|
||||
if (NULL == ptr) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
mandoc_malloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = malloc(size);
|
||||
if (NULL == ptr) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
mandoc_realloc(void *ptr, size_t size)
|
||||
{
|
||||
|
||||
ptr = realloc(ptr, size);
|
||||
if (NULL == ptr) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
mandoc_strdup(const char *ptr)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = strdup(ptr);
|
||||
if (NULL == p) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a quoted or unquoted roff-style request or macro argument.
|
||||
* Return a pointer to the parsed argument, which is either the original
|
||||
* pointer or advanced by one byte in case the argument is quoted.
|
||||
* Null-terminate the argument in place.
|
||||
* Collapse pairs of quotes inside quoted arguments.
|
||||
* Advance the argument pointer to the next argument,
|
||||
* or to the null byte terminating the argument line.
|
||||
*/
|
||||
char *
|
||||
mandoc_getarg(char **cpp, mandocmsg msg, void *data, int ln, int *pos)
|
||||
{
|
||||
char *start, *cp;
|
||||
int quoted, pairs, white;
|
||||
|
||||
/* Quoting can only start with a new word. */
|
||||
start = *cpp;
|
||||
if ('"' == *start) {
|
||||
quoted = 1;
|
||||
start++;
|
||||
} else
|
||||
quoted = 0;
|
||||
|
||||
pairs = 0;
|
||||
white = 0;
|
||||
for (cp = start; '\0' != *cp; cp++) {
|
||||
/* Move left after quoted quotes and escaped backslashes. */
|
||||
if (pairs)
|
||||
cp[-pairs] = cp[0];
|
||||
if ('\\' == cp[0]) {
|
||||
if ('\\' == cp[1]) {
|
||||
/* Poor man's copy mode. */
|
||||
pairs++;
|
||||
cp++;
|
||||
} else if (0 == quoted && ' ' == cp[1])
|
||||
/* Skip escaped blanks. */
|
||||
cp++;
|
||||
} else if (0 == quoted) {
|
||||
if (' ' == cp[0]) {
|
||||
/* Unescaped blanks end unquoted args. */
|
||||
white = 1;
|
||||
break;
|
||||
}
|
||||
} else if ('"' == cp[0]) {
|
||||
if ('"' == cp[1]) {
|
||||
/* Quoted quotes collapse. */
|
||||
pairs++;
|
||||
cp++;
|
||||
} else {
|
||||
/* Unquoted quotes end quoted args. */
|
||||
quoted = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Quoted argument without a closing quote. */
|
||||
if (1 == quoted && msg)
|
||||
(*msg)(MANDOCERR_BADQUOTE, data, ln, *pos, NULL);
|
||||
|
||||
/* Null-terminate this argument and move to the next one. */
|
||||
if (pairs)
|
||||
cp[-pairs] = '\0';
|
||||
if ('\0' != *cp) {
|
||||
*cp++ = '\0';
|
||||
while (' ' == *cp)
|
||||
cp++;
|
||||
}
|
||||
*pos += (cp - start) + (quoted ? 1 : 0);
|
||||
*cpp = cp;
|
||||
|
||||
if ('\0' == *cp && msg && (white || ' ' == cp[-1]))
|
||||
(*msg)(MANDOCERR_EOLNSPACE, data, ln, *pos, NULL);
|
||||
|
||||
return(start);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
a2time(time_t *t, const char *fmt, const char *p)
|
||||
{
|
||||
struct tm tm;
|
||||
char *pp;
|
||||
|
||||
memset(&tm, 0, sizeof(struct tm));
|
||||
|
||||
pp = strptime(p, fmt, &tm);
|
||||
if (NULL != pp && '\0' == *pp) {
|
||||
*t = mktime(&tm);
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert from a manual date string (see mdoc(7) and man(7)) into a
|
||||
* date according to the stipulated date type.
|
||||
*/
|
||||
time_t
|
||||
mandoc_a2time(int flags, const char *p)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
if (MTIME_MDOCDATE & flags) {
|
||||
if (0 == strcmp(p, "$" "Mdocdate$"))
|
||||
return(time(NULL));
|
||||
if (a2time(&t, "$" "Mdocdate: %b %d %Y $", p))
|
||||
return(t);
|
||||
}
|
||||
|
||||
if (MTIME_CANONICAL & flags || MTIME_REDUCED & flags)
|
||||
if (a2time(&t, "%b %d, %Y", p))
|
||||
return(t);
|
||||
|
||||
if (MTIME_ISO_8601 & flags)
|
||||
if (a2time(&t, "%Y-%m-%d", p))
|
||||
return(t);
|
||||
|
||||
if (MTIME_REDUCED & flags) {
|
||||
if (a2time(&t, "%d, %Y", p))
|
||||
return(t);
|
||||
if (a2time(&t, "%Y", p))
|
||||
return(t);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mandoc_eos(const char *p, size_t sz, int enclosed)
|
||||
{
|
||||
const char *q;
|
||||
int found;
|
||||
|
||||
if (0 == sz)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* End-of-sentence recognition must include situations where
|
||||
* some symbols, such as `)', allow prior EOS punctuation to
|
||||
* propogate outward.
|
||||
*/
|
||||
|
||||
found = 0;
|
||||
for (q = p + (int)sz - 1; q >= p; q--) {
|
||||
switch (*q) {
|
||||
case ('\"'):
|
||||
/* FALLTHROUGH */
|
||||
case ('\''):
|
||||
/* FALLTHROUGH */
|
||||
case (']'):
|
||||
/* FALLTHROUGH */
|
||||
case (')'):
|
||||
if (0 == found)
|
||||
enclosed = 1;
|
||||
break;
|
||||
case ('.'):
|
||||
/* FALLTHROUGH */
|
||||
case ('!'):
|
||||
/* FALLTHROUGH */
|
||||
case ('?'):
|
||||
found = 1;
|
||||
break;
|
||||
default:
|
||||
return(found && (!enclosed || isalnum((unsigned char)*q)));
|
||||
}
|
||||
}
|
||||
|
||||
return(found && !enclosed);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mandoc_hyph(const char *start, const char *c)
|
||||
{
|
||||
|
||||
/*
|
||||
* Choose whether to break at a hyphenated character. We only
|
||||
* do this if it's free-standing within a word.
|
||||
*/
|
||||
|
||||
/* Skip first/last character of buffer. */
|
||||
if (c == start || '\0' == *(c + 1))
|
||||
return(0);
|
||||
/* Skip first/last character of word. */
|
||||
if ('\t' == *(c + 1) || '\t' == *(c - 1))
|
||||
return(0);
|
||||
if (' ' == *(c + 1) || ' ' == *(c - 1))
|
||||
return(0);
|
||||
/* Skip double invocations. */
|
||||
if ('-' == *(c + 1) || '-' == *(c - 1))
|
||||
return(0);
|
||||
/* Skip escapes. */
|
||||
if ('\\' == *(c - 1))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
315
usr.bin/mdocml/dist/mandoc.h
vendored
315
usr.bin/mdocml/dist/mandoc.h
vendored
@@ -1,315 +0,0 @@
|
||||
/* $Vendor-Id: mandoc.h,v 1.49 2011/01/06 13:45:47 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef MANDOC_H
|
||||
#define MANDOC_H
|
||||
|
||||
#define ASCII_NBRSP 31 /* non-breaking space */
|
||||
#define ASCII_HYPH 30 /* breakable hyphen */
|
||||
|
||||
/*
|
||||
* Status level. This refers to both internal status (i.e., whilst
|
||||
* running, when warnings/errors are reported) and an indicator of a
|
||||
* threshold of when to halt (when said internal state exceeds the
|
||||
* threshold).
|
||||
*/
|
||||
enum mandoclevel {
|
||||
MANDOCLEVEL_OK = 0,
|
||||
MANDOCLEVEL_RESERVED,
|
||||
MANDOCLEVEL_WARNING, /* warnings: syntax, whitespace, etc. */
|
||||
MANDOCLEVEL_ERROR, /* input has been thrown away */
|
||||
MANDOCLEVEL_FATAL, /* input is borked */
|
||||
MANDOCLEVEL_BADARG, /* bad argument in invocation */
|
||||
MANDOCLEVEL_SYSERR, /* system error */
|
||||
MANDOCLEVEL_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* All possible things that can go wrong within a parse, be it libroff,
|
||||
* libmdoc, or libman.
|
||||
*/
|
||||
enum mandocerr {
|
||||
MANDOCERR_OK,
|
||||
|
||||
MANDOCERR_WARNING, /* ===== start of warnings ===== */
|
||||
|
||||
/* related to the prologue */
|
||||
MANDOCERR_NOTITLE, /* no title in document */
|
||||
MANDOCERR_UPPERCASE, /* document title should be all caps */
|
||||
MANDOCERR_BADMSEC, /* unknown manual section */
|
||||
MANDOCERR_BADDATE, /* cannot parse date argument */
|
||||
MANDOCERR_PROLOGOOO, /* prologue macros out of order */
|
||||
MANDOCERR_PROLOGREP, /* duplicate prologue macro */
|
||||
MANDOCERR_BADPROLOG, /* macro not allowed in prologue */
|
||||
MANDOCERR_BADBODY, /* macro not allowed in body */
|
||||
|
||||
/* related to document structure */
|
||||
MANDOCERR_SO, /* .so is fragile, better use ln(1) */
|
||||
MANDOCERR_NAMESECFIRST, /* NAME section must come first */
|
||||
MANDOCERR_BADNAMESEC, /* bad NAME section contents */
|
||||
MANDOCERR_NONAME, /* manual name not yet set */
|
||||
MANDOCERR_SECOOO, /* sections out of conventional order */
|
||||
MANDOCERR_SECREP, /* duplicate section name */
|
||||
MANDOCERR_SECMSEC, /* section not in conventional manual section */
|
||||
|
||||
/* related to macros and nesting */
|
||||
MANDOCERR_MACROOBS, /* skipping obsolete macro */
|
||||
MANDOCERR_IGNPAR, /* skipping paragraph macro */
|
||||
MANDOCERR_SCOPENEST, /* blocks badly nested */
|
||||
MANDOCERR_CHILD, /* child violates parent syntax */
|
||||
MANDOCERR_NESTEDDISP, /* nested displays are not portable */
|
||||
MANDOCERR_SCOPEREP, /* already in literal mode */
|
||||
|
||||
/* related to missing macro arguments */
|
||||
MANDOCERR_MACROEMPTY, /* skipping empty macro */
|
||||
MANDOCERR_ARGCWARN, /* argument count wrong */
|
||||
MANDOCERR_DISPTYPE, /* missing display type */
|
||||
MANDOCERR_LISTFIRST, /* list type must come first */
|
||||
MANDOCERR_NOWIDTHARG, /* tag lists require a width argument */
|
||||
MANDOCERR_FONTTYPE, /* missing font type */
|
||||
|
||||
/* related to bad macro arguments */
|
||||
MANDOCERR_IGNARGV, /* skipping argument */
|
||||
MANDOCERR_ARGVREP, /* duplicate argument */
|
||||
MANDOCERR_DISPREP, /* duplicate display type */
|
||||
MANDOCERR_LISTREP, /* duplicate list type */
|
||||
MANDOCERR_BADATT, /* unknown AT&T UNIX version */
|
||||
MANDOCERR_BADBOOL, /* bad Boolean value */
|
||||
MANDOCERR_BADFONT, /* unknown font */
|
||||
MANDOCERR_BADSTANDARD, /* unknown standard specifier */
|
||||
MANDOCERR_BADWIDTH, /* bad width argument */
|
||||
|
||||
/* related to plain text */
|
||||
MANDOCERR_NOBLANKLN, /* blank line in non-literal context */
|
||||
MANDOCERR_BADTAB, /* tab in non-literal context */
|
||||
MANDOCERR_EOLNSPACE, /* end of line whitespace */
|
||||
MANDOCERR_BADCOMMENT, /* bad comment style */
|
||||
MANDOCERR_BADESCAPE, /* unknown escape sequence */
|
||||
MANDOCERR_BADQUOTE, /* unterminated quoted string */
|
||||
|
||||
/* related to tables */
|
||||
MANDOCERR_TBLEXTRADAT, /* extra data cells */
|
||||
|
||||
MANDOCERR_ERROR, /* ===== start of errors ===== */
|
||||
|
||||
/* related to tables */
|
||||
MANDOCERR_TBL, /* bad table syntax */
|
||||
MANDOCERR_TBLOPT, /* bad table option */
|
||||
MANDOCERR_TBLLAYOUT, /* bad table layout */
|
||||
MANDOCERR_TBLNOLAYOUT, /* no table layout cells specified */
|
||||
MANDOCERR_TBLNODATA, /* no table data cells specified */
|
||||
MANDOCERR_TBLIGNDATA, /* ignore data in cell */
|
||||
MANDOCERR_TBLBLOCK, /* data block still open */
|
||||
|
||||
MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */
|
||||
MANDOCERR_BADCHAR, /* skipping bad character */
|
||||
MANDOCERR_NOTEXT, /* skipping text before the first section header */
|
||||
MANDOCERR_MACRO, /* skipping unknown macro */
|
||||
MANDOCERR_REQUEST, /* NOT IMPLEMENTED: skipping request */
|
||||
MANDOCERR_LINESCOPE, /* line scope broken */
|
||||
MANDOCERR_ARGCOUNT, /* argument count wrong */
|
||||
MANDOCERR_NOSCOPE, /* skipping end of block that is not open */
|
||||
MANDOCERR_SCOPEBROKEN, /* missing end of block */
|
||||
MANDOCERR_SCOPEEXIT, /* scope open on exit */
|
||||
MANDOCERR_UNAME, /* uname(3) system call failed */
|
||||
/* FIXME: merge following with MANDOCERR_ARGCOUNT */
|
||||
MANDOCERR_NOARGS, /* macro requires line argument(s) */
|
||||
MANDOCERR_NOBODY, /* macro requires body argument(s) */
|
||||
MANDOCERR_NOARGV, /* macro requires argument(s) */
|
||||
MANDOCERR_LISTTYPE, /* missing list type */
|
||||
MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
|
||||
MANDOCERR_BODYLOST, /* body argument(s) will be lost */
|
||||
|
||||
MANDOCERR_FATAL, /* ===== start of fatal errors ===== */
|
||||
|
||||
MANDOCERR_COLUMNS, /* column syntax is inconsistent */
|
||||
MANDOCERR_BADDISP, /* NOT IMPLEMENTED: .Bd -file */
|
||||
MANDOCERR_SYNTLINESCOPE, /* line scope broken, syntax violated */
|
||||
MANDOCERR_SYNTARGVCOUNT, /* argument count wrong, violates syntax */
|
||||
MANDOCERR_SYNTCHILD, /* child violates parent syntax */
|
||||
MANDOCERR_SYNTARGCOUNT, /* argument count wrong, violates syntax */
|
||||
MANDOCERR_SOPATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
|
||||
MANDOCERR_NODOCBODY, /* no document body */
|
||||
MANDOCERR_NODOCPROLOG, /* no document prologue */
|
||||
MANDOCERR_MEM, /* static buffer exhausted */
|
||||
MANDOCERR_MAX
|
||||
};
|
||||
|
||||
struct tbl {
|
||||
char tab; /* cell-separator */
|
||||
char decimal; /* decimal point */
|
||||
int linesize;
|
||||
int opts;
|
||||
#define TBL_OPT_CENTRE (1 << 0)
|
||||
#define TBL_OPT_EXPAND (1 << 1)
|
||||
#define TBL_OPT_BOX (1 << 2)
|
||||
#define TBL_OPT_DBOX (1 << 3)
|
||||
#define TBL_OPT_ALLBOX (1 << 4)
|
||||
#define TBL_OPT_NOKEEP (1 << 5)
|
||||
#define TBL_OPT_NOSPACE (1 << 6)
|
||||
int cols; /* number of columns */
|
||||
};
|
||||
|
||||
enum tbl_headt {
|
||||
TBL_HEAD_DATA, /* plug in data from tbl_dat */
|
||||
TBL_HEAD_VERT, /* vertical spacer */
|
||||
TBL_HEAD_DVERT /* double-vertical spacer */
|
||||
};
|
||||
|
||||
/*
|
||||
* The head of a table specifies all of its columns. When formatting a
|
||||
* tbl_span, iterate over these and plug in data from the tbl_span when
|
||||
* appropriate, using tbl_cell as a guide to placement.
|
||||
*/
|
||||
struct tbl_head {
|
||||
enum tbl_headt pos;
|
||||
int ident; /* 0 <= unique id < cols */
|
||||
struct tbl_head *next;
|
||||
struct tbl_head *prev;
|
||||
};
|
||||
|
||||
enum tbl_cellt {
|
||||
TBL_CELL_CENTRE, /* c, C */
|
||||
TBL_CELL_RIGHT, /* r, R */
|
||||
TBL_CELL_LEFT, /* l, L */
|
||||
TBL_CELL_NUMBER, /* n, N */
|
||||
TBL_CELL_SPAN, /* s, S */
|
||||
TBL_CELL_LONG, /* a, A */
|
||||
TBL_CELL_DOWN, /* ^ */
|
||||
TBL_CELL_HORIZ, /* _, - */
|
||||
TBL_CELL_DHORIZ, /* = */
|
||||
TBL_CELL_VERT, /* | */
|
||||
TBL_CELL_DVERT, /* || */
|
||||
TBL_CELL_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* A cell in a layout row.
|
||||
*/
|
||||
struct tbl_cell {
|
||||
struct tbl_cell *next;
|
||||
enum tbl_cellt pos;
|
||||
int spacing;
|
||||
int flags;
|
||||
#define TBL_CELL_TALIGN (1 << 0) /* t, T */
|
||||
#define TBL_CELL_BALIGN (1 << 1) /* d, D */
|
||||
#define TBL_CELL_BOLD (1 << 2) /* fB, B, b */
|
||||
#define TBL_CELL_ITALIC (1 << 3) /* fI, I, i */
|
||||
#define TBL_CELL_EQUAL (1 << 4) /* e, E */
|
||||
#define TBL_CELL_UP (1 << 5) /* u, U */
|
||||
#define TBL_CELL_WIGN (1 << 6) /* z, Z */
|
||||
struct tbl_head *head;
|
||||
};
|
||||
|
||||
/*
|
||||
* A layout row.
|
||||
*/
|
||||
struct tbl_row {
|
||||
struct tbl_row *next;
|
||||
struct tbl_cell *first;
|
||||
struct tbl_cell *last;
|
||||
};
|
||||
|
||||
enum tbl_datt {
|
||||
TBL_DATA_NONE,
|
||||
TBL_DATA_DATA,
|
||||
TBL_DATA_HORIZ,
|
||||
TBL_DATA_DHORIZ,
|
||||
TBL_DATA_NHORIZ,
|
||||
TBL_DATA_NDHORIZ
|
||||
};
|
||||
|
||||
/*
|
||||
* A cell within a row of data. The "string" field contains the actual
|
||||
* string value that's in the cell. The rest is layout.
|
||||
*/
|
||||
struct tbl_dat {
|
||||
struct tbl_cell *layout; /* layout cell: CAN BE NULL */
|
||||
struct tbl_dat *next;
|
||||
char *string;
|
||||
enum tbl_datt pos;
|
||||
};
|
||||
|
||||
enum tbl_spant {
|
||||
TBL_SPAN_DATA, /* span consists of data */
|
||||
TBL_SPAN_HORIZ, /* span is horizontal line */
|
||||
TBL_SPAN_DHORIZ /* span is double horizontal line */
|
||||
};
|
||||
|
||||
/*
|
||||
* A row of data in a table.
|
||||
*/
|
||||
struct tbl_span {
|
||||
struct tbl *tbl;
|
||||
struct tbl_head *head;
|
||||
struct tbl_row *layout; /* layout row: CAN BE NULL */
|
||||
struct tbl_dat *first;
|
||||
struct tbl_dat *last;
|
||||
int flags;
|
||||
#define TBL_SPAN_FIRST (1 << 0)
|
||||
#define TBL_SPAN_LAST (1 << 1)
|
||||
enum tbl_spant pos;
|
||||
struct tbl_span *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* Available registers (set in libroff, accessed elsewhere).
|
||||
*/
|
||||
enum regs {
|
||||
REG_nS = 0,
|
||||
REG__MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* A register (struct reg) can consist of many types: this consists of
|
||||
* normalised types from the original string form.
|
||||
*/
|
||||
union regval {
|
||||
unsigned u; /* unsigned integer */
|
||||
};
|
||||
|
||||
/*
|
||||
* A single register entity. If "set" is zero, the value of the
|
||||
* register should be the default one, which is per-register. It's
|
||||
* assumed that callers know which type in "v" corresponds to which
|
||||
* register value.
|
||||
*/
|
||||
struct reg {
|
||||
int set; /* whether set or not */
|
||||
union regval v; /* parsed data */
|
||||
};
|
||||
|
||||
/*
|
||||
* The primary interface to setting register values is in libroff,
|
||||
* although libmdoc and libman from time to time will manipulate
|
||||
* registers (such as `.Sh SYNOPSIS' enabling REG_nS).
|
||||
*/
|
||||
struct regset {
|
||||
struct reg regs[REG__MAX];
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Callback function for warnings, errors, and fatal errors as they
|
||||
* occur in the compilers libroff, libmdoc, and libman.
|
||||
*/
|
||||
typedef int (*mandocmsg)(enum mandocerr, void *,
|
||||
int, int, const char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!MANDOC_H*/
|
||||
558
usr.bin/mdocml/dist/mandoc_char.7
vendored
558
usr.bin/mdocml/dist/mandoc_char.7
vendored
@@ -1,558 +0,0 @@
|
||||
.\" $Vendor-Id: mandoc_char.7,v 1.40 2010/10/29 00:05:53 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd October 29, 2010
|
||||
.Dt MANDOC_CHAR 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mandoc_char
|
||||
.Nd mandoc special characters
|
||||
.Sh DESCRIPTION
|
||||
This page documents the special characters and predefined strings accepted by
|
||||
.Xr mandoc 1
|
||||
to format
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
documents.
|
||||
.Pp
|
||||
Both
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
encode special characters with
|
||||
.Sq \eX
|
||||
.Pq for a one-character escape ,
|
||||
.Sq \e(XX
|
||||
.Pq two-character ,
|
||||
and
|
||||
.Sq \e[N]
|
||||
.Pq N-character .
|
||||
One may generalise
|
||||
.Sq \e(XX
|
||||
as
|
||||
.Sq \e[XX]
|
||||
and
|
||||
.Sq \eX
|
||||
as
|
||||
.Sq \e[X] .
|
||||
Predefined strings are functionally similar to special characters, using
|
||||
.Sq \e*X
|
||||
.Pq for a one-character escape ,
|
||||
.Sq \e*(XX
|
||||
.Pq two-character ,
|
||||
and
|
||||
.Sq \e*[N]
|
||||
.Pq N-character .
|
||||
One may generalise
|
||||
.Sq \e*(XX
|
||||
as
|
||||
.Sq \e*[XX]
|
||||
and
|
||||
.Sq \e*X
|
||||
as
|
||||
.Sq \e*[X] .
|
||||
.Pp
|
||||
Note that each output mode will have a different rendering of the
|
||||
characters.
|
||||
It's guaranteed that each input symbol will correspond to a
|
||||
(more or less) meaningful output rendering, regardless the mode.
|
||||
.Sh SPECIAL CHARACTERS
|
||||
These are the preferred input symbols for producing special characters.
|
||||
.Pp
|
||||
Spacing:
|
||||
.Bl -column -compact -offset indent "Input" "Description"
|
||||
.It Em Input Ta Em Description
|
||||
.It \e~ Ta non-breaking, non-collapsing space
|
||||
.It \e Ta breaking, non-collapsing n-width space
|
||||
.It \e^ Ta zero-width space
|
||||
.It \e% Ta zero-width space
|
||||
.It \e& Ta zero-width space
|
||||
.It \e| Ta zero-width space
|
||||
.It \e0 Ta breaking, non-collapsing digit-width space
|
||||
.It \ec Ta removes any trailing space (if applicable)
|
||||
.El
|
||||
.Pp
|
||||
Lines:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(ba Ta \(ba Ta bar
|
||||
.It \e(br Ta \(br Ta box rule
|
||||
.It \e(ul Ta \(ul Ta underscore
|
||||
.It \e(rl Ta \(rl Ta overline
|
||||
.It \e(bb Ta \(bb Ta broken bar
|
||||
.It \e(sl Ta \(sl Ta forward slash
|
||||
.It \e(rs Ta \(rs Ta backward slash
|
||||
.El
|
||||
.Pp
|
||||
Text markers:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(ci Ta \(ci Ta circle
|
||||
.It \e(bu Ta \(bu Ta bullet
|
||||
.It \e(dd Ta \(dd Ta double dagger
|
||||
.It \e(dg Ta \(dg Ta dagger
|
||||
.It \e(lz Ta \(lz Ta lozenge
|
||||
.It \e(sq Ta \(sq Ta white square
|
||||
.It \e(ps Ta \(ps Ta paragraph
|
||||
.It \e(sc Ta \(sc Ta section
|
||||
.It \e(lh Ta \(lh Ta left hand
|
||||
.It \e(rh Ta \(rh Ta right hand
|
||||
.It \e(at Ta \(at Ta at
|
||||
.It \e(sh Ta \(sh Ta hash (pound)
|
||||
.It \e(CR Ta \(CR Ta carriage return
|
||||
.It \e(OK Ta \(OK Ta check mark
|
||||
.El
|
||||
.Pp
|
||||
Legal symbols:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(co Ta \(co Ta copyright
|
||||
.It \e(rg Ta \(rg Ta registered
|
||||
.It \e(tm Ta \(tm Ta trademarked
|
||||
.El
|
||||
.Pp
|
||||
Punctuation:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(em Ta \(em Ta em-dash
|
||||
.It \e(en Ta \(en Ta en-dash
|
||||
.It \e(hy Ta \(hy Ta hyphen
|
||||
.It \ee Ta \e Ta back-slash
|
||||
.It \e. Ta \. Ta period
|
||||
.It \e(r! Ta \(r! Ta upside-down exclamation
|
||||
.It \e(r? Ta \(r? Ta upside-down question
|
||||
.El
|
||||
.Pp
|
||||
Quotes:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(Bq Ta \(Bq Ta right low double-quote
|
||||
.It \e(bq Ta \(bq Ta right low single-quote
|
||||
.It \e(lq Ta \(lq Ta left double-quote
|
||||
.It \e(rq Ta \(rq Ta right double-quote
|
||||
.It \e(oq Ta \(oq Ta left single-quote
|
||||
.It \e(cq Ta \(cq Ta right single-quote
|
||||
.It \e(aq Ta \(aq Ta apostrophe quote (text)
|
||||
.It \e(dq Ta \(dq Ta double quote (text)
|
||||
.It \e(Fo Ta \(Fo Ta left guillemet
|
||||
.It \e(Fc Ta \(Fc Ta right guillemet
|
||||
.It \e(fo Ta \(fo Ta left single guillemet
|
||||
.It \e(fc Ta \(fc Ta right single guillemet
|
||||
.El
|
||||
.Pp
|
||||
Brackets:
|
||||
.Bl -column -compact -offset indent "xxbracketrightbpx" Rendered Description
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(lB Ta \(lB Ta left bracket
|
||||
.It \e(rB Ta \(rB Ta right bracket
|
||||
.It \e(lC Ta \(lC Ta left brace
|
||||
.It \e(rC Ta \(rC Ta right brace
|
||||
.It \e(la Ta \(la Ta left angle
|
||||
.It \e(ra Ta \(ra Ta right angle
|
||||
.It \e(bv Ta \(bv Ta brace extension
|
||||
.It \e[braceex] Ta \[braceex] Ta brace extension
|
||||
.It \e[bracketlefttp] Ta \[bracketlefttp] Ta top-left hooked bracket
|
||||
.It \e[bracketleftbp] Ta \[bracketleftbp] Ta bottom-left hooked bracket
|
||||
.It \e[bracketleftex] Ta \[bracketleftex] Ta left hooked bracket extension
|
||||
.It \e[bracketrighttp] Ta \[bracketrighttp] Ta top-right hooked bracket
|
||||
.It \e[bracketrightbp] Ta \[bracketrightbp] Ta bottom-right hooked bracket
|
||||
.It \e[bracketrightex] Ta \[bracketrightex] Ta right hooked bracket extension
|
||||
.It \e(lt Ta \(lt Ta top-left hooked brace
|
||||
.It \e[bracelefttp] Ta \[bracelefttp] Ta top-left hooked brace
|
||||
.It \e(lk Ta \(lk Ta mid-left hooked brace
|
||||
.It \e[braceleftmid] Ta \[braceleftmid] Ta mid-left hooked brace
|
||||
.It \e(lb Ta \(lb Ta bottom-left hooked brace
|
||||
.It \e[braceleftbp] Ta \[braceleftbp] Ta bottom-left hooked brace
|
||||
.It \e[braceleftex] Ta \[braceleftex] Ta left hooked brace extension
|
||||
.It \e(rt Ta \(rt Ta top-left hooked brace
|
||||
.It \e[bracerighttp] Ta \[bracerighttp] Ta top-right hooked brace
|
||||
.It \e(rk Ta \(rk Ta mid-right hooked brace
|
||||
.It \e[bracerightmid] Ta \[bracerightmid] Ta mid-right hooked brace
|
||||
.It \e(rb Ta \(rb Ta bottom-right hooked brace
|
||||
.It \e[bracerightbp] Ta \[bracerightbp] Ta bottom-right hooked brace
|
||||
.It \e[bracerightex] Ta \[bracerightex] Ta right hooked brace extension
|
||||
.It \e[parenlefttp] Ta \[parenlefttp] Ta top-left hooked parenthesis
|
||||
.It \e[parenleftbp] Ta \[parenleftbp] Ta bottom-left hooked parenthesis
|
||||
.It \e[parenleftex] Ta \[parenleftex] Ta left hooked parenthesis extension
|
||||
.It \e[parenrighttp] Ta \[parenrighttp] Ta top-right hooked parenthesis
|
||||
.It \e[parenrightbp] Ta \[parenrightbp] Ta bottom-right hooked parenthesis
|
||||
.It \e[parenrightex] Ta \[parenrightex] Ta right hooked parenthesis extension
|
||||
.El
|
||||
.Pp
|
||||
Arrows:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(<- Ta \(<- Ta left arrow
|
||||
.It \e(-> Ta \(-> Ta right arrow
|
||||
.It \e(<> Ta \(<> Ta left-right arrow
|
||||
.It \e(da Ta \(da Ta down arrow
|
||||
.It \e(ua Ta \(ua Ta up arrow
|
||||
.It \e(va Ta \(va Ta up-down arrow
|
||||
.It \e(lA Ta \(lA Ta left double-arrow
|
||||
.It \e(rA Ta \(rA Ta right double-arrow
|
||||
.It \e(hA Ta \(hA Ta left-right double-arrow
|
||||
.It \e(uA Ta \(uA Ta up double-arrow
|
||||
.It \e(dA Ta \(dA Ta down double-arrow
|
||||
.It \e(vA Ta \(vA Ta up-down double-arrow
|
||||
.El
|
||||
.Pp
|
||||
Logical:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(AN Ta \(AN Ta logical and
|
||||
.It \e(OR Ta \(OR Ta logical or
|
||||
.It \e(no Ta \(no Ta logical not
|
||||
.It \e[tno] Ta \[tno] Ta logical not (text)
|
||||
.It \e(te Ta \(te Ta existential quantifier
|
||||
.It \e(fa Ta \(fa Ta universal quantifier
|
||||
.It \e(st Ta \(st Ta such that
|
||||
.It \e(tf Ta \(tf Ta therefore
|
||||
.It \e(3d Ta \(3d Ta therefore
|
||||
.It \e(or Ta \(or Ta bitwise or
|
||||
.El
|
||||
.Pp
|
||||
Mathematical:
|
||||
.Bl -column -compact -offset indent "xxcoproductxx" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(pl Ta \(pl Ta plus
|
||||
.It \e(mi Ta \(mi Ta minus
|
||||
.It \e- Ta \- Ta minus (text)
|
||||
.It \e(-+ Ta \(-+ Ta minus-plus
|
||||
.It \e(+- Ta \(+- Ta plus-minus
|
||||
.It \e[t+-] Ta \[t+-] Ta plus-minus (text)
|
||||
.It \e(pc Ta \(pc Ta centre-dot
|
||||
.It \e(mu Ta \(mu Ta multiply
|
||||
.It \e[tmu] Ta \[tmu] Ta multiply (text)
|
||||
.It \e(c* Ta \(c* Ta circle-multiply
|
||||
.It \e(c+ Ta \(c+ Ta circle-plus
|
||||
.It \e(di Ta \(di Ta divide
|
||||
.It \e[tdi] Ta \[tdi] Ta divide (text)
|
||||
.It \e(f/ Ta \(f/ Ta fraction
|
||||
.It \e(** Ta \(** Ta asterisk
|
||||
.It \e(<= Ta \(<= Ta less-than-equal
|
||||
.It \e(>= Ta \(>= Ta greater-than-equal
|
||||
.It \e(<< Ta \(<< Ta much less
|
||||
.It \e(>> Ta \(>> Ta much greater
|
||||
.It \e(eq Ta \(eq Ta equal
|
||||
.It \e(!= Ta \(!= Ta not equal
|
||||
.It \e(== Ta \(== Ta equivalent
|
||||
.It \e(ne Ta \(ne Ta not equivalent
|
||||
.It \e(=~ Ta \(=~ Ta congruent
|
||||
.It \e(-~ Ta \(-~ Ta asymptotically congruent
|
||||
.It \e(ap Ta \(ap Ta asymptotically similar
|
||||
.It \e(~~ Ta \(~~ Ta approximately similar
|
||||
.It \e(~= Ta \(~= Ta approximately equal
|
||||
.It \e(pt Ta \(pt Ta proportionate
|
||||
.It \e(es Ta \(es Ta empty set
|
||||
.It \e(mo Ta \(mo Ta element
|
||||
.It \e(nm Ta \(nm Ta not element
|
||||
.It \e(sb Ta \(sb Ta proper subset
|
||||
.It \e(nb Ta \(nb Ta not subset
|
||||
.It \e(sp Ta \(sp Ta proper superset
|
||||
.It \e(nc Ta \(nc Ta not superset
|
||||
.It \e(ib Ta \(ib Ta reflexive subset
|
||||
.It \e(ip Ta \(ip Ta reflexive superset
|
||||
.It \e(ca Ta \(ca Ta intersection
|
||||
.It \e(cu Ta \(cu Ta union
|
||||
.It \e(/_ Ta \(/_ Ta angle
|
||||
.It \e(pp Ta \(pp Ta perpendicular
|
||||
.It \e(is Ta \(is Ta integral
|
||||
.It \e[integral] Ta \[integral] Ta integral
|
||||
.It \e[sum] Ta \[sum] Ta summation
|
||||
.It \e[product] Ta \[product] Ta product
|
||||
.It \e[coproduct] Ta \[coproduct] Ta coproduct
|
||||
.It \e(gr Ta \(gr Ta gradient
|
||||
.It \e(sr Ta \(sr Ta square root
|
||||
.It \e[sqrt] Ta \[sqrt] Ta square root
|
||||
.It \e(lc Ta \(lc Ta left-ceiling
|
||||
.It \e(rc Ta \(rc Ta right-ceiling
|
||||
.It \e(lf Ta \(lf Ta left-floor
|
||||
.It \e(rf Ta \(rf Ta right-floor
|
||||
.It \e(if Ta \(if Ta infinity
|
||||
.It \e(Ah Ta \(Ah Ta aleph
|
||||
.It \e(Im Ta \(Im Ta imaginary
|
||||
.It \e(Re Ta \(Re Ta real
|
||||
.It \e(pd Ta \(pd Ta partial differential
|
||||
.It \e(-h Ta \(-h Ta Planck constant over 2\(*p
|
||||
.El
|
||||
.Pp
|
||||
Ligatures:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(ff Ta \(ff Ta ff ligature
|
||||
.It \e(fi Ta \(fi Ta fi ligature
|
||||
.It \e(fl Ta \(fl Ta fl ligature
|
||||
.It \e(Fi Ta \(Fi Ta ffi ligature
|
||||
.It \e(Fl Ta \(Fl Ta ffl ligature
|
||||
.It \e(AE Ta \(AE Ta AE
|
||||
.It \e(ae Ta \(ae Ta ae
|
||||
.It \e(OE Ta \(OE Ta OE
|
||||
.It \e(oe Ta \(oe Ta oe
|
||||
.It \e(ss Ta \(ss Ta German eszett
|
||||
.It \e(IJ Ta \(IJ Ta IJ ligature
|
||||
.It \e(ij Ta \(ij Ta ij ligature
|
||||
.El
|
||||
.Pp
|
||||
Accents:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(a" Ta \(a" Ta Hungarian umlaut
|
||||
.It \e(a- Ta \(a- Ta macron
|
||||
.It \e(a. Ta \(a. Ta dotted
|
||||
.It \e(a^ Ta \(a^ Ta circumflex
|
||||
.It \e(aa Ta \(aa Ta acute
|
||||
.It \e' Ta \' Ta acute
|
||||
.It \e(ga Ta \(ga Ta grave
|
||||
.It \e` Ta \` Ta grave
|
||||
.It \e(ab Ta \(ab Ta breve
|
||||
.It \e(ac Ta \(ac Ta cedilla
|
||||
.It \e(ad Ta \(ad Ta dieresis
|
||||
.It \e(ah Ta \(ah Ta caron
|
||||
.It \e(ao Ta \(ao Ta ring
|
||||
.It \e(a~ Ta \(a~ Ta tilde
|
||||
.It \e(ho Ta \(ho Ta ogonek
|
||||
.It \e(ha Ta \(ha Ta hat (text)
|
||||
.It \e(ti Ta \(ti Ta tilde (text)
|
||||
.El
|
||||
.Pp
|
||||
Accented letters:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e('A Ta \('A Ta acute A
|
||||
.It \e('E Ta \('E Ta acute E
|
||||
.It \e('I Ta \('I Ta acute I
|
||||
.It \e('O Ta \('O Ta acute O
|
||||
.It \e('U Ta \('U Ta acute U
|
||||
.It \e('a Ta \('a Ta acute a
|
||||
.It \e('e Ta \('e Ta acute e
|
||||
.It \e('i Ta \('i Ta acute i
|
||||
.It \e('o Ta \('o Ta acute o
|
||||
.It \e('u Ta \('u Ta acute u
|
||||
.It \e(`A Ta \(`A Ta grave A
|
||||
.It \e(`E Ta \(`E Ta grave E
|
||||
.It \e(`I Ta \(`I Ta grave I
|
||||
.It \e(`O Ta \(`O Ta grave O
|
||||
.It \e(`U Ta \(`U Ta grave U
|
||||
.It \e(`a Ta \(`a Ta grave a
|
||||
.It \e(`e Ta \(`e Ta grave e
|
||||
.It \e(`i Ta \(`i Ta grave i
|
||||
.It \e(`o Ta \(`i Ta grave o
|
||||
.It \e(`u Ta \(`u Ta grave u
|
||||
.It \e(~A Ta \(~A Ta tilde A
|
||||
.It \e(~N Ta \(~N Ta tilde N
|
||||
.It \e(~O Ta \(~O Ta tilde O
|
||||
.It \e(~a Ta \(~a Ta tilde a
|
||||
.It \e(~n Ta \(~n Ta tilde n
|
||||
.It \e(~o Ta \(~o Ta tilde o
|
||||
.It \e(:A Ta \(:A Ta dieresis A
|
||||
.It \e(:E Ta \(:E Ta dieresis E
|
||||
.It \e(:I Ta \(:I Ta dieresis I
|
||||
.It \e(:O Ta \(:O Ta dieresis O
|
||||
.It \e(:U Ta \(:U Ta dieresis U
|
||||
.It \e(:a Ta \(:a Ta dieresis a
|
||||
.It \e(:e Ta \(:e Ta dieresis e
|
||||
.It \e(:i Ta \(:i Ta dieresis i
|
||||
.It \e(:o Ta \(:o Ta dieresis o
|
||||
.It \e(:u Ta \(:u Ta dieresis u
|
||||
.It \e(:y Ta \(:y Ta dieresis y
|
||||
.It \e(^A Ta \(^A Ta circumflex A
|
||||
.It \e(^E Ta \(^E Ta circumflex E
|
||||
.It \e(^I Ta \(^I Ta circumflex I
|
||||
.It \e(^O Ta \(^O Ta circumflex O
|
||||
.It \e(^U Ta \(^U Ta circumflex U
|
||||
.It \e(^a Ta \(^a Ta circumflex a
|
||||
.It \e(^e Ta \(^e Ta circumflex e
|
||||
.It \e(^i Ta \(^i Ta circumflex i
|
||||
.It \e(^o Ta \(^o Ta circumflex o
|
||||
.It \e(^u Ta \(^u Ta circumflex u
|
||||
.It \e(,C Ta \(,C Ta cedilla C
|
||||
.It \e(,c Ta \(,c Ta cedilla c
|
||||
.It \e(/L Ta \(/L Ta stroke L
|
||||
.It \e(/l Ta \(/l Ta stroke l
|
||||
.It \e(/O Ta \(/O Ta stroke O
|
||||
.It \e(/o Ta \(/o Ta stroke o
|
||||
.It \e(oA Ta \(oA Ta ring A
|
||||
.It \e(oa Ta \(oa Ta ring a
|
||||
.El
|
||||
.Pp
|
||||
Special letters:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(-D Ta \(-D Ta Eth
|
||||
.It \e(Sd Ta \(Sd Ta eth
|
||||
.It \e(TP Ta \(TP Ta Thorn
|
||||
.It \e(Tp Ta \(Tp Ta thorn
|
||||
.It \e(.i Ta \(.i Ta dotless i
|
||||
.It \e(.j Ta \(.j Ta dotless j
|
||||
.El
|
||||
.Pp
|
||||
Currency:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(Do Ta \(Do Ta dollar
|
||||
.It \e(ct Ta \(ct Ta cent
|
||||
.It \e(Eu Ta \(Eu Ta Euro symbol
|
||||
.It \e(eu Ta \(eu Ta Euro symbol
|
||||
.It \e(Ye Ta \(Ye Ta yen
|
||||
.It \e(Po Ta \(Po Ta pound
|
||||
.It \e(Cs Ta \(Cs Ta Scandinavian
|
||||
.It \e(Fn Ta \(Fn Ta florin
|
||||
.El
|
||||
.Pp
|
||||
Units:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(de Ta \(de Ta degree
|
||||
.It \e(%0 Ta \(%0 Ta per-thousand
|
||||
.It \e(fm Ta \(fm Ta minute
|
||||
.It \e(sd Ta \(sd Ta second
|
||||
.It \e(mc Ta \(mc Ta micro
|
||||
.El
|
||||
.Pp
|
||||
Greek letters:
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e(*A Ta \(*A Ta Alpha
|
||||
.It \e(*B Ta \(*B Ta Beta
|
||||
.It \e(*G Ta \(*G Ta Gamma
|
||||
.It \e(*D Ta \(*D Ta Delta
|
||||
.It \e(*E Ta \(*E Ta Epsilon
|
||||
.It \e(*Z Ta \(*Z Ta Zeta
|
||||
.It \e(*Y Ta \(*Y Ta Eta
|
||||
.It \e(*H Ta \(*H Ta Theta
|
||||
.It \e(*I Ta \(*I Ta Iota
|
||||
.It \e(*K Ta \(*K Ta Kappa
|
||||
.It \e(*L Ta \(*L Ta Lambda
|
||||
.It \e(*M Ta \(*M Ta Mu
|
||||
.It \e(*N Ta \(*N Ta Nu
|
||||
.It \e(*C Ta \(*C Ta Xi
|
||||
.It \e(*O Ta \(*O Ta Omicron
|
||||
.It \e(*P Ta \(*P Ta Pi
|
||||
.It \e(*R Ta \(*R Ta Rho
|
||||
.It \e(*S Ta \(*S Ta Sigma
|
||||
.It \e(*T Ta \(*T Ta Tau
|
||||
.It \e(*U Ta \(*U Ta Upsilon
|
||||
.It \e(*F Ta \(*F Ta Phi
|
||||
.It \e(*X Ta \(*X Ta Chi
|
||||
.It \e(*Q Ta \(*Q Ta Psi
|
||||
.It \e(*W Ta \(*W Ta Omega
|
||||
.It \e(*a Ta \(*a Ta alpha
|
||||
.It \e(*b Ta \(*b Ta beta
|
||||
.It \e(*g Ta \(*g Ta gamma
|
||||
.It \e(*d Ta \(*d Ta delta
|
||||
.It \e(*e Ta \(*e Ta epsilon
|
||||
.It \e(*z Ta \(*z Ta zeta
|
||||
.It \e(*y Ta \(*y Ta eta
|
||||
.It \e(*h Ta \(*h Ta theta
|
||||
.It \e(*i Ta \(*i Ta iota
|
||||
.It \e(*k Ta \(*k Ta kappa
|
||||
.It \e(*l Ta \(*l Ta lambda
|
||||
.It \e(*m Ta \(*m Ta mu
|
||||
.It \e(*n Ta \(*n Ta nu
|
||||
.It \e(*c Ta \(*c Ta xi
|
||||
.It \e(*o Ta \(*o Ta omicron
|
||||
.It \e(*p Ta \(*p Ta pi
|
||||
.It \e(*r Ta \(*r Ta rho
|
||||
.It \e(*s Ta \(*s Ta sigma
|
||||
.It \e(*t Ta \(*t Ta tau
|
||||
.It \e(*u Ta \(*u Ta upsilon
|
||||
.It \e(*f Ta \(*f Ta phi
|
||||
.It \e(*x Ta \(*x Ta chi
|
||||
.It \e(*q Ta \(*q Ta psi
|
||||
.It \e(*w Ta \(*w Ta omega
|
||||
.It \e(+h Ta \(+h Ta theta variant
|
||||
.It \e(+f Ta \(+f Ta phi variant
|
||||
.It \e(+p Ta \(+p Ta pi variant
|
||||
.It \e(+e Ta \(+e Ta epsilon variant
|
||||
.It \e(ts Ta \(ts Ta sigma terminal
|
||||
.El
|
||||
.Sh PREDEFINED STRINGS
|
||||
These are not recommended for use, as they differ across
|
||||
implementations:
|
||||
.Pp
|
||||
.Bl -column -compact -offset indent "Input" "Rendered" "Description"
|
||||
.It Em Input Ta Em Rendered Ta Em Description
|
||||
.It \e*(Ba Ta \*(Ba Ta vertical bar
|
||||
.It \e*(Ne Ta \*(Ne Ta not equal
|
||||
.It \e*(Ge Ta \*(Ge Ta greater-than-equal
|
||||
.It \e*(Le Ta \*(Le Ta less-than-equal
|
||||
.It \e*(Gt Ta \*(Gt Ta greater-than
|
||||
.It \e*(Lt Ta \*(Lt Ta less-than
|
||||
.It \e*(Pm Ta \*(Pm Ta plus-minus
|
||||
.It \e*(If Ta \*(If Ta infinity
|
||||
.It \e*(Pi Ta \*(Pi Ta pi
|
||||
.It \e*(Na Ta \*(Na Ta NaN
|
||||
.It \e*(Am Ta \*(Am Ta ampersand
|
||||
.It \e*R Ta \*R Ta restricted mark
|
||||
.It \e*(Tm Ta \*(Tm Ta trade mark
|
||||
.It \e*q Ta \*q Ta double-quote
|
||||
.It \e*(Rq Ta \*(Rq Ta right-double-quote
|
||||
.It \e*(Lq Ta \*(Lq Ta left-double-quote
|
||||
.It \e*(lp Ta \*(lp Ta right-parenthesis
|
||||
.It \e*(rp Ta \*(rp Ta left-parenthesis
|
||||
.It \e*(lq Ta \*(lq Ta left double-quote
|
||||
.It \e*(rq Ta \*(rq Ta right double-quote
|
||||
.It \e*(ua Ta \*(ua Ta up arrow
|
||||
.It \e*(va Ta \*(va Ta up-down arrow
|
||||
.It \e*(<= Ta \*(<= Ta less-than-equal
|
||||
.It \e*(>= Ta \*(>= Ta greater-than-equal
|
||||
.It \e*(aa Ta \*(aa Ta acute
|
||||
.It \e*(ga Ta \*(ga Ta grave
|
||||
.El
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility of
|
||||
.Nm
|
||||
with older or existing versions of groff.
|
||||
.Pp
|
||||
The following render differently in
|
||||
.Fl T Ns Ar ascii
|
||||
output mode:
|
||||
.Bd -ragged -offset indent
|
||||
\e(ss, \e(nm, \e(nb, \e(nc, \e(ib, \e(ip, \e(pp, \e[sum], \e[product],
|
||||
\e[coproduct], \e(gr, \e(-h, \e(a.
|
||||
.Ed
|
||||
.Pp
|
||||
The following render differently in
|
||||
.Fl T Ns Ar html
|
||||
output mode:
|
||||
.Bd -ragged -offset indent
|
||||
\e(~=, \e(nb, \e(nc
|
||||
.Ed
|
||||
.Pp
|
||||
Finally, the following have been omitted by being poorly documented or
|
||||
having no known representation:
|
||||
.Bd -ragged -offset indent
|
||||
\e[radicalex], \e[sqrtex], \e(ru
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
manual page was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.Sh CAVEATS
|
||||
The
|
||||
.Sq \e*(Ba
|
||||
escape mimics the behaviour of the
|
||||
.Sq \&|
|
||||
character in
|
||||
.Xr mdoc 7 ;
|
||||
thus, if you wish to render a vertical bar with no side effects, use
|
||||
the
|
||||
.Sq \e(ba
|
||||
escape.
|
||||
348
usr.bin/mdocml/dist/mdoc.3
vendored
348
usr.bin/mdocml/dist/mdoc.3
vendored
@@ -1,348 +0,0 @@
|
||||
.\" $Vendor-Id: mdoc.3,v 1.55 2011/01/07 15:07:21 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010 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.
|
||||
.\"
|
||||
.Dd January 7, 2011
|
||||
.Dt MDOC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mdoc ,
|
||||
.Nm mdoc_alloc ,
|
||||
.Nm mdoc_endparse ,
|
||||
.Nm mdoc_free ,
|
||||
.Nm mdoc_meta ,
|
||||
.Nm mdoc_node ,
|
||||
.Nm mdoc_parseln ,
|
||||
.Nm mdoc_reset
|
||||
.Nd mdoc macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In mandoc.h
|
||||
.In mdoc.h
|
||||
.Vt extern const char * const * mdoc_macronames;
|
||||
.Vt extern const char * const * mdoc_argnames;
|
||||
.Ft int
|
||||
.Fo mdoc_addspan
|
||||
.Fa "struct mdoc *mdoc"
|
||||
.Fa "const struct tbl_span *span"
|
||||
.Fc
|
||||
.Ft "struct mdoc *"
|
||||
.Fo mdoc_alloc
|
||||
.Fa "struct regset *regs"
|
||||
.Fa "void *data"
|
||||
.Fa "mandocmsg msgs"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn mdoc_endparse "struct mdoc *mdoc"
|
||||
.Ft void
|
||||
.Fn mdoc_free "struct mdoc *mdoc"
|
||||
.Ft "const struct mdoc_meta *"
|
||||
.Fn mdoc_meta "const struct mdoc *mdoc"
|
||||
.Ft "const struct mdoc_node *"
|
||||
.Fn mdoc_node "const struct mdoc *mdoc"
|
||||
.Ft int
|
||||
.Fo mdoc_parseln
|
||||
.Fa "struct mdoc *mdoc"
|
||||
.Fa "int line"
|
||||
.Fa "char *buf"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn mdoc_reset "struct mdoc *mdoc"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mdoc
|
||||
library parses lines of
|
||||
.Xr mdoc 7
|
||||
input
|
||||
into an abstract syntax tree (AST).
|
||||
.Pp
|
||||
In general, applications initiate a parsing sequence with
|
||||
.Fn mdoc_alloc ,
|
||||
parse each line in a document with
|
||||
.Fn mdoc_parseln ,
|
||||
close the parsing session with
|
||||
.Fn mdoc_endparse ,
|
||||
operate over the syntax tree returned by
|
||||
.Fn mdoc_node
|
||||
and
|
||||
.Fn mdoc_meta ,
|
||||
then free all allocated memory with
|
||||
.Fn mdoc_free .
|
||||
The
|
||||
.Fn mdoc_reset
|
||||
function may be used in order to reset the parser for another input
|
||||
sequence.
|
||||
.Ss Types
|
||||
.Bl -ohang
|
||||
.It Vt struct mdoc
|
||||
An opaque type.
|
||||
Its values are only used privately within the library.
|
||||
.It Vt struct mdoc_node
|
||||
A parsed node.
|
||||
See
|
||||
.Sx Abstract Syntax Tree
|
||||
for details.
|
||||
.El
|
||||
.Ss Functions
|
||||
If
|
||||
.Fn mdoc_addspan ,
|
||||
.Fn mdoc_parseln ,
|
||||
or
|
||||
.Fn mdoc_endparse
|
||||
return 0, calls to any function but
|
||||
.Fn mdoc_reset
|
||||
or
|
||||
.Fn mdoc_free
|
||||
will raise an assertion.
|
||||
.Bl -ohang
|
||||
.It Fn mdoc_addspan
|
||||
Add a table span to the parsing stream.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn mdoc_alloc
|
||||
Allocates a parsing structure.
|
||||
The
|
||||
.Fa data
|
||||
pointer is passed to
|
||||
.Fa msgs .
|
||||
Always returns a valid pointer.
|
||||
The pointer must be freed with
|
||||
.Fn mdoc_free .
|
||||
.It Fn mdoc_reset
|
||||
Reset the parser for another parse routine.
|
||||
After its use,
|
||||
.Fn mdoc_parseln
|
||||
behaves as if invoked for the first time.
|
||||
If it returns 0, memory could not be allocated.
|
||||
.It Fn mdoc_free
|
||||
Free all resources of a parser.
|
||||
The pointer is no longer valid after invocation.
|
||||
.It Fn mdoc_parseln
|
||||
Parse a nil-terminated line of input.
|
||||
This line should not contain the trailing newline.
|
||||
Returns 0 on failure, 1 on success.
|
||||
The input buffer
|
||||
.Fa buf
|
||||
is modified by this function.
|
||||
.It Fn mdoc_endparse
|
||||
Signals that the parse is complete.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn mdoc_node
|
||||
Returns the first node of the parse.
|
||||
.It Fn mdoc_meta
|
||||
Returns the document's parsed meta-data.
|
||||
.El
|
||||
.Ss Variables
|
||||
.Bl -ohang
|
||||
.It Va mdoc_macronames
|
||||
An array of string-ified token names.
|
||||
.It Va mdoc_argnames
|
||||
An array of string-ified token argument names.
|
||||
.El
|
||||
.Ss Abstract Syntax Tree
|
||||
The
|
||||
.Nm
|
||||
functions produce an abstract syntax tree (AST) describing input in a
|
||||
regular form.
|
||||
It may be reviewed at any time with
|
||||
.Fn mdoc_nodes ;
|
||||
however, if called before
|
||||
.Fn mdoc_endparse ,
|
||||
or after
|
||||
.Fn mdoc_endparse
|
||||
or
|
||||
.Fn mdoc_parseln
|
||||
fail, it may be incomplete.
|
||||
.Pp
|
||||
This AST is governed by the ontological
|
||||
rules dictated in
|
||||
.Xr mdoc 7
|
||||
and derives its terminology accordingly.
|
||||
.Qq In-line
|
||||
elements described in
|
||||
.Xr mdoc 7
|
||||
are described simply as
|
||||
.Qq elements .
|
||||
.Pp
|
||||
The AST is composed of
|
||||
.Vt struct mdoc_node
|
||||
nodes with block, head, body, element, root and text types as declared
|
||||
by the
|
||||
.Va type
|
||||
field.
|
||||
Each node also provides its parse point (the
|
||||
.Va line ,
|
||||
.Va sec ,
|
||||
and
|
||||
.Va pos
|
||||
fields), its position in the tree (the
|
||||
.Va parent ,
|
||||
.Va child ,
|
||||
.Va nchild ,
|
||||
.Va next
|
||||
and
|
||||
.Va prev
|
||||
fields) and some type-specific data, in particular, for nodes generated
|
||||
from macros, the generating macro in the
|
||||
.Va tok
|
||||
field.
|
||||
.Pp
|
||||
The tree itself is arranged according to the following normal form,
|
||||
where capitalised non-terminals represent nodes.
|
||||
.Pp
|
||||
.Bl -tag -width "ELEMENTXX" -compact
|
||||
.It ROOT
|
||||
\(<- mnode+
|
||||
.It mnode
|
||||
\(<- BLOCK | ELEMENT | TEXT
|
||||
.It BLOCK
|
||||
\(<- HEAD [TEXT] (BODY [TEXT])+ [TAIL [TEXT]]
|
||||
.It ELEMENT
|
||||
\(<- TEXT*
|
||||
.It HEAD
|
||||
\(<- mnode*
|
||||
.It BODY
|
||||
\(<- mnode* [ENDBODY mnode*]
|
||||
.It TAIL
|
||||
\(<- mnode*
|
||||
.It TEXT
|
||||
\(<- [[:printable:],0x1e]*
|
||||
.El
|
||||
.Pp
|
||||
Of note are the TEXT nodes following the HEAD, BODY and TAIL nodes of
|
||||
the BLOCK production: these refer to punctuation marks.
|
||||
Furthermore, although a TEXT node will generally have a non-zero-length
|
||||
string, in the specific case of
|
||||
.Sq \&.Bd \-literal ,
|
||||
an empty line will produce a zero-length string.
|
||||
Multiple body parts are only found in invocations of
|
||||
.Sq \&Bl \-column ,
|
||||
where a new body introduces a new phrase.
|
||||
.Ss Badly-nested Blocks
|
||||
The ENDBODY node is available to end the formatting associated
|
||||
with a given block before the physical end of that block.
|
||||
It has a non-null
|
||||
.Va end
|
||||
field, is of the BODY
|
||||
.Va type ,
|
||||
has the same
|
||||
.Va tok
|
||||
as the BLOCK it is ending, and has a
|
||||
.Va pending
|
||||
field pointing to that BLOCK's BODY node.
|
||||
It is an indirect child of that BODY node
|
||||
and has no children of its own.
|
||||
.Pp
|
||||
An ENDBODY node is generated when a block ends while one of its child
|
||||
blocks is still open, like in the following example:
|
||||
.Bd -literal -offset indent
|
||||
\&.Ao ao
|
||||
\&.Bo bo ac
|
||||
\&.Ac bc
|
||||
\&.Bc end
|
||||
.Ed
|
||||
.Pp
|
||||
This example results in the following block structure:
|
||||
.Bd -literal -offset indent
|
||||
BLOCK Ao
|
||||
HEAD Ao
|
||||
BODY Ao
|
||||
TEXT ao
|
||||
BLOCK Bo, pending -> Ao
|
||||
HEAD Bo
|
||||
BODY Bo
|
||||
TEXT bo
|
||||
TEXT ac
|
||||
ENDBODY Ao, pending -> Ao
|
||||
TEXT bc
|
||||
TEXT end
|
||||
.Ed
|
||||
.Pp
|
||||
Here, the formatting of the
|
||||
.Sq \&Ao
|
||||
block extends from TEXT ao to TEXT ac,
|
||||
while the formatting of the
|
||||
.Sq \&Bo
|
||||
block extends from TEXT bo to TEXT bc.
|
||||
It renders as follows in
|
||||
.Fl T Ns Cm ascii
|
||||
mode:
|
||||
.Pp
|
||||
.Dl <ao [bo ac> bc] end
|
||||
.Pp
|
||||
Support for badly-nested blocks is only provided for backward
|
||||
compatibility with some older
|
||||
.Xr mdoc 7
|
||||
implementations.
|
||||
Using badly-nested blocks is
|
||||
.Em strongly discouraged :
|
||||
the
|
||||
.Fl T Ns Cm html
|
||||
and
|
||||
.Fl T Ns Cm xhtml
|
||||
front-ends are 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.
|
||||
.Sh EXAMPLES
|
||||
The following example reads lines from stdin and parses them, operating
|
||||
on the finished parse tree with
|
||||
.Fn parsed .
|
||||
This example does not error-check nor free memory upon failure.
|
||||
.Bd -literal -offset indent
|
||||
struct regset regs;
|
||||
struct mdoc *mdoc;
|
||||
const struct mdoc_node *node;
|
||||
char *buf;
|
||||
size_t len;
|
||||
int line;
|
||||
|
||||
bzero(®s, sizeof(struct regset));
|
||||
line = 1;
|
||||
mdoc = mdoc_alloc(®s, NULL, NULL);
|
||||
buf = NULL;
|
||||
alloc_len = 0;
|
||||
|
||||
while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
|
||||
if (len && buflen[len - 1] = '\en')
|
||||
buf[len - 1] = '\e0';
|
||||
if ( ! mdoc_parseln(mdoc, line, buf))
|
||||
errx(1, "mdoc_parseln");
|
||||
line++;
|
||||
}
|
||||
|
||||
if ( ! mdoc_endparse(mdoc))
|
||||
errx(1, "mdoc_endparse");
|
||||
if (NULL == (node = mdoc_node(mdoc)))
|
||||
errx(1, "mdoc_node");
|
||||
|
||||
parsed(mdoc, node);
|
||||
mdoc_free(mdoc);
|
||||
.Ed
|
||||
.Pp
|
||||
To compile this, execute
|
||||
.Pp
|
||||
.Dl % cc main.c libmdoc.a libmandoc.a
|
||||
.Pp
|
||||
where
|
||||
.Pa main.c
|
||||
is the example file.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr mdoc 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
2925
usr.bin/mdocml/dist/mdoc.7
vendored
2925
usr.bin/mdocml/dist/mdoc.7
vendored
File diff suppressed because it is too large
Load Diff
916
usr.bin/mdocml/dist/mdoc.c
vendored
916
usr.bin/mdocml/dist/mdoc.c
vendored
@@ -1,916 +0,0 @@
|
||||
/* $Vendor-Id: mdoc.c,v 1.177 2011/01/03 11:27:33 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
const char *const __mdoc_macronames[MDOC_MAX] = {
|
||||
"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",
|
||||
/* LINTED */
|
||||
"Xr", "%A", "%B", "%D",
|
||||
/* LINTED */
|
||||
"%I", "%J", "%N", "%O",
|
||||
/* LINTED */
|
||||
"%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",
|
||||
/* LINTED */
|
||||
"Brc", "%C", "Es", "En",
|
||||
/* LINTED */
|
||||
"Dx", "%Q", "br", "sp",
|
||||
/* LINTED */
|
||||
"%U", "Ta"
|
||||
};
|
||||
|
||||
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
|
||||
"split", "nosplit", "ragged",
|
||||
"unfilled", "literal", "file",
|
||||
"offset", "bullet", "dash",
|
||||
"hyphen", "item", "enum",
|
||||
"tag", "diag", "hang",
|
||||
"ohang", "inset", "column",
|
||||
"width", "compact", "std",
|
||||
"filled", "words", "emphasis",
|
||||
"symbolic", "nested", "centered"
|
||||
};
|
||||
|
||||
const char * const *mdoc_macronames = __mdoc_macronames;
|
||||
const char * const *mdoc_argnames = __mdoc_argnames;
|
||||
|
||||
static void mdoc_node_free(struct mdoc_node *);
|
||||
static void mdoc_node_unlink(struct mdoc *,
|
||||
struct mdoc_node *);
|
||||
static void mdoc_free1(struct mdoc *);
|
||||
static void mdoc_alloc1(struct mdoc *);
|
||||
static struct mdoc_node *node_alloc(struct mdoc *, int, int,
|
||||
enum mdoct, enum mdoc_type);
|
||||
static int node_append(struct mdoc *,
|
||||
struct mdoc_node *);
|
||||
static int mdoc_ptext(struct mdoc *, int, char *, int);
|
||||
static int mdoc_pmacro(struct mdoc *, int, char *, int);
|
||||
static int mdoc_span_alloc(struct mdoc *,
|
||||
const struct tbl_span *);
|
||||
|
||||
|
||||
const struct mdoc_node *
|
||||
mdoc_node(const struct mdoc *m)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
return(m->first);
|
||||
}
|
||||
|
||||
|
||||
const struct mdoc_meta *
|
||||
mdoc_meta(const struct mdoc *m)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
return(&m->meta);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Frees volatile resources (parse tree, meta-data, fields).
|
||||
*/
|
||||
static void
|
||||
mdoc_free1(struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
if (mdoc->first)
|
||||
mdoc_node_delete(mdoc, mdoc->first);
|
||||
if (mdoc->meta.title)
|
||||
free(mdoc->meta.title);
|
||||
if (mdoc->meta.os)
|
||||
free(mdoc->meta.os);
|
||||
if (mdoc->meta.name)
|
||||
free(mdoc->meta.name);
|
||||
if (mdoc->meta.arch)
|
||||
free(mdoc->meta.arch);
|
||||
if (mdoc->meta.vol)
|
||||
free(mdoc->meta.vol);
|
||||
if (mdoc->meta.msec)
|
||||
free(mdoc->meta.msec);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate all volatile resources (parse tree, meta-data, fields).
|
||||
*/
|
||||
static void
|
||||
mdoc_alloc1(struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
memset(&mdoc->meta, 0, sizeof(struct mdoc_meta));
|
||||
mdoc->flags = 0;
|
||||
mdoc->lastnamed = mdoc->lastsec = SEC_NONE;
|
||||
mdoc->last = mandoc_calloc(1, sizeof(struct mdoc_node));
|
||||
mdoc->first = mdoc->last;
|
||||
mdoc->last->type = MDOC_ROOT;
|
||||
mdoc->next = MDOC_NEXT_CHILD;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free up volatile resources (see mdoc_free1()) then re-initialises the
|
||||
* data with mdoc_alloc1(). After invocation, parse data has been reset
|
||||
* and the parser is ready for re-invocation on a new tree; however,
|
||||
* cross-parse non-volatile data is kept intact.
|
||||
*/
|
||||
void
|
||||
mdoc_reset(struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
mdoc_free1(mdoc);
|
||||
mdoc_alloc1(mdoc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Completely free up all volatile and non-volatile parse resources.
|
||||
* After invocation, the pointer is no longer usable.
|
||||
*/
|
||||
void
|
||||
mdoc_free(struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
mdoc_free1(mdoc);
|
||||
free(mdoc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate volatile and non-volatile parse resources.
|
||||
*/
|
||||
struct mdoc *
|
||||
mdoc_alloc(struct regset *regs, void *data, mandocmsg msg)
|
||||
{
|
||||
struct mdoc *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct mdoc));
|
||||
|
||||
p->msg = msg;
|
||||
p->data = data;
|
||||
p->regs = regs;
|
||||
|
||||
mdoc_hash_init();
|
||||
mdoc_alloc1(p);
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Climb back up the parse tree, validating open scopes. Mostly calls
|
||||
* through to macro_end() in macro.c.
|
||||
*/
|
||||
int
|
||||
mdoc_endparse(struct mdoc *m)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
if (mdoc_macroend(m))
|
||||
return(1);
|
||||
m->flags |= MDOC_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
mdoc_addspan(struct mdoc *m, const struct tbl_span *sp)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
/* FIXME: grab from span. */
|
||||
mdoc_pmsg(m, 0, 0, MANDOCERR_NOTEXT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(mdoc_span_alloc(m, sp));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main parse routine. Parses a single line -- really just hands off to
|
||||
* the macro (mdoc_pmacro()) or text parser (mdoc_ptext()).
|
||||
*/
|
||||
int
|
||||
mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs)
|
||||
{
|
||||
|
||||
assert( ! (MDOC_HALT & m->flags));
|
||||
|
||||
m->flags |= MDOC_NEWLINE;
|
||||
|
||||
/*
|
||||
* Let the roff nS register switch SYNOPSIS mode early,
|
||||
* such that the parser knows at all times
|
||||
* whether this mode is on or off.
|
||||
* Note that this mode is also switched by the Sh macro.
|
||||
*/
|
||||
if (m->regs->regs[(int)REG_nS].set) {
|
||||
if (m->regs->regs[(int)REG_nS].v.u)
|
||||
m->flags |= MDOC_SYNOPSIS;
|
||||
else
|
||||
m->flags &= ~MDOC_SYNOPSIS;
|
||||
}
|
||||
|
||||
return(('.' == buf[offs] || '\'' == buf[offs]) ?
|
||||
mdoc_pmacro(m, ln, buf, offs) :
|
||||
mdoc_ptext(m, ln, buf, offs));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_vmsg(struct mdoc *mdoc, enum mandocerr t,
|
||||
int ln, int pos, const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return((*mdoc->msg)(t, mdoc->data, ln, pos, buf));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_macro(MACRO_PROT_ARGS)
|
||||
{
|
||||
assert(tok < MDOC_MAX);
|
||||
|
||||
/* If we're in the body, deny prologue calls. */
|
||||
|
||||
if (MDOC_PROLOGUE & mdoc_macros[tok].flags &&
|
||||
MDOC_PBODY & m->flags) {
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_BADBODY);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* If we're in the prologue, deny "body" macros. */
|
||||
|
||||
if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) &&
|
||||
! (MDOC_PBODY & m->flags)) {
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_BADPROLOG);
|
||||
if (NULL == m->meta.msec)
|
||||
m->meta.msec = mandoc_strdup("1");
|
||||
if (NULL == m->meta.title)
|
||||
m->meta.title = mandoc_strdup("UNKNOWN");
|
||||
if (NULL == m->meta.vol)
|
||||
m->meta.vol = mandoc_strdup("LOCAL");
|
||||
if (NULL == m->meta.os)
|
||||
m->meta.os = mandoc_strdup("LOCAL");
|
||||
if (0 == m->meta.date)
|
||||
m->meta.date = time(NULL);
|
||||
m->flags |= MDOC_PBODY;
|
||||
}
|
||||
|
||||
return((*mdoc_macros[tok].fp)(m, tok, line, ppos, pos, buf));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
node_append(struct mdoc *mdoc, struct mdoc_node *p)
|
||||
{
|
||||
|
||||
assert(mdoc->last);
|
||||
assert(mdoc->first);
|
||||
assert(MDOC_ROOT != p->type);
|
||||
|
||||
switch (mdoc->next) {
|
||||
case (MDOC_NEXT_SIBLING):
|
||||
mdoc->last->next = p;
|
||||
p->prev = mdoc->last;
|
||||
p->parent = mdoc->last->parent;
|
||||
break;
|
||||
case (MDOC_NEXT_CHILD):
|
||||
mdoc->last->child = p;
|
||||
p->parent = mdoc->last;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
p->parent->nchild++;
|
||||
|
||||
/*
|
||||
* Copy over the normalised-data pointer of our parent. Not
|
||||
* everybody has one, but copying a null pointer is fine.
|
||||
*/
|
||||
|
||||
switch (p->type) {
|
||||
case (MDOC_BODY):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_TAIL):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_HEAD):
|
||||
p->norm = p->parent->norm;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! mdoc_valid_pre(mdoc, p))
|
||||
return(0);
|
||||
|
||||
switch (p->type) {
|
||||
case (MDOC_HEAD):
|
||||
assert(MDOC_BLOCK == p->parent->type);
|
||||
p->parent->head = p;
|
||||
break;
|
||||
case (MDOC_TAIL):
|
||||
assert(MDOC_BLOCK == p->parent->type);
|
||||
p->parent->tail = p;
|
||||
break;
|
||||
case (MDOC_BODY):
|
||||
if (p->end)
|
||||
break;
|
||||
assert(MDOC_BLOCK == p->parent->type);
|
||||
p->parent->body = p;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mdoc->last = p;
|
||||
|
||||
switch (p->type) {
|
||||
case (MDOC_TBL):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_TEXT):
|
||||
if ( ! mdoc_valid_post(mdoc))
|
||||
return(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static struct mdoc_node *
|
||||
node_alloc(struct mdoc *m, int line, int pos,
|
||||
enum mdoct tok, enum mdoc_type type)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct mdoc_node));
|
||||
p->sec = m->lastsec;
|
||||
p->line = line;
|
||||
p->pos = pos;
|
||||
p->tok = tok;
|
||||
p->type = type;
|
||||
|
||||
/* Flag analysis. */
|
||||
|
||||
if (MDOC_SYNOPSIS & m->flags)
|
||||
p->flags |= MDOC_SYNPRETTY;
|
||||
else
|
||||
p->flags &= ~MDOC_SYNPRETTY;
|
||||
if (MDOC_NEWLINE & m->flags)
|
||||
p->flags |= MDOC_LINE;
|
||||
m->flags &= ~MDOC_NEWLINE;
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_tail_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_TAIL);
|
||||
if ( ! node_append(m, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_head_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
assert(m->first);
|
||||
assert(m->last);
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_HEAD);
|
||||
if ( ! node_append(m, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_body_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_BODY);
|
||||
if ( ! node_append(m, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_endbody_alloc(struct mdoc *m, int line, int pos, enum mdoct tok,
|
||||
struct mdoc_node *body, enum mdoc_endbody end)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_BODY);
|
||||
p->pending = body;
|
||||
p->end = end;
|
||||
if ( ! node_append(m, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_block_alloc(struct mdoc *m, int line, int pos,
|
||||
enum mdoct tok, struct mdoc_arg *args)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_BLOCK);
|
||||
p->args = args;
|
||||
if (p->args)
|
||||
(args->refcnt)++;
|
||||
|
||||
switch (tok) {
|
||||
case (MDOC_Bd):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Bf):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Bl):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Rs):
|
||||
p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! node_append(m, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_elem_alloc(struct mdoc *m, int line, int pos,
|
||||
enum mdoct tok, struct mdoc_arg *args)
|
||||
{
|
||||
struct mdoc_node *p;
|
||||
|
||||
p = node_alloc(m, line, pos, tok, MDOC_ELEM);
|
||||
p->args = args;
|
||||
if (p->args)
|
||||
(args->refcnt)++;
|
||||
|
||||
switch (tok) {
|
||||
case (MDOC_An):
|
||||
p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! node_append(m, p))
|
||||
return(0);
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
mdoc_span_alloc(struct mdoc *m, const struct tbl_span *sp)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
|
||||
/* FIXME: grab from tbl_span. */
|
||||
n = node_alloc(m, 0, 0, MDOC_MAX, MDOC_TBL);
|
||||
n->span = sp;
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p)
|
||||
{
|
||||
struct mdoc_node *n;
|
||||
size_t sv, len;
|
||||
|
||||
len = strlen(p);
|
||||
|
||||
n = node_alloc(m, line, pos, MDOC_MAX, MDOC_TEXT);
|
||||
n->string = mandoc_malloc(len + 1);
|
||||
sv = strlcpy(n->string, p, len + 1);
|
||||
|
||||
/* Prohibit truncation. */
|
||||
assert(sv < len + 1);
|
||||
|
||||
if ( ! node_append(m, n))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mdoc_node_free(struct mdoc_node *p)
|
||||
{
|
||||
|
||||
if (MDOC_BLOCK == p->type || MDOC_ELEM == p->type)
|
||||
free(p->norm);
|
||||
if (p->string)
|
||||
free(p->string);
|
||||
if (p->args)
|
||||
mdoc_argv_free(p->args);
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mdoc_node_unlink(struct mdoc *m, struct mdoc_node *n)
|
||||
{
|
||||
|
||||
/* Adjust siblings. */
|
||||
|
||||
if (n->prev)
|
||||
n->prev->next = n->next;
|
||||
if (n->next)
|
||||
n->next->prev = n->prev;
|
||||
|
||||
/* Adjust parent. */
|
||||
|
||||
if (n->parent) {
|
||||
n->parent->nchild--;
|
||||
if (n->parent->child == n)
|
||||
n->parent->child = n->prev ? n->prev : n->next;
|
||||
if (n->parent->last == n)
|
||||
n->parent->last = n->prev ? n->prev : NULL;
|
||||
}
|
||||
|
||||
/* Adjust parse point, if applicable. */
|
||||
|
||||
if (m && m->last == n) {
|
||||
if (n->prev) {
|
||||
m->last = n->prev;
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
} else {
|
||||
m->last = n->parent;
|
||||
m->next = MDOC_NEXT_CHILD;
|
||||
}
|
||||
}
|
||||
|
||||
if (m && m->first == n)
|
||||
m->first = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
|
||||
{
|
||||
|
||||
while (p->child) {
|
||||
assert(p->nchild);
|
||||
mdoc_node_delete(m, p->child);
|
||||
}
|
||||
assert(0 == p->nchild);
|
||||
|
||||
mdoc_node_unlink(m, p);
|
||||
mdoc_node_free(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse free-form text, that is, a line that does not begin with the
|
||||
* control character.
|
||||
*/
|
||||
static int
|
||||
mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
|
||||
{
|
||||
char *c, *ws, *end;
|
||||
struct mdoc_node *n;
|
||||
|
||||
/* Ignore bogus comments. */
|
||||
|
||||
if ('\\' == buf[offs] &&
|
||||
'.' == buf[offs + 1] &&
|
||||
'"' == buf[offs + 2]) {
|
||||
mdoc_pmsg(m, line, offs, MANDOCERR_BADCOMMENT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* No text before an initial macro. */
|
||||
|
||||
if (SEC_NONE == m->lastnamed) {
|
||||
mdoc_pmsg(m, line, offs, MANDOCERR_NOTEXT);
|
||||
return(1);
|
||||
}
|
||||
|
||||
assert(m->last);
|
||||
n = m->last;
|
||||
|
||||
/*
|
||||
* Divert directly to list processing if we're encountering a
|
||||
* columnar MDOC_BLOCK with or without a prior MDOC_BLOCK entry
|
||||
* (a MDOC_BODY means it's already open, in which case we should
|
||||
* process within its context in the normal way).
|
||||
*/
|
||||
|
||||
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
|
||||
LIST_column == n->norm->Bl.type) {
|
||||
/* `Bl' is open without any children. */
|
||||
m->flags |= MDOC_FREECOL;
|
||||
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
|
||||
}
|
||||
|
||||
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
|
||||
NULL != n->parent &&
|
||||
MDOC_Bl == n->parent->tok &&
|
||||
LIST_column == n->parent->norm->Bl.type) {
|
||||
/* `Bl' has block-level `It' children. */
|
||||
m->flags |= MDOC_FREECOL;
|
||||
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for the beginning of unescaped trailing whitespace (ws)
|
||||
* and for the first character not to be output (end).
|
||||
*/
|
||||
|
||||
/* FIXME: replace with strcspn(). */
|
||||
ws = NULL;
|
||||
for (c = end = buf + offs; *c; c++) {
|
||||
switch (*c) {
|
||||
case '-':
|
||||
if (mandoc_hyph(buf + offs, c))
|
||||
*c = ASCII_HYPH;
|
||||
ws = NULL;
|
||||
break;
|
||||
case ' ':
|
||||
if (NULL == ws)
|
||||
ws = c;
|
||||
continue;
|
||||
case '\t':
|
||||
/*
|
||||
* Always warn about trailing tabs,
|
||||
* even outside literal context,
|
||||
* where they should be put on the next line.
|
||||
*/
|
||||
if (NULL == ws)
|
||||
ws = c;
|
||||
/*
|
||||
* Strip trailing tabs in literal context only;
|
||||
* outside, they affect the next line.
|
||||
*/
|
||||
if (MDOC_LITERAL & m->flags)
|
||||
continue;
|
||||
break;
|
||||
case '\\':
|
||||
/* Skip the escaped character, too, if any. */
|
||||
if (c[1])
|
||||
c++;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
ws = NULL;
|
||||
break;
|
||||
}
|
||||
end = c + 1;
|
||||
}
|
||||
*end = '\0';
|
||||
|
||||
if (ws)
|
||||
mdoc_pmsg(m, line, (int)(ws-buf), MANDOCERR_EOLNSPACE);
|
||||
|
||||
if ('\0' == buf[offs] && ! (MDOC_LITERAL & m->flags)) {
|
||||
mdoc_pmsg(m, line, (int)(c-buf), MANDOCERR_NOBLANKLN);
|
||||
|
||||
/*
|
||||
* Insert a `sp' in the case of a blank line. Technically,
|
||||
* blank lines aren't allowed, but enough manuals assume this
|
||||
* behaviour that we want to work around it.
|
||||
*/
|
||||
if ( ! mdoc_elem_alloc(m, line, offs, MDOC_sp, NULL))
|
||||
return(0);
|
||||
|
||||
m->next = MDOC_NEXT_SIBLING;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if ( ! mdoc_word_alloc(m, line, offs, buf+offs))
|
||||
return(0);
|
||||
|
||||
if (MDOC_LITERAL & m->flags)
|
||||
return(1);
|
||||
|
||||
/*
|
||||
* End-of-sentence check. If the last character is an unescaped
|
||||
* EOS character, then flag the node as being the end of a
|
||||
* sentence. The front-end will know how to interpret this.
|
||||
*/
|
||||
|
||||
assert(buf < end);
|
||||
|
||||
if (mandoc_eos(buf+offs, (size_t)(end-buf-offs), 0))
|
||||
m->last->flags |= MDOC_EOS;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse a macro line, that is, a line beginning with the control
|
||||
* character.
|
||||
*/
|
||||
static int
|
||||
mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
|
||||
{
|
||||
enum mdoct tok;
|
||||
int i, j, sv;
|
||||
char mac[5];
|
||||
struct mdoc_node *n;
|
||||
|
||||
/* Empty lines are ignored. */
|
||||
|
||||
offs++;
|
||||
|
||||
if ('\0' == buf[offs])
|
||||
return(1);
|
||||
|
||||
i = offs;
|
||||
|
||||
/* Accept tabs/whitespace after the initial control char. */
|
||||
|
||||
if (' ' == buf[i] || '\t' == buf[i]) {
|
||||
i++;
|
||||
while (buf[i] && (' ' == buf[i] || '\t' == buf[i]))
|
||||
i++;
|
||||
if ('\0' == buf[i])
|
||||
return(1);
|
||||
}
|
||||
|
||||
sv = i;
|
||||
|
||||
/*
|
||||
* Copy the first word into a nil-terminated buffer.
|
||||
* Stop copying when a tab, space, or eoln is encountered.
|
||||
*/
|
||||
|
||||
j = 0;
|
||||
while (j < 4 && '\0' != buf[i] && ' ' != buf[i] && '\t' != buf[i])
|
||||
mac[j++] = buf[i++];
|
||||
mac[j] = '\0';
|
||||
|
||||
tok = (j > 1 || j < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
|
||||
if (MDOC_MAX == tok) {
|
||||
mdoc_vmsg(m, MANDOCERR_MACRO, ln, sv, "%s", buf + sv - 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Disregard the first trailing tab, if applicable. */
|
||||
|
||||
if ('\t' == buf[i])
|
||||
i++;
|
||||
|
||||
/* Jump to the next non-whitespace word. */
|
||||
|
||||
while (buf[i] && ' ' == buf[i])
|
||||
i++;
|
||||
|
||||
/*
|
||||
* Trailing whitespace. Note that tabs are allowed to be passed
|
||||
* into the parser as "text", so we only warn about spaces here.
|
||||
*/
|
||||
|
||||
if ('\0' == buf[i] && ' ' == buf[i - 1])
|
||||
mdoc_pmsg(m, ln, i - 1, MANDOCERR_EOLNSPACE);
|
||||
|
||||
/*
|
||||
* If an initial macro or a list invocation, divert directly
|
||||
* into macro processing.
|
||||
*/
|
||||
|
||||
if (NULL == m->last || MDOC_It == tok || MDOC_El == tok) {
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &i, buf))
|
||||
goto err;
|
||||
return(1);
|
||||
}
|
||||
|
||||
n = m->last;
|
||||
assert(m->last);
|
||||
|
||||
/*
|
||||
* If the first macro of a `Bl -column', open an `It' block
|
||||
* context around the parsed macro.
|
||||
*/
|
||||
|
||||
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
|
||||
LIST_column == n->norm->Bl.type) {
|
||||
m->flags |= MDOC_FREECOL;
|
||||
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
|
||||
goto err;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're following a block-level `It' within a `Bl -column'
|
||||
* context (perhaps opened in the above block or in ptext()),
|
||||
* then open an `It' block context around the parsed macro.
|
||||
*/
|
||||
|
||||
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
|
||||
NULL != n->parent &&
|
||||
MDOC_Bl == n->parent->tok &&
|
||||
LIST_column == n->parent->norm->Bl.type) {
|
||||
m->flags |= MDOC_FREECOL;
|
||||
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
|
||||
goto err;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Normal processing of a macro. */
|
||||
|
||||
if ( ! mdoc_macro(m, tok, ln, sv, &i, buf))
|
||||
goto err;
|
||||
|
||||
return(1);
|
||||
|
||||
err: /* Error out. */
|
||||
|
||||
m->flags |= MDOC_HALT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
436
usr.bin/mdocml/dist/mdoc.h
vendored
436
usr.bin/mdocml/dist/mdoc.h
vendored
@@ -1,436 +0,0 @@
|
||||
/* $Vendor-Id: mdoc.h,v 1.114 2011/01/01 12:18:37 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef MDOC_H
|
||||
#define MDOC_H
|
||||
|
||||
/*
|
||||
* What follows is a list of ALL possible macros.
|
||||
*/
|
||||
enum mdoct {
|
||||
MDOC_Ap = 0,
|
||||
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_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_br,
|
||||
MDOC_sp,
|
||||
MDOC__U,
|
||||
MDOC_Ta,
|
||||
MDOC_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* What follows is a list of ALL possible macro arguments.
|
||||
*/
|
||||
enum mdocargt {
|
||||
MDOC_Split,
|
||||
MDOC_Nosplit,
|
||||
MDOC_Ragged,
|
||||
MDOC_Unfilled,
|
||||
MDOC_Literal,
|
||||
MDOC_File,
|
||||
MDOC_Offset,
|
||||
MDOC_Bullet,
|
||||
MDOC_Dash,
|
||||
MDOC_Hyphen,
|
||||
MDOC_Item,
|
||||
MDOC_Enum,
|
||||
MDOC_Tag,
|
||||
MDOC_Diag,
|
||||
MDOC_Hang,
|
||||
MDOC_Ohang,
|
||||
MDOC_Inset,
|
||||
MDOC_Column,
|
||||
MDOC_Width,
|
||||
MDOC_Compact,
|
||||
MDOC_Std,
|
||||
MDOC_Filled,
|
||||
MDOC_Words,
|
||||
MDOC_Emphasis,
|
||||
MDOC_Symbolic,
|
||||
MDOC_Nested,
|
||||
MDOC_Centred,
|
||||
MDOC_ARG_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Type of a syntax node.
|
||||
*/
|
||||
enum mdoc_type {
|
||||
MDOC_TEXT,
|
||||
MDOC_ELEM,
|
||||
MDOC_HEAD,
|
||||
MDOC_TAIL,
|
||||
MDOC_BODY,
|
||||
MDOC_BLOCK,
|
||||
MDOC_TBL,
|
||||
MDOC_ROOT
|
||||
};
|
||||
|
||||
/*
|
||||
* Section (named/unnamed) of `Sh'. Note that these appear in the
|
||||
* conventional order imposed by mdoc.7.
|
||||
*/
|
||||
enum mdoc_sec {
|
||||
SEC_NONE = 0, /* No section, yet. */
|
||||
SEC_NAME,
|
||||
SEC_LIBRARY,
|
||||
SEC_SYNOPSIS,
|
||||
SEC_DESCRIPTION,
|
||||
SEC_IMPLEMENTATION,
|
||||
SEC_RETURN_VALUES,
|
||||
SEC_ENVIRONMENT,
|
||||
SEC_FILES,
|
||||
SEC_EXIT_STATUS,
|
||||
SEC_EXAMPLES,
|
||||
SEC_DIAGNOSTICS,
|
||||
SEC_COMPATIBILITY,
|
||||
SEC_ERRORS,
|
||||
SEC_SEE_ALSO,
|
||||
SEC_STANDARDS,
|
||||
SEC_HISTORY,
|
||||
SEC_AUTHORS,
|
||||
SEC_CAVEATS,
|
||||
SEC_BUGS,
|
||||
SEC_SECURITY,
|
||||
SEC_CUSTOM, /* User-defined. */
|
||||
SEC__MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Information from prologue.
|
||||
*/
|
||||
struct mdoc_meta {
|
||||
char *msec; /* `Dt' section (1, 3p, etc.) */
|
||||
char *vol; /* `Dt' volume (implied) */
|
||||
char *arch; /* `Dt' arch (i386, etc.) */
|
||||
time_t date; /* `Dd' normalised date */
|
||||
char *title; /* `Dt' title (FOO, etc.) */
|
||||
char *os; /* `Os' system (OpenBSD, etc.) */
|
||||
char *name; /* leading `Nm' name */
|
||||
};
|
||||
|
||||
/*
|
||||
* An argument to a macro (multiple values = `-column xxx yyy').
|
||||
*/
|
||||
struct mdoc_argv {
|
||||
enum mdocargt arg; /* type of argument */
|
||||
int line;
|
||||
int pos;
|
||||
size_t sz; /* elements in "value" */
|
||||
char **value; /* argument strings */
|
||||
};
|
||||
|
||||
/*
|
||||
* Reference-counted macro arguments. These are refcounted because
|
||||
* blocks have multiple instances of the same arguments spread across
|
||||
* the HEAD, BODY, TAIL, and BLOCK node types.
|
||||
*/
|
||||
struct mdoc_arg {
|
||||
size_t argc;
|
||||
struct mdoc_argv *argv;
|
||||
unsigned int refcnt;
|
||||
};
|
||||
|
||||
/*
|
||||
* Indicates that a BODY's formatting has ended, but the scope is still
|
||||
* open. Used for syntax-broken blocks.
|
||||
*/
|
||||
enum mdoc_endbody {
|
||||
ENDBODY_NOT = 0,
|
||||
ENDBODY_SPACE, /* is broken: append a space */
|
||||
ENDBODY_NOSPACE /* is broken: don't append a space */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `Bl' list type.
|
||||
*/
|
||||
enum mdoc_list {
|
||||
LIST__NONE = 0,
|
||||
LIST_bullet,
|
||||
LIST_column,
|
||||
LIST_dash,
|
||||
LIST_diag,
|
||||
LIST_enum,
|
||||
LIST_hang,
|
||||
LIST_hyphen,
|
||||
LIST_inset,
|
||||
LIST_item,
|
||||
LIST_ohang,
|
||||
LIST_tag,
|
||||
LIST_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `Bd' display type.
|
||||
*/
|
||||
enum mdoc_disp {
|
||||
DISP__NONE = 0,
|
||||
DISP_centred,
|
||||
DISP_ragged,
|
||||
DISP_unfilled,
|
||||
DISP_filled,
|
||||
DISP_literal
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `An' splitting argument.
|
||||
*/
|
||||
enum mdoc_auth {
|
||||
AUTH__NONE = 0,
|
||||
AUTH_split,
|
||||
AUTH_nosplit
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised `Bf' font type.
|
||||
*/
|
||||
enum mdoc_font {
|
||||
FONT__NONE = 0,
|
||||
FONT_Em,
|
||||
FONT_Li,
|
||||
FONT_Sy
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `Bd'.
|
||||
*/
|
||||
struct mdoc_bd {
|
||||
const char *offs; /* -offset */
|
||||
enum mdoc_disp type; /* -ragged, etc. */
|
||||
int comp; /* -compact */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `Bl'.
|
||||
*/
|
||||
struct mdoc_bl {
|
||||
const char *width; /* -width */
|
||||
const char *offs; /* -offset */
|
||||
enum mdoc_list type; /* -tag, -enum, etc. */
|
||||
int comp; /* -compact */
|
||||
size_t ncols; /* -column arg count */
|
||||
const char **cols; /* -column val ptr */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `Bf'.
|
||||
*/
|
||||
struct mdoc_bf {
|
||||
enum mdoc_font font; /* font */
|
||||
};
|
||||
|
||||
/*
|
||||
* Normalised arguments for `An'.
|
||||
*/
|
||||
struct mdoc_an {
|
||||
enum mdoc_auth auth; /* -split, etc. */
|
||||
};
|
||||
|
||||
struct mdoc_rs {
|
||||
struct mdoc_node *child_J; /* pointer to %J */
|
||||
};
|
||||
|
||||
/*
|
||||
* Consists of normalised node arguments. These should be used instead
|
||||
* of iterating through the mdoc_arg pointers of a node: defaults are
|
||||
* provided, etc.
|
||||
*/
|
||||
union mdoc_data {
|
||||
struct mdoc_an An;
|
||||
struct mdoc_bd Bd;
|
||||
struct mdoc_bf Bf;
|
||||
struct mdoc_bl Bl;
|
||||
struct mdoc_rs Rs;
|
||||
};
|
||||
|
||||
/*
|
||||
* Single node in tree-linked AST.
|
||||
*/
|
||||
struct mdoc_node {
|
||||
struct mdoc_node *parent; /* parent AST node */
|
||||
struct mdoc_node *child; /* first child AST node */
|
||||
struct mdoc_node *last; /* last child AST node */
|
||||
struct mdoc_node *next; /* sibling AST node */
|
||||
struct mdoc_node *prev; /* prior sibling AST node */
|
||||
int nchild; /* number children */
|
||||
int line; /* parse line */
|
||||
int pos; /* parse column */
|
||||
enum mdoct tok; /* tok or MDOC__MAX if none */
|
||||
int flags;
|
||||
#define MDOC_VALID (1 << 0) /* has been validated */
|
||||
#define MDOC_EOS (1 << 2) /* at sentence boundary */
|
||||
#define MDOC_LINE (1 << 3) /* first macro/text on line */
|
||||
#define MDOC_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting */
|
||||
#define MDOC_ENDED (1 << 5) /* rendering has been ended */
|
||||
enum mdoc_type type; /* AST node type */
|
||||
enum mdoc_sec sec; /* current named section */
|
||||
union mdoc_data *norm; /* normalised args */
|
||||
/* FIXME: these can be union'd to shave a few bytes. */
|
||||
struct mdoc_arg *args; /* BLOCK/ELEM */
|
||||
struct mdoc_node *pending; /* BLOCK */
|
||||
struct mdoc_node *head; /* BLOCK */
|
||||
struct mdoc_node *body; /* BLOCK */
|
||||
struct mdoc_node *tail; /* BLOCK */
|
||||
char *string; /* TEXT */
|
||||
const struct tbl_span *span; /* TBL */
|
||||
enum mdoc_endbody end; /* BODY */
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of macros. Index is enum mdoct. Indexing into this returns
|
||||
* the normalised name, e.g., mdoc_macronames[MDOC_Sh] -> "Sh".
|
||||
*/
|
||||
extern const char *const *mdoc_macronames;
|
||||
|
||||
/*
|
||||
* Names of macro args. Index is enum mdocargt. Indexing into this
|
||||
* returns the normalised name, e.g., mdoc_argnames[MDOC_File] ->
|
||||
* "file".
|
||||
*/
|
||||
extern const char *const *mdoc_argnames;
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct mdoc;
|
||||
|
||||
void mdoc_free(struct mdoc *);
|
||||
struct mdoc *mdoc_alloc(struct regset *, void *, mandocmsg);
|
||||
void mdoc_reset(struct mdoc *);
|
||||
int mdoc_parseln(struct mdoc *, int, char *, int);
|
||||
const struct mdoc_node *mdoc_node(const struct mdoc *);
|
||||
const struct mdoc_meta *mdoc_meta(const struct mdoc *);
|
||||
int mdoc_endparse(struct mdoc *);
|
||||
int mdoc_addspan(struct mdoc *,
|
||||
const struct tbl_span *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!MDOC_H*/
|
||||
792
usr.bin/mdocml/dist/mdoc_argv.c
vendored
792
usr.bin/mdocml/dist/mdoc_argv.c
vendored
@@ -1,792 +0,0 @@
|
||||
/* $Vendor-Id: mdoc_argv.c,v 1.62 2010/12/24 14:00:40 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
#include "libmandoc.h"
|
||||
|
||||
/*
|
||||
* Routines to parse arguments of macros. Arguments follow the syntax
|
||||
* of `-arg [val [valN...]]'. Arguments come in all types: quoted
|
||||
* arguments, multiple arguments per value, no-value arguments, etc.
|
||||
*
|
||||
* There's no limit to the number or arguments that may be allocated.
|
||||
*/
|
||||
|
||||
#define ARGV_NONE (1 << 0)
|
||||
#define ARGV_SINGLE (1 << 1)
|
||||
#define ARGV_MULTI (1 << 2)
|
||||
#define ARGV_OPT_SINGLE (1 << 3)
|
||||
|
||||
#define MULTI_STEP 5
|
||||
|
||||
static enum mdocargt argv_a2arg(enum mdoct, const char *);
|
||||
static enum margserr args(struct mdoc *, int, int *,
|
||||
char *, int, char **);
|
||||
static int argv(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_single(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_opt_single(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
static int argv_multi(struct mdoc *, int,
|
||||
struct mdoc_argv *, int *, char *);
|
||||
|
||||
/* Per-argument flags. */
|
||||
|
||||
static int mdoc_argvflags[MDOC_ARG_MAX] = {
|
||||
ARGV_NONE, /* MDOC_Split */
|
||||
ARGV_NONE, /* MDOC_Nosplit */
|
||||
ARGV_NONE, /* MDOC_Ragged */
|
||||
ARGV_NONE, /* MDOC_Unfilled */
|
||||
ARGV_NONE, /* MDOC_Literal */
|
||||
ARGV_SINGLE, /* MDOC_File */
|
||||
ARGV_OPT_SINGLE, /* MDOC_Offset */
|
||||
ARGV_NONE, /* MDOC_Bullet */
|
||||
ARGV_NONE, /* MDOC_Dash */
|
||||
ARGV_NONE, /* MDOC_Hyphen */
|
||||
ARGV_NONE, /* MDOC_Item */
|
||||
ARGV_NONE, /* MDOC_Enum */
|
||||
ARGV_NONE, /* MDOC_Tag */
|
||||
ARGV_NONE, /* MDOC_Diag */
|
||||
ARGV_NONE, /* MDOC_Hang */
|
||||
ARGV_NONE, /* MDOC_Ohang */
|
||||
ARGV_NONE, /* MDOC_Inset */
|
||||
ARGV_MULTI, /* MDOC_Column */
|
||||
ARGV_SINGLE, /* MDOC_Width */
|
||||
ARGV_NONE, /* MDOC_Compact */
|
||||
ARGV_NONE, /* MDOC_Std */
|
||||
ARGV_NONE, /* MDOC_Filled */
|
||||
ARGV_NONE, /* MDOC_Words */
|
||||
ARGV_NONE, /* MDOC_Emphasis */
|
||||
ARGV_NONE, /* MDOC_Symbolic */
|
||||
ARGV_NONE /* MDOC_Symbolic */
|
||||
};
|
||||
|
||||
static int mdoc_argflags[MDOC_MAX] = {
|
||||
0, /* Ap */
|
||||
0, /* Dd */
|
||||
0, /* Dt */
|
||||
0, /* Os */
|
||||
0, /* Sh */
|
||||
0, /* Ss */
|
||||
0, /* Pp */
|
||||
ARGS_DELIM, /* D1 */
|
||||
ARGS_DELIM, /* Dl */
|
||||
0, /* Bd */
|
||||
0, /* Ed */
|
||||
0, /* Bl */
|
||||
0, /* El */
|
||||
0, /* It */
|
||||
ARGS_DELIM, /* Ad */
|
||||
ARGS_DELIM, /* An */
|
||||
ARGS_DELIM, /* Ar */
|
||||
0, /* Cd */
|
||||
ARGS_DELIM, /* Cm */
|
||||
ARGS_DELIM, /* Dv */
|
||||
ARGS_DELIM, /* Er */
|
||||
ARGS_DELIM, /* Ev */
|
||||
0, /* Ex */
|
||||
ARGS_DELIM, /* Fa */
|
||||
0, /* Fd */
|
||||
ARGS_DELIM, /* Fl */
|
||||
ARGS_DELIM, /* Fn */
|
||||
ARGS_DELIM, /* Ft */
|
||||
ARGS_DELIM, /* Ic */
|
||||
0, /* In */
|
||||
ARGS_DELIM, /* Li */
|
||||
0, /* Nd */
|
||||
ARGS_DELIM, /* Nm */
|
||||
ARGS_DELIM, /* Op */
|
||||
0, /* Ot */
|
||||
ARGS_DELIM, /* Pa */
|
||||
0, /* Rv */
|
||||
ARGS_DELIM, /* St */
|
||||
ARGS_DELIM, /* Va */
|
||||
ARGS_DELIM, /* Vt */
|
||||
ARGS_DELIM, /* Xr */
|
||||
0, /* %A */
|
||||
0, /* %B */
|
||||
0, /* %D */
|
||||
0, /* %I */
|
||||
0, /* %J */
|
||||
0, /* %N */
|
||||
0, /* %O */
|
||||
0, /* %P */
|
||||
0, /* %R */
|
||||
0, /* %T */
|
||||
0, /* %V */
|
||||
ARGS_DELIM, /* Ac */
|
||||
0, /* Ao */
|
||||
ARGS_DELIM, /* Aq */
|
||||
ARGS_DELIM, /* At */
|
||||
ARGS_DELIM, /* Bc */
|
||||
0, /* Bf */
|
||||
0, /* Bo */
|
||||
ARGS_DELIM, /* Bq */
|
||||
ARGS_DELIM, /* Bsx */
|
||||
ARGS_DELIM, /* Bx */
|
||||
0, /* Db */
|
||||
ARGS_DELIM, /* Dc */
|
||||
0, /* Do */
|
||||
ARGS_DELIM, /* Dq */
|
||||
ARGS_DELIM, /* Ec */
|
||||
0, /* Ef */
|
||||
ARGS_DELIM, /* Em */
|
||||
0, /* Eo */
|
||||
ARGS_DELIM, /* Fx */
|
||||
ARGS_DELIM, /* Ms */
|
||||
ARGS_DELIM, /* No */
|
||||
ARGS_DELIM, /* Ns */
|
||||
ARGS_DELIM, /* Nx */
|
||||
ARGS_DELIM, /* Ox */
|
||||
ARGS_DELIM, /* Pc */
|
||||
ARGS_DELIM, /* Pf */
|
||||
0, /* Po */
|
||||
ARGS_DELIM, /* Pq */
|
||||
ARGS_DELIM, /* Qc */
|
||||
ARGS_DELIM, /* Ql */
|
||||
0, /* Qo */
|
||||
ARGS_DELIM, /* Qq */
|
||||
0, /* Re */
|
||||
0, /* Rs */
|
||||
ARGS_DELIM, /* Sc */
|
||||
0, /* So */
|
||||
ARGS_DELIM, /* Sq */
|
||||
0, /* Sm */
|
||||
ARGS_DELIM, /* Sx */
|
||||
ARGS_DELIM, /* Sy */
|
||||
ARGS_DELIM, /* Tn */
|
||||
ARGS_DELIM, /* Ux */
|
||||
ARGS_DELIM, /* Xc */
|
||||
0, /* Xo */
|
||||
0, /* Fo */
|
||||
0, /* Fc */
|
||||
0, /* Oo */
|
||||
ARGS_DELIM, /* Oc */
|
||||
0, /* Bk */
|
||||
0, /* Ek */
|
||||
0, /* Bt */
|
||||
0, /* Hf */
|
||||
0, /* Fr */
|
||||
0, /* Ud */
|
||||
0, /* Lb */
|
||||
0, /* Lp */
|
||||
ARGS_DELIM, /* Lk */
|
||||
ARGS_DELIM, /* Mt */
|
||||
ARGS_DELIM, /* Brq */
|
||||
0, /* Bro */
|
||||
ARGS_DELIM, /* Brc */
|
||||
0, /* %C */
|
||||
0, /* Es */
|
||||
0, /* En */
|
||||
0, /* Dx */
|
||||
0, /* %Q */
|
||||
0, /* br */
|
||||
0, /* sp */
|
||||
0, /* %U */
|
||||
0, /* Ta */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Parse an argument from line text. This comes in the form of -key
|
||||
* [value0...], which may either have a single mandatory value, at least
|
||||
* one mandatory value, an optional single value, or no value.
|
||||
*/
|
||||
enum margverr
|
||||
mdoc_argv(struct mdoc *m, int line, enum mdoct tok,
|
||||
struct mdoc_arg **v, int *pos, char *buf)
|
||||
{
|
||||
char *p, sv;
|
||||
struct mdoc_argv tmp;
|
||||
struct mdoc_arg *arg;
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
return(ARGV_EOLN);
|
||||
|
||||
assert(' ' != buf[*pos]);
|
||||
|
||||
/* Parse through to the first unescaped space. */
|
||||
|
||||
p = &buf[++(*pos)];
|
||||
|
||||
assert(*pos > 0);
|
||||
|
||||
/* LINTED */
|
||||
while (buf[*pos]) {
|
||||
if (' ' == buf[*pos])
|
||||
if ('\\' != buf[*pos - 1])
|
||||
break;
|
||||
(*pos)++;
|
||||
}
|
||||
|
||||
/* XXX - save zeroed byte, if not an argument. */
|
||||
|
||||
sv = '\0';
|
||||
if (buf[*pos]) {
|
||||
sv = buf[*pos];
|
||||
buf[(*pos)++] = '\0';
|
||||
}
|
||||
|
||||
(void)memset(&tmp, 0, sizeof(struct mdoc_argv));
|
||||
tmp.line = line;
|
||||
tmp.pos = *pos;
|
||||
|
||||
/* See if our token accepts the argument. */
|
||||
|
||||
if (MDOC_ARG_MAX == (tmp.arg = argv_a2arg(tok, p))) {
|
||||
/* XXX - restore saved zeroed byte. */
|
||||
if (sv)
|
||||
buf[*pos - 1] = sv;
|
||||
return(ARGV_WORD);
|
||||
}
|
||||
|
||||
while (buf[*pos] && ' ' == buf[*pos])
|
||||
(*pos)++;
|
||||
|
||||
if ( ! argv(m, line, &tmp, pos, buf))
|
||||
return(ARGV_ERROR);
|
||||
|
||||
if (NULL == (arg = *v))
|
||||
arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
|
||||
|
||||
arg->argc++;
|
||||
arg->argv = mandoc_realloc
|
||||
(arg->argv, arg->argc * sizeof(struct mdoc_argv));
|
||||
|
||||
(void)memcpy(&arg->argv[(int)arg->argc - 1],
|
||||
&tmp, sizeof(struct mdoc_argv));
|
||||
|
||||
return(ARGV_ARG);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdoc_argv_free(struct mdoc_arg *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (NULL == p)
|
||||
return;
|
||||
|
||||
if (p->refcnt) {
|
||||
--(p->refcnt);
|
||||
if (p->refcnt)
|
||||
return;
|
||||
}
|
||||
assert(p->argc);
|
||||
|
||||
for (i = (int)p->argc - 1; i >= 0; i--)
|
||||
mdoc_argn_free(p, i);
|
||||
|
||||
free(p->argv);
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mdoc_argn_free(struct mdoc_arg *p, int iarg)
|
||||
{
|
||||
struct mdoc_argv *arg;
|
||||
int j;
|
||||
|
||||
arg = &p->argv[iarg];
|
||||
|
||||
if (arg->sz && arg->value) {
|
||||
for (j = (int)arg->sz - 1; j >= 0; j--)
|
||||
free(arg->value[j]);
|
||||
free(arg->value);
|
||||
}
|
||||
|
||||
for (--p->argc; iarg < (int)p->argc; iarg++)
|
||||
p->argv[iarg] = p->argv[iarg+1];
|
||||
}
|
||||
|
||||
|
||||
enum margserr
|
||||
mdoc_zargs(struct mdoc *m, int line, int *pos,
|
||||
char *buf, int flags, char **v)
|
||||
{
|
||||
|
||||
return(args(m, line, pos, buf, flags, v));
|
||||
}
|
||||
|
||||
|
||||
enum margserr
|
||||
mdoc_args(struct mdoc *m, int line, int *pos,
|
||||
char *buf, enum mdoct tok, char **v)
|
||||
{
|
||||
int fl;
|
||||
struct mdoc_node *n;
|
||||
|
||||
fl = mdoc_argflags[tok];
|
||||
|
||||
if (MDOC_It != tok)
|
||||
return(args(m, line, pos, buf, fl, v));
|
||||
|
||||
/*
|
||||
* We know that we're in an `It', so it's reasonable to expect
|
||||
* us to be sitting in a `Bl'. Someday this may not be the case
|
||||
* (if we allow random `It's sitting out there), so provide a
|
||||
* safe fall-back into the default behaviour.
|
||||
*/
|
||||
|
||||
for (n = m->last; n; n = n->parent)
|
||||
if (MDOC_Bl == n->tok)
|
||||
break;
|
||||
|
||||
if (n && LIST_column == n->norm->Bl.type) {
|
||||
fl |= ARGS_TABSEP;
|
||||
fl &= ~ARGS_DELIM;
|
||||
}
|
||||
|
||||
return(args(m, line, pos, buf, fl, v));
|
||||
}
|
||||
|
||||
|
||||
static enum margserr
|
||||
args(struct mdoc *m, int line, int *pos,
|
||||
char *buf, int fl, char **v)
|
||||
{
|
||||
int i;
|
||||
char *p, *pp;
|
||||
enum margserr rc;
|
||||
enum mdelim d;
|
||||
|
||||
/*
|
||||
* Parse out the terms (like `val' in `.Xx -arg val' or simply
|
||||
* `.Xx val'), which can have all sorts of properties:
|
||||
*
|
||||
* ARGS_DELIM: use special handling if encountering trailing
|
||||
* delimiters in the form of [[::delim::][ ]+]+.
|
||||
*
|
||||
* ARGS_NOWARN: don't post warnings. This is only used when
|
||||
* re-parsing delimiters, as the warnings have already been
|
||||
* posted.
|
||||
*
|
||||
* ARGS_TABSEP: use special handling for tab/`Ta' separated
|
||||
* phrases like in `Bl -column'.
|
||||
*/
|
||||
|
||||
assert(' ' != buf[*pos]);
|
||||
|
||||
if ('\0' == buf[*pos]) {
|
||||
if (MDOC_PPHRASE & m->flags)
|
||||
return(ARGS_EOLN);
|
||||
/*
|
||||
* If we're not in a partial phrase and the flag for
|
||||
* being a phrase literal is still set, the punctuation
|
||||
* is unterminated.
|
||||
*/
|
||||
if (MDOC_PHRASELIT & m->flags)
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE))
|
||||
return(ARGS_ERROR);
|
||||
|
||||
m->flags &= ~MDOC_PHRASELIT;
|
||||
return(ARGS_EOLN);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the first character is a closing delimiter and we're to
|
||||
* look for delimited strings, then pass down the buffer seeing
|
||||
* if it follows the pattern of [[::delim::][ ]+]+. Note that
|
||||
* we ONLY care about closing delimiters.
|
||||
*/
|
||||
|
||||
if ((fl & ARGS_DELIM) && DELIM_CLOSE == mdoc_iscdelim(buf[*pos])) {
|
||||
for (i = *pos; buf[i]; ) {
|
||||
d = mdoc_iscdelim(buf[i]);
|
||||
if (DELIM_NONE == d || DELIM_OPEN == d)
|
||||
break;
|
||||
i++;
|
||||
if ('\0' == buf[i] || ' ' != buf[i])
|
||||
break;
|
||||
i++;
|
||||
while (buf[i] && ' ' == buf[i])
|
||||
i++;
|
||||
}
|
||||
|
||||
if ('\0' == buf[i]) {
|
||||
*v = &buf[*pos];
|
||||
if (i && ' ' != buf[i - 1])
|
||||
return(ARGS_PUNCT);
|
||||
if (ARGS_NOWARN & fl)
|
||||
return(ARGS_PUNCT);
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
return(ARGS_PUNCT);
|
||||
}
|
||||
}
|
||||
|
||||
*v = &buf[*pos];
|
||||
|
||||
/*
|
||||
* First handle TABSEP items, restricted to `Bl -column'. This
|
||||
* ignores conventional token parsing and instead uses tabs or
|
||||
* `Ta' macros to separate phrases. Phrases are parsed again
|
||||
* for arguments at a later phase.
|
||||
*/
|
||||
|
||||
if (ARGS_TABSEP & fl) {
|
||||
/* Scan ahead to tab (can't be escaped). */
|
||||
p = strchr(*v, '\t');
|
||||
pp = NULL;
|
||||
|
||||
/* Scan ahead to unescaped `Ta'. */
|
||||
if ( ! (MDOC_PHRASELIT & m->flags))
|
||||
for (pp = *v; ; pp++) {
|
||||
if (NULL == (pp = strstr(pp, "Ta")))
|
||||
break;
|
||||
if (pp > *v && ' ' != *(pp - 1))
|
||||
continue;
|
||||
if (' ' == *(pp + 2) || '\0' == *(pp + 2))
|
||||
break;
|
||||
}
|
||||
|
||||
/* By default, assume a phrase. */
|
||||
rc = ARGS_PHRASE;
|
||||
|
||||
/*
|
||||
* Adjust new-buffer position to be beyond delimiter
|
||||
* mark (e.g., Ta -> end + 2).
|
||||
*/
|
||||
if (p && pp) {
|
||||
*pos += pp < p ? 2 : 1;
|
||||
rc = pp < p ? ARGS_PHRASE : ARGS_PPHRASE;
|
||||
p = pp < p ? pp : p;
|
||||
} else if (p && ! pp) {
|
||||
rc = ARGS_PPHRASE;
|
||||
*pos += 1;
|
||||
} else if (pp && ! p) {
|
||||
p = pp;
|
||||
*pos += 2;
|
||||
} else {
|
||||
rc = ARGS_PEND;
|
||||
p = strchr(*v, 0);
|
||||
}
|
||||
|
||||
/* Whitespace check for eoln case... */
|
||||
if ('\0' == *p && ' ' == *(p - 1) && ! (ARGS_NOWARN & fl))
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
|
||||
*pos += (int)(p - *v);
|
||||
|
||||
/* Strip delimiter's preceding whitespace. */
|
||||
pp = p - 1;
|
||||
while (pp > *v && ' ' == *pp) {
|
||||
if (pp > *v && '\\' == *(pp - 1))
|
||||
break;
|
||||
pp--;
|
||||
}
|
||||
*(pp + 1) = 0;
|
||||
|
||||
/* Strip delimiter's proceeding whitespace. */
|
||||
for (pp = &buf[*pos]; ' ' == *pp; pp++, (*pos)++)
|
||||
/* Skip ahead. */ ;
|
||||
|
||||
return(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a quoted literal. A quote begins with a double-quote
|
||||
* and ends with a double-quote NOT preceded by a double-quote.
|
||||
* Whitespace is NOT involved in literal termination.
|
||||
*/
|
||||
|
||||
if (MDOC_PHRASELIT & m->flags || '\"' == buf[*pos]) {
|
||||
if ( ! (MDOC_PHRASELIT & m->flags))
|
||||
*v = &buf[++(*pos)];
|
||||
|
||||
if (MDOC_PPHRASE & m->flags)
|
||||
m->flags |= MDOC_PHRASELIT;
|
||||
|
||||
for ( ; buf[*pos]; (*pos)++) {
|
||||
if ('\"' != buf[*pos])
|
||||
continue;
|
||||
if ('\"' != buf[*pos + 1])
|
||||
break;
|
||||
(*pos)++;
|
||||
}
|
||||
|
||||
if ('\0' == buf[*pos]) {
|
||||
if (ARGS_NOWARN & fl || MDOC_PPHRASE & m->flags)
|
||||
return(ARGS_QWORD);
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_BADQUOTE))
|
||||
return(ARGS_ERROR);
|
||||
return(ARGS_QWORD);
|
||||
}
|
||||
|
||||
m->flags &= ~MDOC_PHRASELIT;
|
||||
buf[(*pos)++] = '\0';
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
return(ARGS_QWORD);
|
||||
|
||||
while (' ' == buf[*pos])
|
||||
(*pos)++;
|
||||
|
||||
if (0 == buf[*pos] && ! (ARGS_NOWARN & fl))
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
|
||||
return(ARGS_QWORD);
|
||||
}
|
||||
|
||||
/*
|
||||
* A non-quoted term progresses until either the end of line or
|
||||
* a non-escaped whitespace.
|
||||
*/
|
||||
|
||||
for ( ; buf[*pos]; (*pos)++)
|
||||
if (*pos && ' ' == buf[*pos] && '\\' != buf[*pos - 1])
|
||||
break;
|
||||
|
||||
if ('\0' == buf[*pos])
|
||||
return(ARGS_WORD);
|
||||
|
||||
buf[(*pos)++] = '\0';
|
||||
|
||||
while (' ' == buf[*pos])
|
||||
(*pos)++;
|
||||
|
||||
if ('\0' == buf[*pos] && ! (ARGS_NOWARN & fl))
|
||||
if ( ! mdoc_pmsg(m, line, *pos, MANDOCERR_EOLNSPACE))
|
||||
return(ARGS_ERROR);
|
||||
|
||||
return(ARGS_WORD);
|
||||
}
|
||||
|
||||
|
||||
static enum mdocargt
|
||||
argv_a2arg(enum mdoct tok, const char *p)
|
||||
{
|
||||
|
||||
/*
|
||||
* Parse an argument identifier from its text. XXX - this
|
||||
* should really be table-driven to clarify the code.
|
||||
*
|
||||
* If you add an argument to the list, make sure that you
|
||||
* register it here with its one or more macros!
|
||||
*/
|
||||
|
||||
switch (tok) {
|
||||
case (MDOC_An):
|
||||
if (0 == strcmp(p, "split"))
|
||||
return(MDOC_Split);
|
||||
else if (0 == strcmp(p, "nosplit"))
|
||||
return(MDOC_Nosplit);
|
||||
break;
|
||||
|
||||
case (MDOC_Bd):
|
||||
if (0 == strcmp(p, "ragged"))
|
||||
return(MDOC_Ragged);
|
||||
else if (0 == strcmp(p, "unfilled"))
|
||||
return(MDOC_Unfilled);
|
||||
else if (0 == strcmp(p, "filled"))
|
||||
return(MDOC_Filled);
|
||||
else if (0 == strcmp(p, "literal"))
|
||||
return(MDOC_Literal);
|
||||
else if (0 == strcmp(p, "file"))
|
||||
return(MDOC_File);
|
||||
else if (0 == strcmp(p, "offset"))
|
||||
return(MDOC_Offset);
|
||||
else if (0 == strcmp(p, "compact"))
|
||||
return(MDOC_Compact);
|
||||
else if (0 == strcmp(p, "centered"))
|
||||
return(MDOC_Centred);
|
||||
break;
|
||||
|
||||
case (MDOC_Bf):
|
||||
if (0 == strcmp(p, "emphasis"))
|
||||
return(MDOC_Emphasis);
|
||||
else if (0 == strcmp(p, "literal"))
|
||||
return(MDOC_Literal);
|
||||
else if (0 == strcmp(p, "symbolic"))
|
||||
return(MDOC_Symbolic);
|
||||
break;
|
||||
|
||||
case (MDOC_Bk):
|
||||
if (0 == strcmp(p, "words"))
|
||||
return(MDOC_Words);
|
||||
break;
|
||||
|
||||
case (MDOC_Bl):
|
||||
if (0 == strcmp(p, "bullet"))
|
||||
return(MDOC_Bullet);
|
||||
else if (0 == strcmp(p, "dash"))
|
||||
return(MDOC_Dash);
|
||||
else if (0 == strcmp(p, "hyphen"))
|
||||
return(MDOC_Hyphen);
|
||||
else if (0 == strcmp(p, "item"))
|
||||
return(MDOC_Item);
|
||||
else if (0 == strcmp(p, "enum"))
|
||||
return(MDOC_Enum);
|
||||
else if (0 == strcmp(p, "tag"))
|
||||
return(MDOC_Tag);
|
||||
else if (0 == strcmp(p, "diag"))
|
||||
return(MDOC_Diag);
|
||||
else if (0 == strcmp(p, "hang"))
|
||||
return(MDOC_Hang);
|
||||
else if (0 == strcmp(p, "ohang"))
|
||||
return(MDOC_Ohang);
|
||||
else if (0 == strcmp(p, "inset"))
|
||||
return(MDOC_Inset);
|
||||
else if (0 == strcmp(p, "column"))
|
||||
return(MDOC_Column);
|
||||
else if (0 == strcmp(p, "width"))
|
||||
return(MDOC_Width);
|
||||
else if (0 == strcmp(p, "offset"))
|
||||
return(MDOC_Offset);
|
||||
else if (0 == strcmp(p, "compact"))
|
||||
return(MDOC_Compact);
|
||||
else if (0 == strcmp(p, "nested"))
|
||||
return(MDOC_Nested);
|
||||
break;
|
||||
|
||||
case (MDOC_Rv):
|
||||
/* FALLTHROUGH */
|
||||
case (MDOC_Ex):
|
||||
if (0 == strcmp(p, "std"))
|
||||
return(MDOC_Std);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(MDOC_ARG_MAX);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
argv_multi(struct mdoc *m, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
enum margserr ac;
|
||||
char *p;
|
||||
|
||||
for (v->sz = 0; ; v->sz++) {
|
||||
if ('-' == buf[*pos])
|
||||
break;
|
||||
ac = args(m, line, pos, buf, 0, &p);
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
else if (ARGS_EOLN == ac)
|
||||
break;
|
||||
|
||||
if (0 == v->sz % MULTI_STEP)
|
||||
v->value = mandoc_realloc(v->value,
|
||||
(v->sz + MULTI_STEP) * sizeof(char *));
|
||||
|
||||
v->value[(int)v->sz] = mandoc_strdup(p);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
argv_opt_single(struct mdoc *m, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
enum margserr ac;
|
||||
char *p;
|
||||
|
||||
if ('-' == buf[*pos])
|
||||
return(1);
|
||||
|
||||
ac = args(m, line, pos, buf, 0, &p);
|
||||
if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
if (ARGS_EOLN == ac)
|
||||
return(1);
|
||||
|
||||
v->sz = 1;
|
||||
v->value = mandoc_malloc(sizeof(char *));
|
||||
v->value[0] = mandoc_strdup(p);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse a single, mandatory value from the stream.
|
||||
*/
|
||||
static int
|
||||
argv_single(struct mdoc *m, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
int ppos;
|
||||
enum margserr ac;
|
||||
char *p;
|
||||
|
||||
ppos = *pos;
|
||||
|
||||
ac = args(m, line, pos, buf, 0, &p);
|
||||
if (ARGS_EOLN == ac) {
|
||||
mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTARGVCOUNT);
|
||||
return(0);
|
||||
} else if (ARGS_ERROR == ac)
|
||||
return(0);
|
||||
|
||||
v->sz = 1;
|
||||
v->value = mandoc_malloc(sizeof(char *));
|
||||
v->value[0] = mandoc_strdup(p);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine rules for parsing arguments. Arguments can either accept
|
||||
* no parameters, an optional single parameter, one parameter, or
|
||||
* multiple parameters.
|
||||
*/
|
||||
static int
|
||||
argv(struct mdoc *mdoc, int line,
|
||||
struct mdoc_argv *v, int *pos, char *buf)
|
||||
{
|
||||
|
||||
v->sz = 0;
|
||||
v->value = NULL;
|
||||
|
||||
switch (mdoc_argvflags[v->arg]) {
|
||||
case (ARGV_SINGLE):
|
||||
return(argv_single(mdoc, line, v, pos, buf));
|
||||
case (ARGV_MULTI):
|
||||
return(argv_multi(mdoc, line, v, pos, buf));
|
||||
case (ARGV_OPT_SINGLE):
|
||||
return(argv_opt_single(mdoc, line, v, pos, buf));
|
||||
default:
|
||||
/* ARGV_NONE */
|
||||
break;
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
93
usr.bin/mdocml/dist/mdoc_hash.c
vendored
93
usr.bin/mdocml/dist/mdoc_hash.c
vendored
@@ -1,93 +0,0 @@
|
||||
/* $Vendor-Id: mdoc_hash.c,v 1.16 2010/06/19 20:46:28 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#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 "libmdoc.h"
|
||||
|
||||
static u_char table[27 * 12];
|
||||
|
||||
/*
|
||||
* XXX - this hash has global scope, so if intended for use as a library
|
||||
* with multiple callers, it will need re-invocation protection.
|
||||
*/
|
||||
void
|
||||
mdoc_hash_init(void)
|
||||
{
|
||||
int i, j, major;
|
||||
const char *p;
|
||||
|
||||
memset(table, UCHAR_MAX, sizeof(table));
|
||||
|
||||
for (i = 0; i < (int)MDOC_MAX; i++) {
|
||||
p = mdoc_macronames[i];
|
||||
|
||||
if (isalpha((u_char)p[1]))
|
||||
major = 12 * (tolower((u_char)p[1]) - 97);
|
||||
else
|
||||
major = 12 * 26;
|
||||
|
||||
for (j = 0; j < 12; j++)
|
||||
if (UCHAR_MAX == table[major + j]) {
|
||||
table[major + j] = (u_char)i;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(j < 12);
|
||||
}
|
||||
}
|
||||
|
||||
enum mdoct
|
||||
mdoc_hash_find(const char *p)
|
||||
{
|
||||
int major, i, j;
|
||||
|
||||
if (0 == p[0])
|
||||
return(MDOC_MAX);
|
||||
if ( ! isalpha((u_char)p[0]) && '%' != p[0])
|
||||
return(MDOC_MAX);
|
||||
|
||||
if (isalpha((u_char)p[1]))
|
||||
major = 12 * (tolower((u_char)p[1]) - 97);
|
||||
else if ('1' == p[1])
|
||||
major = 12 * 26;
|
||||
else
|
||||
return(MDOC_MAX);
|
||||
|
||||
if (p[2] && p[3])
|
||||
return(MDOC_MAX);
|
||||
|
||||
for (j = 0; j < 12; j++) {
|
||||
if (UCHAR_MAX == (i = table[major + j]))
|
||||
break;
|
||||
if (0 == strcmp(p, mdoc_macronames[i]))
|
||||
return((enum mdoct)i);
|
||||
}
|
||||
|
||||
return(MDOC_MAX);
|
||||
}
|
||||
2139
usr.bin/mdocml/dist/mdoc_html.c
vendored
2139
usr.bin/mdocml/dist/mdoc_html.c
vendored
File diff suppressed because it is too large
Load Diff
1753
usr.bin/mdocml/dist/mdoc_macro.c
vendored
1753
usr.bin/mdocml/dist/mdoc_macro.c
vendored
File diff suppressed because it is too large
Load Diff
219
usr.bin/mdocml/dist/mdoc_strings.c
vendored
219
usr.bin/mdocml/dist/mdoc_strings.c
vendored
@@ -1,219 +0,0 @@
|
||||
/* $Vendor-Id: mdoc_strings.c,v 1.24 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
static const char * const secnames[SEC__MAX] = {
|
||||
NULL,
|
||||
"NAME",
|
||||
"LIBRARY",
|
||||
"SYNOPSIS",
|
||||
"DESCRIPTION",
|
||||
"IMPLEMENTATION NOTES",
|
||||
"RETURN VALUES",
|
||||
"ENVIRONMENT",
|
||||
"FILES",
|
||||
"EXIT STATUS",
|
||||
"EXAMPLES",
|
||||
"DIAGNOSTICS",
|
||||
"COMPATIBILITY",
|
||||
"ERRORS",
|
||||
"SEE ALSO",
|
||||
"STANDARDS",
|
||||
"HISTORY",
|
||||
"AUTHORS",
|
||||
"CAVEATS",
|
||||
"BUGS",
|
||||
"SECURITY CONSIDERATIONS",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME: this is repeated in print_text() (html.c) and term_word()
|
||||
* (term.c).
|
||||
*/
|
||||
enum mdelim
|
||||
mdoc_iscdelim(char p)
|
||||
{
|
||||
|
||||
switch (p) {
|
||||
case('('):
|
||||
/* FALLTHROUGH */
|
||||
case('['):
|
||||
return(DELIM_OPEN);
|
||||
case('|'):
|
||||
return(DELIM_MIDDLE);
|
||||
case('.'):
|
||||
/* FALLTHROUGH */
|
||||
case(','):
|
||||
/* FALLTHROUGH */
|
||||
case(';'):
|
||||
/* FALLTHROUGH */
|
||||
case(':'):
|
||||
/* FALLTHROUGH */
|
||||
case('?'):
|
||||
/* FALLTHROUGH */
|
||||
case('!'):
|
||||
/* FALLTHROUGH */
|
||||
case(')'):
|
||||
/* FALLTHROUGH */
|
||||
case(']'):
|
||||
return(DELIM_CLOSE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(DELIM_NONE);
|
||||
}
|
||||
|
||||
|
||||
enum mdelim
|
||||
mdoc_isdelim(const char *p)
|
||||
{
|
||||
|
||||
if ('\0' == p[0])
|
||||
return(DELIM_NONE);
|
||||
if ('\0' == p[1])
|
||||
return(mdoc_iscdelim(p[0]));
|
||||
|
||||
/*
|
||||
* XXX; account for groff bubu where the \*(Ba reserved string
|
||||
* is treated in exactly the same way as the vertical bar. This
|
||||
* is the only function that checks for this.
|
||||
*/
|
||||
return(strcmp(p, "\\*(Ba") ? DELIM_NONE : DELIM_MIDDLE);
|
||||
}
|
||||
|
||||
|
||||
enum mdoc_sec
|
||||
mdoc_str2sec(const char *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (int)SEC__MAX; i++)
|
||||
if (secnames[i] && 0 == strcmp(p, secnames[i]))
|
||||
return((enum mdoc_sec)i);
|
||||
|
||||
return(SEC_CUSTOM);
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: move this into an editable .in file. */
|
||||
size_t
|
||||
mdoc_macro2len(enum mdoct macro)
|
||||
{
|
||||
|
||||
switch (macro) {
|
||||
case(MDOC_Ad):
|
||||
return(12);
|
||||
case(MDOC_Ao):
|
||||
return(12);
|
||||
case(MDOC_An):
|
||||
return(12);
|
||||
case(MDOC_Aq):
|
||||
return(12);
|
||||
case(MDOC_Ar):
|
||||
return(12);
|
||||
case(MDOC_Bo):
|
||||
return(12);
|
||||
case(MDOC_Bq):
|
||||
return(12);
|
||||
case(MDOC_Cd):
|
||||
return(12);
|
||||
case(MDOC_Cm):
|
||||
return(10);
|
||||
case(MDOC_Do):
|
||||
return(10);
|
||||
case(MDOC_Dq):
|
||||
return(12);
|
||||
case(MDOC_Dv):
|
||||
return(12);
|
||||
case(MDOC_Eo):
|
||||
return(12);
|
||||
case(MDOC_Em):
|
||||
return(10);
|
||||
case(MDOC_Er):
|
||||
return(17);
|
||||
case(MDOC_Ev):
|
||||
return(15);
|
||||
case(MDOC_Fa):
|
||||
return(12);
|
||||
case(MDOC_Fl):
|
||||
return(10);
|
||||
case(MDOC_Fo):
|
||||
return(16);
|
||||
case(MDOC_Fn):
|
||||
return(16);
|
||||
case(MDOC_Ic):
|
||||
return(10);
|
||||
case(MDOC_Li):
|
||||
return(16);
|
||||
case(MDOC_Ms):
|
||||
return(6);
|
||||
case(MDOC_Nm):
|
||||
return(10);
|
||||
case(MDOC_No):
|
||||
return(12);
|
||||
case(MDOC_Oo):
|
||||
return(10);
|
||||
case(MDOC_Op):
|
||||
return(14);
|
||||
case(MDOC_Pa):
|
||||
return(32);
|
||||
case(MDOC_Pf):
|
||||
return(12);
|
||||
case(MDOC_Po):
|
||||
return(12);
|
||||
case(MDOC_Pq):
|
||||
return(12);
|
||||
case(MDOC_Ql):
|
||||
return(16);
|
||||
case(MDOC_Qo):
|
||||
return(12);
|
||||
case(MDOC_So):
|
||||
return(12);
|
||||
case(MDOC_Sq):
|
||||
return(12);
|
||||
case(MDOC_Sy):
|
||||
return(6);
|
||||
case(MDOC_Sx):
|
||||
return(16);
|
||||
case(MDOC_Tn):
|
||||
return(10);
|
||||
case(MDOC_Va):
|
||||
return(12);
|
||||
case(MDOC_Vt):
|
||||
return(12);
|
||||
case(MDOC_Xr):
|
||||
return(10);
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return(0);
|
||||
}
|
||||
2200
usr.bin/mdocml/dist/mdoc_term.c
vendored
2200
usr.bin/mdocml/dist/mdoc_term.c
vendored
File diff suppressed because it is too large
Load Diff
2239
usr.bin/mdocml/dist/mdoc_validate.c
vendored
2239
usr.bin/mdocml/dist/mdoc_validate.c
vendored
File diff suppressed because it is too large
Load Diff
37
usr.bin/mdocml/dist/msec.c
vendored
37
usr.bin/mdocml/dist/msec.c
vendored
@@ -1,37 +0,0 @@
|
||||
/* $Vendor-Id: msec.c,v 1.8 2010/05/17 22:11:42 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
if (0 == strcmp(p, x)) return(y);
|
||||
|
||||
const char *
|
||||
mdoc_a2msec(const char *p)
|
||||
{
|
||||
|
||||
#include "msec.in"
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
40
usr.bin/mdocml/dist/msec.in
vendored
40
usr.bin/mdocml/dist/msec.in
vendored
@@ -1,40 +0,0 @@
|
||||
/* $Vendor-Id: msec.in,v 1.6 2010/06/19 20:46:28 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These are all possible manual-section macros and what they correspond
|
||||
* to when rendered as the volume title.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
*/
|
||||
|
||||
LINE("1", "NetBSD General Commands Manual")
|
||||
LINE("2", "NetBSD System Calls Manual")
|
||||
LINE("3", "NetBSD Library Functions Manual")
|
||||
LINE("3p", "Perl Library Functions Manual")
|
||||
LINE("4", "NetBSD Kernel Interfaces Manual")
|
||||
LINE("5", "NetBSD File Formats Manual")
|
||||
LINE("6", "NetBSD Games Manual")
|
||||
LINE("7", "NetBSD Miscellaneous Information Manual")
|
||||
LINE("8", "NetBSD System Manager\'s Manual")
|
||||
LINE("9", "NetBSD Kernel Developer\'s Manual")
|
||||
LINE("X11", "X11 Developer\'s Manual")
|
||||
LINE("X11R6", "X11 Developer\'s Manual")
|
||||
LINE("unass", "Unassociated")
|
||||
LINE("local", "Local")
|
||||
LINE("draft", "Draft")
|
||||
LINE("paper", "Paper")
|
||||
562
usr.bin/mdocml/dist/out.c
vendored
562
usr.bin/mdocml/dist/out.c
vendored
@@ -1,562 +0,0 @@
|
||||
/* $Vendor-Id: out.c,v 1.30 2011/01/05 15:37:23 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
|
||||
static void tblcalc_data(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl *, const struct tbl_dat *);
|
||||
static void tblcalc_literal(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl_dat *);
|
||||
static void tblcalc_number(struct rofftbl *, struct roffcol *,
|
||||
const struct tbl *, const struct tbl_dat *);
|
||||
|
||||
/*
|
||||
* Convert a `scaling unit' to a consistent form, or fail. Scaling
|
||||
* units are documented in groff.7, mdoc.7, man.7.
|
||||
*/
|
||||
int
|
||||
a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
|
||||
{
|
||||
char buf[BUFSIZ], hasd;
|
||||
int i;
|
||||
enum roffscale unit;
|
||||
|
||||
if ('\0' == *src)
|
||||
return(0);
|
||||
|
||||
i = hasd = 0;
|
||||
|
||||
switch (*src) {
|
||||
case ('+'):
|
||||
src++;
|
||||
break;
|
||||
case ('-'):
|
||||
buf[i++] = *src++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ('\0' == *src)
|
||||
return(0);
|
||||
|
||||
while (i < BUFSIZ) {
|
||||
if ( ! isdigit((u_char)*src)) {
|
||||
if ('.' != *src)
|
||||
break;
|
||||
else if (hasd)
|
||||
break;
|
||||
else
|
||||
hasd = 1;
|
||||
}
|
||||
buf[i++] = *src++;
|
||||
}
|
||||
|
||||
if (BUFSIZ == i || (*src && *(src + 1)))
|
||||
return(0);
|
||||
|
||||
buf[i] = '\0';
|
||||
|
||||
switch (*src) {
|
||||
case ('c'):
|
||||
unit = SCALE_CM;
|
||||
break;
|
||||
case ('i'):
|
||||
unit = SCALE_IN;
|
||||
break;
|
||||
case ('P'):
|
||||
unit = SCALE_PC;
|
||||
break;
|
||||
case ('p'):
|
||||
unit = SCALE_PT;
|
||||
break;
|
||||
case ('f'):
|
||||
unit = SCALE_FS;
|
||||
break;
|
||||
case ('v'):
|
||||
unit = SCALE_VS;
|
||||
break;
|
||||
case ('m'):
|
||||
unit = SCALE_EM;
|
||||
break;
|
||||
case ('\0'):
|
||||
if (SCALE_MAX == def)
|
||||
return(0);
|
||||
unit = SCALE_BU;
|
||||
break;
|
||||
case ('u'):
|
||||
unit = SCALE_BU;
|
||||
break;
|
||||
case ('M'):
|
||||
unit = SCALE_MM;
|
||||
break;
|
||||
case ('n'):
|
||||
unit = SCALE_EN;
|
||||
break;
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* FIXME: do this in the caller. */
|
||||
if ((dst->scale = atof(buf)) < 0)
|
||||
dst->scale = 0;
|
||||
dst->unit = unit;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Correctly writes the time in nroff form, which differs from standard
|
||||
* form in that a space isn't printed in lieu of the extra %e field for
|
||||
* single-digit dates.
|
||||
*/
|
||||
void
|
||||
time2a(time_t t, char *dst, size_t sz)
|
||||
{
|
||||
struct tm tm;
|
||||
char buf[5];
|
||||
char *p;
|
||||
size_t nsz;
|
||||
|
||||
assert(sz > 1);
|
||||
localtime_r(&t, &tm);
|
||||
|
||||
p = dst;
|
||||
nsz = 0;
|
||||
|
||||
dst[0] = '\0';
|
||||
|
||||
if (0 == (nsz = strftime(p, sz, "%B ", &tm)))
|
||||
return;
|
||||
|
||||
p += (int)nsz;
|
||||
sz -= nsz;
|
||||
|
||||
if (0 == strftime(buf, sizeof(buf), "%e, ", &tm))
|
||||
return;
|
||||
|
||||
nsz = strlcat(p, buf + (' ' == buf[0] ? 1 : 0), sz);
|
||||
|
||||
if (nsz >= sz)
|
||||
return;
|
||||
|
||||
p += (int)nsz;
|
||||
sz -= nsz;
|
||||
|
||||
(void)strftime(p, sz, "%Y", &tm);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
a2roffdeco(enum roffdeco *d, const char **word, size_t *sz)
|
||||
{
|
||||
int i, j, lim;
|
||||
char term, c;
|
||||
const char *wp;
|
||||
enum roffdeco dd;
|
||||
|
||||
*d = DECO_NONE;
|
||||
lim = i = 0;
|
||||
term = '\0';
|
||||
wp = *word;
|
||||
|
||||
switch ((c = wp[i++])) {
|
||||
case ('('):
|
||||
*d = DECO_SPECIAL;
|
||||
lim = 2;
|
||||
break;
|
||||
case ('F'):
|
||||
/* FALLTHROUGH */
|
||||
case ('f'):
|
||||
*d = 'F' == c ? DECO_FFONT : DECO_FONT;
|
||||
|
||||
switch (wp[i++]) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
case ('3'):
|
||||
/* FALLTHROUGH */
|
||||
case ('B'):
|
||||
*d = DECO_BOLD;
|
||||
return(i);
|
||||
case ('2'):
|
||||
/* FALLTHROUGH */
|
||||
case ('I'):
|
||||
*d = DECO_ITALIC;
|
||||
return(i);
|
||||
case ('P'):
|
||||
*d = DECO_PREVIOUS;
|
||||
return(i);
|
||||
case ('1'):
|
||||
/* FALLTHROUGH */
|
||||
case ('R'):
|
||||
*d = DECO_ROMAN;
|
||||
return(i);
|
||||
default:
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ('k'):
|
||||
/* FALLTHROUGH */
|
||||
case ('M'):
|
||||
/* FALLTHROUGH */
|
||||
case ('m'):
|
||||
/* FALLTHROUGH */
|
||||
case ('*'):
|
||||
if ('*' == c)
|
||||
*d = DECO_RESERVED;
|
||||
|
||||
switch (wp[i++]) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
default:
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ('h'):
|
||||
/* FALLTHROUGH */
|
||||
case ('v'):
|
||||
/* FALLTHROUGH */
|
||||
case ('s'):
|
||||
j = 0;
|
||||
if ('+' == wp[i] || '-' == wp[i]) {
|
||||
i++;
|
||||
j = 1;
|
||||
}
|
||||
|
||||
switch (wp[i++]) {
|
||||
case ('('):
|
||||
lim = 2;
|
||||
break;
|
||||
case ('['):
|
||||
term = ']';
|
||||
break;
|
||||
case ('\''):
|
||||
term = '\'';
|
||||
break;
|
||||
case ('0'):
|
||||
j = 1;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ('+' == wp[i] || '-' == wp[i]) {
|
||||
if (j)
|
||||
return(i);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Handle embedded numerical subexp or escape. */
|
||||
|
||||
if ('(' == wp[i]) {
|
||||
while (wp[i] && ')' != wp[i])
|
||||
if ('\\' == wp[i++]) {
|
||||
/* Handle embedded escape. */
|
||||
*word = &wp[i];
|
||||
i += a2roffdeco(&dd, word, sz);
|
||||
}
|
||||
|
||||
if (')' == wp[i++])
|
||||
break;
|
||||
|
||||
*d = DECO_NONE;
|
||||
return(i - 1);
|
||||
} else if ('\\' == wp[i]) {
|
||||
*word = &wp[++i];
|
||||
i += a2roffdeco(&dd, word, sz);
|
||||
}
|
||||
|
||||
break;
|
||||
case ('['):
|
||||
*d = DECO_SPECIAL;
|
||||
term = ']';
|
||||
break;
|
||||
case ('c'):
|
||||
*d = DECO_NOSPACE;
|
||||
return(i);
|
||||
case ('z'):
|
||||
*d = DECO_NONE;
|
||||
if ('\\' == wp[i]) {
|
||||
*word = &wp[++i];
|
||||
return(i + a2roffdeco(&dd, word, sz));
|
||||
} else
|
||||
lim = 1;
|
||||
break;
|
||||
case ('o'):
|
||||
/* FALLTHROUGH */
|
||||
case ('w'):
|
||||
if ('\'' == wp[i++]) {
|
||||
term = '\'';
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
*d = DECO_SSPECIAL;
|
||||
i--;
|
||||
lim = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(term || lim);
|
||||
*word = &wp[i];
|
||||
|
||||
if (term) {
|
||||
j = i;
|
||||
while (wp[i] && wp[i] != term)
|
||||
i++;
|
||||
if ('\0' == wp[i]) {
|
||||
*d = DECO_NONE;
|
||||
return(i);
|
||||
}
|
||||
|
||||
assert(i >= j);
|
||||
*sz = (size_t)(i - j);
|
||||
|
||||
return(i + 1);
|
||||
}
|
||||
|
||||
assert(lim > 0);
|
||||
*sz = (size_t)lim;
|
||||
|
||||
for (j = 0; wp[i] && j < lim; j++)
|
||||
i++;
|
||||
if (j < lim)
|
||||
*d = DECO_NONE;
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the abstract widths and decimal positions of columns in a
|
||||
* table. This routine allocates the columns structures then runs over
|
||||
* all rows and cells in the table. The function pointers in "tbl" are
|
||||
* used for the actual width calculations.
|
||||
*/
|
||||
void
|
||||
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_dat *dp;
|
||||
const struct tbl_head *hp;
|
||||
struct roffcol *col;
|
||||
|
||||
/*
|
||||
* Allocate the master column specifiers. These will hold the
|
||||
* widths and decimal positions for all cells in the column. It
|
||||
* must be freed and nullified by the caller.
|
||||
*/
|
||||
|
||||
assert(NULL == tbl->cols);
|
||||
tbl->cols = calloc(sp->tbl->cols, sizeof(struct roffcol));
|
||||
|
||||
hp = sp->head;
|
||||
|
||||
for ( ; sp; sp = sp->next) {
|
||||
if (TBL_SPAN_DATA != sp->pos)
|
||||
continue;
|
||||
/*
|
||||
* Account for the data cells in the layout, matching it
|
||||
* to data cells in the data section.
|
||||
*/
|
||||
for (dp = sp->first; dp; dp = dp->next) {
|
||||
if (NULL == dp->layout)
|
||||
continue;
|
||||
col = &tbl->cols[dp->layout->head->ident];
|
||||
tblcalc_data(tbl, col, sp->tbl, dp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate width of the spanners. These get one space for a
|
||||
* vertical line, two for a double-vertical line.
|
||||
*/
|
||||
|
||||
for ( ; hp; hp = hp->next) {
|
||||
col = &tbl->cols[hp->ident];
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
col->width = (*tbl->len)(1, tbl->arg);
|
||||
break;
|
||||
case (TBL_HEAD_DVERT):
|
||||
col->width = (*tbl->len)(2, tbl->arg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl *tp, const struct tbl_dat *dp)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
/* Branch down into data sub-types. */
|
||||
|
||||
switch (dp->layout->pos) {
|
||||
case (TBL_CELL_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_DHORIZ):
|
||||
sz = (*tbl->len)(1, tbl->arg);
|
||||
if (col->width < sz)
|
||||
col->width = sz;
|
||||
break;
|
||||
case (TBL_CELL_LONG):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_CENTRE):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_LEFT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_RIGHT):
|
||||
tblcalc_literal(tbl, col, dp);
|
||||
break;
|
||||
case (TBL_CELL_NUMBER):
|
||||
tblcalc_number(tbl, col, tp, dp);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl_dat *dp)
|
||||
{
|
||||
size_t sz, bufsz, spsz;
|
||||
|
||||
/*
|
||||
* Calculate our width and use the spacing, with a minimum
|
||||
* spacing dictated by position (centre, e.g,. gets a space on
|
||||
* either side, while right/left get a single adjacent space).
|
||||
*/
|
||||
|
||||
sz = bufsz = spsz = 0;
|
||||
if (dp->string)
|
||||
sz = (*tbl->slen)(dp->string, tbl->arg);
|
||||
|
||||
assert(dp->layout);
|
||||
switch (dp->layout->pos) {
|
||||
case (TBL_CELL_LONG):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_CENTRE):
|
||||
bufsz = (*tbl->len)(2, tbl->arg);
|
||||
break;
|
||||
default:
|
||||
bufsz = (*tbl->len)(1, tbl->arg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dp->layout->spacing) {
|
||||
spsz = (*tbl->len)(dp->layout->spacing, tbl->arg);
|
||||
bufsz = bufsz > spsz ? bufsz : spsz;
|
||||
}
|
||||
|
||||
sz += bufsz;
|
||||
if (col->width < sz)
|
||||
col->width = sz;
|
||||
}
|
||||
|
||||
static void
|
||||
tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
|
||||
const struct tbl *tp, const struct tbl_dat *dp)
|
||||
{
|
||||
int i;
|
||||
size_t sz, psz, ssz, d;
|
||||
char *cp;
|
||||
const char *str;
|
||||
char buf[2];
|
||||
|
||||
/* TODO: use spacing modifier. */
|
||||
|
||||
/*
|
||||
* First calculate number width and decimal place (last + 1 for
|
||||
* no-decimal numbers). If the stored decimal is subsequent
|
||||
* ours, make our size longer by that difference
|
||||
* (right-"shifting"); similarly, if ours is subsequent the
|
||||
* stored, then extend the stored size by the difference.
|
||||
* Finally, re-assign the stored values.
|
||||
*/
|
||||
|
||||
str = "";
|
||||
if (dp->string)
|
||||
str = dp->string;
|
||||
|
||||
sz = (*tbl->slen)(str, tbl->arg);
|
||||
|
||||
buf[0] = tp->decimal;
|
||||
buf[1] = '\0';
|
||||
|
||||
psz = (*tbl->slen)(buf, tbl->arg);
|
||||
|
||||
if (NULL != (cp = strchr(str, tp->decimal))) {
|
||||
buf[1] = '\0';
|
||||
for (ssz = 0, i = 0; cp != &str[i]; i++) {
|
||||
buf[0] = str[i];
|
||||
ssz += (*tbl->slen)(buf, tbl->arg);
|
||||
}
|
||||
d = ssz + psz;
|
||||
} else
|
||||
d = sz + psz;
|
||||
|
||||
/* Padding. */
|
||||
|
||||
sz += (*tbl->len)(2, tbl->arg);
|
||||
d += (*tbl->len)(1, tbl->arg);
|
||||
|
||||
/* Adjust the settings for this column. */
|
||||
|
||||
if (col->decimal > d) {
|
||||
sz += col->decimal - d;
|
||||
d = col->decimal;
|
||||
} else
|
||||
col->width += d - col->decimal;
|
||||
|
||||
if (sz > col->width)
|
||||
col->width = sz;
|
||||
if (d > col->decimal)
|
||||
col->decimal = d;
|
||||
}
|
||||
|
||||
|
||||
90
usr.bin/mdocml/dist/out.h
vendored
90
usr.bin/mdocml/dist/out.h
vendored
@@ -1,90 +0,0 @@
|
||||
/* $Vendor-Id: out.h,v 1.15 2011/01/05 15:37:23 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef OUT_H
|
||||
#define OUT_H
|
||||
|
||||
#define DATESIZ 24
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct roffcol {
|
||||
size_t width; /* width of cell */
|
||||
size_t decimal; /* decimal position in cell */
|
||||
};
|
||||
|
||||
typedef size_t (*tbl_strlen)(const char *, void *);
|
||||
typedef size_t (*tbl_len)(size_t, void *);
|
||||
|
||||
struct rofftbl {
|
||||
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 */
|
||||
};
|
||||
|
||||
enum roffscale {
|
||||
SCALE_CM,
|
||||
SCALE_IN,
|
||||
SCALE_PC,
|
||||
SCALE_PT,
|
||||
SCALE_EM,
|
||||
SCALE_MM,
|
||||
SCALE_EN,
|
||||
SCALE_BU,
|
||||
SCALE_VS,
|
||||
SCALE_FS,
|
||||
SCALE_MAX
|
||||
};
|
||||
|
||||
enum roffdeco {
|
||||
DECO_NONE,
|
||||
DECO_SPECIAL, /* special character */
|
||||
DECO_SSPECIAL, /* single-char special */
|
||||
DECO_RESERVED, /* reserved word */
|
||||
DECO_BOLD, /* bold font */
|
||||
DECO_ITALIC, /* italic font */
|
||||
DECO_ROMAN, /* "normal" undecorated font */
|
||||
DECO_PREVIOUS, /* revert to previous font */
|
||||
DECO_NOSPACE, /* suppress spacing */
|
||||
DECO_FONT, /* font */
|
||||
DECO_FFONT, /* font family */
|
||||
DECO_MAX
|
||||
};
|
||||
|
||||
struct roffsu {
|
||||
enum roffscale unit;
|
||||
double scale;
|
||||
};
|
||||
|
||||
#define SCALE_VS_INIT(p, v) \
|
||||
do { (p)->unit = SCALE_VS; \
|
||||
(p)->scale = (v); } \
|
||||
while (/* CONSTCOND */ 0)
|
||||
|
||||
#define SCALE_HS_INIT(p, v) \
|
||||
do { (p)->unit = SCALE_BU; \
|
||||
(p)->scale = (v); } \
|
||||
while (/* CONSTCOND */ 0)
|
||||
|
||||
int a2roffsu(const char *, struct roffsu *, enum roffscale);
|
||||
int a2roffdeco(enum roffdeco *, const char **, size_t *);
|
||||
void time2a(time_t, char *, size_t);
|
||||
void tblcalc(struct rofftbl *tbl, const struct tbl_span *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!OUT_H*/
|
||||
177
usr.bin/mdocml/dist/roff.3
vendored
177
usr.bin/mdocml/dist/roff.3
vendored
@@ -1,177 +0,0 @@
|
||||
.\" $Vendor-Id: roff.3,v 1.10 2011/01/01 16:18:39 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 1, 2011
|
||||
.Dt ROFF 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm roff ,
|
||||
.Nm roff_alloc ,
|
||||
.Nm roff_endparse ,
|
||||
.Nm roff_free ,
|
||||
.Nm roff_parseln ,
|
||||
.Nm roff_reset ,
|
||||
.Nm roff_span
|
||||
.Nd roff macro compiler library
|
||||
.Sh SYNOPSIS
|
||||
.In mandoc.h
|
||||
.In roff.h
|
||||
.Ft "struct roff *"
|
||||
.Fo roff_alloc
|
||||
.Fa "struct regset *regs"
|
||||
.Fa "void *data"
|
||||
.Fa "mandocmsg msgs"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn roff_endparse "struct roff *roff"
|
||||
.Ft void
|
||||
.Fn roff_free "struct roff *roff"
|
||||
.Ft "enum rofferr"
|
||||
.Fo roff_parseln
|
||||
.Fa "struct roff *roff"
|
||||
.Fa "int line"
|
||||
.Fa "char **bufp"
|
||||
.Fa "size_t *bufsz"
|
||||
.Fa "int pos"
|
||||
.Fa "int *offs"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn roff_reset "struct roff *roff"
|
||||
.Ft "const struct tbl_span *"
|
||||
.Fn roff_span "const struct roff *roff"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
library processes lines of
|
||||
.Xr roff 7
|
||||
input.
|
||||
.Pp
|
||||
In general, applications initiate a parsing sequence with
|
||||
.Fn roff_alloc ,
|
||||
parse each line in a document with
|
||||
.Fn roff_parseln ,
|
||||
close the parsing session with
|
||||
.Fn roff_endparse ,
|
||||
and finally free all allocated memory with
|
||||
.Fn roff_free .
|
||||
The
|
||||
.Fn roff_reset
|
||||
function may be used in order to reset the parser for another input
|
||||
sequence.
|
||||
.Pp
|
||||
The
|
||||
.Fn roff_parseln
|
||||
function should be invoked before passing a line into the
|
||||
.Xr mdoc 3
|
||||
or
|
||||
.Xr man 3
|
||||
libraries.
|
||||
.Pp
|
||||
See the
|
||||
.Sx EXAMPLES
|
||||
section for a full example.
|
||||
.Sh REFERENCE
|
||||
This section further defines the
|
||||
.Sx Types
|
||||
and
|
||||
.Sx Functions
|
||||
available to programmers.
|
||||
.Ss Types
|
||||
Functions (see
|
||||
.Sx Functions )
|
||||
may use the following types:
|
||||
.Bl -ohang
|
||||
.It Vt "enum rofferr"
|
||||
Instructions for further processing to the caller of
|
||||
.Fn roff_parseln .
|
||||
.It Vt struct roff
|
||||
An opaque type defined in
|
||||
.Pa roff.c .
|
||||
Its values are only used privately within the library.
|
||||
.It Vt mandocmsg
|
||||
A function callback type defined in
|
||||
.Pa mandoc.h .
|
||||
.El
|
||||
.Ss Functions
|
||||
Function descriptions follow:
|
||||
.Bl -ohang
|
||||
.It Fn roff_alloc
|
||||
Allocates a parsing structure.
|
||||
The
|
||||
.Fa data
|
||||
pointer is passed to
|
||||
.Fa msgs .
|
||||
Returns NULL on failure.
|
||||
If non-NULL, the pointer must be freed with
|
||||
.Fn roff_free .
|
||||
.It Fn roff_reset
|
||||
Reset the parser for another parse routine.
|
||||
After its use,
|
||||
.Fn roff_parseln
|
||||
behaves as if invoked for the first time.
|
||||
.It Fn roff_free
|
||||
Free all resources of a parser.
|
||||
The pointer is no longer valid after invocation.
|
||||
.It Fn roff_parseln
|
||||
Parse a nil-terminated line of input.
|
||||
The character array
|
||||
.Fa bufp
|
||||
may be modified or reallocated within this function.
|
||||
In the latter case,
|
||||
.Fa bufsz
|
||||
will be modified accordingly.
|
||||
The
|
||||
.Fa offs
|
||||
pointer will be modified if the line start during subsequent processing
|
||||
of the line is not at the zeroth index.
|
||||
This line should not contain the trailing newline.
|
||||
Returns 0 on failure, 1 on success.
|
||||
.It Fn roff_endparse
|
||||
Signals that the parse is complete.
|
||||
.It Fn roff_span
|
||||
If
|
||||
.Fn roff_parseln
|
||||
returned
|
||||
.Va ROFF_TBL ,
|
||||
return the last parsed table row.
|
||||
Returns NULL otherwise.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
See
|
||||
.Pa main.c
|
||||
in the source distribution for an example of usage.
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 3 ,
|
||||
.Xr mdoc 3 ,
|
||||
.Xr roff 7
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
library was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
.Sh BUGS
|
||||
The implementation of user-defined strings needs improvement:
|
||||
.Bl -dash
|
||||
.It
|
||||
String values are taken literally and are not interpreted.
|
||||
.It
|
||||
Parsing of quoted strings is incomplete.
|
||||
.It
|
||||
The stings are stored internally using a singly linked list,
|
||||
which is fine for small numbers of strings,
|
||||
but ineffient when handling many strings.
|
||||
.El
|
||||
619
usr.bin/mdocml/dist/roff.7
vendored
619
usr.bin/mdocml/dist/roff.7
vendored
@@ -1,619 +0,0 @@
|
||||
.\" $Vendor-Id: roff.7,v 1.23 2011/01/04 23:32:21 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2010 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.
|
||||
.\"
|
||||
.Dd January 4, 2011
|
||||
.Dt ROFF 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm roff
|
||||
.Nd roff language reference for mandoc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm roff
|
||||
language is a general purpose text formatting language.
|
||||
In particular, it serves as the basis for the
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
manual formatting macro languages.
|
||||
This manual describes the subset of the
|
||||
.Nm
|
||||
language accepted by the
|
||||
.Xr mandoc 1
|
||||
utility.
|
||||
.Pp
|
||||
Input lines beginning with the control characters
|
||||
.Sq \&.
|
||||
or
|
||||
.Sq \(aq
|
||||
are parsed for requests and macros.
|
||||
These define the document structure, change the processing state
|
||||
and manipulate the formatting.
|
||||
Some requests and macros also produce formatted output,
|
||||
while others do not.
|
||||
.Pp
|
||||
All other input lines provide free-form text to be printed;
|
||||
the formatting of free-form text depends on the respective
|
||||
processing context.
|
||||
.Sh LANGUAGE SYNTAX
|
||||
.Nm
|
||||
documents may contain only graphable 7-bit ASCII characters, the space
|
||||
character, and, in certain circumstances, the tab character.
|
||||
To produce other characters in the output, use the escape sequences
|
||||
documented in the
|
||||
.Xr mandoc_char 7
|
||||
manual.
|
||||
.Pp
|
||||
All manuals must have
|
||||
.Ux
|
||||
line terminators.
|
||||
.Sh REQUEST SYNTAX
|
||||
A request or macro line consists of:
|
||||
.Pp
|
||||
.Bl -enum -compact
|
||||
.It
|
||||
the control character
|
||||
.Sq \&.
|
||||
or
|
||||
.Sq \(aq
|
||||
at the beginning of the line,
|
||||
.It
|
||||
optionally an arbitrary amount of whitespace,
|
||||
.It
|
||||
the name of the request or the macro, which is one word of arbitrary
|
||||
length, terminated by whitespace,
|
||||
.It
|
||||
and zero or more arguments delimited by whitespace.
|
||||
.El
|
||||
.Pp
|
||||
Thus, the following request lines are all equivalent:
|
||||
.Bd -literal -offset indent
|
||||
\&.ig end
|
||||
\&.ig end
|
||||
\&. ig end
|
||||
.Ed
|
||||
.Sh REQUEST REFERENCE
|
||||
The
|
||||
.Xr mandoc 1
|
||||
.Nm
|
||||
parser recognizes the following requests.
|
||||
Note that the
|
||||
.Nm
|
||||
language defines many more requests not implemented in
|
||||
.Xr mandoc 1 .
|
||||
.Ss \&ad
|
||||
Set line adjustment mode.
|
||||
This line-scoped request is intended to have one argument to select
|
||||
normal, left, right, or center adjustment for subsequent text.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
.Ss \&am
|
||||
Append to a macro definition.
|
||||
The syntax of this request is the same as that of
|
||||
.Sx \&de .
|
||||
It is currently ignored by
|
||||
.Xr mandoc 1 ,
|
||||
as are its children.
|
||||
.Ss \&ami
|
||||
Append to a macro definition, specifying the macro name indirectly.
|
||||
The syntax of this request is the same as that of
|
||||
.Sx \&dei .
|
||||
It is currently ignored by
|
||||
.Xr mandoc 1 ,
|
||||
as are its children.
|
||||
.Ss \&am1
|
||||
Append to a macro definition, switching roff compatibility mode off
|
||||
during macro execution.
|
||||
The syntax of this request is the same as that of
|
||||
.Sx \&de1 .
|
||||
It is currently ignored by
|
||||
.Xr mandoc 1 ,
|
||||
as are its children.
|
||||
.Ss \&de
|
||||
Define a
|
||||
.Nm
|
||||
macro.
|
||||
Its syntax can be either
|
||||
.Bd -literal -offset indent
|
||||
.Pf . Cm \&de Ar name
|
||||
.Ar macro definition
|
||||
\&..
|
||||
.Ed
|
||||
.Pp
|
||||
or
|
||||
.Bd -literal -offset indent
|
||||
.Pf . Cm \&de Ar name Ar end
|
||||
.Ar macro definition
|
||||
.Pf . Ar end
|
||||
.Ed
|
||||
.Pp
|
||||
Both forms define or redefine the macro
|
||||
.Ar name
|
||||
to represent the
|
||||
.Ar macro definition ,
|
||||
which may consist of one or more input lines, including the newline
|
||||
characters terminating each line, optionally containing calls to
|
||||
.Nm
|
||||
requests,
|
||||
.Nm
|
||||
macros or high-level macros like
|
||||
.Xr man 7
|
||||
or
|
||||
.Xr mdoc 7
|
||||
macros, whichever applies to the document in question.
|
||||
.Pp
|
||||
Specifying a custom
|
||||
.Ar end
|
||||
macro works in the same way as for
|
||||
.Sx \&ig ;
|
||||
namely, the call to
|
||||
.Sq Pf . Ar end
|
||||
first ends the
|
||||
.Ar macro definition ,
|
||||
and after that, it is also evaluated as a
|
||||
.Nm
|
||||
request or
|
||||
.Nm
|
||||
macro, but not as a high-level macro.
|
||||
.Pp
|
||||
The macro can be invoked later using the syntax
|
||||
.Pp
|
||||
.D1 Pf . Ar name Op Ar argument Op Ar argument ...
|
||||
.Pp
|
||||
Arguments are separated by blank characters and can be quoted
|
||||
using double-quotes
|
||||
.Pq Sq \(dq
|
||||
to allow inclusion of blank characters into arguments.
|
||||
To include the double-quote character into a quoted argument,
|
||||
escape it from ending the argument by doubling it.
|
||||
.Pp
|
||||
The line invoking the macro will be replaced
|
||||
in the input stream by the
|
||||
.Ar macro definition ,
|
||||
replacing all occurrences of
|
||||
.No \e\e$ Ns Ar N ,
|
||||
where
|
||||
.Ar N
|
||||
is a digit, by the
|
||||
.Ar N Ns th Ar argument .
|
||||
For example,
|
||||
.Bd -literal -offset indent
|
||||
\&.de ZN
|
||||
\efI\e^\e\e$1\e^\efP\e\e$2
|
||||
\&..
|
||||
\&.ZN XtFree .
|
||||
.Ed
|
||||
.Pp
|
||||
produces
|
||||
.Pp
|
||||
.D1 \efI\e^XtFree\e^\efP.
|
||||
.Pp
|
||||
in the input stream, and thus in the output: \fI\^XtFree\^\fP.
|
||||
.Pp
|
||||
Since macros and user-defined strings share a common string table,
|
||||
defining a macro
|
||||
.Ar name
|
||||
clobbers the user-defined string
|
||||
.Ar name ,
|
||||
and the
|
||||
.Ar macro definition
|
||||
can also be printed using the
|
||||
.Sq \e*
|
||||
string interpolation syntax described below
|
||||
.Sx ds ,
|
||||
but this is rarely useful because every macro definition contains at least
|
||||
one explicit newline character.
|
||||
.Pp
|
||||
In order to prevent endless recursion, both groff and
|
||||
.Xr mandoc 1
|
||||
limit the stack depth for expanding macros and strings
|
||||
to a large, but finite number.
|
||||
Do not rely on the exact value of this limit.
|
||||
.Ss \&dei
|
||||
Define a
|
||||
.Nm
|
||||
macro, specifying the macro name indirectly.
|
||||
The syntax of this request is the same as that of
|
||||
.Sx \&de .
|
||||
It is currently ignored by
|
||||
.Xr mandoc 1 ,
|
||||
as are its children.
|
||||
.Ss \&de1
|
||||
Define a
|
||||
.Nm
|
||||
macro that will be executed with
|
||||
.Nm
|
||||
compatibility mode switched off during macro execution.
|
||||
This is a GNU extension not available in traditional
|
||||
.Nm
|
||||
implementations and not even in older versions of groff.
|
||||
Since
|
||||
.Xr mandoc 1
|
||||
does not implement
|
||||
.Nm
|
||||
compatibility mode at all, it handles this request as an alias for
|
||||
.Sx \&de .
|
||||
.Ss \&ds
|
||||
Define a user-defined string.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf . Cm \&ds Ar name Oo \(dq Oc Ns Ar string
|
||||
.Pp
|
||||
The
|
||||
.Ar name
|
||||
and
|
||||
.Ar string
|
||||
arguments are space-separated.
|
||||
If the
|
||||
.Ar string
|
||||
begins with a double-quote character, that character will not be part
|
||||
of the string.
|
||||
All remaining characters on the input line form the
|
||||
.Ar string ,
|
||||
including whitespace and double-quote characters, even trailing ones.
|
||||
.Pp
|
||||
The
|
||||
.Ar string
|
||||
can be interpolated into subsequent text by using
|
||||
.No \e* Ns Bq Ar name
|
||||
for a
|
||||
.Ar name
|
||||
of arbitrary length, or \e*(NN or \e*N if the length of
|
||||
.Ar name
|
||||
is two or one characters, respectively.
|
||||
Interpolation can be prevented by escaping the leading backslash;
|
||||
that is, an asterisk preceded by an even number of backslashes
|
||||
does not trigger string interpolation.
|
||||
.Pp
|
||||
Since user-defined strings and macros share a common string table,
|
||||
defining a string
|
||||
.Ar name
|
||||
clobbers the macro
|
||||
.Ar name ,
|
||||
and the
|
||||
.Ar name
|
||||
used for defining a string can also be invoked as a macro,
|
||||
in which case the following input line will be appended to the
|
||||
.Ar string ,
|
||||
forming a new input line passed to the
|
||||
.Nm
|
||||
parser.
|
||||
For example,
|
||||
.Bd -literal -offset indent
|
||||
\&.ds badidea .S
|
||||
\&.badidea
|
||||
H SYNOPSIS
|
||||
.Ed
|
||||
.Pp
|
||||
invokes the
|
||||
.Cm SH
|
||||
macro when used in a
|
||||
.Xr man 7
|
||||
document.
|
||||
Such abuse is of course strongly discouraged.
|
||||
.Ss \&el
|
||||
The
|
||||
.Qq else
|
||||
half of an if/else conditional.
|
||||
Pops a result off the stack of conditional evaluations pushed by
|
||||
.Sx \&ie
|
||||
and uses it as its conditional.
|
||||
If no stack entries are present (e.g., due to no prior
|
||||
.Sx \&ie
|
||||
calls)
|
||||
then false is assumed.
|
||||
The syntax of this request is similar to
|
||||
.Sx \&if
|
||||
except that the conditional is missing.
|
||||
.Ss \&hy
|
||||
Set automatic hyphenation mode.
|
||||
This line-scoped request is currently ignored.
|
||||
.Ss \&ie
|
||||
The
|
||||
.Qq if
|
||||
half of an if/else conditional.
|
||||
The result of the conditional is pushed into a stack used by subsequent
|
||||
invocations of
|
||||
.Sx \&el ,
|
||||
which may be separated by any intervening input (or not exist at all).
|
||||
Its syntax is equivalent to
|
||||
.Sx \&if .
|
||||
.Ss \&if
|
||||
Begins a conditional.
|
||||
Right now, the conditional evaluates to true
|
||||
if and only if it starts with the letter
|
||||
.Sy n ,
|
||||
indicating processing in nroff style as opposed to troff style.
|
||||
If a conditional is false, its children are not processed, but are
|
||||
syntactically interpreted to preserve the integrity of the input
|
||||
document.
|
||||
Thus,
|
||||
.Pp
|
||||
.D1 \&.if t .ig
|
||||
.Pp
|
||||
will discard the
|
||||
.Sq \&.ig ,
|
||||
which may lead to interesting results, but
|
||||
.Pp
|
||||
.D1 \&.if t .if t \e{\e
|
||||
.Pp
|
||||
will continue to syntactically interpret to the block close of the final
|
||||
conditional.
|
||||
Sub-conditionals, in this case, obviously inherit the truth value of
|
||||
the parent.
|
||||
This request has the following syntax:
|
||||
.Bd -literal -offset indent
|
||||
\&.if COND \e{\e
|
||||
BODY...
|
||||
\&.\e}
|
||||
.Ed
|
||||
.Bd -literal -offset indent
|
||||
\&.if COND \e{ BODY
|
||||
BODY... \e}
|
||||
.Ed
|
||||
.Bd -literal -offset indent
|
||||
\&.if COND \e{ BODY
|
||||
BODY...
|
||||
\&.\e}
|
||||
.Ed
|
||||
.Bd -literal -offset indent
|
||||
\&.if COND \e
|
||||
BODY
|
||||
.Ed
|
||||
.Pp
|
||||
COND is a conditional statement.
|
||||
roff allows for complicated conditionals; mandoc is much simpler.
|
||||
At this time, mandoc supports only
|
||||
.Sq n ,
|
||||
evaluating to true;
|
||||
and
|
||||
.Sq t ,
|
||||
.Sq e ,
|
||||
and
|
||||
.Sq o ,
|
||||
evaluating to false.
|
||||
All other invocations are read up to the next end of line or space and
|
||||
evaluate as false.
|
||||
.Pp
|
||||
If the BODY section is begun by an escaped brace
|
||||
.Sq \e{ ,
|
||||
scope continues until a closing-brace escape sequence
|
||||
.Sq \.\e} .
|
||||
If the BODY is not enclosed in braces, scope continues until
|
||||
the end of the line.
|
||||
If the COND is followed by a BODY on the same line, whether after a
|
||||
brace or not, then requests and macros
|
||||
.Em must
|
||||
begin with a control character.
|
||||
It is generally more intuitive, in this case, to write
|
||||
.Bd -literal -offset indent
|
||||
\&.if COND \e{\e
|
||||
\&.foo
|
||||
bar
|
||||
\&.\e}
|
||||
.Ed
|
||||
.Pp
|
||||
than having the request or macro follow as
|
||||
.Pp
|
||||
.D1 \&.if COND \e{ .foo
|
||||
.Pp
|
||||
The scope of a conditional is always parsed, but only executed if the
|
||||
conditional evaluates to true.
|
||||
.Pp
|
||||
Note that text following an
|
||||
.Sq \&.\e}
|
||||
escape sequence is discarded.
|
||||
Furthermore, if an explicit closing sequence
|
||||
.Sq \e}
|
||||
is specified in a free-form line, the entire line is accepted within the
|
||||
scope of the prior request, not only the text preceding the close, with the
|
||||
.Sq \e}
|
||||
collapsing into a zero-width space.
|
||||
.Ss \&ig
|
||||
Ignore input.
|
||||
Its syntax can be either
|
||||
.Bd -literal -offset indent
|
||||
.Pf . Cm \&ig
|
||||
.Ar ignored text
|
||||
\&..
|
||||
.Ed
|
||||
.Pp
|
||||
or
|
||||
.Bd -literal -offset indent
|
||||
.Pf . Cm \&ig Ar end
|
||||
.Ar ignored text
|
||||
.Pf . Ar end
|
||||
.Ed
|
||||
.Pp
|
||||
In the first case, input is ignored until a
|
||||
.Sq \&..
|
||||
request is encountered on its own line.
|
||||
In the second case, input is ignored until the specified
|
||||
.Sq Pf . Ar end
|
||||
macro is encountered.
|
||||
Do not use the escape character
|
||||
.Sq \e
|
||||
anywhere in the definition of
|
||||
.Ar end ;
|
||||
it would cause very strange behaviour.
|
||||
.Pp
|
||||
When the
|
||||
.Ar end
|
||||
macro is a roff request or a roff macro, like in
|
||||
.Pp
|
||||
.D1 \&.ig if
|
||||
.Pp
|
||||
the subsequent invocation of
|
||||
.Sx \&if
|
||||
will first terminate the
|
||||
.Ar ignored text ,
|
||||
then be invoked as usual.
|
||||
Otherwise, it only terminates the
|
||||
.Ar ignored text ,
|
||||
and arguments following it or the
|
||||
.Sq \&..
|
||||
request are discarded.
|
||||
.Ss \&ne
|
||||
Declare the need for the specified minimum vertical space
|
||||
before the next trap or the bottom of the page.
|
||||
This line-scoped request is currently ignored.
|
||||
.Ss \&nh
|
||||
Turn off automatic hyphenation mode.
|
||||
This line-scoped request is currently ignored.
|
||||
.Ss \&rm
|
||||
Remove a request, macro or string.
|
||||
This request is intended to have one argument,
|
||||
the name of the request, macro or string to be undefined.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
.Ss \&nr
|
||||
Define a register.
|
||||
A register is an arbitrary string value that defines some sort of state,
|
||||
which influences parsing and/or formatting.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Cm \&nr Ar name Ar value
|
||||
.Pp
|
||||
The
|
||||
.Ar value
|
||||
may, at the moment, only be an integer.
|
||||
So far, only the following register
|
||||
.Ar name
|
||||
is recognised:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm nS
|
||||
If set to a positive integer value, certain
|
||||
.Xr mdoc 7
|
||||
macros will behave in the same way as in the
|
||||
.Em SYNOPSIS
|
||||
section.
|
||||
If set to 0, these macros will behave in the same way as outside the
|
||||
.Em SYNOPSIS
|
||||
section, even when called within the
|
||||
.Em SYNOPSIS
|
||||
section itself.
|
||||
Note that starting a new
|
||||
.Xr mdoc 7
|
||||
section with the
|
||||
.Cm \&Sh
|
||||
macro will reset this register.
|
||||
.El
|
||||
.Ss \&so
|
||||
Include a source file.
|
||||
Its syntax is as follows:
|
||||
.Pp
|
||||
.D1 Pf \. Cm \&so Ar file
|
||||
.Pp
|
||||
The
|
||||
.Ar file
|
||||
will be read and its contents processed as input in place of the
|
||||
.Sq \&.so
|
||||
request line.
|
||||
To avoid inadvertant inclusion of unrelated files,
|
||||
.Xr mandoc 1
|
||||
only accepts relative paths not containing the strings
|
||||
.Qq ../
|
||||
and
|
||||
.Qq /.. .
|
||||
.Ss \&tr
|
||||
Output character translation.
|
||||
This request is intended to have one argument,
|
||||
consisting of an even number of characters.
|
||||
Currently, it is ignored including its arguments,
|
||||
and the number of arguments is not checked.
|
||||
.Ss \&T&
|
||||
Re-start a table layout, retaining the options of the prior table
|
||||
invocation.
|
||||
See
|
||||
.Sx \&TS .
|
||||
.Ss \&TE
|
||||
End a table context.
|
||||
See
|
||||
.Sx \&TS .
|
||||
.Ss \&TS
|
||||
Begin a table, which formats input in aligned rows and columns.
|
||||
See
|
||||
.Xr tbl 7
|
||||
for a description of the tbl language.
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility between mandoc and other other
|
||||
.Nm
|
||||
implementations, at this time limited to GNU troff
|
||||
.Pq Qq groff .
|
||||
The term
|
||||
.Qq historic groff
|
||||
refers to groff version 1.15.
|
||||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
The
|
||||
.Cm nS
|
||||
register is only compatible with OpenBSD's groff-1.15.
|
||||
.It
|
||||
Historic groff did not accept white-space before a custom
|
||||
.Ar end
|
||||
macro for the
|
||||
.Sx \&ig
|
||||
request.
|
||||
.It
|
||||
The
|
||||
.Sx \&if
|
||||
and family would print funny white-spaces with historic groff when
|
||||
using the next-line syntax.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr tbl 7
|
||||
.Rs
|
||||
.%A Joseph F. Ossanna
|
||||
.%A Brian W. Kernighan
|
||||
.%I AT&T Bell Laboratories
|
||||
.%T Troff User's Manual
|
||||
.%R Computing Science Technical Report
|
||||
.%N 54
|
||||
.%C Murray Hill, New Jersey
|
||||
.%D 1976 and 1992
|
||||
.%U http://www.kohala.com/start/troff/cstr54.ps
|
||||
.Re
|
||||
.Rs
|
||||
.%A Joseph F. Ossanna
|
||||
.%A Brian W. Kernighan
|
||||
.%A Gunnar Ritter
|
||||
.%T Heirloom Documentation Tools Nroff/Troff User's Manual
|
||||
.%D September 17, 2007
|
||||
.%U http://heirloom.sourceforge.net/doctools/troff.pdf
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The RUNOFF typesetting system was written in PL/1 for the CTSS
|
||||
operating system by Jerome ("Jerry") E. Saltzer in 1961.
|
||||
It was first used as the main documentation tool by Multics since 1963.
|
||||
Robert ("Bob") H. Morris ported it to the GE-635 and called it
|
||||
.Nm ,
|
||||
Doug McIlroy rewrote it in BCPL in 1969,
|
||||
Joseph F. Ossanna rewrote it in PDP-11 assembly in 1973,
|
||||
and Brian W. Kernighan rewrote it in C in 1975.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
This partial
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv
|
||||
and
|
||||
.An Ingo Schwarze Aq schwarze@openbsd.org .
|
||||
1356
usr.bin/mdocml/dist/roff.c
vendored
1356
usr.bin/mdocml/dist/roff.c
vendored
File diff suppressed because it is too large
Load Diff
45
usr.bin/mdocml/dist/roff.h
vendored
45
usr.bin/mdocml/dist/roff.h
vendored
@@ -1,45 +0,0 @@
|
||||
/* $Vendor-Id: roff.h,v 1.22 2011/01/01 16:18:39 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef ROFF_H
|
||||
#define ROFF_H
|
||||
|
||||
enum rofferr {
|
||||
ROFF_CONT, /* continue processing line */
|
||||
ROFF_RERUN, /* re-run roff interpreter with offset */
|
||||
ROFF_APPEND, /* re-run main parser, appending next line */
|
||||
ROFF_REPARSE, /* re-run main parser on the result */
|
||||
ROFF_SO, /* include another file */
|
||||
ROFF_IGN, /* ignore current line */
|
||||
ROFF_TBL, /* a table row was successfully parsed */
|
||||
ROFF_ERR /* badness: puke and stop */
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct roff;
|
||||
|
||||
void roff_free(struct roff *);
|
||||
struct roff *roff_alloc(struct regset *, void *, mandocmsg);
|
||||
void roff_reset(struct roff *);
|
||||
enum rofferr roff_parseln(struct roff *, int,
|
||||
char **, size_t *, int, int *);
|
||||
void roff_endparse(struct roff *);
|
||||
const struct tbl_span *roff_span(const struct roff *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!ROFF_H*/
|
||||
38
usr.bin/mdocml/dist/st.c
vendored
38
usr.bin/mdocml/dist/st.c
vendored
@@ -1,38 +0,0 @@
|
||||
/* $Vendor-Id: st.c,v 1.8 2010/06/19 20:46:28 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
if (0 == strcmp(p, x)) return(y);
|
||||
|
||||
const char *
|
||||
mdoc_a2st(const char *p)
|
||||
{
|
||||
|
||||
#include "st.in"
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
74
usr.bin/mdocml/dist/st.in
vendored
74
usr.bin/mdocml/dist/st.in
vendored
@@ -1,74 +0,0 @@
|
||||
/* $Vendor-Id: st.in,v 1.15 2010/07/31 23:52:58 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines the .St macro arguments. If you add a new
|
||||
* standard, make sure that the left-and side corresponds to the .St
|
||||
* argument (like .St -p1003.1) and the right-hand side corresponds to
|
||||
* the formatted output string.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
*
|
||||
* REMEMBER TO ADD NEW STANDARDS TO MDOC.7!
|
||||
*/
|
||||
|
||||
LINE("-p1003.1-88", "IEEE Std 1003.1-1988 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-90", "IEEE Std 1003.1-1990 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1387.2-95", "IEEE Std 1387.2-1995 (\\(lqPOSIX.7.2\\(rq)")
|
||||
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-p1387.2", "IEEE Std 1387.2 (\\(lqPOSIX.7.2\\(rq)")
|
||||
LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-tcor1", "ISO/IEC 9899/TCOR1:1994 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-tcor2", "ISO/IEC 9899/TCOR2:1995 (\\(lqISO C90\\(rq)")
|
||||
LINE("-isoC-99", "ISO/IEC 9899:1999 (\\(lqISO C99\\(rq)")
|
||||
LINE("-iso9945-1-90", "ISO/IEC 9945-1:1990 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
|
||||
LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(lqPOSIX.2\\(rq)")
|
||||
LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI C\\(rq)")
|
||||
LINE("-ansiC-89", "ANSI X3.159-1989 (\\(lqANSI C\\(rq)")
|
||||
LINE("-ansiC-99", "ANSI/ISO/IEC 9899-1999 (\\(lqANSI C99\\(rq)")
|
||||
LINE("-ieee754", "IEEE Std 754-1985")
|
||||
LINE("-iso8802-3", "ISO 8802-3: 1989")
|
||||
LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)")
|
||||
LINE("-xpg3", "X/Open Portability Guide Issue 3 (\\(lqXPG3\\(rq)")
|
||||
LINE("-xpg4", "X/Open Portability Guide Issue 4 (\\(lqXPG4\\(rq)")
|
||||
LINE("-xpg4.2", "X/Open Portability Guide Issue 4.2 (\\(lqXPG4.2\\(rq)")
|
||||
LINE("-xpg4.3", "X/Open Portability Guide Issue 4.3 (\\(lqXPG4.3\\(rq)")
|
||||
LINE("-xbd5", "X/Open System Interface Definitions Issue 5 (\\(lqXBD5\\(rq)")
|
||||
LINE("-xcu5", "X/Open Commands and Utilities Issue 5 (\\(lqXCU5\\(rq)")
|
||||
LINE("-xsh5", "X/Open System Interfaces and Headers Issue 5 (\\(lqXSH5\\(rq)")
|
||||
LINE("-xns5", "X/Open Networking Services Issue 5 (\\(lqXNS5\\(rq)")
|
||||
LINE("-xns5.2", "X/Open Networking Services Issue 5.2 (\\(lqXNS5.2\\(rq)")
|
||||
LINE("-xns5.2d2.0", "X/Open Networking Services Issue 5.2 Draft 2.0 (\\(lqXNS5.2D2.0\\(rq)")
|
||||
LINE("-xcurses4.2", "X/Open Curses Issue 4 Version 2 (\\(lqXCURSES4.2\\(rq)")
|
||||
LINE("-susv2", "Version 2 of the Single UNIX Specification")
|
||||
LINE("-susv3", "Version 3 of the Single UNIX Specification")
|
||||
LINE("-svid4", "System V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)")
|
||||
322
usr.bin/mdocml/dist/tbl.7
vendored
322
usr.bin/mdocml/dist/tbl.7
vendored
@@ -1,322 +0,0 @@
|
||||
.\" $Vendor-Id: tbl.7,v 1.4 2011/01/07 14:59:52 kristaps Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd January 7, 2011
|
||||
.Dt TBL 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm tbl
|
||||
.Nd tbl language reference for mandoc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm tbl
|
||||
language is a table-formatting language.
|
||||
It is used within
|
||||
.Xr mdoc 7
|
||||
and
|
||||
.Xr man 7
|
||||
.Ux
|
||||
manual pages.
|
||||
This manual describes the subset of the
|
||||
.Nm
|
||||
language accepted by the
|
||||
.Xr mandoc 1
|
||||
utility.
|
||||
.Pp
|
||||
Tables within
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Xr man 7
|
||||
are enclosed by the
|
||||
.Sq TS
|
||||
and
|
||||
.Sq TE
|
||||
macro tags, whose precise syntax is documented in
|
||||
.Xr roff 7 .
|
||||
Tables consist of a series of options on a single line, followed by the
|
||||
table layout, followed by data.
|
||||
.Pp
|
||||
For example, the following creates a boxed table with digits centered in
|
||||
the cells.
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
tab(:) box;
|
||||
c5 c5 c5.
|
||||
1:2:3
|
||||
4:5:6
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
When formatted, the following output is produced:
|
||||
.Bd -filled -offset indent -compact
|
||||
.TS
|
||||
tab(:) box;
|
||||
c5 c5 c5.
|
||||
1:2:3
|
||||
4:5:6
|
||||
.TE
|
||||
.Ed
|
||||
.Sh TABLE STRUCTURE
|
||||
Tables are enclosed by the
|
||||
.Sq TS
|
||||
and
|
||||
.Sq TE
|
||||
.Xr roff 7
|
||||
macros.
|
||||
A table consists of an optional single line of table
|
||||
.Sx Options
|
||||
terminated by a semicolon, followed by one or more lines of
|
||||
.Sx Layout
|
||||
specifications terminated by a period, then
|
||||
.Sx Data .
|
||||
All input must be 7-bit ASCII.
|
||||
Example:
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
box tab(:);
|
||||
c | c
|
||||
| c | c.
|
||||
1:2
|
||||
3:4
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
Table data is
|
||||
.Em pre-processed ,
|
||||
that is, data rows are parsed then inserted into the underlying stream
|
||||
of input data.
|
||||
This allows data rows to be interspersed by arbitrary
|
||||
.Xr roff 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
and
|
||||
.Xr man 7
|
||||
macros such as
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
tab(:);
|
||||
c c c.
|
||||
1:2:3
|
||||
\&.Ao
|
||||
3:2:1
|
||||
\&.Ac
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
in the case of
|
||||
.Xr mdoc 7
|
||||
or
|
||||
.Bd -literal -offset indent
|
||||
\&.TS
|
||||
tab(:);
|
||||
c c c.
|
||||
\&.ds ab 2
|
||||
1:\e*(ab:3
|
||||
\&.I
|
||||
3:2:1
|
||||
\&.TE
|
||||
.Ed
|
||||
.Pp
|
||||
in the case of
|
||||
.Xr man 7 .
|
||||
.Ss Options
|
||||
The first line of a table consists of space-separated option keys and
|
||||
modifiers terminated by a semicolon.
|
||||
If the first line does not have a terminating semicolon, it is assumed
|
||||
that no options are specified and instead a
|
||||
.Sx Layout
|
||||
is processed.
|
||||
Some options accept arguments enclosed by parenthesis.
|
||||
The following case-insensitive options are available:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm center
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
This may also be invoked with
|
||||
.Cm centre .
|
||||
.It Cm delim
|
||||
Accepts a two-character argument.
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm expand
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm box
|
||||
Draw a single-line box around the table.
|
||||
This may also be invoked with
|
||||
.Cm frame .
|
||||
.It Cm doublebox
|
||||
Draw a double-line box around the table.
|
||||
This may also be invoked with
|
||||
.Cm doubleframe .
|
||||
.It Cm allbox
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm tab
|
||||
Accepts a single-character argument.
|
||||
This character is used as a delimiter between data cells, which otherwise
|
||||
defaults to the tab character.
|
||||
.It Cm linesize
|
||||
Accepts a natural number (all digits).
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm nokeep
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm decimalpoint
|
||||
Accepts a single-character argument.
|
||||
This character will be used as the decimal point with the
|
||||
.Cm n
|
||||
layout key.
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm nospaces
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.El
|
||||
.Ss Layout
|
||||
The table layout follows
|
||||
.Sx Options
|
||||
or a
|
||||
.Sq \&T&
|
||||
macro invocation.
|
||||
Layout specifies how data rows are displayed on output.
|
||||
Each layout line corresponds to a line of data; the last layout line
|
||||
applies to all remaining data lines.
|
||||
Layout lines may also be separated by a comma.
|
||||
Each layout cell consists of one of the following case-insensitive keys:
|
||||
.Bl -tag -width Ds
|
||||
.It Cm c
|
||||
Centre a literal string within its column.
|
||||
.It Cm r
|
||||
Right-justify a literal string within its column.
|
||||
.It Cm l
|
||||
Left-justify a literal string within its column.
|
||||
.It Cm n
|
||||
Justify a number around its decimal point.
|
||||
If the decimal point is not found on the number, it's assumed to trail
|
||||
the number.
|
||||
.It Cm s
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm a
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm ^
|
||||
This option is not supported by
|
||||
.Xr mandoc 1 .
|
||||
.It Cm \-
|
||||
Replace the data cell (its contents will be lost) with a single
|
||||
horizontal line.
|
||||
This may also be invoked with
|
||||
.Cm _ .
|
||||
.It Cm =
|
||||
Replace the data cell (its contents will be lost) with a double
|
||||
horizontal line.
|
||||
.It Cm \(ba
|
||||
Emit a vertical bar instead of data.
|
||||
.It Cm \(ba\(ba
|
||||
Emit a double-vertical bar instead of data.
|
||||
.El
|
||||
.Pp
|
||||
For example, the following layout specifies a centre-justified column of
|
||||
minimum width 10, followed by vertical bar, followed by a left-justified
|
||||
column of minimum width 10, another vertical bar, then a column
|
||||
justified about the decimal point in numbers:
|
||||
.Pp
|
||||
.Dl c10 | l10 | n
|
||||
.Pp
|
||||
Keys may be followed by a set of modifiers.
|
||||
A modifier is either a modifier key or a natural number for specifying
|
||||
spacing.
|
||||
The following case-insensitive modifier keys are available:
|
||||
.Cm z ,
|
||||
.Cm u ,
|
||||
.Cm e ,
|
||||
.Cm t ,
|
||||
.Cm d ,
|
||||
.Cm f ,
|
||||
.Cm b ,
|
||||
.Cm i ,
|
||||
.Cm b ,
|
||||
and
|
||||
.Cm i .
|
||||
All of these are ignored by
|
||||
.Xr mandoc 1 .
|
||||
.Ss Data
|
||||
The data section follows the last layout row.
|
||||
By default, cells in a data section are delimited by a tab.
|
||||
This behaviour may be changed with the
|
||||
.Cm tab
|
||||
option.
|
||||
If
|
||||
.Cm _
|
||||
or
|
||||
.Cm =
|
||||
is specified, a single or double line, respectively, is drawn across the
|
||||
data field.
|
||||
If
|
||||
.Cm \e-
|
||||
or
|
||||
.Cm \e=
|
||||
is specified, a line is drawn within the data field (i.e. terminating
|
||||
within the cell and not draw to the border).
|
||||
If the last cell of a line is
|
||||
.Cm T{ ,
|
||||
all subsequent lines are included as part of the cell until
|
||||
.Cm T}
|
||||
is specified as its own data cell.
|
||||
It may then be followed by a tab
|
||||
.Pq or as designated by Cm tab
|
||||
or an end-of-line to terminate the row.
|
||||
.Sh COMPATIBILITY
|
||||
This section documents compatibility between mandoc and other
|
||||
.Nm
|
||||
implementations, at this time limited to GNU tbl.
|
||||
.Pp
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
In GNU tbl, comments and macros are disallowed prior to the data block
|
||||
of a table.
|
||||
The
|
||||
.Xr mandoc 1
|
||||
implementation allows them.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mandoc 1 ,
|
||||
.Xr man 7 ,
|
||||
.Xr mandoc_char 7 ,
|
||||
.Xr mdoc 7 ,
|
||||
.Xr roff 7
|
||||
.Rs
|
||||
.%A M. E. Lesk
|
||||
.%T Tbl\(emA Program to Format Tables
|
||||
.%D June 11, 1976
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The tbl utility, a preprocessor for troff, was originally written by M.
|
||||
E. Lesk at Bell Labs in 1975.
|
||||
The GNU reimplementation of tbl, part of the groff package, was released
|
||||
in 1990 by James Clark.
|
||||
A standalone tbl implementation was written by Kristaps Dzonsons in
|
||||
2010.
|
||||
This formed the basis of the implementation that is part of the
|
||||
.Xr mandoc 1
|
||||
utility.
|
||||
.Sh AUTHORS
|
||||
This partial
|
||||
.Nm
|
||||
reference was written by
|
||||
.An Kristaps Dzonsons Aq kristaps@bsd.lv .
|
||||
159
usr.bin/mdocml/dist/tbl.c
vendored
159
usr.bin/mdocml/dist/tbl.c
vendored
@@ -1,159 +0,0 @@
|
||||
/* $Vendor-Id: tbl.c,v 1.21 2011/01/04 15:02:00 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "roff.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libroff.h"
|
||||
|
||||
enum rofferr
|
||||
tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
|
||||
{
|
||||
int len;
|
||||
const char *cp;
|
||||
|
||||
cp = &p[offs];
|
||||
len = (int)strlen(cp);
|
||||
|
||||
/*
|
||||
* If we're in the options section and we don't have a
|
||||
* terminating semicolon, assume we've moved directly into the
|
||||
* layout section. No need to report a warning: this is,
|
||||
* apparently, standard behaviour.
|
||||
*/
|
||||
|
||||
if (TBL_PART_OPTS == tbl->part && len)
|
||||
if (';' != cp[len - 1])
|
||||
tbl->part = TBL_PART_LAYOUT;
|
||||
|
||||
/* Now process each logical section of the table. */
|
||||
|
||||
switch (tbl->part) {
|
||||
case (TBL_PART_OPTS):
|
||||
return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
|
||||
case (TBL_PART_LAYOUT):
|
||||
return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
|
||||
case (TBL_PART_CDATA):
|
||||
return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* This only returns zero if the line is empty, so we ignore it
|
||||
* and continue on.
|
||||
*/
|
||||
return(tbl_data(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
|
||||
}
|
||||
|
||||
struct tbl_node *
|
||||
tbl_alloc(int pos, int line, void *data, const mandocmsg msg)
|
||||
{
|
||||
struct tbl_node *p;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct tbl_node));
|
||||
p->line = line;
|
||||
p->pos = pos;
|
||||
p->data = data;
|
||||
p->msg = msg;
|
||||
p->part = TBL_PART_OPTS;
|
||||
p->opts.tab = '\t';
|
||||
p->opts.linesize = 12;
|
||||
p->opts.decimal = '.';
|
||||
return(p);
|
||||
}
|
||||
|
||||
void
|
||||
tbl_free(struct tbl_node *p)
|
||||
{
|
||||
struct tbl_row *rp;
|
||||
struct tbl_cell *cp;
|
||||
struct tbl_span *sp;
|
||||
struct tbl_dat *dp;
|
||||
struct tbl_head *hp;
|
||||
|
||||
while (NULL != (rp = p->first_row)) {
|
||||
p->first_row = rp->next;
|
||||
while (rp->first) {
|
||||
cp = rp->first;
|
||||
rp->first = cp->next;
|
||||
free(cp);
|
||||
}
|
||||
free(rp);
|
||||
}
|
||||
|
||||
while (NULL != (sp = p->first_span)) {
|
||||
p->first_span = sp->next;
|
||||
while (sp->first) {
|
||||
dp = sp->first;
|
||||
sp->first = dp->next;
|
||||
if (dp->string)
|
||||
free(dp->string);
|
||||
free(dp);
|
||||
}
|
||||
free(sp);
|
||||
}
|
||||
|
||||
while (NULL != (hp = p->first_head)) {
|
||||
p->first_head = hp->next;
|
||||
free(hp);
|
||||
}
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
void
|
||||
tbl_restart(int line, int pos, struct tbl_node *tbl)
|
||||
{
|
||||
if (TBL_PART_CDATA == tbl->part)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
|
||||
|
||||
tbl->part = TBL_PART_LAYOUT;
|
||||
tbl->line = line;
|
||||
tbl->pos = pos;
|
||||
|
||||
if (NULL == tbl->first_span || NULL == tbl->first_span->first)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
|
||||
}
|
||||
|
||||
const struct tbl_span *
|
||||
tbl_span(const struct tbl_node *tbl)
|
||||
{
|
||||
|
||||
assert(tbl);
|
||||
return(tbl->last_span);
|
||||
}
|
||||
|
||||
void
|
||||
tbl_end(struct tbl_node *tbl)
|
||||
{
|
||||
|
||||
if (NULL == tbl->first_span || NULL == tbl->first_span->first)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
|
||||
|
||||
if (tbl->last_span)
|
||||
tbl->last_span->flags |= TBL_SPAN_LAST;
|
||||
|
||||
if (TBL_PART_CDATA == tbl->part)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
|
||||
}
|
||||
|
||||
218
usr.bin/mdocml/dist/tbl_data.c
vendored
218
usr.bin/mdocml/dist/tbl_data.c
vendored
@@ -1,218 +0,0 @@
|
||||
/* $Vendor-Id: tbl_data.c,v 1.15 2011/01/09 23:14:41 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libroff.h"
|
||||
|
||||
static int data(struct tbl_node *, struct tbl_span *,
|
||||
int, const char *, int *);
|
||||
|
||||
static int
|
||||
data(struct tbl_node *tbl, struct tbl_span *dp,
|
||||
int ln, const char *p, int *pos)
|
||||
{
|
||||
struct tbl_dat *dat;
|
||||
struct tbl_cell *cp;
|
||||
int sv;
|
||||
|
||||
cp = NULL;
|
||||
if (dp->last && dp->last->layout)
|
||||
cp = dp->last->layout->next;
|
||||
else if (NULL == dp->last)
|
||||
cp = dp->layout->first;
|
||||
|
||||
/*
|
||||
* Skip over spanners and vertical lines to data formats, since
|
||||
* we want to match data with data layout cells in the header.
|
||||
*/
|
||||
|
||||
while (cp && (TBL_CELL_VERT == cp->pos ||
|
||||
TBL_CELL_DVERT == cp->pos ||
|
||||
TBL_CELL_SPAN == cp->pos))
|
||||
cp = cp->next;
|
||||
|
||||
dat = mandoc_calloc(1, sizeof(struct tbl_dat));
|
||||
dat->layout = cp;
|
||||
dat->pos = TBL_DATA_NONE;
|
||||
|
||||
if (NULL == dat->layout)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos);
|
||||
|
||||
if (dp->last) {
|
||||
dp->last->next = dat;
|
||||
dp->last = dat;
|
||||
} else
|
||||
dp->last = dp->first = dat;
|
||||
|
||||
sv = *pos;
|
||||
while (p[*pos] && p[*pos] != tbl->opts.tab)
|
||||
(*pos)++;
|
||||
|
||||
/*
|
||||
* Check for a continued-data scope opening. This consists of a
|
||||
* trailing `T{' at the end of the line. Subsequent lines,
|
||||
* until a standalone `T}', are included in our cell.
|
||||
*/
|
||||
|
||||
if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) {
|
||||
tbl->part = TBL_PART_CDATA;
|
||||
return(0);
|
||||
}
|
||||
|
||||
dat->string = mandoc_malloc(*pos - sv + 1);
|
||||
memcpy(dat->string, &p[sv], *pos - sv);
|
||||
dat->string[*pos - sv] = '\0';
|
||||
|
||||
if (p[*pos])
|
||||
(*pos)++;
|
||||
|
||||
if ( ! strcmp(dat->string, "_"))
|
||||
dat->pos = TBL_DATA_HORIZ;
|
||||
else if ( ! strcmp(dat->string, "="))
|
||||
dat->pos = TBL_DATA_DHORIZ;
|
||||
else if ( ! strcmp(dat->string, "\\_"))
|
||||
dat->pos = TBL_DATA_NHORIZ;
|
||||
else if ( ! strcmp(dat->string, "\\="))
|
||||
dat->pos = TBL_DATA_NDHORIZ;
|
||||
else
|
||||
dat->pos = TBL_DATA_DATA;
|
||||
|
||||
if (NULL == dat->layout)
|
||||
return(1);
|
||||
|
||||
if (TBL_CELL_HORIZ == dat->layout->pos ||
|
||||
TBL_CELL_DHORIZ == dat->layout->pos)
|
||||
if (TBL_DATA_DATA == dat->pos && '\0' != *dat->string)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLIGNDATA, ln, sv);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
|
||||
{
|
||||
struct tbl_dat *dat;
|
||||
size_t sz;
|
||||
int pos;
|
||||
|
||||
pos = 0;
|
||||
|
||||
dat = tbl->last_span->last;
|
||||
dat->pos = TBL_DATA_DATA;
|
||||
|
||||
if (p[pos] == 'T' && p[pos + 1] == '}') {
|
||||
pos += 2;
|
||||
if (p[pos] == tbl->opts.tab) {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
pos++;
|
||||
return(data(tbl, tbl->last_span, ln, p, &pos));
|
||||
} else if ('\0' == p[pos]) {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Fallthrough: T} is part of a word. */
|
||||
}
|
||||
|
||||
if (dat->string) {
|
||||
sz = strlen(p) + strlen(dat->string) + 2;
|
||||
dat->string = mandoc_realloc(dat->string, sz);
|
||||
strlcat(dat->string, " ", sz);
|
||||
strlcat(dat->string, p, sz);
|
||||
} else
|
||||
dat->string = mandoc_strdup(p);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
tbl_data(struct tbl_node *tbl, int ln, const char *p)
|
||||
{
|
||||
struct tbl_span *dp;
|
||||
struct tbl_row *rp;
|
||||
int pos;
|
||||
|
||||
pos = 0;
|
||||
|
||||
if ('\0' == p[pos]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, pos);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Choose a layout row: take the one following the last parsed
|
||||
* span's. If that doesn't exist, use the last parsed span's.
|
||||
* If there's no last parsed span, use the first row. Lastly,
|
||||
* if the last span was a horizontal line, use the same layout
|
||||
* (it doesn't "consume" the layout).
|
||||
*
|
||||
* In the end, this can be NULL!
|
||||
*/
|
||||
|
||||
if (tbl->last_span) {
|
||||
assert(tbl->last_span->layout);
|
||||
if (tbl->last_span->pos == TBL_SPAN_DATA)
|
||||
rp = tbl->last_span->layout->next;
|
||||
else
|
||||
rp = tbl->last_span->layout;
|
||||
if (NULL == rp)
|
||||
rp = tbl->last_span->layout;
|
||||
} else
|
||||
rp = tbl->first_row;
|
||||
|
||||
dp = mandoc_calloc(1, sizeof(struct tbl_span));
|
||||
dp->tbl = &tbl->opts;
|
||||
dp->layout = rp;
|
||||
dp->head = tbl->first_head;
|
||||
|
||||
if (tbl->last_span) {
|
||||
tbl->last_span->next = dp;
|
||||
tbl->last_span = dp;
|
||||
} else {
|
||||
tbl->last_span = tbl->first_span = dp;
|
||||
dp->flags |= TBL_SPAN_FIRST;
|
||||
}
|
||||
|
||||
if ( ! strcmp(p, "_")) {
|
||||
dp->pos = TBL_SPAN_HORIZ;
|
||||
return(1);
|
||||
} else if ( ! strcmp(p, "=")) {
|
||||
dp->pos = TBL_SPAN_DHORIZ;
|
||||
return(1);
|
||||
}
|
||||
|
||||
dp->pos = TBL_SPAN_DATA;
|
||||
|
||||
/* This returns 0 when TBL_PART_CDATA is entered. */
|
||||
|
||||
while ('\0' != p[pos])
|
||||
if ( ! data(tbl, dp, ln, p, &pos))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
126
usr.bin/mdocml/dist/tbl_html.c
vendored
126
usr.bin/mdocml/dist/tbl_html.c
vendored
@@ -1,126 +0,0 @@
|
||||
/* $Vendor-Id: tbl_html.c,v 1.5 2011/01/06 12:31:39 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "html.h"
|
||||
|
||||
static size_t html_tbl_len(size_t, void *);
|
||||
static size_t html_tbl_strlen(const char *, void *);
|
||||
|
||||
/* ARGSUSED */
|
||||
static size_t
|
||||
html_tbl_len(size_t sz, void *arg)
|
||||
{
|
||||
|
||||
return(sz);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static size_t
|
||||
html_tbl_strlen(const char *p, void *arg)
|
||||
{
|
||||
|
||||
return(strlen(p));
|
||||
}
|
||||
|
||||
void
|
||||
print_tbl(struct html *h, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
const struct tbl_dat *dp;
|
||||
struct tag *tt;
|
||||
struct htmlpair tag;
|
||||
struct roffsu su;
|
||||
struct roffcol *col;
|
||||
|
||||
/* Inhibit printing of spaces: we do padding ourselves. */
|
||||
|
||||
h->flags |= HTML_NONOSPACE;
|
||||
h->flags |= HTML_NOSPACE;
|
||||
|
||||
/* First pass: calculate widths. */
|
||||
|
||||
if (TBL_SPAN_FIRST & sp->flags) {
|
||||
h->tbl.len = html_tbl_len;
|
||||
h->tbl.slen = html_tbl_strlen;
|
||||
tblcalc(&h->tbl, sp);
|
||||
}
|
||||
|
||||
switch (sp->pos) {
|
||||
case (TBL_SPAN_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_SPAN_DHORIZ):
|
||||
break;
|
||||
default:
|
||||
PAIR_CLASS_INIT(&tag, "tbl");
|
||||
print_otag(h, TAG_TABLE, 1, &tag);
|
||||
print_otag(h, TAG_TR, 0, NULL);
|
||||
|
||||
/* Iterate over template headers. */
|
||||
|
||||
dp = sp->first;
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_DVERT):
|
||||
continue;
|
||||
case (TBL_HEAD_DATA):
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the time being, use the simplest possible
|
||||
* table styling: setting the widths of data
|
||||
* columns.
|
||||
*/
|
||||
|
||||
col = &h->tbl.cols[hp->ident];
|
||||
SCALE_HS_INIT(&su, col->width);
|
||||
bufcat_su(h, "width", &su);
|
||||
PAIR_STYLE_INIT(&tag, h);
|
||||
tt = print_otag(h, TAG_TD, 1, &tag);
|
||||
|
||||
if (dp && dp->string)
|
||||
print_text(h, dp->string);
|
||||
if (dp)
|
||||
dp = dp->next;
|
||||
|
||||
print_tagq(h, tt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
h->flags &= ~HTML_NONOSPACE;
|
||||
|
||||
/* Close out column specifiers on the last span. */
|
||||
|
||||
if (TBL_SPAN_LAST & sp->flags) {
|
||||
assert(h->tbl.cols);
|
||||
free(h->tbl.cols);
|
||||
h->tbl.cols = NULL;
|
||||
}
|
||||
}
|
||||
408
usr.bin/mdocml/dist/tbl_layout.c
vendored
408
usr.bin/mdocml/dist/tbl_layout.c
vendored
@@ -1,408 +0,0 @@
|
||||
/* $Vendor-Id: tbl_layout.c,v 1.13 2011/01/09 05:38:23 joerg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmandoc.h"
|
||||
#include "libroff.h"
|
||||
|
||||
struct tbl_phrase {
|
||||
char name;
|
||||
enum tbl_cellt key;
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME: we can make this parse a lot nicer by, when an error is
|
||||
* encountered in a layout key, bailing to the next key (i.e. to the
|
||||
* next whitespace then continuing).
|
||||
*/
|
||||
|
||||
#define KEYS_MAX 11
|
||||
|
||||
static const struct tbl_phrase keys[KEYS_MAX] = {
|
||||
{ 'c', TBL_CELL_CENTRE },
|
||||
{ 'r', TBL_CELL_RIGHT },
|
||||
{ 'l', TBL_CELL_LEFT },
|
||||
{ 'n', TBL_CELL_NUMBER },
|
||||
{ 's', TBL_CELL_SPAN },
|
||||
{ 'a', TBL_CELL_LONG },
|
||||
{ '^', TBL_CELL_DOWN },
|
||||
{ '-', TBL_CELL_HORIZ },
|
||||
{ '_', TBL_CELL_HORIZ },
|
||||
{ '=', TBL_CELL_DHORIZ },
|
||||
{ '|', TBL_CELL_VERT }
|
||||
};
|
||||
|
||||
static int mods(struct tbl_node *, struct tbl_cell *,
|
||||
int, const char *, int *);
|
||||
static int cell(struct tbl_node *, struct tbl_row *,
|
||||
int, const char *, int *);
|
||||
static void row(struct tbl_node *, int, const char *, int *);
|
||||
static struct tbl_cell *cell_alloc(struct tbl_node *,
|
||||
struct tbl_row *, enum tbl_cellt);
|
||||
static void head_adjust(const struct tbl_cell *,
|
||||
struct tbl_head *);
|
||||
|
||||
static int
|
||||
mods(struct tbl_node *tbl, struct tbl_cell *cp,
|
||||
int ln, const char *p, int *pos)
|
||||
{
|
||||
char buf[5];
|
||||
int i;
|
||||
|
||||
mod:
|
||||
/*
|
||||
* XXX: since, at least for now, modifiers are non-conflicting
|
||||
* (are separable by value, regardless of position), we let
|
||||
* modifiers come in any order. The existing tbl doesn't let
|
||||
* this happen.
|
||||
*/
|
||||
switch (p[*pos]) {
|
||||
case ('\0'):
|
||||
/* FALLTHROUGH */
|
||||
case (' '):
|
||||
/* FALLTHROUGH */
|
||||
case ('\t'):
|
||||
/* FALLTHROUGH */
|
||||
case (','):
|
||||
/* FALLTHROUGH */
|
||||
case ('.'):
|
||||
return(1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Throw away parenthesised expression. */
|
||||
|
||||
if ('(' == p[*pos]) {
|
||||
(*pos)++;
|
||||
while (p[*pos] && ')' != p[*pos])
|
||||
(*pos)++;
|
||||
if (')' == p[*pos]) {
|
||||
(*pos)++;
|
||||
goto mod;
|
||||
}
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Parse numerical spacing from modifier string. */
|
||||
|
||||
if (isdigit((unsigned char)p[*pos])) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ( ! isdigit((unsigned char)p[*pos + i]))
|
||||
break;
|
||||
buf[i] = p[*pos + i];
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
/* No greater than 4 digits. */
|
||||
|
||||
if (4 == i) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
return(0);
|
||||
}
|
||||
|
||||
*pos += i;
|
||||
cp->spacing = atoi(buf);
|
||||
|
||||
goto mod;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* TODO: GNU has many more extensions. */
|
||||
|
||||
switch (tolower((unsigned char)p[(*pos)++])) {
|
||||
case ('z'):
|
||||
cp->flags |= TBL_CELL_WIGN;
|
||||
goto mod;
|
||||
case ('u'):
|
||||
cp->flags |= TBL_CELL_UP;
|
||||
goto mod;
|
||||
case ('e'):
|
||||
cp->flags |= TBL_CELL_EQUAL;
|
||||
goto mod;
|
||||
case ('t'):
|
||||
cp->flags |= TBL_CELL_TALIGN;
|
||||
goto mod;
|
||||
case ('d'):
|
||||
cp->flags |= TBL_CELL_BALIGN;
|
||||
goto mod;
|
||||
case ('w'): /* XXX for now, ignore minimal column width */
|
||||
goto mod;
|
||||
case ('f'):
|
||||
break;
|
||||
case ('b'):
|
||||
/* FALLTHROUGH */
|
||||
case ('i'):
|
||||
(*pos)--;
|
||||
break;
|
||||
default:
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos - 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
switch (tolower((unsigned char)p[(*pos)++])) {
|
||||
case ('b'):
|
||||
cp->flags |= TBL_CELL_BOLD;
|
||||
goto mod;
|
||||
case ('i'):
|
||||
cp->flags |= TBL_CELL_ITALIC;
|
||||
goto mod;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos - 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
cell(struct tbl_node *tbl, struct tbl_row *rp,
|
||||
int ln, const char *p, int *pos)
|
||||
{
|
||||
int i;
|
||||
enum tbl_cellt c;
|
||||
|
||||
/* Parse the column position (`r', `R', `|', ...). */
|
||||
|
||||
for (i = 0; i < KEYS_MAX; i++)
|
||||
if (tolower((unsigned char)p[*pos]) == keys[i].name)
|
||||
break;
|
||||
|
||||
if (KEYS_MAX == i) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
return(0);
|
||||
}
|
||||
|
||||
c = keys[i].key;
|
||||
|
||||
/*
|
||||
* If a span cell is found first, raise a warning and abort the
|
||||
* parse. FIXME: recover from this somehow?
|
||||
*/
|
||||
|
||||
if (NULL == rp->first && TBL_CELL_SPAN == c) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
|
||||
return(0);
|
||||
}
|
||||
|
||||
(*pos)++;
|
||||
|
||||
/* Extra check for the double-vertical. */
|
||||
|
||||
if (TBL_CELL_VERT == c && '|' == p[*pos]) {
|
||||
(*pos)++;
|
||||
c = TBL_CELL_DVERT;
|
||||
}
|
||||
|
||||
/* Disallow adjacent spacers. */
|
||||
|
||||
if (rp->last && (TBL_CELL_VERT == c || TBL_CELL_DVERT == c) &&
|
||||
(TBL_CELL_VERT == rp->last->pos ||
|
||||
TBL_CELL_DVERT == rp->last->pos)) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos - 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Allocate cell then parse its modifiers. */
|
||||
|
||||
return(mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
row(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
||||
{
|
||||
struct tbl_row *rp;
|
||||
|
||||
row: /*
|
||||
* EBNF describing this section:
|
||||
*
|
||||
* row ::= row_list [:space:]* [.]?[\n]
|
||||
* row_list ::= [:space:]* row_elem row_tail
|
||||
* row_tail ::= [:space:]*[,] row_list |
|
||||
* epsilon
|
||||
* row_elem ::= [\t\ ]*[:alpha:]+
|
||||
*/
|
||||
|
||||
rp = mandoc_calloc(1, sizeof(struct tbl_row));
|
||||
if (tbl->last_row) {
|
||||
tbl->last_row->next = rp;
|
||||
tbl->last_row = rp;
|
||||
} else
|
||||
tbl->last_row = tbl->first_row = rp;
|
||||
|
||||
cell:
|
||||
while (isspace((unsigned char)p[*pos]))
|
||||
(*pos)++;
|
||||
|
||||
/* Safely exit layout context. */
|
||||
|
||||
if ('.' == p[*pos]) {
|
||||
tbl->part = TBL_PART_DATA;
|
||||
if (NULL == tbl->first_row)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLNOLAYOUT, ln, *pos);
|
||||
(*pos)++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* End (and possibly restart) a row. */
|
||||
|
||||
if (',' == p[*pos]) {
|
||||
(*pos)++;
|
||||
goto row;
|
||||
} else if ('\0' == p[*pos])
|
||||
return;
|
||||
|
||||
if ( ! cell(tbl, rp, ln, p, pos))
|
||||
return;
|
||||
|
||||
goto cell;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
tbl_layout(struct tbl_node *tbl, int ln, const char *p)
|
||||
{
|
||||
int pos;
|
||||
|
||||
pos = 0;
|
||||
row(tbl, ln, p, &pos);
|
||||
|
||||
/* Always succeed. */
|
||||
return(1);
|
||||
}
|
||||
|
||||
static struct tbl_cell *
|
||||
cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
|
||||
{
|
||||
struct tbl_cell *p, *pp;
|
||||
struct tbl_head *h, *hp;
|
||||
|
||||
p = mandoc_calloc(1, sizeof(struct tbl_cell));
|
||||
|
||||
if (NULL != (pp = rp->last)) {
|
||||
rp->last->next = p;
|
||||
rp->last = p;
|
||||
} else
|
||||
rp->last = rp->first = p;
|
||||
|
||||
p->pos = pos;
|
||||
|
||||
/*
|
||||
* This is a little bit complicated. Here we determine the
|
||||
* header the corresponds to a cell. We add headers dynamically
|
||||
* when need be or re-use them, otherwise. As an example, given
|
||||
* the following:
|
||||
*
|
||||
* 1 c || l
|
||||
* 2 | c | l
|
||||
* 3 l l
|
||||
* 3 || c | l |.
|
||||
*
|
||||
* We first add the new headers (as there are none) in (1); then
|
||||
* in (2) we insert the first spanner (as it doesn't match up
|
||||
* with the header); then we re-use the prior data headers,
|
||||
* skipping over the spanners; then we re-use everything and add
|
||||
* a last spanner. Note that VERT headers are made into DVERT
|
||||
* ones.
|
||||
*/
|
||||
|
||||
h = pp ? pp->head->next : tbl->first_head;
|
||||
|
||||
if (h) {
|
||||
/* Re-use data header. */
|
||||
if (TBL_HEAD_DATA == h->pos &&
|
||||
(TBL_CELL_VERT != p->pos &&
|
||||
TBL_CELL_DVERT != p->pos)) {
|
||||
p->head = h;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Re-use spanner header. */
|
||||
if (TBL_HEAD_DATA != h->pos &&
|
||||
(TBL_CELL_VERT == p->pos ||
|
||||
TBL_CELL_DVERT == p->pos)) {
|
||||
head_adjust(p, h);
|
||||
p->head = h;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Right-shift headers with a new spanner. */
|
||||
if (TBL_HEAD_DATA == h->pos &&
|
||||
(TBL_CELL_VERT == p->pos ||
|
||||
TBL_CELL_DVERT == p->pos)) {
|
||||
hp = mandoc_calloc(1, sizeof(struct tbl_head));
|
||||
hp->ident = tbl->opts.cols++;
|
||||
hp->prev = h->prev;
|
||||
if (h->prev)
|
||||
h->prev->next = hp;
|
||||
if (h == tbl->first_head)
|
||||
tbl->first_head = hp;
|
||||
h->prev = hp;
|
||||
hp->next = h;
|
||||
head_adjust(p, hp);
|
||||
p->head = hp;
|
||||
return(p);
|
||||
}
|
||||
|
||||
if (NULL != (h = h->next)) {
|
||||
head_adjust(p, h);
|
||||
p->head = h;
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Fall through to default case... */
|
||||
}
|
||||
|
||||
hp = mandoc_calloc(1, sizeof(struct tbl_head));
|
||||
hp->ident = tbl->opts.cols++;
|
||||
|
||||
if (tbl->last_head) {
|
||||
hp->prev = tbl->last_head;
|
||||
tbl->last_head->next = hp;
|
||||
tbl->last_head = hp;
|
||||
} else
|
||||
tbl->last_head = tbl->first_head = hp;
|
||||
|
||||
head_adjust(p, hp);
|
||||
p->head = hp;
|
||||
return(p);
|
||||
}
|
||||
|
||||
static void
|
||||
head_adjust(const struct tbl_cell *cell, struct tbl_head *head)
|
||||
{
|
||||
if (TBL_CELL_VERT != cell->pos &&
|
||||
TBL_CELL_DVERT != cell->pos) {
|
||||
head->pos = TBL_HEAD_DATA;
|
||||
return;
|
||||
}
|
||||
|
||||
if (TBL_CELL_VERT == cell->pos)
|
||||
if (TBL_HEAD_DVERT != head->pos)
|
||||
head->pos = TBL_HEAD_VERT;
|
||||
|
||||
if (TBL_CELL_DVERT == cell->pos)
|
||||
head->pos = TBL_HEAD_DVERT;
|
||||
}
|
||||
|
||||
260
usr.bin/mdocml/dist/tbl_opts.c
vendored
260
usr.bin/mdocml/dist/tbl_opts.c
vendored
@@ -1,260 +0,0 @@
|
||||
/* $Vendor-Id: tbl_opts.c,v 1.8 2011/01/09 05:38:23 joerg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libroff.h"
|
||||
|
||||
enum tbl_ident {
|
||||
KEY_CENTRE = 0,
|
||||
KEY_DELIM,
|
||||
KEY_EXPAND,
|
||||
KEY_BOX,
|
||||
KEY_DBOX,
|
||||
KEY_ALLBOX,
|
||||
KEY_TAB,
|
||||
KEY_LINESIZE,
|
||||
KEY_NOKEEP,
|
||||
KEY_DPOINT,
|
||||
KEY_NOSPACE,
|
||||
KEY_FRAME,
|
||||
KEY_DFRAME,
|
||||
KEY_MAX
|
||||
};
|
||||
|
||||
struct tbl_phrase {
|
||||
const char *name;
|
||||
int key;
|
||||
enum tbl_ident ident;
|
||||
};
|
||||
|
||||
/* Handle Commonwealth/American spellings. */
|
||||
#define KEY_MAXKEYS 14
|
||||
|
||||
/* Maximum length of key name string. */
|
||||
#define KEY_MAXNAME 13
|
||||
|
||||
/* Maximum length of key number size. */
|
||||
#define KEY_MAXNUMSZ 10
|
||||
|
||||
static const struct tbl_phrase keys[KEY_MAXKEYS] = {
|
||||
{ "center", TBL_OPT_CENTRE, KEY_CENTRE},
|
||||
{ "centre", TBL_OPT_CENTRE, KEY_CENTRE},
|
||||
{ "delim", 0, KEY_DELIM},
|
||||
{ "expand", TBL_OPT_EXPAND, KEY_EXPAND},
|
||||
{ "box", TBL_OPT_BOX, KEY_BOX},
|
||||
{ "doublebox", TBL_OPT_DBOX, KEY_DBOX},
|
||||
{ "allbox", TBL_OPT_ALLBOX, KEY_ALLBOX},
|
||||
{ "frame", TBL_OPT_BOX, KEY_FRAME},
|
||||
{ "doubleframe", TBL_OPT_DBOX, KEY_DFRAME},
|
||||
{ "tab", 0, KEY_TAB},
|
||||
{ "linesize", 0, KEY_LINESIZE},
|
||||
{ "nokeep", TBL_OPT_NOKEEP, KEY_NOKEEP},
|
||||
{ "decimalpoint", 0, KEY_DPOINT},
|
||||
{ "nospaces", TBL_OPT_NOSPACE, KEY_NOSPACE},
|
||||
};
|
||||
|
||||
static int arg(struct tbl_node *, int,
|
||||
const char *, int *, enum tbl_ident);
|
||||
static void opt(struct tbl_node *, int,
|
||||
const char *, int *);
|
||||
|
||||
static int
|
||||
arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
|
||||
{
|
||||
int i;
|
||||
char buf[KEY_MAXNUMSZ];
|
||||
|
||||
while (isspace((unsigned char)p[*pos]))
|
||||
(*pos)++;
|
||||
|
||||
/* Arguments always begin with a parenthesis. */
|
||||
|
||||
if ('(' != p[*pos]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos);
|
||||
return(0);
|
||||
}
|
||||
|
||||
(*pos)++;
|
||||
|
||||
/*
|
||||
* The arguments can be ANY value, so we can't just stop at the
|
||||
* next close parenthesis (the argument can be a closed
|
||||
* parenthesis itself).
|
||||
*/
|
||||
|
||||
switch (key) {
|
||||
case (KEY_DELIM):
|
||||
if ('\0' == p[(*pos)++]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ('\0' == p[(*pos)++]) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
case (KEY_TAB):
|
||||
if ('\0' != (tbl->opts.tab = p[(*pos)++]))
|
||||
break;
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
return(0);
|
||||
case (KEY_LINESIZE):
|
||||
for (i = 0; i < KEY_MAXNUMSZ && p[*pos]; i++, (*pos)++) {
|
||||
buf[i] = p[*pos];
|
||||
if ( ! isdigit((unsigned char)buf[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < KEY_MAXNUMSZ) {
|
||||
buf[i] = '\0';
|
||||
tbl->opts.linesize = atoi(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
(*tbl->msg)(MANDOCERR_TBL, tbl->data, ln, *pos, NULL);
|
||||
return(0);
|
||||
case (KEY_DPOINT):
|
||||
if ('\0' != (tbl->opts.decimal = p[(*pos)++]))
|
||||
break;
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
return(0);
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* End with a close parenthesis. */
|
||||
|
||||
if (')' == p[(*pos)++])
|
||||
return(1);
|
||||
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos - 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
opt(struct tbl_node *tbl, int ln, const char *p, int *pos)
|
||||
{
|
||||
int i, sv;
|
||||
char buf[KEY_MAXNAME];
|
||||
|
||||
/*
|
||||
* Parse individual options from the stream as surrounded by
|
||||
* this goto. Each pass through the routine parses out a single
|
||||
* option and registers it. Option arguments are processed in
|
||||
* the arg() function.
|
||||
*/
|
||||
|
||||
again: /*
|
||||
* EBNF describing this section:
|
||||
*
|
||||
* options ::= option_list [:space:]* [;][\n]
|
||||
* option_list ::= option option_tail
|
||||
* option_tail ::= [:space:]+ option_list |
|
||||
* ::= epsilon
|
||||
* option ::= [:alpha:]+ args
|
||||
* args ::= [:space:]* [(] [:alpha:]+ [)]
|
||||
*/
|
||||
|
||||
while (isspace((unsigned char)p[*pos]))
|
||||
(*pos)++;
|
||||
|
||||
/* Safe exit point. */
|
||||
|
||||
if (';' == p[*pos])
|
||||
return;
|
||||
|
||||
/* Copy up to first non-alpha character. */
|
||||
|
||||
for (sv = *pos, i = 0; i < KEY_MAXNAME; i++, (*pos)++) {
|
||||
buf[i] = tolower((unsigned char)p[*pos]);
|
||||
if ( ! isalpha((unsigned char)buf[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Exit if buffer is empty (or overrun). */
|
||||
|
||||
if (KEY_MAXNAME == i || 0 == i) {
|
||||
TBL_MSG(tbl, MANDOCERR_TBL, ln, *pos);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[i] = '\0';
|
||||
|
||||
while (isspace((unsigned char)p[*pos]))
|
||||
(*pos)++;
|
||||
|
||||
/*
|
||||
* Look through all of the available keys to find one that
|
||||
* matches the input. FIXME: hashtable this.
|
||||
*/
|
||||
|
||||
for (i = 0; i < KEY_MAXKEYS; i++) {
|
||||
if (strcmp(buf, keys[i].name))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Note: this is more difficult to recover from, as we
|
||||
* can be anywhere in the option sequence and it's
|
||||
* harder to jump to the next. Meanwhile, just bail out
|
||||
* of the sequence altogether.
|
||||
*/
|
||||
|
||||
if (keys[i].key)
|
||||
tbl->opts.opts |= keys[i].key;
|
||||
else if ( ! arg(tbl, ln, p, pos, keys[i].ident))
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow us to recover from bad options by continuing to another
|
||||
* parse sequence.
|
||||
*/
|
||||
|
||||
if (KEY_MAXKEYS == i)
|
||||
TBL_MSG(tbl, MANDOCERR_TBLOPT, ln, sv);
|
||||
|
||||
goto again;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
tbl_option(struct tbl_node *tbl, int ln, const char *p)
|
||||
{
|
||||
int pos;
|
||||
|
||||
/*
|
||||
* Table options are always on just one line, so automatically
|
||||
* switch into the next input mode here.
|
||||
*/
|
||||
tbl->part = TBL_PART_LAYOUT;
|
||||
|
||||
pos = 0;
|
||||
opt(tbl, ln, p, &pos);
|
||||
|
||||
/* Always succeed. */
|
||||
return(1);
|
||||
}
|
||||
425
usr.bin/mdocml/dist/tbl_term.c
vendored
425
usr.bin/mdocml/dist/tbl_term.c
vendored
@@ -1,425 +0,0 @@
|
||||
/* $Vendor-Id: tbl_term.c,v 1.13 2011/01/07 14:59:52 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
|
||||
/* FIXME: `n' modifier doesn't always do the right thing. */
|
||||
/* FIXME: `n' modifier doesn't use the cell-spacing buffer. */
|
||||
|
||||
static size_t term_tbl_len(size_t, void *);
|
||||
static size_t term_tbl_strlen(const char *, void *);
|
||||
static void tbl_char(struct termp *, char, size_t);
|
||||
static void tbl_data(struct termp *, const struct tbl *,
|
||||
const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_hframe(struct termp *, const struct tbl_span *);
|
||||
static void tbl_literal(struct termp *, const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_number(struct termp *, const struct tbl *,
|
||||
const struct tbl_dat *,
|
||||
const struct roffcol *);
|
||||
static void tbl_hrule(struct termp *, const struct tbl_span *);
|
||||
static void tbl_vframe(struct termp *, const struct tbl *);
|
||||
static void tbl_vrule(struct termp *, const struct tbl_head *);
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void
|
||||
term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
const struct tbl_dat *dp;
|
||||
struct roffcol *col;
|
||||
size_t rmargin, maxrmargin;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* The first time we're invoked for a given table block,
|
||||
* calculate the table widths and decimal positions.
|
||||
*/
|
||||
|
||||
if (TBL_SPAN_FIRST & sp->flags) {
|
||||
term_flushln(tp);
|
||||
|
||||
tp->tbl.len = term_tbl_len;
|
||||
tp->tbl.slen = term_tbl_strlen;
|
||||
tp->tbl.arg = tp;
|
||||
|
||||
tblcalc(&tp->tbl, sp);
|
||||
}
|
||||
|
||||
/* Horizontal frame at the start of boxed tables. */
|
||||
|
||||
if (TBL_SPAN_FIRST & sp->flags)
|
||||
tbl_hframe(tp, sp);
|
||||
|
||||
/* Vertical frame at the start of each row. */
|
||||
|
||||
tbl_vframe(tp, sp->tbl);
|
||||
|
||||
/*
|
||||
* Now print the actual data itself depending on the span type.
|
||||
* Spanner spans get a horizontal rule; data spanners have their
|
||||
* data printed by matching data to header.
|
||||
*/
|
||||
|
||||
switch (sp->pos) {
|
||||
case (TBL_SPAN_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_SPAN_DHORIZ):
|
||||
tbl_hrule(tp, sp);
|
||||
break;
|
||||
case (TBL_SPAN_DATA):
|
||||
/* Iterate over template headers. */
|
||||
dp = sp->first;
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_DVERT):
|
||||
tbl_vrule(tp, hp);
|
||||
continue;
|
||||
case (TBL_HEAD_DATA):
|
||||
break;
|
||||
}
|
||||
|
||||
col = &tp->tbl.cols[hp->ident];
|
||||
tbl_data(tp, sp->tbl, dp, col);
|
||||
|
||||
/* Go to the next data cell. */
|
||||
if (dp)
|
||||
dp = dp->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
tbl_vframe(tp, sp->tbl);
|
||||
term_flushln(tp);
|
||||
|
||||
/*
|
||||
* If we're the last row, clean up after ourselves: clear the
|
||||
* existing table configuration and set it to NULL.
|
||||
*/
|
||||
|
||||
if (TBL_SPAN_LAST & sp->flags) {
|
||||
tbl_hframe(tp, sp);
|
||||
assert(tp->tbl.cols);
|
||||
free(tp->tbl.cols);
|
||||
tp->tbl.cols = NULL;
|
||||
}
|
||||
|
||||
tp->flags &= ~TERMP_NONOSPACE;
|
||||
tp->rmargin = rmargin;
|
||||
tp->maxrmargin = maxrmargin;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_hrule(struct termp *tp, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
char c;
|
||||
size_t width;
|
||||
|
||||
/*
|
||||
* An hrule extends across the entire table and is demarked by a
|
||||
* standalone `_' or whatnot in lieu of a table row. Spanning
|
||||
* headers are marked by a `+', as are table boundaries.
|
||||
*/
|
||||
|
||||
c = '-';
|
||||
if (TBL_SPAN_DHORIZ == sp->pos)
|
||||
c = '=';
|
||||
|
||||
/* FIXME: don't use `+' between data and a spanner! */
|
||||
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_DATA):
|
||||
tbl_char(tp, c, width);
|
||||
break;
|
||||
case (TBL_HEAD_DVERT):
|
||||
tbl_char(tp, '+', width);
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_HEAD_VERT):
|
||||
tbl_char(tp, '+', width);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_hframe(struct termp *tp, const struct tbl_span *sp)
|
||||
{
|
||||
const struct tbl_head *hp;
|
||||
size_t width;
|
||||
|
||||
if ( ! (TBL_OPT_BOX & sp->tbl->opts ||
|
||||
TBL_OPT_DBOX & sp->tbl->opts))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Print out the horizontal part of a frame or double frame. A
|
||||
* double frame has an unbroken `-' outer line the width of the
|
||||
* table, bordered by `+'. The frame (or inner frame, in the
|
||||
* case of the double frame) is a `-' bordered by `+' and broken
|
||||
* by `+' whenever a span is encountered.
|
||||
*/
|
||||
|
||||
if (TBL_OPT_DBOX & sp->tbl->opts) {
|
||||
term_word(tp, "+");
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
tbl_char(tp, '-', width);
|
||||
}
|
||||
term_word(tp, "+");
|
||||
term_flushln(tp);
|
||||
}
|
||||
|
||||
term_word(tp, "+");
|
||||
for (hp = sp->head; hp; hp = hp->next) {
|
||||
width = tp->tbl.cols[hp->ident].width;
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_DATA):
|
||||
tbl_char(tp, '-', width);
|
||||
break;
|
||||
default:
|
||||
tbl_char(tp, '+', width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
term_word(tp, "+");
|
||||
term_flushln(tp);
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_data(struct termp *tp, const struct tbl *tbl,
|
||||
const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
enum tbl_cellt pos;
|
||||
|
||||
if (NULL == dp) {
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (dp->pos) {
|
||||
case (TBL_DATA_NONE):
|
||||
tbl_char(tp, ASCII_NBRSP, col->width);
|
||||
return;
|
||||
case (TBL_DATA_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_DATA_NHORIZ):
|
||||
tbl_char(tp, '-', col->width);
|
||||
return;
|
||||
case (TBL_DATA_NDHORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_DATA_DHORIZ):
|
||||
tbl_char(tp, '=', col->width);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
pos = dp && dp->layout ? dp->layout->pos : TBL_CELL_LEFT;
|
||||
|
||||
switch (pos) {
|
||||
case (TBL_CELL_HORIZ):
|
||||
tbl_char(tp, '-', col->width);
|
||||
break;
|
||||
case (TBL_CELL_DHORIZ):
|
||||
tbl_char(tp, '=', col->width);
|
||||
break;
|
||||
case (TBL_CELL_LONG):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_CENTRE):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_LEFT):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_CELL_RIGHT):
|
||||
tbl_literal(tp, dp, col);
|
||||
break;
|
||||
case (TBL_CELL_NUMBER):
|
||||
tbl_number(tp, tbl, dp, col);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_vrule(struct termp *tp, const struct tbl_head *hp)
|
||||
{
|
||||
|
||||
switch (hp->pos) {
|
||||
case (TBL_HEAD_VERT):
|
||||
term_word(tp, "|");
|
||||
break;
|
||||
case (TBL_HEAD_DVERT):
|
||||
term_word(tp, "||");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_vframe(struct termp *tp, const struct tbl *tbl)
|
||||
{
|
||||
|
||||
if (TBL_OPT_BOX & tbl->opts || TBL_OPT_DBOX & tbl->opts)
|
||||
term_word(tp, "|");
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_char(struct termp *tp, char c, size_t len)
|
||||
{
|
||||
size_t i, sz;
|
||||
char cp[2];
|
||||
|
||||
cp[0] = c;
|
||||
cp[1] = '\0';
|
||||
|
||||
sz = term_strlen(tp, cp);
|
||||
|
||||
for (i = 0; i < len; i += sz)
|
||||
term_word(tp, cp);
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_literal(struct termp *tp, const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
size_t padl, padr, ssz;
|
||||
enum tbl_cellt pos;
|
||||
const char *str;
|
||||
|
||||
padl = padr = 0;
|
||||
|
||||
pos = dp && dp->layout ? dp->layout->pos : TBL_CELL_LEFT;
|
||||
str = dp && dp->string ? dp->string : "";
|
||||
|
||||
ssz = term_len(tp, 1);
|
||||
|
||||
switch (pos) {
|
||||
case (TBL_CELL_LONG):
|
||||
padl = ssz;
|
||||
padr = col->width - term_strlen(tp, str) - ssz;
|
||||
break;
|
||||
case (TBL_CELL_CENTRE):
|
||||
padl = col->width - term_strlen(tp, str);
|
||||
if (padl % 2)
|
||||
padr++;
|
||||
padl /= 2;
|
||||
padr += padl;
|
||||
break;
|
||||
case (TBL_CELL_RIGHT):
|
||||
padl = col->width - term_strlen(tp, str);
|
||||
break;
|
||||
default:
|
||||
padr = col->width - term_strlen(tp, str);
|
||||
break;
|
||||
}
|
||||
|
||||
tbl_char(tp, ASCII_NBRSP, padl);
|
||||
term_word(tp, str);
|
||||
tbl_char(tp, ASCII_NBRSP, padr);
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_number(struct termp *tp, const struct tbl *tbl,
|
||||
const struct tbl_dat *dp,
|
||||
const struct roffcol *col)
|
||||
{
|
||||
char *cp;
|
||||
char buf[2];
|
||||
const char *str;
|
||||
size_t sz, psz, ssz, d, padl;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* See calc_data_number(). Left-pad by taking the offset of our
|
||||
* and the maximum decimal; right-pad by the remaining amount.
|
||||
*/
|
||||
|
||||
str = dp && dp->string ? dp->string : "";
|
||||
|
||||
sz = term_strlen(tp, str);
|
||||
|
||||
buf[0] = tbl->decimal;
|
||||
buf[1] = '\0';
|
||||
|
||||
psz = term_strlen(tp, buf);
|
||||
|
||||
if (NULL != (cp = strchr(str, tbl->decimal))) {
|
||||
buf[1] = '\0';
|
||||
for (ssz = 0, i = 0; cp != &str[i]; i++) {
|
||||
buf[0] = str[i];
|
||||
ssz += term_strlen(tp, buf);
|
||||
}
|
||||
d = ssz + psz;
|
||||
} else
|
||||
d = sz + psz;
|
||||
|
||||
sz += term_len(tp, 2);
|
||||
d += term_len(tp, 1);
|
||||
|
||||
padl = col->decimal - d;
|
||||
|
||||
tbl_char(tp, ASCII_NBRSP, padl);
|
||||
term_word(tp, str);
|
||||
tbl_char(tp, ASCII_NBRSP, col->width - sz - padl);
|
||||
}
|
||||
|
||||
740
usr.bin/mdocml/dist/term.c
vendored
740
usr.bin/mdocml/dist/term.c
vendored
@@ -1,740 +0,0 @@
|
||||
/* $Vendor-Id: term.c,v 1.176 2011/01/04 13:14:26 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "chars.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "main.h"
|
||||
|
||||
static void spec(struct termp *, enum roffdeco,
|
||||
const char *, size_t);
|
||||
static void res(struct termp *, const char *, size_t);
|
||||
static void bufferc(struct termp *, char);
|
||||
static void adjbuf(struct termp *p, size_t);
|
||||
static void encode(struct termp *, const char *, size_t);
|
||||
|
||||
|
||||
void
|
||||
term_free(struct termp *p)
|
||||
{
|
||||
|
||||
if (p->buf)
|
||||
free(p->buf);
|
||||
if (p->symtab)
|
||||
chars_free(p->symtab);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_begin(struct termp *p, term_margin head,
|
||||
term_margin foot, const void *arg)
|
||||
{
|
||||
|
||||
p->headf = head;
|
||||
p->footf = foot;
|
||||
p->argf = arg;
|
||||
(*p->begin)(p);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_end(struct termp *p)
|
||||
{
|
||||
|
||||
(*p->end)(p);
|
||||
}
|
||||
|
||||
|
||||
struct termp *
|
||||
term_alloc(enum termenc enc)
|
||||
{
|
||||
struct termp *p;
|
||||
|
||||
p = calloc(1, sizeof(struct termp));
|
||||
if (NULL == p) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
|
||||
p->enc = enc;
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flush a line of text. A "line" is loosely defined as being something
|
||||
* that should be followed by a newline, regardless of whether it's
|
||||
* broken apart by newlines getting there. A line can also be a
|
||||
* fragment of a columnar list (`Bl -tag' or `Bl -column'), which does
|
||||
* not have a trailing newline.
|
||||
*
|
||||
* The following flags may be specified:
|
||||
*
|
||||
* - TERMP_NOLPAD: when beginning to write the line, don't left-pad the
|
||||
* offset value. This is useful when doing columnar lists where the
|
||||
* prior column has right-padded.
|
||||
*
|
||||
* - TERMP_NOBREAK: this is the most important and is used when making
|
||||
* columns. In short: don't print a newline and instead pad to the
|
||||
* right margin. Used in conjunction with TERMP_NOLPAD.
|
||||
*
|
||||
* - TERMP_TWOSPACE: when padding, make sure there are at least two
|
||||
* space characters of padding. Otherwise, rather break the line.
|
||||
*
|
||||
* - TERMP_DANGLE: don't newline when TERMP_NOBREAK is specified and
|
||||
* the line is overrun, and don't pad-right if it's underrun.
|
||||
*
|
||||
* - TERMP_HANG: like TERMP_DANGLE, but doesn't newline when
|
||||
* overruning, instead save the position and continue at that point
|
||||
* when the next invocation.
|
||||
*
|
||||
* In-line line breaking:
|
||||
*
|
||||
* If TERMP_NOBREAK is specified and the line overruns the right
|
||||
* margin, it will break and pad-right to the right margin after
|
||||
* writing. If maxrmargin is violated, it will break and continue
|
||||
* writing from the right-margin, which will lead to the above scenario
|
||||
* upon exit. Otherwise, the line will break at the right margin.
|
||||
*/
|
||||
void
|
||||
term_flushln(struct termp *p)
|
||||
{
|
||||
int i; /* current input position in p->buf */
|
||||
size_t vis; /* current visual position on output */
|
||||
size_t vbl; /* number of blanks to prepend to output */
|
||||
size_t vend; /* end of word visual position on output */
|
||||
size_t bp; /* visual right border position */
|
||||
size_t dv; /* temporary for visual pos calculations */
|
||||
int j; /* temporary loop index for p->buf */
|
||||
int jhy; /* last hyph before overflow w/r/t j */
|
||||
size_t maxvis; /* output position of visible boundary */
|
||||
size_t mmax; /* used in calculating bp */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
assert (p->rmargin >= p->offset);
|
||||
dv = p->rmargin - p->offset;
|
||||
maxvis = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
|
||||
dv = p->maxrmargin - p->offset;
|
||||
mmax = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
|
||||
|
||||
bp = TERMP_NOBREAK & p->flags ? mmax : maxvis;
|
||||
|
||||
/*
|
||||
* Indent the first line of a paragraph.
|
||||
*/
|
||||
vbl = p->flags & TERMP_NOLPAD ? (size_t)0 : p->offset;
|
||||
|
||||
vis = vend = 0;
|
||||
i = 0;
|
||||
|
||||
while (i < (int)p->col) {
|
||||
/*
|
||||
* Handle literal tab characters: collapse all
|
||||
* subsequent tabs into a single huge set of spaces.
|
||||
*/
|
||||
while (i < (int)p->col && '\t' == p->buf[i]) {
|
||||
vend = (vis / p->tabwidth + 1) * p->tabwidth;
|
||||
vbl += vend - vis;
|
||||
vis = vend;
|
||||
i++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count up visible word characters. Control sequences
|
||||
* (starting with the CSI) aren't counted. A space
|
||||
* generates a non-printing word, which is valid (the
|
||||
* space is printed according to regular spacing rules).
|
||||
*/
|
||||
|
||||
for (j = i, jhy = 0; j < (int)p->col; j++) {
|
||||
if ((j && ' ' == p->buf[j]) || '\t' == p->buf[j])
|
||||
break;
|
||||
|
||||
/* Back over the the last printed character. */
|
||||
if (8 == p->buf[j]) {
|
||||
assert(j);
|
||||
vend -= (*p->width)(p, p->buf[j - 1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Regular word. */
|
||||
/* Break at the hyphen point if we overrun. */
|
||||
if (vend > vis && vend < bp &&
|
||||
ASCII_HYPH == p->buf[j])
|
||||
jhy = j;
|
||||
|
||||
vend += (*p->width)(p, p->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) {
|
||||
vend -= vis;
|
||||
(*p->endline)(p);
|
||||
if (TERMP_NOBREAK & p->flags) {
|
||||
p->viscol = p->rmargin;
|
||||
(*p->advance)(p, p->rmargin);
|
||||
vend += p->rmargin - p->offset;
|
||||
} else {
|
||||
p->viscol = 0;
|
||||
vbl = p->offset;
|
||||
}
|
||||
|
||||
/* Remove the p->overstep width. */
|
||||
|
||||
bp += (size_t)p->overstep;
|
||||
p->overstep = 0;
|
||||
}
|
||||
|
||||
/* Write out the [remaining] word. */
|
||||
for ( ; i < (int)p->col; i++) {
|
||||
if (vend > bp && jhy > 0 && i > jhy)
|
||||
break;
|
||||
if ('\t' == p->buf[i])
|
||||
break;
|
||||
if (' ' == p->buf[i]) {
|
||||
j = i;
|
||||
while (' ' == p->buf[i])
|
||||
i++;
|
||||
dv = (size_t)(i - j) * (*p->width)(p, ' ');
|
||||
vbl += dv;
|
||||
vend += dv;
|
||||
break;
|
||||
}
|
||||
if (ASCII_NBRSP == p->buf[i]) {
|
||||
vbl += (*p->width)(p, ' ');
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we definitely know there will be
|
||||
* printable characters to output,
|
||||
* so write preceding white space now.
|
||||
*/
|
||||
if (vbl) {
|
||||
(*p->advance)(p, vbl);
|
||||
p->viscol += vbl;
|
||||
vbl = 0;
|
||||
}
|
||||
|
||||
if (ASCII_HYPH == p->buf[i]) {
|
||||
(*p->letter)(p, '-');
|
||||
p->viscol += (*p->width)(p, '-');
|
||||
} else {
|
||||
(*p->letter)(p, p->buf[i]);
|
||||
p->viscol += (*p->width)(p, p->buf[i]);
|
||||
}
|
||||
}
|
||||
vis = vend;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there was trailing white space, it was not printed;
|
||||
* so reset the cursor position accordingly.
|
||||
*/
|
||||
vis -= vbl;
|
||||
|
||||
p->col = 0;
|
||||
p->overstep = 0;
|
||||
|
||||
if ( ! (TERMP_NOBREAK & p->flags)) {
|
||||
p->viscol = 0;
|
||||
(*p->endline)(p);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TERMP_HANG & p->flags) {
|
||||
/* We need one blank after the tag. */
|
||||
p->overstep = (int)(vis - maxvis + (*p->width)(p, ' '));
|
||||
|
||||
/*
|
||||
* Behave exactly the same way as groff:
|
||||
* If we have overstepped the margin, temporarily move
|
||||
* it to the right and flag the rest of the line to be
|
||||
* shorter.
|
||||
* If we landed right at the margin, be happy.
|
||||
* If we are one step before the margin, temporarily
|
||||
* move it one step LEFT and flag the rest of the line
|
||||
* to be longer.
|
||||
*/
|
||||
if (p->overstep >= -1) {
|
||||
assert((int)maxvis + p->overstep >= 0);
|
||||
maxvis += (size_t)p->overstep;
|
||||
} else
|
||||
p->overstep = 0;
|
||||
|
||||
} else if (TERMP_DANGLE & p->flags)
|
||||
return;
|
||||
|
||||
/* Right-pad. */
|
||||
if (maxvis > vis +
|
||||
((TERMP_TWOSPACE & p->flags) ? (*p->width)(p, ' ') : 0)) {
|
||||
p->viscol += maxvis - vis;
|
||||
(*p->advance)(p, maxvis - vis);
|
||||
vis += (maxvis - vis);
|
||||
} else { /* ...or newline break. */
|
||||
(*p->endline)(p);
|
||||
p->viscol = p->rmargin;
|
||||
(*p->advance)(p, p->rmargin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A newline only breaks an existing line; it won't assert vertical
|
||||
* space. All data in the output buffer is flushed prior to the newline
|
||||
* assertion.
|
||||
*/
|
||||
void
|
||||
term_newln(struct termp *p)
|
||||
{
|
||||
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
if (0 == p->col && 0 == p->viscol) {
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
return;
|
||||
}
|
||||
term_flushln(p);
|
||||
p->flags &= ~TERMP_NOLPAD;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Asserts a vertical space (a full, empty line-break between lines).
|
||||
* Note that if used twice, this will cause two blank spaces and so on.
|
||||
* All data in the output buffer is flushed prior to the newline
|
||||
* assertion.
|
||||
*/
|
||||
void
|
||||
term_vspace(struct termp *p)
|
||||
{
|
||||
|
||||
term_newln(p);
|
||||
p->viscol = 0;
|
||||
(*p->endline)(p);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
spec(struct termp *p, enum roffdeco d, const char *word, size_t len)
|
||||
{
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
rhs = chars_spec2str(p->symtab, word, len, &sz);
|
||||
if (rhs)
|
||||
encode(p, rhs, sz);
|
||||
else if (DECO_SSPECIAL == d)
|
||||
encode(p, word, len);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
res(struct termp *p, const char *word, size_t len)
|
||||
{
|
||||
const char *rhs;
|
||||
size_t sz;
|
||||
|
||||
rhs = chars_res2str(p->symtab, word, len, &sz);
|
||||
if (rhs)
|
||||
encode(p, rhs, sz);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_fontlast(struct termp *p)
|
||||
{
|
||||
enum termfont f;
|
||||
|
||||
f = p->fontl;
|
||||
p->fontl = p->fontq[p->fonti];
|
||||
p->fontq[p->fonti] = f;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_fontrepl(struct termp *p, enum termfont f)
|
||||
{
|
||||
|
||||
p->fontl = p->fontq[p->fonti];
|
||||
p->fontq[p->fonti] = f;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_fontpush(struct termp *p, enum termfont f)
|
||||
{
|
||||
|
||||
assert(p->fonti + 1 < 10);
|
||||
p->fontl = p->fontq[p->fonti];
|
||||
p->fontq[++p->fonti] = f;
|
||||
}
|
||||
|
||||
|
||||
const void *
|
||||
term_fontq(struct termp *p)
|
||||
{
|
||||
|
||||
return(&p->fontq[p->fonti]);
|
||||
}
|
||||
|
||||
|
||||
enum termfont
|
||||
term_fonttop(struct termp *p)
|
||||
{
|
||||
|
||||
return(p->fontq[p->fonti]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_fontpopq(struct termp *p, const void *key)
|
||||
{
|
||||
|
||||
while (p->fonti >= 0 && key != &p->fontq[p->fonti])
|
||||
p->fonti--;
|
||||
assert(p->fonti >= 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
term_fontpop(struct termp *p)
|
||||
{
|
||||
|
||||
assert(p->fonti);
|
||||
p->fonti--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle pwords, partial words, which may be either a single word or a
|
||||
* phrase that cannot be broken down (such as a literal string). This
|
||||
* handles word styling.
|
||||
*/
|
||||
void
|
||||
term_word(struct termp *p, const char *word)
|
||||
{
|
||||
const char *sv, *seq;
|
||||
size_t ssz;
|
||||
enum roffdeco deco;
|
||||
|
||||
sv = word;
|
||||
|
||||
if (word[0] && '\0' == word[1])
|
||||
switch (word[0]) {
|
||||
case('.'):
|
||||
/* FALLTHROUGH */
|
||||
case(','):
|
||||
/* FALLTHROUGH */
|
||||
case(';'):
|
||||
/* FALLTHROUGH */
|
||||
case(':'):
|
||||
/* FALLTHROUGH */
|
||||
case('?'):
|
||||
/* FALLTHROUGH */
|
||||
case('!'):
|
||||
/* FALLTHROUGH */
|
||||
case(')'):
|
||||
/* FALLTHROUGH */
|
||||
case(']'):
|
||||
if ( ! (TERMP_IGNDELIM & p->flags))
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! (TERMP_NOSPACE & p->flags)) {
|
||||
if ( ! (TERMP_KEEP & p->flags)) {
|
||||
if (TERMP_PREKEEP & p->flags)
|
||||
p->flags |= TERMP_KEEP;
|
||||
bufferc(p, ' ');
|
||||
if (TERMP_SENTENCE & p->flags)
|
||||
bufferc(p, ' ');
|
||||
} else
|
||||
bufferc(p, ASCII_NBRSP);
|
||||
}
|
||||
|
||||
if ( ! (p->flags & TERMP_NONOSPACE))
|
||||
p->flags &= ~TERMP_NOSPACE;
|
||||
else
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM);
|
||||
|
||||
while (*word) {
|
||||
if ((ssz = strcspn(word, "\\")) > 0)
|
||||
encode(p, word, ssz);
|
||||
|
||||
word += ssz;
|
||||
if ('\\' != *word)
|
||||
continue;
|
||||
|
||||
seq = ++word;
|
||||
word += a2roffdeco(&deco, &seq, &ssz);
|
||||
|
||||
switch (deco) {
|
||||
case (DECO_RESERVED):
|
||||
res(p, seq, ssz);
|
||||
break;
|
||||
case (DECO_SPECIAL):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_SSPECIAL):
|
||||
spec(p, deco, seq, ssz);
|
||||
break;
|
||||
case (DECO_BOLD):
|
||||
term_fontrepl(p, TERMFONT_BOLD);
|
||||
break;
|
||||
case (DECO_ITALIC):
|
||||
term_fontrepl(p, TERMFONT_UNDER);
|
||||
break;
|
||||
case (DECO_ROMAN):
|
||||
term_fontrepl(p, TERMFONT_NONE);
|
||||
break;
|
||||
case (DECO_PREVIOUS):
|
||||
term_fontlast(p);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (DECO_NOSPACE == deco && '\0' == *word)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that we don't process the pipe: the parser sees it as
|
||||
* punctuation, but we don't in terms of typography.
|
||||
*/
|
||||
if (sv[0] && '\0' == sv[1])
|
||||
switch (sv[0]) {
|
||||
case('('):
|
||||
/* FALLTHROUGH */
|
||||
case('['):
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
adjbuf(struct termp *p, size_t sz)
|
||||
{
|
||||
|
||||
if (0 == p->maxcols)
|
||||
p->maxcols = 1024;
|
||||
while (sz >= p->maxcols)
|
||||
p->maxcols <<= 2;
|
||||
|
||||
p->buf = realloc(p->buf, p->maxcols);
|
||||
if (NULL == p->buf) {
|
||||
perror(NULL);
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bufferc(struct termp *p, char c)
|
||||
{
|
||||
|
||||
if (p->col + 1 >= p->maxcols)
|
||||
adjbuf(p, p->col + 1);
|
||||
|
||||
p->buf[(int)p->col++] = c;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
encode(struct termp *p, const char *word, size_t sz)
|
||||
{
|
||||
enum termfont f;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Encode and buffer a string of characters. If the current
|
||||
* font mode is unset, buffer directly, else encode then buffer
|
||||
* character by character.
|
||||
*/
|
||||
|
||||
if (TERMFONT_NONE == (f = term_fonttop(p))) {
|
||||
if (p->col + sz >= p->maxcols)
|
||||
adjbuf(p, p->col + sz);
|
||||
memcpy(&p->buf[(int)p->col], word, sz);
|
||||
p->col += sz;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pre-buffer, assuming worst-case. */
|
||||
|
||||
if (p->col + 1 + (sz * 3) >= p->maxcols)
|
||||
adjbuf(p, p->col + 1 + (sz * 3));
|
||||
|
||||
for (i = 0; i < (int)sz; i++) {
|
||||
if ( ! isgraph((u_char)word[i])) {
|
||||
p->buf[(int)p->col++] = word[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TERMFONT_UNDER == f)
|
||||
p->buf[(int)p->col++] = '_';
|
||||
else
|
||||
p->buf[(int)p->col++] = word[i];
|
||||
|
||||
p->buf[(int)p->col++] = 8;
|
||||
p->buf[(int)p->col++] = word[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
term_len(const struct termp *p, size_t sz)
|
||||
{
|
||||
|
||||
return((*p->width)(p, ' ') * sz);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
term_strlen(const struct termp *p, const char *cp)
|
||||
{
|
||||
size_t sz, ssz, rsz, i;
|
||||
enum roffdeco d;
|
||||
const char *seq, *rhs;
|
||||
|
||||
for (sz = 0; '\0' != *cp; )
|
||||
/*
|
||||
* Account for escaped sequences within string length
|
||||
* calculations. This follows the logic in term_word()
|
||||
* as we must calculate the width of produced strings.
|
||||
*/
|
||||
if ('\\' == *cp) {
|
||||
seq = ++cp;
|
||||
cp += a2roffdeco(&d, &seq, &ssz);
|
||||
|
||||
switch (d) {
|
||||
case (DECO_RESERVED):
|
||||
rhs = chars_res2str
|
||||
(p->symtab, seq, ssz, &rsz);
|
||||
break;
|
||||
case (DECO_SPECIAL):
|
||||
/* FALLTHROUGH */
|
||||
case (DECO_SSPECIAL):
|
||||
rhs = chars_spec2str
|
||||
(p->symtab, seq, ssz, &rsz);
|
||||
|
||||
/* Allow for one-char escapes. */
|
||||
if (DECO_SSPECIAL != d || rhs)
|
||||
break;
|
||||
|
||||
rhs = seq;
|
||||
rsz = ssz;
|
||||
break;
|
||||
default:
|
||||
rhs = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rhs)
|
||||
for (i = 0; i < rsz; i++)
|
||||
sz += (*p->width)(p, *rhs++);
|
||||
} else if (ASCII_NBRSP == *cp) {
|
||||
sz += (*p->width)(p, ' ');
|
||||
cp++;
|
||||
} else if (ASCII_HYPH == *cp) {
|
||||
sz += (*p->width)(p, '-');
|
||||
cp++;
|
||||
} else
|
||||
sz += (*p->width)(p, *cp++);
|
||||
|
||||
return(sz);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
size_t
|
||||
term_vspan(const struct termp *p, const struct roffsu *su)
|
||||
{
|
||||
double r;
|
||||
|
||||
switch (su->unit) {
|
||||
case (SCALE_CM):
|
||||
r = su->scale * 2;
|
||||
break;
|
||||
case (SCALE_IN):
|
||||
r = su->scale * 6;
|
||||
break;
|
||||
case (SCALE_PC):
|
||||
r = su->scale;
|
||||
break;
|
||||
case (SCALE_PT):
|
||||
r = su->scale / 8;
|
||||
break;
|
||||
case (SCALE_MM):
|
||||
r = su->scale / 1000;
|
||||
break;
|
||||
case (SCALE_VS):
|
||||
r = su->scale;
|
||||
break;
|
||||
default:
|
||||
r = su->scale - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (r < 0.0)
|
||||
r = 0.0;
|
||||
return(/* LINTED */(size_t)
|
||||
r);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
term_hspan(const struct termp *p, const struct roffsu *su)
|
||||
{
|
||||
double v;
|
||||
|
||||
v = ((*p->hspan)(p, su));
|
||||
if (v < 0.0)
|
||||
v = 0.0;
|
||||
return((size_t) /* LINTED */
|
||||
v);
|
||||
}
|
||||
156
usr.bin/mdocml/dist/term.h
vendored
156
usr.bin/mdocml/dist/term.h
vendored
@@ -1,156 +0,0 @@
|
||||
/* $Vendor-Id: term.h,v 1.79 2011/01/05 15:37:23 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef TERM_H
|
||||
#define TERM_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct termp;
|
||||
|
||||
enum termenc {
|
||||
TERMENC_ASCII
|
||||
};
|
||||
|
||||
enum termtype {
|
||||
TERMTYPE_CHAR,
|
||||
TERMTYPE_PS,
|
||||
TERMTYPE_PDF
|
||||
};
|
||||
|
||||
enum termfont {
|
||||
TERMFONT_NONE = 0,
|
||||
TERMFONT_BOLD,
|
||||
TERMFONT_UNDER,
|
||||
TERMFONT__MAX
|
||||
};
|
||||
|
||||
#define TERM_MAXMARGIN 100000 /* FIXME */
|
||||
|
||||
typedef void (*term_margin)(struct termp *, const void *);
|
||||
|
||||
struct termp_ps {
|
||||
int flags;
|
||||
#define PS_INLINE (1 << 0) /* we're in a word */
|
||||
#define PS_MARGINS (1 << 1) /* we're in the margins */
|
||||
#define PS_NEWPAGE (1 << 2) /* new page, no words yet */
|
||||
size_t pscol; /* visible column (AFM units) */
|
||||
size_t psrow; /* visible row (AFM units) */
|
||||
char *psmarg; /* margin buf */
|
||||
size_t psmargsz; /* margin buf size */
|
||||
size_t psmargcur; /* cur index in margin buf */
|
||||
char last; /* character buffer */
|
||||
enum termfont lastf; /* last set font */
|
||||
size_t scale; /* font scaling factor */
|
||||
size_t pages; /* number of pages shown */
|
||||
size_t lineheight; /* line height (AFM units) */
|
||||
size_t top; /* body top (AFM units) */
|
||||
size_t bottom; /* body bottom (AFM units) */
|
||||
size_t height; /* page height (AFM units */
|
||||
size_t width; /* page width (AFM units) */
|
||||
size_t left; /* body left (AFM units) */
|
||||
size_t header; /* header pos (AFM units) */
|
||||
size_t footer; /* footer pos (AFM units) */
|
||||
size_t pdfbytes; /* current output byte */
|
||||
size_t pdflastpg; /* byte of last page mark */
|
||||
size_t pdfbody; /* start of body object */
|
||||
size_t *pdfobjs; /* table of object offsets */
|
||||
size_t pdfobjsz; /* size of pdfobjs */
|
||||
};
|
||||
|
||||
struct termp_tbl {
|
||||
int width; /* width in fixed chars */
|
||||
int decimal; /* decimal point position */
|
||||
};
|
||||
|
||||
struct termp {
|
||||
enum termtype type;
|
||||
struct rofftbl tbl; /* table configuration */
|
||||
size_t defrmargin; /* Right margin of the device. */
|
||||
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 viscol; /* Chars on current line. */
|
||||
int overstep; /* See termp_flushln(). */
|
||||
int flags;
|
||||
#define TERMP_SENTENCE (1 << 1) /* Space before a sentence. */
|
||||
#define TERMP_NOSPACE (1 << 2) /* No space before words. */
|
||||
#define TERMP_NOLPAD (1 << 3) /* See term_flushln(). */
|
||||
#define TERMP_NOBREAK (1 << 4) /* See term_flushln(). */
|
||||
#define TERMP_IGNDELIM (1 << 6) /* Delims like regulars. */
|
||||
#define TERMP_NONOSPACE (1 << 7) /* No space (no autounset). */
|
||||
#define TERMP_DANGLE (1 << 8) /* See term_flushln(). */
|
||||
#define TERMP_HANG (1 << 9) /* See term_flushln(). */
|
||||
#define TERMP_TWOSPACE (1 << 10) /* See term_flushln(). */
|
||||
#define TERMP_NOSPLIT (1 << 11) /* See termp_an_pre/post(). */
|
||||
#define TERMP_SPLIT (1 << 12) /* See termp_an_pre/post(). */
|
||||
#define TERMP_ANPREC (1 << 13) /* See termp_an_pre(). */
|
||||
#define TERMP_KEEP (1 << 14) /* Keep words together. */
|
||||
#define TERMP_PREKEEP (1 << 15) /* ...starting with the next one. */
|
||||
char *buf; /* Output buffer. */
|
||||
enum termenc enc; /* Type of encoding. */
|
||||
void *symtab; /* Encoded-symbol table. */
|
||||
enum termfont fontl; /* Last font set. */
|
||||
enum termfont fontq[10]; /* Symmetric fonts. */
|
||||
int fonti; /* Index of font stack. */
|
||||
term_margin headf; /* invoked to print head */
|
||||
term_margin footf; /* invoked to print foot */
|
||||
void (*letter)(struct termp *, char);
|
||||
void (*begin)(struct termp *);
|
||||
void (*end)(struct termp *);
|
||||
void (*endline)(struct termp *);
|
||||
void (*advance)(struct termp *, size_t);
|
||||
size_t (*width)(const struct termp *, char);
|
||||
double (*hspan)(const struct termp *,
|
||||
const struct roffsu *);
|
||||
const void *argf; /* arg for headf/footf */
|
||||
union {
|
||||
struct termp_ps ps;
|
||||
} engine;
|
||||
};
|
||||
|
||||
struct termp *term_alloc(enum termenc);
|
||||
void term_tbl(struct termp *, const struct tbl_span *);
|
||||
void term_free(struct termp *);
|
||||
void term_newln(struct termp *);
|
||||
void term_vspace(struct termp *);
|
||||
void term_word(struct termp *, const char *);
|
||||
void term_flushln(struct termp *);
|
||||
void term_begin(struct termp *, term_margin,
|
||||
term_margin, const void *);
|
||||
void term_end(struct termp *);
|
||||
|
||||
size_t term_hspan(const struct termp *,
|
||||
const struct roffsu *);
|
||||
size_t 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);
|
||||
|
||||
enum termfont term_fonttop(struct termp *);
|
||||
const void *term_fontq(struct termp *);
|
||||
void term_fontpush(struct termp *, enum termfont);
|
||||
void term_fontpop(struct termp *);
|
||||
void term_fontpopq(struct termp *, const void *);
|
||||
void term_fontrepl(struct termp *, enum termfont);
|
||||
void term_fontlast(struct termp *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /*!TERM_H*/
|
||||
187
usr.bin/mdocml/dist/term_ascii.c
vendored
187
usr.bin/mdocml/dist/term_ascii.c
vendored
@@ -1,187 +0,0 @@
|
||||
/* $Vendor-Id: term_ascii.c,v 1.11 2011/01/02 12:21:07 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "out.h"
|
||||
#include "term.h"
|
||||
#include "main.h"
|
||||
|
||||
static double ascii_hspan(const struct termp *,
|
||||
const struct roffsu *);
|
||||
static size_t ascii_width(const struct termp *, char);
|
||||
static void ascii_advance(struct termp *, size_t);
|
||||
static void ascii_begin(struct termp *);
|
||||
static void ascii_end(struct termp *);
|
||||
static void ascii_endline(struct termp *);
|
||||
static void ascii_letter(struct termp *, char);
|
||||
|
||||
|
||||
void *
|
||||
ascii_alloc(char *outopts)
|
||||
{
|
||||
struct termp *p;
|
||||
const char *toks[2];
|
||||
char *v;
|
||||
|
||||
if (NULL == (p = term_alloc(TERMENC_ASCII)))
|
||||
return(NULL);
|
||||
|
||||
p->tabwidth = 5;
|
||||
p->defrmargin = 78;
|
||||
|
||||
p->advance = ascii_advance;
|
||||
p->begin = ascii_begin;
|
||||
p->end = ascii_end;
|
||||
p->endline = ascii_endline;
|
||||
p->hspan = ascii_hspan;
|
||||
p->letter = ascii_letter;
|
||||
p->type = TERMTYPE_CHAR;
|
||||
p->width = ascii_width;
|
||||
|
||||
toks[0] = "width";
|
||||
toks[1] = NULL;
|
||||
|
||||
while (outopts && *outopts)
|
||||
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
|
||||
case (0):
|
||||
p->defrmargin = (size_t)atoi(v);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enforce a lower boundary. */
|
||||
if (p->defrmargin < 58)
|
||||
p->defrmargin = 58;
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static size_t
|
||||
ascii_width(const struct termp *p, char c)
|
||||
{
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ascii_free(void *arg)
|
||||
{
|
||||
|
||||
term_free((struct termp *)arg);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ascii_letter(struct termp *p, char c)
|
||||
{
|
||||
|
||||
/* LINTED */
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ascii_begin(struct termp *p)
|
||||
{
|
||||
|
||||
(*p->headf)(p, p->argf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ascii_end(struct termp *p)
|
||||
{
|
||||
|
||||
(*p->footf)(p, p->argf);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ascii_endline(struct termp *p)
|
||||
{
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ascii_advance(struct termp *p, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* Just print whitespace on the terminal. */
|
||||
for (i = 0; i < len; i++)
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static double
|
||||
ascii_hspan(const struct termp *p, const struct roffsu *su)
|
||||
{
|
||||
double r;
|
||||
|
||||
/*
|
||||
* Approximate based on character width. These are generated
|
||||
* entirely by eyeballing the screen, but appear to be correct.
|
||||
*/
|
||||
|
||||
switch (su->unit) {
|
||||
case (SCALE_CM):
|
||||
r = 4 * su->scale;
|
||||
break;
|
||||
case (SCALE_IN):
|
||||
r = 10 * su->scale;
|
||||
break;
|
||||
case (SCALE_PC):
|
||||
r = (10 * su->scale) / 6;
|
||||
break;
|
||||
case (SCALE_PT):
|
||||
r = (10 * su->scale) / 72;
|
||||
break;
|
||||
case (SCALE_MM):
|
||||
r = su->scale / 1000;
|
||||
break;
|
||||
case (SCALE_VS):
|
||||
r = su->scale * 2 - 1;
|
||||
break;
|
||||
default:
|
||||
r = su->scale;
|
||||
break;
|
||||
}
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
1161
usr.bin/mdocml/dist/term_ps.c
vendored
1161
usr.bin/mdocml/dist/term_ps.c
vendored
File diff suppressed because it is too large
Load Diff
8
usr.bin/mdocml/dist/test-strlcat.c
vendored
8
usr.bin/mdocml/dist/test-strlcat.c
vendored
@@ -1,8 +0,0 @@
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
strlcat(argv[0], argv[1], 10);
|
||||
return 0;
|
||||
}
|
||||
8
usr.bin/mdocml/dist/test-strlcpy.c
vendored
8
usr.bin/mdocml/dist/test-strlcpy.c
vendored
@@ -1,8 +0,0 @@
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
strlcpy(argv[0], argv[1], 10);
|
||||
return 0;
|
||||
}
|
||||
289
usr.bin/mdocml/dist/tree.c
vendored
289
usr.bin/mdocml/dist/tree.c
vendored
@@ -1,289 +0,0 @@
|
||||
/* $Vendor-Id: tree.c,v 1.31 2011/01/03 13:59:21 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "mdoc.h"
|
||||
#include "man.h"
|
||||
#include "main.h"
|
||||
|
||||
static void print_mdoc(const struct mdoc_node *, int);
|
||||
static void print_man(const struct man_node *, int);
|
||||
static void print_span(const struct tbl_span *, int);
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
tree_mdoc(void *arg, const struct mdoc *mdoc)
|
||||
{
|
||||
|
||||
print_mdoc(mdoc_node(mdoc), 0);
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
tree_man(void *arg, const struct man *man)
|
||||
{
|
||||
|
||||
print_man(man_node(man), 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_mdoc(const struct mdoc_node *n, int indent)
|
||||
{
|
||||
const char *p, *t;
|
||||
int i, j;
|
||||
size_t argc, sz;
|
||||
char **params;
|
||||
struct mdoc_argv *argv;
|
||||
|
||||
argv = NULL;
|
||||
argc = sz = 0;
|
||||
params = NULL;
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_ROOT):
|
||||
t = "root";
|
||||
break;
|
||||
case (MDOC_BLOCK):
|
||||
t = "block";
|
||||
break;
|
||||
case (MDOC_HEAD):
|
||||
t = "block-head";
|
||||
break;
|
||||
case (MDOC_BODY):
|
||||
if (n->end)
|
||||
t = "body-end";
|
||||
else
|
||||
t = "block-body";
|
||||
break;
|
||||
case (MDOC_TAIL):
|
||||
t = "block-tail";
|
||||
break;
|
||||
case (MDOC_ELEM):
|
||||
t = "elem";
|
||||
break;
|
||||
case (MDOC_TEXT):
|
||||
t = "text";
|
||||
break;
|
||||
case (MDOC_TBL):
|
||||
t = "tbl";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
p = NULL;
|
||||
|
||||
switch (n->type) {
|
||||
case (MDOC_TEXT):
|
||||
p = n->string;
|
||||
break;
|
||||
case (MDOC_BODY):
|
||||
p = mdoc_macronames[n->tok];
|
||||
break;
|
||||
case (MDOC_HEAD):
|
||||
p = mdoc_macronames[n->tok];
|
||||
break;
|
||||
case (MDOC_TAIL):
|
||||
p = mdoc_macronames[n->tok];
|
||||
break;
|
||||
case (MDOC_ELEM):
|
||||
p = mdoc_macronames[n->tok];
|
||||
if (n->args) {
|
||||
argv = n->args->argv;
|
||||
argc = n->args->argc;
|
||||
}
|
||||
break;
|
||||
case (MDOC_BLOCK):
|
||||
p = mdoc_macronames[n->tok];
|
||||
if (n->args) {
|
||||
argv = n->args->argv;
|
||||
argc = n->args->argc;
|
||||
}
|
||||
break;
|
||||
case (MDOC_TBL):
|
||||
break;
|
||||
case (MDOC_ROOT):
|
||||
p = "root";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (n->span) {
|
||||
assert(NULL == p);
|
||||
print_span(n->span, indent);
|
||||
} else {
|
||||
for (i = 0; i < indent; i++)
|
||||
putchar('\t');
|
||||
|
||||
printf("%s (%s)", p, t);
|
||||
|
||||
for (i = 0; i < (int)argc; i++) {
|
||||
printf(" -%s", mdoc_argnames[argv[i].arg]);
|
||||
if (argv[i].sz > 0)
|
||||
printf(" [");
|
||||
for (j = 0; j < (int)argv[i].sz; j++)
|
||||
printf(" [%s]", argv[i].value[j]);
|
||||
if (argv[i].sz > 0)
|
||||
printf(" ]");
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)sz; i++)
|
||||
printf(" [%s]", params[i]);
|
||||
|
||||
printf(" %d:%d", n->line, n->pos);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
|
||||
if (n->child)
|
||||
print_mdoc(n->child, indent + 1);
|
||||
if (n->next)
|
||||
print_mdoc(n->next, indent);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_man(const struct man_node *n, int indent)
|
||||
{
|
||||
const char *p, *t;
|
||||
int i;
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_ROOT):
|
||||
t = "root";
|
||||
break;
|
||||
case (MAN_ELEM):
|
||||
t = "elem";
|
||||
break;
|
||||
case (MAN_TEXT):
|
||||
t = "text";
|
||||
break;
|
||||
case (MAN_BLOCK):
|
||||
t = "block";
|
||||
break;
|
||||
case (MAN_HEAD):
|
||||
t = "block-head";
|
||||
break;
|
||||
case (MAN_BODY):
|
||||
t = "block-body";
|
||||
break;
|
||||
case (MAN_TBL):
|
||||
t = "tbl";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
p = NULL;
|
||||
|
||||
switch (n->type) {
|
||||
case (MAN_TEXT):
|
||||
p = n->string;
|
||||
break;
|
||||
case (MAN_ELEM):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_BLOCK):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_HEAD):
|
||||
/* FALLTHROUGH */
|
||||
case (MAN_BODY):
|
||||
p = man_macronames[n->tok];
|
||||
break;
|
||||
case (MAN_ROOT):
|
||||
p = "root";
|
||||
break;
|
||||
case (MAN_TBL):
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (n->span) {
|
||||
assert(NULL == p);
|
||||
print_span(n->span, indent);
|
||||
} else {
|
||||
for (i = 0; i < indent; i++)
|
||||
putchar('\t');
|
||||
printf("%s (%s) %d:%d", p, t, n->line, n->pos);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
|
||||
if (n->child)
|
||||
print_man(n->child, indent + 1);
|
||||
if (n->next)
|
||||
print_man(n->next, indent);
|
||||
}
|
||||
|
||||
static void
|
||||
print_span(const struct tbl_span *sp, int indent)
|
||||
{
|
||||
const struct tbl_dat *dp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
putchar('\t');
|
||||
|
||||
printf("tbl: ");
|
||||
|
||||
switch (sp->pos) {
|
||||
case (TBL_SPAN_HORIZ):
|
||||
putchar('-');
|
||||
return;
|
||||
case (TBL_SPAN_DHORIZ):
|
||||
putchar('=');
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (dp = sp->first; dp; dp = dp->next) {
|
||||
switch (dp->pos) {
|
||||
case (TBL_DATA_HORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_DATA_NHORIZ):
|
||||
putchar('-');
|
||||
continue;
|
||||
case (TBL_DATA_DHORIZ):
|
||||
/* FALLTHROUGH */
|
||||
case (TBL_DATA_NDHORIZ):
|
||||
putchar('=');
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("[%s%s]", dp->string, dp->layout ? "" : "*");
|
||||
if (dp->next)
|
||||
putchar(' ');
|
||||
}
|
||||
}
|
||||
38
usr.bin/mdocml/dist/vol.c
vendored
38
usr.bin/mdocml/dist/vol.c
vendored
@@ -1,38 +0,0 @@
|
||||
/* $Vendor-Id: vol.c,v 1.8 2010/06/19 20:46:28 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mandoc.h"
|
||||
#include "libmdoc.h"
|
||||
|
||||
#define LINE(x, y) \
|
||||
if (0 == strcmp(p, x)) return(y);
|
||||
|
||||
const char *
|
||||
mdoc_a2vol(const char *p)
|
||||
{
|
||||
|
||||
#include "vol.in"
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
35
usr.bin/mdocml/dist/vol.in
vendored
35
usr.bin/mdocml/dist/vol.in
vendored
@@ -1,35 +0,0 @@
|
||||
/* $Vendor-Id: vol.in,v 1.6 2010/06/19 20:46:28 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines volume titles for .Dt.
|
||||
*
|
||||
* Be sure to escape strings.
|
||||
*/
|
||||
|
||||
LINE("USD", "User\'s Supplementary Documents")
|
||||
LINE("PS1", "Programmer\'s Supplementary Documents")
|
||||
LINE("AMD", "Ancestral Manual Documents")
|
||||
LINE("SMM", "System Manager\'s Manual")
|
||||
LINE("URM", "User\'s Reference Manual")
|
||||
LINE("PRM", "Programmer\'s Manual")
|
||||
LINE("KM", "Kernel Manual")
|
||||
LINE("IND", "Manual Master Index")
|
||||
LINE("MMI", "Manual Master Index")
|
||||
LINE("LOCAL", "Local Manual")
|
||||
LINE("LOC", "Local Manual")
|
||||
LINE("CON", "Contributed Software Manual")
|
||||
@@ -1,5 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.2 2010/06/01 21:32:39 joerg Exp $
|
||||
|
||||
SUBDIR= libman libmdoc libroff
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
@@ -1,3 +0,0 @@
|
||||
# $NetBSD: Makefile.inc,v 1.1 2009/10/21 18:04:52 joerg Exp $
|
||||
|
||||
.include "${.PARSEDIR}/../Makefile.inc"
|
||||
@@ -1,10 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.2 2011/01/12 23:02:22 joerg Exp $
|
||||
|
||||
LIBISPRIVATE= yes
|
||||
|
||||
LIB= man
|
||||
SRCS= man_macro.c man.c man_hash.c man_validate.c \
|
||||
mandoc.c man_argv.c
|
||||
MAN= mdoc.3
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,11 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.2 2011/01/12 23:02:22 joerg Exp $
|
||||
|
||||
LIBISPRIVATE= yes
|
||||
|
||||
LIB= mdoc
|
||||
SRCS= mdoc_macro.c mdoc.c mdoc_hash.c mdoc_strings.c \
|
||||
mdoc_argv.c mdoc_validate.c lib.c att.c \
|
||||
arch.c vol.c msec.c st.c mandoc.c
|
||||
MAN= man.3
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,11 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.2 2011/01/12 23:02:22 joerg Exp $
|
||||
|
||||
LIBISPRIVATE= yes
|
||||
|
||||
LIB= roff
|
||||
SRCS= roff.c tbl.c tbl_opts.c tbl_layout.c tbl_data.c
|
||||
MAN=
|
||||
|
||||
COPTS.tbl_layout.c= -Wno-shadow
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,38 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.6 2011/01/12 23:02:22 joerg Exp $
|
||||
|
||||
MAN= mandoc_man.7 mandoc_char.7 mandoc_mdoc.7 mandoc_roff.7 mandoc_tbl.7
|
||||
|
||||
.include <bsd.init.mk>
|
||||
|
||||
mandoc_man.7: ${DISTDIR}/man.7
|
||||
${_MKTARGET_CREATE}
|
||||
rm -f ${.TARGET}
|
||||
${TOOL_CAT} ${DISTDIR}/man.7 > ${.TARGET}
|
||||
|
||||
mandoc_mdoc.7: ${DISTDIR}/mdoc.7
|
||||
${_MKTARGET_CREATE}
|
||||
rm -f ${.TARGET}
|
||||
${TOOL_CAT} ${DISTDIR}/mdoc.7 > ${.TARGET}
|
||||
|
||||
mandoc_roff.7: ${DISTDIR}/roff.7
|
||||
${_MKTARGET_CREATE}
|
||||
rm -f ${.TARGET}
|
||||
${TOOL_CAT} ${DISTDIR}/roff.7 > ${.TARGET}
|
||||
|
||||
mandoc_tbl.7: ${DISTDIR}/tbl.7
|
||||
${_MKTARGET_CREATE}
|
||||
rm -f ${.TARGET}
|
||||
${TOOL_CAT} ${DISTDIR}/tbl.7 > ${.TARGET}
|
||||
|
||||
CLEANFILES+= mandoc_man.7 mandoc_mdoc.7 mandoc_roff.7 mandoc_tbl.7
|
||||
|
||||
.if (${MKHTML} != "no") && (${MKMAN} != "no")
|
||||
FILES= ${DISTDIR}/example.style.css
|
||||
FILESDIR= /usr/man
|
||||
FILESNAME= style.css
|
||||
.endif
|
||||
|
||||
cleandepend:
|
||||
:
|
||||
|
||||
.include <bsd.man.mk>
|
||||
@@ -1,14 +0,0 @@
|
||||
#/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd dist
|
||||
rm -rf ChangeLog.xsl style.css index.css *.sgml
|
||||
|
||||
uuencode external.png < external.png > external.png.uu
|
||||
rm external.png
|
||||
|
||||
for f in [a-z]*; do
|
||||
sed -e 's/[$]Id:/\$Vendor-Id:/' \
|
||||
-e 's/[$]Mdocdate: \([^$]*\) \([0-9][0-9][0-9][0-9]\) [$]/\1, \2/' < $f > $f.new && mv $f.new $f
|
||||
done
|
||||
Reference in New Issue
Block a user