'Unwraps lines based on line length and punctuation
supports a range of html markup and text files
the lookahead regex below is meant look for any non-full stop characters - punctuation
characters which can be used as a full stop should *not* be added below - e.g. ?!ââ. etc
the reason for this is to prevent false positive wrapping.  False positives are more
difficult to detect than false negatives during a manual review of the doc
This function intentionally leaves hyphenated content alone as that is handled by the
dehyphenate routine in a separate step'

def punctuation_unwrap(self, length, content, format):

    def style_unwrap(match):
        style_close = match.group('style_close')
        style_open = match.group('style_open')
        if (style_open and style_close):
            return ((style_close + '    ') + style_open)
        elif (style_open and (not style_close)):
            return ('    ' + style_open)
        elif ((not style_open) and style_close):
            return (style_close + '    ')
        else:
            return '    '
    lookahead = (('(?<=.{' + unicode(length)) + u'}([a-z\xe4\xeb\xef\xf6\xfc\xe0\xe8\xec\xf2\xf9\xe1\u0107\xe9\xed\u013a\xf3\u0155\u0144\u015b\xfa\xfd\xe2\xea\xee\xf4\xfb\xe7\u0105\u0119\u017c\u0131\xe3\xf5\xf1\xe6\xf8\xfe\xf0\xdf\u011b\u013e\u0161\u010d\u0165\u017e\u0148\u010f\u0159\u016f,:)\\IA\xdf]|(?<!\\&\\w{4});))')
    em_en_lookahead = (('(?<=.{' + unicode(length)) + u'}[\u2013\u2014])')
    soft_hyphen = u'\xad'
    line_ending = '\\s*(?P<style_close></(span|[iub])>)?\\s*(</(p|div)>)?'
    blanklines = '\\s*(?P<up2threeblanks><(p|span|div)[^>]*>\\s*(<(p|span|div)[^>]*>\\s*</(span|p|div)>\\s*)</(span|p|div)>\\s*){0,3}\\s*'
    line_opening = '<(p|div)[^>]*>\\s*(?P<style_open><(span|[iub])[^>]*>)?\\s*'
    txt_line_wrap = u'((    | DCTB )*\n){1,4}'
    if (format == 'txt'):
        unwrap_regex = (lookahead + txt_line_wrap)
        em_en_unwrap_regex = (em_en_lookahead + txt_line_wrap)
        shy_unwrap_regex = (soft_hyphen + txt_line_wrap)
    else:
        unwrap_regex = (((lookahead + line_ending) + blanklines) + line_opening)
        em_en_unwrap_regex = (((em_en_lookahead + line_ending) + blanklines) + line_opening)
        shy_unwrap_regex = (((soft_hyphen + line_ending) + blanklines) + line_opening)
    unwrap = re.compile((u'%s' % unwrap_regex), re.UNICODE)
    em_en_unwrap = re.compile((u'%s' % em_en_unwrap_regex), re.UNICODE)
    shy_unwrap = re.compile((u'%s' % shy_unwrap_regex), re.UNICODE)
    if (format == 'txt'):
        content = unwrap.sub('    ', content)
        content = em_en_unwrap.sub('', content)
        content = shy_unwrap.sub('', content)
    else:
        content = unwrap.sub(style_unwrap, content)
        content = em_en_unwrap.sub(style_unwrap, content)
        content = shy_unwrap.sub(style_unwrap, content)
    return content
