program define tabout8

* for use with Stata 8.2
* replaced by tabout 30nov2006 (requires Stata 9.2)
* 1.2.0 Ian Watson 13mar2005
* 1.1.8 Ian Watson 30nov2004
* 1.1.0 Ian Watson 28oct2004
* Program to produce publication quality cross-tabulations


version 8.2
syntax varlist [if] [in] [fweight aweight iweight] using/ ///
   [, REPlace APPend Cells(string) oneway Format(string) ///
   stats(string) n(string) ///
   style(string) lines(string) font(string) bt NOBORDer ///
   total(string) header1(string) header2(string) header3(string) ///
   LEFTHead(string) NOHEADer NOTOTals(string) ///
   body topf(string) botf(string) topstr(string) botstr(string) ///
   PSYMBol(string) DELIM(string) ///
   show(string) LABWidth(int 20) COLWidth(int 11) TABWidth(string)]



tempvar touse
mark `touse' `if' `in'

local varcnt : word count `varlist'

* store existing linesize for resetting on exit

global oldsize=c(linesize)


* set defaults for key macros

local sstats 0
local dstats 0
global dpanel 0
local fcnt 0
local fper 0
local fcum 0
local content 3 // default for cross-tabulations
global nogood 0
local skip 1
local do_N 0
local do_Nc 0
local do_Nl 0

* check parsing and set defaults
* note that only first term in summary stats is checked here
* remainders are checked within the sstats loop


if "`cells'" ~= ""{
   local fword : word 1 of `cells'
      if index("double row col count fcount fper fcum","`fword'") ~= 0 {
         local sstats 0
         if index("`cells'","fcount") ~= 0 local fcnt 1
         if index("`cells'","fper") ~= 0 local fper 1
         if index("`cells'","fcum") ~= 0 local fcum 1
         if index("`cells'","double") ~= 0 global dpanel 1
         if index("`cells'","row") ~= 0 local content 1
         if index("`cells'","col") ~= 0 local content 2
         if index("`cells'","count") ~= 0 local content 3
      }
* following lines need splitting because of Intercooled string limits
      else if ///
         index("N mean var sd skewness kurtosis sum min max","`fword'") ~= 0 | ///
         index("p1 p5 p10 p25 p50 p75 p90 p95 p99","`fword'") ~= 0 | ///
         index("count median iqr r9010 r9050 r7525 r1050","`fword'") ~= 0 {
            local sstats 1
            local numstats : word count `cells'
            local numstats = `numstats'/2 // because each stat is paired with a var
            if index("iqr r9010 r9050 r7525 r1050","`fword'") ~= 0 local dstats 1
      }
      else {
         di as err "The first term you entered in the cells option is incorrect"
         clearglobs
         exit
      }
   }

if `fcnt' == 0 & `fper' == 0 & `fcum' == 0 local fcnt 1 // default for freq tables

* note sstats is summary stats
* dstats is distribution stats, a subset of sstats


if "`oneway'"~="" {
   local crtabs 0
   if `sstats' == 1 {
      local stwidth = `numstats'
      local fstwidth = `numstats' +1
      }
   }
   else {
      if `varcnt' > 1 local crtabs 1
      else local crtabs 0
      if `sstats' == 1 {
         local stwidth = `numstats'
         local fstwidth = `numstats' +1
      }
   }


if "`stats'"~="" {
   local chiword1: word 1 of `stats'
   if "`chiword1'" == "chi2" {
      if `varcnt'~=2 | `crtabs'~=1 {
         di as err "Chi2 only possible with simple two-way tables."
         di as err "You either have more than 2 variables,"
         di as err "or you have specified the oneway option."
         clearglobs
         exit
      }
      else {
         local dochi=1
         local chiword = "chi2"
         local chistr = ""
         local chiword2: word 2 of `stats'
         if "`chiword2'" ~= "" local chidec `chiword2'
            else local chidec 3
         local chiword3: word 3 of `stats'
         if "`chiword2'" ~= "" local pdec `chiword3'
            else local pdec 3

      }
   }
   else {
      di
      di as err "The exact term chi2 is the only acceptable term"
      di as err "for the stats option. No statistics will be processed."
      di
      local dochi=0
      }
}
else local dochi=0

* check that all variable values have labels

local warnlist1=""
local warnlist2=""

   foreach v of local varlist {
      local var_label : variable label `v'
      local val_label : value label `v'
      if "`var_label'" =="" {
         local warnlist1 = "`warnlist1' `v'"
      }
      if "`val_label'" =="" {
         local warnlist2 = "`warnlist2' `v'"
      }
   }
   if "`warnlist1'" ~= "" | "`warnlist2'" ~= ""{
      if "`warnlist1'" ~= "" {
         di
         di as err "Variable(s) `warnlist1' without variable labels."
         di as err "All variables must have labels."
         di
      }
      if "`warnlist2'" ~= "" {
         di
         di as err "Variable(s) `warnlist2' without value labels."
         di as err "All variables must have value labels."
         di
      }
      clearglobs
      exit
   }


if "`append'" == "append" {
   local opt "append"
}
else if "`replace'" == "replace" {
   local opt "replace"
}

* parse remaining syntax and assign to macros
* note the use of some global macros because of sub-routines

if `crtabs' == 0 {
   if `varcnt' == 1 local single 1
   else local single 0
   }
   else {
      if `varcnt' == 2 local single 1
      else local single 0
   }


   if "`format'" ~= "" {
      local numforms: word count `format'
      if `numforms' == 1 {
         local form  "`format'"
         global form "`format'"
      }
      else {
      local form : word 1 of `format'
      global form : word 1 of `format'
      global form1 : word 1 of `format'
      global form2 : word 2 of `format'
      }
   }
   else {
      local numforms 1
      local format "%9.0fc"
      local form "%9.0fc"
      global form "%9.0fc"
      global form1 "%9.0fc"
      global form2 "%9.1f"
   }

   if "`delim'" ~= "" {
      global dl "`delim'"
   }
   else {
      global dl "|"
   }


