def generator(fun):
def wrapper(*args, **kwargs):
gen = fun(*args, **kwargs)
gen.next()
return gen
return wrapper
@generator
def identity():
chunk = None
while True:
chunk = yield chunk
@generator
def lineno():
lineno = 0
chunk = yield
while True:
lineno += 1
chunk = yield lineno
@generator
def lastn(n):
buf = []
chunk = yield
while True:
buf.append(chunk)
if len(buf)>n:
buf.pop(0)
chunk = yield buf
@generator
def grepw(word):
line = yield
while True:
if word in line.split():
line = yield line
else:
line = yield
@generator
def split(*gens):
chunk = yield
while True:
buf = []
for g in gens:
buf.append( g.send(chunk) )
if None in buf:
chunk = yield
else:
chunk = yield buf
@generator
def pair(*gens):
chunks = yield
while True:
buf = []
for chunk, gen in zip(chunks, gens):
buf.append( gen.send(chunk) )
if None in buf:
chunk = yield
else:
chunks = yield buf
@generator
def chain(g1, g2):
chunk = yield
while True:
chunk = g1.send(chunk)
if chunk:
chunk = yield g2.send(chunk)
else:
chunk = yield
def feed(enum, gen):
for trunk in enum:
result = gen.send(trunk)
if result!=None:
yield result
if __name__ == '__main__':
import sys
word = sys.argv[1]
count = int(sys.argv[2])
enum = open(sys.argv[3])
'''
+- lineno --------+
| |
line --+- grepw ------+--- (lineno, line, context lines)
| |
+- context lines -+
'''
gen = split(
lineno(),
grepw(word),
lastn(count)
)
res = feed(enum, gen)
for (lineno, line, last) in res:
print lineno
print ''.join(last)