[Python-modules-commits] [pymarkups] 01/04: Import pymarkups_2.0.0.orig.tar.gz
Dmitry Shachnev
mitya57 at moszumanska.debian.org
Wed May 11 11:12:30 UTC 2016
This is an automated email from the git hooks/post-receive script.
mitya57 pushed a commit to branch master
in repository pymarkups.
commit 8dba2e68c05d5b4e9e33408ddd09a9b10bc43398
Author: Dmitry Shachnev <mitya57 at gmail.com>
Date: Wed May 11 14:07:05 2016 +0300
Import pymarkups_2.0.0.orig.tar.gz
---
.travis.yml | 1 +
Markups.egg-info/PKG-INFO | 22 +++++++---
Markups.egg-info/SOURCES.txt | 1 +
PKG-INFO | 22 +++++++---
README.rst | 20 +++++++--
changelog | 17 ++++++++
docs/custom_markups.rst | 35 ++++++---------
docs/interface.rst | 8 ++++
docs/overview.rst | 11 +++--
markup2html.py | 35 +++++++++++++++
markups/__init__.py | 4 +-
markups/abstract.py | 98 ++++++++++++++++++++++++++++++++++--------
markups/markdown.py | 96 ++++++++++++++++++++++-------------------
markups/restructuredtext.py | 55 ++++++++++++++----------
markups/textile.py | 8 ++--
setup.cfg | 2 +-
tests/test_markdown.py | 56 +++++++++++++++---------
tests/test_restructuredtext.py | 38 +++++++++-------
tests/test_textile.py | 2 +-
19 files changed, 362 insertions(+), 169 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 4ad4dd0..2c72e09 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,5 +7,6 @@ python:
- "3.4"
- "3.5"
- "pypy"
+ - "pypy3"
install: pip install Markdown docutils textile
script: python -m unittest discover -s tests -v
diff --git a/Markups.egg-info/PKG-INFO b/Markups.egg-info/PKG-INFO
index 1eab7cc..55b0ba8 100644
--- a/Markups.egg-info/PKG-INFO
+++ b/Markups.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Markups
-Version: 1.0.1
+Version: 2.0.0
Summary: A wrapper around various text markups
Home-page: https://github.com/retext-project/pymarkups
Author: Dmitry Shachnev
@@ -32,10 +32,14 @@ Description:
...
... This is an example **reStructuredText** document.
... """
- >>> markup.get_document_title(text)
+ >>> result = markup.convert(text)
+ >>> result.get_document_title()
'Hello, world!'
- >>> markup.get_document_body(text)
- '<p>This is an example <strong>reStructuredText</strong> document.</p>\n'
+ >>> print(result.get_document_body()) # doctest: +NORMALIZE_WHITESPACE
+ <div class="document" id="hello-world">
+ <h1 class="title">Hello, world!</h1>
+ <p>This is an example <strong>reStructuredText</strong> document.</p>
+ </div>
.. _Markdown: http://daringfireball.net/projects/markdown/
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
@@ -44,9 +48,17 @@ Description:
The release version can be downloaded from PyPI_. The source code is hosted on
GitHub_.
- .. _PyPI: http://pypi.python.org/pypi/Markups
+ .. _PyPI: https://pypi.python.org/pypi/Markups
.. _GitHub: https://github.com/retext-project/pymarkups
+ The documentation is available online_ or can be generated from source by
+ installing Sphinx_ and running::
+
+ python3 setup.py build_sphinx
+
+ .. _online: https://pythonhosted.org/Markups/
+ .. _Sphinx: http://www.sphinx-doc.org/en/stable/
+
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
diff --git a/Markups.egg-info/SOURCES.txt b/Markups.egg-info/SOURCES.txt
index 52886cc..9132b9b 100644
--- a/Markups.egg-info/SOURCES.txt
+++ b/Markups.egg-info/SOURCES.txt
@@ -4,6 +4,7 @@ LICENSE
MANIFEST.in
README.rst
changelog
+markup2html.py
setup.py
Markups.egg-info/PKG-INFO
Markups.egg-info/SOURCES.txt
diff --git a/PKG-INFO b/PKG-INFO
index 1eab7cc..55b0ba8 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Markups
-Version: 1.0.1
+Version: 2.0.0
Summary: A wrapper around various text markups
Home-page: https://github.com/retext-project/pymarkups
Author: Dmitry Shachnev
@@ -32,10 +32,14 @@ Description:
...
... This is an example **reStructuredText** document.
... """
- >>> markup.get_document_title(text)
+ >>> result = markup.convert(text)
+ >>> result.get_document_title()
'Hello, world!'
- >>> markup.get_document_body(text)
- '<p>This is an example <strong>reStructuredText</strong> document.</p>\n'
+ >>> print(result.get_document_body()) # doctest: +NORMALIZE_WHITESPACE
+ <div class="document" id="hello-world">
+ <h1 class="title">Hello, world!</h1>
+ <p>This is an example <strong>reStructuredText</strong> document.</p>
+ </div>
.. _Markdown: http://daringfireball.net/projects/markdown/
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
@@ -44,9 +48,17 @@ Description:
The release version can be downloaded from PyPI_. The source code is hosted on
GitHub_.
- .. _PyPI: http://pypi.python.org/pypi/Markups
+ .. _PyPI: https://pypi.python.org/pypi/Markups
.. _GitHub: https://github.com/retext-project/pymarkups
+ The documentation is available online_ or can be generated from source by
+ installing Sphinx_ and running::
+
+ python3 setup.py build_sphinx
+
+ .. _online: https://pythonhosted.org/Markups/
+ .. _Sphinx: http://www.sphinx-doc.org/en/stable/
+
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
diff --git a/README.rst b/README.rst
index d27f40b..9f14081 100644
--- a/README.rst
+++ b/README.rst
@@ -23,10 +23,14 @@ Usage example:
...
... This is an example **reStructuredText** document.
... """
- >>> markup.get_document_title(text)
+ >>> result = markup.convert(text)
+ >>> result.get_document_title()
'Hello, world!'
- >>> markup.get_document_body(text)
- '<p>This is an example <strong>reStructuredText</strong> document.</p>\n'
+ >>> print(result.get_document_body()) # doctest: +NORMALIZE_WHITESPACE
+ <div class="document" id="hello-world">
+ <h1 class="title">Hello, world!</h1>
+ <p>This is an example <strong>reStructuredText</strong> document.</p>
+ </div>
.. _Markdown: http://daringfireball.net/projects/markdown/
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
@@ -35,5 +39,13 @@ Usage example:
The release version can be downloaded from PyPI_. The source code is hosted on
GitHub_.
-.. _PyPI: http://pypi.python.org/pypi/Markups
+.. _PyPI: https://pypi.python.org/pypi/Markups
.. _GitHub: https://github.com/retext-project/pymarkups
+
+The documentation is available online_ or can be generated from source by
+installing Sphinx_ and running::
+
+ python3 setup.py build_sphinx
+
+.. _online: https://pythonhosted.org/Markups/
+.. _Sphinx: http://www.sphinx-doc.org/en/stable/
diff --git a/changelog b/changelog
index 40dbdae..ebee1d9 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,20 @@
+Version 2.0.0, 2016-05-09
+=========================
+
+Incompatible changes:
+
+* Changed the API of pymarkups to clearly separate the conversion step from
+ access to the various elements of the result. The old API is deprecated
+ and will be removed in a future release. Please see the documentation for
+ details on using the new API.
+* The reStructuredText markup now includes document title and subtitle in
+ the HTML body.
+
+Other changes:
+
+* Added a ``markup2html.py`` reference script to show API usage.
+* Improved support for specifying Markdown extensions in the document.
+
Version 1.0.1, 2015-12-22
=========================
diff --git a/docs/custom_markups.rst b/docs/custom_markups.rst
index bc6d4b4..7a0d4be 100644
--- a/docs/custom_markups.rst
+++ b/docs/custom_markups.rst
@@ -35,29 +35,18 @@ case of success, and ``False`` in case of failure.
Implementing methods
====================
-Any markup must inherit from :class:`~markups.abstract.AbstractMarkup`
-class.
+Any markup must inherit from :class:`~markups.abstract.AbstractMarkup`.
-Third-party markups must implement
-:meth:`~markups.abstract.AbstractMarkup.get_document_body` method, which
-is the main method of any markup.
+Third-party markups must implement :class:`~markups.abstract.AbstractMarkup`'s
+:meth:`~markups.abstract.AbstractMarkup.convert` method, which must perform the
+time-consuming part of markup conversion and return a newly constructed
+instance of (a subclass of) :class:`~markups.abstract.ConvertedMarkup`.
-Other methods that are optional:
+:class:`~markups.abstract.ConvertedMarkup` encapsulates the title, body,
+stylesheet and javascript of a converted document. Of these only the body is
+required during construction, the others default to an empty string. If
+additional markup-specific state is required to implement
+:class:`~markups.abstract.ConvertedMarkup`, a subclass can be defined and an
+instance of it returned from :meth:`~markups.abstract.AbstractMarkup.convert`
+instead.
- * :meth:`~markups.abstract.AbstractMarkup.get_document_title`;
- * :meth:`~markups.abstract.AbstractMarkup.get_javascript`;
- * :meth:`~markups.abstract.AbstractMarkup.get_stylesheet`.
-
-Using the cache
-===============
-
-Markups are provided with :attr:`~markups.abstract.AbstractMarkup._cache`
-dictionary that can contain any data shared between subsequent calls to
-markup methods. Attribute :attr:`~markups.abstract._enable_cache`
-indicates whether or not the cache should be used (set to ``False`` by
-default).
-
-For example, :meth:`~markups.abstract.AbstractMarkup.get_whole_html`
-method sets :attr:`~markups.abstract._enable_cache` to ``True``, then
-subsequently retrieves document title, body, javascript and stylesheet,
-and sets :attr:`~markups.abstract._enable_cache` back to ``False``.
diff --git a/docs/interface.rst b/docs/interface.rst
index ec7ab26..69075f2 100644
--- a/docs/interface.rst
+++ b/docs/interface.rst
@@ -9,3 +9,11 @@ However, you shouldn't create direct instances of that class. Instead, use one o
.. autoclass:: markups.abstract.AbstractMarkup
:members:
+
+When :class:`~markups.abstract.AbstractMarkup`'s
+:meth:`~markups.abstract.AbstractMarkup.convert` method is called it will
+return an instance of :class:`~markups.abstract.ConvertedMarkup` or a subclass
+thereof that provides access to the conversion results.
+
+.. autoclass:: markups.abstract.ConvertedMarkup
+ :members:
diff --git a/docs/overview.rst b/docs/overview.rst
index 486ab10..321170b 100644
--- a/docs/overview.rst
+++ b/docs/overview.rst
@@ -2,15 +2,14 @@
API overview
============
-For the very basic usage of Python-Markups, one should import
-some markup class from :mod:`markups`, create an instance
-of that class, and use the methods provided by
-:class:`~markups.abstract.AbstractMarkup`:
+For the basic usage of Python-Markups, one should import some markup
+class from :mod:`markups`, create an instance of that class, and use
+the :meth:`~markups.abstract.AbstractMarkup.convert` method:
>>> import markups
>>> markup = markups.ReStructuredTextMarkup()
->>> markup.get_document_body('*reStructuredText* test')
-'<p><em>reStructuredText</em> test</p>\n'
+>>> markup.convert('*reStructuredText* test').get_document_body()
+'<div class="document">\n<p><em>reStructuredText</em> test</p>\n</div>\n'
For advanced usage (like dynamically choosing the markup class),
one may use one of the functions documented below.
diff --git a/markup2html.py b/markup2html.py
new file mode 100755
index 0000000..60d6eb2
--- /dev/null
+++ b/markup2html.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+
+import argparse
+import markups
+import sys
+
+
+def export_file(args):
+ markup = markups.get_markup_for_file_name(args.input_file)
+ with open(args.input_file) as input:
+ text = input.read()
+ if not markup:
+ sys.exit('Markup not available.')
+ converted = markup.convert(text)
+
+ html = converted.get_whole_html(include_stylesheet=args.include_stylesheet,
+ fallback_title=args.fallback_title,
+ webenv=args.web_environment)
+
+ with open(args.output_file, 'w') as output:
+ output.write(html)
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--web-environment', help='export for web environment',
+ action='store_true')
+ parser.add_argument('--include-stylesheet', help='embed the stylesheet into html',
+ action='store_true')
+ parser.add_argument('--fallback-title', help='fallback title of the HTML document',
+ metavar='TITLE')
+ parser.add_argument('input_file', help='input file')
+ parser.add_argument('output_file', help='output file')
+ args = parser.parse_args()
+ export_file(args)
diff --git a/markups/__init__.py b/markups/__init__.py
index 1fe1018..26e53f8 100644
--- a/markups/__init__.py
+++ b/markups/__init__.py
@@ -10,7 +10,7 @@ from markups.markdown import MarkdownMarkup
from markups.restructuredtext import ReStructuredTextMarkup
from markups.textile import TextileMarkup
-__version_tuple__ = (1, 0, 1)
+__version_tuple__ = (2, 0, 0)
__version__ = '.'.join(map(str, __version_tuple__))
builtin_markups = [MarkdownMarkup, ReStructuredTextMarkup, TextileMarkup]
@@ -73,7 +73,7 @@ def get_markup_for_file_name(filename, return_class=False):
>>> import markups
>>> markup = markups.get_markup_for_file_name('foo.mkd')
- >>> markup.get_document_body('**Test**')
+ >>> markup.convert('**Test**').get_document_body()
'<p><strong>Test</strong></p>\\n'
>>> markups.get_markup_for_file_name('bar.rst', return_class=True)
<class 'markups.restructuredtext.ReStructuredTextMarkup'>
diff --git a/markups/abstract.py b/markups/abstract.py
index b664dc4..87da48c 100644
--- a/markups/abstract.py
+++ b/markups/abstract.py
@@ -1,7 +1,20 @@
+# vim: ts=8:sts=8:sw=8:noexpandtab
+
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2014
+from functools import wraps
+from warnings import warn
+
+def _deprecated(function_in):
+ @wraps(function_in)
+ def function_out(*args, **kwargs):
+ warn('Method %s() is deprecated. Please use convert() instead.' %
+ function_in.__name__, DeprecationWarning, stacklevel=2)
+ return function_in(*args, **kwargs)
+ return function_out
+
class AbstractMarkup(object):
"""Abstract class for markup languages.
@@ -20,8 +33,6 @@ class AbstractMarkup(object):
def __init__(self, filename=None):
self.filename = filename
- self._enable_cache = False
- self._cache = {}
@staticmethod
def available():
@@ -34,53 +45,106 @@ class AbstractMarkup(object):
"""
return True
+ def convert(self, text):
+ """
+ :returns: a ConvertedMarkup instance (or a subclass thereof)
+ containing the markup converted to HTML
+ :rtype: ConvertedMarkup
+ """
+ raise NotImplementedError
+
+ @_deprecated
def get_document_title(self, text):
+ return self.convert(text).get_document_title()
+
+ @_deprecated
+ def get_document_body(self, text):
+ return self.convert(text).get_document_body()
+
+ @_deprecated
+ def get_stylesheet(self, text=''):
+ return self.convert(text).get_stylesheet()
+
+ @_deprecated
+ def get_javascript(self, text='', **kwargs):
+ return self.convert(text).get_javascript(**kwargs)
+
+ @_deprecated
+ def get_whole_html(self, text, **kwargs):
+ return self.convert(text).get_whole_html(**kwargs)
+
+
+class ConvertedMarkup(object):
+ """This class encapsulates the title, body, stylesheet and javascript
+ of a converted document.
+
+ Instances of this class are created by :meth:`.AbstractMarkup.convert`
+ method, usually it should not be instantiated directly.
+ """
+
+ def __init__(self, body, title='', stylesheet='', javascript=''):
+ self.title = title
+ self.stylesheet = stylesheet
+ self.javascript = javascript
+ self.body = body
+
+ def get_document_title(self):
"""
:returns: the document title
:rtype: str
"""
- return ''
+ return self.title
- def get_document_body(self, text):
+ def get_document_body(self):
"""
:returns: the contents of the ``<body>`` HTML tag
:rtype: str
"""
- raise NotImplementedError
+ return self.body
- def get_stylesheet(self, text=''):
+ def get_stylesheet(self):
"""
:returns: the contents of ``<style type="text/css">`` HTML tag
:rtype: str
"""
- return ''
+ return self.stylesheet
- def get_javascript(self, text='', webenv=False):
+ def get_javascript(self, webenv=False):
"""
:returns: one or more HTML tags to be inserted into the document
``<head>``.
:rtype: str
+ :param bool webenv: if true, the specific markups may optimize the
+ document for being used in the World Wide Web (for
+ example, a remote version of MathJax script can be
+ inserted instead of the local one).
"""
- return ''
+ return self.javascript
- def get_whole_html(self, text, custom_headers='', include_stylesheet=True,
+ def get_whole_html(self, custom_headers='', include_stylesheet=True,
fallback_title='', webenv=False):
"""
:returns: the full contents of the HTML document (unless overridden
this is a combination of the previous methods)
:rtype: str
+ :param str custom_headers: custom HTML to be inserted into the document
+ ``<head>``
+ :param bool include_stylesheet: if false, the stylesheet will not
+ be included in the document ``<head>``
+ :param str fallback_title: when impossible to get the ``<title>`` from
+ the document, this string can be used as a
+ fallback
+ :param bool webenv: like in :meth:`~.ConvertedMarkup.get_javascript`
+ above
"""
- self._enable_cache = True
- body = self.get_document_body(text)
- stylesheet = ('<style type="text/css">\n' + self.get_stylesheet(text)
+ body = self.get_document_body()
+ stylesheet = ('<style type="text/css">\n' + self.get_stylesheet()
+ '</style>\n' if include_stylesheet else '')
- title = self.get_document_title(text)
+ title = self.get_document_title()
if not title:
title = fallback_title
title_string = ('<title>' + title + '</title>\n') if title else ''
- javascript = self.get_javascript(text, webenv)
- self._enable_cache = False
- self._cache = {}
+ javascript = self.get_javascript(webenv)
return (
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n'
'<html>\n<head>\n'
diff --git a/markups/markdown.py b/markups/markdown.py
index 06184cb..863c426 100644
--- a/markups/markdown.py
+++ b/markups/markdown.py
@@ -1,3 +1,5 @@
+# vim: ts=8:sts=8:sw=8:noexpandtab
+
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2015
@@ -9,7 +11,7 @@ import os
import re
import warnings
import markups.common as common
-from markups.abstract import AbstractMarkup
+from markups.abstract import AbstractMarkup, ConvertedMarkup
MATHJAX_CONFIG = \
'''<script type="text/x-mathjax-config">
@@ -24,7 +26,10 @@ MathJax.Hub.Config({
</script>
'''
-extensions_re = re.compile(r'required.extensions: ([ \w\.\(\),=_]+)', flags=re.IGNORECASE)
+extensions_re = re.compile(r'required.extensions: (.+)', flags=re.IGNORECASE)
+extension_name_re = re.compile(r'[a-z0-9_.]+(?:\([^)]+\))?', flags=re.IGNORECASE)
+
+_canonicalized_ext_names = {}
class MarkdownMarkup(AbstractMarkup):
"""Markup class for Markdown language.
@@ -74,7 +79,7 @@ class MarkdownMarkup(AbstractMarkup):
lines = text.splitlines()
match = extensions_re.search(lines[0]) if lines else None
if match:
- return match.group(1).strip().split()
+ return extension_name_re.findall(match.group(1))
return []
def _canonicalize_extension_name(self, extension_name):
@@ -95,8 +100,8 @@ class MarkdownMarkup(AbstractMarkup):
return prefix + extension_name + parameters
def _apply_extensions(self):
- extensions = (self.requested_extensions or
- self.global_extensions) + self.document_extensions
+ extensions = (self.requested_extensions +
+ self.global_extensions + self.document_extensions)
extensions_final = []
should_push_extra = True
should_push_mathjax = (True, False)
@@ -107,11 +112,15 @@ class MarkdownMarkup(AbstractMarkup):
should_push_extra = False
should_push_mathjax = (False, )
else:
- canonical_name = self._canonicalize_extension_name(extension)
- if not canonical_name:
- warnings.warn('Extension "%s" does not exist.' %
- extension, ImportWarning)
- continue
+ if extension in _canonicalized_ext_names:
+ canonical_name = _canonicalized_ext_names[extension]
+ else:
+ canonical_name = self._canonicalize_extension_name(extension)
+ if canonical_name is None:
+ warnings.warn('Extension "%s" does not exist.' %
+ extension, ImportWarning)
+ continue
+ _canonicalized_ext_names[extension] = canonical_name
if canonical_name not in extensions_final:
extensions_final.append(canonical_name)
if should_push_extra:
@@ -127,44 +136,43 @@ class MarkdownMarkup(AbstractMarkup):
import markdown
self.markdown = markdown
self.requested_extensions = extensions or []
- self.global_extensions = self._get_global_extensions(filename)
+ if extensions is None:
+ self.global_extensions = self._get_global_extensions(filename)
+ else:
+ self.global_extensions = []
self.document_extensions = []
+ _canonicalized_ext_names = {}
+ self._apply_extensions()
+
+ def convert(self, text):
+
+ # Determine body
+ self.md.reset()
+ self.document_extensions = self._get_document_extensions(text)
self._apply_extensions()
+ body = self.md.convert(text) + '\n'
- def get_document_title(self, text):
- if not 'body' in self._cache:
- self.get_document_body(text)
+ # Determine title
if hasattr(self.md, 'Meta') and 'title' in self.md.Meta:
- return str.join(' ', self.md.Meta['title'])
+ title = str.join(' ', self.md.Meta['title'])
else:
- return ''
-
- def get_stylesheet(self, text=''):
- has_codehilite = False
- for extension in self.extensions:
- if extension.endswith('codehilite'):
- has_codehilite = True
- if has_codehilite:
- return common.get_pygments_stylesheet('.codehilite')
- return ''
-
- def get_javascript(self, text='', webenv=False):
- if 'body' in self._cache:
- body = self._cache['body']
+ title = ''
+
+ # Determine stylesheet
+ if any(extension.endswith('codehilite') for extension in self.extensions):
+ stylesheet = common.get_pygments_stylesheet('.codehilite')
else:
- body = self.get_document_body(text)
- if not '<script type="math/tex' in body:
- return ''
- return (MATHJAX_CONFIG + '<script type="text/javascript" src="'
- + common.get_mathjax_url(webenv) + '"></script>')
+ stylesheet = ''
- def get_document_body(self, text):
- self.md.reset()
- document_extensions = self._get_document_extensions(text)
- if document_extensions or self.document_extensions:
- self.document_extensions = document_extensions
- self._apply_extensions()
- converted_text = self.md.convert(text) + '\n'
- if self._enable_cache:
- self._cache['body'] = converted_text
- return converted_text
+ return ConvertedMarkdown(body, title, stylesheet)
+
+class ConvertedMarkdown(ConvertedMarkup):
+
+ def get_javascript(self, webenv=False):
+ if '<script type="math/tex' in self.body:
+ javascript = (MATHJAX_CONFIG + '<script type="text/javascript" src="'
+ + common.get_mathjax_url(webenv) + '"></script>')
+ else:
+ javascript = ''
+
+ return javascript
diff --git a/markups/restructuredtext.py b/markups/restructuredtext.py
index af052d9..ed31b82 100644
--- a/markups/restructuredtext.py
+++ b/markups/restructuredtext.py
@@ -1,9 +1,11 @@
+# vim: ts=8:sts=8:sw=8:noexpandtab
+
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2014
import markups.common as common
-from markups.abstract import AbstractMarkup
+from markups.abstract import AbstractMarkup, ConvertedMarkup
class ReStructuredTextMarkup(AbstractMarkup):
"""Markup class for reStructuredText language.
@@ -40,36 +42,45 @@ class ReStructuredTextMarkup(AbstractMarkup):
from docutils.core import publish_parts
self._publish_parts = publish_parts
- def publish_parts(self, text):
- if 'rest_parts' in self._cache:
- return self._cache['rest_parts']
+ def convert(self, text):
parts = self._publish_parts(text, source_path=self.filename,
writer_name='html', settings_overrides=self.overrides)
- if self._enable_cache:
- self._cache['rest_parts'] = parts
- return parts
- def get_document_title(self, text):
- return self.publish_parts(text)['title']
+ # Determine head
+ head = parts['head']
+
+ # Determine body
+ body = parts['html_body']
- def get_document_body(self, text):
- return self.publish_parts(text)['body']
+ # Determine title
+ title = parts['title']
- def get_stylesheet(self, text=''):
- origstyle = self.publish_parts(text)['stylesheet']
+ # Determine stylesheet
+ origstyle = parts['stylesheet']
# Cut off <style> and </style> tags
stylestart = '<style type="text/css">'
stylesheet = ''
if stylestart in origstyle:
stylesheet = origstyle[origstyle.find(stylestart)+25:origstyle.rfind('</style>')]
- return stylesheet + common.get_pygments_stylesheet('.code')
+ stylesheet += common.get_pygments_stylesheet('.code')
+
+ return ConvertedReStructuredText(head, body, title, stylesheet)
+
- def get_javascript(self, text='', webenv=False):
- head = self.publish_parts(text)['head']
- start_position = head.find('<script ')
- end_position = head.rfind('</script>')
+class ConvertedReStructuredText(ConvertedMarkup):
+
+ def __init__(self, head, body, title, stylesheet):
+ ConvertedMarkup.__init__(self, body, title, stylesheet)
+ self.head = head
+
+ def get_javascript(self, webenv=False):
+ start_position = self.head.find('<script ')
+ end_position = self.head.rfind('</script>')
if start_position >= 0 and end_position >= 0:
- mjurl = head[start_position:end_position+9]+'\n'
- return mjurl.replace(common.MATHJAX_WEB_URL,
- common.get_mathjax_url(webenv))
- return ''
+ mjurl = self.head[start_position:end_position+9]+'\n'
+ javascript = mjurl.replace(common.MATHJAX_WEB_URL,
+ common.get_mathjax_url(webenv))
+ else:
+ javascript = ''
+
+ return javascript
diff --git a/markups/textile.py b/markups/textile.py
index 086b7ad..0e20a74 100644
--- a/markups/textile.py
+++ b/markups/textile.py
@@ -1,3 +1,5 @@
+# vim: ts=8:sts=8:sw=8:noexpandtab
+
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2013-2015
@@ -5,7 +7,7 @@
from __future__ import absolute_import
import markups.common as common
-from markups.abstract import AbstractMarkup
+from markups.abstract import AbstractMarkup, ConvertedMarkup
class TextileMarkup(AbstractMarkup):
"""Markup class for Textile language.
@@ -34,5 +36,5 @@ class TextileMarkup(AbstractMarkup):
from textile import textile
self.textile = textile
- def get_document_body(self, text):
- return self.textile(text)
+ def convert(self, text):
+ return ConvertedMarkup(self.textile(text))
diff --git a/setup.cfg b/setup.cfg
index a669c45..861a9f5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
[egg_info]
-tag_svn_revision = 0
tag_build =
tag_date = 0
+tag_svn_revision = 0
diff --git a/tests/test_markdown.py b/tests/test_markdown.py
index c0d1d1e..24a89d4 100644
--- a/tests/test_markdown.py
+++ b/tests/test_markdown.py
@@ -1,9 +1,12 @@
+# vim: ts=8:sts=8:sw=8:noexpandtab
+
# This file is part of python-markups test suite
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2015
-from markups import MarkdownMarkup
+from markups.markdown import MarkdownMarkup, _canonicalized_ext_names
import unittest
+import warnings
tables_source = \
'''th1 | th2
@@ -132,9 +135,12 @@ r'''<p>
class MarkdownTest(unittest.TestCase):
maxDiff = None
+ def setUp(self):
+ warnings.simplefilter("ignore", Warning)
+
def test_empty_file(self):
markup = MarkdownMarkup()
- self.assertEqual(markup.get_document_body(''), '\n')
+ self.assertEqual(markup.convert('').get_document_body(), '\n')
def test_extensions_loading(self):
markup = MarkdownMarkup()
@@ -149,7 +155,7 @@ class MarkdownTest(unittest.TestCase):
markup = MarkdownMarkup(extensions=['markdown.extensions.footnotes'])
source = ('Footnotes[^1] have a label and the content.\n\n'
'[^1]: This is a footnote content.')
- html = markup.get_document_body(source)
+ html = markup.convert(source).get_document_body()
self.assertIn('<sup', html)
self.assertIn('footnote-backref', html)
@@ -160,39 +166,49 @@ class MarkdownTest(unittest.TestCase):
def test_extensions_parameters(self):
markup = MarkdownMarkup(extensions=['toc(anchorlink=1)'])
- html = markup.get_document_body('## Header')
+ html = markup.convert('## Header').get_document_body()
self.assertEqual(html,
'<h2 id="header"><a class="toclink" href="#header">Header</a></h2>\n')
+ self.assertEqual(_canonicalized_ext_names['toc(anchorlink=1)'],
+ 'markdown.extensions.toc(anchorlink=1)')
def test_document_extensions_parameters(self):
markup = MarkdownMarkup(extensions=[])
toc_header = '<!--- Required extensions: toc(anchorlink=1) --->\n\n'
- html = markup.get_document_body(toc_header + '## Header')
+ html = markup.convert(toc_header + '## Header').get_document_body()
self.assertEqual(html, toc_header +
'<h2 id="header"><a class="toclink" href="#header">Header</a></h2>\n')
+ toc_header = '<!--- Required extensions: toc(title=Table of contents, baselevel=3) wikilinks --->\n\n'
+ html = markup.convert(toc_header + '[TOC]\n\n# Header\n[[Link]]').get_document_body()
+ self.assertEqual(html, toc_header +
+ '<div class="toc"><span class="toctitle">Table of contents</span><ul>\n'
+ '<li><a href="#header">Header</a></li>\n'
+ '</ul>\n</div>\n'
+ '<h3 id="header">Header</h3>\n'
+ '<p><a class="wikilink" href="/Link/">Link</a></p>\n')
def test_extra(self):
markup = MarkdownMarkup()
- html = markup.get_document_body(tables_source)
+ html = markup.convert(tables_source).get_document_body()
self.assertEqual(tables_output, html)
- html = markup.get_document_body(deflists_source)
+ html = markup.convert(deflists_source).get_document_body()
self.assertEqual(deflists_output, html)
def test_remove_extra(self):
markup = MarkdownMarkup(extensions=['remove_extra'])
- html = markup.get_document_body(tables_source)
+ html = markup.convert(tables_source).get_document_body()
self.assertNotIn('<table>', html)
def test_remove_extra_document_extension(self):
markup = MarkdownMarkup(extensions=[])
- html = markup.get_document_body(
+ html = markup.convert(
'Required-Extensions: remove_extra\n\n' +
- tables_source)
+ tables_source).get_document_body()
self.assertNotIn('<table>', html)
def test_remove_extra_removes_mathjax(self):
markup = MarkdownMarkup(extensions=['remove_extra'])
- html = markup.get_document_body('$$1$$')
+ html = markup.convert('$$1$$').get_document_body()
self.assertNotIn('math/tex', html)
def test_meta(self):
@@ -200,39 +216,39 @@ class MarkdownTest(unittest.TestCase):
text = ('Required-Extensions: meta\n'
'Title: Hello, world!\n\n'
'Some text here.')
- title = markup.get_document_title(text)
+ title = markup.convert(text).get_document_title()
self.assertEqual('Hello, world!', title)
def test_default_math(self):
# by default $...$ delimeter should be disabled
markup = MarkdownMarkup(extensions=[])
- self.assertEqual('<p>$1$</p>\n', markup.get_document_body('$1$'))
+ self.assertEqual('<p>$1$</p>\n', markup.convert('$1$').get_document_body())
self.assertEqual('<p>\n<script type="math/tex; mode=display">1</script>\n</p>\n',
- markup.get_document_body('$$1$$'))
+ markup.convert('$$1$$').get_document_body())
def test_mathjax(self):
markup = MarkdownMarkup(extensions=['mathjax'])
# Escaping should work
- self.assertEqual('', markup.get_javascript('Hello, \\$2+2$!'))
- js = markup.get_javascript(mathjax_source)
+ self.assertEqual('', markup.convert('Hello, \\$2+2$!').get_javascript())
+ js = markup.convert(mathjax_source).get_javascript()
self.assertIn('<script', js)
- body = markup.get_document_body(mathjax_source)
+ body = markup.convert(mathjax_source).get_document_body()
self.assertEqual(mathjax_output, body)
def test_mathjax_document_extension(self):
markup = MarkdownMarkup()
text = mathjax_header + mathjax_source
- body = markup.get_document_body(text)
+ body = markup.convert(text).get_document_body()
self.assertEqual(mathjax_header + mathjax_output, body)
def test_mathjax_multiline(self):
markup = MarkdownMarkup(extensions=['mathjax'])
- body = markup.get_document_body(mathjax_multiline_source)
+ body = markup.convert(mathjax_multiline_source).get_document_body()
self.assertEqual(mathjax_multiline_output, body)
def test_mathjax_multilevel(self):
markup = MarkdownMarkup()
- body = markup.get_document_body(mathjax_multilevel_source)
+ body = markup.convert(mathjax_multilevel_source).get_document_body()
self.assertEqual(mathjax_multilevel_output, body)
@unittest.skipUnless(hasattr(unittest.TestCase, 'assertWarnsRegex'), 'assertWarnsRegex is not supported')
diff --git a/tests/test_restructuredtext.py b/tests/test_restructuredtext.py
index eac8351..7d7a147 100644
--- a/tests/test_restructuredtext.py
+++ b/tests/test_restructuredtext.py
@@ -1,3 +1,5 @@
+# vim: ts=8:sts=8:sw=8:noexpandtab
+
# This file is part of python-markups test suite
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2014
@@ -9,45 +11,49 @@ basic_text = \
'''Hello, world!
=============
+Some subtitle
+~~~~~~~~~~~~~
+
This is an example **reStructuredText** document.'''
@unittest.skipUnless(ReStructuredTextMarkup.available(), 'Docutils not available')
class ReStructuredTextTest(unittest.TestCase):
def test_basic(self):
markup = ReStructuredTextMarkup()
- text = markup.get_document_body(basic_text)
- title = markup.get_document_title(basic_text)
- markup._enable_cache = True
- text_from_cache = markup.get_document_body(basic_text)
- title_from_cache = markup.get_document_title(basic_text)
- text_expected = \
- '<p>This is an example <strong>reStructuredText</strong> document.</p>\n'
+ converted = markup.convert(basic_text)
+ text = converted.get_document_body()
+ title = converted.get_document_title()
+ stylesheet = converted.get_stylesheet()
+ text_expected = ('<div class="document" id="hello-world">\n'
+ '<h1 class="title">Hello, world!</h1>\n'
+ '<h2 class="subtitle" id="some-subtitle">Some subtitle</h2>\n'
+ '<p>This is an example <strong>reStructuredText</strong> document.</p>\n'
+ '</div>\n')
title_expected = 'Hello, world!'
self.assertEqual(text_expected, text)
- self.assertEqual(text_expected, text_from_cache)
self.assertEqual(title_expected, title)
- self.assertEqual(title_expected, title_from_cache)
+ self.assertIn('.code', stylesheet)
def test_mathjax_loading(self):
markup = ReStructuredTextMarkup()
- self.assertEqual('', markup.get_javascript('Hello, world!'))
- js = markup.get_javascript('Hello, :math:`2+2`!')
+ self.assertEqual('', markup.convert('Hello, world!').get_javascript())
+ js = markup.convert('Hello, :math:`2+2`!').get_javascript()
self.assertIn('<script', js)
- body = markup.get_document_body('Hello, :math:`2+2`!')
+ body = markup.convert('Hello, :math:`2+2`!').get_document_body()
self.assertIn('<span class="math">', body)
self.assertIn(r'\(2+2\)</span>', body)
def test_errors(self):
markup = ReStructuredTextMarkup('/dev/null',
- settings_overrides = {'warning_stream': False})
- body = markup.get_document_body('`') # unclosed role
+ settings_overrides = {'warning_stream': False})
+ body = markup.convert('`').get_document_body() # unclosed role
... 25 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pymarkups.git
More information about the Python-modules-commits
mailing list