From: kristaps@mdocml.bsd.lv
To: source@mdocml.bsd.lv
Subject: pod2mdoc: Smarts: notice, in a SYNOPSIS, that we're an optional block
Date: Tue, 1 Apr 2014 09:05:50 -0400 (EDT) [thread overview]
Message-ID: <201404011305.s31D5oRB019343@krisdoz.my.domain> (raw)
Log Message:
-----------
Smarts: notice, in a SYNOPSIS, that we're an optional block ("[" matched
to a subsequent, and possibly nested, "]"). Also, re-write the flag
detector to match with real manuals, which use B<-flag arg> very often.
Now accomodate for both the "Fl" (possibly multiple) and the (possible
multiple) subsequent "Ar".
Modified Files:
--------------
pod2mdoc:
pod2mdoc.c
Revision Data
-------------
Index: pod2mdoc.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/pod2mdoc/pod2mdoc.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -Lpod2mdoc.c -Lpod2mdoc.c -u -p -r1.12 -r1.13
--- pod2mdoc.c
+++ pod2mdoc.c
@@ -239,6 +239,60 @@ trylink(const char *buf, size_t *start,
return(1);
}
+
+/*
+ * Doclifting: if we're a bold "-xx" and we're in the SYNOPSIS section,
+ * then it's likely that we're a flag.
+ * Our flag might be followed by an argument, so make sure that we're
+ * accounting for that, too.
+ * If we don't have a flag at all, however, then assume we're an "Ar".
+ */
+static void
+dosynopsisfl(const char *buf, size_t *start, size_t end)
+{
+ size_t i;
+again:
+ (*start)++;
+ for (i = *start; i < end; i++)
+ if (isalnum((int)buf[i]))
+ continue;
+ else if ('-' == buf[i])
+ continue;
+ else if ('_' == buf[i])
+ continue;
+ else
+ break;
+
+ assert(i < end);
+
+ if ( ! (' ' == buf[i] || '>' == buf[i])) {
+ printf("Ar ");
+ return;
+ }
+
+ printf("Fl ");
+ if (end - *start > 1 &&
+ isupper((int)buf[*start]) &&
+ islower((int)buf[*start + 1]) &&
+ (end - *start == 2 ||
+ ' ' == buf[*start + 2]))
+ printf("\\&");
+ printf("%.*s ", (int)(i - *start), &buf[*start]);
+ *start = i;
+
+ if (' ' == buf[i]) {
+ while (i < end && ' ' == buf[i])
+ i++;
+ assert(i < end);
+ if ('-' == buf[i]) {
+ *start = i;
+ goto again;
+ }
+ printf("Ar ");
+ *start = i;
+ }
+}
+
/*
* We're at the character in front of a format code, which is structured
* like X<...> and can contain nested format codes.
@@ -360,29 +414,12 @@ formatcode(struct state *st, const char
printf("Em ");
break;
case (FMT_BOLD):
- /*
- * Doclifting: if we're a bold "-xx" and we're
- * in the SYNOPSIS section, then it's likely
- * that we're a flag.
- * Be really strict: only do this when the dash
- * is followed by alnums til the end marker,
- * which mustn't be a custom.
- */
- if (SECT_SYNOPSIS == st->sect &&
- end - *start > 1 &&
- '-' == buf[*start] &&
- (isalnum((int)buf[*start + 1]) ||
- '?' == buf[*start + 1])) {
- for (i = *start + 1; i < end; i++)
- if ( ! isalnum((int)buf[i]))
- break;
- if (i < end && '>' == buf[i]) {
- (*start)++;
- printf("Fl ");
- break;
- }
- }
- printf("Sy ");
+ if (SECT_SYNOPSIS == st->sect &&
+ 1 == dsz &&
+ '-' == buf[*start])
+ dosynopsisfl(buf, start, end);
+ else
+ printf("Sy ");
break;
case (FMT_CODE):
printf("Qo Li ");
@@ -755,6 +792,61 @@ verbatim(struct state *st, const char *b
}
/*
+ * See dosynopsisop().
+ */
+static int
+hasmatch(const char *buf, size_t start, size_t end)
+{
+ size_t stack;
+
+ for (stack = 0; start < end; start++)
+ if (buf[start] == '[')
+ stack++;
+ else if (buf[start] == ']' && 0 == stack)
+ return(1);
+ else if (buf[start] == ']')
+ stack--;
+ return(0);
+}
+
+/*
+ * If we're in the SYNOPSIS section and we've encounter braces in an
+ * ordinary paragraph, then try to see whether we're an [-option].
+ * Do this, if we're an opening bracket, by first seeing if we have a
+ * matching end via hasmatch().
+ * If we're an ending bracket, see if we have a stack already.
+ */
+static int
+dosynopsisop(const char *buf, int *last,
+ size_t *start, size_t end, size_t *opstack)
+{
+
+ assert('[' == buf[*start] || ']' == buf[*start]);
+
+ if ('[' == buf[*start] && hasmatch(buf, *start + 1, end)) {
+ if ('\n' != *last)
+ putchar('\n');
+ puts(".Oo");
+ (*opstack)++;
+ } else if ('[' == buf[*start])
+ return(0);
+
+ if (']' == buf[*start] && *opstack > 0) {
+ if ('\n' != *last)
+ putchar('\n');
+ puts(".Oc");
+ (*opstack)--;
+ } else if (']' == buf[*start])
+ return(0);
+
+ (*start)++;
+ *last = '\n';
+ while (' ' == buf[*start])
+ (*start)++;
+ return(1);
+}
+
+/*
* Ordinary paragraph.
* Well, this is really the hardest--POD seems to assume that, for
* example, a leading space implies a newline, and so on.
@@ -765,7 +857,7 @@ verbatim(struct state *st, const char *b
static void
ordinary(struct state *st, const char *buf, size_t start, size_t end)
{
- size_t i, j;
+ size_t i, j, opstack;
if ( ! st->parsing || st->paused)
return;
@@ -802,6 +894,7 @@ ordinary(struct state *st, const char *b
st->haspar = 0;
last = '\n';
+ opstack = 0;
while (start < end) {
/*
@@ -817,26 +910,17 @@ ordinary(struct state *st, const char *b
printf("\\&");
else if ('\n' == last && '\'' == buf[start])
printf("\\&");
-#if notyet
/*
* If we're in the SYNOPSIS, have square
* brackets indicate that we're opening and
* closing an optional context.
*/
- if (SECT_SYNOPSIS == st->sect) {
- if ('[' == buf[start] ||
- ']' == buf[start]) {
- if (last != '\n')
- putchar('\n');
- if ('[' == buf[start])
- printf(".Oo\n");
- else
- printf(".Oc\n");
- start++;
- continue;
- }
- }
-#endif
+ if (SECT_SYNOPSIS == st->sect &&
+ ('[' == buf[start] ||
+ ']' == buf[start]) &&
+ dosynopsisop(buf, &last,
+ &start, end, &opstack))
+ continue;
putchar(last = buf[start++]);
if ('\\' == last)
putchar('e');
--
To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv
reply other threads:[~2014-04-01 13:05 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=201404011305.s31D5oRB019343@krisdoz.my.domain \
--to=kristaps@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).