Markups-1.0.1/0000755000175000017500000000000012636260065014003 5ustar dmitrydmitry00000000000000Markups-1.0.1/docs/0000755000175000017500000000000012636260064014732 5ustar dmitrydmitry00000000000000Markups-1.0.1/docs/overview.rst0000644000175000017500000000240512561175331017332 0ustar dmitrydmitry00000000000000============ 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`: >>> import markups >>> markup = markups.ReStructuredTextMarkup() >>> markup.get_document_body('*reStructuredText* test') '

reStructuredText test

\n' For advanced usage (like dynamically choosing the markup class), one may use one of the functions documented below. Getting lists of available markups ================================== .. autofunction:: markups.get_all_markups .. autofunction:: markups.get_available_markups .. autofunction:: markups.get_custom_markups Getting a specific markup ========================= .. autofunction:: markups.get_markup_for_file_name .. autofunction:: markups.find_markup_class_by_name .. _configuration-directory: Configuration directory ======================= Some markups can provide configuration files that the user may use to change the behavior. These files are stored in a single configuration directory. If :envvar:`XDG_CONFIG_HOME` is defined, then the configuration directory is it. Otherwise, it is :file:`.config` subdirectory in the user's home directory. Markups-1.0.1/docs/interface.rst0000644000175000017500000000052512561175331017425 0ustar dmitrydmitry00000000000000================ Markup interface ================ The main class for interacting with markups is :class:`~markups.abstract.AbstractMarkup`. However, you shouldn't create direct instances of that class. Instead, use one of the :doc:`standard markup classes `. .. autoclass:: markups.abstract.AbstractMarkup :members: Markups-1.0.1/docs/standard_markups.rst0000644000175000017500000000542612633272000021023 0ustar dmitrydmitry00000000000000================ Built-in markups ================ These markups are available by default: Markdown markup =============== Markdown_ markup uses Python-Markdown_ as a backend (version 2.6 is required). There are several ways to enable `Python-Markdown extensions`_. * List extensions in a file named :file:`markdown-extensions.txt` in the :ref:`configuration directory `, separated by newline. The extensions will be automatically applied to all documents. * If :file:`markdown-extensions.txt` is placed into working directory, all documents in that directory will get extensions listed in that file. * If first line of a document contains ":samp:`Required extensions: {ext1 ext2 ...}`", that list will be applied to a document. * Finally, one can programmatically pass list of extension names to :class:`markups.MarkdownMarkup` constructor. Additionally to features provided by Python-Markdown, this markup also supports a syntax for LaTeX-style math formulas (powered by MathJax_). The delimiters are: ================ =============== Inline math Standalone math ================ =============== ``$...$`` [#f1]_ ``$$...$$`` ``\(...\)`` ``\[...\]`` ================ =============== .. [#f1] To enable single-dollar-sign delimiter, one should enable virtual ``mathjax`` extension. The `Python-Markdown Extra`_ set of extensions is enabled by default. To disable it, one can enable virtual ``remove_extra`` extension (which also completely disables LaTeX formulas support). The default file extension associated with Markdown markup is ``.mkd``, though many other extensions (including ``.md`` and ``.markdown``) are supported as well. .. _Markdown: http://daringfireball.net/projects/markdown/ .. _Python-Markdown: https://pythonhosted.org/Markdown/ .. _MathJax: https://www.mathjax.org/ .. _`Python-Markdown extensions`: http://pythonhosted.org/Markdown/extensions/ .. _`Python-Markdown Extra`: http://pythonhosted.org/Markdown/extensions/extra.html .. autoclass:: markups.MarkdownMarkup reStructuredText markup ======================== This markup provides support for reStructuredText_ language (the language this documentation is written in). It uses Docutils_ Python module. The file extension associated with reStructuredText markup is ``.rst``. .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Docutils: http://docutils.sourceforge.net/ .. autoclass:: markups.ReStructuredTextMarkup Textile markup ============== This markup provides support for Textile_ language. It uses python-textile_ module. The file extension associated with Textile markup is ``.textile``. .. _Textile: https://en.wikipedia.org/wiki/Textile_(markup_language) .. _python-textile: https://github.com/textile/python-textile .. autoclass:: markups.TextileMarkup Markups-1.0.1/docs/conf.py0000644000175000017500000000306112633313326016226 0ustar dmitrydmitry00000000000000#!/usr/bin/env python3 import sys import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('..')) # -- General configuration ------------------------------------------------ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Python-Markups' copyright = u'2015, Dmitry Shachnev' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. from markups import __version_tuple__ # The short X.Y version. version = '%d.%d' % __version_tuple__[:2] # The full version, including alpha/beta/rc tags. release = '%d.%d.%d' % __version_tuple__ # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'nature' Markups-1.0.1/docs/custom_markups.rst0000644000175000017500000000422612561175331020543 0ustar dmitrydmitry00000000000000============== Custom Markups ============== Registering the markup module ============================= A third-party markup is a Python module that can be installed the usual way. Every module should have :data:`markup` property pointing to the markup class. To register the markup, one should append the full module name to file named ``pymarkups.txt`` in the :ref:`configuration directory `. To check if the module was found by Python-Markups, one can check if the module is present in return value of :func:`~markups.get_custom_markups` function. .. versionchanged:: 0.6 The third-party markup is now a normal Python module, not necessarily a file in ``markups`` namespace. Importing third-party modules ============================= A markup must not directly import any third party Python module it uses at file level. Instead, it should check the module availability in :meth:`~markups.abstract.AbstractMarkup.available` static method. That method can try to import the needed modules, and return ``True`` in case of success, and ``False`` in case of failure. Implementing methods ==================== Any markup must inherit from :class:`~markups.abstract.AbstractMarkup` class. Third-party markups must implement :meth:`~markups.abstract.AbstractMarkup.get_document_body` method, which is the main method of any markup. Other methods that are optional: * :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``. Markups-1.0.1/docs/changelog.rst0000644000175000017500000000050012575334254017413 0ustar dmitrydmitry00000000000000======================== Python-Markups changelog ======================== This changelog only lists the most important changes that happened in Python-Markups. Please see the `Git log`_ for the full list of changes. .. _`Git log`: https://github.com/retext-project/pymarkups/commits/master .. include:: ../changelog Markups-1.0.1/docs/index.rst0000644000175000017500000000177612575334301016604 0ustar dmitrydmitry00000000000000=================================== Python-Markups module documentation =================================== Introduction to Python-Markups ============================== Python-Markups is a module that provides unified interface for using various markup languages, such as Markdown, reStructuredText, and Textile. It is also possible for clients to create and register their own markup languages. The output language Python-Markups works with is HTML. Stylesheets and JavaScript sections are supported. The abstract interface that any markup implements is :class:`~markups.abstract.AbstractMarkup`. Contents ======== .. toctree:: overview interface standard_markups custom_markups changelog Links ===== * Python-Markups source code is hosted on GitHub_. * You can get the source tarball from PyPI_. * It is also packaged in Debian_. .. _GitHub: https://github.com/retext-project/pymarkups .. _PyPI: https://pypi.python.org/pypi/Markups .. _Debian: https://packages.debian.org/sid/source/pymarkups Markups-1.0.1/changelog0000644000175000017500000000617212636257360015667 0ustar dmitrydmitry00000000000000Version 1.0.1, 2015-12-22 ========================= * The Textile markup now uses the recommended python-textile API. * Fixed warnings during installation. * Python-Markdown Math extension updated to the latest version. Version 1.0, 2015-12-13 ======================= * Web module removed, as ReText no longer needs it. * Textile markup updated to work with the latest version of Python-Textile module. * The setup script now uses setuptools when it is available. * Testsuite and documentation improvements. Version 0.6.3, 2015-06-16 ========================= * No-change re-upload with fixed tarball and changelog. Version 0.6.2, 2015-06-09 ========================= * Markdown markup: fixed detection of codehilite extension with options. * Added a warning about deprecation of the markups.web module. Version 0.6.1, 2015-04-19 ========================= * PyMarkups now uses warnings system instead of printing messages to stderr. * Improvements to Markdown markup: + Fixed parsing math that contains nested environments (thanks to Gautam Iyer for the patch). + Fixed crash on extensions names starting with dot. * Miscellaneous fixes. Version 0.6, 2015-01-25 ======================= Incompatible changes: * Custom markups are now normal Python modules. * Web module no longer supports Python 2.x. Other changes: * Refactor the code related to Markdown extensions to make it work with upcoming Python-Markdown releases. * MathJax extension is now in a separate module. Version 0.5.2, 2014-11-05 ========================= * Fixed loading of Markdown extensions with options. Version 0.5.1, 2014-09-16 ========================= * Fixed Markdown markup crash on empty files. * Include documentation in the tarballs. * Testsuite improvements. Version 0.5, 2014-07-25 ======================= * Improvements to Markdown markup: + All math delimeters except ``$...$`` are now enabled by default. + ``remove_extra`` extension now disables formulas support. + It is now possible to specify required extensions in the first line of the file. * Add Sphinx documentation. Version 0.4, 2013-11-30 ======================= * Add Textile markup. * reStructuredText markup now supports file names and settings overrides. * Web module now raises WebUpdateError when updating fails. Version 0.3, 2013-07-25 ======================= * MathJax support in Markdown has been improved and no longer relies on tex2jax extension. * It is now possible to pass extensions list to MarkdownMarkup constructor. * Pygments style is now configurable. * Testsuite improvements. Version 0.2.3, 2012-11-02 ========================= * Fix support for custom working directory in web module. * Bug fixes in Markdown module and tests. Version 0.2.2, 2012-10-02 ========================= * Re-written math support for Markdown. * Add tests to the tarball. * Add example template for web module. * Bug fixes in Markdown and web modules. Version 0.2.1, 2012-09-09 ========================= * Add caching support, to speed up get_document_body function. * Add testsuite. * Fix some bugs in markdown module. Version 0.2, 2012-09-04 ======================= * Initial release. Markups-1.0.1/markups/0000755000175000017500000000000012636260064015464 5ustar dmitrydmitry00000000000000Markups-1.0.1/markups/restructuredtext.py0000644000175000017500000000471312561175331021502 0ustar dmitrydmitry00000000000000# 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 class ReStructuredTextMarkup(AbstractMarkup): """Markup class for reStructuredText language. Inherits :class:`~markups.abstract.AbstractMarkup`. :param settings_overrides: optional dictionary of overrides for the `Docutils settings`_ :type settings_overrides: dict .. _`Docutils settings`: http://docutils.sourceforge.net/docs/user/config.html """ name = 'reStructuredText' attributes = { common.LANGUAGE_HOME_PAGE: 'http://docutils.sourceforge.net/rst.html', common.MODULE_HOME_PAGE: 'http://docutils.sourceforge.net/', common.SYNTAX_DOCUMENTATION: 'http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html' } file_extensions = ('.rst', '.rest') default_extension = '.rst' @staticmethod def available(): try: import docutils.core except ImportError: return False return True def __init__(self, filename=None, settings_overrides=None): self.overrides = settings_overrides or {} self.overrides.update({'math_output': 'MathJax'}) AbstractMarkup.__init__(self, filename) 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'] 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'] def get_document_body(self, text): return self.publish_parts(text)['body'] def get_stylesheet(self, text=''): origstyle = self.publish_parts(text)['stylesheet'] # Cut off tags stylestart = '')] return stylesheet + common.get_pygments_stylesheet('.code') def get_javascript(self, text='', webenv=False): head = self.publish_parts(text)['head'] start_position = head.find(' ''' extensions_re = re.compile(r'required.extensions: ([ \w\.\(\),=_]+)', flags=re.IGNORECASE) class MarkdownMarkup(AbstractMarkup): """Markup class for Markdown language. Inherits :class:`~markups.abstract.AbstractMarkup`. :param extensions: list of extension names :type extensions: list """ name = 'Markdown' attributes = { common.LANGUAGE_HOME_PAGE: 'http://daringfireball.net/projects/markdown/', common.MODULE_HOME_PAGE: 'https://github.com/Waylan/Python-Markdown/', common.SYNTAX_DOCUMENTATION: 'http://daringfireball.net/projects/markdown/syntax' } file_extensions = ('.md', '.mkd', '.mkdn', '.mdwn', '.mdown', '.markdown') default_extension = '.mkd' @staticmethod def available(): try: import markdown except ImportError: return False return hasattr(markdown, 'version_info') and markdown.version_info >= (2, 6) def _load_extensions_list_from_file(self, filename): try: extensions_file = open(filename) except IOError: return [] else: extensions = [line.rstrip() for line in extensions_file if not line.startswith('#')] extensions_file.close() return extensions def _get_global_extensions(self, filename): extensions = self._load_extensions_list_from_file( os.path.join(common.CONFIGURATION_DIR, 'markdown-extensions.txt')) local_directory = os.path.dirname(filename) if filename else '' extensions += self._load_extensions_list_from_file( os.path.join(local_directory, 'markdown-extensions.txt')) return extensions def _get_document_extensions(self, text): lines = text.splitlines() match = extensions_re.search(lines[0]) if lines else None if match: return match.group(1).strip().split() return [] def _canonicalize_extension_name(self, extension_name): lb = extension_name.find('(') if lb >= 0: extension_name, parameters = extension_name[:lb], extension_name[lb:] else: parameters = '' prefixes = ('markdown.extensions.', '', 'mdx_') for prefix in prefixes: try: module = importlib.import_module(prefix + extension_name) if not hasattr(module, 'makeExtension'): continue except (ImportError, ValueError, TypeError): pass else: return prefix + extension_name + parameters def _apply_extensions(self): extensions = (self.requested_extensions or self.global_extensions) + self.document_extensions extensions_final = [] should_push_extra = True should_push_mathjax = (True, False) for extension in extensions: if extension == 'mathjax': should_push_mathjax = (True, True) elif extension == 'remove_extra': 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 canonical_name not in extensions_final: extensions_final.append(canonical_name) if should_push_extra: extensions_final.append('markdown.extensions.extra') if should_push_mathjax[0]: extensions_final.append('markups.mdx_mathjax(enable_dollar_delimiter=%r)' % should_push_mathjax[1]) self.md = self.markdown.Markdown(extensions=extensions_final, output_format='html4') self.extensions = extensions_final def __init__(self, filename=None, extensions=None): AbstractMarkup.__init__(self, filename) import markdown self.markdown = markdown self.requested_extensions = extensions or [] self.global_extensions = self._get_global_extensions(filename) self.document_extensions = [] self._apply_extensions() def get_document_title(self, text): if not 'body' in self._cache: self.get_document_body(text) if hasattr(self.md, 'Meta') and 'title' in self.md.Meta: return 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'] else: body = self.get_document_body(text) if not '') 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 Markups-1.0.1/markups/abstract.py0000644000175000017500000000461612561175331017647 0ustar dmitrydmitry00000000000000# This file is part of python-markups module # License: BSD # Copyright: (C) Dmitry Shachnev, 2012-2014 class AbstractMarkup(object): """Abstract class for markup languages. :param filename: optional name of the file :type filename: str """ #: name of the markup visible to user name = '' #: various attributes, like links to website and syntax documentation attributes = {} #: indicates which file extensions are associated with the markup file_extensions = () #: the default file extension default_extension = '' def __init__(self, filename=None): self.filename = filename self._enable_cache = False self._cache = {} @staticmethod def available(): """ :returns: whether the markup is ready for use (for example, whether the required third-party modules are importable) :rtype: bool """ return True def get_document_title(self, text): """ :returns: the document title :rtype: str """ return '' def get_document_body(self, text): """ :returns: the contents of the ```` HTML tag :rtype: str """ raise NotImplementedError def get_stylesheet(self, text=''): """ :returns: the contents of ``\n' if include_stylesheet else '') title = self.get_document_title(text) if not title: title = fallback_title title_string = ('' + title + '\n') if title else '' javascript = self.get_javascript(text, webenv) self._enable_cache = False self._cache = {} return ( '\n' '\n\n' '\n' + custom_headers + title_string + stylesheet + javascript + '\n\n' + body + '\n\n' ) Markups-1.0.1/markups/common.py0000644000175000017500000000166012602764711017332 0ustar dmitrydmitry00000000000000# This file is part of python-markups module # License: BSD # Copyright: (C) Dmitry Shachnev, 2012-2015 import os.path # Some common constants and functions (LANGUAGE_HOME_PAGE, MODULE_HOME_PAGE, SYNTAX_DOCUMENTATION) = range(3) CONFIGURATION_DIR = (os.getenv('XDG_CONFIG_HOME') or os.getenv('APPDATA') or os.path.expanduser('~/.config')) MATHJAX_LOCAL_URL = 'file:///usr/share/javascript/mathjax/MathJax.js' MATHJAX_WEB_URL = 'https://cdn.mathjax.org/mathjax/latest/MathJax.js' PYGMENTS_STYLE = 'default' def get_pygments_stylesheet(selector, style=None): if style is None: style = PYGMENTS_STYLE if style == '': return '' try: from pygments.formatters import HtmlFormatter except ImportError: return '' else: return HtmlFormatter(style=style).get_style_defs(selector) + '\n' def get_mathjax_url(webenv): if os.path.exists(MATHJAX_LOCAL_URL[7:]) and not webenv: return MATHJAX_LOCAL_URL else: return MATHJAX_WEB_URL Markups-1.0.1/markups/mdx_mathjax.py0000644000175000017500000000457212633336576020363 0ustar dmitrydmitry00000000000000# This file is part of python-markups module # License: BSD # Copyright: (C) Dmitry Shachnev, 2015 # Maintained in https://github.com/mitya57/python-markdown-math ''' Math extension for Python-Markdown ================================== Adds support for displaying math formulas using [MathJax](http://www.mathjax.org/). Author: 2015, Dmitry Shachnev . ''' from __future__ import absolute_import import markdown class MathExtension(markdown.extensions.Extension): def __init__(self, *args, **kwargs): self.config = { 'enable_dollar_delimiter': [False, 'Enable single-dollar delimiter'], } super(MathExtension, self).__init__(*args, **kwargs) def extendMarkdown(self, md, md_globals): def handle_match_inline(m): node = markdown.util.etree.Element('script') node.set('type', 'math/tex') node.text = markdown.util.AtomicString(m.group(3)) return node def handle_match(m): node = markdown.util.etree.Element('script') node.set('type', 'math/tex; mode=display') if '\\begin' in m.group(2): node.text = markdown.util.AtomicString(m.group(2) + m.group(4) + m.group(5)) else: node.text = markdown.util.AtomicString(m.group(3)) return node inlinemathpatterns = ( markdown.inlinepatterns.Pattern(r'(?>> import markups >>> markup = markups.get_markup_for_file_name("myfile.rst") >>> markup.name 'reStructuredText' >>> markup.attributes[markups.common.SYNTAX_DOCUMENTATION] 'http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html' >>> text = """ ... Hello, world! ... ============= ... ... This is an example **reStructuredText** document. ... """ >>> markup.get_document_title(text) 'Hello, world!' >>> markup.get_document_body(text) '

This is an example reStructuredText document.

\n' .. _Markdown: http://daringfireball.net/projects/markdown/ .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Textile: https://en.wikipedia.org/wiki/Textile_(markup_language) The release version can be downloaded from PyPI_. The source code is hosted on GitHub_. .. _PyPI: http://pypi.python.org/pypi/Markups .. _GitHub: https://github.com/retext-project/pymarkups 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: Programming Language :: Python :: 3.5 Classifier: Topic :: Text Processing :: Markup Classifier: Topic :: Text Processing :: General Classifier: Topic :: Software Development :: Libraries :: Python Modules Markups-1.0.1/Markups.egg-info/dependency_links.txt0000644000175000017500000000000112636260064023164 0ustar dmitrydmitry00000000000000 Markups-1.0.1/Markups.egg-info/top_level.txt0000644000175000017500000000001012636260064021637 0ustar dmitrydmitry00000000000000markups Markups-1.0.1/Markups.egg-info/SOURCES.txt0000644000175000017500000000112512636260064021001 0ustar dmitrydmitry00000000000000.gitignore .travis.yml LICENSE MANIFEST.in README.rst changelog setup.py Markups.egg-info/PKG-INFO Markups.egg-info/SOURCES.txt Markups.egg-info/dependency_links.txt Markups.egg-info/top_level.txt docs/changelog.rst docs/conf.py docs/custom_markups.rst docs/index.rst docs/interface.rst docs/overview.rst docs/standard_markups.rst markups/__init__.py markups/abstract.py markups/common.py markups/markdown.py markups/mdx_mathjax.py markups/restructuredtext.py markups/textile.py tests/__init__.py tests/test_markdown.py tests/test_public_api.py tests/test_restructuredtext.py tests/test_textile.pyMarkups-1.0.1/PKG-INFO0000644000175000017500000000503412636260065015102 0ustar dmitrydmitry00000000000000Metadata-Version: 1.1 Name: Markups Version: 1.0.1 Summary: A wrapper around various text markups Home-page: https://github.com/retext-project/pymarkups Author: Dmitry Shachnev Author-email: mitya57@gmail.com License: BSD Description: .. image:: https://api.travis-ci.org/retext-project/pymarkups.svg :target: https://travis-ci.org/retext-project/pymarkups :alt: Travis CI status This module provides a wrapper around various text markup languages. Available by default are Markdown_, reStructuredText_ and Textile_, but you can easily add your own markups. Usage example: .. code:: python >>> import markups >>> markup = markups.get_markup_for_file_name("myfile.rst") >>> markup.name 'reStructuredText' >>> markup.attributes[markups.common.SYNTAX_DOCUMENTATION] 'http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html' >>> text = """ ... Hello, world! ... ============= ... ... This is an example **reStructuredText** document. ... """ >>> markup.get_document_title(text) 'Hello, world!' >>> markup.get_document_body(text) '

This is an example reStructuredText document.

\n' .. _Markdown: http://daringfireball.net/projects/markdown/ .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Textile: https://en.wikipedia.org/wiki/Textile_(markup_language) The release version can be downloaded from PyPI_. The source code is hosted on GitHub_. .. _PyPI: http://pypi.python.org/pypi/Markups .. _GitHub: https://github.com/retext-project/pymarkups 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: Programming Language :: Python :: 3.5 Classifier: Topic :: Text Processing :: Markup Classifier: Topic :: Text Processing :: General Classifier: Topic :: Software Development :: Libraries :: Python Modules Markups-1.0.1/README.rst0000644000175000017500000000242612633315323015471 0ustar dmitrydmitry00000000000000.. image:: https://api.travis-ci.org/retext-project/pymarkups.svg :target: https://travis-ci.org/retext-project/pymarkups :alt: Travis CI status This module provides a wrapper around various text markup languages. Available by default are Markdown_, reStructuredText_ and Textile_, but you can easily add your own markups. Usage example: .. code:: python >>> import markups >>> markup = markups.get_markup_for_file_name("myfile.rst") >>> markup.name 'reStructuredText' >>> markup.attributes[markups.common.SYNTAX_DOCUMENTATION] 'http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html' >>> text = """ ... Hello, world! ... ============= ... ... This is an example **reStructuredText** document. ... """ >>> markup.get_document_title(text) 'Hello, world!' >>> markup.get_document_body(text) '

This is an example reStructuredText document.

\n' .. _Markdown: http://daringfireball.net/projects/markdown/ .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Textile: https://en.wikipedia.org/wiki/Textile_(markup_language) The release version can be downloaded from PyPI_. The source code is hosted on GitHub_. .. _PyPI: http://pypi.python.org/pypi/Markups .. _GitHub: https://github.com/retext-project/pymarkups Markups-1.0.1/LICENSE0000644000175000017500000000273612561175331015016 0ustar dmitrydmitry00000000000000Copyright 2012-2015 Dmitry Shachnev . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Markups-1.0.1/setup.cfg0000644000175000017500000000007312636260065015624 0ustar dmitrydmitry00000000000000[egg_info] tag_svn_revision = 0 tag_build = tag_date = 0 Markups-1.0.1/tests/0000755000175000017500000000000012636260065015145 5ustar dmitrydmitry00000000000000Markups-1.0.1/tests/__init__.py0000644000175000017500000000013312561175331017251 0ustar dmitrydmitry00000000000000from unittest.main import main if __name__ == '__main__': main(module=None, verbosity=2) Markups-1.0.1/tests/test_public_api.py0000644000175000017500000000160612633265246020673 0ustar dmitrydmitry00000000000000# This file is part of python-markups test suite # License: BSD # Copyright: (C) Dmitry Shachnev, 2012-2015 import markups import unittest class APITest(unittest.TestCase): def test_api(self): all_markups = markups.get_all_markups() self.assertIn(markups.MarkdownMarkup, all_markups) self.assertIn(markups.ReStructuredTextMarkup, all_markups) markup_class = markups.find_markup_class_by_name('restructuredtext') self.assertEqual(markups.ReStructuredTextMarkup, markup_class) markup_class = markups.get_markup_for_file_name('myfile.mkd', return_class=True) self.assertEqual(markups.MarkdownMarkup, markup_class) @unittest.skipUnless(markups.MarkdownMarkup.available(), 'Markdown not available') def test_api_instance(self): markup = markups.get_markup_for_file_name('myfile.mkd') self.assertIsInstance(markup, markups.MarkdownMarkup) if __name__ == '__main__': unittest.main() Markups-1.0.1/tests/test_restructuredtext.py0000644000175000017500000000355312561175331022222 0ustar dmitrydmitry00000000000000# This file is part of python-markups test suite # License: BSD # Copyright: (C) Dmitry Shachnev, 2012-2014 import unittest from markups import ReStructuredTextMarkup basic_text = \ '''Hello, world! ============= 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 = \ '

This is an example reStructuredText document.

\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) def test_mathjax_loading(self): markup = ReStructuredTextMarkup() self.assertEqual('', markup.get_javascript('Hello, world!')) js = markup.get_javascript('Hello, :math:`2+2`!') self.assertIn('', body) self.assertIn(r'\(2+2\)', body) def test_errors(self): markup = ReStructuredTextMarkup('/dev/null', settings_overrides = {'warning_stream': False}) body = markup.get_document_body('`') # unclosed role self.assertIn('system-message', body) self.assertIn('/dev/null', body) def test_errors_overridden(self): markup = ReStructuredTextMarkup('/dev/null', settings_overrides = {'report_level': 4}) body = markup.get_document_body('`') # unclosed role self.assertNotIn('system-message', body) if __name__ == '__main__': unittest.main() Markups-1.0.1/tests/test_markdown.py0000644000175000017500000001526412633271412020403 0ustar dmitrydmitry00000000000000# This file is part of python-markups test suite # License: BSD # Copyright: (C) Dmitry Shachnev, 2012-2015 from markups import MarkdownMarkup import unittest tables_source = \ '''th1 | th2 --- | --- t11 | t21 t12 | t22''' tables_output = \ '''
th1 th2
t11 t21
t12 t22
''' deflists_source = \ '''Apple : Pomaceous fruit of plants of the genus Malus in the family Rosaceae. Orange : The fruit of an evergreen tree of the genus Citrus.''' deflists_output = \ '''
Apple
Pomaceous fruit of plants of the genus Malus in the family Rosaceae.
Orange
The fruit of an evergreen tree of the genus Citrus.
''' mathjax_header = \ '\n\n' mathjax_source = \ r'''$i_1$ some text \$escaped\$ $i_2$ \(\LaTeX\) \\(escaped\) $$m_1$$ text $$m_2$$ \[m_3\] text \[m_4\] \( \sin \alpha \) text \( \sin \beta \) \[ \alpha \] text \[ \beta \] \$$escaped\$$ \\[escaped\] ''' mathjax_output = \ r'''

some text \$escaped\$

\(escaped)

text

text

text

text

\$$escaped\$$ \[escaped]

''' mathjax_multiline_source = \ r''' $$ \TeX \LaTeX $$ ''' mathjax_multiline_output = \ '''

''' mathjax_multilevel_source = \ r''' \begin{equation*} \begin{pmatrix} 1 & 0\\ 0 & 1 \end{pmatrix} \end{equation*} ''' mathjax_multilevel_output = \ r'''

''' @unittest.skipUnless(MarkdownMarkup.available(), 'Markdown not available') class MarkdownTest(unittest.TestCase): maxDiff = None def test_empty_file(self): markup = MarkdownMarkup() self.assertEqual(markup.get_document_body(''), '\n') def test_extensions_loading(self): markup = MarkdownMarkup() self.assertIsNone(markup._canonicalize_extension_name('nonexistent')) self.assertIsNone(markup._canonicalize_extension_name('nonexistent(someoption)')) self.assertIsNone(markup._canonicalize_extension_name('.foobar')) self.assertEqual(markup._canonicalize_extension_name('meta'), 'markdown.extensions.meta') self.assertEqual(markup._canonicalize_extension_name('meta(someoption)'), 'markdown.extensions.meta(someoption)') def test_loading_extensions_by_module_name(self): 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) self.assertIn('Header\n') def test_document_extensions_parameters(self): markup = MarkdownMarkup(extensions=[]) toc_header = '\n\n' html = markup.get_document_body(toc_header + '## Header') self.assertEqual(html, toc_header + '\n') def test_extra(self): markup = MarkdownMarkup() html = markup.get_document_body(tables_source) self.assertEqual(tables_output, html) html = markup.get_document_body(deflists_source) self.assertEqual(deflists_output, html) def test_remove_extra(self): markup = MarkdownMarkup(extensions=['remove_extra']) html = markup.get_document_body(tables_source) self.assertNotIn('', html) def test_remove_extra_document_extension(self): markup = MarkdownMarkup(extensions=[]) html = markup.get_document_body( 'Required-Extensions: remove_extra\n\n' + tables_source) self.assertNotIn('
', html) def test_remove_extra_removes_mathjax(self): markup = MarkdownMarkup(extensions=['remove_extra']) html = markup.get_document_body('$$1$$') self.assertNotIn('math/tex', html) def test_meta(self): markup = MarkdownMarkup() text = ('Required-Extensions: meta\n' 'Title: Hello, world!\n\n' 'Some text here.') title = markup.get_document_title(text) self.assertEqual('Hello, world!', title) def test_default_math(self): # by default $...$ delimeter should be disabled markup = MarkdownMarkup(extensions=[]) self.assertEqual('

$1$

\n', markup.get_document_body('$1$')) self.assertEqual('

\n\n

\n', markup.get_document_body('$$1$$')) 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.assertIn('Hello, world!

') if __name__ == '__main__': unittest.main() Markups-1.0.1/.gitignore0000644000175000017500000000006712561175331015774 0ustar dmitrydmitry00000000000000build dist MANIFEST Markups.egg-info __pycache__ *.pyc Markups-1.0.1/setup.py0000755000175000017500000000327112633315775015531 0ustar dmitrydmitry00000000000000#!/usr/bin/env python3 import sys try: from setuptools import setup, Command except ImportError: from distutils.core import setup, Command from markups import __version__ as version from os.path import dirname, join with open(join(dirname(__file__), 'README.rst')) as readme_file: long_description = '\n' + readme_file.read() classifiers = [ 'Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Topic :: Text Processing :: Markup', 'Topic :: Text Processing :: General', 'Topic :: Software Development :: Libraries :: Python Modules' ] class run_tests(Command): user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): from unittest.main import main testprogram = main(module=None, argv=sys.argv[:1], verbosity=2, exit=False) if not testprogram.result.wasSuccessful(): sys.exit(1) cmdclass = {} if sys.version_info[0] >= 3: cmdclass['test'] = run_tests setup_args = { 'name': 'Markups', 'version': version, 'description': 'A wrapper around various text markups', 'long_description': long_description, 'author': 'Dmitry Shachnev', 'author_email': 'mitya57@gmail.com', 'url': 'https://github.com/retext-project/pymarkups', 'packages': ['markups'], 'license': 'BSD', 'cmdclass': cmdclass, 'classifiers': classifiers } setup(**setup_args) Markups-1.0.1/.travis.yml0000644000175000017500000000030112633550112016076 0ustar dmitrydmitry00000000000000sudo: false language: python python: - "2.7" - "3.2" - "3.3" - "3.4" - "3.5" - "pypy" install: pip install Markdown docutils textile script: python -m unittest discover -s tests -v Markups-1.0.1/MANIFEST.in0000644000175000017500000000016712633342307015542 0ustar dmitrydmitry00000000000000include LICENSE include README.rst include changelog recursive-include docs *.rst conf.py recursive-include tests *.py