#!/bin/sh
LIB=|LIBDIR|
# Copyright 1991-2018 by Norman Ramsey.  All rights reserved.
# See file COPYRIGHT for more information.
# Don't try to understand this file!  Look at lib/totex.nw in the noweb source!
delay=0 noindex=0
for i do
  case $i in
    -delay)   delay=1   ;;
    -noindex) noindex=1 ;;
    *) echo "This can't happen -- $i passed to totex" 1>&2 ; exit 1 ;;
  esac
done
nawk 'BEGIN              { code=0 ; quoting=0 ; text=1; defns[0] = 0
                                                        ulist[0] = 0 }
      /^@begin code/     { code=1 ; printf "\\nwbegincode{%s}", substr($0, 13) }
      /^@end code/       { code=0 ; printf "\\nwendcode{}"; lastdefnlabel = "" }
      /^@begin docs 0$/ { if (delay) next }
      /^@end docs 0$/   { if (delay) { 
                            printf "\\nwfilename{%s}", filename; delay=0; next
                          } }
      /^@begin docs/     { text=0 ; printf "\\nwbegindocs{%s}", substr($0, 13) }
      /^@end docs/       {          printf "\\nwenddocs{}" }
      /^@text /          { line = substr($0, 7) ; text += length - 6
                           if (code)         printf "%s", escape_brace_bslash(line) 
                           else if (quoting) printf "%s", TeXliteral(line)
                           else              printf "%s", line
                         }
      /^@nl$/            { if (!code) {if (text==0) printf "\\nwdocspar"
                                       text=1}
                           if (quoting) printf "\\nwnewline"
                           printf "\n" 
                         }
      /^@defn /          { name = substr($0, 7); if (lastxreflabel != "") {
                                                   printf "\\sublabel{%s}", lastxreflabel
                                                   printf "\\nwmargintag{%s}", label2tag(lastxreflabel)
                                                 }
                                                 printf "\\moddef{%s%s}\\%sendmoddef", convquotes(name), (lastxrefref != "" ? ("~" label2tag(lastxrefref)) : ""), defns[name]
                                                 lastdefnlabel = lastxreflabel
                                                 lastxreflabel = lastxrefref = ""
                                                 defns[name] = "plus" }
      /^@use /           { printf "\\LA{}%s%s\\RA{}", 
                               convquotes(substr($0, 6)), (lastxrefref != "" ? ("~" label2tag(lastxrefref)) : "") 
                         }
      /^@quote$/         { quoting = 1 ; printf "{\\tt{}" }
      /^@endquote$/      { quoting = 0 ; printf "}" }
      /^@file /          { filename = substr($0, 7); lastxreflabel = lastxrefref = ""
                           if (!delay) printf "\\nwfilename{%s}", filename 
                         }
      /^@literal /       { printf "%s", substr($0, 10) }
      /^@header latex /  { printf "\\documentclass{article}\\usepackage{noweb}\\pagestyle{noweb}\\noweboptions{%s}%s",
                                  substr($0, 15),  "\\begin{document}" }
      /^@header tex /    { printf "\\input nwmac " }
      /^@trailer latex$/ { print "\\end{document}" }
      /^@trailer tex$/   { print "\\bye" }
      /^@xref label /     { lastxreflabel = substr($0, 13) }
      /^@xref ref /       { lastxrefref   = substr($0, 11) }
      /^@xref begindefs$/ { printf "\\nwalsodefined{" }
      /^@xref defitem /   { printf "\\\\{%s}", substr($0, 15) }
      /^@xref enddefs$/   { printf "}" }
      /^@xref beginuses$/ { printf "\\nwused{" }
      /^@xref useitem /   { printf "\\\\{%s}", substr($0, 15) }
      /^@xref enduses$/   { printf "}" }
      /^@xref notused /   { printf "\\nwnotused{%s}", TeXliteral(substr($0, 15)) }
      /^@xref nextdef /   { } 
      /^@xref prevdef /   { } 
      /^@xref beginchunks$/             { }
      /^@xref chunkbegin /              { label = $3; name = substr($0, 19 + length(label)) 
                                          printf "\\nwixlogsorted{c}{{%s}{%s}{",
                                            convquotes(name), label
                                        }
      /^@xref chunkuse /                { printf "\\nwixu{%s}", substr($0, 16) }
      /^@xref chunkdefn /               { printf "\\nwixd{%s}", substr($0, 17) }
      /^@xref chunkend$/                { print "}}%" }
      /^@xref endchunks$/               { }
      /^@index nl$/               { print (code ? "\\eatline" : "%") }
      /^@index defn / {
               if (!noindex) { arg = substr($0, 13); if (lastxreflabel != "") printf "\\nosublabel{%s}", lastxreflabel
                                                     if (lastxrefref != "")
                                                       printf "\\nwindexdefn{%s}{%s}{%s}", TeXliteral(arg), indexlabel(arg), lastxrefref
                                                     lastxreflabel = lastxrefref = "" } }
      /^@index localdefn / {
               if (!noindex) { arg = substr($0, 18); if (lastxreflabel != "") printf "\\nosublabel{%s}", lastxreflabel
                                                     if (lastxrefref != "")
                                                       printf "\\nwindexdefn{%s}{%s}{%s}", TeXliteral(arg), indexlabel(arg), lastxrefref
                                                     lastxreflabel = lastxrefref = "" } }
      /^@index use /  {
               if (!noindex) { arg = substr($0, 12); if (!code) {
                                                       if (lastxreflabel != "") printf "\\protect\\nosublabel{%s}", lastxreflabel
                                                       if (lastxrefref != "")
                                                         printf "\\protect\\nwindexuse{%s}{%s}{%s}", 
                                                                     TeXliteral(arg), indexlabel(arg), lastxrefref
                                                     }
                                                     lastxreflabel = lastxrefref = "" } }
      /^@index begindefs$/ { if (!noindex) { printf "\\nwidentdefs{" } }
      /^@index isused /    { if (!noindex) { } } # handled by latex
      /^@index defitem /   { if (!noindex) { i = substr($0,16); printf "\\\\{{%s}{%s}}", TeXliteral(i), indexlabel(i) } }
      /^@index enddefs$/   { if (!noindex) { printf "}" } }
      /^@index beginuses$/ { if (!noindex) { printf "\\nwidentuses{"; ucount = 0 } }
      /^@index isdefined / { if (!noindex) { } } # latex finds the definitions
      /^@index useitem /   { if (!noindex) { i = substr($0, 16); printf "\\\\{{%s}{%s}}", TeXliteral(i), indexlabel(i) 
                                         ulist[ucount++] = i
                                       } }
      /^@index enduses$/   { if (!noindex) { printf "}"; if (lastdefnlabel != "") {
                                                           for (j = 0; j < ucount; j++)
                                                             printf "\\nwindexuse{%s}{%s}{%s}", 
                                                                         TeXliteral(ulist[j]), indexlabel(ulist[j]), lastdefnlabel
                                                         } } }
      /^@index beginindex$/ { if (!noindex) { } }
      /^@index entrybegin / { if (!noindex) { label = $3; name = substr($0, 20 + length(label)) 
                                          printf "\\nwixlogsorted{i}{{%s}{%s}}%%\n", 
                                            TeXliteral(name), indexlabel(name)
                                        } }
      /^@index entryuse /   { if (!noindex) { } } # handled by latex
      /^@index entrydefn /  { if (!noindex) { } } # handled by latex
      /^@index entryend$/   { if (!noindex) { } }
      /^@index endindex$/   { if (!noindex) { } }

      END                { printf "\n" }
      function label2tag(label) {
        return "{\\nwtagstyle{}\\subpageref{" label "}}"
      }
      function escape_brace_bslash(line) {
        gsub(/[\\{}]/, "\n&", line)
        gsub(/\n/, "\\", line)
        return line
      }
      function convquotes(s, r, i) {
        r = ""
        while (i = index(s, "[[")) {
          r = r substr(s, 1, i-1) "\\code{}"
          s = substr(s, i+2)
          if (i = match(s, "\\]\\]+")) {
            r = r TeXliteral(substr(s, 1, i-1+RLENGTH-2)) "\\edoc{}"
            s = substr(s, i+RLENGTH)
          } else {
            r = r s "\\edoc{}"
            s = ""
          }
        }
        return r s
      }
      function indexlabel(ident, l) {
        l = ident
        gsub(/:/,  ":col", l)         # must be first  (colon)
        gsub(/ /,  ":sp",  l)      # space
        gsub(/#/,  ":has", l)     # hash
        gsub(/\$/, ":do",  l)      # dollar
        gsub(/%/,  ":pe",  l)      # percent
        gsub(/&/,  ":am",  l)      # ampersand
        gsub(/,/,  ":com", l)     # commad
        gsub(/\\/, ":bs",  l)      # backslash
        gsub(/\^/, ":hat", l)     # hat
        gsub(/_/,  ":un",  l)      # underscore
        gsub(/{/,  ":lb",  l)      # left brace
        gsub(/}/,  ":rb",  l)      # right brace
        gsub(/~/,  ":ti",  l)      # tilde
        return l
      }
      function TeXliteral(arg) {
        gsub(/\\/, "<\\char92>",  arg)
        gsub(/}/,  "<\\char125}", arg)
        gsub(/{/,  "{\\char123}", arg)
        gsub(/<\\char/, "{\\char", arg)
        gsub(/{\\char92>/, "{\\char92}", arg)
        gsub(/\$/, "{\\char36}",  arg)
        gsub(/&/,  "{\\char38}",  arg)
        gsub(/#/,  "{\\char35}",  arg)
        gsub(/\^/, "{\\char94}",  arg)
        gsub(/_/,  "{\\char95}",  arg)
        gsub(/%/,  "{\\char37}",  arg)
        gsub(/~/,  "{\\char126}", arg)
        gsub(/ /,  "\\ ",         arg)
        return arg
      }' delay=$delay noindex=$noindex
