import unittest, string
from pymarkdown import Markdown, sub

class PyMarkDownTestCase(unittest.TestCase):

    def setUp(self):
        pass

    def testH1(self):
        text = """
asdf
====
"""
        html = """<h1>asdf</h1>\n"""
        self.assertEquals(Markdown(text), html)

    def testH2(self):
        text = """
asdf
----
"""
        html = """<h2>asdf</h2>\n"""
        self.assertEquals(Markdown(text), html)

    def testH1Alt(self):
        text = """
# asdf
"""
        html = """<h1>asdf</h1>\n"""

        self.assertEquals(Markdown(text), html)

    def testH2Alt(self):
        text = """
## asdf
"""
        html = """<h2>asdf</h2>\n"""

        self.assertEquals(Markdown(text), html)

    def testH3Alt(self):
        text = """
### asdf
"""
        html = """<h3>asdf</h3>\n"""

        self.assertEquals(Markdown(text), html)

    def testH4Alt(self):
        text = """
#### asdf
"""
        html = """<h4>asdf</h4>\n"""

        self.assertEquals(Markdown(text), html)

    def testH5Alt(self):
        text = """
##### asdf
"""
        html = """<h5>asdf</h5>\n"""

        self.assertEquals(Markdown(text), html)

    def testH6Alt(self):
        text = """
###### asdf
"""
        html = """<h6>asdf</h6>\n"""

        self.assertEquals(Markdown(text), html)

    def testH7Alt(self):
        text = """
####### asdf
"""
        html = """<h6># asdf</h6>\n"""

        self.assertEquals(Markdown(text), html)

    def testH1AltClosing1(self):
        text = """
# asdf #
"""
        html = """<h1>asdf</h1>\n"""

        self.assertEquals(Markdown(text), html)

    def testH1AltClosing2(self):
        text = """
# asdf ####
"""
        html = """<h1>asdf</h1>\n"""

        self.assertEquals(Markdown(text), html)

    def testHTMLElements(self):
        text = """
This is a regular paragraph.

<table>
    <tr>
        <td>Foo</td>
    </tr>
</table>

This is another regular paragraph.
"""
        html = """<p>This is a regular paragraph.</p>

<table>
    <tr>
        <td>Foo</td>
    </tr>
</table>

<p>This is another regular paragraph.</p>
"""

        self.assertEquals(Markdown(text), html)

    def testHTMLEntities1(self):
        # & in URLs
        text = """<a href="http://images.google.com/images?num=30&q=larry+bird">asdf</a>"""
        html = """<p><a href="http://images.google.com/images?num=30&amp;q=larry+bird">asdf</a></p>
"""
        self.assertEquals(Markdown(text), html)

    def testHTMLEntities2(self):
        # Real entities (&copy;)
        text = """&copy;"""
        html = """<p>&copy;</p>
"""
        self.assertEquals(Markdown(text), html)

    def testHTMLEntities3(self):
        # Normal & outside any magic
        text = """AT&T"""
        html = """<p>AT&amp;T</p>
"""
        self.assertEquals(Markdown(text), html)

    def testHTMLLessThan(self):
        text = """4 < 5"""
        html = """<p>4 &lt; 5</p>
"""
        self.assertEquals(Markdown(text), html)

    def testParagraphBreak(self):
        text = """This is a paragraph.

This is another, long, long, long, long, long, long, long, long, long
paragraph.  It will have a break at the end of this line. ASDF ASDF  
The previous line ends with two spaces and should therefore have a br
element

And then another paragraph
"""
        html = """<p>This is a paragraph.</p>

<p>This is another, long, long, long, long, long, long, long, long, long
paragraph.  It will have a break at the end of this line. ASDF ASDF <br />
The previous line ends with two spaces and should therefore have a br
element</p>

<p>And then another paragraph</p>
"""
        self.assertEquals(Markdown(text), html)

    def testBlockQuote1(self):
        text = """> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
> 
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
> id sem consectetuer libero luctus adipiscing."""
        html = """<blockquote>
  <p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
  consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
  Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
  
  <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
  id sem consectetuer libero luctus adipiscing.</p>
</blockquote>
"""
        self.assertEquals(Markdown(text), html)

    def testBlockQuote2(self):
        text = """
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.
"""
        html = """<blockquote>
  <p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
  consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
  Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
  
  <p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
  id sem consectetuer libero luctus adipiscing.</p>
</blockquote>
"""
        self.assertEquals(Markdown(text), html)


    def testNestedBlockQuote1(self):
        text = """
> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.
"""
        html = """<blockquote>
  <p>This is the first level of quoting.</p>
  
  <blockquote>
    <p>This is nested blockquote.</p>
  </blockquote>
  
  <p>Back to the first level.</p>
</blockquote>
"""
        self.assertEquals(Markdown(text), html)

    def testNestedBlockQuote1(self):
        text = """
> ## This is a header.
> 
> 1.   This is the first list item.
> 2.   This is the second list item.
> 
> Here's some example code:
> 
>     return shell_exec("echo $input | $markdown_script");
"""
        html = """<blockquote>
  <h2>This is a header.</h2>
  
  <ol>
  <li>This is the first list item.</li>
  <li>This is the second list item.</li>
  </ol>
  
  <p>Here's some example code:</p>
  
  <pre><code>return shell_exec("echo $input | $markdown_script");
  </code></pre>
</blockquote>
"""
        self.assertEquals(Markdown(text), html)

    def testUnorderedList1(self):
        text = """
*   Red
*   Green
*   Blue
"""
        html = """<ul>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ul>
"""
        self.assertEquals(Markdown(text), html)

    def testUnorderedList2(self):
        text = """
-   Red
-   Green
-   Blue
"""
        html = """<ul>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ul>
"""
        self.assertEquals(Markdown(text), html)

    def testUnorderedList3(self):
        text = """
-   Red
-   Green
-   Blue
"""
        html = """<ul>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ul>
"""
        self.assertEquals(Markdown(text), html)

    def testOrderedList1(self):
        text = """
1.  Bird
2.  McHale
3.  Parish
"""
        html = """<ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol>
"""
        self.assertEquals(Markdown(text), html)

    def testOrderedList2(self):
        text = """
1.  Bird
1.  McHale
1.  Parish
"""
        html = """<ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol>
"""
        self.assertEquals(Markdown(text), html)

    def testOrderedList3(self):
        text = """
3.  Bird
1.  McHale
8.  Parish
"""
        html = """<ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol>
"""
        self.assertEquals(Markdown(text), html)

    def testHangingIndent1(self):
        text = """
*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
    viverra nec, fringilla in, laoreet vitae, risus.
*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
    Suspendisse id sem consectetuer libero luctus adipiscing.
"""
        html = """<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.</li>
<li>Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.</li>
</ul>
"""
        self.assertEquals(Markdown(text), html)

    def testHangingIndent2(self):
        text = """
*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
"""
        html = """<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.</li>
<li>Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.</li>
</ul>
"""
        self.assertEquals(Markdown(text), html)

    def testUnorderedListWrapInParagraph(self):
        text = """
*   Bird

*   Magic
"""
        html = """<ul>
<li><p>Bird</p></li>
<li><p>Magic</p></li>
</ul>
"""
        self.assertEquals(Markdown(text), html)


    def testUnorderedListWrapMultipleParagraphs(self):
        text = """
1.  This is a list item with two paragraphs. Lorem ipsum dolor
    sit amet, consectetuer adipiscing elit. Aliquam hendrerit
    mi posuere lectus.

    Vestibulum enim wisi, viverra nec, fringilla in, laoreet
    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
    sit amet velit.

2.  Suspendisse id sem consectetuer libero luctus adipiscing.
"""
        html = """<ol>
<li><p>This is a list item with two paragraphs. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
mi posuere lectus.</p>

<p>Vestibulum enim wisi, viverra nec, fringilla in, laoreet
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
sit amet velit.</p></li>
<li><p>Suspendisse id sem consectetuer libero luctus adipiscing.</p></li>
</ol>
"""
        self.assertEquals(Markdown(text), html)

    def testUnorderedListWrapMultipleParagraphsLazy(self):
        text = """
*   This is a list item with two paragraphs.

    This is the second paragraph in the list item. You're
only required to indent the first line. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.

*   Another item in the same list.
"""
        html = """<ul>
<li><p>This is a list item with two paragraphs.</p>

<p>This is the second paragraph in the list item. You're
only required to indent the first line. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.</p></li>
<li><p>Another item in the same list.</p></li>
</ul>
"""
        self.assertEquals(Markdown(text), html)

    def testBlockQuoteInList(self):
        text = """
*   A list item with a blockquote:

    > This is a blockquote
    > inside a list item.
"""
        html = """<ul>
<li><p>A list item with a blockquote:</p>

<blockquote>
  <p>This is a blockquote
  inside a list item.</p>
</blockquote></li>
</ul>
"""
        self.assertEquals(Markdown(text), html)

    def testCodeInList(self):
        text = """
*   A list item with a code block:

        <code goes here>
"""
        html = """<ul>
<li><p>A list item with a code block:</p>

<pre><code>&lt;code goes here&gt;
</code></pre></li>
</ul>
"""
        self.assertEquals(Markdown(text), html)
        

    def testAccidentalOrderedList(self):
        text = """1986. What a great season."""
        html = """<ol>
<li>What a great season.</li>
</ol>
"""
        self.assertEquals(Markdown(text), html)

    def testAccidentalOrderedListFixed(self):
        text = """1986\. What a great season."""
        html = """<p>1986. What a great season.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testCodeBlock(self):
        text = """This is a normal paragraph:

    This is a code block.
