#!/usr/bin/env python
import unittest
import sys

if __name__ == "__main__":
    # Hack because we can't use from . import w/e if we're __main__
    import os.path
    sys.path = ([os.path.dirname(os.path.dirname(os.path.realpath(__file__)))]
                + sys.path)

from redbeans.parser import Parser
from redbeans.formats import Format
from redbeans.html import HTMLFormat
from redbeans.latex import LaTeXFormat

from redbeans.tokens import *

if '-v' in sys.argv:
    import redbeans.creole
    redbeans.creole.debug = True

class TestCreole(unittest.TestCase):

    def error_func(self):
        self.error = True

    def assertMakes(self, mf, str, format, correct, expect_error=False):
        if '-v' in sys.argv:
            print >>sys.stderr,"...................... New Test.................."
        self.error = False
        parser = Parser(format, mf, error_func=self.error_func)
        ev = ''
        for s in parser.iparse(str):
            if '-v' in sys.argv: print >>sys.stderr, repr(s)
            ev += s
        self.assertEqual(correct, ev)
        self.assertEqual(expect_error, self.error)

    def testBasics(self):
        self.assertMakes(None,'foo',Format,'foo')
        self.assertMakes(None, "foo **bar** baz was a parrot.", Format,
                         "foo *bar* baz was a parrot.")
        self.assertMakes(None, "foo '[[GoogleFish|Google Fish]]' baz was a parrot.",HTMLFormat,u"""<p>foo \u2018<a href="./GoogleFish" class="internal">Google Fish</a>\u2019 baz was a parrot.</p>""")
        self.assertMakes(None, "foo '[[GoogleFish]]' baz was a parrot.",
                         Format,
                         u"foo \u2018GoogleFish@<GoogleFish>\u2019 baz was a parrot.")
        self.assertMakes(None,'{{wombat.png}}',Format,'[wombat.png]')
        self.assertMakes(None,'{{wombat.png|A wombat}}',Format,'[A wombat]')


        self.assertMakes(None,'[[Foo]] [[Bar]] [[Baz]]',HTMLFormat,'''<p><a href="./Foo" class="internal">Foo</a> <a href="./Bar" class="internal">Bar</a> <a href="./Baz" class="internal">Baz</a></p>''')

    def testBasicLists(self):
        self.assertMakes(None,"""Fwee!
 * Foo
 ** Bar
 * Baz""",Format,"""Fwee!

 * Foo
  * Bar
 * Baz""")

        self.assertMakes(None,'\n* Test',Format,' * Test')
        self.assertMakes(None,'\n* Test',HTMLFormat,'<ul>\n <li>Test</li>\n</ul>')
        self.assertMakes(None,'\n* Test\n# Rest',HTMLFormat,'''<ul>
 <li>Test</li>
</ul><ol>
 <li>Rest</li>
</ol>''')

        self.assertMakes(None,'''
 * [[StatCard]]
 * [[StatCard]]
 * [[StatCard]]

''',HTMLFormat,u'''<ul>
 <li><a href="./StatCard" class="internal">StatCard</a></li>
 <li><a href="./StatCard" class="internal">StatCard</a></li>
 <li><a href="./StatCard" class="internal">StatCard</a></li>
</ul>''')
        self.assertMakes(None, '**Bold**', HTMLFormat,
                         '<p><b>Bold</b></p>')
        self.assertMakes(None, '##Typewriter##', HTMLFormat,
                         '<p><tt>Typewriter</tt></p>')

    def testListIntegration(self):
        self.assertMakes(None,'''
* [[StatCard]]
== Not A StatCard ==
* [[StatCard]]

''',HTMLFormat,u'''<ul>
 <li><a href="./StatCard" class="internal">StatCard</a></li>
</ul>

<h2>Not A StatCard</h2>

<ul>
 <li><a href="./StatCard" class="internal">StatCard</a></li>
</ul>''')

        def mf(name, argstr=None,content=None):
            if name == 'cheese':
                yield Text(u'cheese\n')
            elif name == 'lis':
                yield Start(UNORDERED_ITEM, 1)
                yield Text(u'Foo')
                yield End(UNORDERED_ITEM, 1)
                yield Start(UNORDERED_ITEM, 1)
                yield Text(u'Bar')
                yield End(UNORDERED_ITEM, 1)

        self.assertMakes(mf,'''
* Fleas
* <<cheese/>>
* Trees

''',HTMLFormat,u'''<ul>
 <li>Fleas</li>
 <li>cheese\n</li>
 <li>Trees</li>
</ul>''')
        self.assertMakes(mf, '''|=Title|<<lis/>>|''', HTMLFormat,
                         '''<table>
<tr><th>Title</th><td><ul>
 <li>Foo</li>
 <li>Bar</li>
</ul></td></tr>
</table>''')

    def testBasicMacros(self):
        # Macros
        def mf(name, argstr, content=None):
            if name == 'fish':
                if content:
                    for t in content:
                        assert False, t
                yield Text(u"Carp")
        self.assertMakes(mf,'<<fish />>',Format,'Carp')
        self.assertMakes(mf,r'\fish{}',Format,'Carp')
        self.assertMakes(mf,r'\fish',Format,'Carp')
        self.assertMakes(mf,r'\fish cake\fish',Format,'Carp cakeCarp')
        self.assertMakes(mf,'\\fish\ncake\\fish',Format,'Carp cakeCarp')

        self.assertMakes(mf, '[[foo|<<fish />>]]', Format,
                         'Carp@<foo>')

        def mf(name, argstr=None, content=None):
            if name == 'fish':
                yield Start(HEADING, 2)
                yield Text(u"Test")
                yield End(HEADING, 2)
        self.assertMakes(mf,'Foo\n<<fish />>',HTMLFormat,'<p>Foo\n</p>\n\n<h2>Test</h2>')
        self.assertMakes(mf,'Foo\n  <<fish />>',HTMLFormat,'<p>Foo\n  </p>\n\n<h2>Test</h2>')

        def mf(name, argstr=None, content=None):
            if name == 'twice':
                lst = list(content)
                #print >>sys.stderr, 'twice:', lst
                for x in xrange(2):
                    for t in lst:
                        yield t
        self.assertMakes(mf,'''<<twice>>
* This<</twice>>''',Format,''' * This
 * This''')
        self.assertMakes(mf,'''<<twice>>* This<</twice>>''',Format,'''* This* This''')

        def mf(name, argstr=None, content=None):
            if name == 'par':
                yield Entity(ENV_BREAK)
            elif name == 'fish':
                yield Start(UNORDERED_ITEM, 1)
                yield Text(u"Carp")
                yield End(UNORDERED_ITEM, 1)
                yield Entity(ENV_BREAK)
                yield Start(UNORDERED_ITEM, 1)
                yield Text(u"Trout")
                yield End(UNORDERED_ITEM, 1)
        self.assertMakes(mf,'''Bob<<par/>>George''',HTMLFormat,'''<p>Bob</p>

<p>George</p>''')
        self.assertMakes(mf,'''Bob<<fish/>>George''',HTMLFormat,'''<p>Bob</p>

<ul>
 <li>Carp</li>
</ul>

<ul>
 <li>Trout</li>
</ul>

<p>George</p>''')
        self.assertMakes(mf,'''|= Title |= Fish |
| Ralph | Which<<par/>>Carp |''',HTMLFormat,'''<table>
<tr><th>Title</th><th>Fish</th></tr>
<tr><td>Ralph</td><td>Which<br /><br />\n\nCarp</td></tr>
</table>''')
        self.assertMakes(mf,'''**Bob<<par/>>George**''',HTMLFormat,'''<p><b>Bob<br /><br />

George</b></p>''')

        
        def mf(name, argstr=None, content=None):
            if name == 'bar':
                yield Text(u"Foo")
            elif name == 'fish':
                yield Entity(MACRO, ('bar', None))
        self.assertMakes(mf,'''<<bar/>>''',Format,'''Foo''')
        self.assertMakes(mf,'''<<fish/>>''',Format,'''Foo''')

        self.assertMakes(mf, '''<<bar\nargstr>><</bar>>''', Format,
                         '''Foo''')

    def testBrokenMacros(self):
        # Macros
        def mf(name, argstr, content=None):
            if name == 'fish':
                yield Text(u"Carp")
            else:
                yield Text(u'???' + name)
        self.assertMakes(mf,'<<fish />', Format, 'Carp')
        self.assertMakes(mf,'<<fish />\nCheese', Format, 'Carp Cheese')
        self.assertMakes(mf,'<<fish>Cheese<</fish>>', Format, u"???fish>Cheese<</fish!! Unclosed macro 'fish>Cheese<</fish'! !!", expect_error=True)

        self.assertMakes(mf, r'\fish{', Format, u"Carp!! Unclosed macro 'fish'! !!", expect_error=True)
        self.assertMakes(mf, r'\fish{\fish{}', Format, u"Carp!! Unclosed macro 'fish'! !!", expect_error=True)
        self.assertMakes(mf, '\\fish{\nCheese', Format, u"Carp!! Unclosed macro 'fish'! !!", expect_error=True)
        self.assertMakes(mf, r'\fish{}{', Format, u"Carp!! Unclosed macro 'fish'! !!", expect_error=True)

    def testContentMacros(self):
        def mf(name, argstr=None, content=None):
            if name == 'par':
                yield Entity(ENV_BREAK)
            elif name == 'bold':
                yield Start(BOLD)
                for t in content:
                    yield t
                yield End(BOLD)
            elif name == 'great':
                yield Start(BOLD)
                for t in content:
                    yield t
                yield End(BOLD)
            elif name == 'token':
                yield Text(u':')
            elif name == 'let':
                for t in content:
                    yield t
        self.assertMakes(mf,'''<<bold>>Bob George<</bold>>''',HTMLFormat,'''<p><b>Bob George</b></p>''')
        self.assertMakes(mf,r'''\bold{Bob George}''',HTMLFormat,'''<p><b>Bob George</b></p>''')
        self.assertMakes(mf,r'''\bold{Bob George''',HTMLFormat,'''<p><b>Bob George</b><span class="error">Unclosed macro 'bold'!</span></p>''', expect_error=True)

        self.assertMakes(mf, '''<<bold>>Nesting is <<bold>>great<</bold>>!<</bold>>''', HTMLFormat, '''<p><b>Nesting is <b>great</b>!</b></p>''')
        self.assertMakes(mf, '''<<bold>>Nesting is <<great>>great<</great>>!<</bold>>''', HTMLFormat, '''<p><b>Nesting is <b>great</b>!</b></p>''')

        self.assertMakes(mf, '''<<let owner=leaf>>
<<let>>
  == Name ==

  <<let>>
    * A
    * <<let>>[[B]]<</let>>
  <</let>>
<</let>>

<</let>>''', HTMLFormat, '''<h2>Name</h2>

<ul>
 <li>A</li>
 <li><a href="./B" class="internal">B</a>
  </li>
</ul>

''')
        self.assertMakes(mf, '''<<let owner=leaf>>

== Name ==
* C
* [[Badge]]
<<let>>
  <<let>>
    == [[Next]] ==
  <</let>>
  <<let>>
    * A
    * <<let>>[[B]]<</let>>
  <</let>>
<</let>>

<</let>>''', HTMLFormat, '''

<h2>Name</h2>

<ul>
 <li>C</li>
 <li><a href="./Badge" class="internal">Badge</a>

  <h2><a href="./Next" class="internal">Next</a></h2>
  
  <ul>
 <li>A</li>
 <li><a href="./B" class="internal">B</a>
  </li>
</ul></li>
</ul>

''')

        self.assertMakes(mf, '''<<let fish="<<token/>>">>
  <<token/>> is equivalent to :
<</let>>''', Format, ": is equivalent to :")
        self.assertMakes(mf, '''<<let ".pdf">>
  <<token/>> is equivalent to :
<</let>>''', Format, ": is equivalent to :")

        self.assertMakes(mf, '''<<let>>
  <<token />>

  To flip over.

  <<whatever/>>

  <<token />>

  To go on this Quest.
<</let>>
''', LaTeXFormat, ":\n\n  To flip over.\n\n\n\n:\n\n  To go on this Quest.")

    def testBoldLists(self):
        # Bold/list interaction
        self.assertMakes(None,'** foo **',Format,'* foo *')
        self.assertMakes(None,'//* Bar//',Format,'/* Bar/')

        self.assertMakes(None,'http://web.mit.edu/',Format,'http://web.mit.edu/')
        self.assertMakes(None,'http://web.mit.edu/ Next',LaTeXFormat,r'{\ttfamily \href{http://web.mit.edu/}{http://web.mit.edu/}} Next')

        self.assertMakes(None,'## foo ##',Format,' foo ')
        self.assertMakes(None,'''* bar
## foo ##''',Format,''' * bar
  # foo ''')
        self.assertMakes(None,'''* bar

## foo ##''',Format,''' * bar

 foo ''')

    def testHeadings(self):
        # Headings
        self.assertMakes(None,'= Head =',HTMLFormat,'<h1>Head</h1>')
        self.assertMakes(None,'== Head',Format,'== Head ==')
        self.assertMakes(None,'=== Head ===',Format,'=== Head ===')
        self.assertMakes(None,'= Head ===',Format,'= Head =')

        self.assertMakes(None,'Foo\n== Head',HTMLFormat,'<p>Foo</p>\n\n<h2>Head</h2>')
        self.assertMakes(None,'Foo == Head',HTMLFormat,'<p>Foo == Head</p>')
        
        self.assertMakes(None,'''Paragraph.

= Head ===

Wine is great.''',Format,'Paragraph.\n\n= Head =\n\nWine is great.')
        self.assertMakes(None,'''* Listless
** List listers.

== Head ==

Wine is great.''',Format,' * Listless\n  * List listers.\n\n== Head ==\n\nWine is great.')

        self.assertMakes(None,'''* Listless
** List listers.

== Head ==

Wine is great.''',HTMLFormat,'''<ul>
 <li>Listless</li>
  <ul>
   <li>List listers.</li>
  </ul>
</ul>

<h2>Head</h2>

<p>Wine is great.</p>''')

    def testTables(self):
        self.assertMakes(None,'|= Test |= Table |\n|Here|Contents|',Format,'''\t* Test *\t* Table *\n\tHere\tContents''')
        self.assertMakes(None,'|= Test |= Table |\n|Here|Contents|',HTMLFormat,'''<table>
<tr><th>Test</th><th>Table</th></tr>
<tr><td>Here</td><td>Contents</td></tr>
</table>''')

        self.assertMakes(None,'| Test | Table |\n|Here|Contents|\n|Three| LineS |',HTMLFormat,'''<table>
<tr><td>Test</td><td>Table</td></tr>
<tr><td>Here</td><td>Contents</td></tr>
<tr><td>Three</td><td>LineS</td></tr>
</table>''')

        def mf(name, argstr=None, content=None):
            if name == 'mesa':
                yield Start(TABLE_ROW)
                yield Start(TABLE_HEADING)
                yield Text(u' Foo ')
                yield End(TABLE_HEADING)
                yield Start(TABLE_HEADING)
                yield Text(u' Bar')
                yield End(TABLE_HEADING)
                yield End(TABLE_ROW)
                yield Start(TABLE_ROW)
                yield Start(TABLE_CELL)
                yield Text(u'Baz')
                yield End(TABLE_CELL)
                yield Start(TABLE_CELL)
                yield Text(u'Quux')
                yield End(TABLE_CELL)
                yield End(TABLE_ROW)
            elif name == 'table':
                yield Start(TABLE)
                for t in content:
                    yield t
                yield End(TABLE)
        self.assertMakes(mf,'''<<mesa/>>''',HTMLFormat,'''<table>
<tr><th> Foo </th><th> Bar</th></tr>
<tr><td>Baz</td><td>Quux</td></tr>
</table>''')
        self.assertMakes(mf,'''<<mesa/>>
|Rab|Ongo''',HTMLFormat,'''<table>
<tr><th> Foo </th><th> Bar</th></tr>
<tr><td>Baz</td><td>Quux</td></tr>
<tr><td>Rab</td><td>Ongo</td></tr>
</table>''')
        self.assertMakes(mf,'''|Rab|Ongo
<<mesa/>>''',HTMLFormat,'''<table>
<tr><td>Rab</td><td>Ongo</td></tr>
<tr><th> Foo </th><th> Bar</th></tr>
<tr><td>Baz</td><td>Quux</td></tr>
</table>''')

        self.assertMakes(mf, '''<<table>>
| A | B
| C | D
<</table>>''', HTMLFormat, '''<table>
<tr><td>A</td><td>B</td></tr>
<tr><td>C</td><td>D</td></tr>
</table>''')
        
        def mf(name, argstr=None,content=None):
            if name == 'cheese':
                yield Text(u'cheese\n')
            elif name == 'mesa':
                yield Start(TABLE_ROW)
                yield Start(TABLE_CELL)
                yield Text(u'Foo ')
                yield End(TABLE_CELL)
                yield Start(TABLE_CELL)
                yield Entity(MACRO, ['cheese', None])
                yield End(TABLE_CELL)
                yield End(TABLE_ROW)
                yield Start(TABLE_ROW)
                yield Start(TABLE_CELL)
                yield Text(u"Baz ")
                yield End(TABLE_CELL)
                yield Start(TABLE_CELL)
                yield Entity(MACRO, ['cheese', None])
                yield End(TABLE_CELL)
                yield End(TABLE_ROW)
        self.assertMakes(mf,'''<<mesa />>''',HTMLFormat,'''<table>
<tr><td>Foo </td><td>cheese\n</td></tr>
<tr><td>Baz </td><td>cheese\n</td></tr>
</table>''')

        self.assertMakes(None,'''This is to test that things like the foll

|= Title |= More Title|
| Body | Elephant |''',HTMLFormat,'''<p>This is to test that things like the foll</p>

<table>
<tr><th>Title</th><th>More Title</th></tr>
<tr><td>Body</td><td>Elephant</td></tr>
</table>''')

        def mf(name, argstr=None,content=None):
            if name == 'repeat':
                lst = list(content)
                for x in xrange(3):
                    for t in lst:
                        yield t
        self.assertMakes(mf,'''|=Title|=Row
<<repeat>>
|Foo|Bar<</repeat>>
|Last|Row''', HTMLFormat,'''<table>
<tr><th>Title</th><th>Row</th></tr>
<tr><td>Foo</td><td>Bar</td></tr>
<tr><td>Foo</td><td>Bar</td></tr>
<tr><td>Foo</td><td>Bar</td></tr>
<tr><td>Last</td><td>Row</td></tr>
</table>''')

        self.assertMakes(None, '''
|= Faction   |= Brainwashed
| [[Light]]  | [[ThomasMorgan]]

9 regular actors:
# [[Max]]
''', HTMLFormat, '''<table>
<tr><th>Faction</th><th>Brainwashed</th></tr>
<tr><td><a href="./Light" class="internal">Light</a></td><td><a href="./ThomasMorgan" class="internal">ThomasMorgan</a></td></tr>
</table>

<p>9 regular actors:</p>

<ol>
 <li><a href="./Max" class="internal">Max</a></li>
</ol>''')

    def testDynamicLists(self):
        def mf(name, argstr=None, content=None):
            if name == 'tree':
                for x in [1,2,2,3,2,3,4,1,2,1,2,3,3,1]:
                    yield Start(UNORDERED_ITEM, x)
                    yield Text(u'content')
                    yield End(UNORDERED_ITEM, x)
        self.assertMakes(mf,'''Tree:

<<tree/>>''',HTMLFormat,'''<p>Tree:</p>

<ul>
 <li>content</li>
  <ul>
   <li>content</li>
   <li>content</li>
    <ul>
     <li>content</li>
    </ul>
   <li>content</li>
    <ul>
     <li>content</li>
      <ul>
       <li>content</li>
      </ul>
    </ul>
  </ul>
 <li>content</li>
  <ul>
   <li>content</li>
  </ul>
 <li>content</li>
  <ul>
   <li>content</li>
    <ul>
     <li>content</li>
     <li>content</li>
    </ul>
  </ul>
 <li>content</li>
</ul>''')

    def testBlockquote(self):
        # Blockquote
        self.assertMakes(None,''': Line
:: More indented
: Less''',HTMLFormat,'''<blockquote>
 Line
  <blockquote>
   More indented
  </blockquote>
 Less
</blockquote>''')
        self.assertMakes(None,'''Para
> Line
>> More indented
>> Second
> Less''',HTMLFormat,'''<p>Para</p>

<blockquote>
 Line
  <blockquote>
   More indented
   Second
  </blockquote>
 Less
</blockquote>''')

    def testURLEncoding(self):
        self.assertMakes(None,'''[[http://sevenmonkey.mit.edu/Japan/Early Netsuke]]''',HTMLFormat,
                         '''<p><a href="http://sevenmonkey.mit.edu/Japan/Early%20Netsuke" class="external">http://sevenmonkey.mit.edu/Japan/Early Netsuke</a></p>''')
        self.assertMakes(None,'''[[http://heraldry.sca.org/sena.html#A1|SENA]]''',HTMLFormat,
                         '''<p><a href="http://heraldry.sca.org/sena.html#A1" class="external">SENA</a></p>''')

    def testEscapes(self):
        #Escape tests
        self.assertMakes(None,'''http://pianojuice.net/~xavid''',HTMLFormat,
                  '''<p><tt><a href="http://pianojuice.net/~xavid" class="external">http://pianojuice.net/~xavid</a></tt></p>''')
        self.assertMakes(None,'''[[http://pianojuice.net/~xavid|My home page]]''',HTMLFormat,
                         '''<p><a href="http://pianojuice.net/~xavid" class="external">My home page</a></p>''')
        self.assertMakes(None,'''~http://pianojuice.net/~xavid''',HTMLFormat,
                  '''<p>http://pianojuice.net/xavid</p>''')
        self.assertMakes(None,'''~http://pianojuice.net/~~xavid''',HTMLFormat,
                  '''<p>http://pianojuice.net/~xavid</p>''')

        self.assertMakes(None,'''**bold**''',HTMLFormat,
                  '''<p><b>bold</b></p>''')
        self.assertMakes(None,'''~**bold**''',HTMLFormat,
                  '''<p>**bold<b></b></p>''')
        self.assertMakes(None,'''~**bold~**''',HTMLFormat,
                  '''<p>**bold**</p>''')
        self.assertMakes(None,'''~***bold**''',HTMLFormat,
                  '''<p>*<b>bold</b></p>''')
        self.assertMakes(None, '''##~###''', HTMLFormat,
                  '''<p><tt>#</tt></p>''')

        self.assertMakes(None, '''~Xavid''', Format, '~Xavid')

    def testFullparse(self):
        def mf(name, argstr=None, content=None):
            if name == 'block':
                for t in content:
                    yield t
                yield Entity(ENV_BREAK, True)
        self.assertMakes(mf,'''
<<block>>
* Fleas
* Swiss
<</block>>
* Trees
''',HTMLFormat,'''<ul>
 <li>Fleas</li>
 <li>Swiss</li>
</ul>

<ul>
 <li>Trees</li>
</ul>''')

    def testLaTeX(self):
        self.assertMakes(None, '[[Foo|Bar]]', LaTeXFormat,
                         r'\href{Foo}{Bar}')
        self.assertMakes(None, '* Foo\n* Bar\n* Baz', LaTeXFormat,
                         '\\begin{itemize}\n\\item Foo\n\\item Bar\n\\item Baz\n\\end{itemize}\n')

        def mf(name, argstr=None, content=None):
            if name == 'propname':
                yield Text(u'CR')
        self.assertMakes(mf,'''Foo.

* **<<propname/>>**: 4''',
                         LaTeXFormat,
                         r'''Foo.

\begin{itemize}
\item {\bfseries CR}: 4
\end{itemize}
''')
        self.assertMakes(mf, "'", LaTeXFormat, u'\u2018')
        self.assertMakes(mf, "~'", LaTeXFormat, r'\textquotesingle{}')
        self.assertMakes(mf, '"', LaTeXFormat, u'\u201c')
        self.assertMakes(mf, '~"', LaTeXFormat, r'\textquotedbl{}')

