3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
30 * For more info, check our website at http://www.gromacs.org
33 * GROningen Mixture of Alchemy and Childrens' Stories
38 #include "gromacs/utility/gmx_header_config.h"
44 #include "gromacs/utility/exceptions.h"
45 #include "gromacs/utility/stringutil.h"
47 #include "gmx_fatal.h"
59 /* The source code in this file should be thread-safe.
60 Please keep it that way. */
64 const char *search,*replace;
68 char *search,*replace;
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. */
76 const t_sandr_const sandrTeX[] = {
84 /* Escaping underscore for LaTeX is no longer necessary, and it breaks
85 * text searching and the index if you do. */
90 { "<=", "\\ensuremath{\\leq{}}"},
91 { ">=", "\\ensuremath{\\geq{}}"},
92 { "<", "\\textless{}" },
93 { ">", "\\textgreater{}" },
95 { "\\^{}t", "\\ensuremath{^t}" },
96 { "\\^{}a", "\\ensuremath{^a}" },
97 { "\\^{}b", "\\ensuremath{^b}" },
98 { "\\^{}2", "\\ensuremath{^2}" },
99 { "\\^{}3", "\\ensuremath{^3}" },
100 { "\\^{}6", "\\ensuremath{^6}" },
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{\\" },
109 { "[MATH]","\\ensuremath{" },
111 { "[CHEVRON]", "\\ensuremath{<}" },
112 { "[chevron]", "\\ensuremath{>}" },
113 { "[MAG]", "\\ensuremath{|}" },
114 { "[mag]", "\\ensuremath{|}" },
115 { "[INT]","\\ensuremath{\\int" },
121 { "[SUM]","\\ensuremath{\\sum" },
123 { "[SUB]","\\ensuremath{_{" },
125 { "[SQRT]","\\ensuremath{\\sqrt{" },
127 { "[EXP]","\\ensuremath{\\exp{(" },
129 { "[LN]","\\ensuremath{\\ln{(" },
131 { "[LOG]","\\ensuremath{\\log{(" },
133 { "[COS]","\\ensuremath{\\cos{(" },
135 { "[SIN]","\\ensuremath{\\sin{(" },
137 { "[TAN]","\\ensuremath{\\tan{(" },
139 { "[COSH]","\\ensuremath{\\cosh{(" },
141 { "[SINH]","\\ensuremath{\\sinh{(" },
143 { "[TANH]","\\ensuremath{\\tanh{(" },
146 #define NSRTEX asize(sandrTeX)
148 const t_sandr_const sandrTty[] = {
161 { "[INT]","integral" },
162 { "[FROM]"," from " },
171 { "[SQRT]","sqrt(" },
185 { "[COSH]","cosh(" },
187 { "[SINH]","sinh(" },
189 { "[TANH]","tanh(" },
196 #define NSRTTY asize(sandrTty)
198 const t_sandr_const sandrWiki[] = {
202 { "[TT]", "<code>" },
203 { "[tt]", "</code>" },
214 { "[INT]","integral" },
215 { "[FROM]"," from " },
224 { "[SQRT]","sqrt(" },
238 { "[COSH]","cosh(" },
240 { "[SINH]","sinh(" },
242 { "[TANH]","tanh(" },
249 #define NSRWIKI asize(sandrWiki)
251 const t_sandr_const sandrNROFF[] = {
264 { "[INT]","integral" },
265 { "[FROM]"," from " },
274 { "[SQRT]","sqrt(" },
288 { "[COSH]","cosh(" },
290 { "[SINH]","sinh(" },
292 { "[TANH]","tanh(" },
305 #define NSRNROFF asize(sandrNROFF)
307 const t_sandr_const sandrHTML[] = {
322 { "[INT]","integral" },
323 { "[FROM]"," from " },
332 { "[SQRT]","sqrt(" },
346 { "[COSH]","cosh(" },
348 { "[SINH]","sinh(" },
350 { "[TANH]","tanh(" },
357 #define NSRHTML asize(sandrHTML)
359 const t_sandr_const sandrXML[] = {
363 { "[tt]", "</arg>" },
365 { "[bb]", "</emp>" },
374 { "[INT]","integral" },
375 { "[FROM]"," from " },
384 { "[SQRT]","sqrt(" },
398 { "[COSH]","cosh(" },
400 { "[SINH]","sinh(" },
402 { "[TANH]","tanh(" },
404 { "[PAR]","</par>\n<par>" },
405 { "[BR]", "<br />" },
409 #define NSRXML asize(sandrXML)
411 static void mynum(char *buf,int n)
414 sprintf(buf,"%2d",n);
416 sprintf(buf,"0%1d",n);
419 static char *mydate(char buf[], int maxsize,gmx_bool bWiki)
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" };
428 #ifdef GMX_NATIVE_WINDOWS
430 localtime_s(&tm,&now);
432 localtime_r(&now,&tm);
435 /* subtract one from maxsize, so we have room for \0. */
437 char dd[8],mm[8],ss[8],hh[8],mn[8];
439 mynum(dd,tm.tm_mday);
442 mynum(hh,tm.tm_hour);
444 sprintf(buf,"%4d-%2s-%2sT%2s:%2s:%2sZ",
445 tm.tm_year+1900,mm,dd,hh,mn,ss);
448 sprintf(buf,"%s %d %s %d",day[tm.tm_wday],tm.tm_mday,
449 mon[tm.tm_mon],tm.tm_year+1900);
454 /* Data structure for saved HTML links */
455 typedef struct t_linkdata {
460 static t_linkdata *init_linkdata()
470 static void finish_linkdata(t_linkdata *p)
474 for(i=0;i<p->nsr;i++) {
475 sfree(p->sr[i].search);
476 sfree(p->sr[i].replace);
482 static char *repall(const char *s,int nsr,const t_sandr_const sa[])
486 std::string result(s);
487 for (int i = 0; i < nsr; ++i)
489 result = gmx::replaceAll(result, sa[i].search, sa[i].replace);
491 return gmx_strdup(result.c_str());
493 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
496 static char *repallww(const char *s,int nsr,const t_sandr sa[])
500 std::string result(s);
501 for (int i = 0; i < nsr; ++i)
503 result = gmx::replaceAllWords(result, sa[i].search, sa[i].replace);
505 return gmx_strdup(result.c_str());
507 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
510 static char *html_xref(char *s,const char *program, t_linkdata *links,gmx_bool bWiki)
512 char buf[256],**filestr;
515 if (links->sr == NULL) {
516 n=get_file("links.dat",&(filestr));
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]);
523 sprintf(buf,"[[%s]]",filestr[i]);
525 sprintf(buf,"<a href=\"%s.html\">%s</a>",filestr[i],filestr[i]);
526 links->sr[j].replace=gmx_strdup(buf);
535 return repallww(s,links->nsr,links->sr);
538 char *check_tex(const char *s)
540 return repall(s,NSRTEX,sandrTeX);
543 static char *check_nroff(const char *s)
545 return repall(s,NSRNROFF,sandrNROFF);
548 static char *check_wiki(const char *s,const char *program, t_linkdata *links)
552 buf = repall(s,NSRWIKI,sandrWiki);
553 buf = html_xref(buf,program,links,TRUE);
558 static char *check_html(const char *s,const char *program, t_linkdata *links)
562 buf = repall(s,NSRHTML,sandrHTML);
563 buf = html_xref(buf,program,links,FALSE);
568 #define NWR(s) check_wiki(s,program,links)
569 #define NSR(s) check_html(s,program,links)
571 #define FLAG_SET(flag, mask) ((flag & mask) == mask)
572 char *fileopt(unsigned long flag,char buf[],int maxsize)
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");
583 sprintf(tmp,"Dunno");
585 if (FLAG_SET(flag, ffOPT)) {
587 if (FLAG_SET(flag, ffSET))
592 if (FLAG_SET(flag, ffLIB))
593 strcat(tmp,", Lib.");
594 if (FLAG_SET(flag, ffMULT))
595 strcat(tmp,", Mult.");
597 sprintf(buf,"%s",tmp);
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,
612 fprintf(out,"\\section{\\normindex{%s}}\\label{%s}\n\n",check_tex(program),check_tex(program));
615 for(i=0; (i<nldesc); i++)
616 fprintf(out,"%s\n",check_tex(desc[i]));
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");
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));
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));
651 fprintf(out,"\\end{tabbing}\\vspace{-4ex}\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");
660 /* fprintf(out,"\n\\newpage\n"); */
663 static void write_nroffman(FILE *out,
665 int nldesc,const char **desc,
666 int nfile,t_filenm *fnm,
667 int npargs,t_pargs *pa,
668 int nbug,const char **bugs,
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());
681 fprintf(out,".SH SYNOPSIS\n");
682 fprintf(out,"\\f3%s\\fP\n",program);
684 /* command line arguments */
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]));
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));
695 fprintf(out,".BI \"%s\" \" %s \"\n",check_nroff(pa[i].option),
696 check_nroff(get_arg_desc(pa[i].type)));
701 fprintf(out,".SH DESCRIPTION\n");
702 for(i=0; (i<nldesc); i++)
703 fprintf(out,"\\&%s\n",check_nroff(desc[i]));
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)));
718 fprintf(out,".SH OTHER OPTIONS\n");
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));
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));
736 fprintf(out,".SH KNOWN PROBLEMS\n");
737 for(i=0; (i<nbug); i++)
738 fprintf(out,"\\- %s\n\n",check_nroff(bugs[i]));
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");
746 char *check_tty(const char *s)
748 return repall(s,NSRTTY,sandrTty);
752 print_tty_formatted(FILE *out, int nldesc, const char **desc,int indent,
753 t_linkdata *links,const char *program,gmx_bool bWiki)
761 for(i=0; (i<nldesc); i++) {
762 if ((strlen(buf)>0) &&
763 (buf[strlen(buf)-1] !=' ') && (buf[strlen(buf)-1] !='\n'))
768 temp=check_tty(desc[i]);
769 if (strlen(buf) + strlen(temp) >= (size_t)(buflen-2)) {
770 buflen += strlen(temp);
776 /* Make lines of at most 79 characters */
777 temp = wrap_lines(buf,78,indent,FALSE);
778 fprintf(out,"%s\n",temp);
783 static void write_ttyman(FILE *out,
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,
796 fprintf(out,"%s\n\n",check_tty(program));
797 fprintf(out,"%s\n%s\n",GromacsVersion(),mydate(buf,255,FALSE));
800 fprintf(out,"DESCRIPTION\n-----------\n");
801 print_tty_formatted(out,nldesc,desc,0,links,program,FALSE);
805 fprintf(out,"KNOWN PROBLEMS\n----------\n");
806 for(i=0; i<nbug; i++) {
807 snew(tmp,strlen(bugs[i])+3);
809 strcpy(tmp+2,check_tty(bugs[i]));
810 fprintf(out,"%s\n",wrap_lines(tmp,78,2,FALSE));
816 pr_fns(out,nfile,fnm);
819 print_pargs(out,npargs,pa,FALSE);
823 static void pr_html_files(FILE *out,int nfile,t_filenm fnm[],
824 const char *program,t_linkdata *links,gmx_bool bWiki)
827 char link[10],tmp[255];
830 fprintf(out," %-10s %-12s %-12s %-s\n"
831 " -----------------------------------------------------\n",
832 "Option","Filename","Type","Description");
835 "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
840 "<TH>description</TH>"
843 for(i=0; (i<nfile); i++) {
844 strcpy(link,ftp2ext(fnm[i].ftp));
845 if (strcmp(link,"???")==0)
846 strcpy(link,"files");
848 fprintf(out," %-10s %-16s %-12s %-s\n",
851 fileopt(fnm[i].flag,tmp,255),
852 NWR(ftp2desc(fnm[i].ftp)));
856 "<TD ALIGN=RIGHT> <b><tt>%s</tt></b> </TD>"
857 "<TD ALIGN=RIGHT> <tt><a href=\"%s.html\">%12s</a></tt> </TD>"
861 fnm[i].opt,link,fnm[i].fns[0],fileopt(fnm[i].flag,tmp,255),
862 NSR(ftp2desc(fnm[i].ftp)));
865 fprintf(out,"</TABLE>\n");
868 static void write_wikiman(FILE *out,
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,
879 fprintf(out,"<page>\n<title>Manual:%s_%s</title>\n",program,
881 fprintf(out,"<revision>\n");
882 fprintf(out,"<timestamp>%s</timestamp>\n",mydate(buf,255,TRUE));
883 fprintf(out,"<text xml:space=\"preserve\">\n");
885 fprintf(out,"== Description ==\n");
886 print_tty_formatted(out,nldesc,desc,0,links,program,TRUE);
890 fprintf(out,"== Known Problems ==\n");
891 for(i=0; i<nbug; i++) {
892 snew(tmp,strlen(bugs[i])+3);
894 strcpy(tmp+2,bugs[i]);
895 fprintf(out,"%s\n",NWR(tmp));
900 fprintf(out,"\n== Files ==\n");
901 pr_html_files(out,nfile,fnm,program,links,TRUE);
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);
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");
920 static void write_htmlman(FILE *out,
922 int nldesc,const char **desc,
923 int nfile,t_filenm *fnm,
924 int npargs,t_pargs *pa,
925 int nbug,const char **bugs,
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));
946 fprintf(out,"<H3>Description</H3>\n<p>\n");
947 for(i=0; (i<nldesc); i++)
948 fprintf(out,"%s\n",NSR(desc[i]));
951 fprintf(out,"<P>\n");
952 fprintf(out,"<H3>Files</H3>\n");
953 pr_html_files(out,nfile,fnm,program,links,FALSE);
956 fprintf(out,"<P>\n");
957 fprintf(out,"<H3>Other options</H3>\n");
959 "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=2>\n"
964 "<TH>description</TH>"
966 for(i=0; (i<npargs); i++)
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>"
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");
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");
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");
996 char *check_xml(const char *s,const char *program,t_linkdata *links)
1000 buf=repall(s,NSRXML,sandrXML);
1001 buf=html_xref(buf,program,links,FALSE); /* the same in html and xml */
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,
1015 char link[10],buf[256],opt[10];
1017 #define NSR2(s) check_xml(s,program,links)
1018 #define FLAG(w,f) (((w) & (f))==(f))
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"); */
1023 fprintf(out,"<program name=\"%s\">",program);
1025 fprintf(out,"\n<description>\n<par>\n");
1026 for(i=0; (i<nldesc); i++)
1027 fprintf(out,"%s\n",NSR2(desc[i]));
1029 fprintf(out,"</par>\n</description>\n");
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);
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"
1046 ftp2defnm(fnm[i].ftp), /* from gmxlib/filenm.c */
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)));
1052 fprintf(out,"</files>\n");
1056 fprintf(out,"\n<options>\n");
1057 for(i=0; (i<npargs); i++)
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"
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");
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");
1076 fprintf(out,"\n</program>\n</gromacs-manual>\n");
1080 static void pr_opts(FILE *fp,
1081 int nfile, t_filenm *fnm,
1082 int npargs, t_pargs pa[], int shell)
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);
1095 fprintf(fp," %s",pa[i].option+1);
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);
1106 fprintf(fp," -%s",pa[i].option+1);
1107 fprintf(fp,"' -- $c)); return 0; fi\n");
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);
1117 fprintf(fp," %s",pa[i].option+1);
1123 static void write_cshcompl(FILE *out,
1124 int nfile, t_filenm *fnm,
1125 int npargs, t_pargs *pa)
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);
1134 static void write_zshcompl(FILE *out,
1135 int nfile, t_filenm *fnm,
1136 int npargs, t_pargs *pa)
1138 fprintf(out,"compctl ");
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());
1147 static void write_bashcompl(FILE *out,
1148 int nfile, t_filenm *fnm,
1149 int npargs, t_pargs *pa)
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");
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());
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,
1172 const char *cls = program;
1177 fprintf(out,"#!/usr/bin/python\n\nfrom GmxDialog import *\n\n");
1179 /* Class definition */
1180 fprintf(out,"class %s:\n",cls);
1181 fprintf(out," def __init__(self,tk):\n");
1184 fprintf(out," %s_help = \"\"\"\n",cls);
1185 fprintf(out," DESCRIPTION\n");
1186 print_tty_formatted(out,nldesc,desc,8,links,program,FALSE);
1188 fprintf(out,"\n BUGS and PROBLEMS\n");
1189 for(i=0; i<nbug; i++) {
1190 snew(tmp,strlen(bugs[i])+3);
1192 strcpy(tmp+2,check_tty(bugs[i]));
1193 fprintf(out,"%s\n",wrap_lines(tmp,78,10,TRUE));
1197 fprintf(out," \"\"\"\n\n # Command line options\n");
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])));
1207 for(i=0; (i<npargs); i++) {
1208 switch(pa[i].type) {
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])));
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])));
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])));
1224 fprintf(stderr,"Sorry, no rvecs yet...\n");
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])));
1239 /* Make the dialog box */
1240 fprintf(out," gmxd = gmx_dialog(tk,\"%s\",flags,%s_help)\n\n",
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");
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,
1264 links=init_linkdata();
1266 /* Don't write hidden options to completions, it just
1267 * makes the options more complicated for normal users
1277 for(i=0;i<npargs;i++)
1278 if (!is_hidden(&pa[i])) {
1284 if ((pr=strrchr(program,DIR_SEPARATOR)) == NULL)
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);
1314 finish_linkdata(links);
1317 const char *get_arg_desc(int type) {
1318 static const char *argtp[etNR] = {
1319 "int", "step", "real", "time", "string", "bool", "vector", "enum"