textile-2.1.5/0000755000076500000240000000000011560135413013074 5ustar cwdstaff00000000000000textile-2.1.5/PKG-INFO0000644000076500000240000000117211560135413014172 0ustar cwdstaff00000000000000Metadata-Version: 1.0 Name: textile Version: 2.1.5 Summary: Textile processing for python. Home-page: http://github.com/chrisdrackett/python-textile Author: Chris Drackett Author-email: chris@chrisdrackett.com License: UNKNOWN Description: UNKNOWN Keywords: textile,text Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules textile-2.1.5/setup.cfg0000644000076500000240000000026311560135413014716 0ustar cwdstaff00000000000000[nosetests] detailed-errors = 1 with-coverage = 1 cover-package = textile cover-erase = 1 with-doctest = 1 with-id = 1 [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 textile-2.1.5/setup.py0000644000076500000240000000150111560135411014601 0ustar cwdstaff00000000000000from setuptools import setup, find_packages version = '2.1.5' setup( name='textile', version=version, description='Textile processing for python.', author='Chris Drackett', author_email='chris@chrisdrackett.com', url='http://github.com/chrisdrackett/python-textile', packages=find_packages(), classifiers=[ 'Development Status :: 3 - Alpha', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Software Development :: Libraries :: Python Modules', ], keywords='textile,text', test_suite = 'nose.collector', tests_require = ['nose'], include_package_data=True, zip_safe=False, ) textile-2.1.5/textile/0000755000076500000240000000000011560135413014552 5ustar cwdstaff00000000000000textile-2.1.5/textile/__init__.py0000644000076500000240000000015011560133635016663 0ustar cwdstaff00000000000000from functions import textile, textile_restricted, Textile __all__ = ['textile', 'textile_restricted'] textile-2.1.5/textile/functions.py0000644000076500000240000010052411560133635017142 0ustar cwdstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- __copyright__ = """ Copyright (c) 2009, Jason Samsa, http://jsamsa.com/ Copyright (c) 2010, Kurt Raschke Copyright (c) 2004, Roberto A. F. De Almeida, http://dealmeida.net/ Copyright (c) 2003, Mark Pilgrim, http://diveintomark.org/ Original PHP Version: Copyright (c) 2003-2004, Dean Allen All rights reserved. Thanks to Carlo Zottmann for refactoring Textile's procedural code into a class framework Additions and fixes Copyright (c) 2006 Alex Shiels http://thresholdstate.com/ """ import re import uuid import string from urlparse import urlparse from textile.tools import sanitizer, imagesize def _normalize_newlines(string): out = string.strip() out = re.sub(r'\r\n', '\n', out) out = re.sub(r'\n{3,}', '\n\n', out) out = re.sub(r'\n\s*\n', '\n\n', out) out = re.sub(r'"$', '" ', out) return out class Textile(object): horizontal_align_re = r'(?:\<(?!>)|(?|\<\>|\=|[()]+(?! ))' vertical_align_re = r'[\-^~]' class_re = r'(?:\([^)]+\))' language_re = r'(?:\[[^\]]+\])' style_re = r'(?:\{[^}]+\})' colspan_re = r'(?:\\\d+)' rowspan_re = r'(?:\/\d+)' align_re = r'(?:%s|%s)*' % (horizontal_align_re, vertical_align_re) table_span_re = r'(?:%s|%s)*' % (colspan_re, rowspan_re) c = r'(?:%s)*' % '|'.join([class_re, style_re, language_re, horizontal_align_re]) pnct = r'[-!"#$%&()*+,/:;<=>?@\'\[\\\]\.^_`{|}~]' urlch = '[\w"$\-_.+*\'(),";\/?:@=&%#{}|\\^~\[\]`]' url_schemes = ('http', 'https', 'ftp', 'mailto') btag = ('bq', 'bc', 'notextile', 'pre', 'h[1-6]', 'fn\d+', 'p') btag_lite = ('bq', 'bc', 'p') iAlign = {'<': 'float: left;', '>': 'float: right;', '=': 'display: block; margin: 0 auto;'} vAlign = {'^': 'top', '-': 'middle', '~': 'bottom'} hAlign = {'<': 'left', '=': 'center', '>': 'right', '<>': 'justify'} glyph_defaults = ( ('txt_quote_single_open', '‘'), ('txt_quote_single_close', '’'), ('txt_quote_double_open', '“'), ('txt_quote_double_close', '”'), ('txt_apostrophe', '’'), ('txt_prime', '′'), ('txt_prime_double', '″'), ('txt_ellipsis', '…'), ('txt_emdash', '—'), ('txt_endash', '–'), ('txt_dimension', '×'), ('txt_trademark', '™'), ('txt_registered', '®'), ('txt_copyright', '©'), ) def __init__(self, restricted=False, lite=False, noimage=False, auto_link=False, get_sizes=False): """docstring for __init__""" self.restricted = restricted self.lite = lite self.noimage = noimage self.get_sizes = get_sizes self.auto_link = auto_link self.fn = {} self.urlrefs = {} self.shelf = {} self.rel = '' self.html_type = 'xhtml' def textile(self, text, rel=None, head_offset=0, html_type='xhtml', sanitize=False): """ >>> import textile >>> textile.textile('some textile') '\\t

some textile

