summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-03-30 19:47:48 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-03-30 19:47:48 +0000
commitb0b643c847c8a9530fc19fc081c52b9b6f5159dd (patch)
treeee93f2fc78dc0fddd4abbfdcd79f9df0714656ed
parent1f5b9d128ee296272c97a8e1a191d09c75b10fd1 (diff)
downloadmandoc-b0b643c847c8a9530fc19fc081c52b9b6f5159dd.tar.gz
Implement the roff(7) .ll (line length) request.
Found by naddy@ in the textproc/enchant(1) port. Of course, do not use this in new manuals.
-rw-r--r--TODO3
-rw-r--r--man.c2
-rw-r--r--man.h1
-rw-r--r--man_html.c1
-rw-r--r--man_macro.c1
-rw-r--r--man_term.c12
-rw-r--r--man_validate.c1
-rw-r--r--mdoc.c2
-rw-r--r--mdoc.h1
-rw-r--r--mdoc_argv.c1
-rw-r--r--mdoc_html.c12
-rw-r--r--mdoc_macro.c1
-rw-r--r--mdoc_man.c10
-rw-r--r--mdoc_term.c18
-rw-r--r--mdoc_validate.c1
-rw-r--r--roff.715
-rw-r--r--term.h5
-rw-r--r--term_ascii.c16
-rw-r--r--term_ps.c17
19 files changed, 109 insertions, 11 deletions
diff --git a/TODO b/TODO
index 64fac2f2..fb283b78 100644
--- a/TODO
+++ b/TODO
@@ -27,9 +27,6 @@ None known.
- .fc (field control)
found by naddy@ in xloadimage(1)
-- .ll (line length)
- found by naddy@ in textproc/enchant(1) Sat, 12 Oct 2013 03:27:10 +0200
-
- .nr third argument (auto-increment step size, requires \n+)
found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700
diff --git a/man.c b/man.c
index 2fa49fb8..ca625305 100644
--- a/man.c
+++ b/man.c
@@ -45,7 +45,7 @@ const char *const __man_macronames[MAN_MAX] = {
"fi", "RE", "RS", "DT",
"UC", "PD", "AT", "in",
"ft", "OP", "EX", "EE",
- "UR", "UE"
+ "UR", "UE", "ll"
};
const char * const *man_macronames = __man_macronames;
diff --git a/man.h b/man.h
index fa479cce..fd6b9f91 100644
--- a/man.h
+++ b/man.h
@@ -57,6 +57,7 @@ enum mant {
MAN_EE,
MAN_UR,
MAN_UE,
+ MAN_ll,
MAN_MAX
};
diff --git a/man_html.c b/man_html.c
index 65c3e5ee..b1134e1a 100644
--- a/man_html.c
+++ b/man_html.c
@@ -119,6 +119,7 @@ static const struct htmlman mans[MAN_MAX] = {
{ man_literal_pre, NULL }, /* EE */
{ man_UR_pre, NULL }, /* UR */
{ NULL, NULL }, /* UE */
+ { man_ign_pre, NULL }, /* ll */
};
/*
diff --git a/man_macro.c b/man_macro.c
index bcfdcc55..9049a6ad 100644
--- a/man_macro.c
+++ b/man_macro.c
@@ -91,6 +91,7 @@ const struct man_macro __man_macros[MAN_MAX] = {
{ in_line_eoln, MAN_BSCOPE }, /* EE */
{ blk_exp, MAN_BSCOPE | MAN_EXPLICIT }, /* UR */
{ blk_close, 0 }, /* UE */
+ { in_line_eoln, 0 }, /* ll */
};
const struct man_macro * const man_macros = __man_macros;
diff --git a/man_term.c b/man_term.c
index 5babe788..0b18d4a5 100644
--- a/man_term.c
+++ b/man_term.c
@@ -84,6 +84,7 @@ static int pre_ft(DECL_ARGS);
static int pre_ign(DECL_ARGS);
static int pre_in(DECL_ARGS);
static int pre_literal(DECL_ARGS);
+static int pre_ll(DECL_ARGS);
static int pre_sp(DECL_ARGS);
static void post_IP(DECL_ARGS);
@@ -133,6 +134,7 @@ static const struct termact termacts[MAN_MAX] = {
{ pre_literal, NULL, 0 }, /* EE */
{ pre_UR, post_UR, 0 }, /* UR */
{ NULL, NULL, 0 }, /* UE */
+ { pre_ll, NULL, MAN_NOTEXT }, /* ll */
};
@@ -237,6 +239,16 @@ pre_ign(DECL_ARGS)
/* ARGSUSED */
static int
+pre_ll(DECL_ARGS)
+{
+
+ (*p->setwidth)(p, n->nchild ? a2width(p, n->child->string) : 0);
+ return(0);
+}
+
+
+/* ARGSUSED */
+static int
pre_I(DECL_ARGS)
{
diff --git a/man_validate.c b/man_validate.c
index 43f0b691..4e8374f4 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -124,6 +124,7 @@ static const struct man_valid man_valids[MAN_MAX] = {
{ NULL, posts_fi }, /* EE */
{ NULL, posts_ur }, /* UR */
{ NULL, NULL }, /* UE */
+ { NULL, NULL }, /* ll */
};
diff --git a/mdoc.c b/mdoc.c
index c3f84c4a..58c65508 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -72,7 +72,7 @@ const char *const __mdoc_macronames[MDOC_MAX] = {
/* LINTED */
"Dx", "%Q", "br", "sp",
/* LINTED */
- "%U", "Ta"
+ "%U", "Ta", "ll",
};
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
diff --git a/mdoc.h b/mdoc.h
index 86da0334..e4144406 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -140,6 +140,7 @@ enum mdoct {
MDOC_sp,
MDOC__U,
MDOC_Ta,
+ MDOC_ll,
MDOC_MAX
};
diff --git a/mdoc_argv.c b/mdoc_argv.c
index a7e609b1..17179f43 100644
--- a/mdoc_argv.c
+++ b/mdoc_argv.c
@@ -267,6 +267,7 @@ static const struct mdocarg mdocargs[MDOC_MAX] = {
{ ARGSFL_NONE, NULL }, /* sp */
{ ARGSFL_NONE, NULL }, /* %U */
{ ARGSFL_NONE, NULL }, /* Ta */
+ { ARGSFL_NONE, NULL }, /* ll */
};
diff --git a/mdoc_html.c b/mdoc_html.c
index 02390c42..bc6d4efa 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2014 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
@@ -95,6 +96,7 @@ static int mdoc_it_pre(MDOC_ARGS);
static int mdoc_lb_pre(MDOC_ARGS);
static int mdoc_li_pre(MDOC_ARGS);
static int mdoc_lk_pre(MDOC_ARGS);
+static int mdoc_ll_pre(MDOC_ARGS);
static int mdoc_mt_pre(MDOC_ARGS);
static int mdoc_ms_pre(MDOC_ARGS);
static int mdoc_nd_pre(MDOC_ARGS);
@@ -242,6 +244,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
{mdoc_sp_pre, NULL}, /* sp */
{mdoc__x_pre, mdoc__x_post}, /* %U */
{NULL, NULL}, /* Ta */
+ {mdoc_ll_pre, NULL}, /* ll */
};
static const char * const lists[LIST_MAX] = {
@@ -1599,12 +1602,19 @@ mdoc_sm_pre(MDOC_ARGS)
/* ARGSUSED */
static int
+mdoc_ll_pre(MDOC_ARGS)
+{
+
+ return(0);
+}
+
+/* ARGSUSED */
+static int
mdoc_pp_pre(MDOC_ARGS)
{
print_otag(h, TAG_P, 0, NULL);
return(0);
-
}
/* ARGSUSED */
diff --git a/mdoc_macro.c b/mdoc_macro.c
index 1b12f916..7c80d234 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -211,6 +211,7 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ in_line_eoln, 0 }, /* sp */
{ in_line_eoln, 0 }, /* %U */
{ phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */
+ { in_line_eoln, 0 }, /* ll */
};
const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
diff --git a/mdoc_man.c b/mdoc_man.c
index a6a9fa05..44039ab4 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -90,6 +90,7 @@ static int pre_in(DECL_ARGS);
static int pre_it(DECL_ARGS);
static int pre_lk(DECL_ARGS);
static int pre_li(DECL_ARGS);
+static int pre_ll(DECL_ARGS);
static int pre_nm(DECL_ARGS);
static int pre_no(DECL_ARGS);
static int pre_ns(DECL_ARGS);
@@ -241,6 +242,7 @@ static const struct manact manacts[MDOC_MAX + 1] = {
{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
+ { NULL, pre_ll, post_sp, NULL, NULL }, /* ll */
{ NULL, NULL, NULL, NULL, NULL }, /* ROOT */
};
@@ -1406,6 +1408,14 @@ pre_lk(DECL_ARGS)
}
static int
+pre_ll(DECL_ARGS)
+{
+
+ print_line(".ll", 0);
+ return(1);
+}
+
+static int
pre_li(DECL_ARGS)
{
diff --git a/mdoc_term.c b/mdoc_term.c
index 73ef6d72..8da9366b 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -104,6 +104,7 @@ static int termp_ft_pre(DECL_ARGS);
static int termp_in_pre(DECL_ARGS);
static int termp_it_pre(DECL_ARGS);
static int termp_li_pre(DECL_ARGS);
+static int termp_ll_pre(DECL_ARGS);
static int termp_lk_pre(DECL_ARGS);
static int termp_nd_pre(DECL_ARGS);
static int termp_nm_pre(DECL_ARGS);
@@ -244,6 +245,7 @@ static const struct termact termacts[MDOC_MAX] = {
{ termp_sp_pre, NULL }, /* sp */
{ NULL, termp____post }, /* %U */
{ NULL, NULL }, /* Ta */
+ { termp_ll_pre, NULL }, /* ll */
};
@@ -384,8 +386,10 @@ print_mdoc_node(DECL_ARGS)
if (MDOC_EOS & n->flags)
p->flags |= TERMP_SENTENCE;
- p->offset = offset;
- p->rmargin = rmargin;
+ if (MDOC_ll != n->tok) {
+ p->offset = offset;
+ p->rmargin = rmargin;
+ }
}
@@ -615,6 +619,16 @@ print_bvspace(struct termp *p,
/* ARGSUSED */
static int
+termp_ll_pre(DECL_ARGS)
+{
+
+ (*p->setwidth)(p, n->nchild ? a2width(p, n->child->string) : 0);
+ return(0);
+}
+
+
+/* ARGSUSED */
+static int
termp_it_pre(DECL_ARGS)
{
const struct mdoc_node *bl, *nn;
diff --git a/mdoc_validate.c b/mdoc_validate.c
index b56e0eda..86e5a267 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -304,6 +304,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, posts_sp }, /* sp */
{ NULL, posts_text1 }, /* %U */
{ NULL, NULL }, /* Ta */
+ { NULL, NULL }, /* ll */
};
#define RSORD_MAX 14 /* Number of `Rs' blocks. */
diff --git a/roff.7 b/roff.7
index d557a2e8..7a60cf30 100644
--- a/roff.7
+++ b/roff.7
@@ -874,6 +874,21 @@ Otherwise, it only terminates the
and arguments following it or the
.Sq \&..
request are discarded.
+.Ss \&ll
+Change the output line length.
+Its syntax is as follows:
+.Pp
+.D1 Pf . Cm \&ll Op Ar width
+.Pp
+If the
+.Ar width
+argument is omitted, the line length is reset to its previous value.
+The default setting for terminal output is 78n.
+Using this request in new manuals is discouraged for several reasons,
+among others because it overrides the
+.Xr mandoc 1
+.Fl O Cm width
+command line option.
.Ss \&ne
Declare the need for the specified minimum vertical space
before the next trap or the bottom of the page.
diff --git a/term.h b/term.h
index eced1a0f..f676afe8 100644
--- a/term.h
+++ b/term.h
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2012, 2013, 2014 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
@@ -57,6 +57,7 @@ struct termp {
int mdocstyle; /* imitate mdoc(7) output */
size_t defindent; /* Default indent for text. */
size_t defrmargin; /* Right margin of the device. */
+ size_t lastrmargin; /* Right margin before the last ll. */
size_t rmargin; /* Current right margin. */
size_t maxrmargin; /* Max right margin. */
size_t maxcols; /* Max size of buf. */
@@ -94,6 +95,7 @@ struct termp {
void (*end)(struct termp *);
void (*endline)(struct termp *);
void (*advance)(struct termp *, size_t);
+ void (*setwidth)(struct termp *, size_t);
size_t (*width)(const struct termp *, int);
double (*hspan)(const struct termp *,
const struct roffsu *);
@@ -112,6 +114,7 @@ void term_begin(struct termp *, term_margin,
term_margin, const void *);
void term_end(struct termp *);
+void term_setwidth(struct termp *, size_t);
size_t term_hspan(const struct termp *,
const struct roffsu *);
size_t term_vspan(const struct termp *,
diff --git a/term_ascii.c b/term_ascii.c
index 3fccc675..a9242348 100644
--- a/term_ascii.c
+++ b/term_ascii.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2014 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
@@ -57,6 +58,7 @@ static void ascii_begin(struct termp *);
static void ascii_end(struct termp *);
static void ascii_endline(struct termp *);
static void ascii_letter(struct termp *, int);
+static void ascii_setwidth(struct termp *, size_t);
#ifdef USE_WCHAR
static void locale_advance(struct termp *, size_t);
@@ -75,7 +77,7 @@ ascii_init(enum termenc enc, char *outopts)
p = mandoc_calloc(1, sizeof(struct termp));
p->tabwidth = 5;
- p->defrmargin = 78;
+ p->defrmargin = p->lastrmargin = 78;
p->begin = ascii_begin;
p->end = ascii_end;
@@ -86,6 +88,7 @@ ascii_init(enum termenc enc, char *outopts)
p->advance = ascii_advance;
p->endline = ascii_endline;
p->letter = ascii_letter;
+ p->setwidth = ascii_setwidth;
p->width = ascii_width;
#ifdef USE_WCHAR
@@ -157,6 +160,17 @@ locale_alloc(char *outopts)
return(ascii_init(TERMENC_LOCALE, outopts));
}
+static void
+ascii_setwidth(struct termp *p, size_t width)
+{
+ size_t lastwidth;
+
+ lastwidth = p->defrmargin;
+ p->rmargin = p->maxrmargin = p->defrmargin =
+ width ? width : p->lastrmargin;
+ p->lastrmargin = lastwidth;
+}
+
/* ARGSUSED */
static size_t
ascii_width(const struct termp *p, int c)
diff --git a/term_ps.c b/term_ps.c
index 7ab58682..845028a9 100644
--- a/term_ps.c
+++ b/term_ps.c
@@ -1,6 +1,7 @@
/* $Id$ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2014 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
@@ -75,6 +76,7 @@ struct termp_ps {
size_t bottom; /* body bottom (AFM units) */
size_t height; /* page height (AFM units */
size_t width; /* page width (AFM units) */
+ size_t lastwidth; /* page width before last ll */
size_t left; /* body left (AFM units) */
size_t header; /* header pos (AFM units) */
size_t footer; /* footer pos (AFM units) */
@@ -104,6 +106,7 @@ __attribute__((__format__ (__printf__, 2, 3)))
static void ps_printf(struct termp *, const char *, ...);
static void ps_putchar(struct termp *, char);
static void ps_setfont(struct termp *, enum termfont);
+static void ps_setwidth(struct termp *, size_t);
static struct termp *pspdf_alloc(char *);
static void pdf_obj(struct termp *, size_t);
@@ -449,6 +452,7 @@ pspdf_alloc(char *outopts)
p->endline = ps_endline;
p->hspan = ps_hspan;
p->letter = ps_letter;
+ p->setwidth = ps_setwidth;
p->width = ps_width;
toks[0] = "paper";
@@ -517,7 +521,7 @@ pspdf_alloc(char *outopts)
lineheight = PNT2AFM(p, ((double)p->ps->scale * 1.4));
- p->ps->width = (size_t)pagex;
+ p->ps->width = p->ps->lastwidth = (size_t)pagex;
p->ps->height = (size_t)pagey;
p->ps->header = pagey - (marginy / 2) - (lineheight / 2);
p->ps->top = pagey - marginy;
@@ -531,6 +535,17 @@ pspdf_alloc(char *outopts)
}
+static void
+ps_setwidth(struct termp *p, size_t width)
+{
+ size_t lastwidth;
+
+ lastwidth = p->ps->width;
+ p->ps->width = width ? width : p->ps->lastwidth;
+ p->ps->lastwidth = lastwidth;
+}
+
+
void
pspdf_free(void *arg)
{