X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/5b1d0032b0eb6f4a347c0c2cfdbe6e4bb4f959ab..22e33bbadced87bb648d8038291cc2e88afe74b5:/bk_info.c diff --git a/bk_info.c b/bk_info.c index 5c05817..4a6ea73 100644 --- a/bk_info.c +++ b/bk_info.c @@ -21,6 +21,27 @@ * * Section 1.2: Nodename. Title of section. * * - might be helpful to diagnose duplicate node names! + * + * - more flexibility in heading underlines, like text backend. + * + Given info.el's fontifier, we'd want the following defaults: + * \cfg{info-title-underline}{*} + * \cfg{info-chapter-underline}{=} + * \cfg{info-section-underline}{0}{-} + * \cfg{info-section-underline}{1}{.} + * + * - Indices generated by makeinfo use a menu rather than a bunch of + * cross-references, which reduces visual clutter rather. For + * singly-referenced items, it looks like: + * * toner cartridge, replacing: Toner. + * It does a horrid job on multiply-referenced entries, though, + * perhaps because the name before the colon is meant to be unique. + * Info's 'i' command requires the use of a menu -- it fails to + * find any index entries at all with Halibut's current index format. + * + * - The string "*note" is matched case-insensitively, so we could + * make things slightly less ugly by using the lower-case version + * when the user asks for \k. Unfortunately, standalone Info seems + * to match node names case-sensitively, so we can't downcase that. */ #include @@ -39,6 +60,7 @@ typedef struct { wchar_t *lquote, *rquote; wchar_t *sectsuffix, *underline; wchar_t *rule; + wchar_t *index_text; } infoconfig; typedef struct { @@ -84,7 +106,8 @@ static int info_check_index(word *, node *, indexdata *); static int info_rdaddwc(info_data *, word *, word *, int, infoconfig *); static node *info_node_new(char *name, int charset); -static char *info_node_name(paragraph *p, infoconfig *); +static char *info_node_name_for_para(paragraph *p, infoconfig *); +static char *info_node_name_for_text(wchar_t *text, infoconfig *); static infoconfig info_configure(paragraph *source) { infoconfig ret; @@ -110,6 +133,7 @@ static infoconfig info_configure(paragraph *source) { ret.rquote = uadv(ret.lquote); ret.sectsuffix = L": "; ret.underline = L"\x203E\0-\0\0"; + ret.index_text = L"Index"; /* * Two-pass configuration so that we can pick up global config @@ -124,6 +148,8 @@ static infoconfig info_configure(paragraph *source) { ret.lquote = uadv(p->keyword); ret.rquote = uadv(ret.lquote); } + } else if (!ustricmp(p->keyword, L"index")) { + ret.index_text = uadv(p->keyword); } } } @@ -134,9 +160,7 @@ static infoconfig info_configure(paragraph *source) { sfree(ret.filename); ret.filename = dupstr(adv(p->origkeyword)); } else if (!ustricmp(p->keyword, L"info-charset")) { - char *csname = utoa_dup(uadv(p->keyword), CS_ASCII); - ret.charset = charset_from_localenc(csname); - sfree(csname); + ret.charset = charset_from_ustr(&p->fpos, uadv(p->keyword)); } else if (!ustricmp(p->keyword, L"info-max-file-size")) { ret.maxfilesize = utoi(uadv(p->keyword)); } else if (!ustricmp(p->keyword, L"info-width")) { @@ -249,7 +273,7 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, node *newnode, *upnode; char *nodename; - nodename = info_node_name(p, &conf); + nodename = info_node_name_for_para(p, &conf); newnode = info_node_new(nodename, conf.charset); sfree(nodename); @@ -269,6 +293,9 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, currnode = newnode; } break; + default: + p->private_data = NULL; + break; } /* @@ -279,7 +306,7 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, indexentry *entry; for (i = 0; (entry = index234(idx->entries, i)) != NULL; i++) { - info_idx *ii = mknew(info_idx); + info_idx *ii = snew(info_idx); info_data id = EMPTY_INFO_DATA; id.charset = conf.charset; @@ -315,12 +342,12 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, char *s; section = uadv(p->keyword); - shortname = *section ? uadv(section) : NULL; - longname = *shortname ? uadv(shortname) : NULL; - kw = *longname ? uadv(longname) : NULL; + shortname = *section ? uadv(section) : L""; + longname = *shortname ? uadv(shortname) : L""; + kw = *longname ? uadv(longname) : L""; if (!*longname) { - error(err_infodirentry, &p->fpos); + error(err_cfginsufarg, &p->fpos, p->origkeyword, 3); continue; } @@ -494,15 +521,25 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, node *newnode; int i, j, k; indexentry *entry; + char *nodename; + + nodename = info_node_name_for_text(conf.index_text, &conf); + newnode = info_node_new(nodename, conf.charset); + sfree(nodename); - newnode = info_node_new("Index", conf.charset); newnode->up = topnode; currnode->next = newnode; newnode->prev = currnode; currnode->listnext = newnode; - info_rdaddsc(&newnode->text, "Index\n-----\n\n"); + k = info_rdadds(&newnode->text, conf.index_text); + info_rdaddsc(&newnode->text, "\n"); + while (k > 0) { + info_rdadds(&newnode->text, conf.underline); + k -= ustrwid(conf.underline, conf.charset); + } + info_rdaddsc(&newnode->text, "\n\n"); info_menu_item(&topnode->text, newnode, NULL, &conf); @@ -631,7 +668,7 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, if (fp) fclose(fp); - fname = mknewa(char, strlen(conf.filename) + 40); + fname = snewn(strlen(conf.filename) + 40, char); sprintf(fname, "%s-%d", conf.filename, filenum); fp = fopen(fname, "w"); if (!fp) { @@ -678,7 +715,7 @@ static int info_check_index(word *w, node *n, indexdata *idx) if (ii->nnodes >= ii->nodesize) { ii->nodesize += 32; - ii->nodes = resize(ii->nodes, ii->nodesize); + ii->nodes = sresize(ii->nodes, ii->nodesize, node *); } ii->nodes[ii->nnodes++] = n; @@ -708,7 +745,7 @@ static word *info_transform_wordlist(word *words, keywordlist *keywords) * In Info, we do nothing special for xrefs to * numbered list items or bibliography entries. */ - break; + continue; } else { /* * An xref to a different section has its text @@ -1024,7 +1061,7 @@ static node *info_node_new(char *name, int charset) { node *n; - n = mknew(node); + n = snew(node); n->text = empty_info_data; n->text.charset = charset; n->up = n->next = n->prev = n->lastchild = n->listnext = NULL; @@ -1034,32 +1071,49 @@ static node *info_node_new(char *name, int charset) return n; } -static char *info_node_name(paragraph *par, infoconfig *cfg) +static char *info_node_name_core(info_data *id, filepos *fpos) { - info_data id = EMPTY_INFO_DATA; char *p, *q; - id.charset = cfg->charset; - info_rdaddwc(&id, par->kwtext ? par->kwtext : par->words, - NULL, FALSE, cfg); - info_rdaddsc(&id, NULL); - /* - * We cannot have commas or colons in a node name. Remove any - * that we find, with a warning. + * We cannot have commas, colons or parentheses in a node name. + * Remove any that we find, with a warning. */ - p = q = id.output.text; + p = q = id->output.text; while (*p) { - if (*p == ':' || *p == ',') { - error(err_infonodechar, &par->fpos, *p); + if (*p == ':' || *p == ',' || *p == '(' || *p == ')') { + error(err_infonodechar, fpos, *p); } else { *q++ = *p; } p++; } - *p = '\0'; + *q = '\0'; + + return id->output.text; +} + +static char *info_node_name_for_para(paragraph *par, infoconfig *cfg) +{ + info_data id = EMPTY_INFO_DATA; + + id.charset = cfg->charset; + info_rdaddwc(&id, par->kwtext ? par->kwtext : par->words, + NULL, FALSE, cfg); + info_rdaddsc(&id, NULL); + + return info_node_name_core(&id, &par->fpos); +} + +static char *info_node_name_for_text(wchar_t *text, infoconfig *cfg) +{ + info_data id = EMPTY_INFO_DATA; + + id.charset = cfg->charset; + info_rdadds(&id, text); + info_rdaddsc(&id, NULL); - return id.output.text; + return info_node_name_core(&id, NULL); } static void info_menu_item(info_data *text, node *n, paragraph *p,