' """ self.html_type = html_type # text = unicode(text) text = _normalize_newlines(text) if self.restricted: text = self.encode_html(text, quotes=False) if rel: self.rel = ' rel="%s"' % rel text = self.getRefs(text) text = self.block(text, int(head_offset)) text = self.retrieve(text) if sanitize: text = sanitizer.sanitize(text, self.html_type) return text def pba(self, block_attributes, element=None): """ Parse block attributes. >>> t = Textile() >>> t.pba(r'\3') '' >>> t.pba(r'\\3', element='td') ' colspan="3"' >>> t.pba(r'/4', element='td') ' rowspan="4"' >>> t.pba(r'\\3/4', element='td') ' colspan="3" rowspan="4"' >>> t.pba('^', element='td') ' style="vertical-align:top;"' >>> t.pba('{line-height:18px}') ' style="line-height:18px;"' >>> t.pba('(foo-bar)') ' class="foo-bar"' >>> t.pba('(#myid)') ' id="myid"' >>> t.pba('(foo-bar#myid)') ' class="foo-bar" id="myid"' >>> t.pba('((((') ' style="padding-left:4em;"' >>> t.pba(')))') ' style="padding-right:3em;"' >>> t.pba('[fr]') ' lang="fr"' >>> rt = Textile() >>> rt.restricted = True >>> rt.pba('[en]') ' lang="en"' >>> rt.pba('(#id)') '' """ style = [] aclass = '' lang = '' colspan = '' rowspan = '' block_id = '' if not block_attributes: return '' matched = block_attributes if element == 'td': m = re.search(r'\\(\d+)', matched) if m: colspan = m.group(1) m = re.search(r'/(\d+)', matched) if m: rowspan = m.group(1) if element == 'td' or element == 'tr': m = re.search(r'(%s)' % self.vertical_align_re, matched) if m: style.append("vertical-align:%s;" % self.vAlign[m.group(1)]) m = re.search(r'\{([^}]*)\}', matched) if m: style.append(m.group(1).rstrip(';') + ';') matched = matched.replace(m.group(0), '') m = re.search(r'\[([^\]]+)\]', matched, re.U) if m: lang = m.group(1) matched = matched.replace(m.group(0), '') m = re.search(r'\(([^()]+)\)', matched, re.U) if m: aclass = m.group(1) matched = matched.replace(m.group(0), '') m = re.search(r'([(]+)', matched) if m: style.append("padding-left:%sem;" % len(m.group(1))) matched = matched.replace(m.group(0), '') m = re.search(r'([)]+)', matched) if m: style.append("padding-right:%sem;" % len(m.group(1))) matched = matched.replace(m.group(0), '') m = re.search(r'(%s)' % self.horizontal_align_re, matched) if m: style.append("text-align:%s;" % self.hAlign[m.group(1)]) m = re.search(r'^(.*)#(.*)$', aclass) if m: block_id = m.group(2) aclass = m.group(1) if self.restricted: if lang: return ' lang="%s"' % lang else: return '' result = [] if style: result.append(' style="%s"' % "".join(style)) if aclass: result.append(' class="%s"' % aclass) if lang: result.append(' lang="%s"' % lang) if block_id: result.append(' id="%s"' % block_id) if colspan: result.append(' colspan="%s"' % colspan) if rowspan: result.append(' rowspan="%s"' % rowspan) return ''.join(result) def hasRawText(self, text): """ checks whether the text has text not already enclosed by a block tag >>> t = Textile() >>> t.hasRawText('

foo bar biz baz

') False >>> t.hasRawText(' why yes, yes it does') True """ r = re.compile(r'<(p|blockquote|div|form|table|ul|ol|pre|h\d)[^>]*?>.*', re.S).sub('', text.strip()).strip() r = re.compile(r'<(hr|br)[^>]*?/>').sub('', r) return '' != r def table(self, text): r""" >>> t = Textile() >>> t.table('(rowclass). |one|two|three|\n|a|b|c|') '\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t
onetwothree
abc
\n\n' """ text = text + "\n\n" pattern = re.compile(r'^(?:table(_?%(s)s%(a)s%(c)s)\. ?\n)?^(%(a)s%(c)s\.? ?\|.*\|)\n\n' % {'s': self.table_span_re, 'a': self.align_re, 'c': self.c}, re.S | re.M | re.U) return pattern.sub(self.fTable, text) def fTable(self, match): tatts = self.pba(match.group(1), 'table') rows = [] for row in [x for x in match.group(2).split('\n') if x]: rmtch = re.search(r'^(%s%s\. )(.*)' % (self.align_re, self.c), row.lstrip()) if rmtch: ratts = self.pba(rmtch.group(1), 'tr') row = rmtch.group(2) else: ratts = '' cells = [] for cell in row.split('|')[1:-1]: ctyp = 'd' if re.search(r'^_', cell): ctyp = "h" cmtch = re.search(r'^(_?%s%s%s\. )(.*)' % (self.table_span_re, self.align_re, self.c), cell) if cmtch: catts = self.pba(cmtch.group(1), 'td') cell = cmtch.group(2) else: catts = '' cell = self.graf(self.span(cell)) cells.append('\t\t\t%s' % (ctyp, catts, cell, ctyp)) rows.append("\t\t\n%s\n\t\t" % (ratts, '\n'.join(cells))) cells = [] catts = None return "\t\n%s\n\t\n\n" % (tatts, '\n'.join(rows)) def lists(self, text): """ >>> t = Textile() >>> t.lists("* one\\n* two\\n* three") '\\t
    \\n\\t\\t
  • one
  • \\n\\t\\t
  • two
  • \\n\\t\\t
  • three
  • \\n\\t
' """ #Replace line-initial bullets with asterisks bullet_pattern = re.compile(u'^•', re.U | re.M) pattern = re.compile(r'^([#*]+%s .*)$(?![^#*])' % self.c, re.U | re.M | re.S) return pattern.sub(self.fList, bullet_pattern.sub('*', text)) def fList(self, match): text = match.group(0).split("\n") result = [] lists = [] for i, line in enumerate(text): try: nextline = text[i + 1] except IndexError: nextline = '' m = re.search(r"^([#*]+)(%s%s) (.*)$" % (self.align_re, self.c), line, re.S) if m: tl, atts, content = m.groups() nl = '' nm = re.search(r'^([#*]+)\s.*', nextline) if nm: nl = nm.group(1) if tl not in lists: lists.append(tl) atts = self.pba(atts) line = "\t<%sl%s>\n\t\t
  • %s" % (self.listType(tl), atts, self.graf(content)) else: line = "\t\t
  • " + self.graf(content) if len(nl) <= len(tl): line = line + "
  • " for k in reversed(lists): if len(k) > len(nl): line = line + "\n\t" % self.listType(k) if len(k) > 1: line = line + "" lists.remove(k) result.append(line) return "\n".join(result) def listType(self, list_string): if re.search(r'^#+', list_string): return 'o' else: return 'u' def doPBr(self, in_): return re.compile(r'<(p)([^>]*?)>(.*)()', re.S).sub(self.doBr, in_) def doBr(self, match): if self.html_type == 'html': content = re.sub(r'(.+)(?:(?)|(?))\n(?![#*\s|])', '\\1
    ', match.group(3)) else: content = re.sub(r'(.+)(?:(?)|(?))\n(?![#*\s|])', '\\1
    ', match.group(3)) return '<%s%s>%s%s' % (match.group(1), match.group(2), content, match.group(4)) def block(self, text, head_offset=0): """ >>> t = Textile() >>> t.block('h1. foobar baby') '\\t

    foobar baby

    ' """ if not self.lite: tre = '|'.join(self.btag) else: tre = '|'.join(self.btag_lite) text = text.split('\n\n') tag = 'p' atts = cite = graf = ext = '' c1 = '' out = [] anon = False for line in text: pattern = r'^(%s)(%s%s)\.(\.?)(?::(\S+))? (.*)$' % (tre, self.align_re, self.c) match = re.search(pattern, line, re.S) if match: if ext: out.append(out.pop() + c1) tag, atts, ext, cite, graf = match.groups() h_match = re.search(r'h([1-6])', tag) if h_match: head_level, = h_match.groups() tag = 'h%i' % max(1, min(int(head_level) + head_offset, 6)) o1, o2, content, c2, c1 = self.fBlock(tag, atts, ext, cite, graf) # leave off c1 if this block is extended, # we'll close it at the start of the next block if ext: line = "%s%s%s%s" % (o1, o2, content, c2) else: line = "%s%s%s%s%s" % (o1, o2, content, c2, c1) else: anon = True if ext or not re.search(r'^\s', line): o1, o2, content, c2, c1 = self.fBlock(tag, atts, ext, cite, line) # skip $o1/$c1 because this is part of a continuing # extended block if tag == 'p' and not self.hasRawText(content): line = content else: line = "%s%s%s" % (o2, content, c2) else: line = self.graf(line) line = self.doPBr(line) if self.html_type == 'xhtml': line = re.sub(r'
    ', '
    ', line) if ext and anon: out.append(out.pop() + "\n" + line) else: out.append(line) if not ext: tag = 'p' atts = '' cite = '' graf = '' if ext: out.append(out.pop() + c1) return '\n\n'.join(out) def fBlock(self, tag, atts, ext, cite, content): """ >>> t = Textile() >>> t.fBlock("bq", "", None, "", "Hello BlockQuote") ('\\t
    \\n', '\\t\\t

    ', 'Hello BlockQuote', '

    ', '\\n\\t
    ') >>> t.fBlock("bq", "", None, "http://google.com", "Hello BlockQuote") ('\\t
    \\n', '\\t\\t

    ', 'Hello BlockQuote', '

    ', '\\n\\t
    ') >>> t.fBlock("bc", "", None, "", 'printf "Hello, World";') # doctest: +ELLIPSIS ('
    ', '', ..., '', '
    ') >>> t.fBlock("h1", "", None, "", "foobar") ('', '\\t

    ', 'foobar', '

    ', '') """ atts = self.pba(atts) o1 = o2 = c2 = c1 = '' m = re.search(r'fn(\d+)', tag) if m: tag = 'p' if m.group(1) in self.fn: fnid = self.fn[m.group(1)] else: fnid = m.group(1) atts = atts + ' id="fn%s"' % fnid if atts.find('class=') < 0: atts = atts + ' class="footnote"' content = ('%s' % m.group(1)) + content if tag == 'bq': cite = self.checkRefs(cite) if cite: cite = ' cite="%s"' % cite else: cite = '' o1 = "\t\n" % (cite, atts) o2 = "\t\t" % atts c2 = "

    " c1 = "\n\t" elif tag == 'bc': o1 = "" % atts o2 = "" % atts c2 = "" c1 = "" content = self.shelve(self.encode_html(content.rstrip("\n") + "\n")) elif tag == 'notextile': content = self.shelve(content) o1 = o2 = '' c1 = c2 = '' elif tag == 'pre': content = self.shelve(self.encode_html(content.rstrip("\n") + "\n")) o1 = "" % atts o2 = c2 = '' c1 = '' else: o2 = "\t<%s%s>" % (tag, atts) c2 = "" % tag content = self.graf(content) return o1, o2, content, c2, c1 def footnoteRef(self, text): """ >>> t = Textile() >>> t.footnoteRef('foo[1] ') # doctest: +ELLIPSIS 'foo1 ' """ return re.compile(r'\b\[([0-9]+)\](\s)?', re.U).sub(self.footnoteID, text) def footnoteID(self, match): footnoteNum, text = match.groups() if footnoteNum not in self.fn: self.fn[footnoteNum] = str(uuid.uuid4()) footnoteID = self.fn[footnoteNum] if not text: text = '' return '%s%s' % ( footnoteID, footnoteNum, text) def glyphs(self, text): """ >>> t = Textile() >>> t.glyphs("apostrophe's") 'apostrophe’s' >>> t.glyphs("back in '88") 'back in ’88' >>> t.glyphs('foo ...') 'foo …' >>> t.glyphs('--') '—' >>> t.glyphs('FooBar[tm]') 'FooBar™' >>> t.glyphs("

    Cat's Cradle by Vonnegut

    ") '

    Cat’s Cradle by Vonnegut

    ' """ # fix: hackish text = re.sub(r'"\Z', '\" ', text) glyph_search = ( # apostrophe's re.compile(r"(\w)\'(\w)"), # back in '88 re.compile(r'(\s)\'(\d+\w?)\b(?!\')'), # single closing re.compile(r'(\S)\'(?=\s|' + self.pnct + '|<|$)'), # single opening re.compile(r'\'/'), # double closing re.compile(r'(\S)\"(?=\s|' + self.pnct + '|<|$)'), # double opening re.compile(r'"'), # 3+ uppercase acronym re.compile(r'\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])'), # 3+ uppercase re.compile(r'\b([A-Z][A-Z\'\-]+[A-Z])(?=[\s.,\)>])'), # ellipsis re.compile(r'\b(\s{0,1})?\.{3}'), # em dash re.compile(r'(\s?)--(\s?)'), # en dash re.compile(r'\s-(?:\s|$)'), # dimension sign re.compile(r'(\d+)( ?)x( ?)(?=\d+)'), # trademark re.compile(r'\b ?[([]TM[])]', re.I), # registered re.compile(r'\b ?[([]R[])]', re.I), # copyright re.compile(r'\b ?[([]C[])]', re.I), ) glyph_replace = [x % dict(self.glyph_defaults) for x in ( r'\1%(txt_apostrophe)s\2', # apostrophe's r'\1%(txt_apostrophe)s\2', # back in '88 r'\1%(txt_quote_single_close)s', # single closing r'%(txt_quote_single_open)s', # single opening r'\1%(txt_quote_double_close)s', # double closing r'%(txt_quote_double_open)s', # double opening r'\1', # 3+ uppercase acronym r'\1', # 3+ uppercase r'\1%(txt_ellipsis)s', # ellipsis r'\1%(txt_emdash)s\2', # em dash r' %(txt_endash)s ', # en dash r'\1\2%(txt_dimension)s\3', # dimension sign r'%(txt_trademark)s', # trademark r'%(txt_registered)s', # registered r'%(txt_copyright)s', # copyright )] result = [] for line in re.compile(r'(<.*?>)', re.U).split(text): if not re.search(r'<.*>', line): for s, r in zip(glyph_search, glyph_replace): line = s.sub(r, line) result.append(line) return ''.join(result) def getRefs(self, text): """ Capture and store URL references in self.urlrefs. >>> t = Textile() >>> t.getRefs("some text [Google]http://www.google.com") 'some text ' >>> t.urlrefs {'Google': 'http://www.google.com'} """ pattern = re.compile(r'(?:(?<=^)|(?<=\s))\[(.+)\]((?:http(?:s?):\/\/|\/)\S+)(?=\s|$)', re.U) text = pattern.sub(self.refs, text) return text def refs(self, match): flag, url = match.groups() self.urlrefs[flag] = url return '' def checkRefs(self, url): return self.urlrefs.get(url, url) def isRelURL(self, url): """ Identify relative urls. >>> t = Textile() >>> t.isRelURL("http://www.google.com/") False >>> t.isRelURL("/foo") True """ (scheme, netloc) = urlparse(url)[0:2] return not scheme and not netloc def relURL(self, url): """ >>> t = Textile() >>> t.relURL("http://www.google.com/") 'http://www.google.com/' >>> t.restricted = True >>> t.relURL("gopher://gopher.com/") '#' """ scheme = urlparse(url)[0] if self.restricted and scheme and scheme not in self.url_schemes: return '#' return url def shelve(self, text): itemID = str(uuid.uuid4()) self.shelf[itemID] = text return itemID def retrieve(self, text): """ >>> t = Textile() >>> id = t.shelve("foobar") >>> t.retrieve(id) 'foobar' """ while True: old = text for k, v in self.shelf.items(): text = text.replace(k, v) if text == old: break return text def encode_html(self, text, quotes=True): a = ( ('&', '&'), ('<', '<'), ('>', '>')) if quotes: a = a + (("'", '''), ('"', '"')) for k, v in a: text = text.replace(k, v) return text def graf(self, text): if not self.lite: text = self.noTextile(text) text = self.code(text) if self.auto_link: text = self.autoLink(text) text = self.links(text) if not self.noimage: text = self.image(text) text = self.lists(text) if not self.lite: text = self.table(text) text = self.span(text) text = self.footnoteRef(text) text = self.glyphs(text) return text.rstrip('\n') def autoLink(self, text): """ >>> t = Textile() >>> t.autoLink("http://www.ya.ru") '"http://www.ya.ru":http://www.ya.ru' """ pattern = re.compile(r"""\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))""", re.U | re.I) return pattern.sub(r'"\1":\1', text) def links(self, text): """ >>> t = Textile() >>> t.links('fooobar "Google":http://google.com/foobar/ and hello world "flickr":http://flickr.com/photos/jsamsa/ ') # doctest: +ELLIPSIS 'fooobar ... and hello world ...' """ punct = '!"#$%&\'*+,-./:;=?@\\^_`|~' pattern = r''' (?P
    [\s\[{(]|[%s])?         #leading text
                "                               #opening quote
                (?P%s)                    #block attributes
                (?P[^"]+?)                #link text
                \s?
                (?:\((?P[^)]+?)\)(?="))? #optional title
                ":                              #closing quote, colon
                (?P<url>(?:ftp|https?)?         #URL
                            (?: :// )?
                            [-A-Za-z0-9+&@#/?=~_()|!:,.;%%]*
                            [-A-Za-z0-9+&@#/=~_()|]
                )
                (?P<post>[^\w\/;]*?)	    #trailing text
                (?=<|\s|$)
            ''' % (re.escape(punct), self.c)
    
            text = re.compile(pattern, re.X).sub(self.fLink, text)
    
            return text
    
        def fLink(self, match):
            pre, atts, text, title, url, post = match.groups()
    
            if pre == None:
                pre = ''
    
            # assume ) at the end of the url is not actually part of the url
            # unless the url also contains a (
            if url.endswith(')') and not url.find('(') > -1:
                post = url[-1] + post
                url = url[:-1]
    
            url = self.checkRefs(url)
    
            atts = self.pba(atts)
            if title:
                atts = atts + ' title="%s"' % self.encode_html(title)
    
            if not self.noimage:
                text = self.image(text)
    
            text = self.span(text)
            text = self.glyphs(text)
    
            url = self.relURL(url)
            out = '<a href="%s"%s%s>%s</a>' % (self.encode_html(url),
                                               atts, self.rel, text)
            out = self.shelve(out)
            return ''.join([pre, out, post])
    
        def span(self, text):
            """
            >>> t = Textile()
            >>> t.span(r"hello %(bob)span *strong* and **bold**% goodbye")
            'hello <span class="bob">span <strong>strong</strong> and <b>bold</b></span> goodbye'
            """
            qtags = (r'\*\*', r'\*', r'\?\?', r'\-', r'__',
                     r'_', r'%', r'\+', r'~', r'\^')
            pnct = ".,\"'?!;:("
    
            for qtag in qtags:
                pattern = re.compile(r"""
                    (?:^|(?<=[\s>%(pnct)s])|([\[{]))
                    (%(qtag)s)(?!%(qtag)s)
                    (%(c)s)
                    (?::\(([^)]+?)\))?
                    ([^\s%(qtag)s]+|\S[^%(qtag)s\n]*[^\s%(qtag)s\n])
                    ([%(pnct)s]*)
                    %(qtag)s
                    (?:$|([\]}])|(?=%(selfpnct)s{1,2}|\s))
                """ % {'qtag': qtag, 'c': self.c, 'pnct': pnct,
                       'selfpnct': self.pnct}, re.X)
                text = pattern.sub(self.fSpan, text)
            return text
    
        def fSpan(self, match):
            _, tag, atts, cite, content, end, _ = match.groups()
    
            qtags = {'*': 'strong',
                    '**': 'b',
                    '??': 'cite',
                     '_': 'em',
                    '__': 'i',
                     '-': 'del',
                     '%': 'span',
                     '+': 'ins',
                     '~': 'sub',
                     '^': 'sup'}
    
            tag = qtags[tag]
            atts = self.pba(atts)
            if cite:
                atts = atts + ' cite="%s"' % cite
    
            content = self.span(content)
    
            out = "<%s%s>%s%s</%s>" % (tag, atts, content, end, tag)
            return out
    
        def image(self, text):
            """
            >>> t = Textile()
            >>> t.image('!/imgs/myphoto.jpg!:http://jsamsa.com')
            '<a href="http://jsamsa.com" class="img"><img src="/imgs/myphoto.jpg" alt="" /></a>'
            >>> t.image('!</imgs/myphoto.jpg!')
            '<img src="/imgs/myphoto.jpg" style="float: left;" alt="" />'
            """
            pattern = re.compile(r"""
                (?:[\[{])?         # pre
                \!                 # opening !
                (\<|\=|\>)?        # optional alignment atts
                (%s)               # optional style,class atts
                (?:\. )?           # optional dot-space
                ([^\s(!]+)         # presume this is the src
                \s?                # optional space
                (?:\(([^\)]+)\))?  # optional title
                \!                 # closing
                (?::(\S+))?        # optional href
                (?:[\]}]|(?=\s|$)) # lookahead: space or end of string
            """ % self.c, re.U | re.X)
            return pattern.sub(self.fImage, text)
    
        def fImage(self, match):
            # (None, '', '/imgs/myphoto.jpg', None, None)
            align, atts, url, title, href = match.groups()
            atts = self.pba(atts)
    
            if align:
                atts = atts + ' style="%s"' % self.iAlign[align]
    
            if title:
                atts = atts + ' title="%s" alt="%s"' % (title, title)
            else:
                atts = atts + ' alt=""'
    
            if not self.isRelURL(url) and self.get_sizes:
                size = imagesize.getimagesize(url)
                if size:
                    atts += " %s" % size
    
            if href:
                href = self.checkRefs(href)
    
            url = self.checkRefs(url)
            url = self.relURL(url)
    
            out = []
            if href:
                out.append('<a href="%s" class="img">' % href)
            if self.html_type == 'html':
                out.append('<img src="%s"%s>' % (url, atts))
            else:
                out.append('<img src="%s"%s />' % (url, atts))
            if href:
                out.append('</a>')
    
            return ''.join(out)
    
        def code(self, text):
            text = self.doSpecial(text, '<code>', '</code>', self.fCode)
            text = self.doSpecial(text, '@', '@', self.fCode)
            text = self.doSpecial(text, '<pre>', '</pre>', self.fPre)
            return text
    
        def fCode(self, match):
            before, text, after = match.groups()
            if after == None:
                after = ''
            # text needs to be escaped
            if not self.restricted:
                text = self.encode_html(text, quotes=False)
            return ''.join([before, self.shelve('<code>%s</code>' % text), after])
    
        def fPre(self, match):
            before, text, after = match.groups()
            if after == None:
                after = ''
            # text needs to be escaped
            if not self.restricted:
                text = self.encode_html(text)
            return ''.join([before, '<pre>', self.shelve(text), '</pre>', after])
    
        def doSpecial(self, text, start, end, method):
            pattern = re.compile(r'(^|\s|[\[({>])%s(.*?)%s(\s|$|[\])}])?'
                                 % (re.escape(start), re.escape(end)), re.M | re.S)
            return pattern.sub(method, text)
    
        def noTextile(self, text):
            text = self.doSpecial(text, '<notextile>', '</notextile>',
                                  self.fTextile)
            return self.doSpecial(text, '==', '==', self.fTextile)
    
        def fTextile(self, match):
            before, notextile, after = match.groups()
            if after == None:
                after = ''
            return ''.join([before, self.shelve(notextile), after])
    
    
    def textile(text, head_offset=0, html_type='xhtml', auto_link=False,
                encoding=None, output=None):
        """
        Apply Textile to a block of text.
    
        This function takes the following additional parameters:
    
        auto_link - enable automatic linking of URLs (default: False)
        head_offset - offset to apply to heading levels (default: 0)
        html_type - 'xhtml' or 'html' style tags (default: 'xhtml')
    
        """
        return Textile(auto_link=auto_link).textile(text, head_offset=head_offset,
                                                      html_type=html_type)
    
    
    def textile_restricted(text, lite=True, noimage=True, html_type='xhtml',
                           auto_link=False):
        """
        Apply Textile to a block of text, with restrictions designed for weblog
        comments and other untrusted input.  Raw HTML is escaped, style attributes
        are disabled, and rel='nofollow' is added to external links.
    
        This function takes the following additional parameters:
    
        auto_link - enable automatic linking of URLs (default: False)
        html_type - 'xhtml' or 'html' style tags (default: 'xhtml')
        lite - restrict block tags to p, bq, and bc, disable tables (default: True)
        noimage - disable image tags (default: True)
    
        """
        return Textile(restricted=True, lite=lite,
                       noimage=noimage, auto_link=auto_link).textile(
            text, rel='nofollow', html_type=html_type)
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile/tests/������������������������������������������������������������������������0000755�0000765�0000024�00000000000�11560135413�015714� 5����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile/tests/__init__.py�������������������������������������������������������������0000644�0000765�0000024�00000053325�11560133635�020041� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ # -*- coding: utf-8 -*-
    import textile
    import re
    from nose.tools import eq_, assert_true
    from nose.plugins.skip import SkipTest
    
    """
    ('>>> import textile')
    '<p>>>> import textile</p>'
    
    """
    
    
    class TestKnownValues():
        xhtml_known_values = (
            ('hello, world', '\t<p>hello, world</p>'),
    
            ('A single paragraph.\n\nFollowed by another.','\t<p>A single paragraph.</p>\n\n\t<p>Followed by another.</p>'),
    
            ('I am <b>very</b> serious.\n\n<pre>\nI am <b>very</b> serious.\n</pre>',
             '\t<p>I am <b>very</b> serious.</p>\n\n<pre>\nI am <b>very</b> serious.\n</pre>'),
    
            ('I spoke.\nAnd none replied.', '\t<p>I spoke.<br />And none replied.</p>'),
    
            ('"Observe!"', '\t<p>“Observe!” </p>'),
    
            ('Observe -- very nice!', '\t<p>Observe — very nice!</p>'),
    
            ('Observe - tiny and brief.', '\t<p>Observe – tiny and brief.</p>'),
    
            ('Observe...', '\t<p>Observe…</p>'),
    
            ('Observe ...', '\t<p>Observe …</p>'),
    
            ('Observe: 2 x 2.', '\t<p>Observe: 2 × 2.</p>'),
    
            ('one(TM), two(R), three(C).', '\t<p>one™, two®, three©.</p>'),
    
            ('h1. Header 1', '\t<h1>Header 1</h1>'),
    
            ('h2. Header 2', '\t<h2>Header 2</h2>'),
    
            ('h3. Header 3', '\t<h3>Header 3</h3>'),
    
            ('An old text\n\nbq. A block quotation.\n\nAny old text''',
            '\t<p>An old text</p>\n\n\t<blockquote>\n\t\t<p>A block quotation.</p>\n\t</blockquote>\n\n\t<p>Any old text</p>'),
    
            ('I _believe_ every word.', '\t<p>I <em>believe</em> every word.</p>'),
    
            ('And then? She *fell*!', '\t<p>And then? She <strong>fell</strong>!</p>'),
    
            ('I __know__.\nI **really** __know__.', '\t<p>I <i>know</i>.<br />I <b>really</b> <i>know</i>.</p>'),
    
            ("??Cat's Cradle?? by Vonnegut", '\t<p><cite>Cat’s Cradle</cite> by Vonnegut</p>'),
    
            ('Convert with @str(foo)@', '\t<p>Convert with <code>str(foo)</code></p>'),
    
            ('I\'m -sure- not sure.', '\t<p>I’m <del>sure</del> not sure.</p>'),
    
            ('You are a +pleasant+ child.', '\t<p>You are a <ins>pleasant</ins> child.</p>'),
    
            ('a ^2^ + b ^2^ = c ^2^', '\t<p>a <sup>2</sup> + b <sup>2</sup> = c <sup>2</sup></p>'),
    
            ('log ~2~ x', '\t<p>log <sub>2</sub> x</p>'),
    
            ('I\'m %unaware% of most soft drinks.', '\t<p>I’m <span>unaware</span> of most soft drinks.</p>'),
    
            ("I'm %{color:red}unaware%\nof most soft drinks.", '\t<p>I’m <span style="color:red;">unaware</span><br />of most soft drinks.</p>'),
    
            ('p(example1). An example', '\t<p class="example1">An example</p>'),
    
            ('p(#big-red). Red here', '\t<p id="big-red">Red here</p>'),
    
            ('p(example1#big-red2). Red here', '\t<p class="example1" id="big-red2">Red here</p>'),
    
            ('p{color:blue;margin:30px}. Spacey blue', '\t<p style="color:blue;margin:30px;">Spacey blue</p>'),
    
            ('p[fr]. rouge', '\t<p lang="fr">rouge</p>'),
    
            ('I seriously *{color:red}blushed*\nwhen I _(big)sprouted_ that\ncorn stalk from my\n%[es]cabeza%.',
            '\t<p>I seriously <strong style="color:red;">blushed</strong><br />when I <em class="big">sprouted</em>'
            ' that<br />corn stalk from my<br /><span lang="es">cabeza</span>.</p>'),
    
            ('p<. align left', '\t<p style="text-align:left;">align left</p>'),
    
            ('p>. align right', '\t<p style="text-align:right;">align right</p>'),
    
            ('p=. centered', '\t<p style="text-align:center;">centered</p>'),
    
            ('p<>. justified', '\t<p style="text-align:justify;">justified</p>'),
    
            ('p(. left ident 1em', '\t<p style="padding-left:1em;">left ident 1em</p>'),
    
            ('p((. left ident 2em', '\t<p style="padding-left:2em;">left ident 2em</p>'),
    
            ('p))). right ident 3em', '\t<p style="padding-right:3em;">right ident 3em</p>'),
    
            ('h2()>. Bingo.', '\t<h2 style="padding-left:1em;padding-right:1em;text-align:right;">Bingo.</h2>'),
    
            ('h3()>[no]{color:red}. Bingo', '\t<h3 style="color:red;padding-left:1em;padding-right:1em;text-align:right;" lang="no">Bingo</h3>'),
    
            ('<pre>\n<code>\na.gsub!( /</, "" )\n</code>\n</pre>',
             '<pre>\n<code>\na.gsub!( /</, "" )\n</code>\n</pre>'),
    
            ('<div style="float:right;">\n\nh3. Sidebar\n\n"Hobix":http://hobix.com/\n"Ruby":http://ruby-lang.org/\n\n</div>\n\n'
             'The main text of the\npage goes here and will\nstay to the left of the\nsidebar.',
             '\t<p><div style="float:right;"></p>\n\n\t<h3>Sidebar</h3>\n\n\t<p><a href="http://hobix.com/">Hobix</a><br />'
             '<a href="http://ruby-lang.org/">Ruby</a></p>\n\n\t<p></div></p>\n\n\t<p>The main text of the<br />'
             'page goes here and will<br />stay to the left of the<br />sidebar.</p>'),
    
            ('# A first item\n# A second item\n# A third',
             '\t<ol>\n\t\t<li>A first item</li>\n\t\t<li>A second item</li>\n\t\t<li>A third</li>\n\t</ol>'),
    
            ('# Fuel could be:\n## Coal\n## Gasoline\n## Electricity\n# Humans need only:\n## Water\n## Protein',
             '\t<ol>\n\t\t<li>Fuel could be:\n\t<ol>\n\t\t<li>Coal</li>\n\t\t<li>Gasoline</li>\n\t\t<li>Electricity</li>\n\t</ol></li>\n\t\t'
             '<li>Humans need only:\n\t<ol>\n\t\t<li>Water</li>\n\t\t<li>Protein</li>\n\t</ol></li>\n\t</ol>'),
    
            ('* A first item\n* A second item\n* A third',
             '\t<ul>\n\t\t<li>A first item</li>\n\t\t<li>A second item</li>\n\t\t<li>A third</li>\n\t</ul>'),
    
            (u'• A first item\n• A second item\n• A third',
             '\t<ul>\n\t\t<li>A first item</li>\n\t\t<li>A second item</li>\n\t\t<li>A third</li>\n\t</ul>'),
    
            ('* Fuel could be:\n** Coal\n** Gasoline\n** Electricity\n* Humans need only:\n** Water\n** Protein',
             '\t<ul>\n\t\t<li>Fuel could be:\n\t<ul>\n\t\t<li>Coal</li>\n\t\t<li>Gasoline</li>\n\t\t<li>Electricity</li>\n\t</ul></li>\n\t\t'
             '<li>Humans need only:\n\t<ul>\n\t\t<li>Water</li>\n\t\t<li>Protein</li>\n\t</ul></li>\n\t</ul>'),
    
            ('I searched "Google":http://google.com.', '\t<p>I searched <a href="http://google.com">Google</a>.</p>'),
    
            ('I searched "a search engine (Google)":http://google.com.', '\t<p>I searched <a href="http://google.com" title="Google">a search engine</a>.</p>'),
    
            ('I am crazy about "Hobix":hobix\nand "it\'s":hobix "all":hobix I ever\n"link to":hobix!\n\n[hobix]http://hobix.com',
             '\t<p>I am crazy about <a href="http://hobix.com">Hobix</a><br />and <a href="http://hobix.com">it’s</a> '
             '<a href="http://hobix.com">all</a> I ever<br /><a href="http://hobix.com">link to</a>!</p>\n\n'),
    
            ('!http://hobix.com/sample.jpg!', '\t<p><img src="http://hobix.com/sample.jpg" alt="" /></p>'),
    
            ('!openwindow1.gif(Bunny.)!', '\t<p><img src="openwindow1.gif" title="Bunny." alt="Bunny." /></p>'),
    
            ('!openwindow1.gif!:http://hobix.com/', '\t<p><a href="http://hobix.com/" class="img"><img src="openwindow1.gif" alt="" /></a></p>'),
    
            ('!>obake.gif!\n\nAnd others sat all round the small\nmachine and paid it to sing to them.',
             '\t<p><img src="obake.gif" style="float: right;" alt="" /></p>\n\n\t'
             '<p>And others sat all round the small<br />machine and paid it to sing to them.</p>'),
    
            ('We use CSS(Cascading Style Sheets).', '\t<p>We use <acronym title="Cascading Style Sheets">CSS</acronym>.</p>'),
    
            ('|one|two|three|\n|a|b|c|',
             '\t<table>\n\t\t<tr>\n\t\t\t<td>one</td>\n\t\t\t<td>two</td>\n\t\t\t<td>three</td>\n\t\t</tr>'
             '\n\t\t<tr>\n\t\t\t<td>a</td>\n\t\t\t<td>b</td>\n\t\t\t<td>c</td>\n\t\t</tr>\n\t</table>'),
    
            ('| name | age | sex |\n| joan | 24 | f |\n| archie | 29 | m |\n| bella | 45 | f |',
             '\t<table>\n\t\t<tr>\n\t\t\t<td> name </td>\n\t\t\t<td> age </td>\n\t\t\t<td> sex </td>\n\t\t</tr>'
             '\n\t\t<tr>\n\t\t\t<td> joan </td>\n\t\t\t<td> 24 </td>\n\t\t\t<td> f </td>\n\t\t</tr>'
             '\n\t\t<tr>\n\t\t\t<td> archie </td>\n\t\t\t<td> 29 </td>\n\t\t\t<td> m </td>\n\t\t</tr>'
             '\n\t\t<tr>\n\t\t\t<td> bella </td>\n\t\t\t<td> 45 </td>\n\t\t\t<td> f </td>\n\t\t</tr>\n\t</table>'),
    
            ('|_. name |_. age |_. sex |\n| joan | 24 | f |\n| archie | 29 | m |\n| bella | 45 | f |',
             '\t<table>\n\t\t<tr>\n\t\t\t<th>name </th>\n\t\t\t<th>age </th>\n\t\t\t<th>sex </th>\n\t\t</tr>'
             '\n\t\t<tr>\n\t\t\t<td> joan </td>\n\t\t\t<td> 24 </td>\n\t\t\t<td> f </td>\n\t\t</tr>'
             '\n\t\t<tr>\n\t\t\t<td> archie </td>\n\t\t\t<td> 29 </td>\n\t\t\t<td> m </td>\n\t\t</tr>'
             '\n\t\t<tr>\n\t\t\t<td> bella </td>\n\t\t\t<td> 45 </td>\n\t\t\t<td> f </td>\n\t\t</tr>\n\t</table>'),
    
            # ('<script>alert("hello");</script>', ''),
    
            ('pre.. Hello\n\nHello Again\n\np. normal text', '<pre>Hello\n\nHello Again\n</pre>\n\n\t<p>normal text</p>'),
    
            ('<pre>this is in a pre tag</pre>', '<pre>this is in a pre tag</pre>'),
    
            ('"test1":http://foo.com/bar--baz\n\n"test2":http://foo.com/bar---baz\n\n"test3":http://foo.com/bar-17-18-baz',
             '\t<p><a href="http://foo.com/bar--baz">test1</a></p>\n\n\t'
             '<p><a href="http://foo.com/bar---baz">test2</a></p>\n\n\t'
             '<p><a href="http://foo.com/bar-17-18-baz">test3</a></p>'),
    
            # ('"foo ==(bar)==":#foobar', '\t<p><a href="#foobar">foo (bar)</a></p>'),
    
            ('!http://render.mathim.com/A%5EtAx%20%3D%20A%5Et%28Ax%29.!',
             '\t<p><img src="http://render.mathim.com/A%5EtAx%20%3D%20A%5Et%28Ax%29." alt="" /></p>'),
    
            ('* Point one\n* Point two\n## Step 1\n## Step 2\n## Step 3\n* Point three\n** Sub point 1\n** Sub point 2',
             '\t<ul>\n\t\t<li>Point one</li>\n\t\t<li>Point two\n\t<ol>\n\t\t<li>Step 1</li>\n\t\t<li>Step 2</li>\n\t\t'
             '<li>Step 3</li>\n\t</ol></li>\n\t\t<li>Point three\n\t<ul>\n\t\t<li>Sub point 1</li>\n\t\t'
             '<li>Sub point 2</li>\n\t</ul></li>\n\t</ul>'),
    
            ('@array[4] = 8@', '\t<p><code>array[4] = 8</code></p>'),
    
            ('#{color:blue} one\n# two\n# three',
             '\t<ol style="color:blue;">\n\t\t<li>one</li>\n\t\t<li>two</li>\n\t\t<li>three</li>\n\t</ol>'),
    
            ('Links (like "this":http://foo.com), are now mangled in 2.1.0, whereas 2.0 parsed them correctly.',
             '\t<p>Links (like <a href="http://foo.com">this</a>), are now mangled in 2.1.0, whereas 2.0 parsed them correctly.</p>'),
    
            ('@monospaced text@, followed by text',
             '\t<p><code>monospaced text</code>, followed by text</p>'),
    
            ('h2. A header\n\n\n\n\n\nsome text', '\t<h2>A header</h2>\n\n\t<p>some text</p>'),
    
            ('*:(foo)foo bar baz*','\t<p><strong cite="foo">foo bar baz</strong></p>'),
    
            ('pre.. foo bar baz\nquux','<pre>foo bar baz\nquux\n</pre>'),
    
            ('line of text\n\n    leading spaces','\t<p>line of text</p>\n\n    leading spaces'),
    
            ('"some text":http://www.example.com/?q=foo%20bar and more text','\t<p><a href="http://www.example.com/?q=foo%20bar">some text</a> and more text</p>'),
    
            ('(??some text??)','\t<p>(<cite>some text</cite>)</p>'),
    
            ('(*bold text*)','\t<p>(<strong>bold text</strong>)</p>'),
    
            ('H[~2~]O','\t<p>H<sub>2</sub>O</p>'),
    
            (u"p=. Où est l'école, l'église s'il vous plaît?",
             u"""\t<p style="text-align:center;">Où est l’école, l’église s’il vous plaît?</p>"""),
            
            ("p=. *_The_* _*Prisoner*_", 
             """\t<p style="text-align:center;"><strong><em>The</em></strong> <em><strong>Prisoner</strong></em></p>"""),
    
            ("""p=. "An emphasised _word._" & "*A spanned phrase.*" """,
             """\t<p style="text-align:center;">“An emphasised <em>word.</em>” & “<strong>A spanned phrase.</strong>” </p>"""),
    
            ("""p=. "*Here*'s a word!" """, 
             """\t<p style="text-align:center;">“<strong>Here</strong>’s a word!” </p>"""),
    
            ("""p=. "Please visit our "Textile Test Page":http://textile.sitemonks.com" """,
             """\t<p style="text-align:center;">“Please visit our <a href="http://textile.sitemonks.com">Textile Test Page</a>” </p>"""),
            
            (u"""| Foreign EXPÓŅÉNTIAL |""",
             u"""\t<table>\n\t\t<tr>\n\t\t\t<td>Foreign <span class="caps">EXPÓŅÉNTIAL</span> </td>\n\t\t\t<td>\n\t\t</tr>\n\t</table>"""),
    
            (u"""p=. Tell me, what is AJAX(Asynchronous Javascript and XML), please?""", 
             u"""\t<p style="text-align:center;">Tell me, what is <acronym title="Asynchronous Javascript and XML">AJAX</acronym>, please?</p>"""),
    
    
        )
    
        # A few extra cases for HTML4
        html_known_values = (
            ('I spoke.\nAnd none replied.', '\t<p>I spoke.<br>And none replied.</p>'),
            ('I __know__.\nI **really** __know__.', '\t<p>I <i>know</i>.<br>I <b>really</b> <i>know</i>.</p>'),
            ("I'm %{color:red}unaware%\nof most soft drinks.", '\t<p>I’m <span style="color:red;">unaware</span><br>of most soft drinks.</p>'),
            ('I seriously *{color:red}blushed*\nwhen I _(big)sprouted_ that\ncorn stalk from my\n%[es]cabeza%.',
            '\t<p>I seriously <strong style="color:red;">blushed</strong><br>when I <em class="big">sprouted</em>'
            ' that<br>corn stalk from my<br><span lang="es">cabeza</span>.</p>'),
            ('<pre>\n<code>\na.gsub!( /</, "" )\n</code>\n</pre>',
             '<pre>\n<code>\na.gsub!( /</, "" )\n</code>\n</pre>'),
            ('<div style="float:right;">\n\nh3. Sidebar\n\n"Hobix":http://hobix.com/\n"Ruby":http://ruby-lang.org/\n\n</div>\n\n'
             'The main text of the\npage goes here and will\nstay to the left of the\nsidebar.',
             '\t<p><div style="float:right;"></p>\n\n\t<h3>Sidebar</h3>\n\n\t<p><a href="http://hobix.com/">Hobix</a><br>'
             '<a href="http://ruby-lang.org/">Ruby</a></p>\n\n\t<p></div></p>\n\n\t<p>The main text of the<br>'
             'page goes here and will<br>stay to the left of the<br>sidebar.</p>'),
            ('I am crazy about "Hobix":hobix\nand "it\'s":hobix "all":hobix I ever\n"link to":hobix!\n\n[hobix]http://hobix.com',
             '\t<p>I am crazy about <a href="http://hobix.com">Hobix</a><br>and <a href="http://hobix.com">it’s</a> '
             '<a href="http://hobix.com">all</a> I ever<br><a href="http://hobix.com">link to</a>!</p>\n\n'),
            ('!http://hobix.com/sample.jpg!', '\t<p><img src="http://hobix.com/sample.jpg" alt=""></p>'),
            ('!openwindow1.gif(Bunny.)!', '\t<p><img src="openwindow1.gif" title="Bunny." alt="Bunny."></p>'),
            ('!openwindow1.gif!:http://hobix.com/', '\t<p><a href="http://hobix.com/" class="img"><img src="openwindow1.gif" alt=""></a></p>'),
            ('!>obake.gif!\n\nAnd others sat all round the small\nmachine and paid it to sing to them.',
             '\t<p><img src="obake.gif" style="float: right;" alt=""></p>\n\n\t'
             '<p>And others sat all round the small<br>machine and paid it to sing to them.</p>'),
            ('!http://render.mathim.com/A%5EtAx%20%3D%20A%5Et%28Ax%29.!',
             '\t<p><img src="http://render.mathim.com/A%5EtAx%20%3D%20A%5Et%28Ax%29." alt=""></p>'),
            ('notextile. <b> foo bar baz</b>\n\np. quux\n','<b> foo bar baz</b>\n\n\t<p>quux</p>')
        )
    
        def testKnownValuesXHTML(self):
            # XHTML
            for t, h in self.xhtml_known_values:
                yield self.check_textile, t, h, 'xhtml'
    
        def testKnownValuesHTML(self):
            # HTML4
            for t, h in self.html_known_values:
                yield self.check_textile, t, h, 'html'
    
        def check_textile(self, input, expected_output, html_type):
            output = textile.textile(input, html_type=html_type)
            eq_(output, expected_output)
    
    
    class Tests():
        def testFootnoteReference(self):
            html = textile.textile('YACC[1]')
            assert_true(re.search('^\t<p>YACC<sup class="footnote"><a href="#fn[a-z0-9-]+">1</a></sup></p>', html))
    
        def testFootnote(self):
            html = textile.textile('This is covered elsewhere[1].\n\nfn1. Down here, in fact.\n\nfn2. Here is another footnote.')
            assert_true(re.search('^\t<p>This is covered elsewhere<sup class="footnote"><a href="#fn[a-z0-9-]+">1</a></sup>.</p>\n\n\t<p id="fn[a-z0-9-]+" class="footnote"><sup>1</sup>Down here, in fact.</p>\n\n\t<p id="fn[a-z0-9-]+" class="footnote"><sup>2</sup>Here is another footnote.</p>$', html))
    
        def testURLWithHyphens(self):
            eq_(textile.textile('"foo":http://google.com/one--two'), '\t<p><a href="http://google.com/one--two">foo</a></p>')
    
        def testIssue024TableColspan(self):
            eq_(textile.textile('|\\2. spans two cols |\n| col 1 | col 2 |'),
                '\t<table>\n\t\t<tr>\n\t\t\t<td colspan="2">spans two cols </td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td> col 1 </td>\n\t\t\t<td> col 2 </td>\n\t\t</tr>\n\t</table>')
    
        def testPBAColspan(self):
            eq_(textile.Textile().pba(r'\3', element='td'), ' colspan="3"')
    
        def testIssue002Escaping(self):
            foo = '"foo ==(bar)==":#foobar'
            eq_(textile.textile(foo), '\t<p><a href="#foobar">foo (bar)</a></p>')
    
        def testIssue014NewlinesInExtendedPreBlocks(self):
            text = "pre.. Hello\n\nAgain\n\np. normal text"
            eq_(textile.textile(text), '<pre>Hello\n\nAgain\n</pre>\n\n\t<p>normal text</p>')
    
        def testURLWithParens(self):
            text = '"python":http://en.wikipedia.org/wiki/Python_(programming_language)'
            expect = '\t<p><a href="http://en.wikipedia.org/wiki/Python_(programming_language)">python</a></p>'
            result = textile.textile(text)
            eq_(result, expect)
    
        def testTableWithHyphenStyles(self):
            text = 'table(linkblog-thumbnail).\n|(linkblog-thumbnail-cell). apple|bear|'
            expect = '\t<table class="linkblog-thumbnail">\n\t\t<tr>\n\t\t\t<td style="vertical-align:middle;" class="linkblog-thumbnail-cell">apple</td>\n\t\t\t<td>bear</td>\n\t\t</tr>\n\t</table>'
            result = textile.textile(text)
            eq_(result, expect)
    
        def testHeadOffset(self):
            text = 'h2. This is a header'
            head_offset = 2
            expect = '\t<h4>This is a header</h4>'
            result = textile.textile(text, head_offset=head_offset)
            eq_(result, expect)
    
        def testIssue035(self):
            result = textile.textile('"z"')
            expect = '\t<p>“z” </p>'
            eq_(result, expect)
    
            result = textile.textile('" z"')
            expect = '\t<p>“ z” </p>'
            eq_(result, expect)
    
        def testIssue032(self):
            text = "|thing|||otherthing|"
            result = textile.textile(text)
            expect = "\t<table>\n\t\t<tr>\n\t\t\t<td>thing</td>\n\t\t\t<td></td>\n\t\t\t<td></td>\n\t\t\t<td>otherthing</td>\n\t\t</tr>\n\t</table>"
            eq_(result, expect)
    
        def testIssue036(self):
            test = '"signup":signup\n[signup]http://myservice.com/signup'
            result = textile.textile(test)
            expect = '\t<p><a href="http://myservice.com/signup">signup</a></p>'
            eq_(result, expect)
    
            test = '"signup":signup\n[signup]https://myservice.com/signup'
            result = textile.textile(test)
            expect = '\t<p><a href="https://myservice.com/signup">signup</a></p>'
            eq_(result, expect)
    
        def testNestedFormatting(self):
            test = "*_test text_*"
            result = textile.textile(test)
            expect = "\t<p><strong><em>test text</em></strong></p>"
    
            eq_(result, expect)
    
            test = "_*test text*_"
            result = textile.textile(test)
            expect = "\t<p><em><strong>test text</strong></em></p>"
    
            eq_(result, expect)
    
        def testRestricted(self):
            test = "this is \"some\" *bold text*."
            result = textile.textile_restricted(test)
            expect = "\t<p>this is “some” <strong>bold text</strong>.</p>"
    
            eq_(result, expect)
    
            #Note that the HTML is escaped, thus rendering
            #the <script> tag harmless.
            test = "Here is some text.\n<script>alert('hello world')</script>"
            result = textile.textile_restricted(test)
            expect = "\t<p>Here is some text.<br /><script>alert('hello world’)</script></p>"
    
            eq_(result, expect)
    
        def testQuotesInCode(self):
            test = "<code>'quoted string'</code>"
            result = textile.textile(test)
            expect = "\t<p><code>'quoted string'</code></p>"
    
            eq_(result, expect)
    
        def testUnicodeFootnote(self):
            html = textile.textile(u'текст[1]')
            assert_true(re.compile(u'^\t<p>текст<sup class="footnote"><a href="#fn[a-z0-9-]+">1</a></sup></p>', re.U).search(html))
    
        def testAutoLinking(self):
            test = "some text http://www.google.com"
            result = "\t<p>some text <a href=\"http://www.google.com\">http://www.google.com</a></p>"
            expect = textile.textile(test, auto_link=True)
    
            eq_(result, expect)
    
        def testPre(self):
            test = "<pre>some preformatted text</pre>other text"
            result = "\t<p><pre>some preformatted text</pre>other text</p>"
            expect = textile.textile(test)
    
            eq_(result, expect)
    
        def testSanitize(self):
            try:
                import html5lib
            except ImportError:
                raise SkipTest()
    
            test = "a paragraph of benign text"
            result = "\t<p>a paragraph of benign text</p>"
            expect = textile.Textile().textile(test, sanitize=True)
            eq_(result, expect)
    
            test = """<p style="width: expression(alert('evil'));">a paragraph of evil text</p>"""
            result = '<p style="">a paragraph of evil text</p>'
            expect = textile.Textile().textile(test, sanitize=True)
            eq_(result, expect)
    
            test = """<p>a paragraph of benign text<br />and more text</p>"""
            result = '<p>a paragraph of benign text<br>and more text</p>'
            expect = textile.Textile().textile(test, sanitize=True,
                                               html_type='html')
            eq_(result, expect)
    
        def testImageSize(self):
            try:
                import ImageFile
            except ImportError:
                raise SkipTest()
    
            test = "!http://www.google.com/intl/en_ALL/images/srpr/logo1w.png!"
            result = '\t<p><img src="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" alt="" width="275" height="95" /></p>'
            expect = textile.Textile(get_sizes=True).textile(test)
            eq_(result, expect)
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile/textilefactory.py�������������������������������������������������������������0000644�0000765�0000024�00000004310�11560133635�020174� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from functions import Textile
    
    
    class TextileFactory(object):
        """
        Use TextileFactory to create a Textile object which can be re-used
        to process multiple strings with the same settings.
    
        >>> f = TextileFactory()
        >>> f.process("some text here")
        '\\t<p>some text here</p>'
    
        >>> f = TextileFactory(restricted=True)
        >>> f.process("more text here")
        '\\t<p>more text here</p>'
    
        Certain parameter values are not permitted because they are illogical:
    
        >>> f = TextileFactory(lite=True)
        Traceback (most recent call last):
        ...
        ValueError: lite can only be enabled in restricted mode
    
        >>> f = TextileFactory(head_offset=7)
        Traceback (most recent call last):
        ...
        ValueError: head_offset must be 0-6
    
        >>> f = TextileFactory(html_type='html5')
        Traceback (most recent call last):
        ...
        ValueError: html_type must be 'html' or 'xhtml'
    
    
        """
    
        def __init__(self, restricted=False, lite=False, sanitize=False,
                     noimage=None, auto_link=False, get_sizes=False,
                     head_offset=0, html_type='xhtml'):
    
            self.class_parms = {}
            self.method_parms = {}
    
            if lite and not restricted:
                raise ValueError("lite can only be enabled in restricted mode")
    
            if restricted:
                self.class_parms['restricted'] = True
                self.class_parms['lite'] = lite
                self.method_parms['rel'] = 'nofollow'
    
            if noimage is None:
                if restricted:
                    noimage = True
                else:
                    noimage = False
    
            self.class_parms['noimage'] = noimage
            self.method_parms['sanitize'] = sanitize
            self.class_parms['auto_link'] = auto_link
            self.class_parms['get_sizes'] = get_sizes
    
            if int(head_offset) not in range(0, 6):
                raise ValueError("head_offset must be 0-6")
            else:
                self.method_parms['head_offset'] = head_offset
    
            if html_type not in ['html', 'xhtml']:
                raise ValueError("html_type must be 'html' or 'xhtml'")
            else:
                self.method_parms['html_type'] = html_type
    
        def process(self, text):
            return Textile(**self.class_parms).textile(text, **self.method_parms)
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile/tools/������������������������������������������������������������������������0000755�0000765�0000024�00000000000�11560135413�015712� 5����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile/tools/__init__.py�������������������������������������������������������������0000644�0000765�0000024�00000000000�11560133635�020015� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile/tools/imagesize.py������������������������������������������������������������0000644�0000765�0000024�00000001744�11560133635�020253� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def getimagesize(url):
        """
        Attempts to determine an image's width and height, and returns a string
        suitable for use in an <img> tag, or an empty string in case of failure.
        Requires that PIL is installed.
    
        >>> getimagesize("http://www.google.com/intl/en_ALL/images/logo.gif")
        ... #doctest: +ELLIPSIS
        'width="..." height="..."'
    
        >>> getimagesize("http://bad.domain/")
        ''
    
        """
    
        try:
            import ImageFile
            import urllib2
        except ImportError:
            return ''
    
        try:
            p = ImageFile.Parser()
            f = urllib2.urlopen(url)
            while True:
                s = f.read(1024)
                if not s:
                    break
                p.feed(s)
                if p.image:
                    return 'width="%i" height="%i"' % p.image.size
        except (IOError, ValueError):
            return ''
    
    
    def setup_module(module):
        from nose.plugins.skip import SkipTest
        try:
            import ImageFile
        except ImportError:
            raise SkipTest()
    ����������������������������textile-2.1.5/textile/tools/sanitizer.py������������������������������������������������������������0000644�0000765�0000024�00000002043�11560133635�020277� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������def sanitize(string, html_type):
        """
        >>> sanitize("\\t<p>a paragraph</p>","html")
        u'\\t<p>a paragraph</p>'
    
        >>> sanitize("\\t<script>alert('evil script');</script>", "xhtml")
        u"\\t<script>alert('evil script');</script>"
    
        """
        try:
            import html5lib
            from html5lib import sanitizer, serializer, treewalkers, treebuilders
        except ImportError:
            raise Exception("html5lib not available")
    
        p = html5lib.HTMLParser(tokenizer=sanitizer.HTMLSanitizer)
        tree = p.parseFragment(string)
    
        walker = treewalkers.getTreeWalker("simpletree")
        stream = walker(tree)
    
        if html_type == 'xhtml':
            s = serializer.xhtmlserializer.XHTMLSerializer()
        else:
            s = serializer.htmlserializer.HTMLSerializer(omit_optional_tags=False,
                                                         quote_attr_values=True)
        return s.render(stream)
    
    
    def setup_module(module):
        from nose.plugins.skip import SkipTest
        try:
            import html5lib
        except ImportError:
            raise SkipTest()
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile.egg-info/���������������������������������������������������������������������0000755�0000765�0000024�00000000000�11560135413�016244� 5����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile.egg-info/dependency_links.txt�������������������������������������������������0000644�0000765�0000024�00000000001�11560135413�022312� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile.egg-info/not-zip-safe���������������������������������������������������������0000644�0000765�0000024�00000000001�11560135267�020501� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile.egg-info/PKG-INFO�������������������������������������������������������������0000644�0000765�0000024�00000001172�11560135413�017342� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Metadata-Version: 1.0
    Name: textile
    Version: 2.1.5
    Summary: Textile processing for python.
    Home-page: http://github.com/chrisdrackett/python-textile
    Author: Chris Drackett
    Author-email: chris@chrisdrackett.com
    License: UNKNOWN
    Description: UNKNOWN
    Keywords: textile,text
    Platform: UNKNOWN
    Classifier: Development Status :: 3 - Alpha
    Classifier: Environment :: Web Environment
    Classifier: Intended Audience :: Developers
    Classifier: License :: OSI Approved :: BSD License
    Classifier: Operating System :: OS Independent
    Classifier: Programming Language :: Python
    Classifier: Topic :: Software Development :: Libraries :: Python Modules
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile.egg-info/SOURCES.txt����������������������������������������������������������0000644�0000765�0000024�00000000531�11560135413�020127� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������setup.cfg
    setup.py
    textile/__init__.py
    textile/functions.py
    textile/textilefactory.py
    textile.egg-info/PKG-INFO
    textile.egg-info/SOURCES.txt
    textile.egg-info/dependency_links.txt
    textile.egg-info/not-zip-safe
    textile.egg-info/top_level.txt
    textile/tests/__init__.py
    textile/tools/__init__.py
    textile/tools/imagesize.py
    textile/tools/sanitizer.py�����������������������������������������������������������������������������������������������������������������������������������������������������������������������textile-2.1.5/textile.egg-info/top_level.txt��������������������������������������������������������0000644�0000765�0000024�00000000010�11560135413�020765� 0����������������������������������������������������������������������������������������������������ustar  �cwd�����������������������������staff���������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������textile
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������