From: schwarze@mdocml.bsd.lv
To: source@mdocml.bsd.lv
Subject: mdocml: Correct indentation for lists and displays inside lists.
Date: Sun, 18 Nov 2012 13:02:23 -0500 (EST) [thread overview]
Message-ID: <201211181802.qAII2NVF031841@krisdoz.my.domain> (raw)
Log Message:
-----------
Correct indentation for lists and displays inside lists.
Inspired by a diff from millert@, but implemented rather
differently and with slightly better functionality.
In particular, this one respects -offset and -width
arguments found in the input file.
Modified Files:
--------------
mdocml:
mdoc_man.c
Revision Data
-------------
Index: mdoc_man.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_man.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -Lmdoc_man.c -Lmdoc_man.c -u -p -r1.42 -r1.43
--- mdoc_man.c
+++ mdoc_man.c
@@ -254,6 +254,11 @@ static int outflags;
#define MMAN_An_split (1 << 8) /* author mode is "split" */
#define MMAN_An_nosplit (1 << 9) /* author mode is "nosplit" */
+#define BL_STACK_MAX 32
+
+static size_t Bl_stack[BL_STACK_MAX]; /* offsets [chars] */
+static int Bl_stack_post[BL_STACK_MAX]; /* add final .RE */
+static int Bl_stack_len; /* number of nested Bl blocks */
static int TPremain; /* characters before tag is full */
static struct {
@@ -390,6 +395,7 @@ print_offs(const char *v)
struct roffsu su;
size_t sz;
+ /* Convert v into a number (of characters). */
if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
sz = 0;
else if (0 == strcmp(v, "indent"))
@@ -397,11 +403,29 @@ print_offs(const char *v)
else if (0 == strcmp(v, "indent-two"))
sz = 12;
else if (a2roffsu(v, &su, SCALE_MAX)) {
- print_word(v);
- return;
+ if (SCALE_EN == su.unit)
+ sz = su.scale;
+ else {
+ /*
+ * XXX
+ * If we are inside an enclosing list,
+ * there is no easy way to add the two
+ * indentations because they are provided
+ * in terms of different units.
+ */
+ print_word(v);
+ return;
+ }
} else
sz = strlen(v);
+ /*
+ * We are inside an enclosing list.
+ * Add the two indentations.
+ */
+ if (Bl_stack_len)
+ sz += Bl_stack[Bl_stack_len - 1];
+
snprintf(buf, sizeof(buf), "%ldn", sz);
print_word(buf);
}
@@ -416,6 +440,8 @@ print_width(const char *v, const struct
numeric = 1;
remain = 0;
+
+ /* Convert v into a number (of characters). */
if (NULL == v)
sz = defsz;
else if (a2roffsu(v, &su, SCALE_MAX)) {
@@ -432,6 +458,24 @@ print_width(const char *v, const struct
chsz = (NULL != child && MDOC_TEXT == child->type) ?
strlen(child->string) : 0;
+ /*
+ * If we are inside an enclosing list,
+ * preserve its indentation.
+ */
+ if (Bl_stack_len && Bl_stack[Bl_stack_len - 1]) {
+ print_line(".RS", 0);
+ snprintf(buf, sizeof(buf), "%ldn",
+ Bl_stack[Bl_stack_len - 1]);
+ print_word(buf);
+ }
+
+ /*
+ * Save our own indentation,
+ * such that child lists can use it.
+ */
+ Bl_stack[Bl_stack_len++] = sz + 2;
+
+ /* Set up the current list. */
if (defsz && chsz > sz)
print_block(".HP", 0);
else {
@@ -767,11 +811,28 @@ pre_bd(DECL_ARGS)
static void
post_bd(DECL_ARGS)
{
+ char buf[24];
+ /* Close out this display. */
print_line(".RE", MMAN_nl);
if (DISP_unfilled == n->norm->Bd.type ||
DISP_literal == n->norm->Bd.type)
print_line(".fi", MMAN_nl);
+
+ /*
+ * If we are inside an enclosing list and the current
+ * list item is not yet finished, restore the correct
+ * indentation for what remains of that item.
+ */
+ if (NULL != n->parent->next &&
+ Bl_stack_len && Bl_stack[Bl_stack_len - 1]) {
+ print_line(".RS", 0);
+ snprintf(buf, sizeof(buf), "%ldn",
+ Bl_stack[Bl_stack_len - 1]);
+ print_word(buf);
+ /* Remeber to close out this .RS block later. */
+ Bl_stack_post[Bl_stack_len - 1] = 1;
+ }
}
static int
@@ -1197,10 +1258,46 @@ post_it(DECL_ARGS)
}
break;
case (MDOC_BODY):
- if (LIST_column == bln->norm->Bl.type &&
- NULL != n->next) {
- putchar('\t');
- outflags &= ~MMAN_spc;
+ switch (bln->norm->Bl.type) {
+ case (LIST_bullet):
+ /* FALLTHROUGH */
+ case (LIST_dash):
+ /* FALLTHROUGH */
+ case (LIST_hyphen):
+ /* FALLTHROUGH */
+ case (LIST_enum):
+ /* FALLTHROUGH */
+ case (LIST_hang):
+ /* FALLTHROUGH */
+ case (LIST_tag):
+ assert(Bl_stack_len);
+ Bl_stack[--Bl_stack_len] = 0;
+
+ /*
+ * Our indentation had to be restored
+ * after a child display.
+ * Close out that indentation block now.
+ */
+ if (Bl_stack_post[Bl_stack_len]) {
+ print_line(".RE", MMAN_nl);
+ Bl_stack_post[Bl_stack_len] = 0;
+ }
+
+ /*
+ * We are inside an enclosing list.
+ * Restore the indentation of that list.
+ */
+ if (Bl_stack_len && Bl_stack[Bl_stack_len - 1])
+ print_line(".RE", MMAN_nl);
+ break;
+ case (LIST_column):
+ if (NULL != n->next) {
+ putchar('\t');
+ outflags &= ~MMAN_spc;
+ }
+ break;
+ default:
+ break;
}
break;
default:
--
To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv
reply other threads:[~2012-11-18 18:02 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201211181802.qAII2NVF031841@krisdoz.my.domain \
--to=schwarze@mdocml.bsd.lv \
--cc=source@mdocml.bsd.lv \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).