From 9972b0f0d1ce6e08ce6f9505980c9c889ae994bc Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 12 Sep 1999 15:38:06 +0000 Subject: More development... [originally from svn r220] --- biblio.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 biblio.c (limited to 'biblio.c') diff --git a/biblio.c b/biblio.c new file mode 100644 index 0000000..70e9411 --- /dev/null +++ b/biblio.c @@ -0,0 +1,104 @@ +/* + * biblio.c: process the bibliography + */ + +#include +#include "buttress.h" + +static wchar_t *gentext(int num) { + wchar_t text[22]; + wchar_t *p = text + sizeof(text); + *--p = L'\0'; + *--p = L']'; + while (num != 0) { + assert(p > text); + *--p = L"0123456789"[num % 10]; + num /= 10; + } + assert(p > text); + *--p = L'['; + return ustrdup(p); +} + +static void cite_biblio(keywordlist *kl, wchar_t *key, filepos fpos) { + keyword *kw = kw_lookup(kl, key); + if (!kw) + error(err_nosuchkw, &fpos, key); + else { + /* + * We've found a \k reference. If it's a + * bibliography entry ... + */ + if (kw->para->type == para_Biblio) { + /* + * ... then mark the paragraph as cited. + */ + kw->para->type = para_BiblioCited; + } + } +} + +/* + * Make a pass through the source form, generating citation formats + * for bibliography entries and also marking which bibliography + * entries are actually cited (or \nocite-ed). + */ + +void gen_citations(paragraph *source, keywordlist *kl) { + paragraph *para; + int bibnum = 0; + + for (para = source; para; para = para->next) { + word *ptr; + + /* + * \BR and \nocite paragraphs get special processing here. + */ + if (para->type == para_BR) { + keyword *kw = kw_lookup(kl, para->keyword); + if (!kw) { + error(err_nosuchkw, ¶->fpos, para->keyword); + } else if (kw->text) { + error(err_multiBR, ¶->fpos, para->keyword); + } else { + kw->text = dup_word_list(para->words); + } + } else if (para->type == para_NoCite) { + wchar_t *wp = para->keyword; + while (*wp) { + cite_biblio(kl, wp, para->fpos); + wp += 1+ustrlen(wp); + } + } + + /* + * Scan for keyword references. + */ + for (ptr = para->words; ptr; ptr = ptr->next) { + if (ptr->type == word_UpperXref || + ptr->type == word_LowerXref) + cite_biblio(kl, ptr->text, ptr->fpos); + } + } + + /* + * We're now almost done; all that remains is to scan through + * the cited bibliography entries and invent default citation + * texts for the ones that don't already have explicitly + * provided \BR text. + */ + for (para = source; para; para = para->next) { + if (para->type == para_BiblioCited) { + keyword *kw = kw_lookup(kl, para->keyword); + assert(kw != NULL); + if (!kw->text) { + word *wd = smalloc(sizeof(word)); + wd->text = gentext(++bibnum); + wd->type = word_Normal; + wd->alt = NULL; + wd->next = NULL; + kw->text = wd; + } + } + } +} -- cgit v1.1