Load a separated value text file to a list of lists of strings of records.

    Takes a tabular text file with a specified delimeter and end-of-line 
    character, and return data as a list of lists of strings corresponding to 
    records (rows).  Also uses and returns metadata (including column names, 
    formats, coloring, &c.) if these items are determined during the loading 
    process.   

    **Parameters**

        **fname** :  string or file object

            Path (or file object) corresponding to a separated variable
            (CSV) text file.
 
        **delimiter** : single-character string
        
            When reading text file, character to use as delimiter to split 
            fields.  If not specified, the delimiter is determined first by 
            looking for special-format metadata specifying the delimiter, and 
            then if no specification is found, attempts are made to infer 
            delimiter from file contents.  (See **inflines** parameter below.)  
            
        **delimiter_regex** : regular expression (compiled or in string format)                    
         
            Regular expression to use to recognize delimiters, in place of a 
            single character.  (For instance, to have whitespace delimiting, 
            using delimiter_regex = '[\s*]+')
                         
        **lineterminator** : single-character string
        
            Line terminator to use when reading in using SVfile.
            
        **skipinitialspace** : boolean
        
            If true, strips whitespace following the delimiter from field.   
            
       The **delimiter**, **linterminator** and **skipinitialspace** 
       parameters are passed on as parameters to the python CSV module, which is 
       used for reading in delimited text files.  Additional parameters from 
       that interface that are replicated in this constructor include 
       **quotechar**, **escapechar**, **quoting**, **doublequote** and 
       **dialect** (see CSV module documentation for more information).

        **skiprows** :  non-negative integer, optional

            When reading from a text file, the first `skiprows` lines are 
            ignored.  Default is 0, e.g no rows are skipped. 

        **uselines** : pair of non-negative integer, optional
        
            When reading from a text file, range of lines of data to load.  (In 
            contrast to **skiprows**, which specifies file rows to ignore 
            before looking for header information, **uselines** specifies which 
            data (non-header) lines to use, after header has been striped and 
            processed.)  See **headerlines** below.
            
        **comments** : single-character string, optional
            
            When reading from a text file, character used to distinguish header 
            lines.  If specified, any lines beginning with this character at the 
            top of the file are assumed to contain header information and not 
            row data. 
      
        **headerlines** : integer, optional

            When reading from a text file, the number of lines at the top of the 
            file (after the first  `skiprows` lines) corresponding to the header 
            of the file, where metadata can be found.  Lines after headerlines 
            are assumed to contain row contents.  If not specified, value is 
            determined first by looking for special metametadata  in first line 
            of file (see Tabular reference documentation for more information 
            about this), and if no such metadata is found, is inferred by 
            looking at file contents.    
            
        **namesinheader** : Boolean, optional

            When reading from a text file, if `namesinheader == True`, then 
            assume the column names are in the last header line (unless 
            overridden by existing metadata or metametadata directive).  Default 
            is True.                        
            
        **linefixer** : callable, optional

           This callable is applied to every line in the file.  If specified, 
           the called is applied directly to the strings in the file, after 
           they're split in lines but before they're split into fields.  The 
           purpose is to make lines with errors or mistakes amenable to 
           delimiter inference and field-splitting. 
            
        **inflines** :  integer, optional
        
            Number of lines of file to use as sample data when inferring 
            delimiter and header.   

        **metametadata** :  dictionary of integers or pairs of integers
            
            Specifies supplementary metametadata information for use 
            with SVfile loading.  See Tabular reference documentation for more 
            information
            
    **Returns**

            **records** :  list of lists of strings

                List of lists corresponding to records (rows) of data.

            **metadata** :  dictionary

                Metadata read and constructed during process of reading file.

    **See Also:**

            :func:`tabular.io.loadSV`, :func:`tabular.io.saveSV`, 
            :func:`tabular.io.DEFAULT_TYPEINFERER`

