diff options
| author | Simon Tatham <anakin@pobox.com> | 1999-09-12 15:38:06 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 1999-09-12 15:38:06 +0000 |
| commit | 9972b0f0d1ce6e08ce6f9505980c9c889ae994bc (patch) | |
| tree | cb867829840d4746c10d0fdba6409f1cf256d5c9 /biblio.c | |
| parent | d3c026f08f629659b5efe23fe8bffd3cf9b845f6 (diff) | |
| download | halibut-9972b0f0d1ce6e08ce6f9505980c9c889ae994bc.zip halibut-9972b0f0d1ce6e08ce6f9505980c9c889ae994bc.tar.gz halibut-9972b0f0d1ce6e08ce6f9505980c9c889ae994bc.tar.bz2 halibut-9972b0f0d1ce6e08ce6f9505980c9c889ae994bc.tar.xz | |
More development...
[originally from svn r220]
Diffstat (limited to 'biblio.c')
| -rw-r--r-- | biblio.c | 104 |
1 files changed, 104 insertions, 0 deletions
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 <assert.h> +#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; + } + } + } +} |