"""
        html = """<p>This is a normal paragraph:</p>

<pre><code>This is a code block.
</code></pre>
"""

        self.assertEquals(Markdown(text), html)

    def testCodeBlockIndentation(self):
        text = """Here is an example of AppleScript:

    tell application "Foo"
        beep
    end tell
"""
        html = """<p>Here is an example of AppleScript:</p>

<pre><code>tell application "Foo"
    beep
end tell
</code></pre>
"""
        self.assertEquals(Markdown(text), html)


    def testCodeBlockEntities(self):
        text = """    <div class="footer">
        &copy; 2004 Foo Corporation
    </div>"""
        html = """<pre><code>&lt;div class="footer"&gt;
    &amp;copy; 2004 Foo Corporation
&lt;/div&gt;
</code></pre>
"""
        self.assertEquals(Markdown(text), html)

    def testHorisontalRule1(self):
        text = """* * *"""
        html = """<hr />
"""

        self.assertEquals(Markdown(text), html)

    def testHorisontalRule2(self):
        text = """***"""
        html = """<hr />
"""

        self.assertEquals(Markdown(text), html)

    def testHorisontalRule3(self):
        text = """*****"""
        html = """<hr />
"""

        self.assertEquals(Markdown(text), html)

    def testHorisontalRule4(self):
        text = """- - -"""
        html = """<hr />
