mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-02-05 00:07:38 -08:00
This commit represents a new era for Gentoo: Storing the gentoo-x86 tree in Git, as converted from CVS. This commit is the start of the NEW history. Any historical data is intended to be grafted onto this point. Creation process: 1. Take final CVS checkout snapshot 2. Remove ALL ChangeLog* files 3. Transform all Manifests to thin 4. Remove empty Manifests 5. Convert all stale $Header$/$Id$ CVS keywords to non-expanded Git $Id$ 5.1. Do not touch files with -kb/-ko keyword flags. Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> X-Thanks: Alec Warner <antarus@gentoo.org> - did the GSoC 2006 migration tests X-Thanks: Robin H. Johnson <robbat2@gentoo.org> - infra guy, herding this project X-Thanks: Nguyen Thai Ngoc Duy <pclouds@gentoo.org> - Former Gentoo developer, wrote Git features for the migration X-Thanks: Brian Harring <ferringb@gentoo.org> - wrote much python to improve cvs2svn X-Thanks: Rich Freeman <rich0@gentoo.org> - validation scripts X-Thanks: Patrick Lauer <patrick@gentoo.org> - Gentoo dev, running new 2014 work in migration X-Thanks: Michał Górny <mgorny@gentoo.org> - scripts, QA, nagging X-Thanks: All of other Gentoo developers - many ideas and lots of paint on the bikeshed
537 lines
17 KiB
Diff
537 lines
17 KiB
Diff
diff --git a/CHANGES.rst b/CHANGES.rst
|
|
index eb204dd..3eb99a7 100644
|
|
--- a/CHANGES.rst
|
|
+++ b/CHANGES.rst
|
|
@@ -3,6 +3,14 @@ Changelog
|
|
|
|
Here is the full history of mistune.
|
|
|
|
+Version 0.7
|
|
+~~~~~~~~~~~
|
|
+
|
|
+Release date not decided.
|
|
+
|
|
+* Fix the breaking change in version 0.6 with options: **parse_inline_html** and **parse_block_html**
|
|
+
|
|
+
|
|
Version 0.6
|
|
~~~~~~~~~~~
|
|
|
|
diff --git a/README.rst b/README.rst
|
|
index 894833b..f6cb5f9 100644
|
|
--- a/README.rst
|
|
+++ b/README.rst
|
|
@@ -38,12 +38,6 @@ Installing mistune with pip::
|
|
|
|
$ pip install mistune
|
|
|
|
-If pip is not available, try easy_install::
|
|
-
|
|
- $ easy_install mistune
|
|
-
|
|
-Cython Feature
|
|
-~~~~~~~~~~~~~~
|
|
|
|
Mistune can be faster, if you compile with cython::
|
|
|
|
@@ -59,10 +53,49 @@ A simple API that render a markdown formatted text:
|
|
|
|
import mistune
|
|
|
|
- mistune.markdown('I am using **markdown**')
|
|
- # output: <p>I am using <strong>markdown</strong></p>
|
|
+ mistune.markdown('I am using **mistune markdown parser**')
|
|
+ # output: <p>I am using <strong>mistune markdown parser</strong></p>
|
|
+
|
|
+If you care about performance, it is better to re-use the Markdown instance:
|
|
+
|
|
+.. code:: python
|
|
+
|
|
+ import mistune
|
|
+
|
|
+ markdown = mistune.Markdown()
|
|
+ markdown('I am using **mistune markdown parser**')
|
|
+
|
|
+Mistune has enabled all features by default. You don't have to configure
|
|
+anything. But there are options for you to change the parser behaviors.
|
|
+
|
|
+
|
|
+Options
|
|
+-------
|
|
+
|
|
+Here is a list of all options that will affect the rendering results,
|
|
+configure them with ``mistune.Renderer``:
|
|
+
|
|
+.. code:: python
|
|
+
|
|
+ renderer = mistune.Renderer(escape=True, hard_wrap=True)
|
|
+ # use this renderer instance
|
|
+ markdown = mistune.Markdown(renderer=renderer)
|
|
+ markdown(text)
|
|
+
|
|
+* **escape**: if set to *True*, all raw html tags will be escaped.
|
|
+* **hard_wrap**: if set to *True*, it will has GFM line breaks feature.
|
|
+* **use_xhtml**: if set to *True*, all tags will be in xhtml, for example: ``<hr />``.
|
|
+* **parse_html**: parse text in block and inline level html.
|
|
+* **parse_block_html**: parse text only in block level html.
|
|
+* **parse_inline_html**: parse text only in inline level html.
|
|
+
|
|
+When using the default renderer, you can use one of the following shortcuts::
|
|
+
|
|
+ mistune.markdown(text, escape=True, hard_wrap=True)
|
|
+
|
|
+ markdown = mistune.Markdown(escape=True, hard_wrap=True)
|
|
+ markdown(text)
|
|
|
|
-Mistune has all features by default. You don't have to configure anything.
|
|
|
|
Renderer
|
|
--------
|
|
@@ -79,7 +112,7 @@ Here is an example of code highlighting:
|
|
from pygments.lexers import get_lexer_by_name
|
|
from pygments.formatters import HtmlFormatter
|
|
|
|
- class MyRenderer(mistune.Renderer):
|
|
+ class HighlightRenderer(mistune.Renderer):
|
|
def block_code(self, code, lang):
|
|
if not lang:
|
|
return '\n<pre><code>%s</code></pre>\n' % \
|
|
@@ -88,9 +121,9 @@ Here is an example of code highlighting:
|
|
formatter = HtmlFormatter()
|
|
return highlight(code, lexer, formatter)
|
|
|
|
- renderer = MyRenderer()
|
|
- md = mistune.Markdown(renderer=renderer)
|
|
- print(md.render('Some Markdown text.'))
|
|
+ renderer = HighlightRenderer()
|
|
+ markdown = mistune.Markdown(renderer=renderer)
|
|
+ print(markdown('Some code text.'))
|
|
|
|
|
|
Block Level
|
|
@@ -127,34 +160,18 @@ Here is a list of span level renderer API::
|
|
linebreak()
|
|
newline()
|
|
link(link, title, content)
|
|
- tag(html)
|
|
strikethrough(text)
|
|
text(text)
|
|
+ inline_html(text)
|
|
|
|
+Footnotes
|
|
+~~~~~~~~~
|
|
|
|
-Options
|
|
--------
|
|
-
|
|
-Here is a list of all options that will affect the rendering results:
|
|
-
|
|
-.. code:: python
|
|
-
|
|
- renderer = mistune.Renderer(escape=True)
|
|
- md = mistune.Markdown(renderer=renderer)
|
|
- md.render(text)
|
|
-
|
|
-* **escape**: if set to *True*, all raw html tags will be escaped.
|
|
-* **hard_wrap**: if set to *True*, it will has GFM line breaks feature.
|
|
-* **use_xhtml**: if set to *True*, all tags will be in xhtml, for example: ``<hr />``.
|
|
-* **parse_html**: parse text in block level html.
|
|
-
|
|
-When using the default renderer, you can use one of the following shorthands::
|
|
-
|
|
- mistune.markdown(text, escape=True)
|
|
-
|
|
- md = mistune.Markdown(escape=True)
|
|
- md.render(text)
|
|
+Here is a list of renderers related to footnotes::
|
|
|
|
+ footnote_ref(key, index)
|
|
+ footnote_item(key, text)
|
|
+ footnotes(text)
|
|
|
|
Lexers
|
|
------
|
|
@@ -172,33 +189,23 @@ It is an inline grammar, which requires custom ``InlineGrammar`` and
|
|
import copy
|
|
from mistune import Renderer, InlineGrammar, InlineLexer
|
|
|
|
- class MyRenderer(Renderer):
|
|
+ class WikiLinkRenderer(Renderer):
|
|
def wiki_link(self, alt, link):
|
|
return '<a href="%s">%s</a>' % (link, alt)
|
|
|
|
+ class WikiLinkInlineLexer(InlineLexer):
|
|
+ def enable_wiki_link(self):
|
|
+ # add wiki_link rules
|
|
+ self.rules.wiki_link = re.compile(
|
|
+ r'\[\[' # [[
|
|
+ r'([\s\S]+?\|[\s\S]+?)' # Page 2|Page 2
|
|
+ r'\]\](?!\])' # ]]
|
|
+ )
|
|
|
|
- class MyInlineGrammar(InlineGrammar):
|
|
- # it would take a while for creating the right regex
|
|
- wiki_link = re.compile(
|
|
- r'\[\[' # [[
|
|
- r'([\s\S]+?\|[\s\S]+?)' # Page 2|Page 2
|
|
- r'\]\](?!\])' # ]]
|
|
- )
|
|
-
|
|
-
|
|
- class MyInlineLexer(InlineLexer):
|
|
- default_rules = copy.copy(InlineLexer.default_rules)
|
|
-
|
|
- # Add wiki_link parser to default rules
|
|
- # you can insert it any place you like
|
|
- default_rules.insert(3, 'wiki_link')
|
|
-
|
|
- def __init__(self, renderer, rules=None, **kwargs):
|
|
- if rules is None:
|
|
- # use the inline grammar
|
|
- rules = MyInlineGrammar()
|
|
-
|
|
- super(MyInlineLexer, self).__init__(renderer, rules, **kwargs)
|
|
+ # Add wiki_link parser to default rules
|
|
+ # you can insert it some place you like
|
|
+ # but place matters, maybe 3 is not good
|
|
+ self.default_rules.insert(3, 'wiki_link')
|
|
|
|
def output_wiki_link(self, m):
|
|
text = m.group(1)
|
|
@@ -211,8 +218,10 @@ You should pass the inline lexer to ``Markdown`` parser:
|
|
|
|
.. code:: python
|
|
|
|
- renderer = MyRenderer()
|
|
- inline = MyInlineLexer(renderer)
|
|
+ renderer = WikiLinkRenderer()
|
|
+ inline = WikiLinkInlineLexer(renderer)
|
|
+ # enable the feature
|
|
+ inline.enable_wiki_link()
|
|
markdown = Markdown(renderer, inline=inline)
|
|
markdown('[[Link Text|Wiki Link]]')
|
|
|
|
@@ -220,12 +229,21 @@ It is the same with block level lexer. It would take a while to understand
|
|
the whole mechanism. But you won't do the trick a lot.
|
|
|
|
|
|
-Contribution
|
|
-------------
|
|
+Contribution & Extensions
|
|
+-------------------------
|
|
|
|
Mistune itself doesn't accept any extension. It will always be a simple one
|
|
file script.
|
|
|
|
If you want to add features, you can head over to `mistune-contrib`_.
|
|
|
|
+Here are some extensions already in `mistune-contrib`_:
|
|
+
|
|
+* Math/MathJax features
|
|
+* Highlight Code Renderer
|
|
+* TOC table of content features
|
|
+* MultiMarkdown Metadata parser
|
|
+
|
|
+Get inspired with the contrib repository.
|
|
+
|
|
.. _`mistune-contrib`: https://github.com/lepture/mistune-contrib
|
|
diff --git a/mistune.py b/mistune.py
|
|
index 316f86d..86d215e 100644
|
|
--- a/mistune.py
|
|
+++ b/mistune.py
|
|
@@ -476,6 +476,11 @@ class InlineLexer(object):
|
|
'double_emphasis', 'emphasis', 'code',
|
|
'linebreak', 'strikethrough', 'text',
|
|
]
|
|
+ inline_html_rules = [
|
|
+ 'escape', 'autolink', 'url', 'link', 'reflink',
|
|
+ 'nolink', 'double_emphasis', 'emphasis', 'code',
|
|
+ 'linebreak', 'strikethrough', 'text',
|
|
+ ]
|
|
|
|
def __init__(self, renderer, rules=None, **kwargs):
|
|
self.renderer = renderer
|
|
@@ -491,6 +496,10 @@ class InlineLexer(object):
|
|
self._in_link = False
|
|
self._in_footnote = False
|
|
|
|
+ kwargs.update(self.renderer.options)
|
|
+ _to_parse = kwargs.get('parse_html') or kwargs.get('parse_inline_html')
|
|
+ self._parse_inline_html = _to_parse
|
|
+
|
|
def __call__(self, text):
|
|
return self.output(text)
|
|
|
|
@@ -553,7 +562,15 @@ class InlineLexer(object):
|
|
return self.renderer.autolink(link, False)
|
|
|
|
def output_inline_html(self, m):
|
|
- return self.renderer.inline_html(m.group(0))
|
|
+ text = m.group(0)
|
|
+ if self._parse_inline_html:
|
|
+ if m.group(1) == 'a':
|
|
+ self._in_link = True
|
|
+ text = self.output(text, rules=self.inline_html_rules)
|
|
+ self._in_link = False
|
|
+ else:
|
|
+ text = self.output(text, rules=self.inline_html_rules)
|
|
+ return self.renderer.inline_html(text)
|
|
|
|
def output_footnote(self, m):
|
|
key = _keyify(m.group(1))
|
|
@@ -909,6 +926,10 @@ class Markdown(object):
|
|
self.footnotes = []
|
|
self.tokens = []
|
|
|
|
+ # detect if it should parse text in block html
|
|
+ _to_parse = kwargs.get('parse_html') or kwargs.get('parse_block_html')
|
|
+ self._parse_block_html = _to_parse
|
|
+
|
|
def __call__(self, text):
|
|
return self.parse(text)
|
|
|
|
@@ -1072,7 +1093,7 @@ class Markdown(object):
|
|
|
|
def output_block_html(self):
|
|
text = self.token['text']
|
|
- if self.options.get('parse_html') and not self.token.get('pre'):
|
|
+ if self._parse_block_html and not self.token.get('pre'):
|
|
text = self.inline(text)
|
|
return self.renderer.block_html(text)
|
|
|
|
diff --git a/tests/test_cases.py b/tests/test_cases.py
|
|
index 933fa4c..3853a67 100644
|
|
--- a/tests/test_cases.py
|
|
+++ b/tests/test_cases.py
|
|
@@ -99,12 +99,36 @@ def test_use_xhtml():
|
|
assert '<img src="bar" alt="foo" title="title" />' in ret
|
|
|
|
|
|
-def test_block_html():
|
|
+def test_parse_html():
|
|
ret = mistune.markdown('<div>**foo**</div>')
|
|
assert '<strong>' not in ret
|
|
ret = mistune.markdown('<div>**foo**</div>', parse_html=True)
|
|
assert '<strong>' in ret
|
|
|
|
+ ret = mistune.markdown('<span>**foo**</span>')
|
|
+ assert '<strong>' not in ret
|
|
+ ret = mistune.markdown('<span>**foo**</span>', parse_html=True)
|
|
+ assert '<strong>' in ret
|
|
+
|
|
+ ret = mistune.markdown('<span>http://example.com</span>', parse_html=True)
|
|
+ assert 'href' in ret
|
|
+ ret = mistune.markdown('<a>http://example.com</a>', parse_html=True)
|
|
+ assert 'href' not in ret
|
|
+
|
|
+
|
|
+def test_parse_inline_html():
|
|
+ ret = mistune.markdown('<div>**foo**</div>', parse_inline_html=True)
|
|
+ assert '<strong>' not in ret
|
|
+ ret = mistune.markdown('<span>**foo**</span>', parse_inline_html=True)
|
|
+ assert '<strong>' in ret
|
|
+
|
|
+
|
|
+def test_parse_block_html():
|
|
+ ret = mistune.markdown('<div>**foo**</div>', parse_block_html=True)
|
|
+ assert '<strong>' in ret
|
|
+ ret = mistune.markdown('<span>**foo**</span>', parse_block_html=True)
|
|
+ assert '<strong>' not in ret
|
|
+
|
|
|
|
def test_trigger_more_cases():
|
|
markdown = mistune.Markdown(
|
|
@@ -114,79 +138,3 @@ def test_trigger_more_cases():
|
|
)
|
|
ret = markdown.render('foo[^foo]\n\n[^foo]: foo\n\n[^foo]: bar\n')
|
|
assert 'bar' not in ret
|
|
-
|
|
-
|
|
-def test_custom_lexer():
|
|
- import copy
|
|
-
|
|
- class MyInlineGrammar(mistune.InlineGrammar):
|
|
- # it would take a while for creating the right regex
|
|
- wiki_link = re.compile(
|
|
- r'\[\[' # [[
|
|
- r'([\s\S]+?\|[\s\S]+?)' # Page 2|Page 2
|
|
- r'\]\](?!\])' # ]]
|
|
- )
|
|
-
|
|
- class MyInlineLexer(mistune.InlineLexer):
|
|
- default_rules = copy.copy(mistune.InlineLexer.default_rules)
|
|
- default_rules.insert(3, 'wiki_link')
|
|
-
|
|
- def __init__(self, renderer, rules=None, **kwargs):
|
|
- if rules is None:
|
|
- rules = MyInlineGrammar()
|
|
-
|
|
- super(MyInlineLexer, self).__init__(renderer, rules, **kwargs)
|
|
-
|
|
- def output_wiki_link(self, m):
|
|
- text = m.group(1)
|
|
- alt, link = text.split('|')
|
|
- return '<a href="%s">%s</a>' % (link, alt)
|
|
-
|
|
- markdown = mistune.Markdown(inline=MyInlineLexer)
|
|
- ret = markdown('[[Link Text|Wiki Link]]')
|
|
- assert '<a href' in ret
|
|
-
|
|
-
|
|
-def test_token_tree():
|
|
- """Tests a Renderer that returns a list from the placeholder method."""
|
|
-
|
|
- class CustomRenderer(mistune.Renderer):
|
|
- def placeholder(self):
|
|
- return []
|
|
-
|
|
- def __getattribute__(self, name):
|
|
- """Saves the arguments to each Markdown handling method."""
|
|
- found = CustomRenderer.__dict__.get(name)
|
|
- if found:
|
|
- return object.__getattribute__(self, name)
|
|
-
|
|
- def fake_method(*args, **kwargs):
|
|
- return [(name, args, kwargs)]
|
|
- return fake_method
|
|
-
|
|
- with open(os.path.join(root, 'fixtures', 'data', 'tree.md')) as f:
|
|
- content = f.read()
|
|
-
|
|
- expected = [
|
|
- ('header', ([('text', ('Title here',), {})], 2, 'Title here'), {}),
|
|
- ('paragraph', ([('text', ('Some text.',), {})],), {}),
|
|
- ('paragraph',
|
|
- ([('text', ('In two paragraphs. And then a list.',), {})],),
|
|
- {}),
|
|
- ('list',
|
|
- ([('list_item', ([('text', ('foo',), {})],), {}),
|
|
- ('list_item',
|
|
- ([('text', ('bar',), {}),
|
|
- ('list',
|
|
- ([('list_item', ([('text', ('meep',), {})],), {}),
|
|
- ('list_item', ([('text', ('stuff',), {})],), {})],
|
|
- True),
|
|
- {})],),
|
|
- {})],
|
|
- False),
|
|
- {})
|
|
- ]
|
|
-
|
|
- processor = mistune.Markdown(renderer=CustomRenderer())
|
|
- found = processor.render(content)
|
|
- assert expected == found, "Expected:\n%r\n\nFound:\n%r" % (expected, found)
|
|
diff --git a/tests/test_subclassing.py b/tests/test_subclassing.py
|
|
index 2cebfc0..f0df225 100644
|
|
--- a/tests/test_subclassing.py
|
|
+++ b/tests/test_subclassing.py
|
|
@@ -2,6 +2,7 @@
|
|
|
|
import os
|
|
import re
|
|
+import copy
|
|
import mistune
|
|
|
|
root = os.path.dirname(__file__)
|
|
@@ -73,7 +74,7 @@ class MarkdownWithMath(mistune.Markdown):
|
|
)
|
|
|
|
|
|
-class CustomRenderer(mistune.Renderer):
|
|
+class MathRenderer(mistune.Renderer):
|
|
def block_math(self, text):
|
|
return '$$%s$$' % text
|
|
|
|
@@ -92,7 +93,7 @@ def assert_data(filename):
|
|
else:
|
|
text = filename
|
|
|
|
- rv = MarkdownWithMath(renderer=CustomRenderer()).render(text)
|
|
+ rv = MarkdownWithMath(renderer=MathRenderer()).render(text)
|
|
assert text in rv
|
|
|
|
|
|
@@ -109,3 +110,82 @@ def test_markdown2html_math():
|
|
def test_math_paragraph():
|
|
# https://github.com/ipython/ipython/issues/6724
|
|
assert_data('math-paragraph.md')
|
|
+
|
|
+
|
|
+class WikiInlineGrammar(mistune.InlineGrammar):
|
|
+ # it would take a while for creating the right regex
|
|
+ wiki_link = re.compile(
|
|
+ r'\[\[' # [[
|
|
+ r'([\s\S]+?\|[\s\S]+?)' # Page 2|Page 2
|
|
+ r'\]\](?!\])' # ]]
|
|
+ )
|
|
+
|
|
+
|
|
+class WikiInlineLexer(mistune.InlineLexer):
|
|
+ default_rules = copy.copy(mistune.InlineLexer.default_rules)
|
|
+ default_rules.insert(3, 'wiki_link')
|
|
+
|
|
+ def __init__(self, renderer, rules=None, **kwargs):
|
|
+ if rules is None:
|
|
+ rules = WikiInlineGrammar()
|
|
+
|
|
+ super(WikiInlineLexer, self).__init__(renderer, rules, **kwargs)
|
|
+
|
|
+ def output_wiki_link(self, m):
|
|
+ text = m.group(1)
|
|
+ alt, link = text.split('|')
|
|
+ return '<a href="%s">%s</a>' % (link, alt)
|
|
+
|
|
+
|
|
+def test_custom_lexer():
|
|
+ markdown = mistune.Markdown(inline=WikiInlineLexer)
|
|
+ ret = markdown('[[Link Text|Wiki Link]]')
|
|
+ assert '<a href' in ret
|
|
+
|
|
+
|
|
+class TokenTreeRenderer(mistune.Renderer):
|
|
+ # options is required
|
|
+ options = {}
|
|
+
|
|
+ def placeholder(self):
|
|
+ return []
|
|
+
|
|
+ def __getattribute__(self, name):
|
|
+ """Saves the arguments to each Markdown handling method."""
|
|
+ found = TokenTreeRenderer.__dict__.get(name)
|
|
+ if found is not None:
|
|
+ return object.__getattribute__(self, name)
|
|
+
|
|
+ def fake_method(*args, **kwargs):
|
|
+ return [(name, args, kwargs)]
|
|
+ return fake_method
|
|
+
|
|
+
|
|
+def test_token_tree():
|
|
+ """Tests a Renderer that returns a list from the placeholder method."""
|
|
+ with open(os.path.join(root, 'fixtures', 'data', 'tree.md')) as f:
|
|
+ content = f.read()
|
|
+
|
|
+ expected = [
|
|
+ ('header', ([('text', ('Title here',), {})], 2, 'Title here'), {}),
|
|
+ ('paragraph', ([('text', ('Some text.',), {})],), {}),
|
|
+ ('paragraph',
|
|
+ ([('text', ('In two paragraphs. And then a list.',), {})],),
|
|
+ {}),
|
|
+ ('list',
|
|
+ ([('list_item', ([('text', ('foo',), {})],), {}),
|
|
+ ('list_item',
|
|
+ ([('text', ('bar',), {}),
|
|
+ ('list',
|
|
+ ([('list_item', ([('text', ('meep',), {})],), {}),
|
|
+ ('list_item', ([('text', ('stuff',), {})],), {})],
|
|
+ True),
|
|
+ {})],),
|
|
+ {})],
|
|
+ False),
|
|
+ {})
|
|
+ ]
|
|
+
|
|
+ processor = mistune.Markdown(renderer=TokenTreeRenderer())
|
|
+ found = processor.render(content)
|
|
+ assert expected == found, "Expected:\n%r\n\nFound:\n%r" % (expected, found)
|