function Markdown($text)
{
    #
    # Main function. The order in which other subs are called here is
    # essential. Link and image substitutions need to happen before
    # _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
    # and <img> tags get encoded.
    #
    # Clear the global hashes. If we don't clear these, you get conflicts
    # from other articles when generating a page which contains more than
    # one article (e.g. an index page that shows the N most recent
    # articles):
    global $md_urls, $md_titles, $md_html_blocks, $md_html_hashes;
    $md_urls = array();
    $md_titles = array();
    $md_html_blocks = array();
    $md_html_hashes = array();
    # Standardize line endings:
    #   DOS to Unix and Mac to Unix
    $text = str_replace(array("\r\n", "\r"), "\n", $text);
    # Make sure $text ends with a couple of newlines:
    $text .= "\n\n";
    # Convert all tabs to spaces.
    $text = _Detab($text);
    # Turn block-level HTML blocks into hash entries
    $text = _HashHTMLBlocks($text);
    # Strip any lines consisting only of spaces and tabs.
    # This makes subsequent regexen easier to write, because we can
    # match consecutive blank lines with /\n+/ instead of something
    # contorted like /[ \t]*\n+/ .
    $text = preg_replace('/^[ \\t]+$/m', '', $text);
    # Strip link definitions, store in hashes.
    $text = _StripLinkDefinitions($text);
    $text = _RunBlockGamut($text, FALSE);
    $text = _UnescapeSpecialChars($text);
    return $text . "\n";
}
function _DoCodeBlocks_callback($matches)
{
    $prevchar = $matches[1];
    $newlines = $matches[2];
    $codeblock = $matches[4];
    $result;
    # return value
    $prefix = "";
    if (!(preg_match('/\\s/', $prevchar) || $prevchar == "")) {
        $prefix = "{$prevchar}:";
    }
    $codeblock = _EncodeCode(_Outdent($codeblock));
    $codeblock = _Detab($codeblock);
    # trim leading newlines and trailing whitespace
    $codeblock = preg_replace(array('/\\A\\n+/', '/\\s+\\z/'), '', $codeblock);
    $result = $prefix . "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n";
    return $result;
}
function _DoCodeBlocks_callback($matches)
{
    $codeblock = $matches[1];
    $codeblock = _EncodeCode(_Outdent($codeblock));
    $codeblock = _Detab($codeblock);
    # trim leading newlines and trailing whitespace
    $codeblock = preg_replace(array('/\\A\\n+/', '/\\s+\\z/'), '', $codeblock);
    $result = "\n\n<pre><code>" . $codeblock . "\n</code></pre>\n\n";
    return $result;
}