# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. include include "lroff.h" define DIRECTIVE 1 # processing codes define NAME 2 define TEXT 3 define F_ROMAN 1 # font changes define F_ITALIC 2 define F_BOLD 3 define F_PREVIOUS 4 define F_TELETYPE 5 # HTML-specific font define SPTR Memi[$1+$2] define SECTION Memc[SPTR($1,$2)] define MAX_SECTIONS 256 # LROFF2HTML -- Convert LROFF text to HTML. By default we process the # entire file however we allow for the printing of only a particular section # or labelled text block to be compatible with the HELP task options. # If a section name is given that section will be printed and and .ls # block request will be ignored. procedure lroff2html (in, out, module, parstr, center, ls_block, section) int in #I input file descriptor int out #I output file descriptor char module[ARB] #I .help module name char parstr[ARB] #I .help optional keyword 2 char center[ARB] #I .help optional keyword 3 char ls_block[ARB] #I .ls block to search for char section[ARB] #I section to print pointer sp, ip, sptr pointer ibuf, unesc, name, level int lastline, font, indented, ls_level int i, arg, nsec, cmd bool format, quit_at_le, quit_at_ih, formatted int lh_findsection(), lh_findblock(), nextcmd() int stridxs(), getline(), strlen(), strmatch(), getarg() define text_ 99 define err_ 98 include "lroff.com" begin call smark (sp) call salloc (ibuf, SZ_IBUF, TY_CHAR) call salloc (unesc, SZ_IBUF, TY_CHAR) call salloc (name, SZ_LINE, TY_CHAR) call salloc (level, SZ_FNAME, TY_CHAR) call salloc (sptr, MAX_SECTIONS, TY_POINTER) call aclrc (Memc[ibuf], SZ_IBUF) call aclrc (Memc[name], SZ_LINE) call aclrc (Memc[unesc], SZ_IBUF) call aclrc (Memc[level], SZ_FNAME) # Initialize. lastline = TEXT font = F_ROMAN indented = YES nsec = 0 ls_level = 0 format = true quit_at_le = false quit_at_ih = false formatted = false # Initialize the section numbering. call amovki (0, nh_level, MAX_NHLEVEL) # Determine whether or not the text is formatted. repeat { if (getline (in, Memc[ibuf]) == EOF) goto err_ for (ip=1; IS_WHITE(Memc[ibuf+ip-1]); ip=ip+1) ; } until (Memc[ibuf+ip-1] != '\n') call ungetline (in, Memc[ibuf]) if (Memc[ibuf] == '.') formatted = true # Scan forward if searching for and item. if (section[1] != EOS) { if (lh_findsection (in, formatted, section) == EOF) goto err_ } else if (ls_block[1] != EOS) { if (lh_findblock (in, formatted, ls_block) == EOF) goto err_ quit_at_le = true } # Begin the output. call lh_prolog (out, module, parstr, center) call fprintf (out, "%s\n\n") if (nsec > 0) { call fprintf (out, "\n") call pargstr (SECTION(sptr,nsec-1)) } # Make the section name a URL target. call lh_mkname (Memc[ibuf], Memc[name]) if (Memc[level] == EOS) { call fprintf (out, "

%s

\n") call pargstr (Memc[name]) call pargstr (Memc[ibuf]) } else { call fprintf (out, "

%s %s

\n") call pargstr (Memc[name]) call pargstr (Memc[level]) call pargstr (Memc[ibuf]) Memc[level] = EOS } call fprintf (out, "\n") call pargstr (Memc[ibuf]) if (indented == YES) call fprintf (out, "\n\n\n") call pargstr (SECTION(sptr,nsec-1)) } # Write out an HTML comment giving the document section names. call fprintf (out, "\n\n") call fprintf (out, "\n\n") call flush (out) err_ call sfree (sp) end # LH_PROLOG -- Begin the HTML output, print the header table for a help # page if we have the information. procedure lh_prolog (fd, mod, date, title) int fd #I output file descriptor char mod[ARB] #I .help module name char date[ARB] #I .help keyword 2 char title[ARB] #I .help keyword 3 begin call fprintf (fd, "\n\n") # If we only have the module name don't bother with header. if (date[1] == EOS && title[1] == EOS) return # Begin the HTML output prolog. call fprintf (fd, "\n") # Left side page header. call fprintf (fd, "\n") # Center page header. if (title[1] != EOS) { call fprintf (fd, "\n") } # Right side page header. call fprintf (fd, "\n") call fprintf (fd, "
\n") if (date[1] == EOS) { call fprintf (fd, "%s") call pargstr (mod) } else { call fprintf (fd, "%s (%s)") call pargstr (mod) call pargstr (date) } call fprintf (fd, "\n") call fprintf (fd, "%s\n") call pargstr (title) call fprintf (fd, "\n") if (date[1] == EOS) { call fprintf (fd, "%s") call pargstr (mod) } else { call fprintf (fd, "%s (%s)") call pargstr (mod) call pargstr (date) } call fprintf (fd, "

