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