source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* pod2mdoc: Smarts: notice, in a SYNOPSIS, that we're an optional block
@ 2014-04-01 13:05 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2014-04-01 13:05 UTC (permalink / raw)
  To: source

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-04-01 13:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-01 13:05 pod2mdoc: Smarts: notice, in a SYNOPSIS, that we're an optional block kristaps

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).