source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* texi2mdoc: Enormous patch (re-)fixing (again) the vertical space issue,
@ 2015-03-11 12:52 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2015-03-11 12:52 UTC (permalink / raw)
  To: source

Log Message:
-----------
Enormous patch (re-)fixing (again) the vertical space issue, which works
even better in delaying vertical space until needed.
This also adds a lot more indexing capabilities.
All indexing has an HAVE_INDEX preprocess directive, since this is not
really mdoc(7) (yet).

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

Revision Data
-------------
Index: extern.h
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/extern.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -Lextern.h -Lextern.h -u -p -r1.26 -r1.27
--- extern.h
+++ extern.h
@@ -32,6 +32,8 @@
 #  endif
 #endif
 
+#define HAVE_INDEX 1
+
 /*
  * This defines each one of the Texinfo commands that we understand.
  * Obviously this only refers to native commands; overriden names are a
@@ -275,6 +277,7 @@ enum	texicmd {
 	TEXICMD_TITLEFONT,
 	TEXICMD_TITLEPAGE,
 	TEXICMD_TOP,
+	TEXICMD_TPINDEX,
 	TEXICMD_U,
 	TEXICMD_UBARACCENT,
 	TEXICMD_UDOTACCENT,
@@ -293,6 +296,7 @@ enum	texicmd {
 	TEXICMD_VERBATIM,
 	TEXICMD_VERBATIMINCLUDE,
 	TEXICMD_VINDEX,
+	TEXICMD_VRINDEX,
 	TEXICMD_VSKIP,
 	TEXICMD_VTABLE,
 	TEXICMD_W,
@@ -369,6 +373,17 @@ struct	teximacro {
 };
 
 /*
+ * Index tables.
+ * These have a two or three letter name (usually) and any number of
+ * terms that are associated with it.
+ */
+struct	texidex {
+	char		 *name;
+	char		**index;
+	size_t		  indexsz;
+};
+
+/*
  * The main parse structure.
  * This keeps any necessary information handy.
  */
