Index: tools/demos/textool.py
===================================================================
--- tools/demos/textool.py	(revision 2712)
+++ tools/demos/textool.py	(revision 2712)
@@ -0,0 +1,462 @@
+#
+# function textable -- a Python script to make LaTeX tables
+# from ASCII files with columns
+#
+# Version 1.0
+#
+# Usage:
+#
+# The call
+#
+#       textable(filename)
+#
+#   where filename is the name of an ASCII file with columns
+#
+#   generates a new file 'filename'+'.tex'
+#   with generic header and footer, alignment tabs, and
+#   special LaTeX characters escaped.
+#   If the number of lines is less than 40 all one table is generated;
+#   otherwise the data is broken into two tables.
+#   The fontsize is reduced progressively with the number of 
+#   lines but no more than two tables will be generated.
+#
+#
+# O. Nielsen, ANU, April 2000
+
+
+"""
+This module contains two functions to generate LaTeX tables.
+
+-------------------
+textool.maketable()
+-------------------
+
+Declaration:
+  maketable(array,title=None,rowlab=None,collab=None,maxcol=None, \
+            filename=None)
+
+Usage:
+  Generates a new file 'filename'+'.tex'
+  with a generic header and footer, alignment tabs, and
+  special LaTeX characters escaped.
+  If the number of lines is less than 40 all one table is generated;
+  otherwise the data is broken into two tables.
+  The fontsize is reduced progressively with the number of
+  lines but no more than two tables will be generated.
+
+  Input: array     array is a list of lists containing entries for the
+                   table. Each list corresponds to one row, but they do
+                   not need to be the same length.
+         title     (optional) String to be used as title
+         rowlab    (optional) List of strings to used for row labels
+         collab    (optional) List of strings to used for column labels
+         maxcol    (optional) maximal number of columns (if known)
+         filename  (optional) filename for tex file (default='maketable')
+
+
+
+
+------------------
+textool.textable()
+------------------
+
+Declaration:
+  textable(filename)
+
+Usage:
+  Reads data from the ascii file filename and calls maketable to produce
+  a LaTeX version. The file should contain rows of data elements but not
+  necessarily having the same length.
+  Running textable on arbitrary files is possible but meaningless.
+
+
+         
+"""
+
+
+
+def textable(FN):	
+  from string import *
+  
+  input = open(FN,'r')         # Open file with ASCII columns
+  #output = open(FN+'.tex','w') # Open file with LateX table
+
+  x = input.readlines()
+  print 'Textable got ', len(x), 'records from ', FN
+
+  
+  maxcol = 0
+  array = []
+  for n in range(len(x)):    
+    record = split(rstrip(x[n]))
+    array.append(record)
+    col = len(record)   # Number of columns in this record  
+    if col > maxcol:
+      maxcol = col      # Determine maximal number of columns      
+
+  maketable(array,rowlab=[],collab=[],title=FN,filename=FN+'.tex')      
+
+  return()
+
+#
+# Core routine for making and writing TeX table
+#
+# array is a list of lists (rows)
+#  
+def maketable(array,title=None,rowlab=None,collab=None,maxcol=None,filename=None):        
+
+  splitthreshold = 40 # Maximal number of lines in one table
+                      # Tables with more lines are split into two
+
+  import types
+  		      
+  #
+  # Input checks
+  #---------------
+  
+  #
+  # File name
+  #
+  if not filename:
+    if title:
+      filename = nospace(title) + '.tex'
+    else:  
+      filename = 'maketable.tex'
+    
+  output = open(filename,'w') # Open file with LateX table
+
+  #
+  # array
+  #
+  
+  if not type(array) in [types.ListType, types.TupleType]:
+    array = [array]
+  
+  #
+  # Maximal number of columns
+  #
+  if not maxcol:
+    maxcol = 0 
+    for n in range(len(array)):    
+      record = array[n]
+      if not type(record) in [types.ListType, types.TupleType]:      
+        record = [record]
+      col = len(record)   # Number of columns in this record  
+      if col > maxcol:
+        maxcol = col      # Determine maximal number of columns      
+
+  #
+  # Column labels
+  #	
+  if not collab:
+    collab = []
+    
+  collab = list(collab) # Make copy to protect input list from being modified
+      
+
+  for j in range(maxcol):
+    if j >= len(collab):  
+      collab.append('Col '+`j`)    # Default column label
+    collab[j] = '\\textbf{'+collab[j]+'}'
+
+  #
+  # Row labels
+  #     
+  if not rowlab:
+    rowlab = []	
+    
+  rowlab = list(rowlab) # Make copy to protect input list from being modified  
+    
+  for j in range(len(array)):
+    if j >= len(rowlab):  
+      rowlab.append('Row '+`j`)    # Default row label
+    rowlab[j] = '\\textbf{'+rowlab[j]+'}'
+
+  #
+  # Function body
+  #	
+  y = []
+  for n in range(len(array)):    
+    record = array[n]
+    if not type(record) in [types.ListType, types.TupleType]:      
+      record = [record]
+    
+    col = len(record)   # Number of columns in this record  
+    
+    if col > 0:
+      # Aggregate Latex line  
+      texline = rowlab[n]+' & '
+      for j in range(maxcol):
+        if j > 0: 
+          texline = texline+'\t& '
+        
+	if j < col:
+          texline = texline+texmap(str(record[j]))  
+ 
+      texline = texline + ' \\\\'
+      y.append(texline)
+  
+  
+  #
+  # Make a qualified guess about splitting of table and fontsize
+  #   
+  if len(y) <= splitthreshold:
+    splittab = 0
+    tabstyle = 1
+  elif splitthreshold < len(y) <= 2*splitthreshold:
+    splittab = 1
+    tabstyle = 2
+  else:
+    splittab = 1  
+    tabstyle = 3  
+
+  if 5 < maxcol < 7:
+    tabstyle = max(tabstyle,3)
+  elif maxcol >= 7:      
+    tabstyle = max(tabstyle,4)
+            
+  
+  #
+  # Create generic table header
+  #
+  header = []
+  colform = '|l||' + 'c|'*maxcol
+  if tabstyle == 1:
+    header.append('{\\normalsize') 
+  elif tabstyle == 2:
+    header.append('{\\small')
+  elif tabstyle == 2:
+    header.append('{\\scriptsize')
+  else:          
+    header.append('{\\tiny')
+      
+  header.append('\\begin{tabular}{'+colform+'} \\hline')
+
+  
+  colnames = ' & '
+  for j in range(maxcol):
+    if j > 0: 
+      colnames = colnames+'\t& '
+   
+  #  colnames = colnames+'\\textbf{Col '+`j`+'}'
+    colnames = colnames+collab[j]
+
+  header.append(colnames+'\\\\ \\hline\\hline')
+
+  #
+  # Create generic table footer
+  #
+  footer = []
+  footer.append('\\end{tabular}}')
+
+
+  #
+  # Generate file
+  #
+ 
+  output.write('\\begin{table}[hbt]\n')
+  output.write('\\begin{center}\n')  
+  if title:
+    output.write('\\textbf{'+texmap(str(title))+'}\\\\ \n')    
+  output.write('\n')  
+
+  #
+  # One column table
+  #  
+  if not splittab:
+    # Header
+    for n in range(len(header)):  
+      output.write(header[n]+'\n')          
+    
+    # Contents   
+    for n in range(len(y)):  
+      output.write(y[n])          
+      if n == len(y)-1:            # Put a hline after last entry
+  	output.write(' \\hline \n') 
+      else:
+  	output.write('\n')     
+    # Footer    	
+    for n in range(len(footer)):  
+      output.write(footer[n]+'\n')
+
+  #
+  # Two column table 
+  #  
+  else:
+    tablen = int(round(len(y)/2.0))
+    for m in range(1):
+      # Header
+      output.write('\makebox[0.48\\textwidth]{\n')                
+      for n in range(len(header)):  
+    	output.write(header[n]+'\n')          
+      
+      # Contents   
+      k = 0
+      for n in range(len(y)):  
+        k = k+1
+    	output.write(y[n])          
+    	if k == tablen:            # Put a hline after last entry
+	  k = 0
+   	  output.write(' \\hline \n') 
+          # Footer    	
+          for j in range(len(footer)):  
+    	    output.write(footer[j]+'\n')
+	  output.write('}\n')  
+          output.write('\hspace*{1mm}\n')                	  
+          output.write('\makebox[0.48\\textwidth]{\n')                	  
+          # Header
+          for j in range(len(header)):  
+    	    output.write(header[j]+'\n')          
+    	elif n == len(y)-1:        # Put a hline after last entry	    
+   	  output.write(' \\hline \n') 	
+	  if n == 2*tablen-2:      # add an empty line for symmetry
+            output.write('\\multicolumn{'+`maxcol`+'}{c}{} \\\\ \n')  
+    	else:
+   	  output.write('\n')     
+	  
+      #	  
+      # Final footer    	
+      #
+      for n in range(len(footer)):  
+    	output.write(footer[n]+'\n')
+      output.write('}\n')        
+           
+  output.write('\\end{center}\n')  
+  output.write('\\caption{ }\n')  
+  if title:  
+    output.write('\\label{tab:'+title+'}\n')  
+  else:
+    output.write('\\label{tab: }\n')  
+    
+  output.write('\\end{table}\n')
+              
+  output.close()    
+  print 'Textable wrote generic LaTeX table to', filename
+
+  
+# texmap(s)
+#  maps string s into Latex
+#
+def texmap(s):
+  import types
+  from string import *
+
+  s = replace(s,'\\','\\backslash') 
+  s = replace(s,'#','\\#') 
+  s = replace(s,'$','\\$')
+  s = replace(s,'%','\\%')  
+  s = replace(s,'&','\\&')
+  s = replace(s,'~','\\~')
+  s = replace(s,'_','\\_')
+  s = replace(s,'^','\\^')
+  s = replace(s,'{','\\{')
+  s = replace(s,'}','\\}')  
+      
+  return(s)
+
+def nospace(s):
+  #
+  # Replace spaces in s with underscores
+  #  
+
+  import string
+  
+  newstr = ''
+  for i in range(len(s)):
+    if s[i] == ' ':
+      newstr = newstr+'_'
+    else:
+      newstr = newstr+s[i]  
+      
+  return(newstr)    
+
+
+#======================= EXAMPLE ======================
+
+def gen_latex_section(dataset,items,years,names='',filename=None):
+
+  """gen_latex_section(dataset,items,years,names ='',filename=None)
+     Generates a LaTeX document with basic statistics relating
+     to the cohort defined by items, dataset, and years.
+     The content of the generated report contains graphs with agergp, 
+     gender statistics and gender, RRMA statisitics.
+     In addition there are tables with this information.
+     The parameter names is used in the headlines.
+
+     Example:
+     from CRCdefs import MBSitems
+
+     key = 'COLONOSCOPY'
+     gen_latex_section('mbs',MBSitems[key],[1997,1998],key)
+  """
+
+  import os, types
+  from re import match                           # Regular Expressions
+  from textool import *
+
+  if not type(years) in [types.ListType, types.TupleType]:
+    years = [years]
+  if not type(items) in [types.ListType, types.TupleType]:
+    items = [items]
+    
+  if not filename:
+    if names == '':  
+      filename = 'Autoreport'
+    else:
+      filename = nospace(names)
+    
+  os.system('mkdir '+ filename)
+  #os.system('cd '+ filename)  
+  curdir = os.getcwd()
+  os.chdir(filename)  
+  
+  output = open(filename+'.tex','w')  
+  
+  output.write('\\documentclass{article}\n')  
+  output.write('\\usepackage{epsfig}\n')  
+  output.write('\\begin{document}\n')    
+  
+  output.write('\\section{Findings}\n\n')
+  for year in years:
+    plot_age_gender(dataset,items,year,names,geneps=1)  
+    plot_rrma_gender(dataset,items,year,names,geneps=1)      
+  
+  output.write('\\subsection{Basic statistics from ')
+  output.write(texmap(dataset)+'}\n')    
+  #output.write(texmap(dataset)+' in '+str(year)+'}\n')
+ 
+  texfiles = []
+  epsfiles = []    
+  files = os.listdir('.')
+    
+  for fname in files:
+    if match('.+eps',fname):
+      epsfiles.append(fname)
+
+    if match('.+tex',fname) and not match(filename+'.tex',fname):
+      texfiles.append(fname)
+
+  output.write('\\begin{center}\n')        
+  for file in epsfiles:
+    output.write('  \\epsfxsize=0.47\\textwidth \\epsfbox{'+file+'}\n')
+  output.write('\\end{center}\n\n')
+  output.write('\\clearpage\n\n')  
+  
+  for file in texfiles:  
+    output.write('\\input{'+file+'}\n')
+      
+  output.write('\\clearpage\n\n')
+    
+  output.write('\\end{document}\n')        
+  output.close()      
+	      
+  os.system('latex '+filename)
+  os.system('dvips '+filename+' -o '+filename+'.ps')
+  os.system('ghostview '+filename+'.ps &') 
+  print 'print the report using lpr ' + filename + '.ps'  
+  #print(' *****************************************************
+  #          print the report using lpr ' + filename + '.ps
+  #        ********************************************************')
+  
+  os.chdir(curdir)  
+  
