def all_but_blocks(names, data, newline="<STR_LIT:\n>", remove_empty_next=True,<EOL>remove_comments=True):
@allow_implicit_stop<EOL>def remove_blocks(name, iterable):<EOL><INDENT>start, end = BLOCK_START % name, BLOCK_END % name<EOL>it = iter(iterable)<EOL>while True:<EOL><INDENT>line = next(it)<EOL>while line != start:<EOL><INDENT>yield line<EOL>line = next(it)<EOL><DEDENT>it = tail(itertools.dropwhile(not_eq(end), it))<EOL>if remove_empty_next:<EOL><INDENT>it = itertools.dropwhile(lambda el: not el.strip(), it)<EOL><DEDENT><DEDENT><DEDENT>if isinstance(names, str):<EOL><INDENT>names = [names]<EOL><DEDENT>processors = [functools.partial(remove_blocks, name) for name in names]<EOL>if remove_comments:<EOL><INDENT>processors.append(commentless)<EOL><DEDENT>gen = functools.reduce(lambda result, func: func(result),<EOL>processors, data)<EOL>return gen if newline is None else newline.join(gen)<EOL>
Multiline string from a list of strings data, removing every
block with any of the given names, as well as their delimiters.
Removes the empty lines after BLOCK_END when ``remove_empty_next``
is True. Returns a joined string with the given newline, or a
line generator if it's None. If desired, this function use
``commentless`` internally to remove the remaining comments.