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