1
2 /*
3 * xrefs.c - commands for LaTeX cross references
4 *
5 * Copyright (C) 2001-2002 The Free Software Foundation
6 *
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 * This file is available from http://sourceforge.net/projects/latex2rtf/
22 *
23 * Authors: 2001-2002 Scott Prahl
24 */
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include "main.h"
30 #include "utils.h"
31 #include "convert.h"
32 #include "funct1.h"
33 #include "commands.h"
34 #include "cfg.h"
35 #include "xrefs.h"
36 #include "parser.h"
37 #include "preamble.h"
38 #include "lengths.h"
39 #include "fonts.h"
40 #include "styles.h"
41 #include "definitions.h"
42 #include "equations.h"
43 #include "vertical.h"
44 #include "fields.h"
45 #include "counters.h"
46 #include "auxfile.h"
47 #include "labels.h"
48 #include "acronyms.h"
49 #include "biblio.h"
50
51 char *g_figure_label = NULL;
52 char *g_table_label = NULL;
53 char *g_equation_label = NULL;
54 char *g_section_label = NULL;
55 int g_suppress_name = FALSE;
56 static int g_warned_once = FALSE;
57
58 #define MAX_LABELS 200
59 #define MAX_CITATIONS 1000
60 #define BIB_STYLE_ALPHA 0
61 #define BIB_STYLE_SUPER 1
62 #define BIB_STYLE_NUMBER 2
63 #define MAX_AUTHOR_SIZE 201
64 #define MAX_YEAR_SIZE 51
65
66 char *BIB_DASH_MARKER="%dash%";
67
68 char *g_label_list[MAX_LABELS];
69 int g_label_list_number = -1;
70
71 typedef struct citekey_type {
72 char *key;
73 int number;
74 } citekey_type;
75
76
77 static char *g_all_citations[MAX_CITATIONS];
78 static int g_last_citation = 0;
79 static int g_current_cite_type = 0;
80 static int g_current_cite_seen = 0;
81 static int g_current_cite_paren = 0;
82 static char g_last_author_cited[MAX_AUTHOR_SIZE];
83 static char g_last_year_cited[MAX_YEAR_SIZE];
84 static int g_citation_longnamesfirst = 0;
85 static int g_current_cite_item = 0;
86 static int g_sorted_citations = FALSE;
87 static int g_compressed_citations = FALSE;
88
89 static char *g_bibpunct_open = NULL;
90 static char *g_bibpunct_close = NULL;
91 static char *g_bibpunct_cite_sep = NULL;
92 static char *g_bibpunct_author_date_sep = NULL;
93 static char *g_bibpunct_numbers_sep = NULL;
94 static char *g_bibpunct_postnote_sep = NULL;
95 static char *g_bibstyle_punct[2] = {"[", "]"};
96 static int g_bibpunct_cite_sep_touched = FALSE;
97 static int g_bibpunct_style_paren_touched = FALSE;
98 static int g_bibpunct_style = BIB_STYLE_ALPHA;
99 static int g_in_bibliography = FALSE;
100
InitializeBibliography(void)101 void InitializeBibliography(void)
102 {
103 g_bibpunct_open = strdup("(");
104 g_bibpunct_close = strdup(")");
105 g_bibpunct_cite_sep = strdup(",");
106 g_bibpunct_author_date_sep = strdup(",");
107 g_bibpunct_numbers_sep = strdup(",");
108 g_bibpunct_postnote_sep = strdup(", ");
109 g_bibpunct_cite_sep_touched = FALSE;
110 g_bibpunct_style_paren_touched = FALSE;
111 g_bibpunct_style = BIB_STYLE_ALPHA;
112 }
113
set_longnamesfirst(void)114 void set_longnamesfirst(void)
115 {
116 g_citation_longnamesfirst = TRUE;
117 }
118
set_bibpunct_style_super(void)119 void set_bibpunct_style_super(void)
120 {
121 g_bibpunct_style = BIB_STYLE_SUPER;
122 }
123
set_bibpunct_style_number(void)124 void set_bibpunct_style_number(void)
125 {
126 g_bibpunct_style = BIB_STYLE_NUMBER;
127 }
128
set_bibpunct_style_separator(char * s)129 void set_bibpunct_style_separator(char *s)
130 {
131 g_bibpunct_cite_sep_touched = TRUE;
132 g_bibpunct_cite_sep=strdup(s);
133 }
134
set_bibpunct_style_paren(char * open,char * close)135 void set_bibpunct_style_paren(char *open, char *close)
136 {
137 g_bibpunct_style_paren_touched = TRUE;
138 g_bibpunct_open = strdup(open);
139 g_bibpunct_close = strdup(close);
140 }
141
set_author_date_and_numbers_sep(char * ad,char * n)142 static void set_author_date_and_numbers_sep(char *ad, char *n)
143 {
144 safe_free(g_bibpunct_author_date_sep);
145 g_bibpunct_author_date_sep = strdup(ad);
146
147 safe_free(g_bibpunct_numbers_sep);
148 g_bibpunct_numbers_sep = strdup(n);
149 }
150
set_sorted_citations(void)151 void set_sorted_citations(void)
152 {
153 g_sorted_citations = TRUE;
154 }
155
set_compressed_citations(void)156 void set_compressed_citations(void)
157 {
158 g_compressed_citations = TRUE;
159 }
160
161 /*************************************************************************
162 * return 1 if citation used otherwise return 0 and add citation to list
163 ************************************************************************/
citation_used(char * citation)164 static int citation_used(char *citation)
165 {
166 int i;
167
168 for (i = 0; i < g_last_citation; i++) {
169 if (strcmp(citation, g_all_citations[i]) == 0)
170 return 1;
171 }
172
173 if (g_last_citation > MAX_CITATIONS - 1) {
174 diagnostics(WARNING, "Too many citations ... increase MAX_CITATIONS");
175 } else {
176 g_all_citations[g_last_citation] = strdup(citation);
177 g_last_citation++;
178 }
179
180 return 0;
181 }
182
183 /*************************************************************************
184 purpose: obtains a reference from .aux file
185 code==SCANAUX_NUMBER (0) means \token{reference}{number} -> "number"
186 code==SCANAUX_SECT (1) means \token{reference}{{sect}{line}} -> "sect"
187
188 for 'newlabel' (NEWLABEL_TOKEN) and 'bibcite' (BIBCITE_TOKEN)
189
190 harvardcite is done natively without calling ScanAux
191 ************************************************************************/
192
ScanAux(int token_id,char * reference,int code)193 static char *ScanAux(int token_id, char *reference, int code)
194 {
195 switch (token_id) {
196 case NEWLABEL_TOKEN :
197 switch (code) {
198 case SCANAUX_NUMBER:
199 return getLabelDefinition(reference);
200 case SCANAUX_SECT:
201 return getLabelSection(reference);
202 default:
203 diagnostics(ERROR,"assert failed in ScanAux: unknown code (%d) for token %d",code,token_id);
204 return NULL;
205 }
206 break;
207
208 case BIBCITE_TOKEN:
209 switch (code) {
210 case SCANAUX_NUMBER:
211 return getBiblioRef(reference);
212 case SCANAUX_SECT:
213 return getBiblioFirst(reference);
214 default:
215 diagnostics(ERROR,"assert failed in ScanAux: unknown code (%d) for token %d",code,token_id);
216 return NULL;
217 }
218 break;
219
220 default:
221 diagnostics(ERROR,"assert failed in ScanAux: unknown token_id %d",token_id);
222 }
223 return NULL;
224 }
225 /*************************************************************************
226 purpose: obtains a \bibentry{reference} from the .bbl file
227 this consists of all lines after \bibentry{reference} until two
228 newlines in a row are found.
229 Finally, remove a '.' if at the end
230 ************************************************************************/
ScanBbl(char * reference)231 static char *ScanBbl(char *reference)
232 {
233 char line[512];
234 static FILE *f_bbl = NULL;
235 char *buffer, *target;
236 char *s=NULL;
237 char last_c;
238 int i=1;
239
240 if (g_bbl_file_missing || strlen(reference) == 0) {
241 return NULL;
242 }
243 target = strdup_together3("{", reference,"}");
244 diagnostics(4, "seeking '%s' in .bbl", target);
245
246 if (f_bbl == NULL && (f_bbl = my_fopen(g_bbl_name, "rb")) == NULL) {
247 diagnostics(WARNING, "No .bbl file. Run LaTeX to create one.");
248 g_bbl_file_missing = TRUE;
249 return NULL;
250 }
251 rewind(f_bbl);
252
253 /* scan each line for \bibentry{reference} */
254 while (my_fgets(line, 511, f_bbl)) {
255 s = strstr(line,target);
256 if (s) break;
257 }
258
259 safe_free(target);
260 if (s == NULL) return NULL;
261 buffer = (char *) malloc(4096);
262
263 /* scan bbl file until we encounter \n\n */
264 last_c = '\0';
265 for (i=0; i<4096; i++) {
266 buffer[i] = my_fgetc(f_bbl);
267 if (feof(f_bbl)) break;
268 if (buffer[i] == '\n' && last_c == '\n') break;
269 last_c = buffer[i];
270 }
271
272 /* strip trailing . and any spaces at the end */
273 while (buffer[i] ==' ' || buffer[i] == '\n') i--;
274 if (buffer[i] == '.') i--;
275
276 buffer[i+1] = '\0';
277 s = strdup_nocomments(buffer);
278 safe_free(buffer);
279 return s;
280 }
281
282 /******************************************************************************
283 purpose: creates RTF so that endnotes will be emitted at this point
284 ******************************************************************************/
CmdTheEndNotes(int code)285 void CmdTheEndNotes(int code)
286 {
287 diagnostics(4, "Entering CmdTheEndNotes");
288
289 CmdVspace(VSPACE_BIG_SKIP);
290 startParagraph("bibliography", PARAGRAPH_SECTION_TITLE);
291 fprintRTF("{\\sect ");
292 InsertStyle("section");
293 fprintRTF(" Notes");
294 CmdEndParagraph(0);
295
296 fprintRTF("\\endnhere}");
297 }
298
299 /******************************************************************************
300 purpose: converts footnotes and endnotes from LaTeX to Rtf
301 params : code specifies whether it is a footnote or a thanks-mark
302 ******************************************************************************/
CmdFootNote(int code)303 void CmdFootNote(int code)
304 {
305 char *number, *text;
306 static int thankno = 0; /*WH 2009-11-10: changed from 1 to 0*/
307
308 diagnostics(4, "Entering ConvertFootNote");
309 number = getBracketParam(); /* ignored by automatic footnumber * generation */
310 text = getBraceParam();
311
312 switch (code) {
313 case FOOTNOTE_THANKS:
314 thankno++;
315 fprintRTF("{");
316 InsertStyle("footnote reference");
317 fprintRTF(" %d}\n", thankno);
318 fprintRTF("{\\*\\footnote\\pard ");
319 InsertStyle("footnote text");
320 fprintRTF("{");
321 InsertStyle("footnote reference");
322 fprintRTF("%d} ", thankno);
323 break;
324
325 case FOOTNOTE:
326 fprintRTF("{");
327 InsertStyle("footnote reference");
328 fprintRTF("\\chftn}\n");
329 fprintRTF("{\\*\\footnote\\pard ");
330 InsertStyle("footnote text");
331 fprintRTF("{");
332 InsertStyle("footnote reference");
333 fprintRTF("\\chftn} ");
334 break;
335
336 case FOOTNOTE_TEXT:
337 fprintRTF("{\\*\\footnote\\pard ");
338 InsertStyle("footnote text");
339 break;
340
341 case ENDNOTE:
342 fprintRTF("{");
343 InsertStyle("endnote reference");
344 fprintRTF("\\chftn}\n");
345 fprintRTF("{\\*\\footnote\\ftnalt\\pard ");
346 InsertStyle("endnote text");
347 fprintRTF("{");
348 InsertStyle("endnote reference");
349 fprintRTF("\\chftn} ");
350 break;
351
352 case ENDNOTE_TEXT:
353 fprintRTF("{\\*\\footnote\\ftnalt\\pard ");
354 InsertStyle("endnote text");
355 break;
356
357 }
358
359 ConvertString(text);
360 fprintRTF("}\n");
361 diagnostics(4, "Exiting CmdFootNote");
362 safe_free(text);
363 if (number) safe_free(number);
364 }
365
366 /******************************************************************************
367 purpose: handle the \nocite{tag}
368 ******************************************************************************/
CmdNoCite(int code)369 void CmdNoCite(int code)
370 {
371 safe_free(getBraceParam()); /* just skip the parameter */
372 }
373
374 /******************************************************************************
375 purpose: handle the \bibliographystyle
376 ******************************************************************************/
CmdBibliographyStyle(int code)377 void CmdBibliographyStyle(int code)
378 {
379 char *s = getBraceParam(); /* throw away bib style name */
380
381 diagnostics(4, "CmdBibliographyStyle <%s>", s);
382
383 safe_free(s);
384 }
385
386 /******************************************************************************
387 purpose: handle the \bibstyle
388 ******************************************************************************/
CmdBibStyle(int code)389 void CmdBibStyle(int code)
390 {
391 char *s = getBraceParam(); /* get style name */
392
393 diagnostics(4, "CmdBibStyle <%s>", s);
394
395 /* Derived from `natbib.sty' on 2 Nov. 2010 */
396 if (strcmp(s, "nature") == 0) {
397 g_bibstyle_punct[0] = "" ;
398 g_bibstyle_punct[1] = ".";
399 g_bibpunct_style = BIB_STYLE_SUPER;
400 g_sorted_citations = TRUE;
401 g_compressed_citations = TRUE;
402 set_bibpunct_style_separator(",");
403 set_bibpunct_style_paren("","");
404 set_author_date_and_numbers_sep("", ",");
405 } else if (strcmp(s, "chicago") == 0) {
406 g_bibpunct_style = BIB_STYLE_ALPHA;
407 set_bibpunct_style_separator(";");
408 set_bibpunct_style_paren("(",")");
409 set_author_date_and_numbers_sep(",", ",");
410 } else if (strcmp(s, "named") == 0) {
411 g_bibpunct_style = BIB_STYLE_ALPHA;
412 set_bibpunct_style_separator(";");
413 set_bibpunct_style_paren("[","]");
414 set_bibpunct_style_separator(";");
415 } else if (strcmp(s, "agu") == 0) {
416 g_bibpunct_style = BIB_STYLE_ALPHA;
417 set_bibpunct_style_separator(";");
418 set_bibpunct_style_paren("[","]");
419 set_bibpunct_style_separator(";");
420 set_author_date_and_numbers_sep(",", ",~");
421 } else if (strcmp(s, "egs") == 0) {
422 g_bibpunct_style = BIB_STYLE_ALPHA;
423 set_bibpunct_style_paren("(",")");
424 set_bibpunct_style_separator(";");
425 set_author_date_and_numbers_sep(",", ",");
426 } else if (strcmp(s, "agsm") == 0) {
427 g_bibpunct_style = BIB_STYLE_ALPHA;
428 set_bibpunct_style_paren("(",")");
429 set_bibpunct_style_separator(",");
430 set_author_date_and_numbers_sep("", ",");
431 } else if (strcmp(s, "kluwer") == 0) {
432 g_bibpunct_style = BIB_STYLE_ALPHA;
433 set_bibpunct_style_paren("(",")");
434 set_bibpunct_style_separator(",");
435 set_author_date_and_numbers_sep("", ",");
436 } else if (strcmp(s, "dcu") == 0) {
437 g_bibpunct_style = BIB_STYLE_ALPHA;
438 set_bibpunct_style_paren("(",")");
439 set_bibpunct_style_separator(";");
440 set_author_date_and_numbers_sep(";", ",");
441 } else if (strcmp(s, "aa") == 0) {
442 g_bibpunct_style = BIB_STYLE_ALPHA;
443 set_bibpunct_style_paren("(",")");
444 set_bibpunct_style_separator(";");
445 set_author_date_and_numbers_sep("", ",");
446 } else if (strcmp(s, "pass") == 0) {
447 g_bibpunct_style = BIB_STYLE_ALPHA;
448 set_bibpunct_style_paren("(",")");
449 set_bibpunct_style_separator(";");
450 set_author_date_and_numbers_sep(",", ",");
451 } else if (strcmp(s, "anngeo") == 0) {
452 g_bibpunct_style = BIB_STYLE_ALPHA;
453 set_bibpunct_style_paren("(",")");
454 set_bibpunct_style_separator(";");
455 set_author_date_and_numbers_sep(",", ",");
456 } else if (strcmp(s, "nlinproc") == 0) {
457 g_bibpunct_style = BIB_STYLE_ALPHA;
458 set_bibpunct_style_paren("(",")");
459 set_bibpunct_style_separator(";");
460 set_author_date_and_numbers_sep(",", ",");
461 } else if (strcmp(s, "cospar") == 0) {
462 g_bibstyle_punct[0] = "" ;
463 g_bibstyle_punct[1] = ".";
464 g_bibpunct_style = BIB_STYLE_NUMBER;
465 set_bibpunct_style_paren("/","/");
466 set_bibpunct_style_separator(",");
467 set_author_date_and_numbers_sep("", "");
468 } else if (strcmp(s, "esa") == 0) {
469 g_bibstyle_punct[0] = "" ;
470 g_bibstyle_punct[1] = ".";
471 g_bibpunct_style = BIB_STYLE_NUMBER;
472 set_bibpunct_style_paren("(Ref.~",")");
473 set_bibpunct_style_separator(",");
474 set_author_date_and_numbers_sep("", "");
475 } else if (strcmp(s, "plain") == 0 ||
476 strcmp(s, "alpha") == 0 ||
477 strcmp(s, "abbrv") == 0 ||
478 strcmp(s, "unsrt") == 0) {
479 g_bibpunct_style = BIB_STYLE_NUMBER;
480 set_bibpunct_style_paren("[","]");
481 set_bibpunct_style_separator(",");
482 set_author_date_and_numbers_sep("", ",");
483 } else if (strcmp(s, "plainnat") == 0 ||
484 strcmp(s, "abbrvnat") == 0 ||
485 strcmp(s, "unsrtnat") == 0) {
486 g_bibpunct_style = BIB_STYLE_ALPHA;
487 set_bibpunct_style_paren("[","]");
488 set_bibpunct_style_separator(",");
489 set_author_date_and_numbers_sep(",", ",");
490 } else
491 diagnostics(WARNING, "\\bibstyle{%s} unknown -- ignored.", s);
492
493 safe_free(s);
494 }
495
496 /******************************************************************************
497 purpose: handle the \bibliography
498 ******************************************************************************/
CmdBibliography(int code)499 void CmdBibliography(int code)
500 {
501 int err;
502 char *s;
503
504 s = getBraceParam(); /* throw away bibliography name */
505 safe_free(s);
506
507 err = PushSource(g_bbl_name, NULL);
508 g_in_bibliography = TRUE;
509
510 if (!err) {
511 diagnostics(2, "CmdBibliography ... begin Convert()");
512 Convert();
513 diagnostics(2, "CmdBibliography ... done Convert()");
514 /* PopSource();*/
515 } else
516 diagnostics(WARNING, "Cannot open bibliography file. Create %s using BibTeX", g_bbl_name);
517
518 g_in_bibliography = FALSE;
519 }
520
521 /******************************************************************************
522 purpose: handle the \thebibliography
523 ******************************************************************************/
CmdThebibliography(int code)524 void CmdThebibliography(int code)
525 {
526 int amount = 450;
527 int i;
528
529 if (code & ON) {
530 char *s = getBraceParam(); /* throw away widest_label */
531 diagnostics(4,"\\begin{thebibliography}");
532
533 safe_free(s);
534
535 CmdEndParagraph(0);
536 CmdVspace(VSPACE_MEDIUM_SKIP);
537
538 if (g_document_type == FORMAT_APA) {
539 ConvertString("\\begin{center}{\\bf");
540 } else {
541 startParagraph("bibliography", PARAGRAPH_SECTION_TITLE);
542 fprintRTF("{\\plain\\b\\fs32 ");
543 }
544 i = existsDefinition("refname"); /* see if refname has * been redefined */
545 if (i > -1) {
546 char *str = expandDefinition(i);
547
548 ConvertString(str);
549 safe_free(str);
550 } else {
551 if (g_document_type == FORMAT_ARTICLE || g_document_type == FORMAT_APA)
552 ConvertBabelName("REFNAME");
553 else
554 ConvertBabelName("BIBNAME");
555 }
556
557 if (g_document_type == FORMAT_APA) {
558 ConvertString("}\\end{center}");
559 } else {
560 fprintRTF("}");
561 CmdEndParagraph(0);
562 }
563 CmdVspace(VSPACE_SMALL_SKIP);
564
565 PushEnvironment(BIBLIOGRAPHY_MODE);
566 setLength("parindent", -amount);
567 setLeftMarginIndent(getLeftMarginIndent() + amount);
568 } else {
569 diagnostics(4,"\\end{thebibliography}");
570 CmdEndParagraph(0);
571 CmdVspace(VSPACE_SMALL_SKIP);
572 PopEnvironment();
573 g_processing_list_environment = FALSE;
574 }
575 }
576
577 /******************************************************************************
578 purpose: handle the \bibitem
579 ******************************************************************************/
CmdBibitem(int code)580 void CmdBibitem(int code)
581 {
582 char *label, *key, *signet, *s, *raw, *raw2, c;
583
584 g_processing_list_environment = TRUE;
585 CmdEndParagraph(0);
586 startParagraph("bibitem", PARAGRAPH_FIRST);
587
588 label = getBracketParam();
589
590 raw = getBraceParam();
591 raw2 = strdup_nocomments(raw);
592 key = strdup_noblanks(raw2);
593 safe_free(raw);
594 safe_free(raw2);
595
596 signet = strdup_nobadchars(key);
597
598 s = ScanAux(BIBCITE_TOKEN, key, SCANAUX_NUMBER);
599
600 if (label && !s) { /* happens when file needs to be latex'ed again */
601 if (!g_warned_once){
602 diagnostics(WARNING, "Cannot locate \\bibcite{%s} in .aux file",key);
603 diagnostics(WARNING, "**** The .tex file probably needs to be LaTeXed again ***");
604 g_warned_once = TRUE;
605 }
606 fprintRTF("[");
607 ConvertString(label);
608 fprintRTF("]");
609 } else {
610 diagnostics(4, "CmdBibitem <%s>", s);
611 if (g_document_bibstyle == BIBSTYLE_STANDARD ||
612 (g_document_bibstyle == BIBSTYLE_NATBIB && g_bibpunct_style != BIB_STYLE_ALPHA)) {
613 fprintRTF("%s", g_bibstyle_punct[0]);
614 fprintRTF("{\\v\\*\\bkmkstart BIB_%s}", signet);
615 ConvertString(s);
616 fprintRTF("{\\*\\bkmkend BIB_%s}", signet);
617 fprintRTF("%s", g_bibstyle_punct[1]);
618 fprintRTF("\\tab\n");
619 }
620 /* else emit nothing for APALIKE */
621 }
622
623 if (s)
624 safe_free(s);
625 if (label)
626 safe_free(label);
627 safe_free(signet);
628 safe_free(key);
629
630 c = getNonBlank();
631 ungetTexChar(c);
632 }
633
634 /******************************************************************************
635 purpose: handle the \bibentry
636 ******************************************************************************/
CmdBibEntry(int code)637 void CmdBibEntry(int code)
638 {
639 char *key, *s;
640
641 key = getBraceParam();
642 s = ScanBbl(key);
643 if (s) {
644 ConvertString(s);
645 safe_free(s);
646 }
647 safe_free(key);
648 }
649
CmdNewblock(int code)650 void CmdNewblock(int code)
651 {
652 /*
653 * if openbib chosen then start a paragraph with 1.5em indent
654 * otherwise do nothing
655 */
656 }
657
658 /******************************************************************************
659 purpose: convert \index{classe!article@\textit{article}!section}
660 to {\xe\v "classe:{\i article}:section"}
661 ******************************************************************************/
CmdIndex(int code)662 void CmdIndex(int code)
663 {
664 char *text, *r, *s, *t;
665
666 getNonBlank();
667 text = getDelimitedText('{', '}', TRUE);
668 diagnostics(4, "CmdIndex \\index{%s}", text);
669 fprintRTF("{\\xe{\\v ");
670
671 t = text;
672 while (t) {
673 s = t;
674 t = strchr(s, '!');
675 if (t)
676 *t = '\0';
677 r = strchr(s, '@');
678 if (r)
679 s = r + 1;
680 ConvertString(s);
681 /* while (*s && *s != '@') fprintRTF("%c",*s++); */
682 if (t) {
683 fprintRTF("\\:");
684 t++;
685 }
686 }
687
688 fprintRTF("}}");
689 diagnostics(4, "leaving CmdIndex");
690 safe_free(text);
691 }
692
CmdPrintIndex(int code)693 void CmdPrintIndex(int code)
694 {
695 CmdEndParagraph(0);
696 fprintRTF("\\page ");
697 fprintRTF("{\\field{\\*\\fldinst{INDEX \\\\c 2}}{\\fldrslt{}}}");
698 }
699
ExistsBookmark(char * s)700 static int ExistsBookmark(char *s)
701 {
702 int i;
703
704 if (!s)
705 return FALSE;
706 for (i = 0; i <= g_label_list_number; i++) {
707 if (strcmp(s, g_label_list[i]) == 0)
708 return TRUE;
709 }
710 return FALSE;
711 }
712
RecordBookmark(char * s)713 static void RecordBookmark(char *s)
714 {
715 if (!s)
716 return;
717 if (g_label_list_number >= MAX_LABELS)
718 diagnostics(WARNING, "Too many labels...some cross-references will fail");
719 else {
720 g_label_list_number++;
721 g_label_list[g_label_list_number] = strdup(s);
722 }
723 }
724
InsertBookmark(char * name,char * text)725 void InsertBookmark(char *name, char *text)
726 {
727 char *signet;
728
729 if (!name) {
730 if (getTexMode() == MODE_VERTICAL)
731 changeTexMode(MODE_HORIZONTAL);
732 fprintRTF("%s", text);
733 return;
734 }
735 signet = strdup_nobadchars(name);
736
737 if (ExistsBookmark(signet)) {
738 diagnostics(4, "bookmark %s already exists", signet);
739
740 } else {
741 diagnostics(4, "bookmark %s being inserted around <%s>", signet, text);
742 RecordBookmark(signet);
743 if (fields_use_REF())
744 fprintRTF("{\\*\\bkmkstart BM%s}", signet);
745 fprintRTF("%s", text);
746 if (fields_use_REF())
747 fprintRTF("{\\*\\bkmkend BM%s}", signet);
748 }
749
750 safe_free(signet);
751 }
752
InsertContentMark(char marker,char * s1,char * s2,char * s3)753 void InsertContentMark(char marker, char *s1, char *s2, char *s3)
754 {
755 fprintRTF("{\\field{\\*\\fldinst TC \"");
756 ConvertString(s1);
757 ConvertString(s2);
758 ConvertString(s3);
759 fprintRTF("\" \\\\f %c}{\\fldrslt }}", marker);
760 }
761
762 /******************************************************************************
763 purpose: handles \label \ref \pageref \cite
764 ******************************************************************************/
CmdLabel(int code)765 void CmdLabel(int code)
766 {
767 int brace;
768 char *text, *signet, *s, *t, *p;
769 char *option = NULL;
770 int mode = getTexMode();
771
772 option = getBracketParam();
773 text = getBraceParam();
774 if (strlen(text) == 0) {
775 safe_free(text);
776 return;
777 }
778 switch (code) {
779 case LABEL_LABEL:
780 if (g_processing_figure || g_processing_table)
781 break;
782 if (mode == MODE_DISPLAYMATH) {
783 g_equation_label = strdup_nobadchars(text);
784 diagnostics(4, "equation label is <%s>", text);
785 } else
786 InsertBookmark(text, "");
787 break;
788
789 case LABEL_HYPERREF:
790 case LABEL_REF:
791 case LABEL_EQREF:
792 case LABEL_VREF:
793 signet = strdup_nobadchars(text);
794 s = ScanAux(NEWLABEL_TOKEN, text, SCANAUX_SECT);
795 if (code == LABEL_EQREF)
796 fprintRTF("(");
797
798 if (fields_use_REF()) {
799 fprintRTF("{\\field{\\*\\fldinst{\\lang1024 REF BM%s \\\\* MERGEFORMAT }}", signet);
800 fprintRTF("{\\fldrslt{");
801 }
802
803 if (s)
804 ConvertString(s);
805 else
806 fprintRTF("?");
807
808 if (fields_use_REF())
809 fprintRTF("}}}");
810
811 if (code == LABEL_EQREF)
812 fprintRTF(")");
813
814 if (code == LABEL_VREF) {
815 fprintRTF(" ");
816 if (fields_use_REF()) {
817 fprintRTF("{\\field{\\*\\fldinst{\\lang1024 PAGEREF BM%s \\\\p }}", signet);
818 fprintRTF("{\\fldrslt{");
819 }
820 fprintRTF("%s", signet);
821 if (fields_use_REF())
822 fprintRTF("}}}");
823 }
824
825 safe_free(signet);
826 if (s) safe_free(s);
827
828 break;
829
830 case LABEL_HYPERPAGEREF:
831 case LABEL_PAGEREF:
832 signet = strdup_nobadchars(text);
833 if (fields_use_REF()) {
834 fprintRTF("{\\field{\\*\\fldinst{\\lang1024 PAGEREF BM%s \\\\* MERGEFORMAT }}", signet);
835 fprintRTF("{\\fldrslt{");
836 }
837 fprintRTF("%s", signet);
838 if (fields_use_REF())
839 fprintRTF("}}}");
840 safe_free(signet);
841 break;
842
843 case LABEL_NAMEREF:
844 signet = strdup_nobadchars(text);
845 s = ScanAux(NEWLABEL_TOKEN, text, SCANAUX_NUMBER);
846 if (s) {
847 /* s should look like {2}{1}{Random Stuff\relax }{section.2}{} */
848 t = strchr(s,'{');
849 if (t) t=strchr(t+1,'{');
850 if (t) t=strchr(t+1,'{');
851 if (t) {
852 t++;
853 p=t;
854 brace = 1;
855 /* find end of string ... counting braces */
856 while (p && *p) {
857 if (*p=='{') brace++;
858 if (*p=='}') {
859 brace--;
860 if (brace == 0) break;
861 }
862 p++;
863 }
864 if (p) *p='\0';
865 ConvertString(t);
866 }
867 }
868
869 safe_free(signet);
870 if (s) safe_free(s);
871 break;
872 }
873
874 safe_free(text);
875 if (option)
876 safe_free(option);
877 }
878
879 /*
880 * given s="name1,name2,name3" returns "name2,name3" and makes s="name1" no
881 * memory is allocated, commas are replaced by '\0'
882 */
popCommaName(char * s)883 static char *popCommaName(char *s)
884 {
885 char *t;
886
887 if (s == NULL || *s == '\0')
888 return NULL;
889
890 t = strchr(s, ',');
891 if (!t)
892 return NULL;
893
894 *t = '\0'; /* replace ',' with '\0' */
895 return t + 1; /* next string starts after ',' */
896 }
897
898 /******************************************************************************
899 purpose: return bracketed parameter
900
901 \item<1> ---> "1" \item<> ---> "" \item the ---> NULL
902 ^ ^ ^
903 \item <1> ---> "1" \item <> ---> "" \item the ---> NULL
904 ^ ^ ^
905 ******************************************************************************/
getAngleParam(void)906 static char *getAngleParam(void)
907 {
908 char c, *text;
909
910 c = getNonBlank();
911
912 if (c == '<') {
913 text = getDelimitedText('<', '>', TRUE);
914 diagnostics(5, "getAngleParam [%s]", text);
915
916 } else {
917 ungetTexChar(c);
918 text = NULL;
919 diagnostics(5, "getAngleParam []");
920 }
921
922 return text;
923 }
924
isEmptyName(char * s)925 static int isEmptyName(char *s)
926 {
927 if (s == NULL)
928 return 1;
929 if (s[0] == '\0')
930 return 1;
931 if (s[0] == '{' && s[1] == '}')
932 return 1;
933 return 0;
934 }
935
ConvertNatbib(char * s,int code,char * pre,char * post,int first,int last)936 static void ConvertNatbib(char *s, int code, char *pre, char *post, int first, int last)
937 {
938 char *n, *year, *abbv, *full, *v;
939 int author_repeated, year_repeated;
940
941 PushSource(NULL, s);
942 n = getBraceParam();
943 year = getBraceParam();
944 abbv = getBraceParam();
945 full = getBraceParam();
946 PopSource();
947 diagnostics(4, "natbib pre=[%s] post=<%s> n=<%s> year=<%s> abbv=<%s> full=<%s>", pre, post, n, year, abbv, full);
948 author_repeated = FALSE;
949 year_repeated = FALSE;
950
951 /* for numbers just write and then exit */
952 if (g_bibpunct_style != BIB_STYLE_ALPHA){
953 if (!first) {
954 ConvertString(g_bibpunct_cite_sep);
955 if (g_bibpunct_style == BIB_STYLE_NUMBER)
956 fprintRTF(" ");
957 }
958
959 ConvertString(n);
960 safe_free(n);
961 safe_free(year);
962 safe_free(abbv);
963 safe_free(full);
964 return;
965 }
966
967 switch (code) {
968
969 case CITE_CITE:
970 v = abbv;
971 if (g_citation_longnamesfirst && !isEmptyName(full))
972 v = full;
973
974 if (isEmptyName(v))
975 v = n;
976
977 if (strcmp(v, g_last_author_cited) == 0)
978 author_repeated = TRUE;
979
980 if (strncmp(year, g_last_year_cited, 4) == 0) /* over simplistic test * ... */
981 year_repeated = TRUE;
982
983 if (!first && !author_repeated) {
984 ConvertString(g_bibpunct_cite_sep);
985 fprintRTF(" ");
986 }
987 ConvertString(v);
988 fprintRTF(" ");
989 ConvertString(g_bibpunct_open);
990 ConvertString(year);
991 ConvertString(g_bibpunct_close);
992 break;
993
994 case CITE_T:
995 case CITE_T_STAR:
996 case CITE_T_CAP:
997 v = abbv;
998 if (CITE_T == code && g_citation_longnamesfirst && !g_current_cite_seen)
999 if (!isEmptyName(full))
1000 v = full;
1001 if (CITE_T_STAR == code)
1002 if (!isEmptyName(full))
1003 v = full;
1004
1005 if (strcmp(v, g_last_author_cited) == 0)
1006 author_repeated = TRUE;
1007
1008 if (!first && !author_repeated) {
1009 ConvertString(g_bibpunct_close);
1010 ConvertString(g_bibpunct_cite_sep);
1011 fprintRTF(" ");
1012 }
1013
1014 if (CITE_T_CAP == code) {
1015 v[1]=toupper(v[1]);
1016 }
1017
1018 if (!author_repeated) { /* suppress repeated names */
1019 ConvertString(v);
1020 my_strlcpy(g_last_author_cited, v, MAX_AUTHOR_SIZE);
1021 my_strlcpy(g_last_year_cited, year, MAX_YEAR_SIZE);
1022 if (g_bibpunct_style == BIB_STYLE_ALPHA) {
1023 fprintRTF(" ");
1024 ConvertString(g_bibpunct_open);
1025 if (pre) {
1026 ConvertString(pre);
1027 fprintRTF(" ");
1028 }
1029 ConvertString(year);
1030 }
1031 } else if (g_bibpunct_style == BIB_STYLE_ALPHA) {
1032 if (!year_repeated) {
1033 ConvertString(g_bibpunct_numbers_sep);
1034 fprintRTF(" ");
1035 ConvertString(year);
1036 } else {
1037 char *ss = strdup(year + 4);
1038 ConvertString(g_bibpunct_numbers_sep);
1039 ConvertString(ss);
1040 safe_free(ss);
1041 }
1042 }
1043
1044 if (g_bibpunct_style == BIB_STYLE_ALPHA) {
1045 if (last && post && !isEmptyName(post)) {
1046 ConvertString(g_bibpunct_postnote_sep);
1047 ConvertString(post);
1048 }
1049 if (last)
1050 ConvertString(g_bibpunct_close);
1051 }
1052 break;
1053
1054 case CITE_ALT:
1055 case CITE_ALT_STAR:
1056 case CITE_ALT_CAP:
1057 v = abbv;
1058
1059 if (strcmp(v, g_last_author_cited) == 0)
1060 author_repeated = TRUE;
1061
1062 if (strncmp(year, g_last_year_cited, 4) == 0) /* over simplistic test * ... */
1063 year_repeated = TRUE;
1064
1065 if (!first && !author_repeated) {
1066 ConvertString(g_bibpunct_cite_sep);
1067 fprintRTF(" ");
1068 }
1069
1070 if (CITE_ALT_CAP == code) {
1071 v[1]=toupper(v[1]);
1072 }
1073
1074 if (!author_repeated) { /* suppress repeated names */
1075 ConvertString(v);
1076 my_strlcpy(g_last_author_cited, v, MAX_AUTHOR_SIZE);
1077 my_strlcpy(g_last_year_cited, year, MAX_YEAR_SIZE);
1078 fprintRTF(" ");
1079 if (pre) {
1080 ConvertString(pre);
1081 fprintRTF(" ");
1082 }
1083 ConvertString(year);
1084 } else {
1085 if (!year_repeated) {
1086 ConvertString(g_bibpunct_numbers_sep);
1087 fprintRTF(" ");
1088 ConvertString(year);
1089 } else {
1090 char *ss = strdup(year + 4);
1091 ConvertString(g_bibpunct_numbers_sep);
1092 ConvertString(ss);
1093 safe_free(ss);
1094 }
1095 }
1096 if (last && post && !isEmptyName(post)) {
1097 ConvertString(g_bibpunct_postnote_sep);
1098 ConvertString(post);
1099 }
1100 break;
1101
1102 case CITE_P:
1103 case CITE_P_CAP:
1104 v = abbv;
1105
1106 if (strcmp(v, g_last_author_cited) == 0)
1107 author_repeated = TRUE;
1108
1109 if (strncmp(year, g_last_year_cited, 4) == 0) /* over simplistic test * ... */
1110 year_repeated = TRUE;
1111
1112 if (!first && !author_repeated) {
1113 ConvertString(g_bibpunct_cite_sep);
1114 fprintRTF(" ");
1115 }
1116
1117 if (pre && g_current_cite_item == 1) {
1118 ConvertString(pre);
1119 fprintRTF(" ");
1120 }
1121
1122 if (CITE_P_CAP == code) {
1123 v[1]=toupper(v[1]);
1124 }
1125
1126 if (!author_repeated) { /* suppress repeated names */
1127 ConvertString(v);
1128 my_strlcpy(g_last_author_cited, v, MAX_AUTHOR_SIZE);
1129 my_strlcpy(g_last_year_cited, year, MAX_YEAR_SIZE);
1130 ConvertString(g_bibpunct_author_date_sep);
1131 fprintRTF(" ");
1132 } else {
1133 ConvertString(g_bibpunct_numbers_sep);
1134 fprintRTF(" ");
1135 }
1136
1137 ConvertString(year);
1138
1139 if (last && post && !isEmptyName(post)) {
1140 ConvertString(g_bibpunct_postnote_sep);
1141 ConvertString(post);
1142 }
1143 break;
1144
1145 case CITE_P_STAR:
1146 case CITE_ALP:
1147 case CITE_ALP_STAR:
1148 case CITE_ALP_CAP:
1149 v = abbv;
1150 if (CITE_P == code && g_citation_longnamesfirst && !g_current_cite_seen)
1151 if (!isEmptyName(full))
1152 v = full;
1153 if (CITE_P_STAR == code)
1154 if (!isEmptyName(full))
1155 v = full;
1156
1157 if (strcmp(v, g_last_author_cited) == 0)
1158 author_repeated = TRUE;
1159
1160 if (strncmp(year, g_last_year_cited, 4) == 0) /* over simplistic test * ... */
1161 year_repeated = TRUE;
1162
1163 if (pre && g_current_cite_item == 1) {
1164 ConvertString(pre);
1165 fprintRTF(" ");
1166 }
1167
1168 if (!first && !author_repeated) {
1169 ConvertString(g_bibpunct_cite_sep);
1170 fprintRTF(" ");
1171 }
1172
1173 if (CITE_ALP_CAP == code) {
1174 v[1]=toupper(v[1]);
1175 }
1176
1177 if (!author_repeated) { /* suppress repeated names */
1178 ConvertString(v);
1179 my_strlcpy(g_last_author_cited, v, MAX_AUTHOR_SIZE);
1180 my_strlcpy(g_last_year_cited, year, MAX_YEAR_SIZE);
1181 ConvertString(g_bibpunct_author_date_sep);
1182 fprintRTF(" ");
1183 ConvertString(year);
1184 } else {
1185 if (!year_repeated) {
1186 ConvertString(g_bibpunct_numbers_sep);
1187 fprintRTF(" ");
1188 ConvertString(year);
1189 } else {
1190 char *ss = strdup(year + 4);
1191 ConvertString(g_bibpunct_numbers_sep);
1192 ConvertString(ss);
1193 safe_free(ss);
1194 }
1195 }
1196
1197 if (last && post && !isEmptyName(post)) {
1198 ConvertString(g_bibpunct_postnote_sep);
1199 ConvertString(post);
1200 }
1201 break;
1202
1203 case CITE_AUTHOR:
1204 case CITE_AUTHOR_STAR:
1205 case CITE_AUTHOR_CAP:
1206 v = abbv;
1207 if (!first) {
1208 ConvertString(g_bibpunct_cite_sep);
1209 fprintRTF(" ");
1210 }
1211 if (CITE_AUTHOR == code && g_citation_longnamesfirst && !g_current_cite_seen)
1212 if (!isEmptyName(full))
1213 v = full;
1214
1215 if (CITE_AUTHOR_CAP == code) {
1216 v[1]=toupper(v[1]);
1217 }
1218
1219 if (CITE_AUTHOR_STAR == code)
1220 if (!isEmptyName(full))
1221 v = full;
1222
1223 ConvertString(v);
1224 if (last && post && !isEmptyName(post)) {
1225 ConvertString(g_bibpunct_postnote_sep);
1226 ConvertString(post);
1227 }
1228 break;
1229
1230 case CITE_YEAR:
1231 case CITE_YEAR_P:
1232 if (!first) {
1233 ConvertString(g_bibpunct_cite_sep);
1234 fprintRTF(" ");
1235 }
1236
1237 if (CITE_YEAR != code && pre && g_current_cite_item == 1) {
1238 ConvertString(pre);
1239 fprintRTF(" ");
1240 }
1241 ConvertString(year);
1242
1243 if (last && post && !isEmptyName(post)) {
1244 ConvertString(g_bibpunct_postnote_sep);
1245 ConvertString(post);
1246 }
1247 break;
1248 }
1249 safe_free(n);
1250 safe_free(year);
1251 safe_free(abbv);
1252 safe_free(full);
1253 }
1254
1255 /* convert preparsed harvard cites */
ConvertHarvard(biblioElem * bibElem,int code,char * pre,char * post,int first)1256 static void ConvertHarvard(biblioElem *bibElem, int code, char *pre, char *post, int first)
1257 {
1258 char *year, *abbv, *full;
1259 int author_repeated, year_repeated;
1260
1261 year = strdup(bibElem->biblioYear);
1262 abbv = strdup(bibElem->biblioAbbr);
1263 full = strdup(bibElem->biblioFull);
1264
1265 diagnostics(4, "harvard pre=[%s] post=<%s> full=<%s> abbv=<%s> year=<%s>", pre, post, full, abbv, year);
1266 author_repeated = FALSE;
1267 year_repeated = FALSE;
1268 switch (code) {
1269 case CITE_AFFIXED:
1270 if (first && pre) {
1271 ConvertString(pre);
1272 fprintRTF(" ");
1273 }
1274 ConvertString(full);
1275 fprintRTF(" ");
1276 ConvertString(year);
1277 break;
1278
1279 case CITE_CITE:
1280 ConvertString(full);
1281 fprintRTF(" ");
1282 ConvertString(year);
1283 break;
1284
1285 case CITE_YEAR:
1286 case CITE_YEAR_STAR:
1287 ConvertString(year);
1288 break;
1289
1290 case CITE_NAME:
1291 ConvertString(full);
1292 break;
1293
1294 case CITE_AS_NOUN:
1295 ConvertString(full);
1296 fprintRTF(" (");
1297 ConvertString(year);
1298 fprintRTF(")");
1299 break;
1300
1301 case CITE_POSSESSIVE:
1302 ConvertString(full);
1303 fprintRTF("\\rquote s (");
1304 ConvertString(year);
1305 fprintRTF(")");
1306 break;
1307 }
1308 safe_free(full);
1309 safe_free(year);
1310 safe_free(abbv);
1311 }
1312
CmdNatexlab(int code)1313 void CmdNatexlab(int code)
1314 {
1315 char *s = getBracketParam();
1316 if (!BIB_STYLE_NUMBER)
1317 ConvertString(s);
1318 safe_free(s);
1319 }
1320
1321 /******************************************************************************
1322 Use \bibpunct (in the preamble only) with 6 mandatory arguments:
1323 1. opening bracket for citation
1324 2. closing bracket
1325 3. citation separator (for multiple citations in one \cite)
1326 4. the letter n for numerical styles, s for superscripts
1327 else anything for author-year
1328 5. punctuation between authors and date
1329 6. punctuation between years (or numbers) when common authors missing
1330
1331 One optional argument is the character coming before post-notes. It
1332 appears in square braces before all other arguments. May be left off.
1333 Example (and default)
1334 \bibpunct[, ]{(}{)}{;}{a}{,}{,}
1335 ******************************************************************************/
1336
CmdBibpunct(int code)1337 void CmdBibpunct(int code)
1338 {
1339 char *s = NULL;
1340
1341 s = getBracketParam();
1342 if (s) {
1343 safe_free(g_bibpunct_postnote_sep);
1344 g_bibpunct_postnote_sep = s;
1345 }
1346
1347 safe_free(g_bibpunct_open);
1348 g_bibpunct_open=getBraceParam();
1349
1350 safe_free(g_bibpunct_close);
1351 g_bibpunct_close=getBraceParam();
1352
1353 safe_free(g_bibpunct_cite_sep);
1354 g_bibpunct_cite_sep=getBraceParam();
1355
1356 /* not implemented */
1357 s=getBraceParam();
1358 if (*s == 's')
1359 g_bibpunct_style = BIB_STYLE_SUPER;
1360 if (*s == 'n')
1361 g_bibpunct_style = BIB_STYLE_NUMBER;
1362 if (*s == 'a')
1363 g_bibpunct_style = BIB_STYLE_ALPHA;
1364 safe_free(s);
1365
1366 safe_free(g_bibpunct_author_date_sep);
1367 g_bibpunct_author_date_sep=getBraceParam();
1368
1369 safe_free(g_bibpunct_numbers_sep);
1370 g_bibpunct_numbers_sep=getBraceParam();
1371
1372 g_bibpunct_cite_sep_touched = TRUE;
1373 g_bibpunct_style_paren_touched = TRUE;
1374 }
1375
CmpFunc(const void * _a,const void * _b)1376 static int CmpFunc( const void * _a, const void * _b)
1377 {
1378 citekey_type * aa = (citekey_type *) _a;
1379 citekey_type * bb = (citekey_type *) _b;
1380 int a = (*aa).number;
1381 int b = (*bb).number;
1382
1383 if (a > b) return 1;
1384 if (a == b) return 0;
1385 return -1;
1386 }
1387
reorder_citations(char * keys,int scan_aux_code)1388 static char * reorder_citations(char *keys, int scan_aux_code)
1389 {
1390 char *key, *remaining_keys,*ordered_keys,*a,*b;
1391 int n,i;
1392 int dash;
1393 citekey_type names[100];
1394
1395 diagnostics(4,"original list <%s> scan aux code=%d",keys,scan_aux_code);
1396
1397 /* gather citekeys and numbers into list */
1398 key = keys;
1399 remaining_keys = popCommaName(key);
1400 n=0;
1401 while (key && n < 100) {
1402 char *s = ScanAux(BIBCITE_TOKEN, key, scan_aux_code);
1403 if (s) {
1404 int number;
1405 sscanf(s,"%d",&number);
1406 safe_free(s);
1407 names[n].key = key;
1408 names[n].number = number;
1409 n++;
1410 }
1411 key = remaining_keys;
1412 remaining_keys = popCommaName(key);
1413 }
1414
1415 /* if there is no .aux file or only one key return original list */
1416 if (n<=1) {
1417 ordered_keys = strdup(keys);
1418 return ordered_keys;
1419 }
1420
1421 /* sort list according to the numbers */
1422 qsort(names, n, sizeof(citekey_type), CmpFunc);
1423
1424 /* write the sorted list of keys into a string */
1425 ordered_keys=strdup(names[0].key);
1426 dash = FALSE;
1427
1428 for (i=1; i<n; i++) {
1429 if (g_compressed_citations && dash && i!=n-1 && names[i].number+1==names[i+1].number)
1430 continue; /* skip intermediate numbers */
1431
1432 a = strdup_together(ordered_keys, ",");
1433
1434 if (g_compressed_citations && !dash && i!=n-1 && names[i-1].number+2==names[i+1].number) {
1435 /* insert dash */
1436 dash = TRUE;
1437 b = strdup_together(a, BIB_DASH_MARKER);
1438 } else {
1439 /* normal case */
1440 dash = FALSE;
1441 b = strdup_together(a, names[i].key);
1442 }
1443 safe_free(a);
1444 safe_free(ordered_keys);
1445 ordered_keys=b;
1446 }
1447
1448 diagnostics(4,"compressed list <%s>",ordered_keys);
1449 return ordered_keys;
1450 }
1451
1452 /******************************************************************************
1453 purpose: handles \cite
1454 ******************************************************************************/
CmdCite(int code)1455 void CmdCite(int code)
1456 {
1457 char *text, *str1;
1458 char *keys, *key, *next_keys;
1459 char *option = NULL;
1460 char *pretext = NULL;
1461 int first_key = TRUE;
1462
1463 /* Setup punctuation and read options before citation */
1464 g_current_cite_paren = TRUE;
1465 g_last_author_cited[0] = '\0';
1466 g_last_year_cited[0] = '\0';
1467
1468 if (g_document_bibstyle == BIBSTYLE_STANDARD) {
1469 safe_free(g_bibpunct_open);
1470 safe_free(g_bibpunct_close);
1471 g_bibpunct_open = strdup("[");
1472 g_bibpunct_close = strdup("]");
1473 option = getBracketParam();
1474 }
1475 if (g_document_bibstyle == BIBSTYLE_APALIKE) {
1476 option = getBracketParam();
1477 }
1478 if (g_document_bibstyle == BIBSTYLE_AUTHORDATE) {
1479 option = getBracketParam();
1480 }
1481
1482 if (g_document_bibstyle == BIBSTYLE_APACITE) {
1483 pretext = getAngleParam();
1484 option = getBracketParam();
1485 if (code != CITE_CITE && code != CITE_FULL && code != CITE_SHORT && code != CITE_YEAR)
1486 g_current_cite_paren = FALSE;
1487 g_current_cite_type = code;
1488 }
1489
1490 text = getBraceParam();
1491 str1 = strdup_nocomments(text);
1492 safe_free(text);
1493 text = str1;
1494
1495 if (strlen(text) == 0) {
1496 safe_free(text);
1497 if (pretext)
1498 safe_free(pretext);
1499 if (option)
1500 safe_free(option);
1501 return;
1502 }
1503 /* output text before citation */
1504 if (g_current_cite_paren) {
1505 fprintRTF("\n");
1506 ConvertString(g_bibpunct_open);
1507 }
1508
1509 if (pretext && g_document_bibstyle == BIBSTYLE_APACITE) {
1510 ConvertString(pretext);
1511 fprintRTF(" ");
1512 }
1513
1514 /* clean-up keys and sort if necessary */
1515 keys = strdup_noblanks(text);
1516 safe_free(text);
1517 if (g_sorted_citations){
1518 text = reorder_citations(keys,SCANAUX_NUMBER);
1519 safe_free(keys);
1520 keys = text;
1521 }
1522
1523 /* now start processing keys */
1524 key = keys;
1525 next_keys = popCommaName(key);
1526
1527 g_current_cite_item = 0;
1528 while (key) {
1529 char *s, *t;
1530
1531 g_current_cite_item++;
1532
1533 if (strcmp(key,BIB_DASH_MARKER)==0) {
1534 fprintRTF("-");
1535 first_key = TRUE; /* inhibit comma after dash */
1536 key = next_keys;
1537 next_keys = popCommaName(key); /* key modified to be a * single key */
1538 continue;
1539 }
1540
1541 s = ScanAux(BIBCITE_TOKEN, key, SCANAUX_NUMBER); /* look up bibliographic * reference */
1542
1543 if (g_document_bibstyle == BIBSTYLE_APALIKE) { /* can't use Word refs for APALIKE or APACITE */
1544 t = s ? s : key;
1545 if (!first_key) {
1546 ConvertString(g_bibpunct_cite_sep);
1547 fprintRTF(" ");
1548 }
1549 ConvertString(t);
1550 }
1551 if (g_document_bibstyle == BIBSTYLE_AUTHORDATE) {
1552 if (!first_key) {
1553 ConvertString(g_bibpunct_cite_sep);
1554 fprintRTF(" ");
1555 }
1556 t = s ? s : key;
1557 if (code == CITE_SHORT)
1558 g_suppress_name = TRUE;
1559 ConvertString(t);
1560 if (code == CITE_SHORT)
1561 g_suppress_name = FALSE;
1562 }
1563 if (g_document_bibstyle == BIBSTYLE_APACITE) {
1564 if (!first_key) {
1565 ConvertString(g_bibpunct_cite_sep);
1566 fprintRTF(" ");
1567 }
1568 t = s ? s : key;
1569 g_current_cite_seen = citation_used(key);
1570 ConvertString(t);
1571 }
1572
1573 if (g_document_bibstyle == BIBSTYLE_STANDARD) {
1574 char *signet = strdup_nobadchars(key);
1575
1576 if (!first_key) {
1577 ConvertString(g_bibpunct_cite_sep);
1578 fprintRTF(" ");
1579 }
1580 t = s ? s : signet; /* if .aux is missing or * incomplete use original * citation */
1581 if (fields_use_REF()) {
1582 fprintRTF("{\\field{\\*\\fldinst{\\lang1024 REF BIB_%s \\\\* MERGEFORMAT }}", signet);
1583 fprintRTF("{\\fldrslt{");
1584 }
1585 ConvertString(t);
1586 if (fields_use_REF())
1587 fprintRTF("}}}");
1588 safe_free(signet);
1589 }
1590
1591 first_key = FALSE;
1592 key = next_keys;
1593 next_keys = popCommaName(key); /* key modified to be a * single key */
1594 safe_free(s);
1595 }
1596
1597 /* final text after citation */
1598 if (option) {
1599 ConvertString(g_bibpunct_postnote_sep);
1600 ConvertString(option);
1601 }
1602
1603 if (g_current_cite_paren) {
1604 fprintRTF("\n");
1605 ConvertString(g_bibpunct_close);
1606 }
1607
1608 safe_free(keys);
1609 safe_free(option);
1610 safe_free(pretext);
1611 }
1612
1613 /******************************************************************************
1614 purpose: handles \citations for natbib package
1615 ******************************************************************************/
CmdNatbibCite(int code)1616 void CmdNatbibCite(int code)
1617 {
1618 char *text, *str1;
1619 char *keys, *key, *next_keys;
1620 char *option = NULL;
1621 char *pretext = NULL;
1622 int first_key = TRUE;
1623 int last_key = FALSE;
1624
1625 /* Setup punctuation and read options before citation */
1626 g_current_cite_paren = TRUE;
1627 g_last_author_cited[0] = '\0';
1628 g_last_year_cited[0] = '\0';
1629
1630 if (!g_bibpunct_cite_sep_touched) {
1631 safe_free(g_bibpunct_cite_sep);
1632 g_bibpunct_cite_sep = strdup(";");
1633 }
1634
1635 if (!g_bibpunct_style_paren_touched) {
1636 safe_free(g_bibpunct_cite_sep);
1637 g_bibpunct_cite_sep = strdup(";");
1638 }
1639
1640 pretext = getBracketParam();
1641 option = getBracketParam();
1642 if (!option) {
1643 option = pretext;
1644 pretext = '\0';
1645 }
1646 if (code != CITE_P && code != CITE_P_STAR && code != CITE_YEAR_P)
1647 g_current_cite_paren = FALSE;
1648
1649 if (g_bibpunct_style == BIB_STYLE_SUPER)
1650 g_current_cite_paren = FALSE;
1651
1652 if (g_bibpunct_style == BIB_STYLE_NUMBER)
1653 g_current_cite_paren = TRUE;
1654
1655 text = getBraceParam();
1656 str1 = strdup_nocomments(text);
1657 safe_free(text);
1658 text = str1;
1659
1660 /* no citation, just clean up and exit */
1661 if (strlen(text) == 0) {
1662 safe_free(text);
1663 if (pretext)
1664 safe_free(pretext);
1665 if (option)
1666 safe_free(option);
1667 return;
1668 }
1669
1670 /* superscript style */
1671 if (g_bibpunct_style == BIB_STYLE_SUPER)
1672 fprintRTF("{\\up%d\\fs%d ", script_shift(), script_size());
1673
1674 /* write open parenthesis before citation starts */
1675 if (g_current_cite_paren)
1676 ConvertString(g_bibpunct_open);
1677
1678 /* clean-up keys and sort if necessary */
1679 keys = strdup_noblanks(text);
1680 safe_free(text);
1681 if (g_sorted_citations){
1682 text = reorder_citations(keys,SCANAUX_SECT);
1683 safe_free(keys);
1684 keys = text;
1685 }
1686
1687 /* now process each citation key */
1688 g_current_cite_item = 0;
1689 key = keys;
1690 next_keys = popCommaName(key);
1691 last_key = !next_keys;
1692
1693 while (key) {
1694 char *s;
1695
1696 g_current_cite_item++;
1697
1698 if (strcmp(key,BIB_DASH_MARKER)==0) { /* a citation, not a dash */
1699
1700 fprintRTF("-"); /* just write a dash */
1701 first_key = TRUE; /* no comma after dash */
1702
1703 } else {
1704
1705 /* look up citation and write it to the RTF stream */
1706 s = ScanAux(BIBCITE_TOKEN, key, SCANAUX_NUMBER);
1707
1708 diagnostics(4, "natbib key=[%s] <%s> ", key, s);
1709 if (s) {
1710 g_current_cite_seen = citation_used(key);
1711 ConvertNatbib(s, code, pretext, option, first_key, last_key);
1712 } else {
1713 if (!first_key) {
1714 ConvertString(g_bibpunct_cite_sep);
1715 fprintRTF(" ");
1716 }
1717 ConvertString(key);
1718 }
1719 if (s) safe_free(s);
1720 first_key = FALSE;
1721 }
1722
1723 key = next_keys;
1724 next_keys = popCommaName(key);
1725 last_key = !next_keys;
1726 }
1727
1728 if (g_current_cite_paren)
1729 ConvertString(g_bibpunct_close);
1730
1731 if (g_bibpunct_style == BIB_STYLE_SUPER)
1732 fprintRTF("}");
1733
1734 if (keys)
1735 safe_free(keys);
1736 if (option)
1737 safe_free(option);
1738 if (pretext)
1739 safe_free(pretext);
1740 }
1741
1742 /******************************************************************************
1743 purpose: handles \citations for harvard.sty
1744 ******************************************************************************/
CmdHarvardCite(int code)1745 void CmdHarvardCite(int code)
1746 {
1747 char *text, *s;
1748 char *keys, *key, *next_keys;
1749 char *posttext = NULL;
1750 char *pretext = NULL;
1751 int first_key = TRUE;
1752
1753 /* Setup punctuation and read options before citation */
1754 g_current_cite_paren = TRUE;
1755 g_last_author_cited[0] = '\0';
1756 g_last_year_cited[0] = '\0';
1757 if (code == CITE_AS_NOUN || code == CITE_YEAR_STAR ||
1758 code == CITE_NAME || code == CITE_POSSESSIVE)
1759 g_current_cite_paren = FALSE;
1760
1761 /* read citation entry */
1762 posttext = getBracketParam();
1763 text = getBraceParam();
1764 if (code == CITE_AFFIXED)
1765 pretext = getBraceParam();
1766 s = strdup_nocomments(text);
1767 safe_free(text);
1768 text = s;
1769
1770 if (strlen(text) == 0) {
1771 safe_free(text);
1772 if (pretext) safe_free(pretext);
1773 if (posttext)safe_free(posttext);
1774 return;
1775 }
1776
1777 /* output text before citation */
1778 if (g_current_cite_paren) {
1779 fprintRTF("\n");
1780 ConvertString(g_bibpunct_open);
1781 }
1782
1783 /* clean-up keys and sort if necessary */
1784 keys = strdup_noblanks(text);
1785 safe_free(text);
1786 if (g_sorted_citations){
1787 text = reorder_citations(keys,SCANAUX_NUMBER);
1788 safe_free(keys);
1789 keys = text;
1790 }
1791
1792 /* now start processing keys */
1793 key = keys;
1794 next_keys = popCommaName(key);
1795
1796 g_current_cite_item = 0;
1797 while (key) {
1798 biblioElem *hcite;
1799
1800 g_current_cite_item++;
1801
1802 if (strcmp(key,BIB_DASH_MARKER)==0) {
1803 fprintRTF("-");
1804 first_key = TRUE;
1805 key = next_keys;
1806 next_keys = popCommaName(key);
1807 continue;
1808 }
1809 hcite = getBiblio(key);
1810
1811 if (!first_key) {
1812 ConvertString(g_bibpunct_cite_sep);
1813 fprintRTF(" ");
1814 }
1815
1816 /* make sure the cite was found and that the type is hardvard */
1817 if (NULL != hcite && hcite->biblioType == BIBLIO_HARVARD) {
1818 g_current_cite_seen = citation_used(key);
1819 ConvertHarvard(hcite, code, pretext, NULL, first_key);
1820 } else {
1821 ConvertString(key);
1822 }
1823 first_key = FALSE;
1824 key = next_keys;
1825 next_keys = popCommaName(key);
1826 }
1827
1828 /* final text after citation */
1829 if (posttext) {
1830 fprintRTF("%s", g_bibpunct_postnote_sep);
1831 ConvertString(posttext);
1832 }
1833
1834 if (g_current_cite_paren) {
1835 fprintRTF("\n");
1836 ConvertString(g_bibpunct_close);
1837 }
1838
1839 if (keys)
1840 safe_free(keys);
1841 if (posttext)
1842 safe_free(posttext);
1843 if (pretext)
1844 safe_free(pretext);
1845 }
1846
putHtmlRTF(const char * style)1847 static void putHtmlRTF(const char *style)
1848 {
1849 int n;
1850
1851 if (style) {
1852 /* possible styles are "tt", "rm", "sf", and "same" */
1853 if (strstr(style,"rm"))
1854 CmdFontFamily(F_FAMILY_ROMAN);
1855 else if (strstr(style,"tt"))
1856 CmdFontFamily(F_FAMILY_TYPEWRITER);
1857 else if (strstr(style,"sf"))
1858 CmdFontFamily(F_FAMILY_SANSSERIF);
1859 } else
1860 CmdFontFamily(F_FAMILY_TYPEWRITER);
1861
1862 n = existsDefinition("UrlFont");
1863 if (n != -1) ConvertString("\\UrlFont");
1864
1865 }
1866 /******************************************************************************
1867 purpose: just create a hyperlink using word fields
1868 ******************************************************************************/
InsertRtfHyperlink(const char * text,const char * url,const char * baseurl,const char * style)1869 static void InsertRtfHyperlink(const char *text, const char *url,
1870 const char *baseurl, const char *style)
1871 {
1872
1873 char * fullurl = strdup_together(baseurl,url);
1874 fprintRTF("{");
1875 putHtmlRTF(style);
1876 fprintRTF("\\field{\\*\\fldinst{ HYPERLINK \"");
1877 putRtfStrEscaped(fullurl);
1878 fprintRTF("\" }{{}}}{\\fldrslt{");
1879 ConvertString(text);
1880 fprintRTF("}}}");
1881 safe_free(fullurl);
1882 }
1883
1884 /******************************************************************************
1885 purpose: handles \htmladdnormallink{text}{link}
1886 ******************************************************************************/
CmdHtml(int code)1887 void CmdHtml(int code)
1888 {
1889 static char *baseurl = NULL;
1890 static char *urlstyle = NULL;
1891 char *text=NULL;
1892 char *url=NULL;
1893 char *s = NULL;
1894
1895 switch (code) {
1896 case LABEL_HTMLADDNORMALREF:
1897
1898 text = getBraceParam();
1899 url = getBraceParam();
1900
1901 while ((s = strstr(text, "\\~{}")) != NULL) {
1902 *s = '~';
1903 my_strcpy(s + 1, s + 4);
1904 }
1905 while ((s = strstr(url, "\\~{}")) != NULL) {
1906 *s = '~';
1907 my_strcpy(s + 1, s + 4);
1908 }
1909 InsertRtfHyperlink(text, url, NULL, NULL);
1910 break;
1911
1912
1913 case LABEL_HTMLREF:
1914 text = getBraceParam();
1915 url = getBraceParam();
1916 ConvertString(text);
1917 break;
1918
1919 case LABEL_HYPERREF:
1920 /* \hyperref[label]{text} or \hyperref{url}{category}{name}{text} */
1921 url = getBracketParam();
1922 if (!url) {
1923 char *a, *b, *category, *name;
1924 a = getBraceParam();
1925 category = getBraceParam();
1926 name = getBraceParam();
1927 b = strdup_together3(a,"#",category);
1928 url = strdup_together3(b,".",name);
1929 safe_free(b);
1930 safe_free(name);
1931 safe_free(category);
1932 safe_free(a);
1933 }
1934 text = getBraceParam();
1935 InsertRtfHyperlink(text, url, baseurl, urlstyle);
1936 break;
1937
1938 case LABEL_HREF:
1939 url = getBraceParam();
1940 text = getBraceParam();
1941 InsertRtfHyperlink(text, url, baseurl, urlstyle);
1942 break;
1943
1944 case LABEL_URL_HYPER:
1945 /* cannot use insertHyperlink because url has toxic characters */
1946 url = getBraceRawParam();
1947 text = strdup_together(baseurl,url);
1948 fprintRTF("{");
1949 putHtmlRTF(urlstyle);
1950 fprintRTF("\\field{\\*\\fldinst{ HYPERLINK \"");
1951 putRtfStrEscaped(text);
1952 fprintRTF("\" }{{}}}{\\fldrslt{");
1953 putRtfStrEscaped(text);
1954 fprintRTF("}}}");
1955 break;
1956
1957 case LABEL_URL:
1958 case LABEL_NO_LINK_URL:
1959 url = getBraceRawParam();
1960 text = strdup_together(baseurl,url);
1961 fprintRTF("{");
1962 putHtmlRTF(urlstyle);
1963 putRtfStrEscaped(text);
1964 fprintRTF("}");
1965 break;
1966
1967 case LABEL_BASE_URL:
1968 if (baseurl) safe_free(baseurl);
1969 baseurl = getBraceRawParam();
1970 break;
1971
1972 case LABEL_URLSTYLE:
1973 if (urlstyle) safe_free(urlstyle);
1974 urlstyle = getBraceParam();
1975 break;
1976 }
1977
1978 if (text) safe_free(text);
1979 if (url) safe_free(url);
1980 }
1981
CmdBCAY(int code)1982 void CmdBCAY(int code)
1983 {
1984 char *s=NULL, *t, *v, *year;
1985
1986 s = getBraceParam();
1987
1988 diagnostics(4, "Entering CmdBCAY", s);
1989
1990 t = getBraceParam();
1991 year = getBraceParam();
1992 v = g_current_cite_seen ? t : s;
1993
1994 diagnostics(4, "s = <%s>", s);
1995 diagnostics(4, "t = <%s>", t);
1996 diagnostics(4, "year = <%s>", year);
1997 diagnostics(4, "type = %d, seen = %d, item= %d", g_current_cite_type, g_current_cite_seen, g_current_cite_item);
1998
1999 switch (g_current_cite_type) {
2000
2001 case CITE_CITE:
2002 case CITE_CITE_NP:
2003 case CITE_CITE_A:
2004 if (strcmp(v, g_last_author_cited) != 0) { /* suppress repeated names */
2005 ConvertString(v);
2006 my_strlcpy(g_last_author_cited, v, MAX_AUTHOR_SIZE);
2007 my_strlcpy(g_last_year_cited, year, MAX_YEAR_SIZE);
2008
2009 if (g_current_cite_type == CITE_CITE_A)
2010 fprintRTF(" (");
2011 else
2012 fprintRTF(", ");
2013 }
2014 ConvertString(year);
2015 if (g_current_cite_type == CITE_CITE_A)
2016 fprintRTF(")");
2017 break;
2018
2019 case CITE_CITE_AUTHOR:
2020 ConvertString(v);
2021 break;
2022
2023 case CITE_FULL:
2024 case CITE_FULL_NP:
2025 case CITE_FULL_A:
2026 ConvertString(s);
2027 if (g_current_cite_type == CITE_FULL_A)
2028 fprintRTF(" (");
2029 else
2030 fprintRTF(", ");
2031
2032 ConvertString(year);
2033 if (g_current_cite_type == CITE_FULL_A)
2034 fprintRTF(")");
2035 break;
2036
2037 case CITE_FULL_AUTHOR:
2038 ConvertString(s);
2039 break;
2040
2041 case CITE_SHORT:
2042 case CITE_SHORT_NP:
2043 case CITE_SHORT_A:
2044 case CITE_SHORT_AUTHOR:
2045 ConvertString(t);
2046 if (g_current_cite_type == CITE_SHORT_A)
2047 fprintRTF(" (");
2048 else
2049 fprintRTF(", ");
2050
2051 ConvertString(year);
2052 if (g_current_cite_type == CITE_SHORT_A)
2053 fprintRTF(")");
2054 break;
2055
2056 case CITE_YEAR:
2057 case CITE_YEAR_NP:
2058 ConvertString(year);
2059 break;
2060
2061 }
2062 safe_free(s);
2063 safe_free(t);
2064 safe_free(year);
2065 }
2066
ConvertBraceParam(char * pre,char * post)2067 static void ConvertBraceParam(char *pre, char *post)
2068 {
2069 char *s=NULL;
2070 char *t=NULL;
2071 s = getBraceParam();
2072 if (strlen(s)>0) {
2073 t = strdup_together3(pre,s,post);
2074 ConvertString(t);
2075 safe_free(t);
2076 }
2077 safe_free(s);
2078 }
2079
DiscardBraceParam(void)2080 static void DiscardBraceParam(void)
2081 {
2082 char *s;
2083 s = getBraceParam();
2084 if (s) safe_free(s);
2085 }
2086
2087 /******************************************************************************
2088 purpose: handles apacite stuff
2089 ******************************************************************************/
CmdApaCite(int code)2090 void CmdApaCite(int code)
2091 {
2092 int n;
2093 char *s;
2094 char * month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
2095 switch (code) {
2096 case 0:
2097 fprintRTF(" (");
2098 break; /* BBOP */
2099 case 1:
2100 fprintRTF("&");
2101 break; /* BBAA */
2102 case 2:
2103 fprintRTF("and");
2104 break; /* BBAB */
2105 case 3:
2106 fprintRTF(", ");
2107 break; /* BBAY */
2108 case 4:
2109 fprintRTF("; ");
2110 break; /* BBC */
2111 case 5:
2112 fprintRTF(", ");
2113 break; /* BBN */
2114 case 6:
2115 fprintRTF(")");
2116 break; /* BBCP */
2117 case 7:
2118 fprintRTF("");
2119 break; /* BBOQ */
2120 case 8:
2121 fprintRTF("");
2122 break; /* BBCQ */
2123 case 9:
2124 fprintRTF(",");
2125 break; /* BCBT */
2126 case 10:
2127 fprintRTF(",");
2128 break; /* BCBL */
2129 case 11:
2130 s = getBraceParam();
2131 fprintRTF("et al.");
2132 safe_free(s);
2133 break; /* BOthers */
2134 case 12:
2135 fprintRTF("in press");
2136 break; /* BIP */
2137 case 13:
2138 fprintRTF("and");
2139 break; /* BAnd */
2140 case 14:
2141 fprintRTF("Ed.");
2142 break; /* BED */
2143 case 15:
2144 fprintRTF("Eds.");
2145 break; /* BEDS */
2146 case 16:
2147 fprintRTF("Trans.");
2148 break; /* BTRANS */
2149 case 17:
2150 fprintRTF("Trans.");
2151 break; /* BTRANSS */
2152 case 18:
2153 fprintRTF("Chair");
2154 break; /* BCHAIR */
2155 case 19:
2156 fprintRTF("Chairs");
2157 break; /* BCHAIRS */
2158 case 20:
2159 fprintRTF("Vol.");
2160 break; /* BVOL */
2161 case 21:
2162 fprintRTF("Vols.");
2163 break; /* BVOLS */
2164 case 22:
2165 fprintRTF("No.");
2166 break; /* BNUM */
2167 case 23:
2168 fprintRTF("Nos.");
2169 break; /* BNUMS */
2170 case 24:
2171 fprintRTF("ed.");
2172 break; /* BEd */
2173 case 25:
2174 fprintRTF("p.");
2175 break; /* BPG */
2176 case 26:
2177 fprintRTF("pp.");
2178 break; /* BPGS */
2179 case 27:
2180 fprintRTF("Tech. Rep.");
2181 break; /* BTR */
2182 case 28:
2183 fprintRTF("Doctoral dissertation");
2184 break; /* BPhD */
2185 case 29:
2186 fprintRTF("Unpublished doctoral dissertation");
2187 break; /* BUPhD */
2188 case 30:
2189 fprintRTF("Master's thesis");
2190 break; /* BMTh */
2191 case 31:
2192 fprintRTF("Unpublished master's thesis");
2193 break; /* BUMTh */
2194 case 32:
2195 fprintRTF("Original work published ");
2196 break; /* BOWP */
2197 case 33:
2198 fprintRTF("Reprinted from ");
2199 break; /* BREPR */
2200 case 34:
2201 s = getBraceParam(); /* BCnt {1} */
2202 if (sscanf(s, "%d", &n) == 1)
2203 fprintRTF("%c", (char) 'a' + n - 1);
2204 safe_free(s);
2205 break;
2206 case 35:
2207 if (g_current_cite_paren || g_in_bibliography)
2208 fprintRTF("&");
2209 else
2210 fprintRTF("and"); /* BBA */
2211 break;
2212 case 36:
2213 DiscardBraceParam(); /* \AX{entry} */
2214 diagnostics(4, "Ignoring \\AX{blah blah}");
2215 break;
2216 case 37:
2217 fprintRTF(". ");
2218 break; /* BPBI */
2219 case 38:
2220 fprintRTF("In");
2221 break; /* BIn */
2222
2223 case CITE_APA_CITE_METASTAR:
2224 ConvertString("$\\star");
2225 break;
2226
2227 case CITE_APA_CITE_YEAR:
2228 ConvertBraceParam("",""); /* \APACyear{1991} */
2229 break;
2230
2231 case CITE_APA_CITE_A_TITLE:
2232 ConvertBraceParam("``","''");
2233 break;
2234
2235 case CITE_APA_CITE_B_TITLE:
2236 ConvertBraceParam("\\textit{","}"); /* \APACcitebtitle{title} */
2237 break;
2238
2239 case CITE_APA_CITE_INSERT:
2240 DiscardBraceParam(); /* discard \APACinsertmetastar{art 1} ?? */
2241 break;
2242
2243 case CITE_APA_YMD:
2244 fprintRTF("(");
2245 ConvertBraceParam("",""); /* \APACrefYearMonthDay{1991}{month}{day} */
2246 ConvertBraceParam(", ",""); /* month */
2247 ConvertBraceParam(" ",""); /* day */
2248 fprintRTF(")");
2249 break;
2250
2251 case CITE_APA_REF_A_TITLE:
2252 DiscardBraceParam(); /* ignore first entry?? */
2253 ConvertBraceParam("",""); /* \APACrefatitle{title}{title} */
2254 break;
2255
2256 case CITE_APA_REF_B_TITLE:
2257 DiscardBraceParam(); /* ignore first entry?? */
2258 ConvertBraceParam("\\textit{","}"); /* \APACrefbtitle{title}{title} */
2259 break;
2260
2261 case CITE_APA_JVNP:
2262 ConvertBraceParam("\\textit{","}"); /* \APACjournalVolNumPages{Journal of nothingness}{2}{}{1-2} */
2263 ConvertBraceParam(", \\textit{","}"); /* volume */
2264 ConvertBraceParam("(",")"); /* number (10) */
2265 ConvertBraceParam(", ",""); /* pages */
2266 break;
2267
2268 case CITE_APA_REF_YEAR:
2269 ConvertBraceParam("(",")"); /* \APACrefYear{1991} */
2270 break;
2271
2272 case CITE_APA_ADD_PUB:
2273 ConvertBraceParam("",": "); /* \APACaddressPublisher{Somewhere}{PublishCo} */
2274 ConvertBraceParam("","");
2275 break;
2276
2277 case CITE_PRINT_BACK_REFS: /* ignore \PrintBackRefs{\CurrentBib} */
2278 DiscardBraceParam();
2279 break;
2280
2281 case CITE_PRINT_ORDINAL:
2282 case CITE_PRINT_CARDINAL:
2283 ConvertBraceParam("","");
2284 break;
2285
2286 case CITE_APA_ADD_PUB_EQ_AUTHOR:
2287 /* \APACaddressPublisherEqAuth{Washington, DC}{{American Psychiatric Association}} */
2288 ConvertBraceParam("",": Author");
2289 DiscardBraceParam();
2290 break;
2291
2292 case CITE_APA_REF_A_E_TITLE: /* english translation of article */
2293 DiscardBraceParam();
2294 ConvertBraceParam("[","]");
2295 break;
2296
2297 case CITE_APA_REF_B_E_TITLE: /* english translation of book */
2298 DiscardBraceParam();
2299 ConvertBraceParam("[","]");
2300 break;
2301
2302 case CITE_APA_MONTH:
2303 s = getBraceParam();
2304 if (s && *s) {
2305 sscanf(s, "%d", &n);
2306 ConvertString(month[n-1]);
2307 safe_free(s);
2308 }
2309 break;
2310
2311 case CITE_APA_B_VOL_ED_TR: /* \APACbVolEdTR{}{tech report}*/
2312 DiscardBraceParam();
2313 ConvertBraceParam("(",")");
2314 break;
2315
2316 case CITE_APA_B_VOL_ED_TR_PGS: /* \APACbVolEdTRpgs{}{tech report}{}*/
2317 fprintRTF("(");
2318 DiscardBraceParam();
2319 ConvertBraceParam("",""); /* \APACbVolEdTRpgs{}{tech report}{}*/
2320 ConvertBraceParam(", ",""); /* more info */
2321 fprintRTF(")");
2322 break;
2323
2324 case CITE_APA_ADD_INST: /* APACaddressInstitution{add}{inst} */
2325 ConvertBraceParam("","");
2326 ConvertBraceParam(": ",""); /* more info */
2327 break;
2328
2329 case CITE_APA_HOW:
2330 ConvertBraceParam("","");
2331 break;
2332
2333 case CITE_APA_ORIG_YEAR_NOTE:
2334 ConvertBraceParam("(Original work published ",")");
2335 DiscardBraceParam();
2336 break;
2337
2338 case CITE_APA_ORIG_JOUR:
2339 s = getBraceParam(); /* year */
2340 ConvertBraceParam("(Reprinted from \\textit{","}"); /* article */
2341 if (s && *s) {
2342 fprintRTF(", ");
2343 ConvertString(s);
2344 safe_free(s);
2345 }
2346
2347 ConvertBraceParam(", \\textit{","}"); /* volume */
2348 ConvertBraceParam("(",")"); /* number (10) */
2349 ConvertBraceParam(", ",""); /* pages */
2350 fprintRTF(")");
2351 break;
2352
2353 case CITE_APA_REF_NOTE:
2354 ConvertBraceParam("(",")");
2355 break;
2356
2357 case CITE_APA_UNSKIP: /*do nothing! */
2358 break;
2359
2360 default:;
2361 }
2362 }
2363
2364 /******************************************************************************
2365 purpose: handles \citename from authordate bib style
2366 ******************************************************************************/
CmdCiteName(int code)2367 void CmdCiteName(int code)
2368 {
2369 char *s=NULL;
2370
2371 s = getBraceParam();
2372
2373 diagnostics(4, "Entering CmdCitename [%s]", (s) ? s : "");
2374
2375 if (!g_suppress_name)
2376 ConvertString(s);
2377
2378 safe_free(s);
2379
2380 }
2381
2382 /******************************************************************************
2383 purpose: handles \numberline{3.2.1}
2384 ******************************************************************************/
CmdNumberLine(int code)2385 void CmdNumberLine(int code)
2386 {
2387 char *number;
2388
2389 number = getBraceParam();
2390 diagnostics(4, "Entering CmdNumberLine [%s]", number);
2391 ConvertString(number);
2392 fprintRTF("\\tab\n");
2393 safe_free(number);
2394 }
2395
2396 /******************************************************************************
2397 purpose: handles
2398 \harvarditem[optional]{a}{b}{c}
2399 \harvardyearleft
2400 \harvardyearright
2401 \harvardand
2402 ******************************************************************************/
CmdHarvard(int code)2403 void CmdHarvard(int code)
2404 {
2405 switch (code) {
2406 case CITE_HARVARD_ITEM:
2407 ignoreBracketParam();
2408 ignoreBraceParam();
2409 ignoreBraceParam();
2410 ignoreBraceParam();
2411 break;
2412
2413 case CITE_HARVARD_YEAR_LEFT:
2414 fprintRTF("(");
2415 break;
2416
2417 case CITE_HARVARD_YEAR_RIGHT:
2418 fprintRTF(")");
2419 break;
2420
2421 case CITE_HARVARD_AND:
2422 fprintRTF("&");
2423 default:
2424 break;
2425 }
2426 }
2427
2428 /******************************************************************************
2429 purpose: handles \citename from authordate bib style
2430 ******************************************************************************/
CmdContentsLine(int code)2431 void CmdContentsLine(int code)
2432 {
2433 char *type, *text, *num, *contents_type;
2434
2435 type = getBraceParam();
2436 text = getBraceParam();
2437 num = getBraceParam();
2438
2439 diagnostics(4, "Entering CmdContentsLine %s [%s]", type, text);
2440
2441 startParagraph("contents", PARAGRAPH_SECTION_TITLE);
2442 fprintRTF("{");
2443 contents_type = strdup_together("contents_", type);
2444 InsertStyle(contents_type);
2445 fprintRTF(" ");
2446 ConvertString(text);
2447 CmdEndParagraph(0);
2448 fprintRTF("}");
2449
2450 safe_free(type);
2451 safe_free(text);
2452 safe_free(num);
2453 safe_free(contents_type);
2454 }
2455
2456 /******************************************************************************
2457 purpose: handles \listoffigures \listoftables
2458 ******************************************************************************/
CmdListOf(int code)2459 void CmdListOf(int code)
2460 {
2461 char c = ' ';
2462
2463 diagnostics(4, "Entering CmdListOf");
2464
2465 startParagraph("contents", PARAGRAPH_SECTION_TITLE);
2466 fprintRTF(" ");
2467
2468 switch (code) {
2469
2470 case LIST_OF_FIGURES:
2471 ConvertBabelName("LISTFIGURENAME");
2472 c = 'f';
2473 break;
2474
2475 case LIST_OF_TABLES:
2476 ConvertBabelName("LISTTABLENAME");
2477 c = 't';
2478 break;
2479
2480 case TABLE_OF_CONTENTS:
2481 ConvertBabelName("CONTENTSNAME");
2482 c = 'c';
2483 break;
2484 }
2485
2486 CmdEndParagraph(0);
2487
2488 startParagraph("Normal", PARAGRAPH_GENERIC);
2489 CmdVspace(VSPACE_SMALL_SKIP);
2490 g_tableofcontents = TRUE;
2491 fprintRTF("{\\field{\\*\\fldinst TOC \\\\f %c }{\\fldrslt }}\n",c);
2492 CmdNewPage(NewPage);
2493 CmdEndParagraph(0);
2494 }
2495