[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