source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* texi2mdoc: Add initial (and rather crude) support to print
@ 2015-03-01  0:25 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2015-03-01  0:25 UTC (permalink / raw)
  To: source

Log Message:
-----------
Add initial (and rather crude) support to print chapter-by-chapter nodes.
This is because with most manuals, apropos(1) is useless: it will point
to somewhere in a million lines.
This allows texi2moc to break apart a manual into chapters, each of which
links to other chapters, and which (at least in theory) will allow for
easier digesting of material.

Modified Files:
--------------
    texi2mdoc:
        extern.h
        main.c
        texi2mdoc.1
        util.c

Revision Data
-------------
Index: main.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/main.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -Lmain.c -Lmain.c -u -p -r1.54 -r1.55
--- main.c
+++ main.c
@@ -26,7 +26,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
 #include <unistd.h>
 
 #include "extern.h"
@@ -1553,9 +1552,11 @@ dosection(struct texi *p, enum texicmd c
 	int		 sec;
 
 	switch (cmd) {
+	case (TEXICMD_TOP):
+		sec = 0;
+		break;
 	case (TEXICMD_APPENDIX):
 	case (TEXICMD_CHAPTER):
-	case (TEXICMD_TOP):
 	case (TEXICMD_UNNUMBERED):
 		sec = sectioner(p, 0);
 		break;
@@ -1574,6 +1575,11 @@ dosection(struct texi *p, enum texicmd c
 	else if (p->literal)
 		texierr(p, "\"%s\" in a literal scope!?", sects[sec]);
 
+	if (0 == sec && NULL != p->chapters) {
+		teximdocclose(p, 0);
+		teximdocopen(p);
+	}
+
 	teximacroopen(p, sects[sec]);
 	parseeoln(p, pos);
 	teximacroclose(p);
@@ -1581,6 +1587,18 @@ dosection(struct texi *p, enum texicmd c
 }
 
 static void
+dotop(struct texi *p, enum texicmd cmd, size_t *pos)
+{
+
+	if (--p->ign)
+		texierr(p, "@top command while ignoring");
+
+	if (NULL == p->chapters)
+		teximdocopen(p);
+	dosection(p, cmd, pos);
+}
+
+static void
 dosp(struct texi *p, enum texicmd cmd, size_t *pos)
 {
 
@@ -1593,51 +1611,6 @@ dosp(struct texi *p, enum texicmd cmd, s
 }
 
 static void
-dotop(struct texi *p, enum texicmd cmd, size_t *pos)
-{
-	const char	*cp;
-	time_t		 t;
-	char		 date[32];
-
-	if (--p->ign)
-		texierr(p, "@top command while ignoring");
-
-	/*
-	 * Here we print our standard mdoc(7) prologue.
-	 * We use the title set with @settitle for the `Nd' description
-	 * and the source document filename (the first one as invoked on
-	 * the command line) for the title.
-	 * The date is set to the current date.
-	 */
-	t = time(NULL);
-	strftime(date, sizeof(date), "%F", localtime(&t));
-
-	teximacroopen(p, "Dd");
-	texiputchars(p, date);
-	teximacroclose(p);
-	teximacroopen(p, "Dt");
-	for (cp = p->title; '\0' != *cp; cp++)
-		texiputchar(p, toupper((unsigned int)*cp));
-	texiputchars(p, " 7");
-	teximacroclose(p);
-	teximacro(p, "Os");
-	teximacro(p, "Sh NAME");
-	teximacroopen(p, "Nm");
-	for (cp = p->title; '\0' != *cp; cp++)
-		texiputchar(p, *cp);
-	teximacroclose(p);
-	teximacroopen(p, "Nd");
-	if (NULL != p->subtitle)
-		for (cp = p->subtitle; '\0' != *cp; cp++)
-			texiputchar(p, *cp);
-	else
-		texiputchars(p, "Unknown description");
-	teximacroclose(p);
-	p->seenvs = 1;
-	dosection(p, cmd, pos);
-}
-
-static void
 doitem(struct texi *p, enum texicmd cmd, size_t *pos)
 {
 
@@ -1885,10 +1858,14 @@ main(int argc, char *argv[])
 
 	memset(&texi, 0, sizeof(struct texi));
 	texi.ign = 1;
+	texi.outfile = stdout;
 	Idir = NULL;
 
-	while (-1 != (c = getopt(argc, argv, "I:"))) 
+	while (-1 != (c = getopt(argc, argv, "C:I:"))) 
 		switch (c) {
+		case ('C'):
+			texi.chapters = optarg;
+			break;
 		case ('I'):
 			Idir = optarg;
 			break;
@@ -1924,6 +1901,6 @@ main(int argc, char *argv[])
 	texiexit(&texi);
 	return(EXIT_FAILURE);
 usage:
-	fprintf(stderr, "usage: %s [-Idirs] [file]\n", progname);
+	fprintf(stderr, "usage: %s [-Cdir] [-Idirs] [file]\n", progname);
 	return(EXIT_FAILURE);
 }
Index: extern.h
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/extern.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -Lextern.h -Lextern.h -u -p -r1.20 -r1.21
--- extern.h
+++ extern.h
@@ -372,13 +372,18 @@ struct	teximacro {
  * This keeps any necessary information handy.
  */
 struct	texi {
+	const char	 *chapters; /* are we splitting chapters */
+	size_t		  chapnum;
+	char		**dirs; /* texi directories */
+	size_t		  dirsz; /* number of texi directories */
+	FILE		 *outfile;
+	/*
+	 * Run-time parameters.
+	 */
 	struct texifile   files[64]; /* stack of open files */
 	size_t		  filepos; /* number of open files */
 	const char	 *valstack[64]; /* stack of opened values */
 	size_t		  valstackpos; /* position in valstack */
-	size_t		  outcol; /* column in output line */
-	char		**dirs; /* texi directories */
-	size_t		  dirsz; /* number of texi directories */
 	char		 *title; /* title of document */
 	char		 *subtitle; /* subtitle of document */
 	int		  secoffs; /* see sectioner() */
@@ -394,6 +399,7 @@ struct	texi {
 	 */
 	enum texilist	  list; /* current list (set recursively) */
 	int		  outmacro; /* if >0, output is in line macro */
+	size_t		  outcol; /* column in output line */
 	int		  seenws; /* ws has been seen (and ignored) */
 	int		  seenvs; /* newline has been Pp'd */
 	int		  ign; /* if >0, don't print anything */
@@ -438,6 +444,8 @@ void	texifilepop(struct texi *);
 void	teximacro(struct texi *, const char *);
 void	teximacroclose(struct texi *);
 void	teximacroopen(struct texi *, const char *);
+void	teximdocopen(struct texi *);
+void	teximdocclose(struct texi *, int);
 void 	texipunctuate(struct texi *, size_t *);
 void	texiputbuf(struct texi *p, size_t, size_t);
 void	texiputchar(struct texi *p, char);
Index: util.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/util.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -Lutil.c -Lutil.c -u -p -r1.19 -r1.20
--- util.c
+++ util.c
@@ -20,8 +20,6 @@
 #include <assert.h>
 #include <ctype.h>
 #include <fcntl.h>
-#include <getopt.h>
-#include <libgen.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -79,7 +77,9 @@ texiexit(struct texi *p)
 
 	/* Make sure we're newline-terminated. */
 	if (p->outcol)
-		putchar('\n');
+		fputc('\n', p->outfile);
+	if (NULL != p->chapters)
+		teximdocclose(p, 1);
 
 	/* Unmap all files. */
 	while (p->filepos > 0)
@@ -180,13 +180,13 @@ texiputchar(struct texi *p, char c)
 	if (p->ign)
 		return;
 	if ('.' == c && 0 == p->outcol)
-		fputs("\\&", stdout);
+		fputs("\\&", p->outfile);
 	if ('\'' == c && 0 == p->outcol)
-		fputs("\\&", stdout);
+		fputs("\\&", p->outfile);
 
-	putchar(c);
+	fputc(c, p->outfile);
 	if ('\\' == c)
-		putchar('e');
+		fputc('e', p->outfile);
 	p->seenvs = 0;
 	if ('\n' == c) {
 		p->outcol = 0;
@@ -207,10 +207,10 @@ texiputchars(struct texi *p, const char 
 	if (p->ign)
 		return;
 	if ('.' == *s && 0 == p->outcol)
-		fputs("\\&", stdout);
+		fputs("\\&", p->outfile);
 	if ('\'' == *s && 0 == p->outcol)
-		fputs("\\&", stdout);
-	p->outcol += fputs(s, stdout);
+		fputs("\\&", p->outfile);
+	p->outcol += fputs(s, p->outfile);
 	p->seenvs = 0;
 }
 
@@ -239,7 +239,7 @@ teximacroclose(struct texi *p)
 		return;
 
 	if (0 == --p->outmacro) {
-		putchar('\n');
+		fputc('\n', p->outfile);
 		p->outcol = p->seenws = 0;
 	}
 }
@@ -259,19 +259,19 @@ teximacroopen(struct texi *p, const char
 		return;
 
 	if (p->outcol && 0 == p->outmacro) {
-		putchar('\n');
+		fputc('\n', p->outfile);
 		p->outcol = 0;
 	}
 
 	if (0 == p->outmacro)
-		putchar('.');
+		fputc('.', p->outfile);
 	else
-		putchar(' ');
+		fputc(' ', p->outfile);
 
-	if (EOF != (rc = fputs(s, stdout)))
+	if (EOF != (rc = fputs(s, p->outfile)))
 		p->outcol += rc;
 
-	putchar(' ');
+	fputc(' ', p->outfile);
 	p->outcol++;
 	p->outmacro++;
 	p->seenws = 0;
@@ -293,10 +293,11 @@ teximacro(struct texi *p, const char *s)
 		texierr(p, "\"%s\" in a literal scope!?", s);
 
 	if (p->outcol)
-		putchar('\n');
+		fputc('\n', p->outfile);
 
-	putchar('.');
-	puts(s);
+	fputc('.', p->outfile);
+	fputs(s, p->outfile);
+	fputc('\n', p->outfile);
 	p->outcol = p->seenws = 0;
 }
 
@@ -1348,3 +1349,108 @@ argparse(struct texi *p, size_t *pos, si
 	advance(p, pos);
 	return(args);
 }
+
+/*
+ * If we're printing chapters, then do some naviation here and then
+ * close our outfile.
+ * I want to call this the SEE ALSO section, but that's not really what
+ * it is: we'll refer to the "initial" (top) node and the next and
+ * previous chapters.
+ */
+void
+teximdocclose(struct texi *p, int last)
+{
+	char	 buf[PATH_MAX];
+
+	if (NULL == p->chapters || 0 == p->chapnum)
+		return;
+
+	teximacro(p, "Sh INFO NAVIGATION");
+
+	/* Print a reference to the "top" node. */
+	if (p->chapnum > 1) {
+		snprintf(buf, sizeof(buf), "node1 7");
+		teximacroopen(p, "Xr ");
+		texiputchars(p, buf);
+		texiputchars(p, " ,");
+		teximacroclose(p);
+	}
+
+	/* Print a reference to the previous node. */
+	if (p->chapnum > 2) {
+		snprintf(buf, sizeof(buf),
+			"node%zu 7", p->chapnum - 1);
+		teximacroopen(p, "Xr ");
+		texiputchars(p, buf);
+		if ( ! last) 
+			texiputchars(p, " ,");
+		teximacroclose(p);
+	} 
+
+	/* Print a reference to the next node. */
+	if ( ! last) {
+		snprintf(buf, sizeof(buf),
+			"node%zu 7", p->chapnum + 1);
+		teximacroopen(p, "Xr ");
+		texiputchars(p, buf);
+		teximacroclose(p);
+	}
+
+	fclose(p->outfile);
+}
+
+/*
+ * Open a mdoc(7) context.
+ * If we're printing chapters, then open the outfile here, too.
+ * Otherwise just print the mdoc(7) prologue.
+ */
+void
+teximdocopen(struct texi *p)
+{
+	const char	*cp;
+	time_t		 t;
+	char		 date[32];
+	char	 	 fname[PATH_MAX];
+
+	if (NULL != p->chapters) {
+		snprintf(fname, sizeof(fname), "%s/node%zu.7", 
+			p->chapters, ++p->chapnum);
+		p->outfile = fopen(fname, "w");
+		if (NULL == p->outfile)
+			texiabort(p, fname);
+	}
+
+	/*
+	 * Here we print our standard mdoc(7) prologue.
+	 * We use the title set with @settitle for the `Nd' description
+	 * and the source document filename (the first one as invoked on
+	 * the command line) for the title.
+	 * The date is set to the current date.
+	 */
+	t = time(NULL);
+	strftime(date, sizeof(date), "%F", localtime(&t));
+
+	teximacroopen(p, "Dd");
+	texiputchars(p, date);
+	teximacroclose(p);
+	teximacroopen(p, "Dt");
+	for (cp = p->title; '\0' != *cp; cp++)
+		texiputchar(p, toupper((unsigned int)*cp));
+	texiputchars(p, " 7");
+	teximacroclose(p);
+	teximacro(p, "Os");
+	teximacro(p, "Sh NAME");
+	teximacroopen(p, "Nm");
+	for (cp = p->title; '\0' != *cp; cp++)
+		texiputchar(p, *cp);
+	teximacroclose(p);
+	teximacroopen(p, "Nd");
+	if (NULL != p->subtitle)
+		for (cp = p->subtitle; '\0' != *cp; cp++)
+			texiputchar(p, *cp);
+	else
+		texiputchars(p, "Unknown description");
+	teximacroclose(p);
+	p->seenvs = 1;
+}
+
Index: texi2mdoc.1
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/texi2mdoc.1,v
retrieving revision 1.12
retrieving revision 1.13
diff -Ltexi2mdoc.1 -Ltexi2mdoc.1 -u -p -r1.12 -r1.13
--- texi2mdoc.1
+++ texi2mdoc.1
@@ -22,6 +22,7 @@
 .Nd convert texinfo documents to mdoc
 .Sh SYNOPSIS
 .Nm texi2mdoc
+.Op Fl I Ar dir
 .Op Fl I Ar dirs
 .Op Ar file
 .Sh DESCRIPTION
@@ -39,6 +40,13 @@ By default,
 reads from standard input.
 Its arguments are as follows:
 .Bl -tag -width Ds
+.It Fl C Ar dir
+Instead of producing a single document, break apart the input into
+chapter-level documents placed within
+.Ar dir ,
+which must exist.
+These are created as
+.Pa chapterNNN.7 .
 .It Fl I Ar dirs
 Colon-separated directories to search for
 .Li @include
--
 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:[~2015-03-01  0:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-01  0:25 texi2mdoc: Add initial (and rather crude) support to print 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).