Merge release-4-5-patches into release-4-6
[alexxy/gromacs.git] / src / gmxlib / wman.c
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  * 
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * GROningen Mixture of Alchemy and Childrens' Stories
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "string2.h"
40 #include "smalloc.h"
41 #include "sysstuff.h"
42 #include "filenm.h"
43 #include "macros.h"
44 #include "replace.h"
45 #include "wman.h"
46 #include "statutil.h"
47 #include "copyrite.h"
48 #include "strdb.h"
49 #include <time.h>
50 #include "readinp.h"
51
52 /* The source code in this file should be thread-safe. 
53          Please keep it that way. */
54
55
56 typedef struct {
57   const char *search,*replace;
58 } t_sandr_const;
59
60 typedef struct {
61   char *search,*replace;
62 } t_sandr;
63
64 /* The order of these arrays is significant. Text search and replace
65  * for each element occurs in order, so earlier changes can induce
66  * subsequent changes even though the original text might not appear
67  * to invoke the latter changes. */
68
69 const t_sandr_const sandrTeX[] = {
70   { "[TT]", "{\\tt " },
71   { "[tt]", "}"      },
72   { "[BB]", "{\\bf " },
73   { "[bb]", "}"      },
74   { "[IT]", "{\\em " },
75   { "[it]", "}"      },
76   { "[PAR]","\n\n"   },
77   /* Escaping underscore for LaTeX is no longer necessary, and it breaks
78    * text searching and the index if you do. */
79   /*
80   { "_",    "\\_"    },
81   */
82   { "$",    "\\$"    },
83   { "<=",   "\\ensuremath{\\leq{}}"},
84   { ">=",   "\\ensuremath{\\geq{}}"},
85   { "<",    "\\textless{}" },
86   { ">",    "\\textgreater{}" },
87   { "^",    "\\^{}"    },
88   { "\\^{}t", "\\ensuremath{^t}" },
89   { "\\^{}a", "\\ensuremath{^a}" },
90   { "\\^{}b", "\\ensuremath{^b}" },
91   { "\\^{}2", "\\ensuremath{^2}" },
92   { "\\^{}3", "\\ensuremath{^3}" },
93   { "\\^{}6", "\\ensuremath{^6}" },
94   { "#",    "\\#"    },
95   { "[BR]", "\\\\"   },
96   { "%",    "\\%"    },
97   { "&",    "\\&"    },
98   /* The next couple of lines allow true Greek symbols to be written to the 
99      manual, which makes it look pretty */
100   { "[GRK]", "\\ensuremath{\\" },
101   { "[grk]", "}" },
102   { "[MATH]","\\ensuremath{" },
103   { "[math]","}" },
104   { "[CHEVRON]", "\\ensuremath{<}" },
105   { "[chevron]", "\\ensuremath{>}" },
106   { "[MAG]", "\\ensuremath{|}" },
107   { "[mag]", "\\ensuremath{|}" },
108   { "[INT]","\\ensuremath{\\int" },
109   { "[FROM]","_" },
110   { "[from]","" },
111   { "[TO]", "^" },
112   { "[to]", "" },
113   { "[int]","}" },
114   { "[SUM]","\\ensuremath{\\sum" },
115   { "[sum]","}" },
116   { "[SUB]","\\ensuremath{_{" },
117   { "[sub]","}}" },
118   { "[SQRT]","\\ensuremath{\\sqrt{" },
119   { "[sqrt]","}}" },
120   { "[EXP]","\\ensuremath{\\exp{(" },
121   { "[exp]",")}}" },
122   { "[LN]","\\ensuremath{\\ln{(" },
123   { "[ln]",")}}" },
124   { "[LOG]","\\ensuremath{\\log{(" },
125   { "[log]",")}}" },
126   { "[COS]","\\ensuremath{\\cos{(" },
127   { "[cos]",")}}" },
128   { "[SIN]","\\ensuremath{\\sin{(" },
129   { "[sin]",")}}" },
130   { "[TAN]","\\ensuremath{\\tan{(" },
131   { "[tan]",")}}" },
132   { "[COSH]","\\ensuremath{\\cosh{(" },
133   { "[cosh]",")}}" },
134   { "[SINH]","\\ensuremath{\\sinh{(" },
135   { "[sinh]",")}}" },
136   { "[TANH]","\\ensuremath{\\tanh{(" },
137   { "[tanh]",")}}" }
138 };
139 #define NSRTEX asize(sandrTeX)
140
141 const t_sandr_const sandrTty[] = {
142   { "[TT]", "" },
143   { "[tt]", "" },
144   { "[BB]", "" },
145   { "[bb]", "" },
146   { "[IT]", "" },
147   { "[it]", "" },
148   { "[MATH]","" },
149   { "[math]","" },
150   { "[CHEVRON]","<" },
151   { "[chevron]",">" },
152   { "[MAG]", "|" },
153   { "[mag]", "|" },
154   { "[INT]","integral" },
155   { "[FROM]"," from " },
156   { "[from]","" },
157   { "[TO]", " to " },
158   { "[to]", " of" },
159   { "[int]","" },
160   { "[SUM]","sum" },
161   { "[sum]","" },
162   { "[SUB]","_" },
163   { "[sub]","" },
164   { "[SQRT]","sqrt(" },
165   { "[sqrt]",")" },
166   { "[EXP]","exp(" },
167   { "[exp]",")" },
168   { "[LN]","ln(" },
169   { "[ln]",")" },
170   { "[LOG]","log(" },
171   { "[log]",")" },
172   { "[COS]","cos(" },
173   { "[cos]",")" },
174   { "[SIN]","sin(" },
175   { "[sin]",")" },
176   { "[TAN]","tan(" },
177   { "[tan]",")" },
178   { "[COSH]","cosh(" },
179   { "[cosh]",")" },
180   { "[SINH]","sinh(" },
181   { "[sinh]",")" },
182   { "[TANH]","tanh(" },
183   { "[tanh]",")" },
184   { "[PAR]","\n\n" },
185   { "[BR]", "\n"},
186   { "[GRK]", "" },
187   { "[grk]", "" }
188 };
189 #define NSRTTY asize(sandrTty)
190
191 const t_sandr_const sandrWiki[] = {
192   { "&",    "&amp;" },
193   { "<",    "&lt;" },
194   { ">",    "&gt;" },
195   { "[TT]", "&lt;code&gt;" },
196   { "[tt]", "&lt;/code&gt;" },
197   { "[BB]", "'''" },
198   { "[bb]", "'''" },
199   { "[IT]", "''" },
200   { "[it]", "''" },
201   { "[MATH]","" },
202   { "[math]","" },
203   { "[CHEVRON]","<" },
204   { "[chevron]",">" },
205   { "[MAG]", "|" },
206   { "[mag]", "|" },
207   { "[INT]","integral" },
208   { "[FROM]"," from " },
209   { "[from]","" },
210   { "[TO]", " to " },
211   { "[to]", " of" },
212   { "[int]","" },
213   { "[SUM]","sum" },
214   { "[sum]","" },
215   { "[SUB]","_" },
216   { "[sub]","" },
217   { "[SQRT]","sqrt(" },
218   { "[sqrt]",")", },
219   { "[EXP]","exp(" },
220   { "[exp]",")" },
221   { "[LN]","ln(" },
222   { "[ln]",")" },
223   { "[LOG]","log(" },
224   { "[log]",")" },
225   { "[COS]","cos(" },
226   { "[cos]",")" },
227   { "[SIN]","sin(" },
228   { "[sin]",")" },
229   { "[TAN]","tan(" },
230   { "[tan]",")" },
231   { "[COSH]","cosh(" },
232   { "[cosh]",")" },
233   { "[SINH]","sinh(" },
234   { "[sinh]",")" },
235   { "[TANH]","tanh(" },
236   { "[tanh]",")" },
237   { "[PAR]","\n\n" },
238   { "[BR]", "\n" },
239   { "[GRK]", "&" },
240   { "[grk]", ";" }
241 };
242 #define NSRWIKI asize(sandrWiki)
243
244 const t_sandr_const sandrNROFF[] = {
245   { "[TT]", "\\fB " },
246   { "[tt]", "\\fR" },
247   { "[BB]", "\\fB " },
248   { "[bb]", "\\fR" },
249   { "[IT]", "\\fI " },
250   { "[it]", "\\fR" },
251   { "[MATH]","" },
252   { "[math]","" },
253   { "[CHEVRON]","<" },
254   { "[chevron]",">" },
255   { "[MAG]", "|" },
256   { "[mag]", "|" },
257   { "[INT]","integral" },
258   { "[FROM]"," from " },
259   { "[from]","" },
260   { "[TO]", " to " },
261   { "[to]", " of" },
262   { "[int]","" },
263   { "[SUM]","sum" },
264   { "[sum]","" },
265   { "[SUB]","_" },
266   { "[sub]","" },
267   { "[SQRT]","sqrt(" },
268   { "[sqrt]",")", },
269   { "[EXP]","exp(" },
270   { "[exp]",")" },
271   { "[LN]","ln(" },
272   { "[ln]",")" },
273   { "[LOG]","log(" },
274   { "[log]",")" },
275   { "[COS]","cos(" },
276   { "[cos]",")" },
277   { "[SIN]","sin(" },
278   { "[sin]",")" },
279   { "[TAN]","tan(" },
280   { "[tan]",")" },
281   { "[COSH]","cosh(" },
282   { "[cosh]",")" },
283   { "[SINH]","sinh(" },
284   { "[sinh]",")" },
285   { "[TANH]","tanh(" },
286   { "[tanh]",")" },
287   { "[PAR]","\n\n" },
288   { "\n ",    "\n" },
289   { "<",    "" },
290   { ">",    "" },
291   { "^",    "" },
292   { "#",    "" },
293   { "[BR]", "\n"},
294   { "-",    "\\-"},
295   { "[GRK]", "" },
296   { "[grk]", "" }
297 };
298 #define NSRNROFF asize(sandrNROFF)
299
300 const t_sandr_const sandrHTML[] = {
301   { "<",    "&lt;" },
302   { ">",    "&gt;" },
303   { "[TT]", "<tt>" },
304   { "[tt]", "</tt>" },
305   { "[BB]", "<b>" },
306   { "[bb]", "</b>" },
307   { "[IT]", "<it>" },
308   { "[it]", "</it>" },
309   { "[MATH]","" },
310   { "[math]","" },
311   { "[CHEVRON]","<" },
312   { "[chevron]",">" },
313   { "[MAG]", "|" },
314   { "[mag]", "|" },
315   { "[INT]","integral" },
316   { "[FROM]"," from " },
317   { "[from]","" },
318   { "[TO]", " to " },
319   { "[to]", " of" },
320   { "[int]","" },
321   { "[SUM]","sum" },
322   { "[sum]","" },
323   { "[SUB]","_" },
324   { "[sub]","" },
325   { "[SQRT]","sqrt(" },
326   { "[sqrt]",")", },
327   { "[EXP]","exp(" },
328   { "[exp]",")" },
329   { "[LN]","ln(" },
330   { "[ln]",")" },
331   { "[LOG]","log(" },
332   { "[log]",")" },
333   { "[COS]","cos(" },
334   { "[cos]",")" },
335   { "[SIN]","sin(" },
336   { "[sin]",")" },
337   { "[TAN]","tan(" },
338   { "[tan]",")" },
339   { "[COSH]","cosh(" },
340   { "[cosh]",")" },
341   { "[SINH]","sinh(" },
342   { "[sinh]",")" },
343   { "[TANH]","tanh(" },
344   { "[tanh]",")" },
345   { "[PAR]","<p>" },
346   { "[BR]", "<br>" },
347   { "[GRK]", "&"  },
348   { "[grk]", ";"  }
349 };
350 #define NSRHTML asize(sandrHTML)
351
352 const t_sandr_const sandrXML[] = {
353   { "<",    "&lt;" },
354   { ">",    "&gt;" },
355   { "[TT]", "<arg>" },
356   { "[tt]", "</arg>" },
357   { "[BB]", "<emp>" },
358   { "[bb]", "</emp>" },
359   { "[IT]", "<it>" },
360   { "[it]", "</it>" },
361   { "[MATH]","" },
362   { "[math]","" },
363   { "[CHEVRON]","<" },
364   { "[chevron]",">" },
365   { "[MAG]", "|" },
366   { "[mag]", "|" },
367   { "[INT]","integral" },
368   { "[FROM]"," from " },
369   { "[from]","" },
370   { "[TO]", " to " },
371   { "[to]", " of" },
372   { "[int]","" },
373   { "[SUM]","sum" },
374   { "[sum]","" },
375   { "[SUB]","_" },
376   { "[sub]","" },
377   { "[SQRT]","sqrt(" },
378   { "[sqrt]",")", },
379   { "[EXP]","exp(" },
380   { "[exp]",")" },
381   { "[LN]","ln(" },
382   { "[ln]",")" },
383   { "[LOG]","log(" },
384   { "[log]",")" },
385   { "[COS]","cos(" },
386   { "[cos]",")" },
387   { "[SIN]","sin(" },
388   { "[sin]",")" },
389   { "[TAN]","tan(" },
390   { "[tan]",")" },
391   { "[COSH]","cosh(" },
392   { "[cosh]",")" },
393   { "[SINH]","sinh(" },
394   { "[sinh]",")" },
395   { "[TANH]","tanh(" },
396   { "[tanh]",")" },
397   { "[PAR]","</par>\n<par>" },
398   { "[BR]", "<br />" },
399   { "[GRK]", "" },
400   { "[grk]", "" }
401 };
402 #define NSRXML asize(sandrXML)
403
404 static void mynum(char *buf,int n)
405 {
406   if (n >= 10)
407     sprintf(buf,"%2d",n);
408   else
409     sprintf(buf,"0%1d",n);
410 }
411
412 static char *mydate(char buf[], int maxsize,gmx_bool bWiki)
413 {
414   const char *mon[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
415                          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
416   const char *day[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
417   const char *num[] = { "01", "02", "03", "04", "05", "06","07", "08", "09" }; 
418   time_t now;
419   struct tm tm;
420   
421   time(&now);
422 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
423   /* Native windows */
424   localtime_s(&tm,&now);
425 #else
426   localtime_r(&now,&tm);
427 #endif
428
429   /* subtract one from maxsize, so we have room for \0. */
430   if (bWiki) {
431     char dd[8],mm[8],ss[8],hh[8],mn[8];
432     
433     mynum(dd,tm.tm_mday);
434     mynum(mm,tm.tm_mon);
435     mynum(ss,tm.tm_sec);
436     mynum(hh,tm.tm_hour);
437     mynum(mn,tm.tm_min);
438     sprintf(buf,"%4d-%2s-%2sT%2s:%2s:%2sZ",
439              tm.tm_year+1900,mm,dd,hh,mn,ss);
440   }
441   else
442     sprintf(buf,"%s %d %s %d",day[tm.tm_wday],tm.tm_mday,
443              mon[tm.tm_mon],tm.tm_year+1900);
444   
445   return buf;
446 }
447
448 /* Data structure for saved HTML links */
449 typedef struct t_linkdata {
450   int     nsr;
451   t_sandr *sr;
452 } t_linkdata;
453
454 static t_linkdata *init_linkdata()
455 {
456   t_linkdata *p;
457   snew(p,1);
458   p->sr=NULL;
459   p->nsr=0;
460
461   return p;
462 }
463
464 static void finish_linkdata(t_linkdata *p)
465 {
466   int i;
467   
468   for(i=0;i<p->nsr;i++) {
469     sfree(p->sr[i].search);    
470     sfree(p->sr[i].replace);
471   }
472   sfree(p->sr);
473   sfree(p);
474 }
475
476 static char *repall(const char *s,int nsr,const t_sandr_const sa[])
477 {
478   int  i;
479   char *buf1,*buf2;
480   
481   /* Copy input to a non-constant char buffer.
482    * buf1 is allocated here 
483    */
484   buf1=gmx_strdup(s); 
485   
486   for(i=0; (i<nsr); i++) {
487     /* Replace in buffer1, put result in buffer2.
488      * buf2 is allocated here.
489      */
490     buf2=replace(buf1,sa[i].search,sa[i].replace);
491     sfree(buf1);
492     buf1=buf2;
493   }
494   
495   return buf1;
496
497
498 static char *repallww(const char *s,int nsr,const t_sandr sa[])
499 {
500   int  i;
501   char *buf1,*buf2;
502
503   /* Copy input to a non-constant char buffer.
504    * buf1 is allocated here 
505    */
506   buf1=gmx_strdup(s); 
507   
508   for(i=0; (i<nsr); i++) {
509     /* Replace in buffer1, put result in buffer2.
510      * buf2 is allocated here.
511      */
512     buf2=replaceww(buf1,sa[i].search,sa[i].replace);
513     sfree(buf1);
514     buf1=buf2;
515   }
516   return buf1;
517 }
518
519 static char *html_xref(char *s,const char *program, t_linkdata *links,gmx_bool bWiki)
520 {
521   char   buf[256],**filestr;
522   int    i,j,n;
523   
524   if (links->sr == NULL) {
525     n=get_file("links.dat",&(filestr));
526     links->nsr=n;
527     snew(links->sr,n);
528     for(i=0,j=0; (i<n); i++) {
529       if (!program || (gmx_strcasecmp(program,filestr[i])  != 0)) {
530         links->sr[j].search=gmx_strdup(filestr[i]);
531         if (bWiki)
532           sprintf(buf,"[[%s]]",filestr[i]);
533         else
534           sprintf(buf,"<a href=\"%s.html\">%s</a>",filestr[i],filestr[i]);
535         links->sr[j].replace=gmx_strdup(buf);
536         j++;
537       }
538     }
539     links->nsr=j;
540     for(i=0;i<n;i++)
541       sfree(filestr[i]);
542     sfree(filestr);
543   }
544   return repallww(s,links->nsr,links->sr);
545 }
546
547 char *check_tex(const char *s)
548 {
549   return repall(s,NSRTEX,sandrTeX);
550 }
551
552 static char *check_nroff(const char *s)
553 {
554   return repall(s,NSRNROFF,sandrNROFF);
555 }
556
557 static char *check_wiki(const char *s,const char *program, t_linkdata *links)
558 {
559   char *buf;
560   
561   buf = repall(s,NSRWIKI,sandrWiki);
562   buf = html_xref(buf,program,links,TRUE);
563   
564   return buf;
565 }
566
567 static char *check_html(const char *s,const char *program, t_linkdata *links)
568 {
569   char *buf;
570   
571   buf = repall(s,NSRHTML,sandrHTML);
572   buf = html_xref(buf,program,links,FALSE);
573   
574   return buf;
575 }
576
577 #define NWR(s) check_wiki(s,program,links)
578 #define NSR(s) check_html(s,program,links)
579   
580 #define FLAG_SET(flag, mask) ((flag & mask) == mask)
581 char *fileopt(unsigned long flag,char buf[],int maxsize)
582 {
583   char tmp[256];
584   
585   if (FLAG_SET(flag, ffRW))
586     sprintf(tmp,"In/Out");
587   else if (FLAG_SET(flag, ffREAD))
588     sprintf(tmp,"Input");
589   else if (FLAG_SET(flag, ffWRITE))
590     sprintf(tmp,"Output");
591   else
592     sprintf(tmp,"Dunno");
593
594   if (FLAG_SET(flag, ffOPT)) {
595     strcat(tmp,", Opt");
596     if (FLAG_SET(flag, ffSET)) 
597       strcat(tmp,"!");
598     else
599       strcat(tmp,".");
600   }
601   if (FLAG_SET(flag, ffLIB))
602     strcat(tmp,", Lib.");
603   if (FLAG_SET(flag, ffMULT))
604     strcat(tmp,", Mult.");
605
606   sprintf(buf,"%s",tmp);
607   
608   return buf;
609 }
610
611 static void write_texman(FILE *out,const char *program,
612                          int nldesc,const char **desc,
613                          int nfile,t_filenm *fnm,
614                          int npargs,t_pargs *pa,
615                          int nbug,const char **bugs,
616                          t_linkdata *links)
617 {
618   int i;
619   char tmp[256];
620   
621   fprintf(out,"\\section{\\normindex{%s}}\\label{%s}\n\n",check_tex(program),check_tex(program));
622   
623   if (nldesc > 0)
624     for(i=0; (i<nldesc); i++) 
625       fprintf(out,"%s\n",check_tex(desc[i]));
626
627   if (nfile > 0) {
628     fprintf(out,"\\vspace{-2ex}\\begin{tabbing}\n");
629     fprintf(out,"\n{\\normalsize \\bf Files}\\nopagebreak\\\\\n");
630     fprintf(out,"{\\tt ~~~~~~~} \\= {\\tt ~~~~~~~~~~~~~~} \\= "
631             "~~~~~~~~~~~~~~~~~~~~~~ \\= \\nopagebreak\\kill\n");
632     for(i=0; (i<nfile); i++)
633       fprintf(out,"\\>{\\tt %s} \\'\\> {\\tt %s} \\' %s \\> "
634               "\\parbox[t]{0.55\\linewidth}{%s} \\\\\n",
635               check_tex(fnm[i].opt),check_tex(fnm[i].fns[0]),
636               check_tex(fileopt(fnm[i].flag,tmp,255)),
637               check_tex(ftp2desc(fnm[i].ftp)));
638     fprintf(out,"\\end{tabbing}\\vspace{-4ex}\n");
639   }
640   if (npargs > 0) {
641     fprintf(out,"\\vspace{-2ex}\\begin{tabbing}\n");
642     fprintf(out,"\n{\\normalsize \\bf Other options}\\nopagebreak\\\\\n");
643     fprintf(out,"{\\tt ~~~~~~~~~~} \\= vector \\= "
644             "{\\tt ~~~~~~~} \\= \\nopagebreak\\kill\n");
645     for(i=0; (i<npargs); i++) {
646       if (strlen(check_tex(pa_val(&(pa[i]),tmp,255))) <= 8)
647         fprintf(out,"\\> {\\tt %s} \\'\\> %s \\'\\> {\\tt %s} \\' "
648                 "\\parbox[t]{0.68\\linewidth}{%s}\\\\\n",
649                 check_tex(pa[i].option),argtp[pa[i].type],
650                 check_tex(pa_val(&(pa[i]),tmp,255)),
651                 check_tex(pa[i].desc));
652       else
653         fprintf(out,"\\> {\\tt %s} \\'\\> %s \\'\\>\\\\\n"
654                 "\\> \\'\\> \\'\\> {\\tt %s} \\' "
655                 "\\parbox[t]{0.7\\linewidth}{%s}\\\\\n",
656                 check_tex(pa[i].option),argtp[pa[i].type],
657                 check_tex(pa_val(&(pa[i]),tmp,255)),
658                 check_tex(pa[i].desc));
659     }
660     fprintf(out,"\\end{tabbing}\\vspace{-4ex}\n");
661   }
662   if (nbug > 0) {
663     fprintf(out,"\n");
664     fprintf(out,"\\begin{itemize}\n");
665     for(i=0; (i<nbug); i++)
666       fprintf(out,"\\item %s\n",check_tex(bugs[i]));
667     fprintf(out,"\\end{itemize}\n");
668   }
669 /*   fprintf(out,"\n\\newpage\n"); */
670 }
671
672 static void write_nroffman(FILE *out,
673                            const char *program,
674                            int nldesc,const char **desc,
675                            int nfile,t_filenm *fnm,
676                            int npargs,t_pargs *pa,
677                            int nbug,const char **bugs,
678                            t_linkdata *links)
679
680 {
681   int i;
682   char tmp[256];
683   
684   
685   fprintf(out,".TH %s 1 \"%s\" \"\" \"GROMACS suite, %s\"\n",program,mydate(tmp,255,FALSE),GromacsVersion());
686   fprintf(out,".SH NAME\n");
687   fprintf(out,"%s\n",program);
688   fprintf(out,".B %s\n",GromacsVersion());
689   
690   fprintf(out,".SH SYNOPSIS\n");
691   fprintf(out,"\\f3%s\\fP\n",program);
692
693   /* command line arguments */
694   if (nfile > 0) {
695     for(i=0; (i<nfile); i++)
696       fprintf(out,".BI \"%s\" \" %s \"\n",check_nroff(fnm[i].opt),
697               check_nroff(fnm[i].fns[0]));
698   }
699   if (npargs > 0) {
700     for(i=0; (i<npargs); i++)
701       if (pa[i].type == etBOOL)
702         fprintf(out,".BI \"\\-[no]%s\" \"\"\n",check_nroff(pa[i].option+1));
703       else
704         fprintf(out,".BI \"%s\" \" %s \"\n",check_nroff(pa[i].option),
705                 check_nroff(argtp[pa[i].type]));
706   }
707   
708   /* description */
709   if (nldesc > 0) {
710     fprintf(out,".SH DESCRIPTION\n");
711     for(i=0; (i<nldesc); i++) 
712       fprintf(out,"\\&%s\n",check_nroff(desc[i]));
713   }
714
715   /* FILES */
716   if (nfile > 0) {
717     fprintf(out,".SH FILES\n");
718     for(i=0; (i<nfile); i++)
719       fprintf(out,".BI \"%s\" \" %s\" \n.B %s\n %s \n\n",
720               check_nroff(fnm[i].opt),
721               check_nroff(fnm[i].fns[0]),
722               check_nroff(fileopt(fnm[i].flag,tmp,255)),
723               check_nroff(ftp2desc(fnm[i].ftp)));
724   }
725   
726   /* other options */
727   fprintf(out,".SH OTHER OPTIONS\n");
728   if ( npargs > 0 ) {
729     for(i=0; (i<npargs); i++) {
730       if (pa[i].type == etBOOL)
731         fprintf(out,".BI \"\\-[no]%s\"  \"%s\"\n %s\n\n",
732                 check_nroff(pa[i].option+1),
733                 check_nroff(pa_val(&(pa[i]),tmp,255)),
734                 check_nroff(pa[i].desc));
735       else
736         fprintf(out,".BI \"%s\"  \" %s\" \" %s\" \n %s\n\n",
737                 check_nroff(pa[i].option),
738                 check_nroff(argtp[pa[i].type]),
739                 check_nroff(pa_val(&(pa[i]),tmp,255)),
740                 check_nroff(pa[i].desc));
741     }
742   }
743
744   if (nbug > 0) {
745     fprintf(out,".SH KNOWN PROBLEMS\n");
746     for(i=0; (i<nbug); i++)
747       fprintf(out,"\\- %s\n\n",check_nroff(bugs[i]));
748   }
749
750   fprintf(out,".SH SEE ALSO\n.BR gromacs(7)\n\n");
751   fprintf(out,"More information about \\fBGROMACS\\fR is available at <\\fIhttp://www.gromacs.org/\\fR>.\n");
752
753 }
754
755 char *check_tty(const char *s)
756 {
757   return repall(s,NSRTTY,sandrTty);
758 }
759
760 void
761 print_tty_formatted(FILE *out, int nldesc, const char **desc,int indent,
762                     t_linkdata *links,const char *program,gmx_bool bWiki)
763 {
764   char *buf;
765   char *temp;
766   int buflen,i,j;
767
768   buflen = 80*nldesc;
769   snew(buf,buflen);
770   for(i=0; (i<nldesc); i++) {
771     if ((strlen(buf)>0) && 
772         (buf[strlen(buf)-1] !=' ') && (buf[strlen(buf)-1] !='\n'))
773       strcat(buf," ");
774     if (bWiki)
775       temp=NWR(desc[i]);
776     else
777       temp=check_tty(desc[i]);
778     if (strlen(buf) + strlen(temp) >= (size_t)(buflen-2)) {
779       buflen += strlen(temp);
780       srenew(buf,buflen);
781     }
782     strcat(buf,temp);
783     sfree(temp);
784   }
785   /* Make lines of at most 79 characters */
786   temp = wrap_lines(buf,78,indent,FALSE);
787   fprintf(out,"%s\n",temp);
788   sfree(temp);
789   sfree(buf);
790 }
791
792 static void write_ttyman(FILE *out,
793                          const char *program,
794                          int nldesc,const char **desc,
795                          int nfile,t_filenm *fnm,
796                          int npargs,t_pargs *pa,
797                          int nbug,const char **bugs,gmx_bool bHeader,
798                          t_linkdata *links)
799 {
800   int i;
801   char buf[256];
802   char *tmp;
803   
804   if (bHeader) {
805     fprintf(out,"%s\n\n",check_tty(program));
806     fprintf(out,"%s\n%s\n",GromacsVersion(),mydate(buf,255,FALSE));
807   }
808   if (nldesc > 0) {
809     fprintf(out,"DESCRIPTION\n-----------\n");
810     print_tty_formatted(out,nldesc,desc,0,links,program,FALSE);
811   }
812   if (nbug > 0) {
813     fprintf(out,"\n");
814     fprintf(out,"KNOWN PROBLEMS\n----------\n");
815     for(i=0; i<nbug; i++) {
816       snew(tmp,strlen(bugs[i])+3);
817       strcpy(tmp,"* ");
818       strcpy(tmp+2,check_tty(bugs[i]));
819       fprintf(out,"%s\n",wrap_lines(tmp,78,2,FALSE));
820       sfree(tmp);
821     }
822   }
823   if (nfile > 0) {
824     fprintf(out,"\n");
825     pr_fns(out,nfile,fnm);
826   }
827   if (npargs > 0) {
828     print_pargs(out,npargs,pa,FALSE);
829   }
830 }
831
832 static void pr_html_files(FILE *out,int nfile,t_filenm fnm[],
833                           const char *program,t_linkdata *links,gmx_bool bWiki)
834
835   int  i;
836   char link[10],tmp[255];
837   
838   if (bWiki)
839     fprintf(out," %-10s %-12s %-12s %-s\n"
840             " -----------------------------------------------------\n",
841             "Option","Filename","Type","Description");
842   else
843     fprintf(out,
844             "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
845             "<TR>"
846             "<TH>option</TH>"
847             "<TH>filename</TH>"
848             "<TH>type</TH>"
849             "<TH>description</TH>"
850             "</TR>\n");
851   
852   for(i=0; (i<nfile); i++) {
853     strcpy(link,ftp2ext(fnm[i].ftp));
854     if (strcmp(link,"???")==0)
855       strcpy(link,"files");
856     if (bWiki)
857       fprintf(out," %-10s %-16s %-12s %-s\n",
858               fnm[i].opt,
859               NWR(fnm[i].fns[0]),
860               fileopt(fnm[i].flag,tmp,255),
861               NWR(ftp2desc(fnm[i].ftp)));
862     else
863       fprintf(out,
864               "<TR>"
865               "<TD ALIGN=RIGHT> <b><tt>%s</tt></b> </TD>"
866               "<TD ALIGN=RIGHT> <tt><a href=\"%s.html\">%12s</a></tt> </TD>"
867               "<TD> %s </TD>"
868               "<TD> %s </TD>"
869               "</TR>\n",
870               fnm[i].opt,link,fnm[i].fns[0],fileopt(fnm[i].flag,tmp,255),
871               NSR(ftp2desc(fnm[i].ftp)));
872   }
873   if (!bWiki)
874     fprintf(out,"</TABLE>\n");
875 }
876
877 static void write_wikiman(FILE *out,
878                           const char *program,
879                           int nldesc,const char **desc,
880                           int nfile,t_filenm *fnm,
881                           int npargs,t_pargs *pa,
882                           int nbug,const char **bugs,gmx_bool bHeader,
883                           t_linkdata *links)
884 {
885   int i;
886   char buf[256],link[10];
887   char *tmp,*tmp2;
888   fprintf(out,"<page>\n<title>Manual:%s_%s</title>\n",program,
889           VERSION);
890   fprintf(out,"<revision>\n");
891   fprintf(out,"<timestamp>%s</timestamp>\n",mydate(buf,255,TRUE));
892   fprintf(out,"<text xml:space=\"preserve\">\n");
893   if (nldesc > 0) {
894     fprintf(out,"== Description ==\n");
895     print_tty_formatted(out,nldesc,desc,0,links,program,TRUE);
896     fprintf(out,"\n");
897   }
898   if (nbug > 0) {
899     fprintf(out,"== Known Problems ==\n");
900     for(i=0; i<nbug; i++) {
901       snew(tmp,strlen(bugs[i])+3);
902       strcpy(tmp,"* ");
903       strcpy(tmp+2,bugs[i]);
904       fprintf(out,"%s\n",NWR(tmp));
905       sfree(tmp);
906     }
907   }
908   if (nfile > 0) {
909     fprintf(out,"\n== Files ==\n");
910     pr_html_files(out,nfile,fnm,program,links,TRUE);
911   }
912   if (npargs > 0) {
913     fprintf(out,"\n== Options ==\n");
914     fprintf(out," %-12s %-6s %-6s  %-s\n",
915             "Option","Type","Value","Description");
916     fprintf(out," ------------------------------------------------------\n");
917     for(i=0; (i<npargs); i++) {
918       tmp = NWR(pargs_print_line(&pa[i],TRUE));
919       fprintf(out,"%s",tmp);
920       sfree(tmp);
921     }
922   }
923   fprintf(out,"[[category:Manual_Pages_%s|%s]]\n",VERSION,program);
924   fprintf(out,"</text>\n");
925   fprintf(out,"</revision>\n");
926   fprintf(out,"</page>\n\n");
927 }
928
929 static void write_htmlman(FILE *out,
930                           const char *program,
931                           int nldesc,const char **desc,
932                           int nfile,t_filenm *fnm,
933                           int npargs,t_pargs *pa,
934                           int nbug,const char **bugs,
935                           t_linkdata *links)
936 {
937   int i;
938   char link[10],tmp[255];
939   
940   fprintf(out,"<HTML>\n<HEAD>\n<TITLE>%s</TITLE>\n",program);
941   fprintf(out,"<LINK rel=stylesheet href=\"style.css\" type=\"text/css\">\n");
942   fprintf(out,"<BODY text=\"#000000\" bgcolor=\"#FFFFFF\" link=\"#0000FF\" vlink=\"#990000\" alink=\"#FF0000\">\n");
943   fprintf(out,"<TABLE WIDTH=\"98%%\" NOBORDER >\n<TR><TD WIDTH=400>\n");
944   fprintf(out,"<TABLE WIDTH=400 NOBORDER>\n<TD WIDTH=116>\n");
945   fprintf(out,"<a href=\"http://www.gromacs.org/\">"
946           "<img SRC=\"../images/gmxlogo_small.png\""
947           "BORDER=0 </a></td>\n");
948   fprintf(out,"<td ALIGN=LEFT VALIGN=TOP WIDTH=280>"
949           "<br><h2>%s</h2>",program);
950   fprintf(out,"<font size=-1><A HREF=\"../online.html\">Main Table of Contents</A></font><br>");
951   fprintf(out,"<br></td>\n</TABLE></TD><TD WIDTH=\"*\" ALIGN=RIGHT VALIGN=BOTTOM><p><B>%s<br>\n",GromacsVersion());
952   fprintf(out,"%s</B></td></tr></TABLE>\n<HR>\n",mydate(tmp,255,FALSE));
953   
954   if (nldesc > 0) {
955     fprintf(out,"<H3>Description</H3>\n<p>\n");
956     for(i=0; (i<nldesc); i++) 
957       fprintf(out,"%s\n",NSR(desc[i]));
958   }
959   if (nfile > 0) {
960     fprintf(out,"<P>\n");
961     fprintf(out,"<H3>Files</H3>\n");
962     pr_html_files(out,nfile,fnm,program,links,FALSE);
963   }
964   if (npargs > 0) {
965     fprintf(out,"<P>\n");
966     fprintf(out,"<H3>Other options</H3>\n");
967     fprintf(out,
968             "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
969             "<TR>"
970             "<TH>option</TH>"
971             "<TH>type</TH>"
972             "<TH>default</TH>"
973             "<TH>description</TH>"
974             "</TR>\n");
975     for(i=0; (i<npargs); i++)
976       fprintf(out,
977               "<TR>"
978               "<TD ALIGN=RIGHT> <b><tt>%s%s</tt></b> </TD>"
979               "<TD ALIGN=RIGHT> %s </TD>"
980               "<TD ALIGN=RIGHT> <tt>%s</tt> </TD>"
981               "<TD> %s </TD>"
982               "</TD>\n",
983               (pa[i].type == etBOOL)?"-[no]":"-",pa[i].option+1,
984               argtp[pa[i].type],pa_val(&(pa[i]),tmp,255),NSR(pa[i].desc));
985     fprintf(out,"</TABLE>\n");
986   }
987   if (nbug > 0) {
988     fprintf(out,"<P>\n");
989     fprintf(out,"<H3>Known problems</H3>\n");
990     fprintf(out,"<UL>\n");
991     for(i=0; (i<nbug); i++)
992       fprintf(out,"<LI>%s\n",NSR(bugs[i]));
993     fprintf(out,"</UL>\n");
994   }
995   fprintf(out,"<P>\n");
996   fprintf(out,"<hr>\n<div ALIGN=RIGHT>\n");
997   fprintf(out,"<font size=\"-1\"><a href=\"http://www.gromacs.org\">"
998           "http://www.gromacs.org</a></font><br>\n");
999   fprintf(out,"<font size=\"-1\"><a href=\"mailto:gromacs@gromacs.org\">"
1000           "gromacs@gromacs.org</a></font><br>\n");
1001   fprintf(out,"</div>\n");
1002   fprintf(out,"</BODY>\n");
1003 }
1004
1005 char *check_xml(const char *s,const char *program,t_linkdata *links)
1006 {
1007   char *buf;
1008   
1009   buf=repall(s,NSRXML,sandrXML);
1010   buf=html_xref(buf,program,links,FALSE);       /* the same in html and xml */
1011   
1012   return buf;
1013 }
1014
1015 static void write_xmlman(FILE *out,
1016                          const char *program,
1017                          int nldesc,const char **desc,
1018                          int nfile,t_filenm *fnm,
1019                          int npargs,t_pargs *pa,
1020                          int nbug,const char **bugs,
1021                          t_linkdata *links)
1022 {
1023   int i;
1024   char link[10],buf[256],opt[10];
1025
1026 #define NSR2(s) check_xml(s,program,links)
1027 #define FLAG(w,f) (((w) & (f))==(f)) 
1028
1029   fprintf(out,"<gromacs-manual version=\"%s\" date=\"%s\" www=\"http://www.gromacs.org\">\n",GromacsVersion(),mydate(buf,255,FALSE));
1030   /* fprintf(out,"<LINK rel=stylesheet href=\"style.css\" type=\"text/css\">\n"); */
1031
1032   fprintf(out,"<program name=\"%s\">",program);  
1033   if (nldesc > 0) {
1034     fprintf(out,"\n<description>\n<par>\n");
1035     for(i=0; (i<nldesc); i++) 
1036       fprintf(out,"%s\n",NSR2(desc[i]));
1037   }
1038   fprintf(out,"</par>\n</description>\n");
1039
1040   if (nfile > 0) {
1041     fprintf(out,"\n<files>\n");
1042     for(i=0; (i<nfile); i++) {
1043       strcpy(link,ftp2ext(fnm[i].ftp));
1044       if (strcmp(link,"???")==0)
1045         strcpy(link,"files");
1046         if (fnm[i].opt[0]=='-') strcpy(opt,fnm[i].opt+1);
1047         else strcpy(opt,fnm[i].opt);
1048       fprintf(out,
1049               "<file type=\"%s\" typeid=\"%d\">\n"
1050               "\t<flags read=\"%d\" write=\"%d\" optional=\"%d\"/>\n"
1051               "\t<option>%s</option>\n"
1052               "\t<default-name link=\"%s.html\">%s</default-name>\n"
1053               "\t<description>%s</description>\n"
1054               "</file>\n",
1055               ftp2defnm(fnm[i].ftp),    /* from gmxlib/filenm.c */
1056               fnm[i].ftp,
1057               FLAG(fnm[i].flag,ffREAD), FLAG(fnm[i].flag,ffWRITE), FLAG(fnm[i].flag,ffOPT), 
1058               opt,link,fnm[i].fn,/*fileopt(fnm[i].flag),*/
1059               NSR(ftp2desc(fnm[i].ftp)));
1060     }
1061     fprintf(out,"</files>\n");
1062   }
1063
1064   if (npargs > 0) {
1065     fprintf(out,"\n<options>\n");
1066     for(i=0; (i<npargs); i++)
1067       fprintf(out,
1068               "<option type=\"%s\" hidden=\"%d\">\n"
1069               "\t<name >%s</name>\n"
1070               "\t<default-value>%s</default-value>\n"
1071               "\t<description>%s</description>\n"
1072               "</option>\n",
1073               argtp[pa[i].type], is_hidden(&pa[i]),
1074               pa[i].option+1,                  /* +1 - with no trailing '-' */
1075               pa_val(&(pa[i]),buf,255),pa[i].desc); /*argtp[pa[i].type],*/
1076     fprintf(out,"</options>\n");
1077   }
1078
1079   if (nbug > 0) {
1080     fprintf(out,"\n<bugs>\n");
1081     for(i=0; (i<nbug); i++)
1082       fprintf(out,"\t<bug>%s</bug>\n",NSR(bugs[i]));
1083     fprintf(out,"</bugs>\n");
1084   }
1085   fprintf(out,"\n</program>\n</gromacs-manual>\n");
1086 #undef FLAG  
1087 }
1088
1089 static void pr_opts(FILE *fp, 
1090                     int nfile,  t_filenm *fnm, 
1091                     int npargs, t_pargs pa[], int shell)
1092 {
1093   int i;
1094   
1095   switch (shell) {
1096   case eshellCSH:
1097     fprintf(fp," \"c/-/(");
1098     for (i=0; i<nfile; i++)
1099       fprintf(fp," %s",fnm[i].opt+1);
1100     for (i=0; i<npargs; i++)
1101       if ( (pa[i].type==etBOOL) && *(pa[i].u.b) )
1102         fprintf(fp," no%s",pa[i].option+1);
1103       else
1104         fprintf(fp," %s",pa[i].option+1);
1105     fprintf(fp,")/\"");
1106     break;
1107   case eshellBASH:
1108     fprintf(fp,"if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W '");
1109     for (i=0; i<nfile; i++)
1110       fprintf(fp," -%s",fnm[i].opt+1);
1111     for (i=0; i<npargs; i++)
1112       if ( (pa[i].type==etBOOL) && *(pa[i].u.b) )
1113         fprintf(fp," -no%s",pa[i].option+1);
1114       else
1115         fprintf(fp," -%s",pa[i].option+1);
1116     fprintf(fp,"' -- $c)); return 0; fi\n");
1117     break;
1118   case eshellZSH:
1119     fprintf(fp," -x 's[-]' -s \"");
1120     for (i=0; i<nfile; i++)
1121       fprintf(fp," %s",fnm[i].opt+1);
1122     for (i=0; i<npargs; i++)
1123       if ( (pa[i].type==etBOOL) && *(pa[i].u.b) )
1124         fprintf(fp," no%s",pa[i].option+1);
1125       else
1126         fprintf(fp," %s",pa[i].option+1);
1127     fprintf(fp,"\" ");
1128     break;
1129   }
1130 }
1131
1132 static void write_cshcompl(FILE *out,
1133                            int nfile,  t_filenm *fnm,
1134                            int npargs, t_pargs *pa)
1135 {
1136   fprintf(out,"complete %s",ShortProgram());
1137   pr_enums(out,npargs,pa,eshellCSH);
1138   pr_fopts(out,nfile,fnm,eshellCSH);
1139   pr_opts(out,nfile,fnm,npargs,pa,eshellCSH);
1140   fprintf(out,"\n");
1141 }
1142
1143 static void write_zshcompl(FILE *out,
1144                            int nfile,  t_filenm *fnm,
1145                            int npargs, t_pargs *pa)
1146 {
1147   fprintf(out,"compctl ");
1148
1149   /* start with options, since they are always present */
1150   pr_opts(out,nfile,fnm,npargs,pa,eshellZSH);
1151   pr_enums(out,npargs,pa,eshellZSH);
1152   pr_fopts(out,nfile,fnm,eshellZSH);
1153   fprintf(out,"-- %s\n",ShortProgram());
1154 }
1155
1156 static void write_bashcompl(FILE *out,
1157                             int nfile,  t_filenm *fnm,
1158                             int npargs, t_pargs *pa)
1159 {
1160   /* Advanced bash completions are handled by shell functions.
1161    * p and c hold the previous and current word on the command line.
1162    * We need to use extended globbing, so write it in each completion file */
1163   fprintf(out,"shopt -s extglob\n");
1164   fprintf(out,"_%s_compl() {\nlocal p c\n",ShortProgram());
1165   fprintf(out,"COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}\n");
1166   pr_opts(out,nfile,fnm,npargs,pa,eshellBASH);
1167   fprintf(out,"case \"$p\" in\n");
1168   
1169   pr_enums(out,npargs,pa,eshellBASH);
1170   pr_fopts(out,nfile,fnm,eshellBASH);
1171   fprintf(out,"esac }\ncomplete -F _%s_compl %s\n",ShortProgram(),ShortProgram());
1172 }
1173
1174 static void write_py(FILE *out,const char *program,
1175                      int nldesc,const char **desc,
1176                      int nfile,t_filenm *fnm,
1177                      int npargs,t_pargs *pa,
1178                      int nbug,const char **bugs,
1179                      t_linkdata *links)
1180 {
1181   gmx_bool bHidden;
1182   const char *cls = program;
1183   char *tmp;
1184   int  i,j;
1185
1186   /* Header stuff */  
1187   fprintf(out,"#!/usr/bin/python\n\nfrom GmxDialog import *\n\n");
1188   
1189   /* Class definition */
1190   fprintf(out,"class %s:\n",cls);
1191   fprintf(out,"    def __init__(self,tk):\n");
1192   
1193   /* Help text */
1194   fprintf(out,"        %s_help = \"\"\"\n",cls);
1195   fprintf(out,"        DESCRIPTION\n");
1196   print_tty_formatted(out,nldesc,desc,8,links,program,FALSE);
1197   if (nbug > 0) {
1198     fprintf(out,"\n        BUGS and PROBLEMS\n");
1199     for(i=0; i<nbug; i++) {
1200       snew(tmp,strlen(bugs[i])+3);
1201       strcpy(tmp,"* ");
1202       strcpy(tmp+2,check_tty(bugs[i]));
1203       fprintf(out,"%s\n",wrap_lines(tmp,78,10,TRUE));
1204       sfree(tmp);
1205     }
1206   }
1207   fprintf(out,"        \"\"\"\n\n        # Command line options\n");
1208   /* File options */
1209   fprintf(out,"        flags = []\n");
1210   for(i=0; (i<nfile); i++) 
1211     fprintf(out,"        flags.append(pca_file('%s',\"%s\",0,%d))\n",
1212             ftp2ext_generic(fnm[i].ftp),fnm[i].opt ? fnm[i].opt : "k",
1213             is_optional(&(fnm[i])));
1214             
1215             
1216   /* Other options */
1217   for(i=0; (i<npargs); i++) {
1218     switch(pa[i].type) {
1219     case etINT:
1220       fprintf(out,"        flags.append(pca_int(\"%s\",\"%s\",%d,%d))\n",
1221               pa[i].option,pa[i].desc,*pa[i].u.i,is_hidden(&(pa[i])));
1222       break;
1223     case etREAL:
1224     case etTIME:
1225       fprintf(out,"        flags.append(pca_float(\"%s\",\"%s\",%f,%d))\n",
1226               pa[i].option,pa[i].desc,*pa[i].u.r,is_hidden(&(pa[i])));
1227       break;
1228     case etSTR:
1229     case etBOOL:
1230       fprintf(out,"        flags.append(pca_gmx_bool(\"%s\",\"%s\",%d,%d))\n",
1231               pa[i].option,pa[i].desc,*pa[i].u.b,is_hidden(&(pa[i])));
1232       break;
1233     case etRVEC:
1234       fprintf(stderr,"Sorry, no rvecs yet...\n");
1235       break;
1236     case etENUM:
1237       fprintf(out,"        flags.append(pca_enum(\"%s\",\"%s\",\n",
1238               pa[i].option,pa[i].desc);
1239       fprintf(out,"        ['%s'",pa[i].u.c[1]);
1240       for(j=2; (pa[i].u.c[j] != NULL); j++)
1241         fprintf(out,",'%s'",pa[i].u.c[j]);
1242       fprintf(out,"],%d))\n",is_hidden(&(pa[i])));
1243       break;
1244     default:
1245       break;
1246     }
1247   }
1248     
1249   /* Make the dialog box */
1250   fprintf(out,"        gmxd = gmx_dialog(tk,\"%s\",flags,%s_help)\n\n",
1251           cls,cls);
1252           
1253   /* Main loop */
1254   fprintf(out,"#####################################################\n");
1255   fprintf(out,"tk     = Tk()\n");
1256   fprintf(out,"my%s = %s(tk)\n",cls,cls);
1257   fprintf(out,"tk.mainloop()\n");
1258 }
1259
1260 void write_man(FILE *out,const char *mantp,
1261                const char *program,
1262                int nldesc,const char **desc,
1263                int nfile,t_filenm *fnm,
1264                int npargs,t_pargs *pa,
1265                int nbug,const char **bugs,
1266                gmx_bool bHidden)
1267 {
1268   const char *pr;
1269   int     i,npar;
1270   t_pargs *par;
1271  
1272   t_linkdata *links;
1273   
1274   links=init_linkdata();
1275   
1276   /* Don't write hidden options to completions, it just
1277    * makes the options more complicated for normal users
1278    */
1279
1280   if (bHidden) {
1281     npar=npargs;
1282     par=pa;
1283   }
1284   else {
1285     snew(par,npargs);
1286     npar=0;
1287     for(i=0;i<npargs;i++)
1288       if (!is_hidden(&pa[i])) {
1289         par[npar]=pa[i];
1290         npar++;
1291       }
1292   }
1293   
1294   if ((pr=strrchr(program,DIR_SEPARATOR)) == NULL)
1295     pr=program;
1296   else
1297     pr+=1;
1298   if (strcmp(mantp,"tex")==0)
1299     write_texman(out,pr,nldesc,desc,nfile,fnm,npar,par,nbug,bugs,links);
1300   if (strcmp(mantp,"nroff")==0)
1301     write_nroffman(out,pr,nldesc,desc,nfile,fnm,npar,par,nbug,bugs,links);
1302   if (strcmp(mantp,"ascii")==0)
1303     write_ttyman(out,pr,nldesc,desc,nfile,fnm,npar,par,nbug,bugs,TRUE,links);
1304   if (strcmp(mantp,"wiki")==0)
1305     write_wikiman(out,pr,nldesc,desc,nfile,fnm,npar,par,nbug,bugs,TRUE,links);
1306   if (strcmp(mantp,"help")==0)
1307     write_ttyman(out,pr,nldesc,desc,nfile,fnm,npar,par,nbug,bugs,FALSE,links);
1308   if (strcmp(mantp,"html")==0)
1309     write_htmlman(out,pr,nldesc,desc,nfile,fnm,npar,par,nbug,bugs,links);
1310   if (strcmp(mantp,"py")==0)
1311     write_py(out,pr,nldesc,desc,nfile,fnm,npar,par,nbug,bugs,links);
1312   if (strcmp(mantp,"xml")==0)
1313     write_xmlman(out,pr,nldesc,desc,nfile,fnm,npargs,pa,nbug,bugs,links);       
1314   if (strcmp(mantp,"completion-zsh")==0)
1315     write_zshcompl(out,nfile,fnm,npar,par);
1316   if (strcmp(mantp,"completion-bash")==0)
1317     write_bashcompl(out,nfile,fnm,npar,par);
1318   if (strcmp(mantp,"completion-csh")==0)
1319     write_cshcompl(out,nfile,fnm,npar,par);
1320
1321   if (!bHidden)
1322     sfree(par);
1323
1324   finish_linkdata(links);
1325 }
1326