;;; mandefs.mhtml: -*- Meta-HTML -*-  DESCRIPTIVE TEXT.

;;;  Copyright (c) 1996 Brian J. Fox
;;;  Author: Brian J. Fox (bfox@ai.mit.edu) Wed Jul  3 12:09:01 1996.

<defun metahtml::function-db>
  <get-var mhtml::include-prefix mhtml::relative-prefix>/functions.db
</defun>

<defun metahtml::section-db>
  <get-var mhtml::include-prefix mhtml::relative-prefix>/sections.db
</defun>

<defsubst var>
  <i><b><small-caps lower="+0">%body</small-caps></b></i>
</defsubst>

<defmacro example whitespace=delete>
  <ifeq "%0" "code" "<set-var fmt=code>" "<set-var fmt=pre>">
<<get-var fmt>><verbatim quote>%body</verbatim></<get-var fmt>>
</defmacro>

<defmacro complete-example>
<example>
%body
</example>

produces:

<pre>%body</pre>
<p>
</defmacro>

;;; Use <nb [documentation]> for a Nota Bene.
<defun nb>
  <table>
    <tr valign=top>
      <td align=right><font size="-1"><i>Note:</i></font></td>
      <td align=left>
	<font size="-1">
	<plain-text nobr=true>
	  %body
	</plain-text>
	</font>
      </td>
    </tr>
  </table>
</defun>

<set-var preferred-section-order[]="
Variables
Arrays
Packages
Flow Control
Arithmetic Operators
Relational Operators
String Operators
Block Commands
Page Operators
File Operators
Stream Operators
Session Operators
DBM Commands
Database Commands
Msql Database Extensions
Odbc Database Extensions
Language Operators
Macro Commands
Page Variables
Server Variables">

<set-var alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ">

<defun section-sorter section>
  <set-var section=<capitalize <subst-in-string <get-var section> "-" " ">>>
  <set-var i=0 done="">
  <while <and <get-var default::preferred-section-order[i]>
	      <not <get-var done>>>>
    <if <string-eq <get-var section>
		   <get-var default::preferred-section-order[i]>>
	<set-var done = true>
      <increment i>>
  </while>
  <substring <get-var default::alpha> <get-var i> <add i 1>>
</defun>

<defsubst section::get-sections>
  <with-open-database db <metahtml::section-db> mode=read>
    <database-query db true keys=sections>
  </with-open-database>
  <sort sections section-sorter>
</defsubst>

<defun manpage-url arg>
  <if <get-var default::hacking-frames>
      <set-var page=man-page-frame.mhtml>
    <set-var page=man-page.mhtml>>
  <if <get-var arg>
      <prog
	<set-var key=<get-var arg>>
	<set-var extra="?<cgi-encode key>">>>
  <get-var mhtml::url-to-dir>/<get-var page extra>
</defun>

<defun secpage-url arg>
  <if <get-var default::hacking-frames>
      <set-var page=view-section-frame.mhtml>
    <set-var page=view-section.mhtml>>
  <if <get-var arg>
      <prog
	<set-var key=<get-var arg>>
	<set-var extra="?<cgi-encode key>">>>
  <get-var mhtml::url-to-dir>/<get-var page extra>
</defun>

<defun funindex-url>
  <if <get-var default::hacking-frames>
      <set-var page=function-index-frame.mhtml>
    <set-var page=function-index.mhtml>>
  <get-var mhtml::url-to-dir>/<get-var page>
</defun>

<defun varindex-url>
  <if <get-var default::hacking-frames>
      <set-var page=variable-index-frame.mhtml>
    <set-var page=variable-index.mhtml>>
  <get-var mhtml::url-to-dir>/<get-var page>
</defun>

<defun funref section function>
  <a href="<manpage-url <get-var function>>">
    <code><get-var function></code>
  </a>
</defun>

<defun secref>
  <set-var section =
    <upcase <subst-in-string %qbody "^[ \t]+" "" "[ \t]+$" "" " +" "-">>>
  <concat
   <a href="<secpage-url <get-var section>>">
   <capitalize <subst-in-string <get-var section> "-" " ">>
   </a>>
</defun>

<defun varref varname>
  <concat
   <a href="<manpage-url <get-var varname>>">
   <code><get-var varname></code>
   </a>>
</defun>

;;; Okay, here is one that lays out a table according to number of columns,
;;; but listing each item vertically.  The number of items to each column
;;; is determined dividing the total number of items by the number of
;;; desired columns.
<defun vertical-table array-name width link extra-link-info>
  <set-var array[]=<get-var-once <get-var array-name>[]>>
  <set-var size=<prog <set-var x[]=<symbol-info array>> <get-var x[1]>>>
  <set-var limit=<div size <or <get-var width> 1>>>
  <set-var leftover = <sub size <mul limit <or <get-var width> 1>>>>

  <set-var i=0 limits[]="">
  <while <lt i width>>
    <set-var limits[i]=<get-var limit>>
    <increment i>
  </while>

  <set-var i=0>
  <while <gt leftover 0>>
    <increment limits[i]>
    <increment i>
    <decrement leftover>
  </while>

  <table width=100%>
    <set-var i=0 col=0>
    <tr valign=top>
      <while <lt col width>>
	<set-var count=0>
	<td align=left width=<div 100 width>%>
	  <while <and <get-var-once array[i]> <lt count limits[col]>>>
	    <set-var key=<get-var-once array[i]>>
	    <if <get-var-once link>
		<if <not <match <get-var link> "#">>
		    <concat <a href="<get-var-once link>?<cgi-encode key>"
			       <get-var extra-link-info>>
			    <get-var-once key>
			    </a>>
		  <concat <a href="#<get-var key>">
			  <get-var-once key>
			  </a>>>
	      <get-var-once key>>
	    <br>
	    <increment i>
	    <increment count>
	  </while>
	</td>
      <increment col>
    </while>
    </tr>
  </table>