@@ -388,7 +403,7 @@ struct	texi {
 	char		 *title; /* title of document */
 	char		 *subtitle; /* subtitle of document */
 	int		  secoffs; /* see sectioner() */
-	char		**indexs; /* @defindex indices */
+	struct texidex 	 *indexs; /* index entries */
 	size_t		  indexsz; /* entries in indexs */
 	struct texivalue *vals; /* @value entries */
 	size_t		  valsz; /* entries in vals */
@@ -440,6 +455,8 @@ enum texicmd
 	texicmd(const struct texi *, size_t, size_t *, struct teximacro **);
 enum texicmd
 	peekcmd(const struct texi *, size_t);
+enum texicmd
+	peeklinecmd(const struct texi *, size_t);
 void	texierr(struct texi *, const char *, ...)
 		__attribute__((format(printf, 2, 3)))
 		__attribute__((noreturn));
@@ -450,6 +467,9 @@ void	teximacroclose(struct texi *);
 void	teximacroopen(struct texi *, const char *);
 void	teximdocopen(struct texi *, size_t *);
 void	teximdocclose(struct texi *, int);
+void	texindex(struct texi *, const char *,
+		size_t, const char *, size_t);
+void	texindex_add(struct texi *, const char *, size_t);
 void 	texipunctuate(struct texi *, size_t *);
 void	texiputbuf(struct texi *p, size_t, size_t);
 void	texiputchar(struct texi *p, char);
Index: main.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/main.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -Lmain.c -Lmain.c -u -p -r1.65 -r1.66
--- main.c
+++ main.c
@@ -30,12 +30,20 @@
 
 #include "extern.h"
 
+#define	HAVE_INDEX 1
+
+/*
+ * Texinfo can change the "meaning" of its section headings: chapter,
+ * section, subsection, etc., can be promoted and/or demoted to other
+ * levels of heading.
+ * Thus, we use an offset and just jump into this array.
+ */
 #define	SECTSZ 4
 static	const char *const sects[SECTSZ] = {
-	"Sh",
-	"Ss",
-	"Em",
-	"No",
+	"Sh", /* Chapters (sections) */
+	"Ss", /* Sections (subsections) */
+	"Em", /* Subsections (subsubsection) */
+	"Sy", /* Subsubsections (...). */
 };
 
 static	void doaccent(struct texi *, enum texicmd, size_t *);
@@ -53,6 +61,7 @@ static	void doignargn(struct texi *, enu
 static	void doignblock(struct texi *, enum texicmd, size_t *);
 static	void doignbracket(struct texi *, enum texicmd, size_t *);
 static	void doignline(struct texi *, enum texicmd, size_t *);
+static	void doindex(struct texi *, enum texicmd, size_t *);
 static	void doinline(struct texi *, enum texicmd, size_t *);
 static	void doinclude(struct texi *, enum texicmd, size_t *);
 static	void doinsertcopying(struct texi *, enum texicmd, size_t *);
@@ -61,21 +70,16 @@ static	void doitemize(struct texi *, enu
 static	void dolink(struct texi *, enum texicmd, size_t *);
 static	void domacro(struct texi *, enum texicmd, size_t *);
 static	void domath(struct texi *, enum texicmd, size_t *);
-#if 0
 static	void domenu(struct texi *, enum texicmd, size_t *);
-#endif
 static	void domultitable(struct texi *, enum texicmd, size_t *);
-#if 0
 static	void donode(struct texi *, enum texicmd, size_t *);
-#endif
+static	void doprintindex(struct texi *, enum texicmd, size_t *);
 static	void doquotation(struct texi *, enum texicmd, size_t *);
 static	void dotable(struct texi *, enum texicmd, size_t *);
 static	void dotop(struct texi *, enum texicmd, size_t *);
 static	void dosecoffs(struct texi *, enum texicmd, size_t *);
 static	void dosection(struct texi *, enum texicmd, size_t *);
 static	void dosp(struct texi *, enum texicmd, size_t *);
-static	void dosubsection(struct texi *, enum texicmd, size_t *);
-static	void dosubsubsection(struct texi *, enum texicmd, size_t *);
 static	void dosymbol(struct texi *, enum texicmd, size_t *);
 static	void dotab(struct texi *, enum texicmd, size_t *);
 static	void dotitle(struct texi *, enum texicmd, size_t *);
@@ -96,8 +100,8 @@ static	const struct texitok __texitoks[T
 	{ doignbracket, "anchor", 6 }, /* TEXICMD_ANCHOR */
 	{ dosection, "appendix", 8 }, /* TEXICMD_APPENDIX */
 	{ dosection, "appendixsec", 11 }, /* TEXICMD_APPENDIXSEC */
-	{ dosubsection, "appendixsubsec", 14 }, /* TEXICMD_APPENDIXSUBSEC */
-	{ dosubsubsection, "appendixsubsubsec", 17 }, /* TEXICMD_APPENDIXSUBSUBSEC */
+	{ dosection, "appendixsubsec", 14 }, /* TEXICMD_APPENDIXSUBSEC */
+	{ dosection, "appendixsubsubsec", 17 }, /* TEXICMD_APPENDIXSUBSUBSEC */
 	{ doinline, "asis", 4 }, /* TEXICMD_ASIS */
 	{ dosymbol, "*", 1 }, /* TEXICMD_ASTERISK */
 	{ dosymbol, "@", 1 }, /* TEXICMD_AT */
@@ -111,7 +115,7 @@ static	const struct texitok __texitoks[T
 	{ doaccent, ",", 1 }, /* TEXICMD_CEDILLA */
 	{ doignline, "center", 6 }, /* TEXICMD_CENTER */
 	{ dosection, "chapter", 7 }, /* TEXICMD_CHAPTER */
-	{ doignline, "cindex", 6 }, /* TEXICMD_CINDEX */
+	{ doindex, "cindex", 6 }, /* TEXICMD_CINDEX */
 	{ doaccent, "^", 1 }, /* TEXICMD_CIRCUMFLEX */
 	{ doinline, "cite", 4 }, /* TEXICMD_CITE */
 	{ dovalue, "clear", 5 }, /* TEXICMD_CLEAR */
@@ -149,7 +153,7 @@ static	const struct texitok __texitoks[T
 	{ dodefn, "defvarx", 7 }, /* TEXICMD_DEFVARX */
 	{ dodefn, "defvr", 5 }, /* TEXICMD_DEFVR */
 	{ dodefn, "defvrx", 6 }, /* TEXICMD_DEFVRX */
-	{ doignblock, "detailmenu", 10 }, /* TEXICMD_DETAILMENU */
+	{ domenu, "detailmenu", 10 }, /* TEXICMD_DETAILMENU */
 	{ doinline, "dfn", 3 }, /* TEXICMD_DFN */
 	{ dosymbol, "DH", 2 }, /* TEXICMD_DH */
 	{ dosymbol, "dh", 2 }, /* TEXICMD_DHSMALL */
@@ -178,7 +182,7 @@ static	const struct texitok __texitoks[T
 	{ dosymbol, "expansion", 9 }, /* TEXICMD_EXPANSION */
 	{ doinline, "file", 4 }, /* TEXICMD_FILE */
 	{ doignline, "finalout", 8 }, /* TEXICMD_FINALOUT */
-	{ doignline, "findex", 6 }, /* TEXICMD_FINDEX */
+	{ doindex, "findex", 6 }, /* TEXICMD_FINDEX */
 	{ doblock, "flushleft", 9 }, /* TEXICMD_FLUSHLEFT */
 	{ doblock, "flushright", 10 }, /* TEXICMD_FLUSHRIGHT */
 	{ doignline, "firstparagraphindent", 20 }, /* TEXICMD_FIRSTPARAGRAPHINDENT */
@@ -237,20 +241,12 @@ static	const struct texitok __texitoks[T
 	{ domacro, "macro", 5 }, /* TEXICMD_MACRO */
 	{ doaccent, "=", 1 }, /* TEXICMD_MACRON */
 	{ domath, "math", 4 }, /* TEXICMD_MATH */
-#if 0
 	{ domenu, "menu", 4 }, /* TEXICMD_MENU */
-#else
-	{ doignblock, "menu", 4 }, /* TEXICMD_MENU */
-#endif
 	{ dosymbol, "minus", 5 }, /* TEXICMD_MINUS */
 	{ domultitable, "multitable", 10 }, /* TEXICMD_MULTITABLE */
 	{ doignline, "need", 4 }, /* TEXICMD_NEED */
 	{ dosymbol, "\n", 1 }, /* TEXICMD_NEWLINE */
-#if 0
 	{ donode, "node", 4 }, /* TEXICMD_NODE */
-#else
-	{ doignline, "node", 4 }, /* TEXICMD_NODE */
-#endif
 	{ doignline, "noindent", 8 }, /* TEXICMD_NOINDENT */
 	{ dosymbol, "O", 1 }, /* TEXICMD_O */
 	{ dosymbol, "OE", 2 }, /* TEXICMD_OE */
@@ -265,7 +261,7 @@ static	const struct texitok __texitoks[T
 	{ dosymbol, ".", 1 }, /* TEXICMD_PERIOD */
 	{ doignline, "pindex", 6 }, /* TEXICMD_PINDEX */
 	{ dosymbol, "pounds", 6 }, /* TEXICMD_POUNDS */
-	{ doignline, "printindex", 10 }, /* TEXICMD_PRINTINDEX */
+	{ doprintindex, "printindex", 10 }, /* TEXICMD_PRINTINDEX */
 	{ dolink, "pxref", 5 }, /* TEXICMD_PXREF */
 	{ dosymbol, "questiondown", 12 }, /* TEXICMD_QUESTIONDOWN */
 	{ dosymbol, "?", 1 }, /* TEXICMD_QUESTIONMARK */
@@ -306,10 +302,10 @@ static	const struct texitok __texitoks[T
 	{ dosymbol, "}", 1 }, /* TEXICMD_SQUIGGLE_RIGHT */
 	{ dosymbol, "ss", 2 }, /* TEXICMD_SS */
 	{ doinline, "strong", 6 }, /* TEXICMD_STRONG */
-	{ dosubsection, "subheading", 10 }, /* TEXICMD_SUBHEADING */
-	{ dosubsection, "subsection", 10 }, /* TEXICMD_SUBSECTION */
-	{ dosubsubsection, "subsubheading", 13 }, /* TEXICMD_SUBSUBHEADING */
-	{ dosubsubsection, "subsubsection", 13 }, /* TEXICMD_SUBSUBSECTION */
+	{ dosection, "subheading", 10 }, /* TEXICMD_SUBHEADING */
+	{ dosection, "subsection", 10 }, /* TEXICMD_SUBSECTION */
+	{ dosection, "subsubheading", 13 }, /* TEXICMD_SUBSUBHEADING */
+	{ dosection, "subsubsection", 13 }, /* TEXICMD_SUBSUBSECTION */
 	{ doignline, "subtitle", 8 }, /* TEXICMD_SUBTITLE */
 	{ doignline, "summarycontents", 15 }, /* TEXICMD_SUMMARYCONTENTS */
 	{ dodefindex, "synindex", 8 }, /* TEXICMD_SYNINDEX */
@@ -326,19 +322,20 @@ static	const struct texitok __texitoks[T
 	{ dosymbol, "tie", 3 }, /* TEXICMD_TIE */
 	{ doaccent, "tieaccent", 9 }, /* TEXICMD_TIEACCENT */
 	{ doaccent, "~", 1 }, /* TEXICMD_TILDE */
-	{ doignline, "tindex", 6 }, /* TEXICMD_TINDEX */
+	{ doindex, "tindex", 6 }, /* TEXICMD_TINDEX */
 	{ doignline, "title", 5 }, /* TEXICMD_TITLE */
 	{ dobracket, "titlefont", 9 }, /* TEXICMD_TITLEFONT */
 	{ doignblock, "titlepage", 9 }, /* TEXICMD_TITLEPAGE */
 	{ dotop, "top", 3 }, /* TEXICMD_TOP */
+	{ doindex, "tpindex", 7 }, /* TEXICMD_TPINDEX */
 	{ doaccent, "u", 1 }, /* TEXICMD_U */
 	{ doaccent, "ubaraccent", 10 }, /* TEXICMD_UBARACCENT */
 	{ doaccent, "udotaccent", 10 }, /* TEXICMD_UDOTACCENT */
 	{ doaccent, "\"", 1 }, /* TEXICMD_UMLAUT */
 	{ dosection, "unnumbered", 10 }, /* TEXICMD_UNNUMBERED */
 	{ dosection, "unnumberedsec", 13 }, /* TEXICMD_UNNUMBEREDSEC */
-	{ dosubsection, "unnumberedsubsec", 16 }, /* TEXICMD_UNNUMBEREDSUBSEC */
-	{ dosubsubsection, "unnumberedsubsubsec", 19 }, /* TEXICMD_UNNUMBEREDSUBSUBSEC */
+	{ dosection, "unnumberedsubsec", 16 }, /* TEXICMD_UNNUMBEREDSUBSEC */
+	{ dosection, "unnumberedsubsubsec", 19 }, /* TEXICMD_UNNUMBEREDSUBSUBSEC */
 	{ dolink, "uref", 4 }, /* TEXICMD_UREF */
 	{ dolink, "url", 3 }, /* TEXICMD_URL */
 	{ doignline, "", 0 }, /* TEXICMD_USER_INDEX */
@@ -348,7 +345,8 @@ static	const struct texitok __texitoks[T
 	{ doverb, "verb", 4 }, /* TEXICMD_VERB */
 	{ doverbatim, "verbatim", 8 }, /* TEXICMD_VERBATIM */
 	{ doverbinclude, "verbatiminclude", 15 }, /* TEXICMD_VERBATIMINCLUDE */
-	{ doignline, "vindex", 6 }, /* TEXICMD_VINDEX */
+	{ doindex, "vindex", 6 }, /* TEXICMD_VINDEX */
+	{ doindex, "vrindex", 7 }, /* TEXICMD_VRINDEX */
 	{ dosp, "vskip", 5 }, /* TEXICMD_VSKIP */
 	{ dotable, "vtable", 6 }, /* TEXICMD_VTABLE */
 	{ dobracket, "w", 1 }, /* TEXICMD_W */
@@ -359,43 +357,34 @@ static	const struct texitok __texitoks[T
 const	struct texitok *const texitoks = __texitoks;
 
 /*
- * Texinfo has lots of indexes.
- * You can add new ones in a variety of ways.
- * We maintain an array of all of these index names (usually a few
- * letters) and pass unknown commands through the array list.
+ * Define new indexes either by assignment or aliasing (both of these
+ * accept the first argument as the new index).
  */
 static void
 dodefindex(struct texi *p, enum texicmd cmd, size_t *pos)
 {
-	size_t	 start, end;
-	char	*cp;
+	size_t	 start;
 
 	while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
 		advance(p, pos);
-	start = end = *pos;
-	while (end < BUFSZ(p) && ! ismspace(BUF(p)[end]))
-		end++;
-
-	if (start == end) {
-		advanceeoln(p, pos, 1);
+	start = *pos;
+	while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos])
+		advance(p, pos);
+	if (*pos == BUFSZ(p)) {
+		texiwarn(p, "unexpected EOF");
 		return;
 	} 
-	
-	if (NULL == (cp = malloc(end - start + 1)))
-		texiabort(p, NULL);
-	memcpy(cp, &BUF(p)[start], end - start);
-	cp[end - start] = '\0';
-
-	/* FIXME: use reallocarray(). */
-	p->indexs = realloc(p->indexs, 
-		sizeof(char *) * (p->indexsz + 1));
-	if (NULL == p->indexs)
-		texiabort(p, NULL);
-	p->indexs[p->indexsz++] = cp;
-
-	advanceeoln(p, pos, 1);
+	if (0 == *pos - start)
+		texiwarn(p, "zero-length index definition");
+	else
+		texindex_add(p, &BUF(p)[start], *pos - start);
+	advance(p, pos);
 }
 
+/*
+ * Handle both possible "define function" (type, etc.) classes: where
+ * we'll have a body and without one (suffixed with "x").
+ */
 static void
 dodefn(struct texi *p, enum texicmd cmd, size_t *pos)
 {
@@ -427,8 +416,10 @@ dodefn(struct texi *p, enum texicmd cmd,
 		return;
 	}
 
-	if (NULL != blk)
-		texivspace(p);
+	if (p->seenvs >= 0) {
+		teximacro(p, "Pp");
+		p->seenvs = -1;
+	}
 
 	switch (cmd) {
 	case (TEXICMD_DEFTYPEMETHOD):
@@ -456,6 +447,7 @@ dodefn(struct texi *p, enum texicmd cmd,
 		break;
 	}
 
+	p->seenvs = 0;
 	texiputchar(p, ':');
 	texiputchar(p, '\n');
 
@@ -563,10 +555,13 @@ dodefn(struct texi *p, enum texicmd cmd,
 		return;
 	}
 
-	teximacro(p, "Bd -filled -offset indent");
+	texivspace(p);
+	teximacro(p, "Bd -filled -offset indent -compact");
+	p->seenvs = -1;
 	parseto(p, pos, blk);
+	p->seenvs = 0;
 	teximacro(p, "Ed");
-	p->seenvs = 1;
+	texivspace(p);
 }
 
 static void
@@ -721,6 +716,7 @@ doinline(struct texi *p, enum texicmd cm
 	switch (cmd) {
 	case (TEXICMD_CODE):
 	case (TEXICMD_KBD):
+	/* FIXME: quote around @samp{} */
 	case (TEXICMD_SAMP):
 	case (TEXICMD_T):
 		macro = "Li";
@@ -831,9 +827,8 @@ doinsertcopying(struct texi *p, enum tex
 {
 
 	advanceeoln(p, pos, 0);
-	if (NULL == p->copying)
-		return;
-	texisplice(p, p->copying, p->copyingsz, *pos);
+	if (NULL != p->copying)
+		texisplice(p, p->copying, p->copyingsz, *pos);
 }
 
 static void
@@ -898,13 +893,16 @@ doverbatim(struct texi *p, enum texicmd 
 	assert(endpos <= BUFSZ(p));
 	assert('\n' == BUF(p)[*pos]);
 	advance(p, pos);
-	teximacro(p, "Bd -literal -offset indent");
+	texivspace(p);
+	teximacro(p, "Bd -literal -offset indent -compact");
+	p->seenvs = -1;
 	while (*pos < endpos) {
 		texiputchar(p, BUF(p)[*pos]);
 		advance(p, pos);
 	}
+	p->seenvs = 0;
 	teximacro(p, "Ed");
-	p->seenvs = 1;
+	texivspace(p);
 	if (*pos < BUFSZ(p))
 		advanceto(p, pos, endpos + endsz);
 }
@@ -1043,20 +1041,23 @@ dodisplay(struct texi *p, enum texicmd c
 {
 
 	advanceeoln(p, pos, 1);
+	texivspace(p);
 
 	switch (cmd) {
 	case (TEXICMD_FORMAT):
 	case (TEXICMD_SMALLFORMAT):
-		teximacro(p, "Bd -filled");
+		teximacro(p, "Bd -filled -compact");
 		break;
 	default:
-		teximacro(p, "Bd -filled -offset indent");
+		teximacro(p, "Bd -filled -offset indent -compact");
 		break;
 	}
 
+	p->seenvs = -1;
 	parseto(p, pos, texitoks[cmd].tok);
+	p->seenvs = 0;
 	teximacro(p, "Ed");
-	p->seenvs = 1;
+	texivspace(p);
 }
 
 static void
@@ -1065,12 +1066,14 @@ doexample(struct texi *p, enum texicmd c
 
 	advanceeoln(p, pos, 1);
 
-	teximacro(p, "Bd -literal -offset indent");
+	texivspace(p);
+	teximacro(p, "Bd -literal -offset indent -compact");
 	p->literal++;
 	parseto(p, pos, texitoks[cmd].tok);
 	p->literal--;
+	p->seenvs = 0;
 	teximacro(p, "Ed");
-	p->seenvs = 1;
+	texivspace(p);
 }
 
 static void
@@ -1471,14 +1474,102 @@ doquotation(struct texi *p, enum texicmd
 	teximacro(p, "Qc");
 }
 
-#if 0
+static int
+indexcmp(const void *p1, const void *p2)
+{
+
+	return(strcasecmp(*(const char **)p1, *(const char **)p2));
+}
+
+static void
+doprintindex(struct texi *p, enum texicmd cmd, size_t *pos)
+{
+	size_t	 i, j, start, end, len;
+#if HAVE_INDEX
+	char	*cp;
+#endif
+
+	while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+		advance(p, pos);
+	start = *pos;
+	while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos])
+		advance(p, pos);
+	if ((end = *pos) == BUFSZ(p)) {
+		texiwarn(p, "unexpected EOF");
+		return;
+	}
+
+	advance(p, pos);
+	if (0 == (len = end - start)) {
+		texiwarn(p, "zero-length index");
+		return;
+	}
+
+	/* Look for the index in our table. */
+	for (i = 0; i < p->indexsz; i++) {
+		if (strlen(p->indexs[i].name) != len)
+			continue;
+		if (strncmp(p->indexs[i].name, &BUF(p)[start], len))
+			continue;
+		break;
+	}
+
+	if (i == p->indexsz) {
+		texiwarn(p, "cannot find index");
+		return;
+	} else if (0 == p->indexs[i].indexsz) 
+		return;
+
+	/* Alphabetically sort our indices. */
+	qsort(p->indexs[i].index, 
+		p->indexs[i].indexsz, sizeof(char *), indexcmp);
+
+	texivspace(p);
+	teximacro(p, "Bl -tag -width Ds -compact");
+	for (j = 0; j < p->indexs[i].indexsz; j++) {
+		teximacroopen(p, "It");
+#if HAVE_INDEX
+		teximacroopen(p, "Lkx");
+		texiputchars(p, "\"idx");
+		texiputchars(p, p->indexs[i].name);
+		cp = p->indexs[i].index[j];
+		while ('\n' != *cp) {
+			assert('\0' != *cp);
+			texiputchar(p, *cp++);
+		}
+		texiputchars(p, "\" \"");
+		p->literal++;
+#endif
+		texisplice(p, p->indexs[i].index[j], 
+			strlen(p->indexs[i].index[j]), *pos);
+		parseeoln(p, pos);
+#if HAVE_INDEX
+		p->literal--;
+		texiputchars(p, "\"");
+		teximacroclose(p);
+#endif
+		teximacroclose(p);
+	}
+	p->seenvs = 0;
+	teximacro(p, "El");
+	texivspace(p);
+}
+
 static void
 donode(struct texi *p, enum texicmd cmd, size_t *pos)
 {
+	int	 sv = p->seenvs;
+
+	if (NULL != p->chapters) {
+		advanceeoln(p, pos, 1);
+		return;
+	}
 
+#if HAVE_INDEX
+	p->seenvs = -1;
 	teximacroopen(p, "Ix");
-	texiputchars(p, "Node");
-	while (*pos < BUFSZ(p) && isspace(BUF(p)[*pos]))
+	texiputchars(p, "node");
+	while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
 		advance(p, pos);
 	while (*pos < BUFSZ(p)) {
 		if (BUF(p)[*pos] == ',')
@@ -1488,15 +1579,21 @@ donode(struct texi *p, enum texicmd cmd,
 		texiputchar(p, BUF(p)[*pos]);
 		advance(p, pos);
 	}
-
 	teximacroclose(p);
+#endif
 	advanceeoln(p, pos, 1);
+	p->seenvs = sv;
 }
 
+/*
+ * This handles both menu and detailedmenu.
+ * The syntax of these is fairly... unspecific, but what we do here
+ * seems to work with most manuals.
+ */
 static void
 domenu(struct texi *p, enum texicmd cmd, size_t *pos)
 {
-	size_t	 start, sv;
+	size_t	 start, end, sv;
 
 	if (NULL != p->chapters) {
 		doignblock(p, cmd, pos);
@@ -1505,47 +1602,64 @@ domenu(struct texi *p, enum texicmd cmd,
 
 	advanceeoln(p, pos, 1);
 
+	/* 
+	 * Parse past initial stuff. 
+	 * TODO: the manual says we're supposed to make this in bold or
+	 * something.
+	 */
+	while (*pos < BUFSZ(p)) {
+		while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+			advance(p, pos);
+		if ('*' != BUF(p)[*pos]) {
+			if (TEXICMD_END == peeklinecmd(p, *pos))
+				break;
+			parseeoln(p, pos);
+		} else
+			break;
+	}
+
 	texivspace(p);
 	teximacro(p, "Bl -tag -width Ds -compact");
 	while (*pos < BUFSZ(p)) {
-		/* Read to next menu item. */
-		while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos]))
+		/* 
+		 * Read to next menu item. 
+		 * We simply parse every line until we get a magic '*'.
+		 * These lines might occur interspersed OR as the
+		 * description of an entry.
+		 * Either way it's in the `It' block.
+		 */
+		if (0 == p->seenws)
+			p->seenws = *pos < BUFSZ(p) && isws(BUF(p)[*pos]);
+		while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
 			advance(p, pos);
-		if ('*' != BUF(p)[*pos])
-			break;
+		if ('*' != BUF(p)[*pos]) {
+			if (TEXICMD_END == peeklinecmd(p, *pos))
+				break;
+			parseeoln(p, pos);
+			continue;
+		} 
 
-		assert('*' == BUF(p)[*pos]);
+		/* Now we're parsing a menu item. */
 		advance(p, pos);
-		while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos]))
+		while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
 			advance(p, pos);
-		sv = start = *pos;
+		start = sv = *pos;
 		while (*pos < BUFSZ(p) && ':' != BUF(p)[*pos])
 			advance(p, pos);
-		if (*pos == BUFSZ(p) || *pos == start) {
-			texiwarn(p, "empty menu name");
-			break;
-		}
-		teximacroopen(p, "It");
-		teximacroopen(p, "Lkx");
-		texiputchar(p, '"');
-		texiputchars(p, "Node");
-		for (start = sv; start < *pos; start++)
-			texiputchar(p, BUF(p)[start]);
-		texiputchars(p, "\" \"");
-		for (start = sv; start < *pos; start++)
-			texiputchar(p, BUF(p)[start]);
-		texiputchar(p, '"');
-		teximacroclose(p);
-		teximacroclose(p);
-
+		end = *pos;
 		advance(p, pos);
+
 		if (*pos == BUFSZ(p)) {
 			texiwarn(p, "bad menu syntax");
 			break;
 		} else if (':' != BUF(p)[*pos]) {
 			while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
 				advance(p, pos);
-			start = *pos;
+			teximacroopen(p, "It");
+#ifdef HAVE_INDEX
+			teximacroopen(p, "Lkx");
+			texiputchars(p, "\"node");
+#endif
 			while (*pos < BUFSZ(p)) {
 				switch (BUF(p)[*pos]) {
 				case ('\t'):
@@ -1563,52 +1677,47 @@ domenu(struct texi *p, enum texicmd cmd,
 					}
 					/* FALLTHROUGH */
 				default:
+					texiputchar(p, BUF(p)[*pos]);
 					advance(p, pos);
 					continue;
 				}
 				advance(p, pos);
 				break;
 			}
-		} else
-			advance(p, pos);
-
-		while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
-			advance(p, pos);
-
-		if (*pos == BUFSZ(p)) {
-			texiwarn(p, "bad menu syntax");
-			break;
-		}
-
-		while (*pos < BUFSZ(p)) {
-			if ('*' == BUF(p)[*pos])
-				break;
-			if ('\n' != BUF(p)[*pos]) {
-				texiputchar(p, BUF(p)[*pos]);
-				advance(p, pos);
-				continue;
-			}
+#ifdef HAVE_INDEX
+			texiputchars(p, "\" \"");
+			for (start = sv; start < end; start++)
+				texiputchar(p, BUF(p)[start]);
+			texiputchar(p, '"');
+#endif
+		} else {
 			advance(p, pos);
-			while (*pos == BUFSZ(p)) {
-				texiwarn(p, "bad menu syntax");
-				break;
-			} 
-			if ('\n' == BUF(p)[*pos]) {
-				advance(p, pos);
-				break;
-			} else if ('*' == BUF(p)[*pos]) {
-				continue;
-			} else if ('@' == BUF(p)[*pos]) 
-				break;
-			texiputchar(p, ' ');
+			p->seenvs = 0;
+			teximacroopen(p, "It");
+#ifdef HAVE_INDEX
+			teximacroopen(p, "Lkx");
+			texiputchars(p, "\"node");
+			for (start = sv; start < end; start++)
+				texiputchar(p, BUF(p)[start]);
+			texiputchars(p, "\" \"");
+#endif
+			for (start = sv; start < end; start++)
+				texiputchar(p, BUF(p)[start]);
+#ifdef HAVE_INDEX
+			texiputchar(p, '"');
+#endif
 		}
+#ifdef HAVE_INDEX
+		teximacroclose(p);
+#endif
+		teximacroclose(p);
 	}
 
+	advanceeoln(p, pos, 0);
+	p->seenvs = 0;
 	teximacro(p, "El");
-
-	doignblock(p, cmd, pos);
+	texivspace(p);
 }
-#endif
 
 static void
 domath(struct texi *p, enum texicmd cmd, size_t *pos)
@@ -1750,43 +1859,6 @@ sectioner(struct texi *p, int sec)
 }
 
 static void
-dosubsubsection(struct texi *p, enum texicmd cmd, size_t *pos)
-{
-	int	 sec;
-
-	sec = sectioner(p, 3);
-
-	/* We don't have a subsubsubsection, so make one up. */
-	texivspace(p);
-	teximacroopen(p, sects[sec]);
-	parseeoln(p, pos);
-	teximacroclose(p);
-	texivspace(p);
-}
-
-static void
-dosubsection(struct texi *p, enum texicmd cmd, size_t *pos)
-{
-	int	 sec;
-
-	sec = sectioner(p, 2);
-
-	if (p->outmacro)
-		texierr(p, "\"%s\" in open line scope!?", sects[sec]);
-	else if (p->literal)
-		texierr(p, "\"%s\" in a literal scope!?", sects[sec]);
-
-	/* We don't have a subsubsection, so make one up. */
-	if (sec > 1)
-		texivspace(p);
-	teximacroopen(p, sects[sec]);
-	parseeoln(p, pos);
-	teximacroclose(p);
-	if (sec > 1)
-		texivspace(p);
-}
-
-static void
 dosecoffs(struct texi *p, enum texicmd cmd, size_t *pos)
 {
 
@@ -1816,6 +1888,18 @@ dosection(struct texi *p, enum texicmd c
 	case (TEXICMD_UNNUMBEREDSEC):
 		sec = sectioner(p, 1);
 		break;
+	case (TEXICMD_APPENDIXSUBSEC):
+	case (TEXICMD_SUBHEADING):
+	case (TEXICMD_SUBSECTION):
+	case (TEXICMD_UNNUMBEREDSUBSEC):
+		sec = sectioner(p, 2);
+		break;
+	case (TEXICMD_APPENDIXSUBSUBSEC):
+	case (TEXICMD_SUBSUBHEADING):
+	case (TEXICMD_SUBSUBSECTION):
+	case (TEXICMD_UNNUMBEREDSUBSUBSEC):
+		sec = sectioner(p, 3);
+		break;
 	default:
 		abort();
 	}
@@ -1825,6 +1909,11 @@ dosection(struct texi *p, enum texicmd c
 	else if (p->literal)
 		texierr(p, "\"%s\" in a literal scope!?", sects[sec]);
 
+	if (sec < 2)
+		p->seenvs = -1;
+	else 
+		texivspace(p);
+
 	if (0 == sec && NULL != p->chapters) {
 		teximdocclose(p, 0);
 		teximdocopen(p, pos);
@@ -1833,6 +1922,11 @@ dosection(struct texi *p, enum texicmd c
 	teximacroopen(p, sects[sec]);
 	parseeoln(p, pos);
 	teximacroclose(p);
+
+	if (sec < 2)
+		p->seenvs = -1;
+	else
+		texivspace(p);
 }
 
 static void
@@ -1876,9 +1970,11 @@ doitem(struct texi *p, enum texicmd cmd,
 
 	switch (p->list) {
 	case (TEXILIST_ITEM):
+		p->seenvs = -1;
 		teximacroopen(p, "It");
 		break;
 	case (TEXILIST_NOITEM):
+		p->seenvs = -1;
 		teximacro(p, "It");
 		break;
 	default:
@@ -1975,6 +2071,7 @@ domultitable(struct texi *p, enum texicm
 	teximacro(p, "TE");
 	p->literal = svliteral;
 	p->list = sv;
+	texivspace(p);
 }
 
 static void
@@ -1985,10 +2082,12 @@ dotable(struct texi *p, enum texicmd cmd
 	advanceeoln(p, pos, 1);
 
 	p->list = TEXILIST_ITEM;
-	teximacro(p, "Bl -tag -width Ds");
+	texivspace(p);
+	teximacro(p, "Bl -tag -width Ds -compact");
 	parseto(p, pos, texitoks[cmd].tok);
+	p->seenvs = 0;
 	teximacro(p, "El");
-	p->seenvs = 1;
+	texivspace(p);
 	p->list = sv;
 }
 
@@ -2016,10 +2115,12 @@ doenumerate(struct texi *p, enum texicmd
 	advanceeoln(p, pos, 1);
 
 	p->list = TEXILIST_NOITEM;
-	teximacro(p, "Bl -enum");
+	texivspace(p);
+	teximacro(p, "Bl -enum -compact");
 	parseto(p, pos, texitoks[cmd].tok);
+	p->seenvs = 0;
 	teximacro(p, "El");
-	p->seenvs = 1;
+	texivspace(p);
 	p->list = sv;
 }
 
@@ -2031,10 +2132,12 @@ doitemize(struct texi *p, enum texicmd c
 	advanceeoln(p, pos, 1);
 
 	p->list = TEXILIST_NOITEM;
-	teximacro(p, "Bl -bullet");
+	texivspace(p);
+	teximacro(p, "Bl -bullet -compact");
 	parseto(p, pos, texitoks[cmd].tok);
+	p->seenvs = 0;
 	teximacro(p, "El");
-	p->seenvs = 1;
+	texivspace(p);
 	p->list = sv;
 }
 
@@ -2048,6 +2151,56 @@ doignbracket(struct texi *p, enum texicm
 }
 
 static void
+doindex(struct texi *p, enum texicmd cmd, size_t *pos)
+{
+	size_t	 start, end, len;
+
+	while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+		advance(p, pos);
+
+	start = *pos;
+	while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos])
+		advance(p, pos);
+
+	if (*pos == BUFSZ(p)) {
+		texiwarn(p, "unexpected EOF");
+		return;
+	}
+
+	advance(p, pos);
+	end = *pos;
+	if (0 == (len = end - start)) {
+		texiwarn(p, "zero-length index");
+		return;
+	}
+
+	/* Two-letter combos we can look up verbatim. */
+	if (7 == texitoks[cmd].len) {
+		texindex(p, texitoks[cmd].tok, 2, &BUF(p)[start], len);
+		return;
+	}
+
+	assert(6 == texitoks[cmd].len);
+	/* Newer one-letter combos need to be mapped. */
+	switch (texitoks[cmd].tok[0]) {
+	case ('c'):
+		texindex(p, "cp", 2, &BUF(p)[start], len);
+		break;
+	case ('v'):
+		texindex(p, "vr", 2, &BUF(p)[start], len);
+		break;
+	case ('f'):
+		texindex(p, "fn", 2, &BUF(p)[start], len);
+		break;
+	case ('t'):
+		texindex(p, "tp", 2, &BUF(p)[start], len);
+		break;
+	default:
+		abort();
+	}
+}
+
+static void
 doignline(struct texi *p, enum texicmd cmd, size_t *pos)
 {
 
@@ -2110,6 +2263,7 @@ main(int argc, char *argv[])
 	memset(&texi, 0, sizeof(struct texi));
 	texi.ign = 1;
 	texi.outfile = stdout;
+	texi.seenvs = -1;
 	Idir = NULL;
 
 	while (-1 != (c = getopt(argc, argv, "C:I:"))) 
@@ -2126,6 +2280,12 @@ main(int argc, char *argv[])
 
 	argv += optind;
 	argc -= optind;
+
+	/* Add the default Texinfo indices. */
+	texindex_add(&texi, "cp", 2);
+	texindex_add(&texi, "vr", 2);
+	texindex_add(&texi, "tp", 2);
+	texindex_add(&texi, "fn", 2);
 
 	if (argc > 0) {
 		if (NULL == (dirpath = strdup(argv[0])))
Index: util.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/util.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -Lutil.c -Lutil.c -u -p -r1.29 -r1.30
--- util.c
+++ util.c
@@ -103,6 +103,120 @@ texivaluefree(struct texivalue *p)
 	free(p->value);
 }
 
+static void
+texidex_free(struct texidex *p)
+{
+	size_t	 i;
+
+	for (i = 0; i < p->indexsz; i++)
+		free(p->index[i]);
+
+	free(p->index);
+	free(p->name);
+	p->index = NULL;
+	p->indexsz = 0;
+}
+
+/*
+ * Add the text beginning at "index" and of "sz" bytes to the index
+ * named "tok" with name size "toksz".
+ * This will also output the necessary mdoc(7) to construct the index.
+ */
+void
+texindex(struct texi *p, const char *tok,
+	size_t toksz, const char *index, size_t sz)
+{
+	size_t	 i;
+#ifdef HAVE_INDEX
+	char	*cp;
+#endif
+
+	if (0 == sz) {
+		texiwarn(p, "zero-length index entry");
+		return;
+	}
+
+	/* Look for the index.  (Must be found.) */
+	for (i = 0; i < p->indexsz; i++) {
+		if (strlen(p->indexs[i].name) != toksz)
+			continue;
+		if (strncmp(p->indexs[i].name, tok, toksz))
+			continue;
+		break;
+	}
+
+	assert(i < p->indexsz);
+	/* Reallocate index's terms. */
+	p->indexs[i].index = realloc
+		(p->indexs[i].index,
+		 (p->indexs[i].indexsz + 1) *
+		 sizeof(char *));
+	if (NULL == p->indexs[i].index)
+		texiabort(p, NULL);
+
+	/* Add term to term array. */
+	p->indexs[i].index[p->indexs[i].indexsz] = 
+		malloc(sz + 1);
+	if (NULL == p->indexs[i].index[p->indexs[i].indexsz])
+		texiabort(p, NULL);
+	memcpy(p->indexs[i].index[p->indexs[i].indexsz],
+		index, sz);
+	p->indexs[i].index[p->indexs[i].indexsz][sz] = '\0';
+	
+	/* Output mdoc(7) for index. */
+#ifdef HAVE_INDEX
+	p->seenvs = -1;
+	teximacroopen(p, "Ix");
+	texiputchars(p, "idx");
+	texiputchars(p, p->indexs[i].name);
+	cp = p->indexs[i].index[p->indexs[i].indexsz];
+	while ('\n' != *cp) {
+		assert('\0' != *cp);
+		texiputchar(p, *cp++);
+	}
+	teximacroclose(p);
+#endif
+	p->indexs[i].indexsz++;
+}
+
+/*
+ * Add an index entry named "tok" of length "sz".
+ * This usually consists of two letters, e.g., "cp" or "vr".
+ * This does nothing if the index exists or is zero-sized.
+ */
+void
+texindex_add(struct texi *p, const char *tok, size_t sz)
+{
+	size_t	 i;
+	char	*cp;
+
+	if (0 == sz)
+		return;
+
+	/* Make sure we don't have a duplicate. */
+	for (i = 0; i < p->indexsz; i++) {
+		if (strlen(p->indexs[i].name) != sz)
+			continue;
+		if (strncmp(p->indexs[i].name, tok, sz))
+			continue;
+		return;
+	}
+
+	/* Reallocate indices. */
+	p->indexs = realloc(p->indexs, 
+		sizeof(struct texidex) * (p->indexsz + 1));
+	if (NULL == p->indexs)
+		texiabort(p, NULL);
+	if (NULL == (cp = malloc(sz + 1)))
+		texiabort(p, NULL);
+	memcpy(cp, tok, sz);
+	cp[sz] = '\0';
+	p->indexs[p->indexsz].name = cp;
+	p->indexs[p->indexsz].index = NULL;
+	p->indexs[p->indexsz].indexsz = 0;
+	p->indexsz++;
+}
+
 /*
  * Unmap all files that we're currently using and free all resources
  * that we've allocated during the parse.
@@ -128,7 +242,7 @@ texiexit(struct texi *p)
 	for (i = 0; i < p->dirsz; i++)
 		free(p->dirs[i]);
 	for (i = 0; i < p->indexsz; i++)
-		free(p->indexs[i]);
+		texidex_free(&p->indexs[i]);
 	for (i = 0; i < p->valsz; i++) 
 		texivaluefree(&p->vals[i]);
 
@@ -280,14 +394,13 @@ void
 teximacroclose(struct texi *p)
 {
 
-	if (p->ign)
+	if (p->ign || p->literal|| TEXILIST_TABLE == p->list)
 		return;
 
 	if (0 == --p->outmacro) {
 		fputc('\n', p->outfile);
 		p->outcol = p->seenws = 0;
 	}
-	p->seenvs = 0;
 }
 
 /*
@@ -301,7 +414,7 @@ teximacroopen(struct texi *p, const char
 {
 	int	 rc;
 
-	if (p->ign)
+	if (p->ign || p->literal|| TEXILIST_TABLE == p->list)
 		return;
 
 	if (p->outcol && 0 == p->outmacro) {
@@ -309,6 +422,9 @@ teximacroopen(struct texi *p, const char
 		p->outcol = 0;
 	}
 
+	if (p->seenvs > 0 && 0 == p->outmacro)
+		fputs(".Pp\n", p->outfile);
+
 	if (0 == p->outmacro)
 		fputc('.', p->outfile);
 	else
@@ -320,8 +436,7 @@ teximacroopen(struct texi *p, const char
 	fputc(' ', p->outfile);
 	p->outcol++;
 	p->outmacro++;
-	p->seenws = 0;
-	p->seenvs = 0;
+	p->seenws = p->seenvs = 0;
 }
 
 /*
@@ -338,15 +453,15 @@ teximacro(struct texi *p, const char *s)
 		texierr(p, "\"%s\" in open line scope!?", s);
 	if (p->literal)
 		texierr(p, "\"%s\" in a literal scope!?", s);
-
 	if (p->outcol)
 		fputc('\n', p->outfile);
+	if (p->seenvs > 0)
+		fputs(".Pp\n", p->outfile);
 
 	fputc('.', p->outfile);
 	fputs(s, p->outfile);
 	fputc('\n', p->outfile);
 	p->outcol = p->seenws = 0;
-	p->seenvs = 0;
 }
 
 /*
@@ -356,8 +471,8 @@ void
 texivspace(struct texi *p)
 {
 
-	if (TEXILIST_TABLE != p->list)
-		teximacro(p, "Pp");
+	if (TEXILIST_TABLE != p->list && p->seenvs >= 0)
+		p->seenvs = 1;
 }
 
 /*
@@ -420,7 +535,7 @@ texipunctuate(struct texi *p, size_t *po
 	if (end == *pos)
 		return;
 	if (end + 1 == BUFSZ(p) || ' ' == BUF(p)[end] || 
-		'\n' == BUF(p)[end]) {
+		'@' == BUF(p)[end] || '\n' == BUF(p)[end]) {
 		for ( ; start < end; start++) {
 			texiputchar(p, ' ');
 			texiputchar(p, BUF(p)[start]);
@@ -448,6 +563,9 @@ advancenext(struct texi *p, size_t *pos)
 
 	while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos])) {
 		p->seenws = 1;
+		if (0 == p->seenvs && '\n' == BUF(p)[*pos])
+			if (*pos + 1 < BUFSZ(p) && '\n' == BUF(p)[*pos + 1])
+				p->seenvs = 1;
 		advance(p, pos);
 	}
 	return(*pos);
@@ -608,10 +726,12 @@ parseword(struct texi *p, size_t *pos, c
 	 * We don't do this if we're in a literal context (we'll print
 	 * out the newlines themselves) nor in a `TS' table.
 	 */
-	if (p->seenvs && 0 == p->literal && TEXILIST_TABLE != p->list)
-		teximacro(p, "Pp");
-
-	p->seenvs = 0;
+	if (p->seenvs > 0 && 0 == p->literal && TEXILIST_TABLE != p->list) {
+		if (p->outcol > 0)
+			fputc('\n', p->outfile);
+		fputs(".Pp\n", p->outfile);
+		p->outcol = 0;
+	}
 
 	/*
 	 * Some line control: if we (non-macro, non-literal) already
@@ -684,7 +804,9 @@ parseword(struct texi *p, size_t *pos, c
 			continue;
 		}
 
-		if (*pos < BUFSZ(p) - 2 && 
+		if ('"' == BUF(p)[*pos]) {
+			texiputchars(p, "\\(dq");
+		} else if (*pos < BUFSZ(p) - 2 && 
 			 '-' == BUF(p)[*pos] && 
 			 '-' == BUF(p)[*pos + 1] && 
 			 '-' == BUF(p)[*pos + 2]) {
@@ -712,19 +834,23 @@ parseword(struct texi *p, size_t *pos, c
 		advance(p, pos);
 	}
 
-	if (*pos + 1 < BUFSZ(p) && 
-		'\n' == BUF(p)[*pos] &&
-		'\n' == BUF(p)[*pos + 1])
-		p->seenvs = 1;
-
 	/* 
 	 * New sentence, new line:if we (non-macro, non-literal) see a
 	 * period at the end of the last printed word, then open a
 	 * newline.
 	 */
-	if (0 == p->literal && 0 == p->outmacro && 
-		*pos < BUFSZ(p) && '.' == BUF(p)[*pos - 1])
-		texiputchar(p, '\n');
+	if (0 == p->literal && 0 == p->outmacro && *pos < BUFSZ(p))
+		switch (BUF(p)[*pos - 1]) {
+		case ('.'):
+		case ('!'):
+		case ('?'):
+			texiputchar(p, '\n');
+			break;
+		default:
+			break;
+		}
+
+	p->seenvs = 0;
 }
 
 /*
@@ -778,10 +904,10 @@ texicmd(const struct texi *p, size_t pos
 
 	/* Look for it in our indices. */
 	for (i = 0; i < p->indexsz; i++) {
-		toksz = strlen(p->indexs[i]);
+		toksz = strlen(p->indexs[i].name);
 		if (len != 5 + toksz)
 			continue;
-		if (strncmp(&BUF(p)[pos], p->indexs[i], toksz))
+		if (strncmp(&BUF(p)[pos], p->indexs[i].name, toksz))
 			continue;
 		if (0 == strncmp(&BUF(p)[pos + toksz], "index", 5))
 			return(TEXICMD_USER_INDEX);
@@ -946,6 +1072,8 @@ parseeoln(struct texi *p, size_t *pos)
 				texiwarn(p, "unexpected \"{\"");
 			advance(p, pos);
 			continue;
+		case ('\n'):
+			continue;
 		case ('@'):
 			break;
 		default:
@@ -968,6 +1096,18 @@ parseeoln(struct texi *p, size_t *pos)
 		advance(p, pos);
 }
 
+enum texicmd
+peeklinecmd(const struct texi *p, size_t pos)
+{
+	size_t		end;
+
+	while (pos < BUFSZ(p) && isws(BUF(p)[pos]))
+		pos++;
+	if (pos == BUFSZ(p) || '@' != BUF(p)[pos])
+		return(TEXICMD__MAX);
+	return(texicmd(p, pos, &end, NULL));
+}
+
 /*
  * Peek to see if there's a command after subsequent whitespace.
  * If so, return the macro identifier.
@@ -1152,6 +1292,9 @@ parseto(struct texi *p, size_t *pos, con
 		if (NULL != texitoks[cmd].fp) 
 			(*texitoks[cmd].fp)(p, cmd, pos);
 	}
+
+	if (*pos == BUFSZ(p)) 
+		texiwarn(p, "EOF expecting \"%s\" end\n", endtoken);
 }
 
 /*
@@ -1577,6 +1720,7 @@ teximdocopen(struct texi *p, size_t *pos
 	t = time(NULL);
 	strftime(date, sizeof(date), "%F", localtime(&t));
 
+	p->seenvs = -1;
 	teximacroopen(p, "Dd");
 	texiputchars(p, date);
 	teximacroclose(p);
--
 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-11 12:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-11 12:52 texi2mdoc: Enormous patch (re-)fixing (again) the vertical space issue, 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).