home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / stefanb_src / private_projects / autodoc2html / autodoc2html.rexx next >
Encoding:
OS/2 REXX Batch file  |  1996-08-06  |  19.4 KB  |  846 lines

  1. /*
  2.  * AutoDoc2HTML.rexx  V0.0.02
  3.  *
  4.  * Convert AutoDoc file to HTML
  5.  *
  6.  * (c) 1996 Stefan Becker
  7.  */
  8. OPTIONS RESULTS
  9.  
  10. /* Load support libraries */
  11. IF SHOW(L, 'rexxdosssupport.library') == 0 THEN
  12.  CALL ADDLIB('rexxdossupport.library', 0, -30, 0)
  13.  
  14. /* Default command line values */
  15. template      = 'AUTODOC/A,LIBRARY/K,INITFILE/K,TOPNODE/K'
  16. returncode    = 20
  17. args.LIBRARY  = ''
  18. args.INITFILE = ''
  19. args.TOPNODE  = ''
  20.  
  21. /* Define program "constants" */
  22. CONST_Contents = 'Contents'
  23.  
  24. /* Default variable settings. These can be changed in the INITFILE */
  25. comment = ''
  26. header  = ''
  27. footer  = ''
  28. top     = 'Leave AutoDoc'
  29. toc     = 'Contents'
  30.  
  31. /* Analyze command lines */
  32. PARSE SOURCE . . programname .
  33. PARSE ARG arguments
  34.  
  35. /* Help requested? */
  36. IF STRIP(arguments) = '?' THEN DO
  37.  CALL WRITECH(STDOUT, Template || ': ')
  38.  arguments = READLN(STDIN)
  39. END
  40.  
  41. /* Parse command line with template */
  42. IF ReadArgs(arguments, Template, "args.") THEN DO
  43.  
  44.  /* Read initialization file */
  45.  IF initfile ~= '' THEN INTERPRET ReadFile(args.INITFILE)
  46.  
  47.  /* Open autodoc file */
  48.  IF OPEN(autodoc, args.AUTODOC, 'R') THEN DO
  49.  
  50.   /* Get Library name */
  51.   IF GetLibraryName(args.AUTODOC, args.LIBRARY) THEN DO
  52.  
  53.    /* We're starting now... */
  54.    SAY 'Analyzing AutoDoc ''' || args.AUTODOC || ''' for library ''' || library || ''''
  55.  
  56.    /* Parse TOC */
  57.    entries = ReadTOC()
  58.    IF entries ~= 0 THEN DO
  59.  
  60.     /* Write TOC */
  61.     IF WriteTOC(entries) THEN DO
  62.  
  63.      /* Parse each node */
  64.      DO i = 1 TO entries
  65.  
  66.       /* Parse next node */
  67.       IF ReadNode(nodes.i) THEN DO
  68.  
  69.        /* Write HTML document */
  70.        IF ~WriteNode(nodes.i) THEN DO
  71.         SAY 'Couldn''t create HTML document for' nodes.i
  72.         LEAVE
  73.        END
  74.       END
  75.       ELSE DO
  76.        SAY 'Couldn''t read entry for' nodes.i
  77.        LEAVE
  78.       END
  79.      END
  80.  
  81.      /* All OK? */
  82.      IF i = entries + 1 THEN DO
  83.  
  84.       /* Tell the user! */
  85.       SAY 'AutoDoc converted!'
  86.  
  87.       /* Set return code */
  88.       returncode = 0
  89.      END
  90.     END
  91.     ELSE SAY 'Couldn''t create table of contents document!'
  92.    END
  93.    ELSE SAY 'Error in TABLE OF CONTENTS!'
  94.   END
  95.   ELSE SAY 'No library name?!?'
  96.  END
  97.  ELSE SAY 'Couldn''t open AutoDoc ''' || args.AUTODOC || '''!'
  98. END
  99.      /* Command line parsing failed */
  100. ELSE SAY Fault(RC, programname)
  101.  
  102. EXIT returncode
  103.  
  104. /*---------------------------------------------------------------------------*/
  105. /* Analyze AutoDoc TOC  */
  106. ReadTOC: PROCEDURE EXPOSE autodoc library nodes.
  107.  
  108. /* Set default return code */
  109. returncode = 0
  110.  
  111. /* Tell the user */
  112. WRITECH(STDOUT, 'Analyzing table of contents')
  113.  
  114. /* Read first line and check contents */
  115. IF UPPER(STRIP(READLN(autodoc))) == 'TABLE OF CONTENTS' THEN DO
  116.  
  117.  /* Contents line introducer */
  118.  introducer = library || '/'
  119.  namestart  = LENGTH(introducer) + 1
  120.  
  121.  /* Generate node list */
  122.  DO FOREVER
  123.  
  124.   /* Read first character from autodoc */
  125.   line = READCH(autodoc, 1)
  126.  
  127.   /* Which type of line? */
  128.   SELECT
  129.    WHEN line == '0C'X THEN LEAVE   /* End of TOC */
  130.  
  131.    WHEN line == '0A'X THEN ITERATE /* Empty line */
  132.  
  133.    WHEN EOF(autodoc)  THEN DO      /* End of file? */
  134.     SAY ' Unexpected EOF!'
  135.     returncode = 0
  136.     LEAVE
  137.    END
  138.  
  139.    OTHERWISE DO                    /* Non-empty line */
  140.  
  141.     /* Read rest of line */
  142.     line = STRIP(line || READLN(autodoc))
  143.  
  144.     /* Line with spaces? */
  145.     IF line == '' THEN ITERATE
  146.  
  147.     /* Increment counter */
  148.     returncode = returncode + 1
  149.  
  150.     /* Progress report */
  151.     WRITECH(STDOUT, '.')
  152.  
  153.     /* Check format of contents line */
  154.     IF INDEX(line, introducer) == 1 THEN
  155.  
  156.      /* Strip introducer and get node name */
  157.      nodes.returncode = WORD(SUBSTR(line, namestart), 1)
  158.  
  159.     ELSE DO
  160.      SAY ' Erroneous contents line:' line
  161.      returncode = 0
  162.      LEAVE
  163.     END
  164.    END
  165.   END
  166.  END
  167.  
  168.  /* Contents OK? */
  169.  IF returncode ~= 0 THEN SAY ' ' || returncode || ' entries found'
  170. END
  171.  
  172. /* Return result */
  173. RETURN returncode
  174.  
  175. /*---------------------------------------------------------------------------*/
  176. /* Write TOC HTML */
  177. WriteTOC: PROCEDURE EXPOSE CONST_Contents nodes. library args. comment header top footer
  178.  
  179. /* Parse procedure arguments */
  180. PARSE ARG entries
  181.  
  182. /* Set default return code */
  183. returncode = 0
  184.  
  185. /* Read first line and check contents */
  186. IF OpenHTMLFile(CONST_Contents) THEN DO
  187.  
  188.  /* Write header */
  189.  WRITELN(html, '<H2>AutoDoc for ' || library || '</H2><UL>')
  190.  
  191.  /* Create list of links */
  192.  DO i = 1 TO entries
  193.   WRITELN(html, '<LI><A HREF="' || nodes.i || '.html">' || nodes.i || '</A>')
  194.  END
  195.  
  196.  /* End list */
  197.  WRITELN(html, '</UL>')
  198.  
  199.  /* Close contents document */
  200.  CloseHTMLFile(CONST_Contents)
  201.  
  202.  /* All OK */
  203.  returncode = 1
  204. END
  205.  
  206. /* Return result */
  207. RETURN returncode
  208.  
  209. /*---------------------------------------------------------------------------*/
  210. /* Known keyword? */
  211. KnownKeyword: PROCEDURE
  212.  
  213. /* Parse procedure arguments */
  214. PARSE ARG w
  215.  
  216. IF w == 'NAME' | w == 'SYNOPSIS' | w == 'FUNCTION' | w == 'INPUTS' | w == 'BUGS' | w == 'SEE ALSO' THEN RETURN w
  217.  
  218. /* Synonyms for RESULTS */
  219. IF w == 'RESULTS' | w == 'RESULT' THEN RETURN 'RESULTS'
  220.  
  221. /* Synonyms for NOTE */
  222. IF w == 'NOTE' | w == 'NOTES' | w == 'SPECIAL NOTES' | w == 'WARNING' THEN RETURN 'NOTES'
  223.  
  224. /* Synonyms for EXAMPLE */
  225. IF w == 'EXAMPLE' | w == 'EXAMPLES' THEN RETURN 'EXAMPLE'
  226.  
  227. /* Unknown keyword */
  228. RETURN ''
  229.  
  230. /*---------------------------------------------------------------------------*/
  231. /* Parse NAME entry */
  232. ParseNAME: PROCEDURE EXPOSE autodoc
  233.  
  234. /* Parse procedure arguments */
  235. PARSE ARG nodename
  236.  
  237. /* Set default return code */
  238. string = ''
  239. inname = 0
  240.  
  241. /* Scan autodoc */
  242. DO FOREVER
  243.  
  244.  /* Read first character from autodoc */
  245.  line = READCH(autodoc, 1)
  246.  
  247.  /* Which type of line? */
  248.  SELECT
  249.   WHEN line == '0C'X | EOF(autodoc) THEN DO /* End of node or end of file? */
  250.    string = ''
  251.    LEAVE
  252.   END
  253.  
  254.   WHEN line == '0A'X THEN IF inname THEN LEAVE /* Empty line */
  255.  
  256.   OTHERWISE DO                                 /* Non-empty line */
  257.  
  258.    /* Read rest of line */
  259.    line = STRIP(TRANSLATE(line || READLN(autodoc), ' ', '09'X))
  260.  
  261.    /* In name? */
  262.    IF ~inname THEN DO
  263.  
  264.     /* Check line */
  265.     IF (WORD(line, 1) == nodename) & (LEFT(WORD(line, 2), 1) == '-') THEN DO
  266.  
  267.      /* Initialize string */
  268.      string = '<TABLE><TR><TD><CODE>' || nodename || '</CODE><TD>-<TD>' || SUBSTR(line, WORDINDEX(line, 3))
  269.  
  270.      /* Parsing name */
  271.      inname = 1
  272.  
  273.     END
  274.     ELSE DO
  275.      SAY 'Incorrect NAME entry:' line
  276.      string = ''
  277.      LEAVE
  278.     END
  279.    END
  280.    ELSE DO
  281.  
  282.     /* Line with spaces? */
  283.     IF line == '' THEN LEAVE
  284.  
  285.     /* Add line to string */
  286.     string = string || ' ' || line
  287.    END
  288.   END
  289.  END
  290. END
  291.  
  292. /* Entry parsed? */
  293. IF string ~= '' THEN string = string || '</TABLE>'
  294.  
  295. /* Return NAME HTML contents */
  296. return string
  297.  
  298. /*---------------------------------------------------------------------------*/
  299. /* Parse pre-formatted entry */
  300. ParsePreFormatted: PROCEDURE EXPOSE autodoc line dontread
  301.  
  302. /* Initialize string */
  303. string = ''
  304.  
  305. /* Scan autodoc */
  306. DO FOREVER
  307.  
  308.  /* Read first character from autodoc */
  309.  line = READCH(autodoc, 1)
  310.  
  311.  /* Which type of line? */
  312.  SELECT
  313.   WHEN line == '0C'X | EOF(autodoc) THEN DO /* End of node or end of file? */
  314.    string = ''
  315.    LEAVE
  316.   END
  317.  
  318.   WHEN line == '0A'X                THEN string = string || '0A'X
  319.  
  320.   OTHERWISE DO                              /* Non-empty line */
  321.  
  322.    /* Read rest of line */
  323.    line = line || READLN(autodoc)
  324.  
  325.    /* Next entry reached? */
  326.    IF KnownKeyword(STRIP(line)) ~= '' THEN DO
  327.     dontread = 1
  328.     LEAVE
  329.    END
  330.  
  331.    /* Add line to string */
  332.    string = string || line || '0A'X
  333.   END
  334.  END
  335. END
  336.  
  337. /* Entry parsed? */
  338. IF string ~= '' THEN DO
  339.  
  340.  /* Remove leading & trailing empty lines */
  341.  string = STRIP(string, 'B', '0A'X)
  342.  
  343.  /* Complete string */
  344.  string = '<PRE>' || string || '</PRE>'
  345. END
  346.  
  347. /* Return pre-formatted HTML contents */
  348. return string
  349.  
  350. /*---------------------------------------------------------------------------*/
  351. /* Parse several paragraphs */
  352. ParseParagraphs: PROCEDURE EXPOSE autodoc line dontread
  353.  
  354. /* Initialize string */
  355. string      = ''
  356. inparagraph = 0
  357.  
  358. /* Scan autodoc */
  359. DO FOREVER
  360.  
  361.  /* Read first character from autodoc */
  362.  line = READCH(autodoc, 1)
  363.  
  364.  /* Which type of line? */
  365.  SELECT
  366.   WHEN line == '0C'X | EOF(autodoc) THEN DO /* End of node or end of file? */
  367.    string   = ''
  368.    dontread = 1
  369.    LEAVE
  370.   END
  371.  
  372.   WHEN line == '0A'X                THEN DO /* Empty line */
  373.  
  374.    /* In paragraph? */
  375.    IF inparagraph THEN DO
  376.  
  377.     /* Yes, terminate it */
  378.     string      = string || '</P>'
  379.     inparagraph = 0
  380.    END
  381.   END
  382.  
  383.   OTHERWISE DO                              /* Non-empty line */
  384.  
  385.    /* Read rest of line */
  386.    line = STRIP(TRANSLATE(line || READLN(autodoc), ' ', '09'X))
  387.  
  388.    /* Next entry reached? */
  389.    IF KnownKeyword(line) ~= '' THEN DO
  390.     dontread = 1
  391.     LEAVE
  392.    END
  393.  
  394.    /* New paragraph? */
  395.    IF ~inparagraph THEN DO
  396.  
  397.     /* Yes, start it */
  398.     string      = string || '<P>' || line
  399.     inparagraph = 1
  400.    END
  401.    ELSE
  402.     /* No, just add line to string */
  403.     string = string || ' ' || line
  404.  
  405.   END
  406.  END
  407. END
  408.  
  409. /* Entry parsed and still in paragraph? */
  410. IF (string ~= '') & inparagraph THEN string = string || '</P>'
  411.  
  412. /* Return paragraph contents */
  413. return string
  414.  
  415. /*---------------------------------------------------------------------------*/
  416. /* Parse variables */
  417. ParseVariables: PROCEDURE EXPOSE autodoc line dontread
  418.  
  419. /* Initialize string */
  420. string     = '<TABLE>'
  421. invariable = 0
  422.  
  423. /* Scan autodoc */
  424. DO FOREVER
  425.  
  426.  /* Read first character from autodoc */
  427.  line = READCH(autodoc, 1)
  428.  
  429.  /* Which type of line? */
  430.  SELECT
  431.   WHEN line == '0C'X | EOF(autodoc) THEN DO /* End of node or end of file? */
  432.    string   = ''
  433.    dontread = 1
  434.    LEAVE
  435.   END
  436.  
  437.   WHEN line == '0A'X THEN invariable = 0    /* Empty line */
  438.  
  439.   OTHERWISE DO                              /* Non-empty line */
  440.  
  441.    /* Read rest of line */
  442.    line = STRIP(TRANSLATE(line || READLN(autodoc), ' ', '09'X))
  443.  
  444.    /* Next entry reached? */
  445.    IF KnownKeyword(line) ~= '' THEN DO
  446.     dontread = 1
  447.     LEAVE
  448.    END
  449.  
  450.    /* New variable? */
  451.    IF ~invariable THEN DO
  452.  
  453.     /* Check line */
  454.     seperator = INDEX(line, '-')
  455.     IF seperator = 0 THEN DO
  456.      string   = ''
  457.      dontread = 1
  458.      LEAVE
  459.     END
  460.  
  461.     /* Yes, start it */
  462.     invariable = 1
  463.  
  464.     /* Initialize string */
  465.     string = string || '<TR><TD VALIGN=TOP><VAR>' || STRIP(SUBSTR(line, 1, seperator - 1)) || '</VAR><TD VALIGN=TOP>-<TD> ' || SUBSTR(line, WORDINDEX(line, 3))
  466.  
  467.    END
  468.    ELSE
  469.     /* No, just add line to string */
  470.     string = string || ' ' || line
  471.  
  472.   END
  473.  END
  474. END
  475.  
  476. /* Entry parsed and still in paragraph? */
  477. IF string ~= '' THEN string = string || '</TABLE>'
  478.  
  479. /* Return variables contents */
  480. return string
  481.  
  482. /*---------------------------------------------------------------------------*/
  483. /* Parse SEE ALSO entry */
  484. ParseSEEALSO: PROCEDURE EXPOSE autodoc
  485.  
  486. /* Initialize string */
  487. string = ''
  488.  
  489. /* Scan autodoc */
  490. DO FOREVER
  491.  
  492.  /* Read first character from autodoc */
  493.  line = READCH(autodoc, 1)
  494.  
  495.  /* Which type of line? */
  496.  SELECT
  497.   WHEN line == '0C'X | EOF(autodoc) THEN DO /* End of node or end of file? */
  498.    string   = ''
  499.    LEAVE
  500.   END
  501.  
  502.   WHEN line == '0A'X THEN LEAVE             /* Empty line: Stop parsing */
  503.  
  504.   OTHERWISE string = string || STRIP(TRANSLATE(line || READLN(autodoc), ' ', '09X')) || ' '
  505.  END
  506. END
  507.  
  508. /* Entry parsed? */
  509. IF string ~= '' THEN DO
  510.  
  511.  /* Initialize strings */
  512.  functions = STRIP(string)
  513.  string    = '<TABLE>'
  514.  
  515.  /* Parse reference list */
  516.  DO UNTIL functions == ''
  517.  
  518.   /* Add next reference */
  519.   string = string || '<TR><TD>' STRIP(WORD(functions, 1), 'T', ',')
  520.  
  521.   /* Cut out reference */
  522.   functions = DELWORD(functions, 1, 1)
  523.  END
  524.  
  525.  /* Complete string */
  526.  string = string || '</TABLE>'
  527. END
  528.  
  529. /* Return SEE ALSO contents */
  530. return string
  531.  
  532. /*---------------------------------------------------------------------------*/
  533. /* Read node from AutoDoc */
  534. ReadNode: PROCEDURE EXPOSE autodoc library contents.
  535.  
  536. /* Parse procedure arguments */
  537. PARSE ARG nodename
  538.  
  539. /* Set default return code */
  540. returncode = 0
  541.  
  542. /* Get first line */
  543. line = READLN(autodoc)
  544.  
  545. /* Node header */
  546. nodeheader   = library || '/' || nodename
  547. headerlength = LENGTH(nodeheader)
  548.  
  549. /* Check node header: "library/node<n spaces>library/node" */
  550. IF INDEX(line, nodeheader) = 1  & SUBSTR(line, LENGTH(line) + 1 - headerlength) == nodeheader THEN DO
  551.  
  552.  /* Special case for tag functions: They may have several headers! */
  553.  DO FOREVER
  554.  
  555.   /* Read next line */
  556.   line = READLN(autodoc)
  557.  
  558.   /* Does it contain the library name in the first column? */
  559.   IF INDEX(line, library) ~= 1 THEN LEAVE
  560.  END
  561.  
  562.  /* Don't read next line */
  563.  dontread = 1
  564.  
  565.  /* Initialize contents stem */
  566.  contents.NAME     = ''
  567.  contents.SYNOPSIS = ''
  568.  contents.FUNCTION = ''
  569.  contents.INPUTS   = ''
  570.  contents.RESULTS  = ''
  571.  contents.NOTES    = ''
  572.  contents.EXAMPLE  = ''
  573.  contents.BUGS     = ''
  574.  contents.SEEALSO  = ''
  575.  
  576.  /* Scan autodoc */
  577.  DO FOREVER
  578.  
  579.   /* Read first character from autodoc */
  580.   IF ~dontread THEN line = READCH(autodoc, 1)
  581.  
  582.   /* Which type of line? */
  583.   SELECT
  584.    WHEN line == '0C'X THEN DO      /* End of node */
  585.     returncode = 1
  586.     LEAVE
  587.    END
  588.  
  589.    WHEN line == '0A'X THEN ITERATE /* Empty line */
  590.  
  591.    WHEN EOF(autodoc)  THEN DO      /* End of file? */
  592.     SAY ' Unexpected EOF!'
  593.     LEAVE
  594.    END
  595.  
  596.    OTHERWISE DO                    /* Non-empty line */
  597.  
  598.     /* Read rest of line */
  599.     IF dontread THEN dontread = 0
  600.                 ELSE line = line || READLN(autodoc)
  601.     line = STRIP(TRANSLATE(line, ' ', '09'X))
  602.  
  603.     /* Line with spaces? */
  604.     IF line == '' THEN ITERATE
  605.  
  606.     /* Check keyword */
  607.     keyword = KnownKeyword(line)
  608.     IF keyword ~= '' THEN DO
  609.  
  610.      /* Keyword-sensitive parsing */
  611.      SELECT
  612.       WHEN keyword == 'NAME'     THEN contents.NAME       = ParseNAME(nodename)
  613.       WHEN keyword == 'SYNOPSIS' THEN contents.SYNOPSIS   = ParsePreFormatted()
  614.       WHEN keyword == 'FUNCTION' THEN contents.FUNCTION   = ParseParagraphs()
  615.       WHEN keyword == 'INPUTS'   THEN contents.INPUTS     = ParseVariables()
  616.       WHEN keyword == 'RESULTS'  THEN contents.RESULTS    = ParseVariables()
  617.       WHEN keyword == 'NOTES'    THEN contents.NOTES      = ParseParagraphs()
  618.       WHEN keyword == 'EXAMPLE'  THEN contents.EXAMPLE    = ParsePreFormatted()
  619.       WHEN keyword == 'BUGS'     THEN contents.BUGS       = ParseParagraphs()
  620.       WHEN keyword == 'SEE ALSO' THEN contents.SEEALSO    = ParseSEEALSO()
  621.      END
  622.     END
  623.     ELSE DO
  624.      SAY 'Unknown keyword' line
  625.      LEAVE
  626.     END
  627.    END
  628.   END
  629.  END
  630. END
  631. ELSE SAY 'Errorneous header in node ' || nodename || ': ' line
  632.  
  633. /* Return result */
  634. RETURN returncode
  635.  
  636. /*---------------------------------------------------------------------------*/
  637. /* Write one entry to HTML document (with link translation) */
  638. WriteEntry: PROCEDURE EXPOSE html contents. nodes. entries
  639.  
  640. /* Parse procedure arguments */
  641. PARSE ARG entry, name
  642.  
  643. /* Entry valid? */
  644. string = contents.entry
  645. IF string ~= '' THEN DO
  646.  
  647.  /* Name specified? */
  648.  IF name == '' THEN name = entry
  649.  
  650.  /* Replace function names with links */
  651.  start = 1
  652.  DO UNTIL start = 0
  653.  
  654.   /* Scan for () in string */
  655.   start = INDEX(string, '()', start)
  656.   IF start ~= 0 THEN DO
  657.  
  658.    /* Scan for beginning of function name */
  659.    funcstart = LASTPOS(' ', string, start) + 1
  660.    length    = start - funcstart
  661.  
  662.    /* Cut out */
  663.    function = SUBSTR(string, funcstart, length)
  664.    string   = DELSTR(string, funcstart, length + 2)
  665.  
  666.    /* Build new default string */
  667.    newfunction = '<CODE>' || function || '()</CODE>'
  668.  
  669.    /* Scan node list */
  670.    DO i = 1 to entries
  671.  
  672.     /* Local function? */
  673.     IF nodes.i == function THEN DO
  674.  
  675.      /* If local function then generate link */
  676.      newfunction = '<A HREF="' || function || '.html">' || newfunction || '</A>'
  677.      LEAVE
  678.     END
  679.    END
  680.  
  681.    /* Insert new string */
  682.    string = insert(newfunction, string, funcstart - 1)
  683.  
  684.    /* Skip entry */
  685.    start = funcstart + LENGTH(newfunction)
  686.   END
  687.  END
  688.  
  689.  /* Write entry */
  690.  WRITELN(html, '<H2>' || name || '</H2><BLOCKQUOTE>' || string || '</BLOCKQUOTE>')
  691. END
  692.  
  693. /* All OK */
  694. RETURN 0
  695.  
  696. /*---------------------------------------------------------------------------*/
  697. /* Write node HTML document */
  698. WriteNode: PROCEDURE EXPOSE CONST_Contents library contents. args. comment header top toc footer nodes. entries
  699.  
  700. /* Parse procedure arguments */
  701. PARSE ARG nodename
  702.  
  703. /* Set default return code */
  704. returncode = 0
  705.  
  706. /* Check mandatory fields */
  707. IF (contents.NAME ~= '') & (contents.SYNOPSIS ~= '') & (contents.FUNCTION ~= '') THEN DO
  708.  /* Read first line and check contents */
  709.  IF OpenHTMLFile(nodename) THEN DO
  710.  
  711.   /* Write mandatory entries */
  712.   WRITELN(html, '<H2>NAME</H2><BLOCKQUOTE>'     || contents.NAME     || '</BLOCKQUOTE>')
  713.   WRITELN(html, '<H2>SYNOPSIS</H2>'             || contents.SYNOPSIS || '</BLOCKQUOTE>')
  714.   WriteEntry(FUNCTION)
  715.  
  716.   /* Write non mandatory entries */
  717.   WriteEntry(INPUTS)
  718.   WriteEntry(RESULTS)
  719.   WriteEntry(NOTES)
  720.   WriteEntry(EXAMPLE)
  721.   WriteEntry(BUGS)
  722.   WriteEntry(SEEALSO, 'SEE ALSO')
  723.  
  724.   /* Close contents document */
  725.   CloseHTMLFile(nodename)
  726.  
  727.   /* All OK */
  728.   returncode = 1
  729.  END
  730. END
  731. ELSE SAY 'NAME, SYNOPSIS or FUNCTION part missing in ' || nodename || '!'
  732.  
  733. /* Return result */
  734. RETURN returncode
  735.  
  736. /*---------------------------------------------------------------------------*/
  737. /* Read a file into a string */
  738. ReadFile: PROCEDURE
  739.  
  740. /* Parse procedure arguments */
  741. PARSE ARG filename
  742.  
  743. /* Set default return value */
  744. string = ''
  745.  
  746. /* Open file */
  747. IF OPEN(file, filename) THEN
  748. DO
  749.  /* Scan file and append lines */
  750.  DO UNTIL EOF(file)
  751.   string = string || READLN(file)
  752.  END
  753.  
  754.  /* Close file */
  755.  CLOSE(file)
  756. END
  757.  
  758. /* Return result */
  759. RETURN string
  760.  
  761. /*---------------------------------------------------------------------------*/
  762. /* Get library name */
  763. GetLibraryName: PROCEDURE EXPOSE library
  764.  
  765. /* Parse procedure arguments */
  766. PARSE ARG filename library
  767.  
  768. /* Library name specified? */
  769. IF library == '' THEN
  770. DO
  771.  
  772.  /* No, extract library base name from file name */
  773.  IF UPPER(RIGHT(filename, 4)) == '.DOC' THEN DO
  774.  
  775.   /* Strip ending */
  776.   filename = SUBSTR(filename, 1, LENGTH(filename) - 4)
  777.  
  778.   /* Get file name, strip path */
  779.   index = LASTPOS('/', filename)
  780.   IF index ~= 0 THEN filename = SUBSTR(filename, index + 1)
  781.   index = LASTPOS(':', filename)
  782.   IF index ~= 0 THEN filename = SUBSTR(filename, index + 1)
  783.  
  784.   /* Library name extracted */
  785.   library    = filename || '.library'
  786.   returncode = 1
  787.  END
  788. END
  789. ELSE returncode = 1
  790.  
  791. /* Return result */
  792. RETURN returncode
  793.  
  794. /*---------------------------------------------------------------------------*/
  795. /* Open HTML file */
  796. OpenHTMLFile: PROCEDURE EXPOSE html comment header library
  797.  
  798. /* Parse procedure arguments */
  799. PARSE ARG nodename
  800.  
  801. /* Set default return code */
  802. returncode = 0
  803.  
  804. /* Tell the user about it */
  805. WRITECH(STDOUT, 'HTML File: ' || nodename || '... ')
  806.  
  807. /* Open file */
  808. IF OPEN(html, nodename || '.html', W) THEN DO
  809.  
  810.  /* Write header */
  811.  WRITELN(html, '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">')
  812.  WRITELN(html, '<!-- Converted with AutoDoc2HTML (c) 1996 Stefan Becker <stefanb@yello.ping.de> on ' || translate(date(),'-',' ') || ' -->')
  813.  IF comment ~= '' THEN WRITELN(html, '<!-- ' || comment || ' -->')
  814.  WRITELN(html, '<HTML><HEAD><TITLE>AutoDoc: ' || library || '/' || nodename || '</TITLE></HEAD><BODY>')
  815.  IF header ~= '' THEN WRITELN(html, header)
  816.  
  817.  /* All OK */
  818.  returncode = 1
  819. END
  820.  
  821. /* Return result */
  822. RETURN returncode
  823.  
  824. /*---------------------------------------------------------------------------*/
  825. /* Close HTML file */
  826. CloseHTMLFile: PROCEDURE EXPOSE html args. top CONST_Contents toc footer
  827.  
  828. /* Parse procedure arguments */
  829. PARSE ARG nodename
  830.  
  831. WRITELN(html, '<HR><TABLE WIDTH=100%><TR>')
  832. IF args.TOPNODE ~= ''             THEN WRITELN(html, '<TD><A HREF="' || args.TOPNODE || '">' || top || '</A>')
  833. IF nodename     ~= CONST_Contents THEN WRITELN(html, '<TD ALIGN=RIGHT><A HREF="' || CONST_Contents || '.html">' || toc || '</A>')
  834. WRITELN(html, '</TABLE>')
  835. WRITELN(html, footer)
  836. WRITELN(html, '</BODY></HTML>')
  837.  
  838. /* Close file */
  839. CLOSE(html)
  840.  
  841. /* Tell the user about it */
  842. SAY 'DONE'
  843.  
  844. /* Return no result */
  845. RETURN 0
  846.