1 /*********************************************************************/
2 /* bibView: Administration of BibTeX-Databases */
3 /* (Verwaltung von BibTeX-Literaturdatenbanken) */
4 /* */
5 /* Module: ctl_prt.c */
6 /* */
7 /* Print Control */
8 /* - Print BibTeX File */
9 /* - Print list */
10 /* */
11 /* Author: Holger Martin, martinh@informatik.tu-muenchen.de */
12 /* Peter M. Urban, urban@informatik.tu-muenchen.de */
13 /* */
14 /* History: */
15 /* 18.02.92 HM created */
16 /* 05.26.92 Version 1.0 released */
17 /* */
18 /* Copyright 1992 TU MUENCHEN */
19 /* See ./Copyright for complete rights and liability information. */
20 /* */
21 /*********************************************************************/
22
23 #include <stdio.h>
24 #include <X11/Intrinsic.h>
25 #include <X11/StringDefs.h>
26 #include <X11/Shell.h>
27 #include <X11/Xaw/Cardinals.h>
28 #include <X11/Xaw/Command.h>
29 #include <X11/Xaw/Dialog.h>
30 #include <X11/Xaw/Box.h>
31 #include "FileNom.h"
32 #include "bibview.h"
33
34
35 /* macros and definitions */
36 /* ---------------------- */
37 #define MAXTEX 20000
38
39 #define BIB 0
40 #define LIST 1
41
42 /* imported global variables */
43 /* ------------------------- */
44 extern XtAppContext app_context;
45 extern Widget topLevel, mainMenu, desktop;
46 extern Pixmap questPixmap;
47 extern char *latexHeader, *latexFooter;
48 extern int max_linelen, max_fields;
49
50 /* exported global variables */
51 /* ------------------------- */
52
53 char *style_file;
54
55
56 /* local function prototypes */
57 /* ------------------------- */
58 static void getFilename (BibPtr bp, int type);
59 static void cancelGetFname (Widget w, XtPointer clientData, XtPointer callData);
60 static void getFnameListOk (Widget w, XtPointer clientData, XtPointer callData);
61 static void getFnameBibOk (Widget w, XtPointer clientData, XtPointer callData);
62
63 static void getListFilename (BibPtr bp);
64 static void cancelListGetFname (Widget w, XtPointer clientData, XtPointer callData);
65 static void getListFnameOk (Widget w, XtPointer clientData, XtPointer callData);
66
67
68 static Errcode printBegDoc (FILE *fp, String fname);
69 static Errcode printEndDoc (FILE *fp);
70 static Errcode printList (FILE *fp, BibPtr bp, int type);
71 static Errcode printBibList (FILE *fp, BibPtr bp, int type);
72 static Errcode printCard (FILE *fp, CardDataPtr cd);
73 static void WriteLineToArray(char *inh);
74
75
76 /* local global variables */
77 /* ---------------------- */
78 static char texline[MAXTEX];
79
80
81 /*********************************************************************/
82 /* cprPrintBibCmd: */
83 /* Callback function for command print in main menu */
84 /*********************************************************************/
85 void
cprPrintBibCmd(Widget widget,XtPointer clientData,XtPointer callData)86 cprPrintBibCmd (Widget widget, XtPointer clientData, XtPointer callData)
87 {
88 Errcode status;
89
90 if ((status = guwSelectBib("printHead", cprPrintBib)) != OK)
91 guwWarning(status);
92 }
93
94
95 /*********************************************************************/
96 /* cprPrintCmd: */
97 /* Callback function for command print in main menu */
98 /*********************************************************************/
99 void
cprPrintCmd(Widget widget,XtPointer clientData,XtPointer callData)100 cprPrintCmd (Widget widget, XtPointer clientData, XtPointer callData)
101 {
102 BibPtr bp = (BibPtr)clientData;
103 Errcode status;
104
105 if ((status = cprPrintBib(bp)) != OK)
106 guwError(status);
107 }
108
109
110 /*********************************************************************/
111 /* cprPrintBib: */
112 /* Callback function for command print in main menu */
113 /*********************************************************************/
114 Errcode
cprPrintBib(BibPtr bp)115 cprPrintBib (BibPtr bp)
116 {
117 getFilename(bp, BIB);
118 return(OK);
119 }
120
121
122 /*********************************************************************/
123 /* cprPrintListCmd: */
124 /* Callback function for command print in list window */
125 /*********************************************************************/
126 void
cprPrintListCmd(Widget widget,XtPointer clientData,XtPointer callData)127 cprPrintListCmd(Widget widget, XtPointer clientData, XtPointer callData)
128 {
129 BibPtr bp = (BibPtr) clientData;
130
131 getFilename(bp, LIST);
132 }
133
134
135 /*********************************************************************/
136 /* cprPrintList: */
137 /* Print a list of cards to file in LaTeX format */
138 /*********************************************************************/
139 Errcode
cprPrintList(BibPtr bp,String fname,int type)140 cprPrintList (BibPtr bp, String fname, int type)
141 {
142 FILE *fp;
143 Errcode status;
144
145 /* make .bak file of original */
146 if (fname == NULL)
147 return(ERR_NO_OPEN_FILE);
148 if (cotBackupBeforeSave())
149 glbMakeBackup(fname);
150
151 if ((fp = fopen(fname, "w")) == NULL)
152 return(ERR_NO_OPEN_FILE);
153 if (latexHeader != NULL) {
154 fprintf(fp,"%s\n", latexHeader);
155 }
156 else {
157 if ((status = printBegDoc(fp, bp->filename)) != OK) {
158 fclose(fp);
159 return(status);
160 }
161 }
162
163 if (cotPrintAsBib()){
164 if ((status = printBibList(fp, bp, type)) != OK) {
165 fclose(fp);
166 return(status);
167 }
168 }
169 else
170 if ((status = printList(fp, bp, type)) != OK) {
171 fclose(fp);
172 return(status);
173 }
174
175 if (latexFooter != NULL) {
176 fprintf(fp,"%s\n", latexFooter);
177 }
178 else {
179 if ((status = printEndDoc(fp)) != OK) {
180 fclose(fp);
181 return(status);
182 }
183 }
184
185 fclose(fp);
186 return(OK);
187 }
188
189
190 /*********************************************************************/
191 /* cprSaveListCmd: */
192 /* Callback function for command save in list window */
193 /*********************************************************************/
194 void
cprSaveListCmd(Widget widget,XtPointer clientData,XtPointer callData)195 cprSaveListCmd(Widget widget, XtPointer clientData, XtPointer callData)
196 {
197 BibPtr bp = (BibPtr)clientData;
198
199 getListFilename(bp);
200 }
201
202 /*********************************************************************/
203 /* LOCAL FUNCTIONS */
204 /*********************************************************************/
205
206 /*********************************************************************/
207 /* getFilename: */
208 /* Opens dialogbox for user to enter name of file */
209 /*********************************************************************/
210 static void
getFilename(BibPtr bp,int type)211 getFilename (BibPtr bp, int type)
212 {
213 static Widget fsbShell, fsbBox, fsbDialog;
214 Position dx, dy, x, y;
215
216 XtVaGetValues(desktop,
217 XtNx, &dx,
218 XtNy, &dy, NULL);
219 XtTranslateCoords(desktop,
220 (Position)dx + SUBWIN_MARGIN,
221 (Position)dy + SUBWIN_MARGIN,
222 &x, &y);
223
224 fsbShell = XtVaCreatePopupShell("fileSelectBoxShell",
225 topLevelShellWidgetClass, desktop,
226 XtNx, x, XtNy, y, NULL);
227 fsbBox = XtVaCreateManagedWidget("fileSelectBox",
228 boxWidgetClass, fsbShell, NULL);
229 XtVaCreateManagedWidget("filePrintHead",
230 labelWidgetClass, fsbBox,
231 XtNborderWidth, 0, NULL);
232 fsbDialog = XtVaCreateManagedWidget("fileSelectBox",
233 fileNominatorWidgetClass, fsbBox,
234 XtNborderWidth, 0, NULL);
235
236 XtAddCallback(fsbDialog, XtNcancelCallback, cancelGetFname, fsbShell);
237 if (type == LIST)
238 XtAddCallback(fsbDialog, XtNselectCallback, getFnameListOk, bp);
239 else
240 XtAddCallback(fsbDialog, XtNselectCallback, getFnameBibOk, bp);
241
242 XtSetSensitive(mainMenu, FALSE);
243 gubSetSensitive(NULL, FALSE);
244 XtPopup(fsbShell, XtGrabNonexclusive);
245 }
246
247
248 /*********************************************************************/
249 /* getListFilename: */
250 /* Opens dialogbox for user to enter name of file */
251 /*********************************************************************/
252 static void
getListFilename(BibPtr bp)253 getListFilename (BibPtr bp)
254 {
255 static Widget fsbShell, fsbBox, fsbDialog;
256 Position dx, dy, x, y;
257
258 XtVaGetValues(desktop,
259 XtNx, &dx,
260 XtNy, &dy, NULL);
261 XtTranslateCoords(desktop,
262 (Position)dx + SUBWIN_MARGIN,
263 (Position)dy + SUBWIN_MARGIN,
264 &x, &y);
265
266 fsbShell = XtVaCreatePopupShell("fileSelectBoxShell",
267 topLevelShellWidgetClass, desktop,
268 XtNx, x, XtNy, y, NULL);
269 fsbBox = XtVaCreateManagedWidget("fileSelectBox",
270 boxWidgetClass, fsbShell, NULL);
271 XtVaCreateManagedWidget("fileListSaveHead",
272 labelWidgetClass, fsbBox,
273 XtNborderWidth, 0, NULL);
274 fsbDialog = XtVaCreateManagedWidget("fileSelectBox",
275 fileNominatorWidgetClass, fsbBox,
276 XtNborderWidth, 0, NULL);
277
278
279 XtAddCallback(fsbDialog, XtNcancelCallback, cancelListGetFname, fsbShell);
280 XtAddCallback(fsbDialog, XtNselectCallback, getListFnameOk, (XtPointer)bp);
281
282 XtSetSensitive(mainMenu, FALSE);
283 gubSetSensitive(NULL, FALSE);
284 XtPopup(fsbShell, XtGrabNonexclusive);
285 }
286
287
288 /*********************************************************************/
289 /* cancelGetFname: */
290 /* Callback function for CANCEL button in filename box */
291 /*********************************************************************/
292 static void
cancelGetFname(Widget w,XtPointer clientData,XtPointer callData)293 cancelGetFname (Widget w, XtPointer clientData, XtPointer callData)
294 {
295 Widget shell = (Widget)clientData;
296
297 XtSetSensitive(mainMenu, TRUE);
298 gubSetSensitive(NULL, TRUE);
299 XtPopdown(shell);
300 }
301
302
303 /*********************************************************************/
304 /* cancelListGetFname: */
305 /* Callback function for CANCEL button in filename box */
306 /*********************************************************************/
307 static void
cancelListGetFname(Widget w,XtPointer clientData,XtPointer callData)308 cancelListGetFname (Widget w, XtPointer clientData, XtPointer callData)
309 {
310 Widget shell = (Widget)clientData;
311
312 XtSetSensitive(mainMenu, TRUE);
313 gubSetSensitive(NULL, TRUE);
314 XtPopdown(shell);
315 }
316
317
318 /*********************************************************************/
319 /* getFnameListOk: */
320 /* Callback function for OK button in filename box */
321 /*********************************************************************/
322 static void
getFnameListOk(Widget w,XtPointer clientData,XtPointer callData)323 getFnameListOk (Widget w, XtPointer clientData, XtPointer callData)
324 {
325 BibPtr bp = (BibPtr) clientData;
326 String prtName;
327 int status;
328
329 /* get filename and rename windows */
330 prtName = (String)FileNominatorGetFullFileName(w);
331 if (prtName == NULL){
332 XtPopdown(XtParent(XtParent(w)));
333 XtSetSensitive(mainMenu, TRUE);
334 gubSetSensitive(NULL, TRUE);
335 guwError(NO_VALID_FILENAME);
336 return;
337 }
338
339 /* remove file select box */
340 XtPopdown(XtParent(XtParent(w)));
341 XtSetSensitive(mainMenu, TRUE);
342 gubSetSensitive(NULL, TRUE);
343
344 /* write out printfile to disk */
345 if ((status = cprPrintList(bp, prtName, LIST)) != OK)
346 guwError(status);
347
348 }
349
350
351 /*********************************************************************/
352 /* getFnameBibOk: */
353 /* Callback function for OK button in filename box */
354 /*********************************************************************/
355 static void
getFnameBibOk(Widget w,XtPointer clientData,XtPointer callData)356 getFnameBibOk (Widget w, XtPointer clientData, XtPointer callData)
357 {
358 BibPtr bp = (BibPtr) clientData;
359 String prtName;
360 int status;
361
362 /* get filename and rename windows */
363 prtName = (String)FileNominatorGetFullFileName(w);
364 if (prtName == NULL){
365 XtPopdown(XtParent(XtParent(w)));
366 XtSetSensitive(mainMenu, TRUE);
367 gubSetSensitive(NULL, TRUE);
368 guwError(NO_VALID_FILENAME);
369 return;
370 }
371
372
373 /* remove file select box */
374 XtPopdown(XtParent(XtParent(w)));
375 XtSetSensitive(mainMenu, TRUE);
376 gubSetSensitive(NULL, TRUE);
377
378 /* write out printfile to disk */
379 if ((status = cprPrintList(bp, prtName, BIB)) != OK)
380 guwError(status);
381
382 }
383
384
385
386 /*********************************************************************/
387 /* getListFnameOk: */
388 /* Callback function for OK button in filename box */
389 /*********************************************************************/
390 static void
getListFnameOk(Widget w,XtPointer clientData,XtPointer callData)391 getListFnameOk (Widget w, XtPointer clientData, XtPointer callData)
392 {
393 BibPtr bp = (BibPtr)clientData;
394 char tmpfile[MAX_FILEPATHLEN];
395 String prtName, prtPath;
396 int status;
397
398 /* get filename and rename windows */
399 prtName = (String)FileNominatorGetFileName(w);
400 if (prtName == NULL){
401 XtPopdown(XtParent(XtParent(w)));
402 XtSetSensitive(mainMenu, TRUE);
403 gubSetSensitive(NULL, TRUE);
404 guwError(NO_VALID_FILENAME);
405 return;
406 }
407
408 prtPath = (String)FileNominatorGetFullFileName(w);
409 if (prtPath == NULL){
410 XtPopdown(XtParent(XtParent(w)));
411 XtSetSensitive(mainMenu, TRUE);
412 gubSetSensitive(NULL, TRUE);
413 guwError(NO_VALID_FILENAME);
414 return;
415 }
416
417 /* remove file select box */
418 XtPopdown(XtParent(XtParent(w)));
419 XtSetSensitive(mainMenu, TRUE);
420 gubSetSensitive(NULL, TRUE);
421
422 /* make .bak file of original */
423 strcpy(tmpfile, prtPath);
424 if (glbCheckPath(prtPath, prtName) != OK){
425 XtPopdown(XtParent(XtParent(w)));
426 XtSetSensitive(mainMenu, TRUE);
427 gubSetSensitive(NULL, TRUE);
428 guwError(BIF_EWRITE);
429 return;
430 }
431
432 if (cotBackupBeforeSave())
433 glbMakeBackup(prtPath);
434
435 /* write out printfile to disk */
436 if ((status = bifFileListWrite(bp, bp->lw->cardLst, prtPath)) != OK)
437 guwError(status);
438 }
439
440 /*********************************************************************/
441 /* printBegDoc: */
442 /* Print begin of LaTeX file */
443 /*********************************************************************/
444 static Errcode
printBegDoc(FILE * fp,String fname)445 printBegDoc (FILE *fp, String fname)
446 {
447 #ifdef GERMAN
448 fprintf(fp, "\\documentstyle[german]{article}\n");
449 fprintf(fp, "\\begin{document}\n");
450 fprintf(fp, "{\\large \\bf Inhalt der Datei %s -- \\today}\n", fname);
451 #else
452 fprintf(fp, "\\documentstyle{article}\n");
453 fprintf(fp, "\\begin{document}\n");
454 fprintf(fp, "{\\large \\bf Content of file %s -- \\today}\n", fname);
455 #endif
456 return(OK);
457 }
458
459
460 /*********************************************************************/
461 /* printEndDoc: */
462 /* Print end of LaTeX file */
463 /*********************************************************************/
464 static Errcode
printEndDoc(FILE * fp)465 printEndDoc (FILE *fp)
466 {
467 fprintf(fp, "\\end{document}\n");
468 return(OK);
469 }
470
471
472 /*********************************************************************/
473 /* printBibList: */
474 /* Print list of cards to file */
475 /*********************************************************************/
476 static Errcode
printBibList(FILE * fp,BibPtr bp,int type)477 printBibList (FILE *fp, BibPtr bp, int type)
478 {
479 CardListNode *list;
480 char tmpfile[MAX_FILEPATHLEN];
481 int j, zaehler;
482
483 strcpy(tmpfile, bp->filepath);
484 for (j=0; tmpfile[j] != '\0'; j++){
485 if (tmpfile[j] == '.'){
486 if (!strcmp(&tmpfile[j], ".bib")){
487 tmpfile[j]='\0';
488 break;
489 }
490 }
491 }
492
493 fprintf(fp, "\\nocite{");
494 if (type==LIST){
495 zaehler = 8;
496 list = bp->lw->cardLst;
497 if (list != NULL){
498 zaehler += strlen(list->data->mainkey);
499 fprintf(fp, "%s", list->data->mainkey),
500 list = list->next;
501 while (list != NULL) {
502 if (zaehler + strlen(list->data->mainkey) + 2 > max_linelen){
503 fprintf(fp, "}\n\\nocite{%s", list->data->mainkey);
504 zaehler=8+strlen(list->data->mainkey);
505 list = list->next;
506 }
507 else {
508 zaehler += strlen(list->data->mainkey) + 1;
509 fprintf(fp, ",%s", list->data->mainkey);
510 list = list->next;
511 }
512 }
513 }
514 fprintf(fp, "}\n\n");
515 }
516 else
517 fprintf(fp, "*}\n\n");
518 fprintf(fp, "\\bibliographystyle{%s}\n\n", style_file),
519 fprintf(fp, "\\bibliography{%s}\n\n", tmpfile);
520 return(OK);
521 }
522
523
524 /*********************************************************************/
525 /* printList: */
526 /* Print list of cards to file */
527 /*********************************************************************/
528 static Errcode
printList(FILE * fp,BibPtr bp,int type)529 printList (FILE *fp, BibPtr bp, int type)
530 {
531 CardListNode *list, *hlist;
532 CardListNode *cl = NULL;
533 Errcode status;
534
535 if (type == BIB){
536 /* make list of all cards in src bib */
537 if ((status = dbtBuildList(bp->treeIdx, &cl, bp->sortedby)) != DBT_OK) {
538 return(status);
539 }
540 list = cl;
541 }
542 else
543 list = bp->lw->cardLst;
544
545 hlist = list;
546 fprintf(fp, "\\begin{enumerate}\n");
547 while (hlist != NULL) {
548 if ((status = printCard(fp, hlist->data)) != OK)
549 return(status);
550
551 hlist = hlist->next;
552 }
553 fprintf(fp, "\\end{enumerate}\n");
554 if (type == BIB){
555 if ((status = dbtCardListDelete(&list)) != OK)
556 return(status);
557 list = NULL;
558 }
559 return(OK);
560 }
561
562
563 /*********************************************************************/
564 /* printCard: */
565 /* Print card to file */
566 /*********************************************************************/
567 static Errcode
printCard(FILE * fp,CardDataPtr cd)568 printCard (FILE *fp, CardDataPtr cd)
569 {
570 UserFld *hufield;
571 FieldName i;
572
573
574 fprintf(fp, "\\item %s %s\n", cd->cardtypestr, cd->mainkey);
575 fprintf(fp, "\\begin{tabbing}\n");
576 fprintf(fp, "AAAAAAAAAAAAAAAAAAAA\\= \\kill\n");
577
578 for (i=0; i<max_fields; i++){
579 if (!glbIsStringEmpty(cd->field[i])) {
580 WriteLineToArray(cd->field[i]);
581 fprintf(fp, "\\bf %s \\> \\parbox[t]{25em}{%s} \\\\ \n",
582 glbFldToName(i), texline);
583 }
584 }
585
586 /* print userdefined fields */
587 hufield = cd->ufield;
588 while (hufield != NULL) {
589 WriteLineToArray(hufield->fldData);
590 fprintf(fp, "\\bf %s \\> \\parbox[t]{25em}{%s} \\\\ \n",
591 hufield->fldName, texline);
592 hufield = hufield->next;
593 }
594 fprintf(fp, "\\end{tabbing}\n");
595 return(OK);
596 }
597
598
599 /*********************************************************************/
600 /* writeLineToArray: */
601 /* */
602 /*********************************************************************/
603 static void
WriteLineToArray(char * inh)604 WriteLineToArray (char *inh)
605 {
606 int idx;
607 int makro = 2; /* weder Makro, noch String */
608 char *tmp;
609
610 idx = 0;
611 while (*inh == ' ' || *inh == '\t' || *inh == '\n') {
612 texline[idx] = *inh;
613 inh++;
614 idx++;
615 }
616 if (*inh == '@') {
617 texline[idx] = ' ';
618 makro = 1;
619 }
620 else {
621 texline[idx] = '{';
622 idx++;
623 texline[idx] = *inh;
624 makro = 0;
625 }
626 idx++;
627 inh++;
628 while (*inh != '\0') {
629 if (*inh == '@') {
630 tmp = inh;
631 tmp++;
632 if (*tmp == '#') { /* KONKATENATION */
633 if (makro == 1) {
634 /* letzter Teil war ein MAKRO */
635 texline[idx] = ' '; idx++;
636 texline[idx] = '\\'; idx++;
637 texline[idx] = '#'; idx++;
638 texline[idx] = ' '; idx++;
639 tmp++;
640 while (*tmp == ' ' || *tmp == '\t' || *tmp == '\n') {
641 texline[idx] = *tmp;
642 idx++;
643 tmp++;
644 }
645 if (*tmp == '@') { /* naechster Teil ist ein MAKRO */
646 texline[idx] = ' '; idx++;
647 makro = 1;
648 }
649 else {
650 texline[idx] = '{'; idx++;
651 texline[idx] = *tmp;
652 idx++;
653 /* naechster Teil ist ein STRING */
654 makro = 0;
655 }
656 }
657 else if (makro == 0) {
658 /* letzter Teil war ein STRING */
659 texline[idx] = '}'; idx++;
660 texline[idx] = ' '; idx++;
661 texline[idx] = '\\'; idx++;
662 texline[idx] = '#'; idx++;
663 texline[idx] = ' '; idx++;
664 tmp++;
665 while (*tmp == ' ' || *tmp == '\t' || *tmp == '\n') {
666 texline[idx] = *tmp;
667 idx++;
668 tmp++;
669 }
670 if (*tmp == '@') { /* naechster Teil ist ein MAKRO */
671 texline[idx] = ' '; idx++;
672 makro = 1;
673 }
674 else {
675 texline[idx] = '{'; idx++;
676 texline[idx] = *tmp;
677 idx++;
678 makro = 0;
679 }
680 } /* else if makro == 0 */
681 inh = tmp;
682 }
683 else { /* AFFE nicht schreiben */
684 texline[idx] = ' '; idx++;
685 makro = 1;
686 }
687 } /* if @ */
688 else {
689 texline[idx] = *inh;
690 idx++;
691 }
692 inh++;
693 } /* while */
694 if (makro == 0) {
695 texline[idx] = '}'; idx++;
696 }
697 texline[idx] = ','; idx++;
698 texline[idx] = ' '; idx++;
699 texline[idx] = '\0'; idx++;
700 }
701
702