def loadSVrecs(fname, uselines=None, skiprows=0, linefixer=None, 
               delimiter_regex=None, verbosity=DEFAULT_VERBOSITY, **metadata):
    """
    Load a separated value text file to a list of lists of strings of records.

    Takes a tabular text file with a specified delimeter and end-of-line 
    character, and return data as a list of lists of strings corresponding to 
    records (rows).  Also uses and returns metadata (including column names, 
    formats, coloring, &c.) if these items are determined during the loading 
    process.   

    **Parameters**

        **fname** :  string or file object

            Path (or file object) corresponding to a separated variable
            (CSV) text file.
 
        **delimiter** : single-character string
        
            When reading text file, character to use as delimiter to split 
            fields.  If not specified, the delimiter is determined first by 
            looking for special-format metadata specifying the delimiter, and 
            then if no specification is found, attempts are made to infer 
            delimiter from file contents.  (See **inflines** parameter below.)  
            
        **delimiter_regex** : regular expression (compiled or in string format)                    
         
            Regular expression to use to recognize delimiters, in place of a 
            single character.  (For instance, to have whitespace delimiting, 
            using delimiter_regex = '[\s*]+')
                         
        **lineterminator** : single-character string
        
            Line terminator to use when reading in using SVfile.
            
        **skipinitialspace** : boolean
        
            If true, strips whitespace following the delimiter from field.   
            
       The **delimiter**, **linterminator** and **skipinitialspace** 
       parameters are passed on as parameters to the python CSV module, which is 
       used for reading in delimited text files.  Additional parameters from 
       that interface that are replicated in this constructor include 
       **quotechar**, **escapechar**, **quoting**, **doublequote** and 
       **dialect** (see CSV module documentation for more information).

        **skiprows** :  non-negative integer, optional

            When reading from a text file, the first `skiprows` lines are 
            ignored.  Default is 0, e.g no rows are skipped. 

        **uselines** : pair of non-negative integer, optional
        
            When reading from a text file, range of lines of data to load.  (In 
            contrast to **skiprows**, which specifies file rows to ignore 
            before looking for header information, **uselines** specifies which 
            data (non-header) lines to use, after header has been striped and 
            processed.)  See **headerlines** below.
            
        **comments** : single-character string, optional
            
            When reading from a text file, character used to distinguish header 
            lines.  If specified, any lines beginning with this character at the 
            top of the file are assumed to contain header information and not 
            row data. 
      
        **headerlines** : integer, optional

            When reading from a text file, the number of lines at the top of the 
            file (after the first  `skiprows` lines) corresponding to the header 
            of the file, where metadata can be found.  Lines after headerlines 
            are assumed to contain row contents.  If not specified, value is 
            determined first by looking for special metametadata  in first line 
            of file (see Tabular reference documentation for more information 
            about this), and if no such metadata is found, is inferred by 
            looking at file contents.    
            
        **namesinheader** : Boolean, optional

            When reading from a text file, if `namesinheader == True`, then 
            assume the column names are in the last header line (unless 
            overridden by existing metadata or metametadata directive).  Default 
            is True.                        
            
        **linefixer** : callable, optional

           This callable is applied to every line in the file.  If specified, 
           the called is applied directly to the strings in the file, after 
           they're split in lines but before they're split into fields.  The 
           purpose is to make lines with errors or mistakes amenable to 
           delimiter inference and field-splitting. 
            
        **inflines** :  integer, optional
        
            Number of lines of file to use as sample data when inferring 
            delimiter and header.   

        **metametadata** :  dictionary of integers or pairs of integers
            
            Specifies supplementary metametadata information for use 
            with SVfile loading.  See Tabular reference documentation for more 
            information
            
    **Returns**

            **records** :  list of lists of strings

                List of lists corresponding to records (rows) of data.

            **metadata** :  dictionary

                Metadata read and constructed during process of reading file.

    **See Also:**

            :func:`tabular.io.loadSV`, :func:`tabular.io.saveSV`, 
            :func:`tabular.io.DEFAULT_TYPEINFERER`

    """
    if delimiter_regex and isinstance(delimiter_regex, types.StringType):
        import re
        delimiter_regex = re.compile(delimiter_regex) 
   
    [metadata, inferedlines, WHOLETHING] = getmetadata(fname, skiprows=skiprows,
                                                linefixer=linefixer, 
                                                delimiter_regex=delimiter_regex, 
                                                verbosity=verbosity, **metadata)

    if uselines is None:
        uselines = (0,False)
    
    if is_string_like(fname):
        fh = file(fname, 'rU')
    elif hasattr(fname, 'readline'):
        fh = fname
    else:
        raise ValueError('fname must be a string or file handle') 
 
    for _ind in range(skiprows+uselines[0] + metadata['headerlines']):
        fh.readline()
        
    if linefixer or delimiter_regex:
        fh2 = tempfile.TemporaryFile('w+b')
        F = fh.read().strip('\n').split('\n')
        if linefixer:
            F = map(linefixer,F)
        if delimiter_regex:
            F = map(lambda line: 
                    delimiter_regex.sub(metadata['dialect'].delimiter, line), F)       
        fh2.write('\n'.join(F))        
        fh2.seek(0)
        fh = fh2        

    reader = csv.reader(fh, dialect=metadata['dialect'])

    if uselines[1]:
        linelist = []
        for ln in reader:
            if reader.line_num <= uselines[1] - uselines[0]:
                linelist.append(ln)
            else:
                break
    else:
        linelist = list(reader)
      
    fh.close()

    if linelist[-1] == []:
        linelist.pop(-1)

    return [linelist,metadata]