if "`n'"~="" {
   tokenize "`n'", parse("$dl")
   local Nloc `1'
   if "`Nloc'" ~= "" {
      if "`Nloc'" == "col" | "`Nloc'" == "lab" {
         local Nform "%9.0fc"
         local do_N 1
         if "`Nloc'"=="col" local do_Nc 1
         else if "`Nloc'"=="lab" local do_Nl 1
      }
      else {
            di as err "Only col or lab can be entered for location."
            clearglobs
            exit
     }
   }
   local Nlabel `3'
   if "`Nloc'"=="col" {
      if "`Nlabel'" == "d" local Nlabel "n"
      else local Nlabel = subinstr("`Nlabel'"," ","_",.)
   }
   else if "`Nloc'"=="lab" {
      if "`Nlabel'" == "d" {
         local Nlab1 "(n_=_"
         local Nlab2 ")"
       }
       else {
             local Nlabel = subinstr("`Nlabel'"," ","_",.)
             local p = index("`Nlabel'","#")
             local q = length("`Nlabel'")
             local Nlab1 = substr("`Nlabel'",1,`p'-1)
             local Nlab2 = substr("`Nlabel'",`p'+1,`q'-`p')
      }
   }
   local Nwt `5'
   if "`Nwt'" == "d" local Nweight ""
   else local Nweight "[iweight = `Nwt']"
   }




   if "`total'" ~="" {
     tokenize "`total'", parse("$dl")
     local vword `1'
     local hword `3'
   }
   else {
      local hword = "Total"
      local vword = "Total"
   }


   if "`show'" ~= "" {
      if "`show'" =="all" {
         local scr 1
         local cod 1
         }
      else if "`show'" == "table" {
         local scr 1
         local cod 0
         }
      else if "`show'" == "code" {
         local scr 0
         local cod 1
         }
      else if "`show'" == "none" {
         local scr 0
         local cod 0
         }
   }
   else {
      local scr 1
      local cod 0
      }

local rule = cond("`bt'" ~= "", "\\midrule", "\\hline")
local bcode = cond("`body'" ~= "", 1, 0)
local border = cond("`noborder'" ~= "", "", " border=3")


   if "`lines'" ~= "" {
      if "`lines'" == "double" {
         local lspace 2
      }
      else if "`lines'" == "blank" {
         local lspace 3
      }
      else if "`lines'" == "none" {
         local lspace 0
      }
      else local lspace 1
   }
   else local lspace 1

* lefthead moves vertical var lab up & down within headers - default is empty

   if "`lefthead'"~="" {
      if index("1 2 3","`lefthead'") ~= 0 local lefthd "`lefthead'"
      else local lefthd ""
      }
      else local lefthd ""


   if "`font'" ~= "" {
      if "`font'" == "bold" local tfont "bold"
         else if "`font'" == "italic"  local tfont "italic"
            else local tfont "plain"
   }
   else local tfont "plain"

local prefile = cond("`topf'" ~= "", "`topf'" , "")
local postfile = cond("`botf'" ~= "", "`botf'", "")
local topinsert = cond("`topstr'" ~= "", "`topstr'", "")
local botinsert = cond("`botstr'" ~= "", "`botstr'", "")


* no default for ps b/c its contents signals entry into loop later


global ps = cond("`psymbol'" ~= "", "`psymbol'", "")
local dotop = cond("`topinsert'" ~= "" & "$ps" ~= "", 1, 0)
local dobot = cond("`botinsert'" ~= "" & "$ps" ~= "", 1, 0)



if "`header1'" ~="" local topstring1 = "`header1'"
if "`header2'" ~="" local topstring2 = "`header2'"
if "`header3'" ~="" local topstring3 = "`header3'"

local blankhead = cond("`noheader'" ~= "", 1, 0)

   if "`nototals'" ~= "" {
      local dotot 0
      local glbtot "`nototals'"
   }
   else {
      local dotot 1
      local glbtot ""
   }

* set tab delimitted as default output

   if "`style'" ~= "" {
      if "`style'" == "tex" {
         local out 1
      }
      else if "`style'" == "html" {
         local out 2
      }
      else if "`style'" == "tab" {
         local out 3
      }
      else {
         local out 3
      }
   }
   else local out 3

