1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
# Copyright 2001 by Katharine Lindner. All rights reserved.
# This code is part of the Biopython distribution and governed by its
# license. Please see the LICENSE file that should have been included
# as part of this package.
"""Code for more fancy file handles.
Classes:
Filtered is a decorator for File that allows the user to filter the output
on a line by line basis.
The FilteredReader module reads a file and applies a sequence of filters to the input
The constructor sets a default filter chain, but the user can select another filter by setting
Bio.FilteredReader.filter_chain.
handle = open( "filename" )
filtered_reader = Bio.FilteredReader( handle )
filtered_reader.filter_chain = [ remove_asterisks, replace_dot_with_dash ]
filtered_reasder.read()
All filters in the chain must provide the same interface with a line of text as the single
input parameter and altered text as the return value.
"""
import os
import string
import copy
from File import UndoHandle
"""Used for debugging"""
def dump_saved( name, text, j ):
dump_file = open( name + '%d' % j, "w" )
k = 0
for i in range ( 0, len( text ), 80 ):
dump_file.write( '%s\n' % text[ i : i + 80 ] )
dump_file.close()
def remove_leading_whitespace( line ):
return line.lstrip()
def remove_empty_line( line ):
stripped_line = line.strip()
if( stripped_line ):
return line[ : ]
else:
return ''
def remove_useless_dot( line ):
before = line
while( 1 ):
after = before.replace( "\t.\t", "\t\t" )
if( len( before ) == len( after ) ):
break
before = after
if( after.endswith( '.' ) ):
after = after[ :-1 ]
return after
def fix_punctuation( line ):
line = line.replace( "'", '' )
line = line.replace( '"', '' )
line = line.replace( ';', '\t' )
line = line.replace( 'entryname', 'id' )
# line = line.lower( )
if( line ):
return line[ : ]
else:
return ''
class FilteredReader:
def __init__(self, handle ):
self._handle = handle
self._start_line = ''
self._debug_count = 0
self.filter_chain = [ remove_empty_line, remove_useless_dot, fix_punctuation ]
def __getattr__(self, attr):
return getattr(self._handle, attr)
def close(self, *args, **keywds ):
return self._handle.close( *args, **keywds)
def read( self, *args, **keywds ):
line = ''
len_expected = self._get_len_expected( args, keywds )
if( len_expected ):
filtered_text = self.read_block( len_expected )
else:
filtered_text = self.read_to_end()
return filtered_text
def read_block( self, len_expected ):
len_filtered = 0
len_adjusted = len_expected - len( self._start_line )
filtered_text = ''
while( len_filtered < len_expected ):
text_read = self._handle.read( len_adjusted )
full_text = self._start_line + text_read
lines = full_text.splitlines( 1 )
if( text_read == '' ):
filtered_text = filtered_text + self.filter( lines )
break
else:
all_but_last_line = lines[ :-1 ]
self._start_line = lines[ -1 ]
filtered_text = filtered_text + self.filter( all_but_last_line )
len_filtered_text = len( filtered_text )
len_adjusted = len_adjusted - len_filtered_text
return filtered_text[ : ]
def read_to_end( self ):
filtered_text = ''
text_read = self._handle.read()
full_text = self._start_line + text_read
lines = full_text.splitlines( 1 )
filtered_text = filtered_text + self.filter( lines[:] )
return filtered_text[ : ]
def _get_len_expected( self, args, keywds ):
if( len( args) > 0 ):
len_expected = args[ 0 ]
if( len_expected < 0 ):
len_expected = None
elif( keywds.has_key( 'size' ) ):
len_expected = keywds[ 'size' ]
else:
len_expected = None
return len_expected
def filter( self, lines ):
filter_chain = self.filter_chain
filtered_text = ''
for line in lines:
for filter in filter_chain:
line = filter( *( line, ) )
filtered_text = filtered_text + line
return filtered_text
def has_trailing_linefeed( line ):
if( line.endswith( chr( 13 ) ) or \
line.endswith( chr( 10 ) ) ):
return 1
else:
return 0
|