\n") end # LH_ESCAPE -- Escape any HTML problem characters in the line ('<','>','&') # as well as the font changes. procedure lh_escape (str, font, format, special_only, maxch) char str[ARB] #I string to edit int font #U current font bool format #I formatting flag int special_only #I escape only special chars? int maxch #I max length of string pointer sp, ip, buf, keyword int i, gstrcpy(), stridx() define copy_ 90 begin call smark (sp) call salloc (buf, maxch, TY_CHAR) call salloc (keyword, maxch, TY_CHAR) call aclrc (Memc[buf], maxch) call aclrc (Memc[keyword], maxch) ip = buf for (i=1; str[i] != EOS && i <= maxch; i = i + 1) { if (special_only == YES && stridx (str[i], "<>&") == 0) goto copy_ switch (str[i]) { # Handle special chars. case '<': ip = ip + gstrcpy ("<", Memc[ip], SZ_LINE) case '>': ip = ip + gstrcpy (">", Memc[ip], SZ_LINE) case '&': ip = ip + gstrcpy ("&", Memc[ip], SZ_LINE) # Quoted single chars and strings get a special font. case '\'': if (str[i+2] == '\'') { ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) ip = ip + gstrcpy (str[i], Memc[ip], 3) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) i = i + 2 } else goto copy_ case '`': if (str[i+2] == '`' || str[i+2] == '\'') { ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) ip = ip + gstrcpy (str[i], Memc[ip], 3) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) i = i + 2 } else goto copy_ case '"': if (format) { if (font == F_TELETYPE) { # Do a closing quote. ip = ip + gstrcpy ("\"", Memc[ip], SZ_LINE) font = F_ROMAN } else if (font == F_ROMAN) { # Do an opening quote. ip = ip + gstrcpy ("\"", Memc[ip], SZ_LINE) font = F_TELETYPE } else goto copy_ } else goto copy_ # Process font changes. case '\\': if (str[i+1] == 'f') { if (str[i+2] == 'B') { if (font == F_BOLD) next if (font == F_ITALIC) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) font = F_BOLD } else if (str[i+2] == 'I') { if (font == F_ITALIC) next if (font == F_BOLD) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) font = F_ITALIC } else if (str[i+2] == 'R') { if (font == F_BOLD) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) else if (font == F_ITALIC) ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) font = F_ROMAN } else if (str[i+2] == 'P') { if (font == F_BOLD) { ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) } else if (font == F_ITALIC) { ip = ip + gstrcpy ("", Memc[ip], SZ_LINE) } font = F_ROMAN } i = i + 2 } else if (str[i+1] == '\n' || str[i+1] == EOS) { Memc[ip] = str[i] ip = ip + 1 i = i + 1 ip = ip + gstrcpy ("
", Memc[ip], SZ_LINE) } else goto copy_ default: copy_ Memc[ip] = str[i] ip = ip + 1 } } # Add the trailing newline we stripped above. ip = ip + gstrcpy ("\n\0", Memc[ip], SZ_LINE) # Move the string back. call amovc (Memc[buf], str, maxch) call sfree (sp) end # LH_SET_LEVEL -- Increment the level number of a numbered header. procedure lh_set_level (n, level) int n #I level number char level[ARB] #U level string int i, strlen() include "lroff.com" begin # Increment the desired section number; zero all higher # numbered section counters. nh_level[n] = nh_level[n] + 1 call amovki (0, nh_level[n+1], MAX_NHLEVEL - n) # Output the section number followed by a blank and then # the section label. level[1] = EOS do i = 1, n { call sprintf (level[strlen(level)+1], SZ_IBUF, "%d.") call pargi (nh_level[i]) } # Cancel the final "." if subsection heading. Add a blank. if (n > 1 && level[strlen(level)] == '.') level[strlen(level)] = EOS end # LH_FINDBLOCK -- If text contains format directives, eat input lines until # a ".ls" directive is found which contains the block name as a substring. # If the text is not formatted, search for a line beginning with the pattern. int procedure lh_findblock (fd, formatted, param) int fd bool formatted char param[ARB] bool match_found pointer sp, lbuf, pattern int len int getline(), strmatch(), strlen() errchk getline define err_ 90 begin call smark (sp) call salloc (pattern, SZ_FNAME, TY_CHAR) call salloc (lbuf, SZ_LINE, TY_CHAR) match_found = false # Get the first line. if (getline (fd, Memc[lbuf]) == EOF) goto err_ if (formatted) { call sprintf (Memc[pattern], SZ_FNAME, "{%s}") call pargstr (param) repeat { if (strmatch (Memc[lbuf], "^.{ls}") > 0) if (strmatch (Memc[lbuf], Memc[pattern]) > 0) { match_found = true break } } until (getline (fd, Memc[lbuf]) == EOF) } else { call sprintf (Memc[pattern], SZ_FNAME, "^#{%s}") call pargstr (param) repeat { if (strmatch (Memc[lbuf], Memc[pattern]) > 0) { match_found = true break } } until (getline (fd, Memc[lbuf]) == EOF) } call ungetline (fd, Memc[lbuf]) err_ len = strlen (Memc[lbuf]) call sfree (sp) if (match_found) return (len) else return (EOF) end # LH_FINDSECTION -- If text contains format directives, eat input lines until # a ".ih" directive is found for the named section. If the text is not # formatted, search for a line beginning with the section name. define MAXPAT 10 int procedure lh_findsection (fd, formatted, sections) int fd # input file bool formatted # is help block formatted char sections[ARB] # list of sections "a|b|c" bool match_found int npat, ip pointer sp, patbuf, patoff[MAXPAT], op char lbuf[SZ_LINE] bool lh_match() int getline(), strmatch() errchk getline define err_ 91 begin call smark (sp) call salloc (patbuf, SZ_LINE, TY_CHAR) # Process the list of sections into patbuf and patoff, i.e., into a # list of EOS delimited strings in the string buffer patbuf. Each # section name or abbreviation is delimited by '|' (or). npat = 1 op = patbuf patoff[1] = op # Get the first line. if (getline (fd, lbuf) == EOF) goto err_ for (ip=1; sections[ip] != EOS; ip=ip+1) switch (sections[ip]) { case '|': Memc[op] = EOS op = op + 1 npat = min (MAXPAT, npat + 1) patoff[npat] = op default: Memc[op] = sections[ip] op = op + 1 } Memc[op] = EOS match_found = false if (formatted) { repeat { if (strmatch (lbuf, "^.{ih}") > 0) if (getline (fd, lbuf) != EOF) { match_found = lh_match (lbuf, patoff, npat) if (match_found) break } } until (getline (fd, lbuf) == EOF) call ungetline (fd, lbuf) call ungetline (fd, ".ih\n") } else { repeat { match_found = lh_match (lbuf, patoff, npat) if (match_found) break } until (getline (fd, lbuf) == EOF) call ungetline (fd, lbuf) } err_ call sfree (sp) if (match_found) return (OK) else return (EOF) end # LH_MATCH -- Match a set of patterns against a line of test, matching only # at the beginning of line in either case. bool procedure lh_match (lbuf, patoff, npat) char lbuf[ARB] # line of text pointer patoff[npat] # pointers to pattern strings int npat # number of patterns int pat pointer sp, pattern int strmatch() begin call smark (sp) call salloc (pattern, SZ_FNAME, TY_CHAR) for (pat=1; pat <= npat; pat=pat+1) { call sprintf (Memc[pattern], SZ_FNAME, "^{%s}") call pargstr (Memc[patoff[pat]]) if (strmatch (lbuf, Memc[pattern]) > 0) { call sfree (sp) return (true) } } call sfree (sp) return (false) end # LH_MKNAME -- Given a string make it suitable for use as an HREF name. procedure lh_mkname (instr, outstr) char instr[ARB] char outstr[ARB] int i begin # Make it a URL. First convert the section name to a # lower-case string and replace the blanks. call strcpy (instr, outstr, SZ_LINE) call strlwr (outstr) for (i=1; i < SZ_LINE; i=i+1) if (outstr[i] == EOS || outstr[i] == '\n') break else if (!IS_ALNUM(outstr[i])) outstr[i] = '_' end