X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/8902e0ed6134c9ecc1177ef535852070d0e7326d..e48dc0523b16c52691bda5324e5b294d67a25c70:/input.c diff --git a/input.c b/input.c index 9d165fa..efce410 100644 --- a/input.c +++ b/input.c @@ -162,6 +162,7 @@ enum { c__invalid, /* invalid command */ c__comment, /* comment command (\#) */ c__escaped, /* escaped character */ + c__nop, /* no-op */ c__nbsp, /* nonbreaking space */ c_A, /* appendix heading */ c_B, /* bibliography entry */ @@ -231,6 +232,7 @@ static void match_kw(token *tok) { static const struct { char const *name; int id; } keywords[] = { {"#", c__comment}, /* comment command (\#) */ {"-", c__escaped}, /* nonbreaking hyphen */ + {".", c__nop}, /* no-op */ {"A", c_A}, /* appendix heading */ {"B", c_B}, /* bibliography entry */ {"BR", c_BR}, /* bibliography rewrite */ @@ -360,7 +362,7 @@ token get_token(input *in) { } else if (c == '\\') { /* tok_cmd */ c = get(in, &cpos); if (c == '-' || c == '\\' || c == '_' || - c == '#' || c == '{' || c == '}') { + c == '#' || c == '{' || c == '}' || c == '.') { /* single-char command */ rdadd(&rs, c); } else if (c == 'u') { @@ -526,6 +528,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { } type; word **whptr; /* to restore from \u alternatives */ word **idximplicit; /* to restore from \u alternatives */ + filepos fpos; } *sitem; stack parsestk; struct crossparaitem { @@ -590,14 +593,17 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { */ dtor(t), t = get_token(in); } - if (t.type == tok_eop || t.type == tok_eof) + if (t.type == tok_eop || t.type == tok_eof || + t.type == tok_rbrace) { /* might be } terminating \lcont */ + if (t.type == tok_rbrace) + already = TRUE; break; - else if (t.type == tok_cmd && t.cmd == c_c) + } else if (t.type == tok_cmd && t.cmd == c_c) { wtype = word_WeakCode; - else if (t.type == tok_cmd && t.cmd == c_e && - wtype == word_WeakCode) + } else if (t.type == tok_cmd && t.cmd == c_e && + wtype == word_WeakCode) { wtype = word_Emph; - else { + } else { error(err_brokencodepara, &t.pos); prev_para_type = par.type; addpara(par, ret); @@ -631,6 +637,16 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { continue; } + /* + * Also expect, and swallow, any whitespace after that + * (a newline before a code paragraph wouldn't be + * surprising). + */ + do { + dtor(t), t = get_token(in); + } while (t.type == tok_white); + already = TRUE; + if (cmd == c_lcont) { /* * \lcont causes a continuation of a list item into @@ -905,6 +921,11 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { break; } + if (t.type == tok_cmd && t.cmd == c__nop) { + dtor(t), t = get_token(in); + continue; /* do nothing! */ + } + if (t.type == tok_cmd && t.cmd == c__escaped) { t.type = tok_word; /* nice and simple */ t.aux = 0; /* even if `\-' - nonbreaking! */ @@ -968,6 +989,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { /* Error recovery: push nop */ sitem = mknew(struct stack_item); sitem->type = stack_nop; + sitem->fpos = t.pos; stk_push(parsestk, sitem); break; case tok_rbrace: @@ -992,11 +1014,20 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { } if (sitem->type & stack_idx) { indexword->text = ustrdup(indexstr.text); - if (index_downcase) + if (index_downcase) { + word *w; + ustrlow(indexword->text); + ustrlow(indexstr.text); + + for (w = idxwordlist; w; w = w->next) + if (w->text) + ustrlow(w->text); + } indexing = FALSE; rdadd(&indexstr, L'\0'); - index_merge(idx, FALSE, indexstr.text, idxwordlist); + index_merge(idx, FALSE, indexstr.text, + idxwordlist, &sitem->fpos); sfree(indexstr.text); } if (sitem->type & stack_hyper) { @@ -1082,6 +1113,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { addword(wd, &idximplicit); } sitem = mknew(struct stack_item); + sitem->fpos = t.pos; sitem->type = stack_quote; stk_push(parsestk, sitem); } @@ -1157,11 +1189,43 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { * delimiting the text marked by the link. */ dtor(t), t = get_token(in); + sitem = mknew(struct stack_item); + sitem->fpos = wd.fpos; + sitem->type = stack_hyper; + /* + * Special cases: \W{}\i, \W{}\ii + */ + if (t.type == tok_cmd && + (t.cmd == c_i || t.cmd == c_ii)) { + if (indexing) { + error(err_nestedindex, &t.pos); + } else { + /* Add an index-reference word with no + * text as yet */ + wd.type = word_IndexRef; + wd.text = NULL; + wd.alt = NULL; + wd.aux = 0; + wd.breaks = FALSE; + indexword = addword(wd, &whptr); + /* Set up a rdstring to read the + * index text */ + indexstr = nullrs; + /* Flags so that we do the Right + * Things with text */ + index_visible = (type != c_I); + index_downcase = (type == c_ii); + indexing = TRUE; + idxwordlist = NULL; + idximplicit = &idxwordlist; + + sitem->type |= stack_idx; + } + dtor(t), t = get_token(in); + } /* * Special cases: \W{}\c, \W{}\e, \W{}\cw */ - sitem = mknew(struct stack_item); - sitem->type = stack_hyper; if (t.type == tok_cmd && (t.cmd == c_e || t.cmd == c_c || t.cmd == c_cw)) { if (style != word_Normal) @@ -1192,6 +1256,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { /* Error recovery: eat lbrace, push nop. */ dtor(t), t = get_token(in); sitem = mknew(struct stack_item); + sitem->fpos = t.pos; sitem->type = stack_nop; stk_push(parsestk, sitem); } @@ -1204,6 +1269,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { word_Emph); spcstyle = tospacestyle(style); sitem = mknew(struct stack_item); + sitem->fpos = t.pos; sitem->type = stack_style; stk_push(parsestk, sitem); } @@ -1217,10 +1283,12 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { /* Error recovery: eat lbrace, push nop. */ dtor(t), t = get_token(in); sitem = mknew(struct stack_item); + sitem->fpos = t.pos; sitem->type = stack_nop; stk_push(parsestk, sitem); } sitem = mknew(struct stack_item); + sitem->fpos = t.pos; sitem->type = stack_idx; dtor(t), t = get_token(in); /* @@ -1290,6 +1358,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx) { * paragraph. */ sitem = mknew(struct stack_item); + sitem->fpos = t.pos; sitem->type = stack_ualt; sitem->whptr = whptr; sitem->idximplicit = idximplicit;