Add an error check for correct formatting in Deflate uncompressed
[sgt/halibut] / biblio.c
CommitLineData
d7482997 1/*
2 * biblio.c: process the bibliography
3 */
4
5#include <assert.h>
6#include "halibut.h"
7
8static wchar_t *gentext(int num) {
9 wchar_t text[22];
6e969fcf 10 wchar_t *p = text + lenof(text);
d7482997 11 *--p = L'\0';
12 *--p = L']';
13 while (num != 0) {
14 assert(p > text);
15 *--p = L"0123456789"[num % 10];
16 num /= 10;
17 }
18 assert(p > text);
19 *--p = L'[';
20 return ustrdup(p);
21}
22
23static void cite_biblio(keywordlist *kl, wchar_t *key, filepos fpos) {
24 keyword *kw = kw_lookup(kl, key);
25 if (!kw)
26 error(err_nosuchkw, &fpos, key);
27 else {
28 /*
29 * We've found a \k reference. If it's a
30 * bibliography entry ...
31 */
32 if (kw->para->type == para_Biblio) {
33 /*
34 * ... then mark the paragraph as cited.
35 */
36 kw->para->type = para_BiblioCited;
37 }
38 }
39}
40
41/*
42 * Make a pass through the source form, generating citation formats
43 * for bibliography entries and also marking which bibliography
44 * entries are actually cited (or \nocite-ed).
45 */
46
47void gen_citations(paragraph *source, keywordlist *kl) {
48 paragraph *para;
49 int bibnum = 0;
50
51 for (para = source; para; para = para->next) {
52 word *ptr;
53
54 /*
55 * \BR and \nocite paragraphs get special processing here.
56 */
57 if (para->type == para_BR) {
58 keyword *kw = kw_lookup(kl, para->keyword);
59 if (!kw) {
60 error(err_nosuchkw, &para->fpos, para->keyword);
61 } else if (kw->text) {
62 error(err_multiBR, &para->fpos, para->keyword);
63 } else {
64 kw->text = dup_word_list(para->words);
65 }
66 } else if (para->type == para_NoCite) {
67 wchar_t *wp = para->keyword;
68 while (*wp) {
69 cite_biblio(kl, wp, para->fpos);
70 wp = uadv(wp);
71 }
72 }
73
74 /*
75 * Scan for keyword references.
76 */
77 for (ptr = para->words; ptr; ptr = ptr->next) {
78 if (ptr->type == word_UpperXref ||
79 ptr->type == word_LowerXref)
80 cite_biblio(kl, ptr->text, ptr->fpos);
81 }
82 }
83
84 /*
85 * We're now almost done; all that remains is to scan through
86 * the cited bibliography entries and invent default citation
87 * texts for the ones that don't already have explicitly
88 * provided \BR text.
89 */
90 for (para = source; para; para = para->next) {
91 if (para->type == para_BiblioCited) {
92 keyword *kw = kw_lookup(kl, para->keyword);
93 assert(kw != NULL);
94 if (!kw->text) {
95 word *wd = smalloc(sizeof(word));
96 wd->text = gentext(++bibnum);
97 wd->type = word_Normal;
98 wd->alt = NULL;
99 wd->next = NULL;
100 kw->text = wd;
101 }
102 para->kwtext = kw->text;
103 }
104 }
105}