* tablewidth is string, not integer, so that can be left
* alone if need be
   if "`tabwidth'" ~= "" {
      local tabw =  "`tabwidth'"
      set linesize `tabw'
   }
   else {
      local tabw =  ""
   }

* other widths are integers, only need for screen display

local labw = min(max(`labwidth',8),60)
local gap=min(max(`colwidth',6),30)
local dgap = `gap'*2

* PROGRAM PROPER BEGINS HERE
* fill the matrices with tabulate results

local nvars : word count `varlist'
local hvar : word `nvars' of `varlist'
local hlen=length("`hvar'")
local vlen=length("`varlist'")-(`hlen'+1)
local vvar=substr("`varlist'",1,`vlen')

* check first for maximum number of values in the
* horizontal variable - needed for cross-tabulation stacked tables

qui ta `hvar' `hvar' [`weight' `exp'] if `touse', matcol(hvals)
local lgesize = colsof(hvals)


* tables for tables which are not summary stats
* one-wayfrequency tables

if `sstats' == 0 {
   if `crtabs' == 0 {
      local vcnt=0
      foreach v of local varlist {
         local vcnt=`vcnt'+1
         qui ta `v' [`weight' `exp'] if `touse', matcell(newmat) ///
            matrow(newrow)
         local valnames = ""
         local labelname : value label `v'
         local r = rowsof(newmat)
         local l = `r' + 1
         mat labs = J(`l',1,-9)
         mat counts = J(`l',1,0)
         mat percents = J(`l',1,0)
         mat cums = J(`l',1,0)
         local countsum = 0
         forval z = 1/`r'{
                  mat counts[`z',1] = newmat[`z',1]
                  local countsum = `countsum' + newmat[`z',1]
                  mat labs[`z',1] = newrow[`z',1]
               }
         mat counts[`l',1] = `countsum'
         forval z = 1/`r'{
                  mat percents[`z',1] = counts[`z',1]/`countsum'*100
                  if `z' == 1 {
                     mat cums[`z',1] = percents[`z',1]
                  }
                  else {
                     mat cums[`z',1] = percents[`z',1] + cums[`z'-1,1]
                  }
         }
         mat percents[`l',1] = 100
         mat cums[`l',1] = .
         mat freq = labs,counts,percents,cums
         if `vcnt' == 1 mat full = freq
         else mat full = full\freq
      } // end foreach var
   } // if crtabs == 0

   else {

*begin cross-tabulations
   local vcnt=0
   foreach v of local vvar{
      local vcnt=`vcnt'+1
      qui ta `v' `hvar'  [`weight' `exp'] if `touse', matcell(newmat) ///
         matrow(newrow) matcol(newcol) `chiword'
      if `do_N' qui ta `v' `hvar'  `Nweight' if `touse', matcell(Nmat)
      if `dochi' == 1 {
         local df =  (r(r)-1)*(r(c)-1)
         local chival = string(r(chi2),"%9.`chidec'f")
         local pval = string(r(p),"%9.`pdec'f")
         local chistr "Pearson chi-square (`df' df) =" ///
         " `chival', probability = `pval'"
      }
      local valnames = ""
      local labelname : value label `v'
      local r = rowsof(newmat)
      local c = colsof(newmat)
      local l = `lgesize'
      local j = colsof(newcol)
      mat counts = J(`r',`l',0)
      mat Ncounts = J(`r',`l',0)
      mat rownumber = J(`r',1,0)
      mat colnumber = J(1,`l',-9)
      mat rowtot = J(`r',1,0)
      mat Nrowtot = J(`r',1,0)
      forval z = 1/`r'{
      local y = 1
         while `y' < (`j'+1) {
            forval x = 1/`l'{
               if newcol[1,`y'] == hvals[1,`x'] {
                  if newmat[`z',`y'] == . mat counts[`z',`x'] = 0
                     else mat counts[`z',`x'] = newmat[`z',`y']
                  if `do_N' mat Ncounts[`z',`x'] = Nmat[`z',`y']
                  local y = `y'+1
               }
            }
         }
      }
      local c = `l'
      local finalw = `c'+1
      mat coltot = J(1,`finalw',0)
      mat Ncoltot = J(1,`finalw',0)
      forval z=1/`r'{
         forval x=1/`c'{
            mat rowtot[`z',1] = rowtot[`z',1] + counts[`z',`x']
            if `do_N' mat Nrowtot[`z',1] = Nrowtot[`z',1] + Ncounts[`z',`x']
            mat coltot[1,`x'] = coltot[1,`x'] + counts[`z',`x']
            if `do_N' mat Ncoltot[1,`x'] = Ncoltot[1,`x'] + Ncounts[`z',`x']
         }
         mat coltot[1,`finalw']= coltot[1,`finalw'] + rowtot[`z',1]
         if `do_N' mat Ncoltot[1,`finalw']= Ncoltot[1,`finalw'] + Nrowtot[`z',1]

      }
      mat wider = counts,rowtot
      mat longer = wider\coltot
      mat cellcnt = longer
      if `do_N' {
         mat Nwider = Ncounts,Nrowtot
         mat Nlonger = Nwider\Ncoltot
         mat Ncellcnt = Nlonger
      }

* matrix with cell counts complete
* convert to percentages

      local r = rowsof(cellcnt)
      local c = colsof(cellcnt)
      mat colp = J(`r',`c',0)
      forval z = 1/`r'{
         forval x = 1/`c'{
            if cellcnt[`r',`x'] ~= 0 {
               mat colp[`z',`x'] = cellcnt[`z',`x']/cellcnt[`r',`x']*100
            }
            else {
               mat colp[`z',`x'] = 0
            }
         }
      }
      mat rowp=J(`r',`c',0)
      forval z=1/`r'{
         forval x=1/`c'{
            if cellcnt[`z',`c'] ~= 0 {
               mat rowp[`z',`x']=cellcnt[`z',`x']/cellcnt[`z',`c']*100
            }
            else {
               mat rowp[`z',`x'] = 0
            }
         }
      }
      mat blankrow=J(1,1,-9)
      mat rownumber=newrow\blankrow
      if `vcnt'==1{
         mat colper=colp
         mat rowper=rowp
         mat noper=cellcnt
         mat allrownumbers=rownumber
         if `do_N' mat Ncnt=Ncellcnt
      }
      else {
         mat colper=colper\colp
         mat rowper=rowper\rowp
         mat noper=noper\cellcnt
         mat allrownumbers=allrownumbers\rownumber
         if `do_N' mat Ncnt=Ncnt\Ncellcnt
      }
   }


* combine data matrices with labels into display matrix

      if $dpanel ~= 1 {
         if `content'==1 mat full=allrownumbers,rowper
         else if `content'==2 mat full=allrownumbers,colper
         else if `content'== 3 mat full=allrownumbers,noper
      }
      else {
         mat fullcnt = allrownumbers,noper
         mat fullcol = allrownumbers,colper
         local ocols = colsof(fullcnt)
         local ncols = ((`ocols'-1)*2)+1
         local nrows = rowsof(fullcnt)
         mat dcols = J(`nrows',`ncols',0)
         forval r = 1/`nrows' {
            mat dcols[`r',1] = fullcnt[`r',1]
         }
         local j = 2
         local k = 2
         forval c = 2/`ncols' {
            if mod(`c',2)==0 {
               forval r = 1/`nrows' {
                  mat dcols[`r',`c'] = fullcnt[`r',`j']
               }
               local j = `j'+1
            }
            else {
               forval r = 1/`nrows' {
                 mat dcols[`r',`c'] = fullcol[`r',`k']
               }
               local k = `k'+1
            }
         }
         mat full=dcols
      }
   } // if 2 or more variables
} // if sstats == 0

* summary statistics tables


if `sstats' == 1 {
   if `crtabs' == 0 {
      local vcnt=0
      foreach v of local varlist{
         local vcnt=`vcnt'+1
         qui ta `v' if `touse', matrow(newrow)
         local valnames = ""
         local labelname : value label `v'
         local r = rowsof(newrow)
         local c = `stwidth'
         local l = `fstwidth'
         local m = `r'+1
         mat vstats = J(`m',`l',0)
         forval z = 1/`m'{
            if `z' < `m' {
               local valnum = newrow[`z',1]
               mat vstats[`z',1] = `valnum'
            }
            else mat vstats[`z',1] = -9
            local f = 1
            local q = 2
            forval x = 2/`l'{
               local statkind : word `f' of `cells'
               warnstats "`statkind'"
                  if $nogood {
*                     clearglobs // commented out b/c exit is not working??
                     exit
                  }
               local statvar : word `q' of `cells'
               if `z' < `m' qui sum `statvar' [`weight' `exp'] if `touse' ///
                        & `v' == `valnum' , detail
               else qui sum `statvar' [`weight' `exp'] if `touse' ///
                        & !mi(`v'), detail
               if `dstats' == 1 { // change ratios here if require diff type
                  if "`statkind'" == "iqr" local statres = r(p75)-r(p25)
                  else if "`statkind'" == "r9010" local statres = r(p90)/r(p10)
                  else if "`statkind'" == "r9050" local statres = r(p90)/r(p50)
                  else if "`statkind'" == "r7525" local statres = r(p75)/r(p25)
                  else if "`statkind'" == "r1050" local statres = r(p10)/r(p50)
               }
               else {
                  if "`statkind'" == "median" local statkind "p50"
                  if "`statkind'" == "count" local statkind "N"
               local statres = r(`statkind')
               }
               mat vstats[`z',`x'] = `statres'
               local f = `f' + 2 // increment by 2 so that leapfrog to next stat
               local q = `q' + 2 // increment by 2 so that leapfrog to next var
            } //end of loop across the cols
         } // end of loop down the rows
         if `vcnt' == 1 mat full = vstats
         else mat full = full\vstats
      } // end of foreach var
   } // end of crtabs == 0
   else {
      local vcnt=0
      qui ta `hvar' if `touse', matrow(hvar_row)
      foreach v of local vvar{
         local vcnt=`vcnt'+1
         qui ta `v' if `touse', matrow(vvar_row)
         local valnames = ""
         local labelname : value label `v'
         local r = rowsof(vvar_row)
         local c = rowsof(hvar_row)
         local l = `c' + 2 // need 1 extra column for labels and 1 for totals
         local m = `r'+1
         mat vstats = J(`m',`l',0)
         forval z = 1/`m'{
            if `z' < `m' {
               local vvalnum = vvar_row[`z',1]
               mat vstats[`z',1] = `vvalnum'
            }
            else mat vstats[`z',1] = -9
            local f = 1
            local statkind : word 1 of `cells'
            warnstats "`statkind'"
               if $nogood {
*                  clearglobs // commented out b/c exit is not working??
                  exit
                }
            local statvar : word 2 of `cells'
            forval x = 2/`l'{
               local hvalnum = hvar_row[`f',1]
               if `z' < `m' {
                  if `x' < `l' qui sum `statvar' [`weight' `exp'] if `touse' ///
                        & `v' == `vvalnum' & `hvar' == `hvalnum', detail
                  else qui sum `statvar' [`weight' `exp'] if `touse' ///
                        & `v' == `vvalnum' &  !mi(`hvar'), detail
               }
               else {
                  if `x' < `l' qui sum `statvar' [`weight' `exp'] if `touse' ///
                        & !mi(`v') & `hvar' == `hvalnum', detail
                  else qui sum `statvar' [`weight' `exp'] if `touse' ///
                        & !mi(`v') & !mi(`hvar'), detail
              }
               if `dstats' == 1 { // change ratios here if require diff type
                  if "`statkind'" == "iqr" local statres = r(p75)-r(p25)
                  else if "`statkind'" == "r9010" local statres = r(p90)/r(p10)
                  else if "`statkind'" == "r9050" local statres = r(p90)/r(p50)
                  else if "`statkind'" == "r7525" local statres = r(p75)/r(p25)
                  else if "`statkind'" == "r1050" local statres = r(p10)/r(p50)
               }
               else {
                  if "`statkind'" == "median" local statkind "p50"
                  if "`statkind'" == "count" local statkind "N"
               local statres = r(`statkind')
               }
               mat vstats[`z',`x'] = `statres'
               local f = `f' + 1 // work way across the hvars
            } //end of loop across the cols
         } // end of loop down the rows
         if `vcnt' == 1 mat full = vstats
         else mat full = full\vstats
      } // end of foreach var
   } // end of crtabs == 1
} // end of sstats == 1

* data collection complete - now assemble headers

if `blankhead' == 0 { // if headers, continue, else jump straight to data
   if `single' == 1 {
      if `crtabs' == 0 local vlabel : variable label `varlist'
         else local vlabel : variable label `vvar'
      local leftlab = subinstr("`vlabel'"," ","_",.)
   }
   else local leftlab = "_"
   if `crtabs' == 0 { // begin one way tables
      local thecols ""
      if `sstats' == 0 { // begin freq tables
            local thecols ""
            if `fcnt' == 1 & `fper' == 1 & `fcum' == 1 ///
               local thecols "Number Per_cent Cum_Per_cent"
            if `fcnt' == 1 & `fper' == 0 & `fcum' == 0 ///
               local thecols "Number"
            if `fcnt' == 1 & `fper' == 1 & `fcum' == 0 ///
               local thecols "Number Per_cent"
            if `fcnt' == 1 & `fper' == 0 & `fcum' == 1 ///
               local thecols "Number Cum_Per_cent"
            if `fcnt' == 0 & `fper' == 1 & `fcum' == 1 ///
               local thecols "Per_cent Cum_Per_cent"
            if `fcnt' == 0 & `fper' == 1 & `fcum' == 0 ///
               local thecols "Per_cent"
            if `fcnt' == 0 & `fper' == 0 & `fcum' == 1 ///
               local thecols "Cum_Per_cent"
      } // if sstats == 0
      else if `sstats' == 1 { // begin multiple stats across cols
            local numstatvars : word count `cells'
            local l = `numstatvars'
            local q = 2
            forval x = 1/`l'{
               local statvar : word `q' of `cells'
               if "`statvar'" ~= "" local svlab : variable label `statvar'
               local svlab = subinstr("`svlab'"," ","_",.)
               if `q' == 2 local thecols "`svlab'"
                  else {
                  if "`statvar'" ~= "" local thecols "`thecols' `svlab'"
               }
               local q = `q' + 2
            }
      } // end sstats == 1
   } // end crtabs == 0

   else if `crtabs' == 1 { // begin two way tables
      local hlabel : variable label `hvar'
      local rightlab = subinstr("`hlabel'"," ","_",.)
      local thecols ""
      local xcols ""
      local k = colsof(hvals)
      local labelname: value label `hvar'
      local labelname = subinstr("`labelname'"," ","_",.)
      forval j = 1/`k' {
         local m = hvals[1,`j']
         local valnm: label `labelname' `m'
         local valnm = subinstr("`valnm'"," ","_",.)
         local thecols "`thecols' `valnm'"
      }
      local totword = "`hword'"
      local totword = subinstr("`totword'"," ","_",.)
      local thecols "`thecols' `totword'"
      if `do_Nc' local thecols "`thecols' `Nlabel'"
      if $dpanel == 1 { // double panel two way tables
         local k = colsof(hvals) + 1
         forval j = 1/`k' {
            local xcols "`xcols' Num %"
         }
      } // end dpanel == 1
   } // end two way tables

* check position of vertical var lab & assign contents to headers

   local head1 ="_"
   local head2 = "_"
   local head3 = "_"
   if "`leftlab'" == "" local leftlab "_"
   if "`lefthd'" ~= "" local head`lefthd' "`leftlab'"
      else {
         if $dpanel == 1 local head3 "`leftlab'"
         else local head2 "`leftlab'"
      }
   if `crtabs' == 1 {
      local head1 "`head1' `rightlab'"
      local head2 "`head2' `thecols'"
   }
   else local head2 "`head2' `thecols'"
   if $dpanel == 1 local head3 "`head3,' `xcols'"

