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