Skip to content
Snippets Groups Projects
manpages 7.33 KiB
Newer Older
  • Learn to ignore specific revisions
  • // -*- Pike -*-
    
    // $Id: manpages,v 1.26 2000/02/29 20:35:12 neotron Exp $
    
    
    #if __VERSION__ >= 0.6
    import ".";
    #endif /* __VERSION__ >= 0.6 */
    
    
    int verbose = 0;
    
    
    string globalbase;
    object windex;
    
    object whatis;
    
    // Conversion table:
    //
    // "*"		"\\(**"
    // "\\"		"\\e"
    // "()"		"(\\|)"
    // " - "	" \\- "
    
    // "..."	"\\&.\\|.\\|."
    // ".."		"\\&.\\|"
    
      s=replace(s,({">","&","<"}),
    	    ({">","&","<"}));
    
      return(replace(s, ({ "*", "\\", "()", " - ", "...", ".." }),
    		 ({ "\\(**", "\\e", "(\\|)", " \\- ",
    		    "\\&.\\|.\\|.", "\\&.\\|." })));
    
    }
    
    // Some versions of nroff don't like 8-bit chars at all.
    string strip_eightbit(string s)
    {
      return(s & String.strmult("\177", sizeof(s)));
    }
    
    string strip_empty_lines(string s)
    {
      return(Array.filter(s/"\n", lambda(string line) {
    				return(replace(line,
    					       ({ "\t", " " }),
    					       ({ "", "" })) != "");
    			      })*"\n");
    }
    
    void make_page(string base, TAG tag, string ind, string fbase);
    
    void mkdirhier(string what)
    {
       string d=".";
       foreach (what/"/",string add)
       {
          d+="/"+add;
          mkdir(d);
       }
    }
    
    
    int stripws=1;
    
    
    string make_manpage(string base, string|SGML data, string ind, string fbase)
    
    
      if (verbose) {
    
        werror(sprintf("data:%O, stripws:%d\n", data, stripws));
    
        if (sizeof(data)) {
          if (stripws) {
    	string d2 = data;
    	sscanf(data,"%*[ \t\n\r]%s",data);
    	if (stripws == -1) {
    	  stripws = 1;
    	  if (d2[0] == ' ') {
    	    // Keep a single whitespace.
    	    data = " " + data;
    	  }
    	}
          }
          res+=quote_text(data);
    
      } else if(arrayp(data)) {
    
        int n;
        for (n = 0; n < sizeof(data); n++) {
          TAG tag = data[n];
          if (stripws && n) {
    	// Keep a single whitespace between tags.
    	stripws = -1;
          }
    
    	if (verbose) {
    	  werror(sprintf("tag:%O, params:%O\n", tag->tag, tag->params));
    	}
    
    	switch (tag->tag) {
    	case "method":
    	case "function":
    	case "constant":
    	case "class":
    	case "module":
    	case "variable":
    	  make_page(base,tag,ind,fbase);
    	  continue;
    
    	case "man_title":
    
    	  res+="\n.SH "+quote_text(tag->params->title)+"\n";
    
    	case "aarg":
    	  stripws = 1;
    	  res += "\n.br\n\\fB"+make_manpage(base,tag->data,ind,fbase)+"\\fR";
    	  continue;
    
    	case "adesc":
    	  stripws = 1;
    	  res += "\n.br\n.in +.8i .ll -.8i\n"+make_manpage(base,tag->data,ind,fbase) +"\n.in -.8i .ll +.8i\n";
    	  continue;
    	  
    
    	case "p":
    	  res+="\n.PP\n";
    	  stripws=1;
    	  break;
    	case "br":
    
    	case "ex_br":
    
    	  if (tag->params->keep_ws) {
    	    stripws = 0;
    	  } else {
    	    stripws=1;
    	  }
    
    	case "ex_indent":
    	  res += "  ";
    	  continue;
    
    
    	case "link":
    	case "i": 
    	case "emboss":
    
    	  res+="\\f2"+make_manpage(base,tag->data,ind,fbase)+"\\f1";
    	  continue;
    
    	case "b": 
    	case "strong":
    
    	case "ex_keyword":
    
    	  res+="\\f3"+make_manpage(base,tag->data,ind,fbase)+"\\f1";
    	  continue;
    
    
    	case "tt":
    
    	  int ows = stripws;
    	  stripws = 0;
    	  // Should specify a fixed width font.
    	  res += make_manpage(base,tag->data,ind,fbase);
    	  stripws = ows;
    	  continue;
    
    	case "pre":
    
    	case "example":
    	  int ows = stripws;
    
    	  // Ought to specify a fixed width font.
    
    	  res+="\n.nf\n"+
    	    make_manpage(base,tag->data,ind,fbase)+
    	    "\n.fi\n";
    	  stripws = ows;
    
    	res+=make_manpage(base,tag->data,ind,fbase);
          } else if (stringp(tag)) {
    
    	if (sizeof(tag)) {
    	  if (stripws) {
    	    string t2 = tag;
    	    sscanf(tag,"%*[ \t\n\r]%s",tag);
    	    if (stripws == -1) {
    	      stripws = 1;
    	      if (t2[0] == ' ') {
    		// Keep a single whitespace.
    		tag = " " + tag;
    	      }
    	    }
    	  }
    	  res+=quote_text(tag);
    	}
    
    Mirar (Pontus Hagland)'s avatar
    Mirar (Pontus Hagland) committed
    int pages=0;
    
    
    void make_page(string base, TAG tag, string ind, string fbase)
    {
    
    Mirar (Pontus Hagland)'s avatar
    Mirar (Pontus Hagland) committed
    //   werror(ind+tag->tag+" "+tag->params->name+"\n");
     
       werror("manpage "+(++pages)+"...\r");
    
       mixed err = catch {
    
         string *outfiles,*names,*s_outfiles;
         string obase=base;
         string q;
    
         //     werror(sprintf("%s %s %s %s \n", tag->params->name, fbase, globalbase, base));
    
         outfiles=Array.map(names=tag->params->name/",",
    			lambda(string s,string t,string u,string base)
    			{
    			  s=replace(s,"->",".");
    
    			  // We want the man pages to be Image.image.foo for example... a man page for "create" is kinda uninteresting...
    			  //			  sscanf(s,t+".%s",s);
    
    			  return u+"/"+s+"."+base;
    
         // verbose = (names[0] == "Stdio.sendfile");
    
         sscanf(outfiles[0],"%*s/man%*s/%s",q);
         if (q) {
           array(string) a = q/".";
           if (sizeof(a) > 1) {
    	 q = a[..sizeof(a)-2]*".";
           }
    
    Mirar (Pontus Hagland)'s avatar
    Mirar (Pontus Hagland) committed
    //   werror("files: "+outfiles*", "+"\n");
    
         if (tag->params->mansuffix)
         {
           base+=tag->params->mansuffix;
           fbase=(tag->params->name/",")[0];
    
           //       mkdirhier(globalbase+base);
    
         // verbose = ((names*",") == "Thread.Mutex");
    
         string page=strip_empty_lines(make_manpage(base,tag->data,ind+" ",fbase));
    
         //     werror("creating "+outfiles[0]+"...\n"); 
       
    
         object f=Stdio.File(outfiles[0],"wtc");
         string t=ctime(time());
         f->write(strip_eightbit(".\\\" t\n"
    			     ".\\\" automatically generated from wmml\n"
    
    Henrik (Grubba) Grubbström's avatar
    Henrik (Grubba) Grubbström committed
    			     ".TH " + names*"," + " " + upper_case(obase) +
    			     " \"" + t[8..9] + t[3..7] + t[20..23] + "\""
    
    			     " Pike \"Pike Manual\" Pike\n" +
    
    Henrik (Grubba) Grubbström's avatar
    Henrik (Grubba) Grubbström committed
    			     page + "\n"));
    
         f->close();
    
         foreach (outfiles[1..], string s)
         {
           string name;
           sscanf(outfiles[0], "man/%s", name);
    
           //     werror("creating "+s+" -> "+name+"...\n"); 
    
           object f=Stdio.File(s, "wtc");
           f->write(".so "+name+"\n");
           f->close();
         }
    
         foreach (({q})+names, string s) {
           windex->write(sprintf("%-15s %-15s - %s\n",
    			     s,q+" ("+obase+")",
    			     tag->params->title || (names*", ")));
    
    Henrik (Grubba) Grubbström's avatar
    Henrik (Grubba) Grubbström committed
           whatis->write(sprintf("%-23s - %s\n", s  + " (" + obase + ")",
    
    			     tag->params->title || (names*", ")));
         }
       
    
    Mirar (Pontus Hagland)'s avatar
    Mirar (Pontus Hagland) committed
       };
    
       if (err) {
         werror("Error while making manpage for "+tag->name+" ("+base+"):\n"
    	    +master()->describe_backtrace(err));
       }
    
    }
    
    void make_pages(string base, SGML data, string ind, string fbase)
    {
       if (arrayp(data))
          foreach (data, TAG tag)
    	 if (objectp(tag))
    	    if ((<"method","function","class","module">)[tag->tag])
    	       make_page(base,tag,ind,fbase);
    	    else
    	       make_pages(base,tag->data,ind,fbase);
    }
    
    void output(string base, WMML data)
    {
    
       globalbase="man/man3";
       //   mkdirhier("man/man3p");
       mkdirhier("man/man3");
    
       windex=Stdio.File("man/windex", "wtc");
       whatis=Stdio.File("man/whatis", "wtc");
    
       //   make_pages("3p", data->data, "", "");
    
       make_pages("3p", data->data, "", "");
       werror("\n");
    
       // Used by Xman.
       // NB The Xman(1) man-page describes only the old file-format.
       // The format is either (old format)
       //   <section suffix (one char)><section name><lf>
       // or
       //   <section suffix><tab><section name>[<tab>suffix|fold|foldsuffix]<lf>
       // The latter is the only one usable for us.
       object mandesc = Stdio.File("man/mandesc", "wtc");
       mandesc->write("3p\t(3P) Pike Library Functions\n"
    		  "3pi\t(3PI) Pike Image Module\n"
    		  "3pii\t(3PII) Pike Image.image Class\n");
       mandesc->close();
    
    Sgml.Tag|string illustration(object o, mapping|void options)
    {
      return "";
    }
    
    Sgml.Tag|string illustration_jpeg(object o, mapping|void options)
    {
      return "";
    }