/*
* info backend for Halibut
*
- * TODO:
+ * Possible future work:
*
- * - basic vital configuration: Info dir entries in heading, and
- * how to allocate node names
- * - escape, warn or simply remove commas and colons in node
- * names; also test colons in index terms.
- * - test everything in info(1), and probably jed too
+ * - configurable indentation, bullets, emphasis, quotes etc?
*
- * Later:
+ * - configurable choice of how to allocate node names?
+ * + possibly a template-like approach, choosing node names to
+ * be the full section title or perhaps the internal keyword?
+ * + neither of those seems quite right. Perhaps instead a
+ * Windows Help-like mechanism, where a magic config
+ * directive allows user choice of name for every node.
+ * + Only trouble with that is, now what happens to the section
+ * numbers? Do they become completely vestigial and just sit
+ * in the title text of each node? Or do we keep them in the
+ * menus somehow? I think people might occasionally want to
+ * go to a section by number, if only because all the _other_
+ * formats of the same document will reference the numbers
+ * all the time. So our menu lines could look like one of
+ * these:
+ * * Nodename: Section 1.2. Title of section.
+ * * Section 1.2: Nodename. Title of section.
*
- * - configurable indentation, bullets, emphasis, quotes etc?
+ * - might be helpful to diagnose duplicate node names!
*/
#include <stdio.h>
}
void info_backend(paragraph *sourceform, keywordlist *keywords,
- indexdata *idx) {
+ indexdata *idx, void *unused) {
paragraph *p;
infoconfig conf;
word *prefix, *body, *wp;
int width = 70, listindentbefore = 1, listindentafter = 3;
int indent_code = 2, index_width = 40;
- IGNORE(keywords); /* we don't happen to need this */
- IGNORE(idx); /* or this */
+ IGNORE(unused);
conf = info_configure(sourceform);
ii->nodes = NULL;
info_rdaddwc(&rs, entry->text, NULL, FALSE);
- /*
- * FIXME: splatter colons.
- */
+
ii->text = rs.text;
entry->backend_data = ii;
/*
* An Info file begins with a piece of introductory text which
* is apparently never shown anywhere. This seems to me to be a
- * good place to put the copyright notice and the version IDs.
- *
- * FIXME: also Info directory entries are expected to go here.
- * This will need to be a configurable thing of some sort.
+ * good place to put the copyright notice and the version IDs.
+ * Also, Info directory entries are expected to go here.
*/
rdaddsc(&intro_text,
rdaddsc(&intro_text, "\n\n");
for (p = sourceform; p; p = p->next)
+ if (p->type == para_Config &&
+ !ustricmp(p->keyword, L"info-dir-entry")) {
+ wchar_t *section, *shortname, *longname, *kw;
+ char *s;
+
+ section = uadv(p->keyword);
+ shortname = *section ? uadv(section) : NULL;
+ longname = *shortname ? uadv(shortname) : NULL;
+ kw = *longname ? uadv(longname) : NULL;
+
+ if (!*longname) {
+ error(err_infodirentry, &p->fpos);
+ continue;
+ }
+
+ rdaddsc(&intro_text, "INFO-DIR-SECTION ");
+ s = utoa_dup(section);
+ rdaddsc(&intro_text, s);
+ sfree(s);
+ rdaddsc(&intro_text, "\nSTART-INFO-DIR-ENTRY\n* ");
+ s = utoa_dup(shortname);
+ rdaddsc(&intro_text, s);
+ sfree(s);
+ rdaddsc(&intro_text, ": (");
+ s = dupstr(conf.filename);
+ if (strlen(s) > 5 && !strcmp(s+strlen(s)-5, ".info"))
+ s[strlen(s)-5] = '\0';
+ rdaddsc(&intro_text, s);
+ sfree(s);
+ rdaddsc(&intro_text, ")");
+ if (*kw) {
+ keyword *kwl = kw_lookup(keywords, kw);
+ if (kwl && kwl->para->private_data) {
+ node *n = (node *)kwl->para->private_data;
+ rdaddsc(&intro_text, n->name);
+ }
+ }
+ rdaddsc(&intro_text, ". ");
+ s = utoa_dup(longname);
+ rdaddsc(&intro_text, s);
+ sfree(s);
+ rdaddsc(&intro_text, "\nEND-INFO-DIR-ENTRY\n\n");
+ }
+
+ for (p = sourceform; p; p = p->next)
if (p->type == para_Copyright)
info_para(&intro_text, NULL, NULL, p->words, keywords,
0, 0, width);
newnode->prev = currnode;
currnode->listnext = newnode;
- rdaddsc(&newnode->text, "Index\n-----\n\n* Menu:\n\n");
+ rdaddsc(&newnode->text, "Index\n-----\n\n");
info_menu_item(&topnode->text, newnode, NULL);
for (j = 0; j < ii->nnodes; j++) {
int pos0 = newnode->text.pos;
- rdaddsc(&newnode->text, "* ");
/*
* When we have multiple references for a single
* index term, we only display the actual term on
rdaddsc(&newnode->text, ii->text);
for (k = newnode->text.pos - pos0; k < index_width; k++)
rdaddc(&newnode->text, ' ');
- rdaddsc(&newnode->text, ": ");
+ rdaddsc(&newnode->text, " *Note ");
rdaddsc(&newnode->text, ii->nodes[j]->name);
- rdaddsc(&newnode->text, ".\n");
+ rdaddsc(&newnode->text, "::\n");
}
}
}
return 0; /* should never happen */
}
-static int info_width_noxrefs(word *words)
+static int info_width_noxrefs(void *ctx, word *words)
{
+ IGNORE(ctx);
return info_width_internal(words, FALSE);
}
-static int info_width_xrefs(word *words)
+static int info_width_xrefs(void *ctx, word *words)
{
+ IGNORE(ctx);
return info_width_internal(words, TRUE);
}
firstlinewidth = width - length;
wrapwidth = width;
- wrapping = wrap_para(words, firstlinewidth, wrapwidth, info_width_noxrefs);
+ wrapping = wrap_para(words, firstlinewidth, wrapwidth,
+ info_width_noxrefs, NULL, 0);
for (p = wrapping; p; p = p->next) {
info_rdaddwc(&t, p->begin, p->end, FALSE);
length = (t.text ? strlen(t.text) : 0);
} else
e = indent + extraindent;
- wrapping = wrap_para(words, firstlinewidth, width, info_width_xrefs);
+ wrapping = wrap_para(words, firstlinewidth, width, info_width_xrefs,
+ NULL, 0);
for (p = wrapping; p; p = p->next) {
for (i = 0; i < e; i++)
rdaddc(text, ' ');
return n;
}
-static char *info_node_name(paragraph *p)
+static char *info_node_name(paragraph *par)
{
rdstringc rsc = { 0, 0, NULL };
- info_rdaddwc(&rsc, p->kwtext ? p->kwtext : p->words, NULL, FALSE);
+ char *p, *q;
+ info_rdaddwc(&rsc, par->kwtext ? par->kwtext : par->words, NULL, FALSE);
+
+ /*
+ * We cannot have commas or colons in a node name. Remove any
+ * that we find, with a warning.
+ */
+ p = q = rsc.text;
+ while (*p) {
+ if (*p == ':' || *p == ',') {
+ error(err_infonodechar, &par->fpos, *p);
+ } else {
+ *q++ = *p;
+ }
+ p++;
+ }
+ *p = '\0';
+
return rsc.text;
}