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