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