diff options
Diffstat (limited to 'docs')
27 files changed, 2264 insertions, 0 deletions
diff --git a/docs/AUTHORS b/docs/AUTHORS new file mode 100644 index 0000000..2843b56 --- /dev/null +++ b/docs/AUTHORS @@ -0,0 +1,44 @@ +Primary Authors +=============== + +Yuri Takteyev <http://freewisdom.org/>, who has written much of the current code +while procrastingating his Ph.D. + +Waylan Limberg <http://achinghead.com/>, who has written most of the available +extensions and later was asked to join Yuri, fixing nummrious bugs, adding +documentation and making general improvements to the existing codebase, +included a complete refactor of the core. + +Artem Yunusov, who as part of a 2008 GSoC project, has refactored inline +patterns, replaced the NanoDOM with ElementTree support and made various other +improvements. + +Manfed Stienstra <http://www.dwerg.net/>, who wrote the original version of +the script and is responsible for various parts of the existing codebase. + +David Wolever, who refactored the extension API and made other improvements +as he helped to integrate Markdown into Dr.Project. + +Other Contributors +================== + +The incomplete list of individuals below have provided patches or otherwise +contributed to the project in various ways. We would like to thank everyone +who has contributed to the progect in any way. + +Eric Abrahamsen +Jeff Balogh +Sergej Chodarev +Chris Clark +Tiago Cogumbreiro +Kjell Magne Fauske +G. Clark Haynes +Daniel Krech +Steward Midwinter +Jack Miller +Neale Pickett +Paul Stansifer +John Szakmeister +Malcolm Tredinnick +Ben Wilson +and many others who helped by reporting bugs diff --git a/docs/CHANGE_LOG b/docs/CHANGE_LOG new file mode 100644 index 0000000..e005ff8 --- /dev/null +++ b/docs/CHANGE_LOG @@ -0,0 +1,180 @@ +PYTHON MARKDOWN CHANGELOG +========================= + +Sept 28, 2009: Released version 2.0.2-Final. + +May 20, 2009: Released version 2.0.1-Final. + +Mar 30, 2009: Released version 2.0-Final. + +Mar 8, 2009: Release Candidate 2.0-rc-1. + +Feb 2009: Added support for multi-level lists to new Blockprocessors. + +Jan 2009: Added HTML 4 output as an option (thanks Eric Abrahamsen) + +Nov 2008: Added Definistion List ext. Replaced old core with BlockProcessors. +Broken up into multiple files. + +Oct 2008: Changed logging behavior to work better with other systems. +Refactored tree tarversing. Added treap implementation, then replaced with +OrderedDEict. Renamed various processors to better reflect what they actually +do. Refactored footnote ext to match php Extra's output. + +Sept 2008: Moved prettifyTree to a Postprocessor, replaced wikilink ext +with wikilinks (note the s) ext (uses bracketed links instead of CamelCase) +and various bug fixes. + +August 18 2008: Reorganized directory structure. Added a 'docs' dir +and moved all extensions into a 'markdown-extensions' package. +Added additional documentation and a few bug fixes. (v2.0-beta) + +August 4 2008: Updated included extensions to ElementTree. Added a +seperate commanline script. (v2.0-alpha) + +July 2008: Switched from home-grown NanoDOM to ElementTree and +various related bugs (thanks Artem Yunusov). + +June 2008: Fixed issues with nested inline patterns and cleaned +up testing framework (thanks Artem Yunusov). + +May 2008: Added a number of additional extensions to the +distribution and other minor changes. Moved repo to git from svn. + +Mar 2008: Refactored extension api to accept either an +extension name (as a string) or an instance of an extension +(Thanks David Wolever). Fixed various bugs and added doc strings. + +Feb 2008: Various bugfixes mostly regarding extensions. + +Feb 18, 2008: Version 1.7. + +Feb 13, 2008: A little code cleanup and better documentation +and inheritance for pre/post proccessors. + +Feb 9, 2008: Doublequotes no longer html escaped and rawhtml +honors <?foo>, <@foo>, and <%foo> for those who run markdown on +template syntax. + +Dec 12, 2007: Updated docs. Removed encoding arg from Markdown +and markdown as per list discussion. Clean up in prep for 1.7. + +Nov 29, 2007: Added support for images inside links. Also fixed +a few bugs in the footnote extension. + +Nov 19, 2007: `message` now uses python's logging module. Also removed +limit imposed by recursion in _process_section(). You can now parse as +long of a document as your memory can handle. + +Nov 5, 2007: Moved safe_mode code to a textPostprocessor and added +escaping option. + +Nov 3, 2007: Fixed convert method to accept empty strings. + +Oct 30, 2007: Fixed BOM removal (thanks Malcolm Tredinnick). Fixed +infinite loop in bracket regex for inline links. + +Oct 11, 2007: LineBreaks is now an inlinePattern. Fixed HR in +blockquotes. Refactored _processSection method (see tracker #1793419). + +Oct 9, 2007: Added textPreprocessor (from 1.6b). + +Oct 8, 2008: Fixed Lazy Blockquote. Fixed code block on first line. +Fixed empty inline image link. + +Oct 7, 2007: Limit recursion on inlinePatterns. Added a 'safe' tag +to htmlStash. + +March 18, 2007: Fixed or merged a bunch of minor bugs, including +multi-line comments and markup inside links. (Tracker #s: 1683066, +1671153, 1661751, 1627935, 1544371, 1458139.) -> v. 1.6b + +Oct 10, 2006: Fixed a bug that caused some text to be lost after +comments. Added "safe mode" (user's html tags are removed). + +Sept 6, 2006: Added exception for PHP tags when handling html blocks. + +August 7, 2006: Incorporated Sergej Chodarev's patch to fix a problem +with ampersand normalization and html blocks. + +July 10, 2006: Switched to using optparse. Added proper support for +unicode. + +July 9, 2006: Fixed the <!--@address.com> problem (Tracker #1501354). + +May 18, 2006: Stopped catching unquoted titles in reference links. +Stopped creating blank headers. + +May 15, 2006: A bug with lists, recursion on block-level elements, +run-in headers, spaces before headers, unicode input (thanks to Aaron +Swartz). Sourceforge tracker #s: 1489313, 1489312, 1489311, 1488370, +1485178, 1485176. (v. 1.5) + +Mar. 24, 2006: Switched to a not-so-recursive algorithm with +_handleInline. (Version 1.4) + +Mar. 15, 2006: Replaced some instance variables with class variables +(a patch from Stelios Xanthakis). Chris Clark's new regexps that do +not trigger midword underlining. + +Feb. 28, 2006: Clean-up and command-line handling by Stewart +Midwinter. (Version 1.3) + +Feb. 24, 2006: Fixed a bug with the last line of the list appearing +again as a separate paragraph. Incorporated Chris Clark's "mailto" +patch. Added support for <br /> at the end of lines ending in two or +more spaces. Fixed a crashing bug when using ImageReferencePattern. +Added several utility methods to Nanodom. (Version 1.2) + +Jan. 31, 2006: Added "hr" and "hr/" to BLOCK_LEVEL_ELEMENTS and +changed <hr/> to <hr />. (Thanks to Sergej Chodarev.) + +Nov. 26, 2005: Fixed a bug with certain tabbed lines inside lists +getting wrapped in <pre><code>. (v. 1.1) + +Nov. 19, 2005: Made "<!...", "<?...", etc. behave like block-level +HTML tags. + +Nov. 14, 2005: Added entity code and email autolink fix by Tiago +Cogumbreiro. Fixed some small issues with backticks to get 100% +compliance with John's test suite. (v. 1.0) + +Nov. 7, 2005: Added an unlink method for documents to aid with memory +collection (per Doug Sauder's suggestion). + +Oct. 29, 2005: Restricted a set of html tags that get treated as +block-level elements. + +Sept. 18, 2005: Refactored the whole script to make it easier to +customize it and made footnote functionality into an extension. +(v. 0.9) + +Sept. 5, 2005: Fixed a bug with multi-paragraph footnotes. Added +attribute support. + +Sept. 1, 2005: Changed the way headers are handled to allow inline +syntax in headers (e.g. links) and got the lists to use p-tags +correctly (v. 0.8) + +Aug. 29, 2005: Added flexible tabs, fixed a few small issues, added +basic support for footnotes. Got rid of xml.dom.minidom and added +pretty-printing. (v. 0.7) + +Aug. 13, 2005: Fixed a number of small bugs in order to conform to the +test suite. (v. 0.6) + +Aug. 11, 2005: Added support for inline html and entities, inline +images, autolinks, underscore emphasis. Cleaned up and refactored the +code, added some more comments. + +Feb. 19, 2005: Rewrote the handling of high-level elements to allow +multi-line list items and all sorts of nesting. + +Feb. 3, 2005: Reference-style links, single-line lists, backticks, +escape, emphasis in the beginning of the paragraph. + +Nov. 2004: Added links, blockquotes, html blocks to Manfred +Stienstra's code + +Apr. 2004: Manfred's version at http://www.dwerg.net/projects/markdown/ + diff --git a/docs/INSTALL b/docs/INSTALL new file mode 100644 index 0000000..d8feade --- /dev/null +++ b/docs/INSTALL @@ -0,0 +1,73 @@ +Installing Python-Markdown +========================== + +Checking Dependencies +--------------------- + +Python-Markdown requires the ElementTree module to be installed. In Python2.5+ +ElementTree is included as part of the standard library. For earlier versions +of Python, open a Python shell and type the following: + + >>> import cElementTree + >>> import ElementTree + +If at least one of those does not generate any errors, then you have a working +copy of ElementTree installed on your system. As cElementTree is faster, you +may want to install that if you don't already have it and it's available for +your system. + +See <http://effbot.org/zone/element-index.htm> for more information or to +download the latest version of ElementTree. + +The East Way +------------ + +The simplest way to install Python-Markdown is by using SetupTools. As and +Admin/Root user on your system do: + + easy_install ElementTree + easy_install Markdown + +That's it, your done. + +Installing on Windows +--------------------- + +Download the Windows installer (.exe) from PyPI: +<http://pypi.python.org/pypi/Markdown> + +Double-click the file and follow the instructions. + +If you prefer to manually install Python-Markdown in Windows, download the +Zip file, unzip it, and on the command line in the directory you unzipped to: + + python setup.py install + +If you plan to use the provided command line script, you need to make sure your +script directory is on your system path. On a typical Python install of Windows +the Scripts directory is `C:\Python25\Scripts\`. Adjust according to your +system and add that to your system path. + +Installing on *nix Systems +-------------------------- + +From the command line do the following: + + wget http://pypi.python.org/packages/source/M/Markdown/Markdown-2.0.tar.gz + tar xvzf Markdown-2.0.tar.gz + cd markdown-2.0/ + sudo python setup.py install + +Using the Git Repository +------------------------ + +If your the type that like to live on the edge, you may want to keep up with +the latest additions and bug fixes in the repository between releases. +Python-Markdown is maintained in a Git repository on Gitorious.org. To +get a copy of Python-Markdown from the repository do the following from the +command line: + + git clone git://gitorious.org/python-markdown/mainline.git python-markdown + cd python-markdown + python setup.py install + diff --git a/docs/LICENSE b/docs/LICENSE new file mode 100644 index 0000000..4cd8b14 --- /dev/null +++ b/docs/LICENSE @@ -0,0 +1,30 @@ +Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of the <organization> nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/docs/README b/docs/README new file mode 100644 index 0000000..d19a1ea --- /dev/null +++ b/docs/README @@ -0,0 +1,30 @@ +[Python-Markdown][] +=================== + +This is a Python implementation of John Gruber's [Markdown][]. +It is almost completely compliant with the reference implementation, +though there are a few known issues. See [Features][] for information +on what exactly is supported and what is not. Additional features are +supported by the [Available Extensions][]. + +[Python-Markdown]: http://freewisdom.org/projects/python-markdown +[Markdown]: http://daringfireball.net/projects/markdown/ +[Features]: http://www.freewisdom.org/projects/python-markdown/Features +[Available Extensions]: http://www.freewisdom.org/projects/python-markdown/Available_Extensions + + +Documentation +------------- + +Installation and usage documentation is available in the `docs/` directory +of the distribution and on the project website at +<http://freewisdom.org/projects/python-markdown>. + +Support +------- + +You may ask for help and discuss various other issues on the [mailing list][] and report bugs on the [bug tracker][]. + +[mailing list]: http://lists.sourceforge.net/lists/listinfo/python-markdown-discuss +[bug tracker]: http://www.freewisdom.org/projects/python-markdown/Tickets + diff --git a/docs/README.html b/docs/README.html new file mode 100644 index 0000000..49e3b07 --- /dev/null +++ b/docs/README.html @@ -0,0 +1,12 @@ +<h1><a href="http://freewisdom.org/projects/python-markdown">Python-Markdown</a></h1> +<p>This is a Python implementation of John Gruber's <a href="http://daringfireball.net/projects/markdown/">Markdown</a>. +It is almost completely compliant with the reference implementation, +though there are a few known issues. See <a href="http://www.freewisdom.org/projects/python-markdown/Features">Features</a> for information +on what exactly is supported and what is not. Additional features are +supported by the <a href="http://www.freewisdom.org/projects/python-markdown/Available_Extensions">Available Extensions</a>.</p> +<h2>Documentation</h2> +<p>Installation and usage documentation is available in the <code>docs/</code> directory +of the distribution and on the project website at +<a href="http://freewisdom.org/projects/python-markdown">http://freewisdom.org/projects/python-markdown</a>.</p> +<h2>Support</h2> +<p>You may ask for help and discuss various other issues on the <a href="http://lists.sourceforge.net/lists/listinfo/python-markdown-discuss">mailing list</a> and report bugs on the <a href="http://www.freewisdom.org/projects/python-markdown/Tickets">bug tracker</a>.</p>
\ No newline at end of file diff --git a/docs/command_line.txt b/docs/command_line.txt new file mode 100644 index 0000000..d0134ea --- /dev/null +++ b/docs/command_line.txt @@ -0,0 +1,98 @@ +Using Python-Markdown on the Command Line +========================================= + +While Python-Markdown is primarily a python library, a command line script is +included as well. While there are many other command line implementations +of Markdown, you may not have them installed, or you may prefer to use +Python-Markdown's various extensions. + +Setup +----- + +Generally, you may simply call the ``markdown`` file from the command +line. However, if you have fully installed Markdown (``setup.py install`` or +``easy_install``), then the ``markdown`` script will have been copied to +you Python "Scripts" directory. Different systems require different methods to +ensure that any files in the Python "Scripts" directory are on your system +path. + +* **Windows**: + + Assuming a default install on Windows, your "Scripts" directory is most + likely something like ``C:\\Python25\Scripts``. Verify the location of + your "Scripts" directory and add it to you system path. + + Calling ``markdown`` from th ecommand line will call the wrapper batch file + ``markdown.bat`` in the "Scripts" directory created during install. + +* **Linux**: + + As each Linux distribution is different and we can't possibly document all + of them here, we'll provide a few helpful pointers: + + * Some systems will automatically install the script on your path. Try it + and see if it works. Just run ``markdown`` from the command line. + + * Other systems may maintain a separate "Scripts" directory which you + need to add to your path. Find it (check with your distribution) and + either add it to your path or make a symbolic link to it from your path. + + * If you are sure ``markdown`` is on your path, but it still isn't being + found, check the permissions of the file and make sure it is executable. + + As an alternative, you could just ``cd`` into the directory which contains + the source distribution, and run it from there. However, remember that your + markdown text files will not likely be in that directory, so it is much more + convenient to have ``markdown`` on your path. + +The Basics +---------- + +To use ``markdown`` from the command line, run it as + + $ markdown input_file.txt + +or + + $ markdown input_file.txt > output_file.html + +More Options +------------ + +If you are using Python 2.3 or higher, you can also use advanced +command line options to specify encoding or to run extensions. + + $ markdown --help + Usage: markdown INPUTFILE [options] + + Options: + -h, --help show this help message and exit + -f OUTPUT_FILE, --file=OUTPUT_FILE + write output to OUTPUT_FILE + -e ENCODING, --encoding=ENCODING + encoding for input and output files + -q, --quiet suppress all messages + -v, --verbose print info messages + -s SAFE_MODE, --safe=SAFE_MODE + safe mode ('replace', 'remove' or 'escape' user's + HTML tag) + -o OUTPUT_FORMAT, --output_format=OUTPUT_FORMAT + Format of output. One of 'xhtml1' (default) or + 'html4'. + --noisy print debug messages + -x EXTENSION, --extension=EXTENSION + load extension EXTENSION + +Using Extensions +---------------- + +For an extension to be ran this way it must be provided in a module +which should be in your python path (see [[writing_extensions]] for details). +It can then be invoked by the name of that module: + + $ markdown -x footnotes text_with_footnotes.txt > output.html + +If the extension supports config options, you can pass them in as well: + + $ markdown -x "footnotes(PLACE_MARKER=~~~~~~~~)" input.txt + diff --git a/docs/extensions/Abbreviations.txt b/docs/extensions/Abbreviations.txt new file mode 100644 index 0000000..fa54d3c --- /dev/null +++ b/docs/extensions/Abbreviations.txt @@ -0,0 +1,53 @@ +Abbreviations +------------- + +Summary +------- + +The Markdown Abbreviation Extension adds the ability to define abbreviations. +Specifically, any defined abbreviation is wrapped in an `<abbr>` tag. + +The Abbreviation extension is included in the standard Markdown library. + +Syntax +------ + +Abbreviations are defined using the syntax established in +[PHP Markdown Extra][php]. + +[php]: http://www.michelf.com/projects/php-markdown/extra/#abbr + +Thus, the following text (taken from the above referenced PHP documentation): + + The HTML specification + is maintained by the W3C. + + *[HTML]: Hyper Text Markup Language + *[W3C]: World Wide Web Consortium + +will be rendered like so: + + <p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification + is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p> + +Usage +----- + +From the Python interpreter: + + >>> import markdown + >>> text = """ + ... Some text with an ABBR. + ... + ... *[ABBR]: Abbreviation + ... """ + >>> html = markdown.markdown(text, ['abbr']) + +To use with other extensions, just add them to the list, like this: + + >>> html = markdown.markdown(text, ['abbr', 'footnotes']) + +Abbreviations can also be called from the command line using Markdown's `-x` +parameter, like so: + + markdown.py -x abbr source.txt > output.html diff --git a/docs/extensions/CodeHilite.txt b/docs/extensions/CodeHilite.txt new file mode 100644 index 0000000..482ad60 --- /dev/null +++ b/docs/extensions/CodeHilite.txt @@ -0,0 +1,113 @@ +CodeHilite +========== + +Summary +------- + +The CodeHilite Extension adds code/syntax highlighting to standard +Python-Markdown code blocks using [Pygments][]. + +[Python-Markdown]: http://www.freewisdom.org/projects/python-markdown/ +[Pygments]: http://pygments.org/ + +This extension is included in the Markdown library. + +Setup +----- + +You will also need to [download][dl] and install the Pygments package on your +`PYTHONPATH`. You will need to determine the appropriate CSS classes and create +appropriate rules for them, which are either defined in or linked from the +header of your HTML templates. See the excellent [documentation][] for more +details. If no language is defined, Pygments will attempt to guess the +language. When that fails, the code block will display as un-highlighted code. + +[dl]: http://pygments.org/download/ +[documentation]: http://pygments.org/docs + +**Note:** The css and/or javascript is not included as part of this extension +but shall always be provided by the end user. + +Syntax +------ + +The CodeHilite Extension follows the same [syntax][] as regular Markdown code +blocks, with one exception. The hiliter needs to know what language to use for +the code block. There are three ways to tell the hiliter what language the code +block contains and each one has a different result. + +[syntax]: http://daringfireball.net/projects/markdown/syntax#precode + +###SheBang (with path) + +If the first line of the codeblock contains a shebang, the language is derived +from that and line numbers are used. + + #!/usr/bin/python + # Code goes here ... + +Will result in: + + #!/usr/bin/python + # Code goes here ... + + +###SheBang (no path) + +If the first line contains a shebang, but the shebang line does not contain a +path (a single `/` or even a space), then that line is removed from the code +block before processing. Line numbers are used. + + #!python + # Code goes here ... + +Will result in: + + # Code goes here ... + +####Colons + +If the first line begins with three or more colons, the text following the +colons identifies the language. The first line is removed from the code block +before processing and line numbers are not used. + + :::python + # Code goes here ... + +Will result in: + + # Code goes here ... + +###When No Language is Defined + +CodeHilite is completely backward compatible so that if a code block is +encountered that does not define a language, the block is simple wrapped in +`<pre>` tags and output. Note: one exception would be that the Pygments +highlighting engine will try to guess the language. Upon failure, the same +behavior will happen as described here. + + # Code goes here ... + +Will result in: + + # Code goes here ... + +Lets see the source for that: + + <div class="codehilite" ><pre><code># Code goes here ... + </code></pre></div> + +Usage +----- + +From the Python interpreter: + + >>> html = markdown.markdown(text, ['codehilite']) + +If you want every code block to have line numbers, even when using colons +(`:::`) for language identification, the setting `force_linenos` is available +to do so. + + >>> html = markdown.markdown(text, + ... ['codehilite(force_linenos=True)'] + ... ) diff --git a/docs/extensions/Definition_Lists.txt b/docs/extensions/Definition_Lists.txt new file mode 100644 index 0000000..983070d --- /dev/null +++ b/docs/extensions/Definition_Lists.txt @@ -0,0 +1,55 @@ +Definition Lists +---------------- + +Summary +------- + +The Definition List Extension adds the ability to create definition list in +Markdown documents. + +This extension is included in the standard Markdown library. + +Syntax +------ + +Definition lists are defined using the syntax established in +[PHP Markdown Extra][php]. + +[php]: http://www.michelf.com/projects/php-markdown/extra/#def-list + +Thus, the following text (taken from the above referenced PHP documentation): + + Apple + : Pomaceous fruit of plants of the genus Malus in + the family Rosaceae. + + Orange + : The fruit of an evergreen tree of the genus Citrus. + +will be rendered like so: + + <dl> + <dt>Apple</dt> + <dd>Pomaceous fruit of plants of the genus Malus in + the family Rosaceae.</dd> + + <dt>Orange</dt> + <dd>The fruit of an evergreen tree of the genus Citrus.</dd> + </dl> + + +Usage +----- + +From the Python interpreter: + + >>> html = markdown.markdown(text, ['def_list']) + +To use with other extensions, just add them to the list, like this: + + >>> html = markdown.markdown(text, ['def_list', 'footnotes']) + +The extension can also be called from the command line using Markdown's `-x` +parameter: + + markdown.py -x def_list source.txt > output.html diff --git a/docs/extensions/Fenced_Code_Blocks.txt b/docs/extensions/Fenced_Code_Blocks.txt new file mode 100644 index 0000000..6b1ba76 --- /dev/null +++ b/docs/extensions/Fenced_Code_Blocks.txt @@ -0,0 +1,63 @@ +Fenced Code Blocks +================== + +Summary +------- + +This extension adds a secondary way to define code blocks which overcomes a few +limitations of the indented code blocks. + +This extension is included in the standard Markdown library. + +Syntax +------ + +Fenced Code Blocks are defined using the syntax established in +[PHP Markdown Extra][php]. + +[php]: http://www.michelf.com/projects/php-markdown/extra/#fenced-code-blocks + +Thus, the following text (taken from the above referenced PHP documentation): + + This is a paragraph introducing: + + ~~~~~~~~~~~~~~~~~~~~ + a one-line code block + ~~~~~~~~~~~~~~~~~~~~ + +Fenced code blocks can have a blank line as the first and/or last line of a +code block and they can also come immediately after a list item without becoming +part of the list. + +In addition to PHP Extra's syntax, you can define the language of the code +block for use by syntax highlighters etc. The language will be assigned as a +class attribute of the ``<code>`` element in the output. Therefore, you should +define the language as you would a css class - ``.language``. For consistency +with other markdown syntax, the language can *optionally* be wrapped in curly +brackets: + + ~~~~{.python} + # python code + ~~~~ + + ~~~~.html + <p>HTML Document</p> + ~~~~ + +The above will output: + + <pre><code class="python"># python code + </code></pre> + + <pre><code class="html"><p>HTML Document</p> + </code></pre> + +Usage +----- + +From the Python interpreter: + + >>> html = markdown.markdown(text, ['fenced_code']) + + + diff --git a/docs/extensions/HTML_Tidy.txt b/docs/extensions/HTML_Tidy.txt new file mode 100644 index 0000000..52f991f --- /dev/null +++ b/docs/extensions/HTML_Tidy.txt @@ -0,0 +1,27 @@ +HTML Tidy +========= + +Runs [HTML Tidy][] on the output of Python-Markdown using the [uTidylib][] +Python wrapper. Both libtidy and uTidylib must be installed on your system. + +This extension is available in the standard Markdown library since version 2.0. + +[HTML Tidy]: http://tidy.sourceforge.net/ +[uTidylib]: http://utidylib.berlios.de/ + +Note than any Tidy [options][] can be passed in as extension configs. So, +for example, to output HTML rather than XHTML, set ``output_xhtml=0``. To +indent the output, set ``indent=auto`` and to have Tidy wrap the output in +``<html>`` and ``<body>`` tags, set ``show_body_only=0``. See Tidy's +[options][] for a full list of the available options. The defaults are set to +most closely match Markdowns defaults with the exception that you get much +better pretty-printing. + +[options]: http://tidy.sourceforge.net/docs/quickref.html + +Note that options set in this extension will override most any other settings +passed on to Markdown (such as "output_format"). Unlike Markdown, this extension +will also treat raw HTML no different than that output by Markdown. In other +words, it may munge a document authors carefully crafted HTML. Of course, it +may also transform poorly formed raw HTML into nice, valid HTML. Take these +things into consideration when electing to use this extension. diff --git a/docs/extensions/HeaderId.txt b/docs/extensions/HeaderId.txt new file mode 100644 index 0000000..efd1eb8 --- /dev/null +++ b/docs/extensions/HeaderId.txt @@ -0,0 +1,104 @@ +HeaderId +======== + +Summary +------- + +An extension to Python-Markdown that adds an 'id' attribute to HTML header +elements (h1-h6) in markdown's output. + +This extension is included in the standard Markdown library. + +Syntax +------ + +The basic syntax follows [PHP Markdown Extra][]'s implementation: + +[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/#header-id + + Header 1 {#header1} + ======== + + ## Header 2 ## {#header2} + +will result in the following HTML: + + <h1 id="header1">Header 1</h1> + + <h2 id="header2">Header 2</h2> + +However, there is much more that this extension does. + +By default, all headers will automatically have unique "id" attributes +generated based upon the text of the header (See below to turn this off). +Note this example in which all three headers would have the same "id": + + #Header + #Another Header {#header} + #Header + +Results in: + + <h1 id="header">Header</h1> + <h1 id="header_1">Another Header</h1> + <h1 id="header_2">Third Header</h1> + +Configuring the Output +---------------------- + +The HeaderId extension has two configuration settings: + +* **level**: Base level for headers. + + Default: `1` + +* **forceid**: Force all headers to have an id. + + Default: `True` + +The `level` setting allows you to automatically adjust the header levels to fit +within the hierarchy of your html templates. For example, the markdown text for +this page should not contain any headers higher than level 3 (`<h3>`). +Therefore, do the following: + + >>> text = ''' + ... #Some Header + ... ## Next Level''' + >>> html = markdown.markdown(text, ['headerid(level=3)']) + >>> print html + <h3 id="some_header">Some Header</h3> + <h4 id="next_level">Next Level</h4>' + +The `forceid` setting turns on or off the automatically generated ids for +headers that do not have one explicitly defined. + + >>> text = ''' + ... # Some Header + ... # Header with ID # { #foo }''' + >>> html = markdown.markdown(text, ['headerid(forceid=False)']) + >>> print html + <h1>Some Header</h1> + <h1 id="foo">Header with ID</h1> + +Using with Meta-Data +-------------------- + +The HeaderId Extension also supports the [[Meta-Data]] Extension. Please see the documentation for that extension for specifics. The supported meta-data keywords are: + +* `header_level` +* `header_forceid` + +When used, the meta-data will override the settings provided through the +`extension_configs` interface. + +This document: + + header_level: 2 + header_forceid: Off + + # A Header + + +Will result in the following output: + + <h2>A Header</h2> diff --git a/docs/extensions/ImageLinks.txt b/docs/extensions/ImageLinks.txt new file mode 100644 index 0000000..db4f99f --- /dev/null +++ b/docs/extensions/ImageLinks.txt @@ -0,0 +1,27 @@ +ImageLinks +========== + +Summary +------- + +ImageLinks is a Python-Markdown extension that provides a mechanism for +defining mini-photo galleries within a markdown document. + +This extension is part of the Markdown library since 2.0. + +Syntax +------ + +Turns paragraphs like + + <~~~~~~~~~~~~~~~~~~~~~~~~ + dir/subdir + dir/subdir + dir/subdir + ~~~~~~~~~~~~~~ + dir/subdir + dir/subdir + dir/subdir + ~~~~~~~~~~~~~~~~~~~> + +Into mini-photo galleries. diff --git a/docs/extensions/Meta-Data.txt b/docs/extensions/Meta-Data.txt new file mode 100644 index 0000000..982ea67 --- /dev/null +++ b/docs/extensions/Meta-Data.txt @@ -0,0 +1,88 @@ +Meta-Data +========= + +Summary +------- + +An extension to Python-Markdown that adds a syntax for defining meta-data about +a document. The Meta-Data extension is inspired by and follows the syntax of +[MultiMarkdown][]. Currently, this extension does not use the meta-data in any +way, but simply provides it as a `Meta` attribute of a markdown instance for +use by other extensions or directly by your python code. + +[MultiMarkdown]: http://fletcherpenney.net/MultiMarkdown_Syntax_Guide#metadata + +This extension has been a part of the Markdown library since 2.0. + +Syntax +------ + +Meta-data consists of a series of keywords and values defined at the beginning +of a markdown document like this: + + Title: My Document + Summary: A brief description of my document. + Authors: Waylan Limberg + John Doe + Date: October 2, 2007 + blank-value: + base_url: http://example.com + + This is the first paragraph of the document. + +The keywords are case-insensitive and may consist of letters, numbers, +underscores and dashes and must end with a colon. The values consist of +anything following the colon on the line and may even be blank. If a line is +indented 4 or more spaces, that line is assumed to be an additional line of the +value for the previous keyword. A keyword may have as many lines as desired. +The first blank line ends all meta-data for the document. Therefore, the first +line of a document must not be blank. All meta-data is stripped from the +document prior to any further processing by markdown. + +Accessing the Meta-Data +----------------------- + +The meta-data is made available as a python Dict in the `Meta` attribute of an +instance of the Markdown class. For example, using the above document: + + >>> md = markdown.Markdown(extensions = ['meta']) + >>> html = md.convert(text) + >>> # Meta-data has been stripped from output + >>> print html + <p>This is the first paragraph of the document.</p> + + >>> # View meta-data + >>> print md.Meta + { + 'title' : ['My Document'], + 'summary' : ['A brief description of my document.'], + 'authors' : ['Waylan Limberg', 'John Doe'], + 'date' : ['October 2, 2007'], + 'blank-value' : [''], + 'base_url' : ['http://example.com'] + } + +Note that the keys are all lowercase and the values consist of a list of +strings where each item is one line for that key. This way, one could preserve +line breaks if desired. Or the items could be joined where appropriate. No +assumptions are made regarding the data. It is simply passed as found to the +`Meta` attribute. + +Perhaps the meta-data could be passed into a template system, or used by +various markdown extensions. The possibilities are left to the imagination of +the developer. + +Compatible Extensions +--------------------- + +The following are extensions currently known to work with the Meta-Data +Extension and the keywords they are known to support: + +* [[HeaderId]] + * `header_level` + * `header_forceid` +* [[WikiLinks]] + * `wiki_base_url` + * `wiki_end_url` + * `wiki_html_class` + diff --git a/docs/extensions/RSS.txt b/docs/extensions/RSS.txt new file mode 100644 index 0000000..f2ecf0c --- /dev/null +++ b/docs/extensions/RSS.txt @@ -0,0 +1,35 @@ +RSS +=== + +Summary +------- + +An extension to Python-Markdown that outputs a markdown document as RSS. This +extension has been included with Python-Markdown since 1.7 and should be +available to anyone who has a typical install of Python-Markdown. + +Usage +----- + +From the Python interpreter: + + >>> import markdown + >>> text = "Some markdown document." + >>> rss = markdown.markdown(text, ['rss']) + +Configuring the Output +---------------------- + +An RSS document includes some data about the document (URI, author, title) that +will likely need to be configured for your needs. Therefore, three configuration +options are available: + +* **URL** : The Main URL for the document. +* **CREATOR** : The Feed creator's name. +* **TITLE** : The title for the feed. + +An example: + + >>> rss = markdown.markdown(text, extensions = \ + ... ['rss(URL=http://example.com,CREATOR=JOHN DOE,TITLE=My Document)'] + ... ) diff --git a/docs/extensions/Tables.txt b/docs/extensions/Tables.txt new file mode 100644 index 0000000..63d6849 --- /dev/null +++ b/docs/extensions/Tables.txt @@ -0,0 +1,53 @@ +Tables +---------------- + +Summary +------- + +The Table Extension adds the ability to create tables in Markdown documents. + +This extension is included in the standard Markdown library. + +Syntax +------ + +Tables are defined using the syntax established in [PHP Markdown Extra][php]. + +[php]: http://www.michelf.com/projects/php-markdown/extra/#table + +Thus, the following text (taken from the above referenced PHP documentation): + +First Header | Second Header +------------- | ------------- +Content Cell | Content Cell +Content Cell | Content Cell + +will be rendered as: + +<table> +<thead> +<tr> +<th>First Header</th> +<th>Second Header</th> +</tr> +</thead> +<tbody> +<tr> +<td>Content Cell</td> +<td>Content Cell</td> + +</tr> +<tr> +<td>Content Cell</td> +<td>Content Cell</td> +</tr> +</tbody> +</table> + +Usage +----- + +From the Python interpreter: + + >>> html = markdown.markdown(text, ['tables']) + diff --git a/docs/extensions/Tables_of_Contents.txt b/docs/extensions/Tables_of_Contents.txt new file mode 100644 index 0000000..032c25c --- /dev/null +++ b/docs/extensions/Tables_of_Contents.txt @@ -0,0 +1,50 @@ +Table of Contents +================= + +Summary +------- + +Adds a Table of Contents to a Markdown document. + +This extension is included with the Markdown library since version 2.0. + +Syntax +------ + +Place a marker in the document where you would like the table of contents to +appear. Then, a nested list of all the headers in the document will replace the +marker. The marker defaults to ``[TOC]`` so the following document: + + [TOC] + + # Header 1 + + ## Header 2 + +would generate the following output: + + <div class="toc"> + <ul> + <li><a href="#header-1">Header 1</a></li> + <ul> + <li><a href="#header-2">Header 2</a></li> + </ul> + </ul> + </div> + <h1 id="header-1">Header 1</h1> + <h1 id="header-2">Header 2</h1> + +Configuration Options +--------------------- + +The following options are provided to configure the output: + +* **marker**: Text to find and replace with the Table of Contents. Defaults + to ``[TOC]``. +* **slugify**: Callable to generate anchors based on header text. Defaults to a + built in ``slugify`` method. The callable must accept one argument which + contains the text content of the header and return a string which will be + used as the anchor text. +* **title**: Title to insert in TOC ``<div>``. Defaults to ``None``. +* **anchorlink**: Set to ``True`` to have the headers link to themselves. + Default is ``False``. diff --git a/docs/extensions/WikiLinks.txt b/docs/extensions/WikiLinks.txt new file mode 100644 index 0000000..8bbead5 --- /dev/null +++ b/docs/extensions/WikiLinks.txt @@ -0,0 +1,144 @@ +WikiLinks +========= + +Summary +------- + +An extension to Python-Markdown that adds [WikiLinks][]. Specifically, any +``[[bracketed]]`` word is converted to a link. + +[WikiLinks]: http://en.wikipedia.org/wiki/Wikilink + +This extension has been included in the Markdown library since 2.0. + +Syntax +------ + +A ``[[bracketed]]`` word is any combination of upper or lower case letters, +number, dashes, underscores and spaces surrounded by double brackets. Therefore + + [[Bracketed]] + +Would produce the following html: + + <a href="/Bracketed/" class="wikilink">Bracketed</a> + +Note that wikilinks are automatically assigned `class="wikilink"` making it +easy to style wikilinks differently from other links on a page if one so +desires. See below for ways to alter the class. + +You should also note that when a space is used, the space is converted to an +underscore in the link but left as-is in the label. Perhaps an example +would illustrate this best: + + [[Wiki Link]] + +Becomes + + <a href="/Wiki_Link/" class="wikilink">Wiki Link</a> + +Usage +----- + +From the Python interpreter: + + >>> text = "Some text with a [[WikiLink]]." + >>> html = markdown.markdown(text, ['wikilink']) + +The default behavior is to point each link to the document root of the current +domain and close with a trailing slash. Additionally, each link is assigned to +the html class `wikilink`. This may not always be desirable. Therefore, one can +customize that behavior within Python code. Three settings are provided to +change the default behavior: + +1. **base_url**: String to append to beginning of URL. + + Default: `'/'` + +2. **end_url**: String to append to end of URL. + + Default: `'/'` + +3. **html_class**: CSS hook. Leave blank for none. + + Default: `'wikilink'` + +4. **build_url**: Callable which formats the URL from it's parts. + +For an example, let us suppose links should always point to the subdirectory +`/wiki/` and end with `.html` + + >>> html = markdown.markdown(text, + ... ['wikilink(base_url=/wiki/,end_url=.html)'] + ... ) + +The above would result in the following link for `[[WikiLink]]`. + + <a href="/wiki/WikiLink.html" class="wikilink">WikiLink</a> + +If you want to do more that just alter the base and/or end of the URL, you +could also pass in a callable which must accept three arguments (``label``, +``base``, and ``end``). The callable must return the URL in it's entirety. + + def my_url_builder(label, base, end): + # do stuff + return url + + md = markdown.Markdown( + extensions=['wikilinks], + extension_configs={'wikilinks' : [('build_url', my_url_builder)]} + ) + + +The option is also provided to change or remove the class attribute. + + >>> html = markdown.markdown(text, + ... ['wikilink(base_url=myclass)'] + ... ) + +Would cause all wikilinks to be assigned to the class `myclass`. + + <a href="/WikiLink/" class="myclass">WikiLink</a> + +The same options can be used on the command line as well: + + python markdown.py -x wikilink(base_url=http://example.com/,end_url=.html,html_class=foo) src.txt + +Some may prefer the more complex format when calling the `Markdown` class directly: + + >>> md = markdown.Markdown( + ... extensions = ['wikilink'], + ... extension_configs = {'wikilink': [ + ... ('base_url', 'http://example.com/'), + ... ('end_url', '.html'), + ... ('html_class', '') ]}, + ... safe_mode = True + ... ) + >>> html = md.convert(text) + +Using with Meta-Data +-------------------- + +The WikiLink Extension also supports the [[Meta-Data]] Extension. Please see +the documentation for that extension for specifics. The supported meta-data +keywords are: + +* `wiki_base_url` +* `wiki_end_url` +* `wiki_html_class` + +When used, the meta-data will override the settings provided through the +`extension_configs` interface. + +This document: + + wiki_base_url: http://example.com/ + wiki_end_url: .html + wiki_html_class: + + A [[WikiLink]] in the first paragraph. + +would result in the following output (notice the blank `wiki_html_class`): + + <p>A <a href="http://example.com/WikiLink.html">WikiLink</a> in the first paragraph.</p> + diff --git a/docs/extensions/extra.txt b/docs/extensions/extra.txt new file mode 100644 index 0000000..817d58f --- /dev/null +++ b/docs/extensions/extra.txt @@ -0,0 +1,43 @@ +Python-Markdown Extra +===================== + +Summary +------- + +A compilation of various Python-Markdown extensions that (mostly) imitates +[PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/). + +The supported extensions include: + +* [[Abbreviations]] +* [[Definition_Lists]] +* [[Fenced_Code_Blocks]] +* [[Footnotes]] +* [[HeaderId]] +* [[Tables]] + +See each individual extension for syntax documentation. Extra and all it's +supported extensions are included in the standard Markdown library. + +Usage +----- + +From the Python interpreter: + + >>> import markdown + >>> html = markdown.markdown(text, ['extra']) + +In the unlikely event that one or more of the supported extensions are not +available for import, Markdown will simply continue without that +extension. If you would like to be notified of such failures, +you may set Python-Markdown's logger level to "WARN". + +There may be additional extensions that are distributed with +Python-Markdown that are not included here in Extra. Those extensions +are not part of PHP Markdown Extra, and therefore, not part of +Python-Markdown Extra. If you really would like Extra to include +additional extensions, we suggest creating your own clone of Extra +under a different name (see [[Writing Extensions]]). You could also +edit the `extensions` global variable defined in the source, but be +aware that such changes may be lost when you upgrade to any future +version of Python-Markdown. diff --git a/docs/extensions/footnotes.txt b/docs/extensions/footnotes.txt new file mode 100644 index 0000000..7188f44 --- /dev/null +++ b/docs/extensions/footnotes.txt @@ -0,0 +1,62 @@ +Footnotes +========= + +Summary +------- + +An extension to Python-Markdown that adds footnote syntax. This extension has +been included with Python-Markdown since 1.7 and should be available to anyone +who has a typical install of Python-Markdown. + +Syntax +------ + +Python-Markdown's Footnote syntax follows the generally accepted syntax of the +Markdown community at large and almost exactly matches [PHP Markdown Extra][]'s +implementation of footnotes. The only differences involve a few subtleties in +the output. + +[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/#footnotes + +Example: + + Footnotes[^1] have a label[^label] and a definition[^!DEF]. + + [^1]: This is a footnote + [^label]: A footnote on "label" + [^!DEF]: The definition of a footnote. + +A footnote definition may contain multiple lines, paragraphs, code blocks, +blockquotes and most any other markdown syntax. The additional line simply +must be indented at least an additional four spaces. + + [^1]: The first paragraph of the definition. + + Paragraph two of the definition. + + > A blockquote with + > multiple lines. + + a code block + + A final paragraph. + +By default, the footnote definitions are placed at the end of the resulting +HTML document. However, you may want the footnotes in another location within +the document. Simply place the following text at that location within your +markdown document (See how to configure this text below): + + ///Footnotes Go Here/// + +Usage +----- + +From the Python interpreter: + + >>> html = markdown.markdown(text, ['footnotes']) + +To configure the place marker for footnote definitions (just be sure not to +use any existing markdown syntax): + + >>> html = markdown.markdown(text, ['footnotes(PLACE_MARKER=+++my marker+++)']) + diff --git a/docs/extensions/index.txt b/docs/extensions/index.txt new file mode 100644 index 0000000..71d857c --- /dev/null +++ b/docs/extensions/index.txt @@ -0,0 +1,44 @@ +Available Extensions +==================== + +Officially Supported Extensions +------------------------------- + +These extensions are included with (at least) the most recent release and are +officially supported by the Python-Markdown developers. Any documentation is +maintained here and all bug reports should be made to the project. If you +have a typical install of Python-Markdown, these extensions are already +available to you. + +* [[Extra]] + * [[Abbreviations]] + * [[Definition_Lists]] + * [[Fenced_Code_Blocks]] + * [[Footnotes]] + * [[HeaderId]] + * [[Tables]] +* [[CodeHilite]] +* [[HTML_Tidy]] +* [[ImageLinks]] +* [[Meta-Data]] +* [[RSS]] +* [[Table_of_Contents]] +* [[WikiLinks]] + +Unofficially Supported Extensions +--------------------------------- + +These extensions have not yet been included in any official Python-Markdown +release. However, the code is maintained in the projects +[mainline git repository](http://gitorious.org/projects/python-markdown/repos/mainline) +by the Python-Markdown developers and the official documentation is maintained +here. All bug reports should be made to the project. It is anticipated that +these extensions will be included with some future official release, at which +time they will be moved to the above list of official extensions. + +* [[Legacy]] + + + + + diff --git a/docs/release-2.0.1.txt b/docs/release-2.0.1.txt new file mode 100644 index 0000000..e5946b2 --- /dev/null +++ b/docs/release-2.0.1.txt @@ -0,0 +1,16 @@ +Python-Markdown 2.0.1 Release Notes +=================================== + +Python-Markdown 2.0.1 is a bug-fix release. No new features have been added. +Most notably, various issues with the command line script have been fixed. +There have also been a few fixes for minor parsing bugs in some edge cases. +For a full list of changes, see the git log. + +Backwards-incompatible Changes +------------------------------ + +Due to various complications in how Python handles command line scripts in +differance systems and with differant installation tools, we were forced to +rename the commandline script to ``markdown`` (no ".py"). A matching batch +script will get installed on Windows. Any shell scripts which call +``markdown.py`` will need to be altered to call ``markdown`` instead. diff --git a/docs/release-2.0.2.txt b/docs/release-2.0.2.txt new file mode 100644 index 0000000..8ae9a3d --- /dev/null +++ b/docs/release-2.0.2.txt @@ -0,0 +1,9 @@ +Python-Markdown 2.0.2 Release Notes +=================================== + +Python-Markdown 2.0.2 is a bug-fix release. No new features have been added. +Most notably, the setup script has been updated to include a dependency on +ElementTree on older versions of Python (< 2.5). There have also been a few +fixes for minor parsing bugs in some edge cases. For a full list of changes, +see the git log. + diff --git a/docs/release-2.0.txt b/docs/release-2.0.txt new file mode 100644 index 0000000..b1f71ad --- /dev/null +++ b/docs/release-2.0.txt @@ -0,0 +1,67 @@ +Python-Markdown 2.0 Release Notes +================================= + +We are happy to release Python-Markdown 2.0, which has been over a year in the +making. We have rewritten significant portions of the code, dramatically +extending the extension API, increased performance, and added numerous +extensions to the distribution (including an extension that mimics PHP Markdown +Extra), all while maintaining backward compatibility with the end user API in +version 1.7. + +Python-Markdown supports Python versions 2.3, 2.4, 2.5, and 2.6. We've even +released a version converted to Python 3.0! + +Backwards-incompatible Changes +------------------------------ + +While Python-Markdown has experienced numerous internal changes, those changes +should only affect extension authors. If you have not written your own +extensions, then you should not need to make any changes to your code. +However, you may want to ensure that any third party extensions you are using +are compatible with the new API. + +The new extension API is fully documented in [[writing_extensions]]. Below is a +summary of the significant changes: + +* The old home-grown NanoDOM has been replaced with ElementTree. Therefore all + extensions must use ElementTree rather than the old NanoDOM. +* The various processors and patterns are now stored with OrderedDicts rather + than lists. Any code adding processors and/or patterns into Python-Markdown + will need to be adjusted to use the new API using OrderedDicts. +* The various types of processors available have been either combined, added, + or removed. Ensure that your processors match the currently supported types. + +What's New in Python-Markdown 2.0 +--------------------------------- + +Thanks to the work of Artem Yunusov as part of GSoC 2008, Python-Markdown uses +ElementTree internally to build the (X)HTML document from markdown source text. +This has resolved various issues with the older home-grown NanoDOM and made +notable increases in performance. + +Artem also refactored the Inline Patterns to better support nested patterns +which has resolved many inconsistencies in Python-Markdown's parsing of the +markdown syntax. + +The core parser had been completely rewritten, increasing performance and, for +the first time, making it possible to override/add/change the way block level +content is parsed. + +Python-Markdown now parses markdown source text more closely to the other +popular implementations (Perl, PHP, etc.) than it ever has before. With the +exception of a few minor insignificant differences, any difference should be +considered a bug, rather than a limitation of the parser. + +The option to return HTML4 output as apposed to XHTML has been added. In +addition, extensions should be able to easily add additional output formats. + +As part of implementing markdown in the Dr. Project project (a Trac fork), among +other things, David Wolever refactored the "extension" keyword so that it +accepts either the extension names as strings or instances of extensions. This +makes it possible to include multiple extensions in a single module. + +Numerous extensions are included in the distribution by default. See +[[available_extensions]] for a complete list. + +See the [[change_log]] for a full list of changes. + diff --git a/docs/using_as_module.txt b/docs/using_as_module.txt new file mode 100644 index 0000000..130d0a7 --- /dev/null +++ b/docs/using_as_module.txt @@ -0,0 +1,150 @@ +Using Markdown as Python Library +================================ + +First and foremost, Python-Markdown is intended to be a python library module +used by various projects to convert Markdown syntax into HTML. + +The Basics +---------- + +To use markdown as a module: + + import markdown + html = markdown.markdown(your_text_string) + +Encoded Text +------------ + +Note that ``markdown()`` expects **Unicode** as input (although a simple ASCII +string should work) and returns output as Unicode. Do not pass encoded strings to it! +If your input is encoded, e.g. as UTF-8, it is your responsibility to decode +it. E.g.: + + input_file = codecs.open("some_file.txt", mode="r", encoding="utf-8") + text = input_file.read() + html = markdown.markdown(text, extensions) + +If you later want to write it to disk, you should encode it yourself: + + output_file = codecs.open("some_file.html", "w", encoding="utf-8") + output_file.write(html) + +More Options +------------ + +If you want to pass more options, you can create an instance of the ``Markdown`` +class yourself and then use ``convert()`` to generate HTML: + + import markdown + md = markdown.Markdown( + extensions=['footnotes'], + extension_configs= {'footnotes' : ('PLACE_MARKER','~~~~~~~~')}, + safe_mode=True, + output_format='html4' + ) + return md.convert(some_text) + +You should also use this method if you want to process multiple strings: + + md = markdown.Markdown() + html1 = md.convert(text1) + html2 = md.convert(text2) + +Working with Files +------------------ + +While the Markdown class is only intended to work with Unicode text, some +encoding/decoding is required for the command line features. These functions +and methods are only intended to fit the common use case. + +The ``Markdown`` class has the method ``convertFile`` which reads in a file and +writes out to a file-like-object: + + md = markdown.Markdown() + md.convertFile(input="in.txt", output="out.html", encoding="utf-8") + +The markdown module also includes a shortcut function ``markdownFromFile`` that +wraps the above method. + + markdown.markdownFromFile(input="in.txt", + output="out.html", + extensions=[], + encoding="utf-8", + safe=False) + +In either case, if the ``output`` keyword is passed a file name (i.e.: +``output="out.html"``), it will try to write to a file by that name. If +``output`` is passed a file-like-object (i.e. ``output=StringIO.StringIO()``), +it will attempt to write out to that object. Finally, if ``output`` is +set to ``None``, it will write to ``stdout``. + +Using Extensions +---------------- + +One of the parameters that you can pass is a list of Extensions. Extensions +must be available as python modules either within the ``markdown.extensions`` +package or on your PYTHONPATH with names starting with `mdx_`, followed by the +name of the extension. Thus, ``extensions=['footnotes']`` will first look for +the module ``markdown.extensions.footnotes``, then a module named +``mdx_footnotes``. See the documentation specific to the extension you are +using for help in specifying configuration settings for that extension. + +Note that some extensions may need their state reset between each call to +``convert``: + + html1 = md.convert(text1) + md.reset() + html2 = md.convert(text2) + +Safe Mode +--------- + +If you are using Markdown on a web system which will transform text provided +by untrusted users, you may want to use the "safe_mode" option which ensures +that the user's HTML tags are either replaced, removed or escaped. (They can +still create links using Markdown syntax.) + +* To replace HTML, set ``safe_mode="replace"`` (``safe_mode=True`` still works + for backward compatibility with older versions). The HTML will be replaced + with the text defined in ``markdown.HTML_REMOVED_TEXT`` which defaults to + ``[HTML_REMOVED]``. To replace the HTML with something else: + + markdown.HTML_REMOVED_TEXT = "--RAW HTML IS NOT ALLOWED--" + md = markdown.Markdown(safe_mode="replace") + + **Note**: You could edit the value of ``HTML_REMOVED_TEXT`` directly in + markdown/__init__.py but you will need to remember to do so every time you + upgrade to a newer version of Markdown. Therefore, this is not recommended. + +* To remove HTML, set ``safe_mode="remove"``. Any raw HTML will be completely + stripped from the text with no warning to the author. + +* To escape HTML, set ``safe_mode="escape"``. The HTML will be escaped and + included in the document. + +Output Formats +-------------- + +If Markdown is outputing (X)HTML as part of a web page, most likely you will +want the output to match the (X)HTML version used by the rest of your page/site. +Currently, Markdown offers two output formats out of the box; "HTML4" and +"XHTML1" (the default) . Markdown will also accept the formats "HTML" and +"XHTML" which currently map to "HTML4" and "XHTML" respectively. However, +you should use the more explicit keys as the general keys may change in the +future if it makes sense at that time. The keys can either be lowercase or +uppercase. + +To set the output format do: + + html = markdown.markdown(text, output_format='html4') + +Or, when using the Markdown class: + + md = markdown.Markdown(output_format='html4') + html = md.convert(text) + +Note that the output format is only set once for the class and cannot be +specified each time ``convert()`` is called. If you really must change the +output format for the class, you can use the ``set_output_format`` method: + + md.set_output_format('xhtml1') diff --git a/docs/writing_extensions.txt b/docs/writing_extensions.txt new file mode 100644 index 0000000..3aad74a --- /dev/null +++ b/docs/writing_extensions.txt @@ -0,0 +1,594 @@ +Writing Extensions for Python-Markdown +====================================== + +Overview +-------- + +Python-Markdown includes an API for extension writers to plug their own +custom functionality and/or syntax into the parser. There are preprocessors +which allow you to alter the source before it is passed to the parser, +inline patterns which allow you to add, remove or override the syntax of +any inline elements, and postprocessors which allow munging of the +output of the parser before it is returned. If you really want to dive in, +there are also blockprocessors which are part of the core BlockParser. + +As the parser builds an [ElementTree][] object which is later rendered +as Unicode text, there are also some helpers provided to ease manipulation of +the tree. Each part of the API is discussed in its respective section below. +Additionaly, reading the source of some [[Available Extensions]] may be helpful. +For example, the [[Footnotes]] extension uses most of the features documented +here. + +* [Preprocessors][] +* [InlinePatterns][] +* [Treeprocessors][] +* [Postprocessors][] +* [BlockParser][] +* [Working with the ElementTree][] +* [Integrating your code into Markdown][] + * [extendMarkdown][] + * [OrderedDict][] + * [registerExtension][] + * [Config Settings][] + * [makeExtension][] + +<h3 id="preprocessors">Preprocessors</h3> + +Preprocessors munge the source text before it is passed into the Markdown +core. This is an excellent place to clean up bad syntax, extract things the +parser may otherwise choke on and perhaps even store it for later retrieval. + +Preprocessors should inherit from ``markdown.preprocessors.Preprocessor`` and +implement a ``run`` method with one argument ``lines``. The ``run`` method of +each Preprocessor will be passed the entire source text as a list of Unicode +strings. Each string will contain one line of text. The ``run`` method should +return either that list, or an altered list of Unicode strings. + +A pseudo example: + + class MyPreprocessor(markdown.preprocessors.Preprocessor): + def run(self, lines): + new_lines = [] + for line in lines: + m = MYREGEX.match(line) + if m: + # do stuff + else: + new_lines.append(line) + return new_lines + +<h3 id="inlinepatterns">Inline Patterns</h3> + +Inline Patterns implement the inline HTML element syntax for Markdown such as +``*emphasis*`` or ``[links](http://example.com)``. Pattern objects should be +instances of classes that inherit from ``markdown.inlinepatterns.Pattern`` or +one of its children. Each pattern object uses a single regular expression and +must have the following methods: + +* **``getCompiledRegExp()``**: + + Returns a compiled regular expression. + +* **``handleMatch(m)``**: + + Accepts a match object and returns an ElementTree element of a plain + Unicode string. + +Note that any regular expression returned by ``getCompiledRegExp`` must capture +the whole block. Therefore, they should all start with ``r'^(.*?)'`` and end +with ``r'(.*?)!'``. When using the default ``getCompiledRegExp()`` method +provided in the ``Pattern`` you can pass in a regular expression without that +and ``getCompiledRegExp`` will wrap your expression for you. This means that +the first group of your match will be ``m.group(2)`` as ``m.group(1)`` will +match everything before the pattern. + +For an example, consider this simplified emphasis pattern: + + class EmphasisPattern(markdown.inlinepatterns.Pattern): + def handleMatch(self, m): + el = markdown.etree.Element('em') + el.text = m.group(3) + return el + +As discussed in [Integrating Your Code Into Markdown][], an instance of this +class will need to be provided to Markdown. That instance would be created +like so: + + # an oversimplified regex + MYPATTERN = r'\*([^*]+)\*' + # pass in pattern and create instance + emphasis = EmphasisPattern(MYPATTERN) + +Actually it would not be necessary to create that pattern (and not just because +a more sophisticated emphasis pattern already exists in Markdown). The fact is, +that example pattern is not very DRY. A pattern for `**strong**` text would +be almost identical, with the exception that it would create a 'strong' element. +Therefore, Markdown provides a number of generic pattern classes that can +provide some common functionality. For example, both emphasis and strong are +implemented with separate instances of the ``SimpleTagPettern`` listed below. +Feel free to use or extend any of these Pattern classes. + +**Generic Pattern Classes** + +* **``SimpleTextPattern(pattern)``**: + + Returns simple text of ``group(2)`` of a ``pattern``. + +* **``SimpleTagPattern(pattern, tag)``**: + + Returns an element of type "`tag`" with a text attribute of ``group(3)`` + of a ``pattern``. ``tag`` should be a string of a HTML element (i.e.: 'em'). + +* **``SubstituteTagPattern(pattern, tag)``**: + + Returns an element of type "`tag`" with no children or text (i.e.: 'br'). + +There may be other Pattern classes in the Markdown source that you could extend +or use as well. Read through the source and see if there is anything you can +use. You might even get a few ideas for different approaches to your specific +situation. + +<h3 id="treeprocessors">Treeprocessors</h3> + +Treeprocessors manipulate an ElemenTree object after it has passed through the +core BlockParser. This is where additional manipulation of the tree takes +place. Additionally, the InlineProcessor is a Treeprocessor which steps through +the tree and runs the InlinePatterns on the text of each Element in the tree. + +A Treeprocessor should inherit from ``markdown.treeprocessors.Treeprocessor``, +over-ride the ``run`` method which takes one argument ``root`` (an Elementree +object) and returns either that root element or a modified root element. + +A pseudo example: + + class MyTreeprocessor(markdown.treeprocessors.Treeprocessor): + def run(self, root): + #do stuff + return my_modified_root + +For specifics on manipulating the ElementTree, see +[Working with the ElementTree][] below. + +<h3 id="postprocessors">Postprocessors</h3> + +Postprocessors manipulate the document after the ElementTree has been +serialized into a string. Postprocessors should be used to work with the +text just before output. + +A Postprocessor should inherit from ``markdown.postprocessors.Postprocessor`` +and over-ride the ``run`` method which takes one argument ``text`` and returns +a Unicode string. + +Postprocessors are run after the ElementTree has been serialized back into +Unicode text. For example, this may be an appropriate place to add a table of +contents to a document: + + class TocPostprocessor(markdown.postprocessors.Postprocessor): + def run(self, text): + return MYMARKERRE.sub(MyToc, text) + +<h3 id="blockparser">BlockParser</h3> + +Sometimes, pre/tree/postprocessors and Inline Patterns aren't going to do what +you need. Perhaps you want a new type of block type that needs to be integrated +into the core parsing. In such a situation, you can add/change/remove +functionality of the core ``BlockParser``. The BlockParser is composed of a +number of Blockproccessors. The BlockParser steps through each block of text +(split by blank lines) and passes each block to the appropriate Blockprocessor. +That Blockprocessor parses the block and adds it to the ElementTree. The +[[Definition Lists]] extension would be a good example of an extension that +adds/modifies Blockprocessors. + +A Blockprocessor should inherit from ``markdown.blockprocessors.BlockProcessor`` +and implement both the ``test`` and ``run`` methods. + +The ``test`` method is used by BlockParser to identify the type of block. +Therefore the ``test`` method must return a boolean value. If the test returns +``True``, then the BlockParser will call that Blockprocessor's ``run`` method. +If it returns ``False``, the BlockParser will move on to the next +BlockProcessor. + +The **``test``** method takes two arguments: + +* **``parent``**: The parent etree Element of the block. This can be useful as + the block may need to be treated differently if it is inside a list, for + example. + +* **``block``**: A string of the current block of text. The test may be a + simple string method (such as ``block.startswith(some_text)``) or a complex + regular expression. + +The **``run``** method takes two arguments: + +* **``parent``**: A pointer to the parent etree Element of the block. The run + method will most likely attach additional nodes to this parent. Note that + nothing is returned by the method. The Elementree object is altered in place. + +* **``blocks``**: A list of all remaining blocks of the document. Your run + method must remove (pop) the first block from the list (which it altered in + place - not returned) and parse that block. You may find that a block of text + legitimately contains multiple block types. Therefore, after processing the + first type, your processor can insert the remaining text into the beginning + of the ``blocks`` list for future parsing. + +Please be aware that a single block can span multiple text blocks. For example, +The official Markdown syntax rules state that a blank line does not end a +Code Block. If the next block of text is also indented, then it is part of +the previous block. Therefore, the BlockParser was specifically designed to +address these types of situations. If you notice the ``CodeBlockProcessor``, +in the core, you will note that it checks the last child of the ``parent``. +If the last child is a code block (``<pre><code>...</code></pre>``), then it +appends that block to the previous code block rather than creating a new +code block. + +Each BlockProcessor has the following utility methods available: + +* **``lastChild(parent)``**: + + Returns the last child of the given etree Element or ``None`` if it had no + children. + +* **``detab(text)``**: + + Removes one level of indent (four spaces by default) from the front of each + line of the given text string. + +* **``looseDetab(text, level)``**: + + Removes "level" levels of indent (defaults to 1) from the front of each line + of the given text string. However, this methods allows secondary lines to + not be indented as does some parts of the Markdown syntax. + +Each BlockProcessor also has a pointer to the containing BlockParser instance at +``self.parser``, which can be used to check or alter the state of the parser. +The BlockParser tracks it's state in a stack at ``parser.state``. The state +stack is an instance of the ``State`` class. + +**``State``** is a subclass of ``list`` and has the additional methods: + +* **``set(state)``**: + + Set a new state to string ``state``. The new state is appended to the end + of the stack. + +* **``reset()``**: + + Step back one step in the stack. The last state at the end is removed from + the stack. + +* **``isstate(state)``**: + + Test that the top (current) level of the stack is of the given string + ``state``. + +Note that to ensure that the state stack doesn't become corrupted, each time a +state is set for a block, that state *must* be reset when the parser finishes +parsing that block. + +An instance of the **``BlockParser``** is found at ``Markdown.parser``. +``BlockParser`` has the following methods: + +* **``parseDocument(lines)``**: + + Given a list of lines, an ElementTree object is returned. This should be + passed an entire document and is the only method the ``Markdown`` class + calls directly. + +* **``parseChunk(parent, text)``**: + + Parses a chunk of markdown text composed of multiple blocks and attaches + those blocks to the ``parent`` Element. The ``parent`` is altered in place + and nothing is returned. Extensions would most likely use this method for + block parsing. + +* **``parseBlocks(parent, blocks)``**: + + Parses a list of blocks of text and attaches those blocks to the ``parent`` + Element. The ``parent`` is altered in place and nothing is returned. This + method will generally only be used internally to recursively parse nested + blocks of text. + +While is is not recommended, an extension could subclass or completely replace +the ``BlockParser``. The new class would have to provide the same public API. +However, be aware that other extensions may expect the core parser provided +and will not work with such a drastically different parser. + +<h3 id="working_with_et">Working with the ElementTree</h3> + +As mentioned, the Markdown parser converts a source document to an +[ElementTree][] object before serializing that back to Unicode text. +Markdown has provided some helpers to ease that manipulation within the context +of the Markdown module. + +First, to get access to the ElementTree module import ElementTree from +``markdown`` rather than importing it directly. This will ensure you are using +the same version of ElementTree as markdown. The module is named ``etree`` +within Markdown. + + from markdown import etree + +``markdown.etree`` tries to import ElementTree from any known location, first +as a standard library module (from ``xml.etree`` in Python 2.5), then as a third +party package (``Elementree``). In each instance, ``cElementTree`` is tried +first, then ``ElementTree`` if the faster C implementation is not available on +your system. + +Sometimes you may want text inserted into an element to be parsed by +[InlinePatterns][]. In such a situation, simply insert the text as you normally +would and the text will be automatically run through the InlinePatterns. +However, if you do *not* want some text to be parsed by InlinePatterns, +then insert the text as an ``AtomicString``. + + some_element.text = markdown.AtomicString(some_text) + +Here's a basic example which creates an HTML table (note that the contents of +the second cell (``td2``) will be run through InlinePatterns latter): + + table = etree.Element("table") + table.set("cellpadding", "2") # Set cellpadding to 2 + tr = etree.SubElement(table, "tr") # Add child tr to table + td1 = etree.SubElement(tr, "td") # Add child td1 to tr + td1.text = markdown.AtomicString("Cell content") # Add plain text content + td2 = etree.SubElement(tr, "td") # Add second td to tr + td2.text = "*text* with **inline** formatting." # Add markup text + table.tail = "Text after table" # Add text after table + +You can also manipulate an existing tree. Consider the following example which +adds a ``class`` attribute to ``<a>`` elements: + + def set_link_class(self, element): + for child in element: + if child.tag == "a": + child.set("class", "myclass") #set the class attribute + set_link_class(child) # run recursively on children + +For more information about working with ElementTree see the ElementTree +[Documentation](http://effbot.org/zone/element-index.htm) +([Python Docs](http://docs.python.org/lib/module-xml.etree.ElementTree.html)). + +<h3 id="integrating_into_markdown">Integrating Your Code Into Markdown</h3> + +Once you have the various pieces of your extension built, you need to tell +Markdown about them and ensure that they are run in the proper sequence. +Markdown accepts a ``Extension`` instance for each extension. Therefore, you +will need to define a class that extends ``markdown.Extension`` and over-rides +the ``extendMarkdown`` method. Within this class you will manage configuration +options for your extension and attach the various processors and patterns to +the Markdown instance. + +It is important to note that the order of the various processors and patterns +matters. For example, if we replace ``http://...`` links with <a> elements, and +*then* try to deal with inline html, we will end up with a mess. Therefore, +the various types of processors and patterns are stored within an instance of +the Markdown class in [OrderedDict][]s. Your ``Extension`` class will need to +manipulate those OrderedDicts appropriately. You may insert instances of your +processors and patterns into the appropriate location in an OrderedDict, remove +a built-in instance, or replace a built-in instance with your own. + +<h4 id="extendmarkdown">extendMarkdown</h4> + +The ``extendMarkdown`` method of a ``markdown.Extension`` class accepts two +arguments: + +* **``md``**: + + A pointer to the instance of the Markdown class. You should use this to + access the [OrderedDict][]s of processors and patterns. They are found + under the following attributes: + + * ``md.preprocessors`` + * ``md.inlinePatterns`` + * ``md.parser.blockprocessors`` + * ``md.treepreprocessors`` + * ``md.postprocessors`` + + Some other things you may want to access in the markdown instance are: + + * ``md.htmlStash`` + * ``md.output_formats`` + * ``md.set_output_format()`` + * ``md.registerExtension()`` + +* **``md_globals``**: + + Contains all the various global variables within the markdown module. + +Of course, with access to those items, theoretically you have the option to +changing anything through various [monkey_patching][] techniques. However, you +should be aware that the various undocumented or private parts of markdown +may change without notice and your monkey_patches may break with a new release. +Therefore, what you really should be doing is inserting processors and patterns +into the markdown pipeline. Consider yourself warned. + +[monkey_patching]: http://en.wikipedia.org/wiki/Monkey_patch + +A simple example: + + class MyExtension(markdown.Extension): + def extendMarkdown(self, md, md_globals): + # Insert instance of 'mypattern' before 'references' pattern + md.inlinePatterns.add('mypattern', MyPattern(md), '<references') + +<h4 id="ordereddict">OrderedDict</h4> + +An OrderedDict is a dictionary like object that retains the order of it's +items. The items are ordered in the order in which they were appended to +the OrderedDict. However, an item can also be inserted into the OrderedDict +in a specific location in relation to the existing items. + +Think of OrderedDict as a combination of a list and a dictionary as it has +methods common to both. For example, you can get and set items using the +``od[key] = value`` syntax and the methods ``keys()``, ``values()``, and +``items()`` work as expected with the keys, values and items returned in the +proper order. At the same time, you can use ``insert()``, ``append()``, and +``index()`` as you would with a list. + +Generally speaking, within Markdown extensions you will be using the special +helper method ``add()`` to add additional items to an existing OrderedDict. + +The ``add()`` method accepts three arguments: + +* **``key``**: A string. The key is used for later reference to the item. + +* **``value``**: The object instance stored in this item. + +* **``location``**: Optional. The items location in relation to other items. + + Note that the location can consist of a few different values: + + * The special strings ``"_begin"`` and ``"_end"`` insert that item at the + beginning or end of the OrderedDict respectively. + + * A less-than sign (``<``) followed by an existing key (i.e.: + ``"<somekey"``) inserts that item before the existing key. + + * A greater-than sign (``>``) followed by an existing key (i.e.: + ``">somekey"``) inserts that item after the existing key. + +Consider the following example: + + >>> import markdown + >>> od = markdown.OrderedDict() + >>> od['one'] = 1 # The same as: od.add('one', 1, '_begin') + >>> od['three'] = 3 # The same as: od.add('three', 3, '>one') + >>> od['four'] = 4 # The same as: od.add('four', 4, '_end') + >>> od.items() + [("one", 1), ("three", 3), ("four", 4)] + +Note that when building an OrderedDict in order, the extra features of the +``add`` method offer no real value and are not necessary. However, when +manipulating an existing OrderedDict, ``add`` can be very helpful. So let's +insert another item into the OrderedDict. + + >>> od.add('two', 2, '>one') # Insert after 'one' + >>> od.values() + [1, 2, 3, 4] + +Now let's insert another item. + + >>> od.add('twohalf', 2.5, '<three') # Insert before 'three' + >>> od.keys() + ["one", "two", "twohalf", "three", "four"] + +Note that we also could have set the location of "twohalf" to be 'after two' +(i.e.: ``'>two'``). However, it's unlikely that you will have control over the +order in which extensions will be loaded, and this could affect the final +sorted order of an OrderedDict. For example, suppose an extension adding +'twohalf' in the above examples was loaded before a separate extension which +adds 'two'. You may need to take this into consideration when adding your +extension components to the various markdown OrderedDicts. + +Once an OrderedDict is created, the items are available via key: + + MyNode = od['somekey'] + +Therefore, to delete an existing item: + + del od['somekey'] + +To change the value of an existing item (leaving location unchanged): + + od['somekey'] = MyNewObject() + +To change the location of an existing item: + + t.link('somekey', '<otherkey') + +<h4 id="registerextension">registerExtension</h4> + +Some extensions may need to have their state reset between multiple runs of the +Markdown class. For example, consider the following use of the [[Footnotes]] +extension: + + md = markdown.Markdown(extensions=['footnotes']) + html1 = md.convert(text_with_footnote) + md.reset() + html2 = md.convert(text_without_footnote) + +Without calling ``reset``, the footnote definitions from the first document will +be inserted into the second document as they are still stored within the class +instance. Therefore the ``Extension`` class needs to define a ``reset`` method +that will reset the state of the extension (i.e.: ``self.footnotes = {}``). +However, as many extensions do not have a need for ``reset``, ``reset`` is only +called on extensions that are registered. + +To register an extension, call ``md.registerExtension`` from within your +``extendMarkdown`` method: + + + def extendMarkdown(self, md, md_globals): + md.registerExtension(self) + # insert processors and patterns here + +Then, each time ``reset`` is called on the Markdown instance, the ``reset`` +method of each registered extension will be called as well. You should also +note that ``reset`` will be called on each registered extension after it is +initialized the first time. Keep that in mind when over-riding the extension's +``reset`` method. + +<h4 id="configsettings">Config Settings</h4> + +If an extension uses any parameters that the user may want to change, +those parameters should be stored in ``self.config`` of your +``markdown.Extension`` class in the following format: + + self.config = {parameter_1_name : [value1, description1], + parameter_2_name : [value2, description2] } + +When stored this way the config parameters can be over-ridden from the +command line or at the time Markdown is initiated: + + markdown.py -x myextension(SOME_PARAM=2) inputfile.txt > output.txt + +Note that parameters should always be assumed to be set to string +values, and should be converted at run time. For example: + + i = int(self.getConfig("SOME_PARAM")) + +<h4 id="makeextension">makeExtension</h4> + +Each extension should ideally be placed in its own module starting +with the ``mdx_`` prefix (e.g. ``mdx_footnotes.py``). The module must +provide a module-level function called ``makeExtension`` that takes +an optional parameter consisting of a dictionary of configuration over-rides +and returns an instance of the extension. An example from the footnote +extension: + + def makeExtension(configs=None) : + return FootnoteExtension(configs=configs) + +By following the above example, when Markdown is passed the name of your +extension as a string (i.e.: ``'footnotes'``), it will automatically import +the module and call the ``makeExtension`` function initiating your extension. + +You may have noted that the extensions packaged with Python-Markdown do not +use the ``mdx_`` prefix in their module names. This is because they are all +part of the ``markdown.extensions`` package. Markdown will first try to import +from ``markdown.extensions.extname`` and upon failure, ``mdx_extname``. If both +fail, Markdown will continue without the extension. + +However, Markdown will also accept an already existing instance of an extension. +For example: + + import markdown + import myextension + configs = {...} + myext = myextension.MyExtension(configs=configs) + md = markdown.Markdown(extensions=[myext]) + +This is useful if you need to implement a large number of extensions with more +than one residing in a module. + +[Preprocessors]: #preprocessors +[InlinePatterns]: #inlinepatterns +[Treeprocessors]: #treeprocessors +[Postprocessors]: #postprocessors +[BlockParser]: #blockparser +[Working with the ElementTree]: #working_with_et +[Integrating your code into Markdown]: #integrating_into_markdown +[extendMarkdown]: #extendmarkdown +[OrderedDict]: #ordereddict +[registerExtension]: #registerextension +[Config Settings]: #configsettings +[makeExtension]: #makeextension +[ElementTree]: http://effbot.org/zone/element-index.htm |