#!/usr/bin/env python
"""
pargrepp <options> [-e <regexp>] [<file> ...]

Split files or input into multi-line chunks and match those paragraphs for
patterns.  If no <regexp> is provided, we produce all the paragraphs.  If
multiple <regexp> are provided, they are OR'ed together.

By default, a paragraph is defined as a block of text delimited by an empty or
blank line; this behavior can be altered with the -p option.
"""

__version__ = "Revision: 1.6 "
__author__ = "Martin Blais <blais@furius.ca>"

import sys, re

def output_par(par):
    if opts.separator:
        print '-' * 80
    else:
        print
    print par

def main():
    import optparse
    parser = optparse.OptionParser(__doc__.strip(), version=__version__)

    parser.add_option('-i', '--ignore-case', action='store_true',
                      help="Considers upper- and lower-case letters to be"
                      "identical when making comparisons.")

    parser.add_option('-e', '--regexp', action='append', default=[],
                      help="Add a regular expression to search for.")

    parser.add_option('-v', '--invert-match', action='store_true',
                      help="Displays all lines that do not match specified"
                      "expressions.")

    parser.add_option('-s', '--separator', action='store_true',
                      help="Instead of blank lines, render a thick "
                      "separator between the output")

    global opts
    opts, args = parser.parse_args()

    if not args:
        args = ['-']

    splitre = re.compile('\n(?:[ \t]*\n)+')

    try:
        matchfuns = [re.compile('.*%s.*' % regexp,
                                re.S|re.M|(re.I if opts.ignore_case else 0)).match
                     for regexp in opts.regexp]
    except re.error, e:
        parser.error("Error compiling regexp: %s" % e)
    
    invert_match = opts.invert_match
    for fn in args:
        if fn == '-':
            f = sys.stdin
        else:
            f = open(fn, 'r')

        text = f.read()
        if not matchfuns:
            for par in splitre.split(text):
                output_par(par)
        else:
            for par in splitre.split(text):
                match = any(f(par) for f in matchfuns)
                if ((match and not invert_match) or
                    (not match and invert_match)):
                    output_par(par)


if __name__ == "__main__":
    main()



##     parser.add_option('-o', '--or', action='store_true',
##                       help="""The or option:  Display a paragraph if it contains
## any of the regular expressions specified. Since this option is the default, it
## is rarely specified on the command line. It exists primarily to negate the
## effect of a previous -a option. (e.g., If you've defined an alias for pgrep that
## specifies the -a option, -o would be necessary to force the or behavior.)""")

##     parser.add_option('-a', '--and', action='store_true',
##                       help="""The 'and' option: Only display a paragraph if it
## contains all the regular expressions specified. The default is to display a
## paragraph if it contains any of the regular expressions specified. (See the -o
## option, below.""")

##     parser.add_option('-p', '--delimiter', action='store',
##                       help="""Specifies a regular expression to be used match
## paragraph delimiters. Any line that matches this regular expression is assumed
## to delimit paragraphs without actually being part of a paragraph (i.e., lines
## matching this expression are never printed). If this option is not specified, it
## defaults to `^[ ]*$' which matches blank or empty lines. (` ' represents the
## horizontal tab character. If you need to specify a horizontal tab, you'll need
## to type the actual character; pgrep doesn't recognize C-style
## metacharacters.)""")

##     parser.add_option('-I', '--ignore-pattern', action='store_true',
##                       help="""Specifies a pattern of text to ignore, for
##                       example, a comment syntax regexp such at '^#.*' """)

##     parser.add_option('-f', '--file', action='store',
##                       help="""Specifies a file containing regular expressions,
## one expression per line. Each expression in the file is added to the set of
## expression against which paragraphs are to be matched. More than one -f argument
## may be specified; further, -f and -e may be specified together.""")

