#!/bin/sh
# Copyright 1994-2018 by Norman Ramsey.  All rights reserved.
# See file COPYRIGHT for more information.
# Do not try to understand this file!  Look at lib/tohtml.nw in the noweb source!

delay=0 raw=0 localindex=0 noindex=0 nocomment=0
for i do
  case $i in
    -delay)      delay=1      ;;
    -raw)        raw=1        ;;
    -localindex) if [ $noindex -eq 0 ]; then localindex=1; fi;;
    -noindex)    localindex=0; noindex=1 ;;
    -no-gen-comment) nocomment=1 ;;
  esac
done
nawk 'function writechunk(label, ref, tag, name, suffix) {
        printf "%s", 
          linklabelto(label, ref, sgmlwrap(tag, "&lt;" convquotes(name) "&gt;" suffix))
      }
      function linklabelto(label, ref, contents, s) {
        s = label != "" || ref != "" ? "<a" : ""
        if (label != "") s = s " name=" image(label)
        if (ref != "")   s = s " href=" image("#" ref)
        s = s (label != "" || ref != "" ? ">" : "")
        s = s contents
        s = s (label != "" || ref != "" ? "</a>" : "")
        return s
      }

      function linkto(ref, contents) {
        return linklabelto("", ref, contents)
      }

      function linklabel(label, contents) {
        return linklabelto(label, "", contents)
      }
      function sgmlwrap(tag, s) {
        return "<" tag ">" s "</" tag ">"
      }
      function image(s) {
        gsub(/"/, "\\\"", s)
        return "\"" s "\""
      }
      function escapeSpecials (l) {
        gsub(/&/, "\\&amp;", l)
        gsub(/</, "\\&lt;", l)
        gsub(/>/, "\\&gt;", l)
        gsub(/"/, "\\&quot;", l)
        return l
      }
      function convquotes(s, r, i, line) {
        r = ""
        while (i = index(s, "[[")) {
          r = r substr(s, 1, i-1) "<code>"
          s = substr(s, i+2)
          if (i = match(s, "\\]\\]+")) {
            line = substr(s, 1, i-1+RLENGTH-2)
            # line = escapeSpecials(line)  # destroys internal markup --- do not call
            r = r line "</code>"
            s = substr(s, i+RLENGTH)
          } else {
            r = r s "</code>"
            s = ""
          }
        }
        return r s
      }
      BEGIN { 
        defns[0] = 0
        defns_above[0] = 0
        useitemstab[0] = 0 
      }
      !doneraw { # do not do in BEGIN because not all awks assign variables yet
         if (raw) { braw = "\\begin{rawhtml}"; eraw = "\\end{rawhtml}" }
         else       braw = eraw = "" 
         doneraw = 1
         if (!nocomment) {
           print braw "<!-- this file was generated automatically by noweave;" " better not edit it-->" eraw
         }
      }
      /^@begin code / { code = 1; printf "%s<pre>", braw; ecode = "</pre>" }
      /^@end code /   { code = 0; previscode = 1; useitemscount = split(useitemstab[thischunk], a)
                                                  if (pendingprev != "" || pendingnext != "" || useitemscount > 0) {
                                                    if (ecode == "</pre>") {
                                                      printf "</pre><blockquote>"
                                                      ecode = "</blockquote>"
                                                    }
                                                    useprefix = "Used "
                                                    for (j = 1; j <= useitemscount; j++) {
                                                      if (defns_above[a[j]] > 0)
                                                        usedir = "above"
                                                      else
                                                        usedir = "below"
                                                      printf "%s%s", useprefix, linkto(a[j], usedir (useitemscount > 1 ? " (" j ")" : ""))
                                                      useprefix = ", "
                                                    }
                                                    if (useitemscount > 0 && (pendingprev != "" || pendingnext != "")) 
                                                      printf "; "
                                                    p = useitemscount > 0 ? "previous" : "Previous"
                                                    n = useitemscount > 0 ? "next"     : "Next"
                                                    if (pendingprev != "")
                                                      if (pendingnext != "")
                                                        printf "%s and %s definitions", linkto(pendingprev, p), linkto(pendingnext, "next")
                                                      else
                                                        printf "%s definition", linkto(pendingprev, p)
                                                    else
                                                      if (pendingnext != "")
                                                        printf "%s definition", linkto(pendingnext, n)
                                                    pendingprev = pendingnext = ""
                                                    useitems = ""
                                                    print ".<p>"
                                                  }
                        printf "%s%s", ecode, eraw 
                      }
      /^@begin docs / { if (previscode) printf "%s", (raw ? "\\par" : "<p>") 
                        previscode = text = 0
                      }
      /^@end docs /   { if (lastxreflabel != "")
                          printf "%s%s%s\n", braw, linklabel(lastxreflabel, "*"), eraw
                        lastxreflabel = ""
                      }
      /^@text /       { line = substr($0, 7); text += length(line)
                        if (code) {
                          if (lastindexref != "" && line ~ /[^ \t]/) {
                            printf "%s", linkto(lastindexref, line)
                            lastindexref = ""
                          } else {
                            printf "%s", escapeSpecials(line)
                          }
                        } else if (quoting) {
                          if (line ~ /[^ \t]/) {
                            printf "%s", linklabelto(lastxreflabel, lastindexref,
                                                     escapeSpecials(line))
                            lastindexref = lastxreflabel = ""
                          } else {
                            printf "%s", escapeSpecials(line)
                          }
                        } else {
                          if (lastxreflabel != "" && line ~ /[^ \t]/) {
                            match(line, /^[ \t]*/)
                            blanks = substr(line, RSTART, RLENGTH)
                            line = substr(line, RSTART+RLENGTH)
                            if (line ~ /^[{}\\<&]/) {
                              char = "*"
                            } else {
                              char = substr(line, 1, 1)
                              line = substr(line, 2)
                            }
                            printf "%s%s%s%s%s", braw, blanks, linklabel(lastxreflabel, char), eraw, line
                            if (lastxreflabel != "") defns_above[lastxreflabel] = 1
                            lastxreflabel = ""
                          } else {
                            printf "%s", line
                          }
                       }
                     }
      /^@nl$/   { print "" }
      /^@defn / { thischunk = name = substr($0, 7)
                  if (lastxreflabel != "") defns_above[lastxreflabel] = 1
                  writechunk(lastxreflabel, lastxrefref, "dfn", name, defns[name] "=")
                  lastxreflabel = lastxrefref = ""
                  defns[name] = "+"
                }
      /^@use / { writechunk(lastxreflabel, lastxrefref, "i", substr($0, 6), "") }
      /^@quote$/         { quoting = 1 ; printf "%s<code>",  braw }
      /^@endquote$/      { quoting = 0 ; printf "</code>%s", eraw }
      /^@file /          { filename = substr($0, 7); lastxreflabel = lastxrefref = "" }
      /^@literal /       { printf "%s", substr($0, 10) }
      /^@header html /   { printf "<html><head><title>%s</title></head><body>", substr($0, 14)
 }
      /^@trailer html$/  { print "</body></html>" }
      /^@xref label /    { lastxreflabel = substr($0, 13) }
      /^@xref ref /      { lastxrefref   = substr($0, 11) }
      /^@xref prevdef/   { pendingprev   = substr($0, 15) }
      /^@xref nextdef/   { pendingnext   = substr($0, 15) }
      /^@xref beginuses/ { useitems = "" }
      /^@xref useitem /  { useitems = useitems " " substr($0, 15) }
      /^@xref enduses/   { useitemstab[thischunk] = useitems }
      /^@xref notused /  { if (ecode == "</pre>") {
                             printf "</pre><blockquote>"
                             ecode = "</blockquote>"
                           }
                            printf "This code is written to a file (or else not used).<p>"
                         }
      /^@xref (begindefs|defitem|enddefs)/ { }
      /^@xref beginchunks$/ { printf "%s<ul>\n", braw }
      /^@xref chunkbegin /  { label = $3; name = substr($0, 19 + length(label))
                              printf "<li>"; comma = ": "; count = 0
                              writechunk("", label, "i", name, "")
                            }
      /^@xref chunkuse /    { printf "%s%s", comma, linkto(substr($0, 16), "U" ++count)
                              comma = ", "
                            }
      /^@xref chunkdefn /   { printf "%s%s", comma, linkto(substr($0, 17), "D" ++count)
                              comma = ", "
                            }
      /^@xref chunkend$/    { print "" }
      /^@xref endchunks$/   { printf "</ul>%s\n", eraw }
      /^@index beginindex$/  { if (!noindex) { printf "%s<ul>\n", braw } }
      /^@index entrybegin /  { if (!noindex) { 
                               label = $3; name = substr($0, 20 + length(label)) 
                               printf "<li>"; comma = ": "; count = 0
                               printf "%s", 
                                  linklabelto("NWI-" escapeSpecials(name), label, name) 
                               
                             } }
      /^@index entryuse /    { if (!noindex) {
                               printf "%s%s", comma, linkto(substr($0, 17), "U" ++count)
                               comma = ", " 
                             } }
      /^@index entrydefn /   { if (!noindex) {
                                 printf "%s%s", comma, linkto(substr($0, 18), "D" ++count)
                                 comma = ", " 
                             } }
      /^@index entryend$/    { if (!noindex) { print "" } }
      /^@index endindex$/    { if (!noindex) { printf "</ul>%s\n", eraw } }
      /^@index use/       { lastindexref = lastxrefref; lastxrefref = "" }
      /^@index defn/      { lastxreflabel = lastxrefref = "" }
      /^@index localdefn/ { lastxreflabel = lastxrefref = "" }
      /^@index nl/        { }  # do nothing -- destroys line numbering
      /^@index begindefs/ { if (localindex) {
         if (ecode == "</pre>") {
           printf "</pre><blockquote>"
           ecode = "</blockquote>"
         }; printf "Defines"; comma = " " 
      } }
      /^@index isused /   { }
      /^@index defitem /  { if (localindex) { 
         arg = substr($0, 16) 
         printf "%s%s", comma, 
             linkto("NWI-" escapeSpecials(arg), sgmlwrap("code", escapeSpecials(arg)))
         comma = ", "
      } }
      /^@index enddefs/   { if (localindex) { printf " (links are to index).<p>\n" } }
      /^@index (beginuses|isdefined|useitem|enduses)/ { }   # use local links
      END   { print "" }' \
   delay=$delay raw=$raw localindex=$localindex noindex=$noindex nocomment=$nocomment