"""

        self.assertEquals(Markdown(text), html)

    def testHorisontalRule5(self):
        text = """---------------------------------------"""
        html = """<hr />
"""

        self.assertEquals(Markdown(text), html)

    def testHorisontalRule6(self):
        text = """_ _ _"""
        html = """<hr />
"""
        self.assertEquals(Markdown(text), html)

    def testInlineLinkWithTitle(self):
        text = """This is [an example](http://example.com/ "Title") inline link."""
        html = """<p>This is <a href="http://example.com/" title="Title">an example</a> inline link.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testInlineLink(self):
        text = """[This link](http://example.net/) has no title attribute."""
        html = """<p><a href="http://example.net/">This link</a> has no title attribute.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testInlineRelativeLink(self):
        text = """See my [About](/about/) page for details."""
        html = """<p>See my <a href="/about/">About</a> page for details.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testReferenceLink(self):
        text = """This is [an example][id] reference-style link.

[id]: http://example.com/  "Optional Title Here"
"""
        html = """<p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
"""
        
        self.assertEquals(Markdown(text), html)

    def testReferenceLinkWithSpace(self):
        text = """This is [an example] [id] reference-style link.

[id]: http://example.com/  "Optional Title Here"
"""
        html = """<p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
"""
        
        self.assertEquals(Markdown(text), html)

    def testReferenceLinkWithBrackets(self):
        text = """This is [an example][id] reference-style link.

[id]: <http://example.com/>  "Optional Title Here"
"""
        html = """<p>This is <a href="http://example.com/" title="Optional Title Here">an example</a> reference-style link.</p>
"""
        self.assertEquals(Markdown(text), html)


    def testReferenceLinkWithBrokenLine(self):
        text = """This is [an example][id] reference-style link.

[id]: http://example.com/longish/path/to/resource/here
    "Optional Title Here"
"""
        html = """<p>This is <a href="http://example.com/longish/path/to/resource/here" title="Optional Title Here">an example</a> reference-style link.</p>
"""
        self.assertEquals(Markdown(text), html)


    def testReferenceLinkCaseSensitivity(self):
        
        text = """[link text][a]
[link text][A]

[a]: http://example.com
"""
        html = """<p><a href="http://example.com">link text</a>
<a href="http://example.com">link text</a></p>
"""
        self.assertEquals(Markdown(text), html)

    def testReferenceLinkImplicitName(self):
        
        text = """[Google][]

[Google]: http://google.com/
"""
        html = """<p><a href="http://google.com/">Google</a></p>
"""
        self.assertEquals(Markdown(text), html)

    def testReferenceLinkImplicitNameWithSpace(self):
        
        text = """[Daring Fireball][]

[Daring Fireball]: http://daringfireball.net/
"""
        html = """<p><a href="http://daringfireball.net/">Daring Fireball</a></p>
"""
        self.assertEquals(Markdown(text), html)

    def testReferenceLinkInAction(self):
        
        text = """I get 10 times more traffic from [Google] [1] than from
[Yahoo] [2] or [MSN] [3].

  [1]: http://google.com/        "Google"
  [2]: http://search.yahoo.com/  "Yahoo Search"
  [3]: http://search.msn.com/    "MSN Search"
"""
        html = """<p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testReferenceLinkImplicitNamesInAction(self):
        
        text = """I get 10 times more traffic from [Google][] than from
[Yahoo][] or [MSN][].

  [google]: http://google.com/        "Google"
  [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
  [msn]:    http://search.msn.com/    "MSN Search"
"""
        html = """<p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testLinkInAction(self):
        
        text = """I get 10 times more traffic from [Google](http://google.com/ "Google")
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
[MSN](http://search.msn.com/ "MSN Search").
"""
        html = """<p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a>
than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or
<a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testEmphasis1(self):
        
        text = """*single asterisks*"""
        html = """<p><em>single asterisks</em></p>
"""
        self.assertEquals(Markdown(text), html)

    def testEmphasis2(self):
        
        text = """_single underscores_"""
        html = """<p><em>single underscores</em></p>
"""
        self.assertEquals(Markdown(text), html)

    def testStrong1(self):
        
        text = """**double asterisks**"""
        html = """<p><strong>double asterisks</strong></p>
"""
        self.assertEquals(Markdown(text), html)

    def testEmphasis2(self):
        
        text = """__double underscores__"""
        html = """<p><strong>double underscores</strong></p>
"""
        self.assertEquals(Markdown(text), html)

    def testEmphasisMiddleOfWord(self):
        
        text = """un*fucking*believable"""
        html = """<p>un<em>fucking</em>believable</p>
"""
        self.assertEquals(Markdown(text), html)

    def testEmphasisEscaped(self):
        
        text = """\*this text is surrounded by literal asterisks\*"""
        html = """<p>*this text is surrounded by literal asterisks*</p>
"""
        self.assertEquals(Markdown(text), html)

    def testEmphasisSpacesAround(self):
        
        text = """foo * this text is surrounded by literal asterisks with spaces * """
        html = """<p>foo * this text is surrounded by literal asterisks with spaces *</p>
"""
        self.assertEquals(Markdown(text), html)

    def testInlineCode(self):
        
        text = """Use the `printf()` function."""
        html = """<p>Use the <code>printf()</code> function.</p>
"""

        self.assertEquals(Markdown(text), html)

    def testInlineCodeLiteralBacktick(self):
        
        text = """``There is a literal backtick (`) here.``"""
        html = """<p><code>There is a literal backtick (`) here.</code></p>
"""
        self.assertEquals(Markdown(text), html)

    def testInlineCodeLiteralBacktickSpaces(self):
        text = """A single backtick in a code span: `` ` ``"""
        html = """<p>A single backtick in a code span: <code>`</code></p>
"""
        self.assertEquals(Markdown(text), html)

    def testInlineCodeBacktickDelimitedInside(self):
        text = """A backtick-delimited string in a code span: `` `foo` ``"""
        html = """<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
"""
        self.assertEquals(Markdown(text), html)

    def testInlineCodeHTMLEncode(self):
        text = """Please don't use any `<blink>` tags."""
        html = """<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testInlineCodeHTMLEntity(self):
        text = """`&#8212;` is the decimal-encoded equivalent of `&mdash;`."""
        html = """<p><code>&amp;#8212;</code> is the decimal-encoded equivalent of <code>&amp;mdash;</code>.</p>
"""
        self.assertEquals(Markdown(text), html)

    def testImagesSimple(self):
        text = """![Alt text](/path/to/img.jpg)"""
        html = """<p><img src="/path/to/img.jpg" alt="Alt text" title="" /></p>
"""
        self.assertEquals(Markdown(text), html)

    def testImagesWithTitle(self):
        text = """![Alt text](/path/to/img.jpg "Optional title")
"""
        html = """<p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title" /></p>
"""
        self.assertEquals(Markdown(text), html)

    def testImagesReference(self):
        text = """![Alt text][id]

[id]: http://url/to/image  "Optional title attribute"
"""

        html = """<p><img src="http://url/to/image" alt="Alt text" title="Optional title attribute" /></p>
"""
        self.assertEquals(Markdown(text), html)


    def testAutoLink1(self):
        text = """<http://example.com>"""
        html = """<p><a href="http://example.com">http://example.com</a></p>
"""
        self.assertEquals(Markdown(text), html)

    def testAutoLink2(self):
        text = """<http://example.com/foo>"""
        html = """<p><a href="http://example.com/foo">http://example.com/foo</a></p>
"""
        self.assertEquals(Markdown(text), html)

    def testAutoEmailLink(self):
        def handler1(m):
            return chr(string.atoi("%s" % m.groups(1), 16))

        def handler2(m):
            return chr(string.atoi("%s" % m.groups(1)))

        text = """<address@example.com>"""
        pmhtml = Markdown(text)
        pmhtml = sub(r"&#x([0-9A-F][0-9A-F]);", handler1, pmhtml)
        pmhtml = sub(r"&#([0-9]+);", handler2, pmhtml)

        html = """<p><a href="mailto:address@example.com">address@example.com</a></p>
"""
        
        self.assertEquals(pmhtml, html)

    def testStrongAndEm(self):
        text = "***this*** and ___this___"
        html = """<p><strong><em>this</em></strong> and <strong><em>this</em></strong></p>\n"""
        self.assertEquals(Markdown(text), html)

    def testInlineWithBackticksWithNewLine(self):
        text = "`foo\nbar`"
        html = """<p><code>foo\nbar</code></p>\n"""
        self.assertEquals(Markdown(text), html)


if __name__ == '__main__':
    # When this module is executed from the command-line, run all its tests
    unittest.main()