* replace individual lines with user headers where applicable

   forval j = 1/3 {
      local uh`j' = 0 // uh1 to uh3 meaning user headers
      if "`topstring`j''" ~= "" {
         local sub`j' ""
         local head`j' ""
         tokenize "`topstring`j''", parse("$dl")
         if "`1'" ~= "_" local sub`j' = subinstr("`1'"," ","_",.)
            else local sub`j' "_"
         local head`j' "`head`j'' `sub`j''"
         mac shift 2
         while "`1'" ~= "" {
            local sub`j' = subinstr("`1'"," ","_",.)
            local head`j' "`head`j'' `sub`j''"
            mac shift 2
         }
      local uh`j' = 1
      }
   }
} // end blankhead == 0


* DATA & HEADERS
* send to screen (if chosen) and to tempfile

tempname outfile
tempfile tempfile

file open `outfile' using "`tempfile'", write

* values needed for correct screen display

   local lpos = `labw-1'
   local cpos = `labw'+1
   local pos= `gap'
   local numcols = colsof(full)-1
   file write `outfile' "`numcols'" _n
   if "`tabw'" ~= "" {
      local linewide = `tabw'-(`cpos'+1)
      }
      else {
         local linewide=c(linesize) -(`cpos'+1)
      }
   if `scr' di as text "{hline `cpos'}{c TT}{hline `linewide'}"

* headers only if noheader not specified, hence blankhead == 0


   if `blankhead' == 0 {
      forval j= 1/3 {
         local head`j'=ltrim("`head`j''")
         local head`j'=rtrim("`head`j''")
         if "`head`j''" ~= "_" | "`head`j''" ~= "_" {
            local numhcols: word count `head`j''
            local str`j': word 1 of `head`j''
            file write `outfile' "`str`j''"
            local str`j' = subinstr("`str`j''","_"," ",.)
            local str`j' = abbrev("`str`j''",`labw'-2)
            if `scr' di as text "{ralign `lpos': `str`j''}" _c
            if `scr' di as text "{col `cpos'} {c |}"  _c
            local tpos = `cpos'+3
            forval k = 2/`numhcols' {
               local str`j': word `k' of `head`j''
               file write `outfile' "$dl`str`j''"
               local str`j' = subinstr("`str`j''","_"," ",.)
               if `uh`j'' ~= 1 & `j'> 1{ //only fiddle for defaults below line 1
               local abbwide = `gap'
               if `j' == 2 & $dpanel == 1 local abbwide = `gap'*2
               local str`j' = abbrev("`str`j''",`abbwide'-1)
               if `scr' di as text "{ralign `abbwide': `str`j''}" _c
               }
               else if `scr' di as text "{ralign `gap': `str`j''}" _c
            }
         if `scr' di
         file write `outfile' _n
         }
      }
   if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}"
   file write `outfile' "linehere" _n
   } // if blankhead == 0

* begin (if `scr') displaying data & writing to tempfile

   if `crtabs' == 0 {
      local r=rowsof(full)+1
      local w=colsof(full)
      local p=1
      while `p' < `r' {
         foreach v of local varlist{
            local labelname: value label `v'
            local vname: variable label `v'
            if `single' == 0 {
               local v_name = subinstr("`vname'"," ","_",.)
               if "`glbtot'" == "`v'" {
                  local skip 0
                  file write `outfile' "@@`v_name'"
                  local vname = abbrev("`vname'",`labw'-2)
                  if `scr' di as text "{ralign `labw': `vname'} {c |}" _c
               }
               else {
                  local skip 1
                  file write `outfile' "`v_name'" _n
                  local vname = abbrev("`vname'",`labw'-2)
                  if `scr' di as text "{ralign `labw': `vname'} {c |}"
               }
            }
            local k=0
            while `k' ~= -9{
               local f=full[`p',1]
               local valnm: label `labelname' `f'
               local val_nm = subinstr("`valnm'"," ","_",.)
               if `skip' {
                  file write `outfile' "`val_nm' $dl"
                  local valnm = abbrev("`valnm'",`labw'-2)
                  if `scr' di as text "{ralign `labw': `valnm'}" _c
                  if `scr' di as text " {c |} " _c
               }
               else {
                  file write `outfile' " $dl"
               }
               local j=`w'-1
               local pos= `labw' + 5
               local whichcol ""
               if `sstats' == 0 {
                  local numfreq = 0
                  if `fcnt' ==1 {
                     local whichcol = "`whichcol' 2"
                     local numfreq = `numfreq'+1
                     }
                  if `fper' ==1 {
                     local whichcol = "`whichcol' 3"
                     local numfreq = `numfreq'+1
                     }
                  if `fcum' ==1 {
                     local whichcol = "`whichcol' 4"
                     local numfreq = `numfreq'+1
                     }
                  local z = 1
                  tokenize "`whichcol'"
                  forval x = 1/`numfreq' {
                     if `numforms'==1 local form "`format'"
                     else local form: word `z' of `format'
                     if `scr' di as res "{col `pos'}" `form' (full[`p',`1']) _c
                     file write `outfile' `form' (full[`p',`1'])
                     if `x' < `numfreq' file write `outfile' "$dl"
                     local pos = `pos' + `gap'
                     local z = `z'+1
                     macro shift
                  }
               if `scr' di
               file write `outfile' _n
               }
               else if `sstats' == 1 {
                  local z = 1
                  forval x=2/`j'{
                     if `numforms'==1 local form "`format'"
                        else local form: word `z' of `format'
                     if `scr' di as res "{col `pos'}" `form' (full[`p',`x']) _c
                     file write `outfile' `form' (full[`p',`x']) "$dl"
                     local pos = `pos' + `gap'
                     local z = `z'+1
                  }
               if `numforms'==1 local form "`format'"
               else local form: word `z' of `format'
               if `scr' di as res "{col `pos'}" `form' (full[`p',`w'])
               file write `outfile' `form' (full[`p',`w']) _n
               } // end if sstats == 1
               local p=`p'+1
               local k=full[`p',1]
            }
            local v_word = subinstr("`vword'"," ","_",.)
            if `single' == 1 {
               if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}"
               file write `outfile' "linehere" _n
            }
            if `dotot' file write `outfile' "`v_word' $dl"
            local totword = abbrev("`vword'",`labw'-2)
            if `scr' & `dotot' di as text "{ralign `labw': `totword'}" _c
            if `scr' & `dotot' di as text " {c |} " _c
            local pos= `labw' + 5
            if `sstats' == 0 {
               local z = 1
               tokenize "`whichcol'"
               forval x = 1/`numfreq' {
                  if `numforms'==1 local form "`format'"
                     else local form: word `z' of `format'
                  if `scr' & `dotot' di as res "{col `pos'}" `form' (full[`p',`1']) _c
                  if `dotot' file write `outfile' `form' (full[`p',`1'])
                  if `x' < `numfreq' & `dotot' file write `outfile' "$dl"
                  local pos = `pos' + `gap'
                  local z = `z' +1
                  macro shift
                  }
               if `scr' & `dotot' di
               if `dotot' file write `outfile' _n
            }
            else if `sstats' == 1{
               local z = 1
               forval x=2/`j'{
                  if `numforms'==1 local form "`format'"
                  else local form: word `z' of `format'
                  if `scr' & `dotot' di as res "{col `pos'}" `form' (full[`p',`x']) _c
                  if `dotot' file write `outfile' `form' (full[`p',`x']) "$dl"
                  local pos = `pos' + `gap'
                  local z = `z'+1
               }
               if `numforms'==1 local form "`format'"
               else local form: word `z' of `format'
               if `scr' & `dotot' di as res "{col `pos'}" `form' (full[`p',`w'])
               if `dotot' file write `outfile' `form' (full[`p',`w']) _n
            } // end if sstats == 1
            local p=`p'+1
            if `p'~=`r' {
               if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}"
               file write `outfile' "linehere" _n
            }
         }
      }
      if `scr' di as text "{hline `cpos'}{c BT}{hline `linewide'}"
   } // if crtabs == 0

   else if `crtabs' == 1 {
      local r=rowsof(full)+1
      local w=colsof(full)
      if `do_N' local numN = colsof(Ncnt) // needed if asking for N
      local p=1
      while `p' < `r' {
         foreach v of local vvar{
            local labelname: value label `v'
            local vname: variable label `v'
            if `single' == 0 {
               local v_name = subinstr("`vname'"," ","_",.)
               if "`glbtot'" == "`v'" {
                  local skip 0
                  if `do_Nl' {
                     file write `outfile' "@@`v_name'"
                     file write `outfile' "_`Nlab1'"
                     file write `outfile' `Nform' (Ncnt[`p',`numN'])
                     file write `outfile' "`Nlab2'"
                  }
                  else file write `outfile' "@@`v_name'"
                  local vname = abbrev("`vname'",`labw'-2)
                  if `scr' di as text "{ralign `labw': `vname'} {c |}" _c
               }
               else {
                  local skip 1
                  file write `outfile' "`v_name'" _n
                  local vname = abbrev("`vname'",`labw'-2)
                  if `scr' di as text "{ralign `labw': `vname'} {c |}"
               }
            }
            local k=0
            while `k' ~= -9{
               local f=full[`p',1]
               local valnm: label `labelname' `f'
               local val_nm = subinstr("`valnm'"," ","_",.)
               if `skip' {
                  if `do_Nl' {
                     file write `outfile' "`val_nm'"
                     file write `outfile' "_`Nlab1'"
                     file write `outfile' `Nform' (Ncnt[`p',`numN'])
                     file write `outfile' "`Nlab2'"
                     file write `outfile' " $dl"
                 }
                 else file write `outfile' "`val_nm' $dl"
                  local valnm = abbrev("`valnm'",`labw'-2)
                  if `scr' di as text "{ralign `labw': `valnm'}" _c
                  if `scr' di as text " {c |} " _c
               }
               else {
                  file write `outfile' " $dl"
               }
               local j=`w'-1
               local pos= `labw' + 5
                  forval x=2/`j'{
                     formats `x'
                     if `scr' di as res "{col `pos'}" $form (full[`p',`x']) _c
                     file write `outfile' $form (full[`p',`x']) "$dl"
                     local pos = `pos' + `gap'
                  }
               formats `w'
               if `scr' di as res "{col `pos'}" $form (full[`p',`w']) _c
               file write `outfile'  $form (full[`p',`w'])
                  if `do_Nc' {
                     local pos = `pos' + `gap'
                     if `scr' di as res "{col `pos'}" `Nform' (Ncnt[`p',`numN']) _c
                     file write `outfile' "$dl" `Nform' (Ncnt[`p',`numN'])
                  }
               if `scr' di
               file write `outfile' _n
               local p=`p'+1
               local k=full[`p',1]
            }
            local v_word = subinstr("`vword'"," ","_",.)
            if `single' == 1 {
               if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}"
               file write `outfile' "linehere" _n
            }
            if `dotot' & `do_Nl' {
               file write `outfile' "`v_word'"
               file write `outfile' "_`Nlab1'"
               file write `outfile' `Nform' (Ncnt[`p',`numN'])
               file write `outfile' "`Nlab2'"
               file write `outfile' " $dl"
            }
            else if `dotot' file write `outfile' "`v_word' $dl"
            local totword = abbrev("`vword'",`labw'-2)
            if `scr' & `dotot' di as text "{ralign `labw': `totword'}" _c
            if `scr' & `dotot' di as text " {c |} " _c
               local j=`w'-1
               local pos= `labw' + 5
               forval x=2/`j'{
                  formats `x'
                  if `scr' & `dotot' di as res "{col `pos'}" $form (full[`p',`x']) _c
                  if `dotot' file write `outfile' $form (full[`p',`x']) "$dl"
                  local pos = `pos' + `gap'
                  }
                  formats `w'
                  if `scr' & `dotot' di as res "{col `pos'}" $form (full[`p',`w']) _c
                  if `dotot' file write `outfile' $form (full[`p',`w'])
                     if `dotot' & `do_Nc' {
                        local pos = `pos' + `gap'
                        if `scr' di as res "{col `pos'}" `Nform' (Ncnt[`p',`numN']) _c
                        file write `outfile' "$dl" `Nform' (Ncnt[`p',`numN'])
                     }
                  if `scr' & `dotot' di
                  if `dotot' file write `outfile' _n
            local p=`p'+1
            if `p'~=`r' {
               if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}"
               file write `outfile' "linehere" _n
            }

         }
      }
      if `scr' di as text "{hline `cpos'}{c BT}{hline `linewide'}"
   } // end crtabs == 1

if `dochi' == 1 & `scr' {
   di
   di as text "`chistr'" _n
   }

file close `outfile'

* file routines: process tempfile & send to user file
* adding additions before & after & applying style

tempname mainfile
capture file open `mainfile' using "`using'", write `opt'
   if _rc==602 {
      di
      di as err "File `using' already exists."
      di as err "Use the replace option to overwrite",
      di as err "or choose another filename."
      di
      clearglobs
      exit
   }

capture file write `mainfile' ""
         if _rc==111 {
            di
            di as err "File `using'"
            di as err "is already open inside another application."
            di as err "Please close it before running tabout."
            di
            clearglobs
            exit
         }



* note that prefile (topf) is generic, not specific to any one style

   if "`prefile'" ~= "" {
      tempname topfile
      capture file open `topfile' using "`prefile'", read
         if _rc==601 {
            di
            di as err "File `prefile' not found."
            di as err "Check and retype file specification."
            di
            clearglobs
            exit
         }
      file read `topfile' line
      if `dotop' == 1 tokenize "`topinsert'", parse("$dl")
      while r(eof) == 0 {
         if `dotop' == 1 {
            if index("`line'","$ps") > 0 {
               local line : subinstr local line "$ps" "`1'"
               mac shift 2
            }
         }
         file write `mainfile' `"`macval(line)'"' _n
         file read `topfile' line
      }
      file close `topfile'
   }

* open the temp file with all the existing output

file open `outfile' using "`tempfile'", read


* tex output

if `out' == 1 {

   if `bcode' == 1 {
      file write `mainfile' "\\documentclass{article}" _n
      file write `mainfile' "\\usepackage{multicol}" _n
      file write `mainfile' "\\begin{document}" _n
      local numcols = colsof(full)-1
      local cstr = "l"
      forval x = 1/`numcols' {
         local cstr = "`cstr'"+"r"
      }
      file write `mainfile' "\\begin{tabular}{`cstr'}" _n
      file write `mainfile' "\\hline" _n
   }

* main output starts here, headers first, then data

   file read `outfile' line // to grab number of cols
   local span = `line'
   if `do_Nc' local span = `span' + 1

   if `blankhead' == 0 {
      file read `outfile' line
      local line : subinstr local line " " "", all
      local term = "\\\"
      forval j = 1/3 {
         if "`line'" ~= "linehere" {
            if `uh`j'' ~= 1 {
               local fletter = substr("`line'",1,1)
               if "`fletter'" ~= "_" {
                  local fword = substr("`line'",1,index("`line'","$dl")-1)
                  texclean "`fword'"
                  dofont "$clnword" `tfont' "tex"
                  file write `mainfile' " $fonted "
                  local line : subinstr local line "`fword'" "_"
               }
               if `j' == 1 {
                  tokenize "`line'", parse("$dl")
                  mac shift 2
                  while "`1'" ~= "" {
                     texclean "`1'"
                     dofont "$clnword" `tfont' "tex"
                     if `crtabs' == 1 {
                        file write `mainfile' " & \\multicolumn{`span'}{c}{$fonted} \\\" _n
                     }
                     else file write `mainfile' " & $fonted"
                     mac shift 2
                  }
                  if `crtabs' == 0 file write `mainfile' " \\\\\" _n
               } // end first line
               if `j' == 2 {
                  if $dpanel == 1{
                     tokenize "`line'", parse("$dl")
                     mac shift 2
                     while "`1'" ~= "" {
                        texclean "`1'"
                        file write `mainfile' " & \\multicolumn{2}{c}{$clnword}" _n
                        mac shift 2
                     }
                     file write `mainfile' " \\\" _n
                  } // end dpanel
                  else { // not dpanel
                     texclean "`line'"
                     global clnword : subinstr global clnword "$dl" " & ", all
                     file write `mainfile' "$clnword \\\" _n
                  }
               }
               if `j' == 3 {
                  texclean "`line'"
                  global clnword : subinstr global clnword "$dl" " & ", all
                  file write `mainfile' "$clnword \\\" _n
               }
            } // end default
            else userlines "`line'" `mainfile' "tex"
            file read `outfile' line
            local line : subinstr local line  " " "", all
         } // end line condition
      } // end forval loops
      texline `lspace' `mainfile' `rule'
   } // end blankhead

* header done, now data

   file read `outfile' line
   local line : subinstr local line " " "", all
   local lnum 1
   while r(eof) == 0 {
      if "`line'" ~= "linehere" {
         if `lnum' == 1 & `single' ~= 1 {
            local totsym = substr("`line'",1,2)
            if "`totsym'" ~= "@@" {
               texclean "`line'"
               dofont "$clnword" `tfont' "tex"
               file write `mainfile' "$fonted \\\" _n
            }
            else {
               tokenize "`line'", parse("$dl")
               local llen=length("`1'")
               local shtline = substr("`1'",3,`llen'-2)
               texclean "`shtline'"
               dofont "$clnword" `tfont' "tex"
               file write `mainfile' "$fonted"
               mac shift 2
               while "`1'" ~= "" {
                  file write `mainfile' " & `1'"
                  mac shift 2
               }
               file write `mainfile' " \\\" _n
            }
         }
         else {
            tokenize "`line'", parse("$dl")
            texclean "`1'"
            file write `mainfile' "$clnword"
            mac shift 2
            while "`1'" ~= "" {
               file write `mainfile' " & `1'"
               mac shift 2
            }
            file write `mainfile' " \\\" _n
         }
      } // end not line
      else {
         texline `lspace' `mainfile' `rule'
         local lnum 0
      }
      file read `outfile' line
      local line : subinstr local line " " "", all
      local lnum = `lnum'+1
   } // end while not eof

   if `dochi' == 1 {
      texline `lspace' `mainfile' `rule'
      local fspan = `span'+1
      file write `mainfile' "\\multicolumn{`fspan'}{@{}l}{`chistr'} \\\" _n
   }

   if `bcode' == 1 {
      file write `mainfile' "\\hline" _n
      file write `mainfile' "\\end{tabular}" _n
      file write `mainfile' "\\end{document}" _n
   }

   } // end tex output

* html output

if `out' == 2 {

   if `bcode' == 1 {
      file write `mainfile' "<HTML>" _n
      file write `mainfile' "<BODY>" _n
      file write `mainfile' "<TABLE`border'>" _n
   }

   file read `outfile' line // to grab number of cols
   local span = `line'

   if `blankhead' == 0 {
      local fstime "<TR><TD>" //this is needed the first time thru
      file read `outfile' line
      local line : subinstr local line " " "", all
      forval j = 1/3 {
         if "`line'" ~= "linehere" {
            if `uh`j'' ~= 1 {
               local fletter = substr("`line'",1,1)
               if "`fletter'" ~= "_" {
                  local line : subinstr local line "_" " ", all
                  local fword = substr("`line'",1,index("`line'","$dl")-1)
                  dofont "`fword'" `tfont' "html"
                  file write `mainfile' "<TR><TD>$fonted"
                  local line : subinstr local line "`fword'" "_"
               }
               if `j' == 1 {
                  tokenize "`line'", parse("$dl")
                  mac shift 2
                  while "`1'" ~= "" {
                  local term = subinstr("`1'","_"," ",.)
                  dofont "`term'" `tfont' "html"
                     if `crtabs' == 1 {
                        file write `mainfile' ///
                           "<TR><TD><TD colspan=`span' align=center>$fonted" _n
                        file write `mainfile' "<TR><TD>"
                     }
                     else {
                     if `single'==0 {
                        file write `mainfile' "`fstime'<TD>$fonted"
                        local fstime ""
                        }
                        else file write `mainfile' "<TD>$fonted"
                     }
                     mac shift 2
                  }
                  if `crtabs' == 0 {
                     file write `mainfile' _n
                     file write `mainfile' "<TR><TD>"
                     }
               } // end first line
               if `j' == 2 {
                  if $dpanel == 1{
                     tokenize "`line'", parse("$dl")
                     mac shift 2
                     while "`1'" ~= "" {
                     local term = subinstr("`1'","_"," ",.)
                        file write `mainfile' ///
                           " <TD colspan=2 align=center>`term'"
                        mac shift 2
                     }
                     file write `mainfile' _n
                     file write `mainfile' "<TR><TD>"
                  } // end dpanel
                  else { // not dpanel
                     local term : subinstr local line "_" " ", all
                     local term : subinstr local term "$dl" "<TD>", all
                     file write `mainfile' "`term'" _n
                     file write `mainfile' "<TR><TD>"
                  }
               }
               if `j' == 3 {
                  local line : subinstr local line "_" " ", all
                  local term : subinstr local term "$dl" "<TD>", all
                  file write `mainfile' "`term'" _n
                  file write `mainfile' "<TR><TD>"
               }
            } // end default
            else userlines "`line'" `mainfile' "html"
            file read `outfile' line
            local line : subinstr local line " " "", all
         } // end line condition
      } // end forval loops
   } // end blankhead

* header done, now data

   file read `outfile' line
   local line : subinstr local line " " "", all
   local lnum 1
   while r(eof) == 0 {
      if "`line'" ~= "linehere" {
         if `lnum' == 1 & `single' ~= 1 {
            local term : subinstr local line "_" " ", all
            dofont "`term'" `tfont' "html"
            file write `mainfile' "<TR><TD>$fonted" _n
            file write `mainfile' "<TR><TD>"
         }
         else {
            local term : subinstr local line "_" " ", all
            tokenize "`term'", parse("$dl")
            file write `mainfile' "`1'"
            mac shift 2
            while "`1'" ~= "" {
               file write `mainfile' "<TD align=right>`1'"
               mac shift 2
            }
            file write `mainfile' _n
            file write `mainfile' "<TR><TD>"
         }
      } // end not line
      else {
         local lnum 0
      }
      file read `outfile' line
      local line : subinstr local line " " "", all
      local lnum = `lnum'+1
   } // end while not eof

   if `dochi' == 1 {
      local fspan = `span'+1
      file write `mainfile' "<colspan=`fspan' align=left>`chistr'" _n
   }


   if `bcode' == 1 {
      file write `mainfile'  "</TABLE>" _n
      file write `mainfile'  "</BODY>" _n
      file write `mainfile'  "</HTML>" _n
   }


   } // end html output

* tab delimitted output

   if `out' == 3 {
      file read `outfile' line // just to snuffle the number
      file write `mainfile' _n
      file read `outfile' line
      local line : subinstr local line " " "", all
      while r(eof) == 0 {
         if "`line'" ~= "linehere" {
            tokenize "`line'", parse("$dl")
            while "`1'" ~= "" {
               local outword = subinstr("`1'","_"," ",.)
               file write `mainfile' "`outword'" _tab
               mac shift 2
            }
            file write `mainfile' _n
          }
          else {
            if `lspace'== 3 file write `mainfile' _n
          }
       file read `outfile' line
       local line : subinstr local line " " "", all
      } // end while not eof
      file write `mainfile' _n

   if `dochi' == 1 file write `mainfile' "`chistr'" _n

   } // end tab output

* note that postfile (botf) is generic, not specific to any one style

   if "`postfile'" ~= "" {
      tempname botfile
      capture file open `botfile' using "`postfile'", read
         if _rc==601 {
            di
            di as err "File `postfile' not found."
            di as err "Check and retype file specification."
            di
            clearglobs
            exit
         }
      file read `botfile' line
      if `dobot' == 1 tokenize "`botinsert'", parse("$dl")
      while r(eof) == 0 {
         if `dobot' == 1 {
            if index("`line'","$ps") > 0 {
               local line : subinstr local line "$ps" "`1'"
               mac shift 2
            }
         }
         file write `mainfile' `"`macval(line)'"' _n
         file read `botfile' line
         }
      file close `botfile'
   }


file close `mainfile'

di
di as text "File written to: `using'"
di

if `cod' == 1 type "`using'"

* tidy up and exit

file close _all
clearglobs


end

* to check on correct stats term
* note the split lines for Intercooled Stata

program warnstats
   args inword
      if index("N mean var sd skewness kurtosis sum min max","`inword'") == 0 & ///
         index("p1 p5 p10 p25 p50 p75 p90 p95 p99","`inword'") == 0 & ///
         index("count median iqr r9010 r9050 r7525 r1050","`inword'") == 0 {
            di as err "One of the statistics terms you entered in the cells option is incorrect"
            global nogood 1
         }
end



* to simplify processing of double tables

program formats
   args i
   if $dpanel == 1 {
      if mod(`i',2)==0 {
         global form = "$form1"
      }
      else {
         global form = "$form2"
      }
   }
end


program texline
   args kind texfile prnline
      if `kind' == 1 {
         file write `texfile' "`prnline'" _n
      }
      else if `kind' == 2 {
         file write `texfile' "`prnline'" _n
         file write `texfile' "`prnline'" _n
      }
      else if `kind' == 3 {
         file write `texfile' _n
      }
      else if `kind' == 0 {
         file write `texfile' ""
      }
end


program dofont
   args titlewd ftype ostyle
   if "`ostyle'" == "tex" {
      if "`ftype'" == "bold" global fonted "\\textbf{`titlewd'}"
      else if "`ftype'" == "italic" global fonted "\\emph{`titlewd'}"
      else if "`ftype'" == "plain" global fonted "`titlewd'"
   }
   else if "`ostyle'" == "html" {
      if "`ftype'" == "bold" global fonted "<B>`titlewd'</B>"
      else if "`ftype'" == "italic" global fonted "<I>`titlewd'</I>"
      else if "`ftype'" == "plain" global fonted "`titlewd'"
   }
end


* parses and cleans user headers, then outputs them

program userlines
   args inline filenm ostyle
   if "`ostyle'" == "tex" {
      local inline : subinstr local inline "$dl" " & ", all
      local inline : subinstr local inline "_" " ", all
      file write `filenm' "`inline' \\\" _n
   }
   else if "`ostyle'" == "html" {
      local inline : subinstr local inline "$dl" "<TD>", all
      local inline : subinstr local inline "_" " ", all
      file write `filenm' "`inline'" _n
   }
end

program texclean
   args inword
      global clnword : subinstr local inword "_" " ", all
      global clnword : subinstr global clnword "%" " \\%", all
      global clnword : subinstr global clnword "&" " \\&", all
end


program clearglobs
set linesize $oldsize
macro drop form
macro drop dpanel
macro drop form1
macro drop form2
macro drop clnword
macro drop fonted
macro drop ps
macro drop dl
macro drop oldsize
capture mat drop labs
capture mat drop hvals
capture mat drop newmat
capture mat drop newrow
capture mat drop newcol
capture mat drop counts
capture mat drop percents
capture mat drop rownumber
capture mat drop colnumber
capture mat drop rowtot
capture mat drop coltot
capture mat drop wider
capture mat drop longer
capture mat drop blankrow
capture mat drop allrownumbers
capture mat drop full
capture mat drop cellcnt
capture mat drop colp
capture mat drop colper
capture mat drop rowper
capture mat drop rowp
capture mat drop noper
capture mat drop fullcnt
capture mat drop fullcol
capture mat drop dcols
capture mat drop cums
capture mat drop freq
capture mat drop vstats
end