#    def testDefinitionLists(self):
#        self.assertMakes(None,'\n; Test: Desc',Format,'\n * Test: Desc')
#        self.assertMakes(None,'\n; Test: Desc\n',HTMLFormat,'<dl>\n <dt>Test</dt><dd>Desc</dd>\n</dl>\n\n')
#        self.assertMakes(None,'\n; Test: Desc\n;Two: Desc', LaTeXFormat,
#                         r'''\begin{descripton}
#\item[Test] Desc
#\item[Two] Desc
#\end{description}
#''')

    def testTeXMarkup(self):
        def mf(name, argstr=None, content=[]):
            if name == 'textbf':
                yield Start(BOLD)
                for t in content:
                    yield t
                yield End(BOLD)
            elif name == 'emph':
                yield Start(ITALIC)
                for t in content:
                    yield t
                yield End(ITALIC)
            elif name == 'center':
                yield Start(CENTER)
                for t in content:
                    yield t
                yield End(CENTER)
            elif name == 'cenquote':
                yield Start(CENTER)
                closed = False
                for t in content:
                    if (t.op == ENTITY and t.style == MACRO
                        and t.arg[0] == 'break'):
                        yield End(CENTER)
                        yield Start(RIGHT)
                        closed = True
                    else:
                        yield t
                if closed:
                    yield End(RIGHT)
                else:
                    yield End(CENTER)
            elif name == "'":
                lc = list(content)
                assert len(lc) == 1 and lc[0].op == TEXT, lc
                char = lc[0].arg
                assert len(char) == 1
                if char == 'e':
                    yield Text(u'\u00E9')
                else:
                    yield Text(char)
            elif name == "Dude":
                yield Text(u'Bob')
            elif name == "start":
                yield Text(u'1615')
            elif name == "end":
                yield Text(u'1618')
            else:
                assert False, name
                
        self.assertMakes(mf, 'foo', Format, 'foo')
        self.assertMakes(mf, r"foo \textbf{fish} baz was a parrot.",HTMLFormat,"""<p>foo <b>fish</b> baz was a parrot.</p>""")
        self.assertMakes(mf, r"foo \textbf{\emph{fish}} baz was a parrot.",HTMLFormat,"""<p>foo <b><i>fish</i></b> baz was a parrot.</p>""")
        self.assertMakes(mf,'\\center{Row, row, row}',HTMLFormat, '<center>Row, row, row</center>')
        #self.assertMakes(mf,'\\begin{center}\n\nRow, row, row\n\n\\end{center}',HTMLFormat, '<center><p>\n\nRow, row, row\n\n</p>\n\n</center>')
        self.assertMakes(mf, '...', Format, u'\u2026')
        self.assertMakes(mf, "Dr. Alex ``Bulldozer'' Anderson, Esq.", Format,
                         u"Dr. Alex \u201CBulldozer\u201D Anderson, Esq.")

        self.assertMakes(mf, "\cenquote{``Dude.''}{Mike}", HTMLFormat,
                         u'<center>\u201cDude.\u201d</center><p class="right">Mike</p>')

        self.assertMakes(mf, 'Tammy & Rachel', LaTeXFormat, 'Tammy \\& Rachel')
        self.assertMakes(mf, '[[Wherever|Tammy & Rachel]]', LaTeXFormat,
                         '\\href{Wherever}{Tammy \\& Rachel}')

        self.assertMakes(mf, '---', Format, u'\u2014')
        self.assertMakes(mf, '--', Format, u'\u2013')
        self.assertMakes(mf, "Foo---bar.", Format, u"Foo\u2014bar.")
        self.assertMakes(mf, "Foo -- bar.", Format, u"Foo\u2014bar.")
        self.assertMakes(mf, "7--9", Format, u"7\u20139")
        self.assertMakes(mf, "7-9", Format, u"7\u20139")
        self.assertMakes(mf, "Foo--\n\nbar.", Format, u"Foo\u2014\n\nbar.")
        self.assertMakes(mf, '--strike--', Format, u'\u2014strike\u2014')
        self.assertMakes(mf, "The party is from 7--9 or 8--10.", Format,
                         u'The party is from 7\u20139 or 8\u201310.')
        self.assertMakes(mf, "5-story pagoda", Format,
                         u'5-story pagoda')
        self.assertMakes(mf, '\start--\end', Format, u'1615\u20131618')
        self.assertMakes(mf, '\Dude--\Dude', Format, u'Bob\u2013Bob')

        self.assertMakes(mf, "\cenquote{``Dude.''}{-- Mike}", HTMLFormat,
                         u'<center>\u201cDude.\u201d</center><p class="right">\u2014Mike</p>')
        self.assertMakes(mf, r'Pok\'{e}mon', Format, u'Pok\u00E9mon')
        self.assertMakes(mf, r'Pok\'emon', Format, u'Pok\u00E9mon')

        self.assertMakes(mf, r"\Dude's sandwich", Format,
                         u'Bob\u2019s sandwich')
        self.assertMakes(mf, r"I like \Dude.", Format,
                         u'I like Bob.')
        self.assertMakes(mf, r"\Dude{Likes \Actors.}\Dude{}\Dude{}", Format,
                         u'BobBobBob')
        self.assertMakes(mf, r"\Dude{\first}", Format,
                         u'Bob')

        self.assertMakes(mf, r"\textbf{{{otron}}}", HTMLFormat,
                         u'<p><b><img src="./otron" class="internal" alt="otron"></b></p>')
        # TODO(xavid)
        self.assertMakes(mf, r"\textbf{{img}}", HTMLFormat,
                         u'<p><b>{img</b>}</p>')
        self.assertMakes(mf, r"\Dude[[link]]", HTMLFormat,
                         u'<p>Bob<a href="./link" class="internal">link</a></p>')
        self.assertMakes(mf, r"\Dude\\Fish", HTMLFormat,
                         u'<p>Bob<br />Fish</p>')

        self.assertMakes(mf, r"\Dude~\Dude", Format, u'Bob\Dude')

        self.assertMakes(mf, r"<<textbf>>I like \Dude<</textbf>>", Format,
                         u'*I like Bob*')

        self.assertMakes(mf, "* \emph{**\Dude**: \Dude, \Dude}", Format,
                         u' * /*Bob*: Bob, Bob/')

        self.assertMakes(mf, r'''Foo

\Dude

Bar''', LaTeXFormat, u'''Foo

Bob

Bar''')

        # This syntax is standard to use with \LARGE, etc.
        self.assertMakes(mf, r'''{\textbf Foo}''', Format, '*Foo*')
        self.assertMakes(mf, r'''\textbf{{\emph Foo}}''', Format, '*/Foo/*')

        self.assertMakes(mf, r'''\Dude\Dude''', Format, 'BobBob')

        self.assertMakes(mf, r'''== Foo ==

\Dude

== Foo ==''', HTMLFormat, '<h2>Foo</h2>\n\n<p>Bob</p>\n\n<h2>Foo</h2>')

    def testQuotes(self):
        self.assertMakes(None, '"Why?"', Format, u'\u201CWhy?\u201D')
        self.assertMakes(None, "'Why?'", Format, u'\u2018Why?\u2019')
        self.assertMakes(None, 'He asked, "Why?"', Format,
                         u'He asked, \u201CWhy?\u201D')
        self.assertMakes(None, 'He asked "Why?"', Format,
                         u'He asked \u201CWhy?\u201D')
        self.assertMakes(None, '"Why?" he asked.', Format,
                         u'\u201CWhy?\u201D he asked.')
        self.assertMakes(None, '"He told me \'No,\'" she said.', Format,
                         u'\u201CHe told me \u2018No,\u2019\u201D she said.')
        self.assertMakes(None, '"He told me \'No,\' " she said.', Format,
                         u'\u201CHe told me \u2018No,\u2019 \u201D she said.')
        self.assertMakes(None, '"\'No,\' he told me," she said.', Format,
                         u'\u201C\u2018No,\u2019 he told me,\u201D she said.')
        self.assertMakes(None, '" \'No,\' he told me," she said.', Format,
                         u'\u201C \u2018No,\u2019 he told me,\u201D she said.')
        self.assertMakes(None, 'Hank the-"Big"-Man Whistleblower', Format,
                         u'Hank the-\u201CBig\u201D-Man Whistleblower')
        self.assertMakes(None, '("Why?")', Format, u'(\u201CWhy?\u201D)')

        self.assertMakes(None, '**"Why?"**', Format, u'*\u201CWhy?\u201D*')
        self.assertMakes(None, '"**Why?**"', Format, u'\u201C*Why?*\u201D')

        def mf(name, argstr=None, content=None):
            if name == 'break':
                return
            for t in content:
                yield t
        self.assertMakes(mf, r'\cenquote{"Why?"}', Format,
                         u'\u201CWhy?\u201D')
        self.assertMakes(mf, r'\cenquote{"Why?"}{"Why not?}"', Format,
                         u'\u201CWhy?\u201D\u201CWhy not?\u201D')

    def testCodeblock(self):
        self.assertMakes(None, """{{{
foo:
  bar
}}}""", HTMLFormat, """<pre>foo:
  bar</pre>""")

    def testNoindent(self):
        def mf(name, argstr=None, content=None):
            if name == 'noindent':
                yield Entity(NOINDENT)

        # TODO(xavid): The space before Foo is dumb, but not worth worrying
        #              about right now.
        self.assertMakes(mf, '\\noindent\nFoo\n', LaTeXFormat,
                         u'\\noindent{} Foo')

        self.assertMakes(mf, '\\noindent\nFoo\n', HTMLFormat,
                         u'<p class="noindent">\nFoo</p>')

    def testSpacing(self):
        self.assertMakes(None, 'Foo   Bar', Format, 'Foo Bar')
        self.assertMakes(None, 'Foo\n  Bar', Format, 'Foo Bar')

if __name__ == "__main__":
    unittest.main()
    