</defun>

<defsubst array-size whitespace=delete>
  <set-var __info[]=<symbol-info "%0">>
  <or <get-var __info[1]> 0>
</defsubst>

<defsubst array-member whitespace=delete>
  <set-var am::i=0 am::size=<array-size "%1"> am::result="">
  <while <and <not <get-var am::result>>
	      <lt am::i am::size>>>
    <if <string-eq "%0" "<get-var "%1"[am::i]>">
	<set-var am::result=true>>
    <increment am::i>
  </while>
  <get-var am::result>
</defsubst>

<defsubst select-option whitespace=delete>
  <if <array-member "%1" "%0">
      <prog <option selected>%1>
    <prog <if <string-eq "%2" "selected">
	      <prog <option selected>%1>
	    <prog <option>%1>>>>
</defsubst>

<defun pformat symbol>
  <set-var data=<get-var-once <get-var symbol>>>
  <subst-in-var data "\r\n" "\n" "\r" "\n">
  <set-var expr="\n<%ptext>\n<get-var-once data>\n</%ptext><p>">
  <subst-in-var expr "%ptext" "ptext">
  <get-var-once expr>
</defun>

<defun format-section section>
  <set-var dispname=<capitalize <subst-in-string <get-var section> "-" " ">>>
  <h2><get-var dispname></h2>
  <package-delete section>
  <with-open-database db <metahtml::section-db> mode=read>
    <set-var x =
      <database-load-record db <upcase <get-var section>> prefix=section>>
  </with-open-database>

  ;;; Get the functions which belong to this section.
  <set-var default::x=<get-var section>>
  <with-open-database db <metahtml::function-db> mode=read>
    <database-query db <and
			<string-eq <upcase <get-var-once default::x>>
				   <upcase <get-var-once section>>>
			<not <string-eq <get-var-once funtype> variable>>>
      keys=functions>
  </with-open-database>

  <comment>
  ;;; Get the variables which belong to this section.
  <with-open-database db <metahtml::function-db> mode=read>
    <database-query db <and
			<string-eq <get-var-once funtype> variable>
			<string-eq <upcase <get-var-once posted::key>>
				   <upcase <get-var-once section>>>>
      keys=variables>
  </with-open-database>
  </comment>

  ;;; Format the section header information.
  <pformat section::short-desc>
  <pformat section::long-desc>

  ;;; Format each command in this section.
  <set-var findex=0>
  <sort functions>
  <while <get-var functions[findex]>>
    <package-delete function>
    <with-open-database db <metahtml::function-db> mode=read>
      <set-var x =
	<database-load-record db <get-var functions[findex]> prefix=function>>
    </with-open-database>
    <p>
    <table width=100%>
      <tr valign=top>
	<td align=left width=85%>

      <code>
      <when <string-eq <get-var function::funtype> complex>>
	<concat
	 &lt;
	 <b><get-var function::name></b>
	 <set-var i=0>
	 <while <get-var function::req-args[i]>>
	 &nbsp;<i><upcase <get-var function::req-args[i]>></i>
	 <increment i>
	 </while>
	 <set-var i=0>
	 <while <get-var function::opt-args[i]>>
	 <if <string-eq <get-var function::opt-args[i]> "...">
	     <prog &nbsp;<i>...</i>>
	   <prog &nbsp;[<i><upcase <get-var function::opt-args[i]>></i>]>>
	 <increment i>
	 </while>
	 <set-var i=0>
	 <while <get-var function::key-args[i]>>
	 <if <string-eq <get-var function::key-args[i]> "...">
	     <prog &nbsp;<i>...</i>>
	   <prog &nbsp;[<i><upcase <get-var function::key-args[i]>></i>]>>
	 <increment i>
	 </while>
	 &gt;
	 <br>
	 &nbsp;&nbsp;<i>body</i>
	 <br>
	 &lt;/
	 <b><get-var function::name></b>
	 &gt;>
      </when>
    
      <when <string-eq <get-var function::funtype> simple>>
	<concat
	 &lt;
	 <b><get-var function::name></b>
	 <set-var i=0>
	 <while <get-var function::req-args[i]>>
	 &nbsp;<i><upcase <get-var function::req-args[i]>></i>
	 <increment i>
	 </while>
	 <set-var i=0>
	 <while <get-var function::opt-args[i]>>
	 <if <string-eq <get-var function::opt-args[i]> "...">
	     <prog &nbsp;<i>...</i>>
	   <prog &nbsp;[<i><upcase <get-var function::opt-args[i]>></i>]>>
	 <increment i>
	 </while>
	 <set-var i=0>
	 <while <get-var function::key-args[i]>>
	 <if <string-eq <get-var function::key-args[i]> "...">
	     <prog &nbsp;<i>...</i>>
	   <prog &nbsp;[<i><upcase <get-var function::key-args[i]>></i>]>>
	 <increment i>
	 </while>
	 &gt;>
      </when>
      </code>
	</td>
	<td align=right>
	  <b><i><capitalize <get-var function::funtype>></i></b>
	</td>
      </table>
      <p>
      <ul>
	<pformat function::short-desc>
      </ul>
      <p>
    <increment findex>
  </while>
  <p>
</defun>

