From fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 8 Jul 2015 20:46:52 -0400 Subject: Initial commit --- pkg/system/help/lroff/lroff2html.x | 781 +++++++++++++++++++++++++++++++++++++ 1 file changed, 781 insertions(+) create mode 100644 pkg/system/help/lroff/lroff2html.x (limited to 'pkg/system/help/lroff/lroff2html.x') diff --git a/pkg/system/help/lroff/lroff2html.x b/pkg/system/help/lroff/lroff2html.x new file mode 100644 index 00000000..1e3815ae --- /dev/null +++ b/pkg/system/help/lroff/lroff2html.x @@ -0,0 +1,781 @@ +# 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(), lgetarg() + +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 && str[i+1] != '/' && str[i+2] != '/') { + 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 -- cgit