aboutsummaryrefslogtreecommitdiffstats
path: root/mdx
diff options
context:
space:
mode:
authorWaylan Limberg <waylan@gmail.com>2008-08-11 20:12:28 -0400
committerWaylan Limberg <waylan@gmail.com>2008-08-11 20:12:28 -0400
commitf9bc5d2b86a94fb98e791966bb26e1abd5ef0ed2 (patch)
tree217d79e69b8972c0c4fb830a36b6b7524e615000 /mdx
parent2783134621439aaa1130a1b73da36b335c6b0361 (diff)
downloadmarkdown-f9bc5d2b86a94fb98e791966bb26e1abd5ef0ed2.tar.gz
markdown-f9bc5d2b86a94fb98e791966bb26e1abd5ef0ed2.tar.bz2
markdown-f9bc5d2b86a94fb98e791966bb26e1abd5ef0ed2.zip
renamed extension module and set import to extension module first, then mdx_filename
Diffstat (limited to 'mdx')
-rw-r--r--mdx/__init__.py0
-rw-r--r--mdx/mdx_codehilite.py218
-rw-r--r--mdx/mdx_extra.py52
-rw-r--r--mdx/mdx_fenced_code.py105
-rw-r--r--mdx/mdx_footnotes.py276
-rw-r--r--mdx/mdx_headerid.py202
-rw-r--r--mdx/mdx_imagelinks.py135
-rw-r--r--mdx/mdx_meta.py81
-rw-r--r--mdx/mdx_rss.py118
-rw-r--r--mdx/mdx_tables.py72
-rw-r--r--mdx/mdx_wikilink.py140
11 files changed, 0 insertions, 1399 deletions
diff --git a/mdx/__init__.py b/mdx/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/mdx/__init__.py
+++ /dev/null
diff --git a/mdx/mdx_codehilite.py b/mdx/mdx_codehilite.py
deleted file mode 100644
index 73c1a79..0000000
--- a/mdx/mdx_codehilite.py
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/usr/bin/python
-
-"""
-CodeHilite Extension for Python-Markdown
-=======================================
-
-Adds code/syntax highlighting to standard Python-Markdown code blocks.
-
-By [Waylan Limberg](http://achinghead.com/).
-
-Project website: http://achinghead.com/markdown-wikilinks/
-Contact: waylan [at] gmail [dot] com
-
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
-
-Version: 0.2 (April 30, 2008)
-
-Dependencies:
-* [Python 2.3+](http://python.org/)
-* [Markdown 1.7+](http://www.freewisdom.org/projects/python-markdown/)
-* [Pygments](http://pygments.org/)
-
-"""
-
-import markdown
-
-# --------------- CONSTANTS YOU MIGHT WANT TO MODIFY -----------------
-
-try:
- TAB_LENGTH = markdown.TAB_LENGTH
-except AttributeError:
- TAB_LENGTH = 4
-
-
-# ------------------ The Main CodeHilite Class ----------------------
-class CodeHilite:
- """
- Determine language of source code, and pass it into the pygments hilighter.
-
- Basic Usage:
- >>> code = CodeHilite(src = text)
- >>> html = code.hilite()
-
- * src: Can be a string or any object with a .readline attribute.
-
- * linenos: (Boolen) Turns line numbering 'on' or 'off' (off by default).
-
- Low Level Usage:
- >>> code = CodeHilite()
- >>> code.src = text # String or anything with a .readline attribute
- >>> code.linenos = True # True or False; Turns line numbering on or of.
- >>> html = code.hilite()
-
- """
-
- def __init__(self, src=None, linenos = False):
- self.src = src
- self.lang = None
- self.linenos = linenos
-
- def hilite(self):
- """
- Pass code to the [Pygments](http://pygments.pocoo.org/) highliter with
- optional line numbers. The output should then be styled with css to
- your liking. No styles are applied by default - only styling hooks
- (i.e.: <span class="k">).
-
- returns : A string of html.
-
- """
-
- self.src = self.src.strip('\n')
-
- self._getLang()
-
- try:
- from pygments import highlight
- from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer
- from pygments.formatters import HtmlFormatter
- except ImportError:
- # just escape and pass through
- txt = self._escape(self.src)
- '''if num:
- txt = self._number(txt)
- else :
- txt = '<div class="codehilite"><pre>%s</pre></div>\n'% txt'''
- txt = self._number(txt)
- return txt
- else:
- try:
- lexer = get_lexer_by_name(self.lang)
- except ValueError:
- try:
- lexer = guess_lexer(self.src)
- except ValueError:
- lexer = TextLexer()
- formatter = HtmlFormatter(linenos=self.linenos, cssclass="codehilite")
- return highlight(self.src, lexer, formatter)
-
- def _escape(self, txt):
- """ basic html escaping """
- txt = txt.replace('&', '&amp;')
- txt = txt.replace('<', '&lt;')
- txt = txt.replace('>', '&gt;')
- txt = txt.replace('"', '&quot;')
- return txt
-
- def _number(self, txt):
- """ Use <ol> for line numbering """
- # Fix Whitespace
- txt = txt.replace('\t', ' '*TAB_LENGTH)
- txt = txt.replace(" "*4, "&nbsp; &nbsp; ")
- txt = txt.replace(" "*3, "&nbsp; &nbsp;")
- txt = txt.replace(" "*2, "&nbsp; ")
-
- # Add line numbers
- lines = txt.splitlines()
- txt = '<div class="codehilite"><pre><ol>\n'
- for line in lines:
- txt += '\t<li>%s</li>\n'% line
- txt += '</ol></pre></div>\n'
- return txt
-
-
- def _getLang(self):
- """
- Determines language of a code block from shebang lines and whether said
- line should be removed or left in place. If the sheband line contains a
- path (even a single /) then it is assumed to be a real shebang lines and
- left alone. However, if no path is given (e.i.: #!python or :::python)
- then it is assumed to be a mock shebang for language identifitation of a
- code fragment and removed from the code block prior to processing for
- code highlighting. When a mock shebang (e.i: #!python) is found, line
- numbering is turned on. When colons are found in place of a shebang
- (e.i.: :::python), line numbering is left in the current state - off
- by default.
-
- """
-
- import re
-
- #split text into lines
- lines = self.src.split("\n")
- #pull first line to examine
- fl = lines.pop(0)
-
- c = re.compile(r'''
- (?:(?:::+)|(?P<shebang>[#]!)) #shebang or 2 or more colons
- (?P<path>(?:/\w+)*[/ ])? # zero or 1 path ending in either a / or a single space
- (?P<lang>\w*) # the language (a single / or space before lang is a path)
- ''', re.VERBOSE)
- # search first line for shebang
- m = c.search(fl)
- if m:
- # we have a match
- try:
- self.lang = m.group('lang').lower()
- except IndexError:
- self.lang = None
- if m.group('path'):
- # path exists - restore first line
- lines.insert(0, fl)
- if m.group('shebang'):
- # shebang exists - use line numbers
- self.linenos = True
- else:
- # No match
- lines.insert(0, fl)
-
- self.src = "\n".join(lines).strip("\n")
-
-
-
-# ------------------ The Markdown Extension -------------------------------
-class CodeHiliteExtention(markdown.Extension):
- def __init__(self, configs):
- # define default configs
- self.config = {
- 'force_linenos' : [False, "Force line numbers - Default: False"]
- }
-
- # Override defaults with user settings
- for key, value in configs:
- # self.config[key][0] = value
- self.setConfig(key, value)
-
- def extendMarkdown(self, md, md_globals):
-
- def _hiliteCodeBlock(parent_elem, lines, inList):
- """
- Overrides `_processCodeBlock` method in standard Markdown class
- and sends code blocks to a code highlighting proccessor. The result
- is then stored in the HtmlStash, a placeholder is inserted into
- the dom and the remainder of the text file is processed recursively.
-
- * parent_elem: DOM element to which the content will be added
- * lines: a list of lines
- * inList: a level
-
- returns: None
-
- """
-
- detabbed, theRest = md.blockGuru.detectTabbed(lines)
- text = "\n".join(detabbed).rstrip()+"\n"
- code = CodeHilite(text, linenos=self.config['force_linenos'][0])
- placeholder = md.htmlStash.store(code.hilite(), safe=True)
- if parent_elem.text:
- parent_elem.text += placeholder
- else:
- parent_elem.text = placeholder
- md._processSection(parent_elem, theRest, inList)
-
- md._processCodeBlock = _hiliteCodeBlock
-
-def makeExtension(configs={}):
- return CodeHiliteExtention(configs=configs)
-
diff --git a/mdx/mdx_extra.py b/mdx/mdx_extra.py
deleted file mode 100644
index e99bec4..0000000
--- a/mdx/mdx_extra.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-"""
-Python-Markdown Extra Extension
-===============================
-
-A compilation of various Python-Markdown extensions that imitates
-[PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/).
-
-As no-one has yet written a Definition List extension for Python-
-Markdown, definition lists are not yet supported by Extra.
-
-Note that each of the individual extensions still need to be available
-on your PYTHONPATH. This extension simply wraps them all up as a
-convenience so that only one extension needs to be listed when
-initiating Markdown. See the documentation for each individual
-extension for specifics about that extension.
-
-In the 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 differant name. You could also edit the `extensions` global
-variable defined below, but be aware that such changes may be lost
-when you upgrade to any future version of Python-Markdown.
-
-"""
-
-import markdown
-
-extensions = ['fenced_code',
- 'footnotes',
- 'headerid',
- 'tables',
- 'abbr',
- ]
-
-
-class ExtraExtension(markdown.Extension):
- """ Add various extensions to Markdown class."""
-
- def extendMarkdown(self, md, md_globals):
- """ Register extension instances. """
- md.registerExtensions(extensions, self.config)
-
-def makeExtension(configs={}):
- return ExtraExtension(configs=dict(configs))
diff --git a/mdx/mdx_fenced_code.py b/mdx/mdx_fenced_code.py
deleted file mode 100644
index c3d9f7f..0000000
--- a/mdx/mdx_fenced_code.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Fenced Code Extension for Python Markdown
-=========================================
-
-This extension adds Fenced Code Blocks to Python-Markdown.
-
- >>> import markdown
- >>> text = '''
- ... A paragraph before a fenced code block:
- ...
- ... ~~~
- ... Fenced code block
- ... ~~~
- ... '''
- >>> html = markdown.markdown(text, extensions=['fenced_code'])
- >>> html
- u'<p>A paragraph before a fenced code block:\\n</p>\\n<pre><code>Fenced code block\\n</code></pre>'
-
-Works with safe_mode also (we check this because we are using the HtmlStash):
-
- >>> markdown.markdown(text, extensions=['fenced_code'], safe_mode='replace')
- u'<p>A paragraph before a fenced code block:\\n</p>\\n<pre><code>Fenced code block\\n</code></pre>'
-
-Include tilde's in a code block and wrap with blank lines:
-
- >>> text = '''
- ... ~~~~~~~~
- ...
- ... ~~~~
- ...
- ... ~~~~~~~~'''
- >>> markdown.markdown(text, extensions=['fenced_code'])
- u'<pre><code>\\n~~~~\\n\\n</code></pre>'
-
-Multiple blocks and language tags:
-
- >>> text = '''
- ... ~~~~
- ... block one
- ... ~~~~{.python}
- ...
- ... ~~~~
- ... <p>block two</p>
- ... ~~~~{.html}'''
- >>> markdown.markdown(text, extensions=['fenced_code'])
- u'<pre><code class="python">block one\\n</code></pre>\\n\\n<pre><code class="html">&lt;p&gt;block two&lt;/p&gt;\\n</code></pre>'
-
-"""
-
-import markdown, re
-
-# Global vars
-FENCED_BLOCK_RE = re.compile( \
- r'(?P<fence>^~{3,})[ ]*\n(?P<code>.*?)(?P=fence)[ ]*(\{\.(?P<lang>[a-zA-Z0-9_-]*)\})?[ ]*$',
- re.MULTILINE|re.DOTALL
- )
-CODE_WRAP = '<pre><code%s>%s</code></pre>'
-LANG_TAG = ' class="%s"'
-
-
-class FencedCodeExtension(markdown.Extension):
-
- def extendMarkdown(self, md, md_globals):
- """ Add FencedBlockPreprocessor to the Markdown instance. """
-
- FENCED_BLOCK_PREPROCESSOR = FencedBlockPreprocessor()
- FENCED_BLOCK_PREPROCESSOR.md = md
- md.textPreprocessors.insert(0, FENCED_BLOCK_PREPROCESSOR)
-
-
-class FencedBlockPreprocessor(markdown.TextPreprocessor):
-
- def run(self, text):
- """ Match and store Fenced Code Blocks in the HtmlStash. """
- while 1:
- m = FENCED_BLOCK_RE.search(text)
- if m:
- lang = ''
- if m.group('lang'):
- lang = LANG_TAG % m.group('lang')
- code = CODE_WRAP % (lang, self._escape(m.group('code')))
- placeholder = self.md.htmlStash.store(code, safe=True)
- text = '%s\n%s\n%s'% (text[:m.start()], placeholder, text[m.end():])
- else:
- break
- return text
-
- def _escape(self, txt):
- """ basic html escaping """
- txt = txt.replace('&', '&amp;')
- txt = txt.replace('<', '&lt;')
- txt = txt.replace('>', '&gt;')
- txt = txt.replace('"', '&quot;')
- return txt
-
-
-def makeExtension(configs=None):
- return FencedCodeExtension()
-
-
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
diff --git a/mdx/mdx_footnotes.py b/mdx/mdx_footnotes.py
deleted file mode 100644
index b46efbb..0000000
--- a/mdx/mdx_footnotes.py
+++ /dev/null
@@ -1,276 +0,0 @@
-"""
-========================= FOOTNOTES =================================
-
-This section adds footnote handling to markdown. It can be used as
-an example for extending python-markdown with relatively complex
-functionality. While in this case the extension is included inside
-the module itself, it could just as easily be added from outside the
-module. Not that all markdown classes above are ignorant about
-footnotes. All footnote functionality is provided separately and
-then added to the markdown instance at the run time.
-
-Footnote functionality is attached by calling extendMarkdown()
-method of FootnoteExtension. The method also registers the
-extension to allow it's state to be reset by a call to reset()
-method.
-
-Example:
- Footnotes[^1] have a label[^label] and a definition[^!DEF].
-
- [^1]: This is a footnote
- [^label]: A footnote on "label"
- [^!DEF]: The footnote for definition
-
-"""
-
-FN_BACKLINK_TEXT = "zz1337820767766393qq"
-
-
-import re, markdown, random
-from markdown import etree
-
-class FootnoteExtension (markdown.Extension):
-
- DEF_RE = re.compile(r'(\ ?\ ?\ ?)\[\^([^\]]*)\]:\s*(.*)')
- SHORT_USE_RE = re.compile(r'\[\^([^\]]*)\]', re.M) # [^a]
-
- def __init__ (self, configs) :
-
- self.config = {'PLACE_MARKER' :
- ["///Footnotes Go Here///",
- "The text string that marks where the footnotes go"]}
-
- for key, value in configs :
- self.config[key][0] = value
-
- self.reset()
-
- def extendMarkdown(self, md, md_globals) :
-
- self.md = md
-
- # Stateless extensions do not need to be registered
- md.registerExtension(self)
-
- # Insert a preprocessor before ReferencePreprocessor
- index = md.preprocessors.index(md_globals['REFERENCE_PREPROCESSOR'])
- preprocessor = FootnotePreprocessor(self)
- preprocessor.md = md
- md.preprocessors.insert(index, preprocessor)
-
- # Insert an inline pattern before ImageReferencePattern
- FOOTNOTE_RE = r'\[\^([^\]]*)\]' # blah blah [^1] blah
- index = md.inlinePatterns.index(md_globals['IMAGE_REFERENCE_PATTERN'])
- md.inlinePatterns.insert(index, FootnotePattern(FOOTNOTE_RE, self))
-
- # Insert a post-processor that would actually add the footnote div
- postprocessor = FootnotePostprocessor(self)
- postprocessor.extension = self
-
- md.postprocessors.append(postprocessor)
-
- textPostprocessor = FootnoteTextPostprocessor(self)
-
- md.textPostprocessors.append(textPostprocessor)
-
-
- def reset(self) :
- # May be called by Markdown is state reset is desired
-
- self.footnote_suffix = "-" + str(int(random.random()*1000000000))
- self.used_footnotes={}
- self.footnotes = {}
-
- def findFootnotesPlaceholder(self, root):
-
- def finder(element):
- for child in element:
- if child.text:
- if child.text.find(self.getConfig("PLACE_MARKER")) > -1:
- return child, True
- if child.tail:
- if child.tail.find(self.getConfig("PLACE_MARKER")) > -1:
- return (child, element), False
- finder(child)
- return None
-
- res = finder(root)
- return res
-
-
- def setFootnote(self, id, text) :
- self.footnotes[id] = text
-
- def makeFootnoteId(self, num) :
- return 'fn%d%s' % (num, self.footnote_suffix)
-
- def makeFootnoteRefId(self, num) :
- return 'fnr%d%s' % (num, self.footnote_suffix)
-
- def makeFootnotesDiv (self, root) :
- """Creates the div with class='footnote' and populates it with
- the text of the footnotes.
-
- @returns: the footnote div as a dom element """
-
- if not self.footnotes.keys() :
- return None
-
- div = etree.Element("div")
- div.set('class', 'footnote')
- hr = etree.SubElement(div, "hr")
- ol = etree.SubElement(div, "ol")
-
-
- footnotes = [(self.used_footnotes[id], id)
- for id in self.footnotes.keys()]
- footnotes.sort()
-
- for i, id in footnotes :
- li = etree.SubElement(ol, "li")
- li.set("id", self.makeFootnoteId(i))
-
- self.md._processSection(li, self.footnotes[id].split("\n"), looseList=1)
-
- backlink = etree.Element("a")
- backlink.set("href", "#" + self.makeFootnoteRefId(i))
- backlink.set("class", "footnoteBackLink")
- backlink.set("title",
- "Jump back to footnote %d in the text" % i)
- backlink.text = FN_BACKLINK_TEXT
-
- if li.getchildren():
- node = li[-1]
- if node.text:
- li.append(backlink)
- elif node.tag == "p":
- node.append(backlink)
- else:
- p = etree.SubElement(li, "p")
- p.append(backlink)
- div = self.md.applyInlinePatterns(etree.ElementTree(div)).getroot()
- return div
-
-
-class FootnotePreprocessor :
-
- def __init__ (self, footnotes) :
- self.footnotes = footnotes
-
- def run(self, lines) :
-
- self.blockGuru = markdown.BlockGuru()
- lines = self._handleFootnoteDefinitions (lines)
-
- # Make a hash of all footnote marks in the text so that we
- # know in what order they are supposed to appear. (This
- # function call doesn't really substitute anything - it's just
- # a way to get a callback for each occurence.
-
- text = "\n".join(lines)
- self.footnotes.SHORT_USE_RE.sub(self.recordFootnoteUse, text)
-
- return text.split("\n")
-
-
- def recordFootnoteUse(self, match) :
-
- id = match.group(1)
- id = id.strip()
- nextNum = len(self.footnotes.used_footnotes.keys()) + 1
- self.footnotes.used_footnotes[id] = nextNum
-
-
- def _handleFootnoteDefinitions(self, lines) :
- """Recursively finds all footnote definitions in the lines.
-
- @param lines: a list of lines of text
- @returns: a string representing the text with footnote
- definitions removed """
-
- i, id, footnote = self._findFootnoteDefinition(lines)
-
- if id :
-
- plain = lines[:i]
-
- detabbed, theRest = self.blockGuru.detectTabbed(lines[i+1:])
-
- self.footnotes.setFootnote(id,
- footnote + "\n"
- + "\n".join(detabbed))
-
- more_plain = self._handleFootnoteDefinitions(theRest)
- return plain + [""] + more_plain
-
- else :
- return lines
-
- def _findFootnoteDefinition(self, lines) :
- """Finds the first line of a footnote definition.
-
- @param lines: a list of lines of text
- @returns: the index of the line containing a footnote definition """
-
- counter = 0
- for line in lines :
- m = self.footnotes.DEF_RE.match(line)
- if m :
- return counter, m.group(2), m.group(3)
- counter += 1
- return counter, None, None
-
-
-class FootnotePattern (markdown.Pattern) :
-
- def __init__ (self, pattern, footnotes) :
-
- markdown.Pattern.__init__(self, pattern)
- self.footnotes = footnotes
-
- def handleMatch(self, m) :
- sup = etree.Element("sup")
- a = etree.SubElement(sup, "a")
- id = m.group(2)
- num = self.footnotes.used_footnotes[id]
- sup.set('id', self.footnotes.makeFootnoteRefId(num))
- a.set('href', '#' + self.footnotes.makeFootnoteId(num))
- a.text = str(num)
- return sup
-
-class FootnotePostprocessor (markdown.Postprocessor):
-
- def __init__ (self, footnotes) :
- self.footnotes = footnotes
-
- def run(self, root):
- footnotesDiv = self.footnotes.makeFootnotesDiv(root)
- if footnotesDiv:
- result = self.extension.findFootnotesPlaceholder(root)
-
- if result:
- node, isText = result
- if isText:
- node.text = None
- node.getchildren().insert(0, footnotesDiv)
- else:
- child, element = node
- ind = element.getchildren().find(child)
- element.getchildren().insert(ind + 1, footnotesDiv)
- child.tail = None
-
- fnPlaceholder.parent.replaceChild(fnPlaceholder, footnotesDiv)
- else :
- root.append(footnotesDiv)
-
-class FootnoteTextPostprocessor (markdown.Postprocessor):
-
- def __init__ (self, footnotes) :
- self.footnotes = footnotes
-
- def run(self, text) :
- return text.replace(FN_BACKLINK_TEXT, "&#8617;")
-
-def makeExtension(configs=[]):
- return FootnoteExtension(configs=configs)
-
diff --git a/mdx/mdx_headerid.py b/mdx/mdx_headerid.py
deleted file mode 100644
index 8947338..0000000
--- a/mdx/mdx_headerid.py
+++ /dev/null
@@ -1,202 +0,0 @@
-#!/usr/bin/python
-
-"""
-HeaderID Extension for Python-Markdown
-======================================
-
-Adds ability to set HTML IDs for headers.
-
-Basic usage:
-
- >>> import markdown
- >>> text = "# Some Header # {#some_id}"
- >>> md = markdown.markdown(text, ['headerid'])
- >>> md
- u'<h1 id="some_id">Some Header</h1>'
-
-All header IDs are unique:
-
- >>> text = '''
- ... #Header
- ... #Another Header {#header}
- ... #Third Header {#header}'''
- >>> md = markdown.markdown(text, ['headerid'])
- >>> md
- u'<h1 id="header">Header</h1>\\n\\n<h1 id="header_1">Another Header</h1>\\n\\n<h1 id="header_2">Third Header</h1>'
-
-To fit within a html template's hierarchy, set the header base level:
-
- >>> text = '''
- ... #Some Header
- ... ## Next Level'''
- >>> md = markdown.markdown(text, ['headerid(level=3)'])
- >>> md
- u'<h3 id="some_header">Some Header</h3>\\n\\n<h4 id="next_level">Next Level</h4>'
-
-Turn off auto generated IDs:
-
- >>> text = '''
- ... # Some Header
- ... # Header with ID # { #foo }'''
- >>> md = markdown.markdown(text, ['headerid(forceid=False)'])
- >>> md
- u'<h1>Some Header</h1>\\n\\n<h1 id="foo">Header with ID</h1>'
-
-Use with MetaData extension:
-
- >>> text = '''header_level: 2
- ... header_forceid: Off
- ...
- ... # A Header'''
- >>> md = markdown.markdown(text, ['headerid', 'meta'])
- >>> md
- u'<h2>A Header</h2>'
-
-By [Waylan Limberg](http://achinghead.com/).
-
-Project website: http://achinghead.com/markdown-headerid/
-Contact: waylan [at] gmail [dot] com
-
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
-
-Version: 0.1 (May 2, 2008)
-
-Dependencies:
-* [Python 2.3+](http://python.org)
-* [Markdown 1.7+](http://www.freewisdom.org/projects/python-markdown/)
-
-"""
-
-import markdown
-from markdown import etree
-import re
-from string import ascii_lowercase, digits, punctuation
-
-ID_CHARS = ascii_lowercase + digits + '-_'
-
-HEADER_RE = re.compile(r'''^(\#{1,6}) # group(1) = string of hashes
- ( [^{^#]*) # group(2) = Header text
- [\#]* # optional closing hashes (not counted)
- (?:[ \t]*\{[ \t]*\#([-_:a-zA-Z0-9]+)[ \t]*\})? # group(3) = id attr''',
- re.VERBOSE)
-
-IDCOUNT_RE = re.compile(r'^(.*)_([0-9]+)$')
-
-class HeaderIdExtension (markdown.Extension) :
- def __init__(self, configs):
- # set defaults
- self.config = {
- 'level' : ['1', 'Base level for headers.'],
- 'forceid' : ['True', 'Force all headers to have an id.'],
- 'toc_id' : ['toc', 'Set html id of wrapper div for TOC.'],
- 'toc_marker': ['///TOC///', 'Marker to identify position of TOC.']
- }
-
- for key, value in configs:
- self.setConfig(key, value)
-
-
- def extendMarkdown(self, md, md_globals) :
-
- md.IDs = []
- md.toc = Toc(self.getConfig('toc_id'), self.getConfig('toc_marker'))
-
- def _processHeaderId(parent_elem, paragraph) :
- '''
- Overrides _processHeader of Markdown() and
- adds an 'id' to the header.
- '''
- m = HEADER_RE.match(paragraph[0])
- if m :
- start_level, force_id = _get_meta()
- level = len(m.group(1)) + start_level
- if level > 6:
- level = 6
- h = etree.Element("h%d" % level)
- parent_elem.append(h)
- inline = etree.SubElement(h, "inline")
- inline.text = m.group(2).strip()
- i = ''
- if m.group(3):
- i = _unique_id(m.group(3))
- elif force_id:
- i = _create_id(m.group(2).strip())
- if i:
- h.set('id', i)
- md.toc.append(i, inline.text)
- else :
- message(CRITICAL, "We've got a problem header!")
-
- md._processHeader = _processHeaderId
-
- def _get_meta():
- ''' Return meta data suported by this ext as a tuple '''
- level = int(self.config['level'][0]) - 1
- force = _str2bool(self.config['forceid'][0])
- if hasattr(md, 'Meta'):
- if md.Meta.has_key('header_level'):
- level = int(md.Meta['header_level'][0]) - 1
- if md.Meta.has_key('header_forceid'):
- force = _str2bool(md.Meta['header_forceid'][0])
- return level, force
-
- def _str2bool(s, default=False):
- ''' Convert a string to a booleen value. '''
- s = str(s)
- if s.lower() in ['0', 'f', 'false', 'off', 'no', 'n']:
- return False
- elif s.lower() in ['1', 't', 'true', 'on', 'yes', 'y']:
- return True
- return default
-
- def _unique_id(id):
- ''' Ensure ID is unique. Append '_1', '_2'... if not '''
- while id in md.IDs:
- m = IDCOUNT_RE.match(id)
- if m:
- id = '%s_%d'% (m.group(1), int(m.group(2))+1)
- else:
- id = '%s_%d'% (id, 1)
- md.IDs.append(id)
- return id
-
-
- def _create_id(header):
- ''' Return ID from Header text. '''
- h = ''
- for c in header.lower().replace(' ', '_'):
- if c in ID_CHARS:
- h += c
- elif c not in punctuation:
- h += '+'
- return _unique_id(h)
-
-class Toc():
- """ Store a Table of Contents from a documents Headers. """
- def __init__(self, html_id, marker):
- self.html_id = html_id
- self.marker = marker
- self.ids = []
- self.labels = []
-
- def append(self, id, label):
- """ Append an item to the store. """
- self.ids.append(id)
- self.labels.append(label)
-
- def render(self):
- """ Render the TOC as HTML and return unicode. """
- out = u'<div id="%s"><ul>\n' % self.html_id
- for c in range(len(self.ids)):
- out += u'<li><a href="#%s">%s</a></li>\n'%(self.ids[c], self.labels[c])
- out += u'</ul></div>'
- return out
-
-
-def makeExtension(configs=None) :
- return HeaderIdExtension(configs=configs)
-
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
-
diff --git a/mdx/mdx_imagelinks.py b/mdx/mdx_imagelinks.py
deleted file mode 100644
index e545b24..0000000
--- a/mdx/mdx_imagelinks.py
+++ /dev/null
@@ -1,135 +0,0 @@
-"""
-========================= IMAGE LINKS =================================
-
-
-Turns paragraphs like
-
-<~~~~~~~~~~~~~~~~~~~~~~~~
-dir/subdir
-dir/subdir
-dir/subdir
-~~~~~~~~~~~~~~
-dir/subdir
-dir/subdir
-dir/subdir
-~~~~~~~~~~~~~~~~~~~>
-
-Into mini-photo galleries.
-
-"""
-
-import re, markdown
-import url_manager
-
-
-IMAGE_LINK = """<a href="%s"><img src="%s" title="%s"/></a>"""
-SLIDESHOW_LINK = """<a href="%s" target="_blank">[slideshow]</a>"""
-ALBUM_LINK = """&nbsp;<a href="%s">[%s]</a>"""
-
-
-class ImageLinksExtension (markdown.Extension):
-
- def __init__ (self) :
- self.reset()
-
- def extendMarkdown(self, md, md_globals) :
-
- self.md = md
-
- # Stateless extensions do not need to be registered
- md.registerExtension(self)
-
- # Insert a preprocessor before all preprocessors
-
- preprocessor = ImageLinkPreprocessor()
- preprocessor.md = md
- md.preprocessors.insert(0, preprocessor)
-
- def reset(self) :
- # May be called by Markdown is state reset is desired
- pass
-
-
-class ImageLinkPreprocessor (markdown.Preprocessor):
-
- def run(self, lines) :
-
- url = url_manager.BlogEntryUrl(url_manager.BlogUrl("all"),
- "2006/08/29/the_rest_of_our")
-
-
- all_images = []
- blocks = []
- in_image_block = False
-
- new_lines = []
-
- for line in lines :
-
- if line.startswith("<~~~~~~~") :
- albums = []
- rows = []
- in_image_block = True
-
- if not in_image_block :
-
- new_lines.append(line)
-
- else :
-
- line = line.strip()
-
- if line.endswith("~~~~~~>") or not line :
- in_image_block = False
- new_block = "<div><br/><center><span class='image-links'>\n"
-
- album_url_hash = {}
-
- for row in rows :
- for photo_url, title in row :
- new_block += "&nbsp;"
- new_block += IMAGE_LINK % (photo_url,
- photo_url.get_thumbnail(),
- title)
-
- album_url_hash[str(photo_url.get_album())] = 1
-
- new_block += "<br/>"
-
- new_block += "</span>"
- new_block += SLIDESHOW_LINK % url.get_slideshow()
-
- album_urls = album_url_hash.keys()
- album_urls.sort()
-
- if len(album_urls) == 1 :
- new_block += ALBUM_LINK % (album_urls[0], "complete album")
- else :
- for i in range(len(album_urls)) :
- new_block += ALBUM_LINK % (album_urls[i],
- "album %d" % (i + 1) )
-
- new_lines.append(new_block + "</center><br/></div>")
-
- elif line[1:6] == "~~~~~" :
- rows.append([]) # start a new row
- else :
- parts = line.split()
- line = parts[0]
- title = " ".join(parts[1:])
-
- album, photo = line.split("/")
- photo_url = url.get_photo(album, photo,
- len(all_images)+1)
- all_images.append(photo_url)
- rows[-1].append((photo_url, title))
-
- if not album in albums :
- albums.append(album)
-
- return new_lines
-
-
-def makeExtension(configs) :
- return ImageLinksExtension(configs)
-
diff --git a/mdx/mdx_meta.py b/mdx/mdx_meta.py
deleted file mode 100644
index 30dea8a..0000000
--- a/mdx/mdx_meta.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!usr/bin/python
-
-'''
-Meta Data Extension for Python-Markdown
-==========================================
-
-This extension adds Meta Data handling to markdown.
-
- >>> import markdown
- >>> text = """Title: A Test Doc.
- ... Author: Waylan Limberg
- ... John Doe
- ... Blank_Data:
- ...
- ... The body. This is paragraph one.
- ... """
- >>> md = markdown.Markdown(text, ['meta'])
- >>> md.convert()
- u'<p>The body. This is paragraph one.\\n</p>'
- >>> md.Meta
- {u'blank_data': [u''], u'author': [u'Waylan Limberg', u'John Doe'], u'title': [u'A Test Doc.']}
-
-Make sure text without Meta Data still works (markdown < 1.6b returns a <p>).
-
- >>> text = ' Some Code - not extra lines of meta data.'
- >>> md = markdown.Markdown(text, ['meta'])
- >>> md.convert()
- u'<pre><code>Some Code - not extra lines of meta data.\\n</code></pre>'
- >>> md.Meta
- {}
-
-'''
-
-import markdown, re
-
-# Global Vars
-META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
-META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)')
-
-class MetaExtension (markdown.Extension) :
- def __init__(self, configs):
- pass
-
- def extendMarkdown(self, md, md_globals) :
- self.md = md
-
- # Insert meta preprocessor first
- META_PREPROCESSOR = MetaPreprocessor()
- META_PREPROCESSOR.md = md
- md.preprocessors.insert(0, META_PREPROCESSOR)
-
-class MetaPreprocessor(markdown.Preprocessor) :
- def run(self, lines) :
- meta = {}
- key = None
- while 1:
- line = lines.pop(0)
- if line.strip() == '':
- break # blank line - done
- m1 = META_RE.match(line)
- if m1:
- key = m1.group('key').lower().strip()
- meta[key] = [m1.group('value').strip()]
- else:
- m2 = META_MORE_RE.match(line)
- if m2 and key:
- # Add another line to existing key
- meta[key].append(m2.group('value').strip())
- else:
- lines.insert(0, line)
- break # no meta data - done
- self.md.Meta = meta
- return lines
-
-
-def makeExtension(configs=None) :
- return MetaExtension(configs=configs)
-
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
diff --git a/mdx/mdx_rss.py b/mdx/mdx_rss.py
deleted file mode 100644
index b88b9b5..0000000
--- a/mdx/mdx_rss.py
+++ /dev/null
@@ -1,118 +0,0 @@
-import markdown
-from markdown import etree
-
-DEFAULT_URL = "http://www.freewisdom.org/projects/python-markdown/"
-DEFAULT_CREATOR = "Yuri Takhteyev"
-DEFAULT_TITLE = "Markdown in Python"
-GENERATOR = "http://www.freewisdom.org/projects/python-markdown/markdown2rss"
-
-month_map = { "Jan" : "01",
- "Feb" : "02",
- "March" : "03",
- "April" : "04",
- "May" : "05",
- "June" : "06",
- "July" : "07",
- "August" : "08",
- "September" : "09",
- "October" : "10",
- "November" : "11",
- "December" : "12" }
-
-def get_time(heading):
-
- heading = heading.split("-")[0]
- heading = heading.strip().replace(",", " ").replace(".", " ")
-
- month, date, year = heading.split()
- month = month_map[month]
-
- return rdftime(" ".join((month, date, year, "12:00:00 AM")))
-
-def rdftime(time):
-
- time = time.replace(":", " ")
- time = time.replace("/", " ")
- time = time.split()
- return "%s-%s-%sT%s:%s:%s-08:00" % (time[0], time[1], time[2],
- time[3], time[4], time[5])
-
-
-def get_date(text):
- return "date"
-
-class RssExtension (markdown.Extension):
-
- def extendMarkdown(self, md, md_globals):
-
- self.config = { 'URL' : [DEFAULT_URL, "Main URL"],
- 'CREATOR' : [DEFAULT_CREATOR, "Feed creator's name"],
- 'TITLE' : [DEFAULT_TITLE, "Feed title"] }
-
- md.xml_mode = True
-
- # Insert a post-processor that would actually add the title tag
- postprocessor = RssPostProcessor(self)
- postprocessor.ext = self
- md.postprocessors.append(postprocessor)
- md.stripTopLevelTags = 0
- md.docType = '<?xml version="1.0" encoding="utf-8"?>\n'
-
-class RssPostProcessor (markdown.Postprocessor):
-
- def __init__(self, md):
-
- pass
-
- def run (self, root):
-
- rss = etree.Element("rss")
- rss.set("version", "2.0")
-
- channel = etree.SubElement(rss, "channel")
-
- for tag, text in (("title", self.ext.getConfig("TITLE")),
- ("link", self.ext.getConfig("URL")),
- ("description", None)):
-
- element = etree.SubElement(channel, tag)
- element.text = text
-
- for child in root:
-
-
- if child.tag in ["h1", "h2", "h3", "h4", "h5"] :
-
- heading = child.text.strip()
-
- item = etree.SubElement(channel, "item")
-
- link = etree.SubElement(item, "link")
- link.text = self.ext.getConfig("URL")
-
- title = etree.SubElement(item, "title")
- title.text = heading
-
- guid = ''.join([x for x in heading if x.isalnum()])
-
- guidElem = etree.SubElement(item, "guid")
- guidElem.text = guid
- guidElem.set("isPermaLink", "false")
-
- elif child.tag in ["p"] :
- if item:
- description = etree.SubElement(item, "description")
- if len(child):
- content = "\n".join([etree.tostring(node)
- for node in child])
- else:
- content = child.text
- pholder = self.stash.store("<![CDATA[ %s]]>" % content)
- description.text = pholder
-
- return rss
-
-
-def makeExtension(configs):
-
- return RssExtension(configs)
diff --git a/mdx/mdx_tables.py b/mdx/mdx_tables.py
deleted file mode 100644
index 829044c..0000000
--- a/mdx/mdx_tables.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Table extension for Python-Markdown
-"""
-
-import markdown
-from markdown import etree
-
-class TablePattern(markdown.Pattern) :
- def __init__ (self, md):
- markdown.Pattern.__init__(self, r'(^|\n)\|([^\n]*)\|')
- self.md = md
-
- def handleMatch(self, m):
-
- # a single line represents a row
- tr = etree.Element('tr')
-
- # chunks between pipes represent cells
-
- for t in m.group(3).split('|'):
-
- if len(t) >= 2 and t.startswith('*') and t.endswith('*'):
- # if a cell is bounded by asterisks, it is a <th>
- td = etree.Element('th')
- t = t[1:-1]
- else:
- # otherwise it is a <td>
- td = etree.Element('td')
-
- # add text ot inline section, later it will be
- # processed by core
- inline = etree.SubElement(td, "inline")
- inline.text = t
-
- tr.append(td)
- tr.tail = "\n"
-
- return tr
-
-
-class TablePostprocessor:
-
- def _findElement(self, element, name):
- result = []
- for child in element:
- if child.tag == name:
- result.append(child)
- result += self._findElement(child, name)
- return result
-
- def run(self, root):
-
- for element in self._findElement(root, "p"):
- for child in element:
- if child.tail:
- element.tag = "table"
- break
-
-
-
-
-class TableExtension(markdown.Extension):
- def extendMarkdown(self, md, md_globals):
- md.inlinePatterns.insert(0, TablePattern(md))
- md.postprocessors.append(TablePostprocessor())
-
-
-def makeExtension(configs):
- return TableExtension(configs)
-
diff --git a/mdx/mdx_wikilink.py b/mdx/mdx_wikilink.py
deleted file mode 100644
index 47037a6..0000000
--- a/mdx/mdx_wikilink.py
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env python
-
-'''
-WikiLink Extention for Python-Markdown
-======================================
-
-Converts CamelCase words to relative links. Requires Python-Markdown 1.6+
-
-Basic usage:
-
- >>> import markdown
- >>> text = "Some text with a WikiLink."
- >>> md = markdown.markdown(text, ['wikilink'])
- >>> md
- u'<p>Some text with a <a href="/WikiLink/" class="wikilink">WikiLink</a>.\\n</p>'
-
-To define custom settings the simple way:
-
- >>> md = markdown.markdown(text,
- ... ['wikilink(base_url=/wiki/,end_url=.html,html_class=foo)']
- ... )
- >>> md
- u'<p>Some text with a <a href="/wiki/WikiLink.html" class="foo">WikiLink</a>.\\n</p>'
-
-Custom settings the complex way:
-
- >>> md = markdown.Markdown(
- ... extensions = ['wikilink'],
- ... extension_configs = {'wikilink': [
- ... ('base_url', 'http://example.com/'),
- ... ('end_url', '.html'),
- ... ('html_class', '') ]},
- ... safe_mode = True)
- >>> md.convert(text)
- u'<p>Some text with a <a href="http://example.com/WikiLink.html">WikiLink</a>.\\n</p>'
-
-Use MetaData with mdx_meta.py (Note the blank html_class in MetaData):
-
- >>> text = """wiki_base_url: http://example.com/
- ... wiki_end_url: .html
- ... wiki_html_class:
- ...
- ... Some text with a WikiLink."""
- >>> md = markdown.Markdown(extensions=['meta', 'wikilink'])
- >>> md.convert(text)
- u'<p>Some text with a <a href="http://example.com/WikiLink.html">WikiLink</a>.\\n</p>'
-
-MetaData should not carry over to next document:
-
- >>> md.convert("No MetaData here.")
- u'<p>No <a href="/MetaData/" class="wikilink">MetaData</a> here.\\n</p>'
-
-From the command line:
-
- python markdown.py -x wikilink(base_url=http://example.com/,end_url=.html,html_class=foo) src.txt
-
-By [Waylan Limberg](http://achinghead.com/).
-
-Project website: http://achinghead.com/markdown-wikilinks/
-Contact: waylan [at] gmail [dot] com
-
-License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
-
-Version: 0.6 (May 2, 2008)
-
-Dependencies:
-* [Python 2.3+](http://python.org)
-* [Markdown 1.6+](http://www.freewisdom.org/projects/python-markdown/)
-'''
-
-import markdown
-from markdown import etree
-
-class WikiLinkExtension (markdown.Extension) :
- def __init__(self, configs):
- # set extension defaults
- self.config = {
- 'base_url' : ['/', 'String to append to beginning or URL.'],
- 'end_url' : ['/', 'String to append to end of URL.'],
- 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.']
- }
-
- # Override defaults with user settings
- for key, value in configs :
- self.setConfig(key, value)
-
- def extendMarkdown(self, md, md_globals):
- self.md = md
-
- # append to end of inline patterns
- WIKILINK_RE = r'''(?P<escape>\\|\b)(?P<camelcase>([A-Z]+[a-z-_]+){2,})\b'''
- WIKILINK_PATTERN = WikiLinks(WIKILINK_RE, self.config)
- WIKILINK_PATTERN.md = md
- md.inlinePatterns.append(WIKILINK_PATTERN)
-
-
-class WikiLinks (markdown.BasePattern) :
- def __init__(self, pattern, config):
- markdown.BasePattern.__init__(self, pattern)
- self.config = config
-
- def handleMatch(self, m):
- if m.group('escape') == '\\':
- a = m.group('camelcase')
- else:
- base_url, end_url, html_class = self._getMeta()
- url = '%s%s%s'% (base_url, m.group('camelcase'), end_url)
- label = m.group('camelcase').replace('_', ' ')
- a = etree.Element('a')
- a.text = label
- a.set('href', url)
- if html_class:
- a.set('class', html_class)
- return a
-
- def _getMeta(self):
- """ Return meta data or config data. """
- base_url = self.config['base_url'][0]
- end_url = self.config['end_url'][0]
- html_class = self.config['html_class'][0]
- if hasattr(self.md, 'Meta'):
- if self.md.Meta.has_key('wiki_base_url'):
- base_url = self.md.Meta['wiki_base_url'][0]
- if self.md.Meta.has_key('wiki_end_url'):
- end_url = self.md.Meta['wiki_end_url'][0]
- if self.md.Meta.has_key('wiki_html_class'):
- html_class = self.md.Meta['wiki_html_class'][0]
- return base_url, end_url, html_class
-
- def type(self):
- return "WLink"
-
-
-def makeExtension(configs=None) :
- return WikiLinkExtension(configs=configs)
-
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
-