Markdown-2.6.9/ 0000755 0000765 0000024 00000000000 13145427672 013743 5 ustar waylan staff 0000000 0000000 Markdown-2.6.9/bin/ 0000755 0000765 0000024 00000000000 13145427671 014512 5 ustar waylan staff 0000000 0000000 Markdown-2.6.9/bin/markdown_py 0000755 0000765 0000024 00000001771 13064117426 016772 0 ustar waylan staff 0000000 0000000 #!/usr/bin/env python
"""
Python Markdown, the Command Line Script
========================================
This is the command line script for Python Markdown.
Basic use from the command line:
markdown source.txt > destination.html
Run "markdown --help" to see more options.
See markdown/__init__.py for information on using Python Markdown as a module.
## Authors and License
Started by [Manfred Stienstra](http://www.dwerg.net/). Continued and
maintained by [Yuri Takhteyev](http://www.freewisdom.org), [Waylan
Limberg](http://achinghead.com/) and [Artem Yunusov](http://blog.splyer.com).
Contact: markdown@freewisdom.org
Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
Copyright 200? Django Software Foundation (OrderedDict implementation)
Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
Copyright 2004 Manfred Stienstra (the original version)
License: BSD (see docs/LICENSE for details).
"""
if __name__ == '__main__':
from markdown.__main__ import run
run()
Markdown-2.6.9/docs/ 0000755 0000765 0000024 00000000000 13145427671 014672 5 ustar waylan staff 0000000 0000000 Markdown-2.6.9/docs/_template.html 0000644 0000765 0000024 00000004763 13145415574 017543 0 ustar waylan staff 0000000 0000000
Markdown-2.6.9/docs/authors.txt 0000644 0000765 0000024 00000003262 13064117426 017115 0 ustar waylan staff 0000000 0000000 title: Authors
prev_title: Release Notes for v2.0
prev_url: release-2.0.html
next_title: Table of Contents
next_url: siteindex.html
Primary Authors
===============
[Yuri Takteyev](http://freewisdom.org/)
: Yuri has written much of the current code while procrastinating his Ph.D.
[Waylan Limberg](http://achinghead.com/)
: Waylan is the current maintainer of the code and has written much the current
code base, included a complete refactor of the core. He started out by
authoring many of the available extensions and later was asked to join Yuri,
where he began fixing numerous bugs, adding documentation and making general
improvements to the existing code base.
Artem Yunusov
: Artem, who as part of a 2008 GSoC project, refactored inline patterns,
replaced the NanoDOM with ElementTree support and made various other
improvements.
[Manfed Stienstra](http://www.dwerg.net/)
: Manfed wrote the original version of the script and is responsible for
various parts of the existing code base.
David Wolever
: David 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 project 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
Markdown-2.6.9/docs/basic.css 0000644 0000765 0000024 00000015365 13064117426 016471 0 ustar waylan staff 0000000 0000000 /**
* Sphinx stylesheet -- basic theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
img {
border: 0;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table {
border: 0 solid #dce;
border-collapse: collapse;
}
table td, table th {
padding: 2px 5px 2px 5px;
}
table td {
border: 1px solid #ddd;
background-color: #eef;
}
table td p.last, table th p.last {
margin-bottom: 0;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
table th {
border: 1px solid #cac;
background-color: #ede;
}
th {
text-align: left;
padding-right: 5px;
}
th.head {
text-align: center;
}
/* -- other body styles ----------------------------------------------------- */
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlight {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.refcount {
color: #060;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
p.deprecated {
background-color: #ffe4e4;
border: 1px solid #f66;
padding: 7px
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.impl-detail {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
border: 1px solid #ccc;
}
.impl-detail .compound-first {
margin-top: 0;
}
.impl-detail .compound-last {
margin-bottom: 0;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden;
}
code {
font-size: 1.1em;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}
Markdown-2.6.9/docs/change_log.txt 0000644 0000765 0000024 00000020366 13145423307 017520 0 ustar waylan staff 0000000 0000000 title: Change Log
prev_title: Test Suite
prev_url: test_suite.html
next_title: Release Notes for v2.6
next_url: release-2.6.html
Python-Markdown Change Log
=========================
Aug 17, 2017: Released version 2.6.9 (a bug-fix release).
Jan 25, 2017: Released version 2.6.8 (a bug-fix release).
Sept 23, 2016: Released version 2.6.7 (a bug-fix release).
Mar 20, 2016: Released version 2.6.6 (a bug-fix release).
Nov 24, 2015: Released version 2.6.5 (a bug-fix release).
Nov 6, 2015: Released version 2.6.4 (a bug-fix release).
Oct 26, 2015: Released version 2.6.3 (a bug-fix release).
Apr 20, 2015: Released version 2.6.2 (a bug-fix release).
Mar 8, 2015: Released version 2.6.1 (a bug-fix release). The (new)
`yaml` option has been removed from the Meta-Data Extension as it was buggy
(see [#390](https://github.com/Python-Markdown/markdown/issues/390)).
Feb 19, 2015: Released version 2.6 ([Notes](release-2.6.html)).
Nov 19, 2014: Released version 2.5.2 (a bug-fix release).
Sept 26, 2014: Released version 2.5.1 (a bug-fix release).
Sept 12, 2014: Released version 2.5.0 ([Notes](release-2.5.html)).
Feb 16, 2014: Released version 2.4.0 ([Notes](release-2.4.html)).
Mar 22, 2013: Released version 2.3.1 (a bug-fix release).
Mar 14, 2013: Released version 2.3.0 ([Notes](release-2.3.html))
Nov 4, 2012: Released version 2.2.1 ([Notes](release-2.2.1.html)).
Jul 5, 2012: Released version 2.2.0 ([Notes](release-2.2.0.html)).
Jan 22, 2012: Released version 2.1.1 ([Notes](release-2.1.1.html)).
Nov 24, 2011: Released version 2.1.0 ([Notes](release-2.1.0.html)).
Oct 7, 2009: Released version 2.0.3.
Sept 28, 2009: Released version 2.0.2 ([Notes](release-2.0.2.html)).
May 20, 2009: Released version 2.0.1 ([Notes](release-2.0.1.html)).
Mar 30, 2009: Released version 2.0 ([Notes](release-2.0.html)).
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 Definition 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 traversing. Added `treap` implementation, then replaced with
OrderedDict. 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' directory
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
separate command line 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 repository 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 bug-fixes mostly regarding extensions.
Feb 18, 2008: Version 1.7.
Feb 13, 2008: A little code cleanup and better documentation
and inheritance for Preprocessors/Postprocessors.
Feb 9, 2008: Double-quotes no longer HTML escaped and raw HTML
honors ``, `<@foo>`, and `<%foo>` for those who run markdown on
template syntax.
Dec 12, 2007: Updated docs. Removed encoding argument 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 regular expression 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 inline patterns. 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 `" % _escape_cdata(text))
elif tag is ProcessingInstruction:
write("%s?>" % _escape_cdata(text))
else:
tag = qnames[tag]
if tag is None:
if text:
write(_escape_cdata(text))
for e in elem:
_serialize_html(write, e, qnames, None, format)
else:
write("<" + tag)
items = elem.items()
if items or namespaces:
items = sorted(items) # lexical order
for k, v in items:
if isinstance(k, QName):
k = k.text
if isinstance(v, QName):
v = qnames[v.text]
else:
v = _escape_attrib_html(v)
if qnames[k] == v and format == 'html':
# handle boolean attributes
write(" %s" % v)
else:
write(" %s=\"%s\"" % (qnames[k], v))
if namespaces:
items = namespaces.items()
items.sort(key=lambda x: x[1]) # sort on prefix
for v, k in items:
if k:
k = ":" + k
write(" xmlns%s=\"%s\"" % (k, _escape_attrib(v)))
if format == "xhtml" and tag.lower() in HTML_EMPTY:
write(" />")
else:
write(">")
if text:
if tag.lower() in ["script", "style"]:
write(text)
else:
write(_escape_cdata(text))
for e in elem:
_serialize_html(write, e, qnames, None, format)
if tag.lower() not in HTML_EMPTY:
write("" + tag + ">")
if elem.tail:
write(_escape_cdata(elem.tail))
def _write_html(root,
encoding=None,
default_namespace=None,
format="html"):
assert root is not None
data = []
write = data.append
qnames, namespaces = _namespaces(root, default_namespace)
_serialize_html(write, root, qnames, namespaces, format)
if encoding is None:
return "".join(data)
else:
return _encode("".join(data))
# --------------------------------------------------------------------
# serialization support
def _namespaces(elem, default_namespace=None):
# identify namespaces used in this tree
# maps qnames to *encoded* prefix:local names
qnames = {None: None}
# maps uri:s to prefixes
namespaces = {}
if default_namespace:
namespaces[default_namespace] = ""
def add_qname(qname):
# calculate serialized qname representation
try:
if qname[:1] == "{":
uri, tag = qname[1:].split("}", 1)
prefix = namespaces.get(uri)
if prefix is None:
prefix = _namespace_map.get(uri)
if prefix is None:
prefix = "ns%d" % len(namespaces)
if prefix != "xml":
namespaces[uri] = prefix
if prefix:
qnames[qname] = "%s:%s" % (prefix, tag)
else:
qnames[qname] = tag # default element
else:
if default_namespace:
raise ValueError(
"cannot use non-qualified names with "
"default_namespace option"
)
qnames[qname] = qname
except TypeError: # pragma: no cover
_raise_serialization_error(qname)
# populate qname and namespaces table
try:
iterate = elem.iter
except AttributeError:
iterate = elem.getiterator # cET compatibility
for elem in iterate():
tag = elem.tag
if isinstance(tag, QName) and tag.text not in qnames:
add_qname(tag.text)
elif isinstance(tag, util.string_type):
if tag not in qnames:
add_qname(tag)
elif tag is not None and tag is not Comment and tag is not PI:
_raise_serialization_error(tag)
for key, value in elem.items():
if isinstance(key, QName):
key = key.text
if key not in qnames:
add_qname(key)
if isinstance(value, QName) and value.text not in qnames:
add_qname(value.text)
text = elem.text
if isinstance(text, QName) and text.text not in qnames:
add_qname(text.text)
return qnames, namespaces
def to_html_string(element):
return _write_html(ElementTree(element).getroot(), format="html")
def to_xhtml_string(element):
return _write_html(ElementTree(element).getroot(), format="xhtml")
Markdown-2.6.9/markdown/treeprocessors.py 0000644 0000765 0000024 00000031350 13064117426 021214 0 ustar waylan staff 0000000 0000000 from __future__ import unicode_literals
from __future__ import absolute_import
from . import util
from . import odict
from . import inlinepatterns
def build_treeprocessors(md_instance, **kwargs):
""" Build the default treeprocessors for Markdown. """
treeprocessors = odict.OrderedDict()
treeprocessors["inline"] = InlineProcessor(md_instance)
treeprocessors["prettify"] = PrettifyTreeprocessor(md_instance)
return treeprocessors
def isString(s):
""" Check if it's string """
if not isinstance(s, util.AtomicString):
return isinstance(s, util.string_type)
return False
class Treeprocessor(util.Processor):
"""
Treeprocessors are run on the ElementTree object before serialization.
Each Treeprocessor implements a "run" method that takes a pointer to an
ElementTree, modifies it as necessary and returns an ElementTree
object.
Treeprocessors must extend markdown.Treeprocessor.
"""
def run(self, root):
"""
Subclasses of Treeprocessor should implement a `run` method, which
takes a root ElementTree. This method can return another ElementTree
object, and the existing root ElementTree will be replaced, or it can
modify the current tree and return None.
"""
pass # pragma: no cover
class InlineProcessor(Treeprocessor):
"""
A Treeprocessor that traverses a tree, applying inline patterns.
"""
def __init__(self, md):
self.__placeholder_prefix = util.INLINE_PLACEHOLDER_PREFIX
self.__placeholder_suffix = util.ETX
self.__placeholder_length = 4 + len(self.__placeholder_prefix) \
+ len(self.__placeholder_suffix)
self.__placeholder_re = util.INLINE_PLACEHOLDER_RE
self.markdown = md
self.inlinePatterns = md.inlinePatterns
def __makePlaceholder(self, type):
""" Generate a placeholder """
id = "%04d" % len(self.stashed_nodes)
hash = util.INLINE_PLACEHOLDER % id
return hash, id
def __findPlaceholder(self, data, index):
"""
Extract id from data string, start from index
Keyword arguments:
* data: string
* index: index, from which we start search
Returns: placeholder id and string index, after the found placeholder.
"""
m = self.__placeholder_re.search(data, index)
if m:
return m.group(1), m.end()
else:
return None, index + 1
def __stashNode(self, node, type):
""" Add node to stash """
placeholder, id = self.__makePlaceholder(type)
self.stashed_nodes[id] = node
return placeholder
def __handleInline(self, data, patternIndex=0):
"""
Process string with inline patterns and replace it
with placeholders
Keyword arguments:
* data: A line of Markdown text
* patternIndex: The index of the inlinePattern to start with
Returns: String with placeholders.
"""
if not isinstance(data, util.AtomicString):
startIndex = 0
while patternIndex < len(self.inlinePatterns):
data, matched, startIndex = self.__applyPattern(
self.inlinePatterns.value_for_index(patternIndex),
data, patternIndex, startIndex)
if not matched:
patternIndex += 1
return data
def __processElementText(self, node, subnode, isText=True):
"""
Process placeholders in Element.text or Element.tail
of Elements popped from self.stashed_nodes.
Keywords arguments:
* node: parent node
* subnode: processing node
* isText: bool variable, True - it's text, False - it's tail
Returns: None
"""
if isText:
text = subnode.text
subnode.text = None
else:
text = subnode.tail
subnode.tail = None
childResult = self.__processPlaceholders(text, subnode, isText)
if not isText and node is not subnode:
pos = list(node).index(subnode) + 1
else:
pos = 0
childResult.reverse()
for newChild in childResult:
node.insert(pos, newChild)
def __processPlaceholders(self, data, parent, isText=True):
"""
Process string with placeholders and generate ElementTree tree.
Keyword arguments:
* data: string with placeholders instead of ElementTree elements.
* parent: Element, which contains processing inline data
Returns: list with ElementTree elements with applied inline patterns.
"""
def linkText(text):
if text:
if result:
if result[-1].tail:
result[-1].tail += text
else:
result[-1].tail = text
elif not isText:
if parent.tail:
parent.tail += text
else:
parent.tail = text
else:
if parent.text:
parent.text += text
else:
parent.text = text
result = []
strartIndex = 0
while data:
index = data.find(self.__placeholder_prefix, strartIndex)
if index != -1:
id, phEndIndex = self.__findPlaceholder(data, index)
if id in self.stashed_nodes:
node = self.stashed_nodes.get(id)
if index > 0:
text = data[strartIndex:index]
linkText(text)
if not isString(node): # it's Element
for child in [node] + list(node):
if child.tail:
if child.tail.strip():
self.__processElementText(
node, child, False
)
if child.text:
if child.text.strip():
self.__processElementText(child, child)
else: # it's just a string
linkText(node)
strartIndex = phEndIndex
continue
strartIndex = phEndIndex
result.append(node)
else: # wrong placeholder
end = index + len(self.__placeholder_prefix)
linkText(data[strartIndex:end])
strartIndex = end
else:
text = data[strartIndex:]
if isinstance(data, util.AtomicString):
# We don't want to loose the AtomicString
text = util.AtomicString(text)
linkText(text)
data = ""
return result
def __applyPattern(self, pattern, data, patternIndex, startIndex=0):
"""
Check if the line fits the pattern, create the necessary
elements, add it to stashed_nodes.
Keyword arguments:
* data: the text to be processed
* pattern: the pattern to be checked
* patternIndex: index of current pattern
* startIndex: string index, from which we start searching
Returns: String with placeholders instead of ElementTree elements.
"""
match = pattern.getCompiledRegExp().match(data[startIndex:])
leftData = data[:startIndex]
if not match:
return data, False, 0
node = pattern.handleMatch(match)
if node is None:
return data, True, len(leftData)+match.span(len(match.groups()))[0]
if not isString(node):
if not isinstance(node.text, util.AtomicString):
# We need to process current node too
for child in [node] + list(node):
if not isString(node):
if child.text:
child.text = self.__handleInline(
child.text, patternIndex + 1
)
if child.tail:
child.tail = self.__handleInline(
child.tail, patternIndex
)
placeholder = self.__stashNode(node, pattern.type())
return "%s%s%s%s" % (leftData,
match.group(1),
placeholder, match.groups()[-1]), True, 0
def run(self, tree):
"""Apply inline patterns to a parsed Markdown tree.
Iterate over ElementTree, find elements with inline tag, apply inline
patterns and append newly created Elements to tree. If you don't
want to process your data with inline paterns, instead of normal
string, use subclass AtomicString:
node.text = markdown.AtomicString("This will not be processed.")
Arguments:
* tree: ElementTree object, representing Markdown tree.
Returns: ElementTree object with applied inline patterns.
"""
self.stashed_nodes = {}
stack = [tree]
while stack:
currElement = stack.pop()
insertQueue = []
for child in currElement:
if child.text and not isinstance(
child.text, util.AtomicString
):
text = child.text
child.text = None
lst = self.__processPlaceholders(
self.__handleInline(text), child
)
stack += lst
insertQueue.append((child, lst))
if child.tail:
tail = self.__handleInline(child.tail)
dumby = util.etree.Element('d')
child.tail = None
tailResult = self.__processPlaceholders(tail, dumby, False)
if dumby.tail:
child.tail = dumby.tail
pos = list(currElement).index(child) + 1
tailResult.reverse()
for newChild in tailResult:
currElement.insert(pos, newChild)
if len(child):
stack.append(child)
for element, lst in insertQueue:
if self.markdown.enable_attributes:
if element.text and isString(element.text):
element.text = inlinepatterns.handleAttributes(
element.text, element
)
i = 0
for newChild in lst:
if self.markdown.enable_attributes:
# Processing attributes
if newChild.tail and isString(newChild.tail):
newChild.tail = inlinepatterns.handleAttributes(
newChild.tail, element
)
if newChild.text and isString(newChild.text):
newChild.text = inlinepatterns.handleAttributes(
newChild.text, newChild
)
element.insert(i, newChild)
i += 1
return tree
class PrettifyTreeprocessor(Treeprocessor):
""" Add linebreaks to the html document. """
def _prettifyETree(self, elem):
""" Recursively add linebreaks to ElementTree children. """
i = "\n"
if util.isBlockLevel(elem.tag) and elem.tag not in ['code', 'pre']:
if (not elem.text or not elem.text.strip()) \
and len(elem) and util.isBlockLevel(elem[0].tag):
elem.text = i
for e in elem:
if util.isBlockLevel(e.tag):
self._prettifyETree(e)
if not elem.tail or not elem.tail.strip():
elem.tail = i
if not elem.tail or not elem.tail.strip():
elem.tail = i
def run(self, root):
""" Add linebreaks to ElementTree root object. """
self._prettifyETree(root)
# Do 's seperately as they are often in the middle of
# inline content and missed by _prettifyETree.
brs = root.iter('br')
for br in brs:
if not br.tail or not br.tail.strip():
br.tail = '\n'
else:
br.tail = '\n%s' % br.tail
# Clean up extra empty lines at end of code blocks.
pres = root.iter('pre')
for pre in pres:
if len(pre) and pre[0].tag == 'code':
pre[0].text = util.AtomicString(pre[0].text.rstrip() + '\n')
Markdown-2.6.9/markdown/util.py 0000644 0000765 0000024 00000013016 13064117426 017106 0 ustar waylan staff 0000000 0000000 # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import re
import sys
"""
Python 3 Stuff
=============================================================================
"""
PY3 = sys.version_info[0] == 3
if PY3: # pragma: no cover
string_type = str
text_type = str
int2str = chr
else: # pragma: no cover
string_type = basestring # noqa
text_type = unicode # noqa
int2str = unichr # noqa
"""
Constants you might want to modify
-----------------------------------------------------------------------------
"""
BLOCK_LEVEL_ELEMENTS = re.compile(
"^(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul"
"|script|noscript|form|fieldset|iframe|math"
"|hr|hr/|style|li|dt|dd|thead|tbody"
"|tr|th|td|section|footer|header|group|figure"
"|figcaption|aside|article|canvas|output"
"|progress|video|nav|main)$",
re.IGNORECASE
)
# Placeholders
STX = '\u0002' # Use STX ("Start of text") for start-of-placeholder
ETX = '\u0003' # Use ETX ("End of text") for end-of-placeholder
INLINE_PLACEHOLDER_PREFIX = STX+"klzzwxh:"
INLINE_PLACEHOLDER = INLINE_PLACEHOLDER_PREFIX + "%s" + ETX
INLINE_PLACEHOLDER_RE = re.compile(INLINE_PLACEHOLDER % r'([0-9]+)')
AMP_SUBSTITUTE = STX+"amp"+ETX
HTML_PLACEHOLDER = STX + "wzxhzdk:%s" + ETX
HTML_PLACEHOLDER_RE = re.compile(HTML_PLACEHOLDER % r'([0-9]+)')
TAG_PLACEHOLDER = STX + "hzzhzkh:%s" + ETX
"""
Constants you probably do not need to change
-----------------------------------------------------------------------------
"""
RTL_BIDI_RANGES = (
('\u0590', '\u07FF'),
# Hebrew (0590-05FF), Arabic (0600-06FF),
# Syriac (0700-074F), Arabic supplement (0750-077F),
# Thaana (0780-07BF), Nko (07C0-07FF).
('\u2D30', '\u2D7F') # Tifinagh
)
# Extensions should use "markdown.util.etree" instead of "etree" (or do `from
# markdown.util import etree`). Do not import it by yourself.
try: # pragma: no cover
# Is the C implementation of ElementTree available?
import xml.etree.cElementTree as etree
from xml.etree.ElementTree import Comment
# Serializers (including ours) test with non-c Comment
etree.test_comment = Comment
if etree.VERSION < "1.0.5":
raise RuntimeError("cElementTree version 1.0.5 or higher is required.")
except (ImportError, RuntimeError): # pragma: no cover
# Use the Python implementation of ElementTree?
import xml.etree.ElementTree as etree
if etree.VERSION < "1.1":
raise RuntimeError("ElementTree version 1.1 or higher is required")
"""
AUXILIARY GLOBAL FUNCTIONS
=============================================================================
"""
def isBlockLevel(tag):
"""Check if the tag is a block level HTML tag."""
if isinstance(tag, string_type):
return BLOCK_LEVEL_ELEMENTS.match(tag)
# Some ElementTree tags are not strings, so return False.
return False
def parseBoolValue(value, fail_on_errors=True, preserve_none=False):
"""Parses a string representing bool value. If parsing was successful,
returns True or False. If preserve_none=True, returns True, False,
or None. If parsing was not successful, raises ValueError, or, if
fail_on_errors=False, returns None."""
if not isinstance(value, string_type):
if preserve_none and value is None:
return value
return bool(value)
elif preserve_none and value.lower() == 'none':
return None
elif value.lower() in ('true', 'yes', 'y', 'on', '1'):
return True
elif value.lower() in ('false', 'no', 'n', 'off', '0', 'none'):
return False
elif fail_on_errors:
raise ValueError('Cannot parse bool value: %r' % value)
"""
MISC AUXILIARY CLASSES
=============================================================================
"""
class AtomicString(text_type):
"""A string which should not be further processed."""
pass
class Processor(object):
def __init__(self, markdown_instance=None):
if markdown_instance:
self.markdown = markdown_instance
class HtmlStash(object):
"""
This class is used for stashing HTML objects that we extract
in the beginning and replace with place-holders.
"""
def __init__(self):
""" Create a HtmlStash. """
self.html_counter = 0 # for counting inline html segments
self.rawHtmlBlocks = []
self.tag_counter = 0
self.tag_data = [] # list of dictionaries in the order tags appear
def store(self, html, safe=False):
"""
Saves an HTML segment for later reinsertion. Returns a
placeholder string that needs to be inserted into the
document.
Keyword arguments:
* html: an html segment
* safe: label an html segment as safe for safemode
Returns : a placeholder string
"""
self.rawHtmlBlocks.append((html, safe))
placeholder = self.get_placeholder(self.html_counter)
self.html_counter += 1
return placeholder
def reset(self):
self.html_counter = 0
self.rawHtmlBlocks = []
def get_placeholder(self, key):
return HTML_PLACEHOLDER % key
def store_tag(self, tag, attrs, left_index, right_index):
"""Store tag data and return a placeholder."""
self.tag_data.append({'tag': tag, 'attrs': attrs,
'left_index': left_index,
'right_index': right_index})
placeholder = TAG_PLACEHOLDER % str(self.tag_counter)
self.tag_counter += 1 # equal to the tag's index in self.tag_data
return placeholder
Markdown-2.6.9/PKG-INFO 0000644 0000765 0000024 00000004276 13145427672 015051 0 ustar waylan staff 0000000 0000000 Metadata-Version: 1.1
Name: Markdown
Version: 2.6.9
Summary: Python implementation of Markdown.
Home-page: https://pythonhosted.org/Markdown/
Author: Waylan Limberg
Author-email: waylan.limberg@icloud.com
License: BSD License
Download-URL: http://pypi.python.org/packages/source/M/Markdown/Markdown-2.6.9.tar.gz
Description:
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`_.
.. _Markdown: http://daringfireball.net/projects/markdown/
.. _Features: https://pythonhosted.org/Markdown/index.html#Features
.. _`Available Extensions`: https://pythonhosted.org/Markdown/extensions/index.html
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://github.com/Python-Markdown/markdown/issues
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Topic :: Communications :: Email :: Filters
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Filters
Classifier: Topic :: Text Processing :: Markup :: HTML
Markdown-2.6.9/README.md 0000644 0000765 0000024 00000004212 13145420521 015203 0 ustar waylan staff 0000000 0000000 [Python-Markdown][]
===================
[](https://travis-ci.org/Python-Markdown/markdown)
[](https://coveralls.io/r/Python-Markdown/markdown?branch=master)
[](http://pypi.python.org/pypi/Markdown)
[](http://pypi.python.org/pypi/Markdown)
[](http://opensource.org/licenses/BSD-3-Clause)
[][Code of Conduct]
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]: https://pythonhosted.org/Markdown/
[Markdown]: http://daringfireball.net/projects/markdown/
[Features]: https://pythonhosted.org/Markdown/index.html#Features
[Available Extensions]: https://pythonhosted.org/Markdown/extensions/index.html
Documentation
-------------
Installation and usage documentation is available in the `docs/` directory
of the distribution and on the project website at
.
See the change log at .
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://github.com/Python-Markdown/markdown/issues
Code of Conduct
---------------
Everyone interacting in the Python-Markdown project's codebases, issue trackers, and mailing lists is expected to follow the [Code of Conduct].
[Code of Conduct]: https://github.com/Python-Markdown/markdown/blob/master/CODE_OF_CONDUCT.md
Markdown-2.6.9/run-tests.py 0000755 0000765 0000024 00000001135 13064117426 016255 0 ustar waylan staff 0000000 0000000 #!/usr/bin/env python
import tests
import os
import sys
if len(sys.argv) > 1 and sys.argv[1] == "update":
if len(sys.argv) > 2:
config = tests.get_config(os.path.dirname(sys.argv[2]))
root, ext = os.path.splitext(sys.argv[2])
if ext == config.get(
config.get_section(os.path.basename(root)), 'input_ext'
):
tests.generate(root, config)
else:
print(
sys.argv[2],
'does not have a valid file extension. Check config.'
)
else:
tests.generate_all()
else:
tests.run()
Markdown-2.6.9/setup.cfg 0000644 0000765 0000024 00000000014 13064117426 015550 0 ustar waylan staff 0000000 0000000 [nosetests]
Markdown-2.6.9/setup.py 0000755 0000765 0000024 00000023217 13145427647 015467 0 ustar waylan staff 0000000 0000000 #!/usr/bin/env python
from __future__ import with_statement
import sys
import os
from distutils.core import setup
from distutils.command.install_scripts import install_scripts
from distutils.command.build import build
from distutils.core import Command
from distutils.util import change_root, newer
import codecs
import imp
def get_version():
" Get version & version_info without importing markdown.__init__ "
path = os.path.join(os.path.dirname(__file__), 'markdown')
fp, pathname, desc = imp.find_module('__version__', [path])
try:
v = imp.load_module('__version__', fp, pathname, desc)
return v.version, v.version_info
finally:
fp.close()
version, version_info = get_version()
# Get development Status for classifiers
dev_status_map = {
'alpha': '3 - Alpha',
'beta': '4 - Beta',
'rc': '4 - Beta',
'final': '5 - Production/Stable'
}
if version_info[3] == 'alpha' and version_info[4] == 0:
DEVSTATUS = '2 - Pre-Alpha'
else:
DEVSTATUS = dev_status_map[version_info[3]]
# The command line script name. Currently set to "markdown_py" so as not to
# conflict with the perl implimentation (which uses "markdown"). We can't use
# "markdown.py" as the default config on some systems will cause the script to
# try to import itself rather than the library which will raise an error.
SCRIPT_NAME = 'markdown_py'
class md_install_scripts(install_scripts):
""" Customized install_scripts. Create markdown_py.bat for win32. """
def run(self):
install_scripts.run(self)
if sys.platform == 'win32':
try:
script_dir = os.path.join(sys.prefix, 'Scripts')
script_path = os.path.join(script_dir, SCRIPT_NAME)
bat_str = '@"%s" "%s" %%*' % (sys.executable, script_path)
bat_path = os.path.join(
self.install_dir, '%s.bat' % SCRIPT_NAME
)
f = open(bat_path, 'w')
f.write(bat_str)
f.close()
print('Created: %s' % bat_path)
except Exception:
_, err, _ = sys.exc_info() # for both 2.x & 3.x compatability
print('ERROR: Unable to create %s: %s' % (bat_path, err))
class build_docs(Command):
""" Build markdown documentation into html."""
description = '"build" documentation (convert markdown text to html)'
user_options = [
('build-base=', 'd', 'directory to "build" to'),
('force', 'f', 'forcibly build everything (ignore file timestamps)'),
]
boolean_options = ['force']
def initialize_options(self):
self.build_base = None
self.force = None
self.docs = None
self.sitemap = ''
def finalize_options(self):
self.set_undefined_options(
'build',
('build_base', 'build_base'),
('force', 'force')
)
self.docs = self._get_docs()
def _get_docs(self):
for root, dirs, files in os.walk('docs'):
for file in files:
if not file.startswith('_'):
path = os.path.join(root, file)
yield path
def _get_context(self, src, path):
""" Build and return context to pass to template. """
# set defaults
c = {
'title': '',
'prev_url': '',
'prev_title': '',
'next_url': '',
'next_title': '',
'crumb': '',
'version': version,
}
c['body'] = self.md.convert(src)
c['toc'] = self.md.toc
for k, v in self.md.Meta.items():
c[k] = ' '.join(v)
self.md.reset()
# Manipulate path
path = path[len(os.path.join(self.build_base, 'docs/')):]
dir, file = os.path.split(path)
name, ext = os.path.splitext(file)
parts = [x for x in dir.split(os.sep) if x]
c['source'] = '%s.txt' % name
c['base'] = '../' * len(parts)
# Build page title
if name.lower() != 'index' or parts:
c['page_title'] = '%s — Python Markdown' % c['title']
else:
c['page_title'] = 'Python Markdown'
# Build crumb trail
crumbs = []
ctemp = '