home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) default_smartypants_attr = '1' import re tags_to_skip_regex = re.compile('<(/)?(style|pre|code|kbd|script|math)[^>]*>', re.I) def verify_installation(request): return 1 def cb_story(args): try: forbidden_flavours = args['entry']['smartypants_forbidden_flavours'] except KeyError: forbidden_flavours = [ 'rss'] try: attributes = args['entry']['smartypants_attributes'] except KeyError: attributes = default_smartypants_attr if attributes is None: attributes = default_smartypants_attr entryData = args['entry'].getData() try: if args['request']['flavour'] in forbidden_flavours: return None except KeyError: if '<' in args['entry']['body'][0:15]: return None except: '<' in args['entry']['body'][0:15] args['entry']['body'] = smartyPants(entryData, attributes) args['entry']['title'] = smartyPants(args['entry']['title'], attributes) def smartyPants(text, attr = default_smartypants_attr): convert_quot = False skipped_tag_stack = [] do_dashes = '0' do_backticks = '0' do_quotes = '0' do_ellipses = '0' do_stupefy = '0' if attr == '0': return text if attr == '1': do_quotes = '1' do_backticks = '1' do_dashes = '1' do_ellipses = '1' elif attr == '2': do_quotes = '1' do_backticks = '1' do_dashes = '2' do_ellipses = '1' elif attr == '3': do_quotes = '1' do_backticks = '1' do_dashes = '3' do_ellipses = '1' elif attr == '-1': do_stupefy = '1' else: for c in attr: if c == 'q': do_quotes = '1' continue if c == 'b': do_backticks = '1' continue if c == 'B': do_backticks = '2' continue if c == 'd': do_dashes = '1' continue if c == 'D': do_dashes = '2' continue if c == 'i': do_dashes = '3' continue if c == 'e': do_ellipses = '1' continue if c == 'w': convert_quot = '1' continue tokens = _tokenize(text) result = [] in_pre = False prev_token_last_char = '' for cur_token in tokens: if cur_token[0] == 'tag': result.append(cur_token[1]) skip_match = tags_to_skip_regex.match(cur_token[1]) if skip_match is not None: if not skip_match.group(1): skipped_tag_stack.append(skip_match.group(2).lower()) in_pre = True elif len(skipped_tag_stack) > 0: if skip_match.group(2).lower() == skipped_tag_stack[-1]: skipped_tag_stack.pop() if len(skipped_tag_stack) == 0: in_pre = False skip_match is not None t = cur_token[1] last_char = t[-1:] if not in_pre: t = processEscapes(t) if convert_quot != '0': t = re.sub('"', '"', t) if do_dashes != '0': if do_dashes == '1': t = educateDashes(t) if do_dashes == '2': t = educateDashesOldSchool(t) if do_dashes == '3': t = educateDashesOldSchoolInverted(t) if do_ellipses != '0': t = educateEllipses(t) if do_backticks != '0': t = educateBackticks(t) if do_backticks == '2': t = educateSingleBackticks(t) if do_quotes != '0': if t == "'": if re.match('\\S', prev_token_last_char): t = '’' else: t = '‘' elif t == '"': if re.match('\\S', prev_token_last_char): t = '”' else: t = '“' else: t = educateQuotes(t) if do_stupefy == '1': t = stupefyEntities(t) prev_token_last_char = last_char result.append(t) return ''.join(result) def educateQuotes(str): punct_class = '[!"#\\$\\%\'()*+,-.\\/:;<=>?\\@\\[\\\\\\]\\^_`{|}~]' str = re.sub("^'(?=%s\\\\B)" % (punct_class,), '’', str) str = re.sub('^"(?=%s\\\\B)' % (punct_class,), '”', str) str = re.sub('"\'(?=\\w)', '“‘', str) str = re.sub('\'"(?=\\w)', '‘“', str) str = re.sub("\\b'(?=\\d{2}s)", '’', str) close_class = '[^\\ \\t\\r\\n\\[\\{\\(\\-]' dec_dashes = '–|—' opening_single_quotes_regex = re.compile("\n\t\t\t(\n\t\t\t\t\\s | # a whitespace char, or\n\t\t\t\t | # a non-breaking space entity, or\n\t\t\t\t-- | # dashes, or\n\t\t\t\t&[mn]dash; | # named dash entities\n\t\t\t\t%s | # or decimal entities\n\t\t\t\t&\\#x201[34]; # or hex\n\t\t\t)\n\t\t\t' # the quote\n\t\t\t(?=\\w) # followed by a word character\n\t\t\t" % (dec_dashes,), re.VERBOSE) str = opening_single_quotes_regex.sub('\\1‘', str) closing_single_quotes_regex = re.compile("\n\t\t\t(%s)\n\t\t\t'\n\t\t\t(?!\\s | s\\b | \\d)\n\t\t\t" % (close_class,), re.VERBOSE) str = closing_single_quotes_regex.sub('\\1’', str) closing_single_quotes_regex = re.compile("\n\t\t\t(%s)\n\t\t\t'\n\t\t\t(\\s | s\\b)\n\t\t\t" % (close_class,), re.VERBOSE) str = closing_single_quotes_regex.sub('\\1’\\2', str) str = re.sub("'", '‘', str) opening_double_quotes_regex = re.compile('\n\t\t\t(\n\t\t\t\t\\s | # a whitespace char, or\n\t\t\t\t | # a non-breaking space entity, or\n\t\t\t\t-- | # dashes, or\n\t\t\t\t&[mn]dash; | # named dash entities\n\t\t\t\t%s | # or decimal entities\n\t\t\t\t&\\#x201[34]; # or hex\n\t\t\t)\n\t\t\t" # the quote\n\t\t\t(?=\\w) # followed by a word character\n\t\t\t' % (dec_dashes,), re.VERBOSE) str = opening_double_quotes_regex.sub('\\1“', str) closing_double_quotes_regex = re.compile('\n\t\t\t#(%s)? # character that indicates the quote should be closing\n\t\t\t"\n\t\t\t(?=\\s)\n\t\t\t' % (close_class,), re.VERBOSE) str = closing_double_quotes_regex.sub('”', str) closing_double_quotes_regex = re.compile('\n\t\t\t(%s) # character that indicates the quote should be closing\n\t\t\t"\n\t\t\t' % (close_class,), re.VERBOSE) str = closing_double_quotes_regex.sub('\\1”', str) str = re.sub('"', '“', str) return str def educateBackticks(str): str = re.sub('``', '“', str) str = re.sub("''", '”', str) return str def educateSingleBackticks(str): str = re.sub('`', '‘', str) str = re.sub("'", '’', str) return str def educateDashes(str): str = re.sub('---', '–', str) str = re.sub('--', '—', str) return str def educateDashesOldSchool(str): str = re.sub('---', '—', str) str = re.sub('--', '–', str) return str def educateDashesOldSchoolInverted(str): str = re.sub('---', '–', str) str = re.sub('--', '—', str) return str def educateEllipses(str): str = re.sub('\\.\\.\\.', '…', str) str = re.sub('\\. \\. \\.', '…', str) return str def stupefyEntities(str): str = re.sub('–', '-', str) str = re.sub('—', '--', str) str = re.sub('‘', "'", str) str = re.sub('’', "'", str) str = re.sub('“', '"', str) str = re.sub('”', '"', str) str = re.sub('…', '...', str) return str def processEscapes(str): str = re.sub('\\\\\\\\', '\', str) str = re.sub('\\\\"', '"', str) str = re.sub("\\\\'", ''', str) str = re.sub('\\\\\\.', '.', str) str = re.sub('\\\\-', '-', str) str = re.sub('\\\\`', '`', str) return str def _tokenize(str): tokens = [] tag_soup = re.compile('([^<]*)(<[^>]*>)') token_match = tag_soup.search(str) previous_end = 0 while token_match is not None: if token_match.group(1): tokens.append([ 'text', token_match.group(1)]) tokens.append([ 'tag', token_match.group(2)]) previous_end = token_match.end() token_match = tag_soup.search(str, token_match.end()) if previous_end < len(str): tokens.append([ 'text', str[previous_end:]]) return tokens if __name__ == '__main__': import locale try: locale.setlocale(locale.LC_ALL, '') except: pass from docutils.core import publish_string docstring_html = publish_string(__doc__, writer_name = 'html') print docstring_html import unittest sp = smartyPants class TestSmartypantsAllAttributes(unittest.TestCase): def test_dates(self): self.assertEqual(sp("1440-80's"), '1440-80’s') self.assertEqual(sp("1440-'80s"), '1440-‘80s') self.assertEqual(sp("1440---'80s"), '1440–‘80s') self.assertEqual(sp('1960s'), '1960s') self.assertEqual(sp("1960's"), '1960’s') self.assertEqual(sp("one two '60s"), 'one two ‘60s') self.assertEqual(sp("'60s"), '‘60s') def test_skip_tags(self): self.assertEqual(sp('<script type="text/javascript">\n<!--\nvar href = "http://www.google.com";\nvar linktext = "google";\ndocument.write(\'<a href="\' + href + \'">\' + linktext + "</a>");\n//-->\n</script>'), '<script type="text/javascript">\n<!--\nvar href = "http://www.google.com";\nvar linktext = "google";\ndocument.write(\'<a href="\' + href + \'">\' + linktext + "</a>");\n//-->\n</script>') self.assertEqual(sp("<p>He said "Let's write some code." This code here <code>if True:\n\tprint "Okay"</code> is python code.</p>"), '<p>He said “Let’s write some code.” This code here <code>if True:\n\tprint "Okay"</code> is python code.</p>') def test_ordinal_numbers(self): self.assertEqual(sp('21st century'), '21st century') self.assertEqual(sp('3rd'), '3rd') def test_educated_quotes(self): self.assertEqual(sp('"Isn\'t this fun?"'), '“Isn’t this fun?”') unittest.main() __author__ = 'Chad Miller <smartypantspy@chad.org>' __version__ = '1.5_1.6: Fri, 27 Jul 2007 07:06:40 -0400' __url__ = 'http://wiki.chad.org/SmartyPantsPy' __description__ = 'Smart-quotes, smart-ellipses, and smart-dashes for weblog entries in pyblosxom'