Markups-2.0.1/ 0000755 0001750 0001750 00000000000 13123541060 013771 5 ustar dmitry dmitry 0000000 0000000 Markups-2.0.1/docs/ 0000755 0001750 0001750 00000000000 13123541060 014721 5 ustar dmitry dmitry 0000000 0000000 Markups-2.0.1/docs/overview.rst 0000644 0001750 0001750 00000002444 12714144476 017344 0 ustar dmitry dmitry 0000000 0000000 ============
API overview
============
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.convert('*reStructuredText* test').get_document_body()
'
\n
reStructuredText test
\n
\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-2.0.1/docs/interface.rst 0000644 0001750 0001750 00000001226 12664103407 017424 0 ustar dmitry dmitry 0000000 0000000 ================
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:
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:
Markups-2.0.1/docs/standard_markups.rst 0000644 0001750 0001750 00000005427 13117570273 021040 0 ustar dmitry dmitry 0000000 0000000 ================
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: https://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-2.0.1/docs/conf.py 0000644 0001750 0001750 00000003061 13117570737 016240 0 ustar dmitry dmitry 0000000 0000000 #!/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'2017, 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-2.0.1/docs/custom_markups.rst 0000644 0001750 0001750 00000003666 12664103407 020552 0 ustar dmitry dmitry 0000000 0000000 ==============
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`.
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`.
: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.
Markups-2.0.1/docs/changelog.rst 0000644 0001750 0001750 00000000500 12575334254 017414 0 ustar dmitry dmitry 0000000 0000000 ========================
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-2.0.1/docs/index.rst 0000644 0001750 0001750 00000001776 12575334301 016605 0 ustar dmitry dmitry 0000000 0000000 ===================================
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-2.0.1/changelog 0000644 0001750 0001750 00000007623 13123540340 015653 0 ustar dmitry dmitry 0000000 0000000 Version 2.0.1, 2017-06-24
=========================
* The new MathJax CDN is used, the old one will be shut down soon.
* When using MathJax with Markdown, the AMSmath and AMSsymbols extensions are
now enabled.
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
=========================
* 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-2.0.1/markups/ 0000755 0001750 0001750 00000000000 13123541060 015453 5 ustar dmitry dmitry 0000000 0000000 Markups-2.0.1/markups/restructuredtext.py 0000644 0001750 0001750 00000004775 13123540002 021475 0 ustar dmitry dmitry 0000000 0000000 # vim: ts=8:sts=8:sw=8:noexpandtab
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2017
import markups.common as common
from markups.abstract import AbstractMarkup, ConvertedMarkup
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 %s?config=TeX-AMS_CHTML' % common.MATHJAX_WEB_URL,
'syntax_highlight': 'short',
})
AbstractMarkup.__init__(self, filename)
from docutils.core import publish_parts
self._publish_parts = publish_parts
def convert(self, text):
parts = self._publish_parts(text, source_path=self.filename,
writer_name='html', settings_overrides=self.overrides)
# Determine head
head = parts['head']
# Determine body
body = parts['html_body']
# Determine title
title = parts['title']
# Determine stylesheet
origstyle = parts['stylesheet']
# Cut off tags
stylestart = '')]
stylesheet += common.get_pygments_stylesheet('.code')
return ConvertedReStructuredText(head, body, title, stylesheet)
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):
if 'MathJax.js?config=TeX-AMS_CHTML' not in self.head:
return ''
return ('\n' %
common.get_mathjax_url(webenv))
Markups-2.0.1/markups/__init__.py 0000644 0001750 0001750 00000006110 13123540353 017566 0 ustar dmitry dmitry 0000000 0000000 # This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2015
import importlib
import os
import warnings
from markups.common import CONFIGURATION_DIR
from markups.markdown import MarkdownMarkup
from markups.restructuredtext import ReStructuredTextMarkup
from markups.textile import TextileMarkup
__version_tuple__ = (2, 0, 1)
__version__ = '.'.join(map(str, __version_tuple__))
builtin_markups = [MarkdownMarkup, ReStructuredTextMarkup, TextileMarkup]
# Public API
def get_custom_markups():
"""
:returns: list of registered :doc:`custom markups `
:rtype: list of markup classes
"""
try:
list_file = open(os.path.join(CONFIGURATION_DIR, 'pymarkups.txt'))
except IOError:
return []
else:
custom_markups_names = [line.rstrip() for line in list_file]
custom_markups = []
for markup_name in custom_markups_names:
try:
module = importlib.import_module(markup_name)
custom_markups.append(module.markup)
except (ImportError, AttributeError):
warnings.warn('Warning: cannot import module %r.' %
markup_name, ImportWarning)
return custom_markups
def get_all_markups():
"""
:returns: list of all markups (both standard and custom ones)
:rtype: list of markup classes
"""
return builtin_markups + get_custom_markups()
def get_available_markups():
"""
:returns: list of all available markups (markups whose
:meth:`~markups.abstract.AbstractMarkup.available`
method returns True)
:rtype: list of markup classes
"""
available_markups = []
for markup in get_all_markups():
if markup.available():
available_markups.append(markup)
return available_markups
def get_markup_for_file_name(filename, return_class=False):
"""
:param filename: name of the file
:type filename: str
:param return_class: if true, this function will return
a class rather than an instance
:type return_class: bool
:returns: a markup with
:attr:`~markups.abstract.AbstractMarkup.file_extensions`
attribute containing extension of `filename`, if found,
otherwise ``None``
>>> import markups
>>> markup = markups.get_markup_for_file_name('foo.mkd')
>>> markup.convert('**Test**').get_document_body()
'Test
\\n'
>>> markups.get_markup_for_file_name('bar.rst', return_class=True)
"""
markup_class = None
for markup in get_all_markups():
for extension in markup.file_extensions:
if filename.endswith(extension):
markup_class = markup
if return_class:
return markup_class
if markup_class and markup_class.available():
return markup_class(filename=filename)
def find_markup_class_by_name(name):
"""
:returns: a markup with
:attr:`~markups.abstract.AbstractMarkup.name`
attribute matching `name`, if found, otherwise ``None``
:rtype: class
>>> import markups
>>> markups.find_markup_class_by_name('textile')
"""
for markup in get_all_markups():
if markup.name.lower() == name.lower():
return markup
Markups-2.0.1/markups/textile.py 0000644 0001750 0001750 00000002077 13117570655 017530 0 ustar dmitry dmitry 0000000 0000000 # vim: ts=8:sts=8:sw=8:noexpandtab
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2013-2016
from __future__ import absolute_import
import markups.common as common
from markups.abstract import AbstractMarkup, ConvertedMarkup
class TextileMarkup(AbstractMarkup):
"""Markup class for Textile language.
Inherits :class:`~markups.abstract.AbstractMarkup`.
"""
name = 'Textile'
attributes = {
common.LANGUAGE_HOME_PAGE: 'http://en.wikipedia.org/wiki/Textile_(markup_language)',
common.MODULE_HOME_PAGE: 'https://github.com/textile/python-textile',
common.SYNTAX_DOCUMENTATION: 'http://movabletype.org/documentation/author/textile-2-syntax.html'
}
file_extensions = ('.textile',)
default_extension = '.textile'
@staticmethod
def available():
try:
import textile
except ImportError:
return False
return True
def __init__(self, filename=None):
AbstractMarkup.__init__(self, filename)
from textile import textile
self.textile = textile
def convert(self, text):
return ConvertedMarkup(self.textile(text))
Markups-2.0.1/markups/markdown.py 0000644 0001750 0001750 00000012717 13117570614 017671 0 ustar dmitry dmitry 0000000 0000000 # vim: ts=8:sts=8:sw=8:noexpandtab
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2017
from __future__ import absolute_import
import importlib
import os
import re
import warnings
import markups.common as common
from markups.abstract import AbstractMarkup, ConvertedMarkup
MATHJAX_CONFIG = \
'''
'''
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.
Inherits :class:`~markups.abstract.AbstractMarkup`.
:param extensions: list of extension names
:type extensions: list
"""
name = 'Markdown'
attributes = {
common.LANGUAGE_HOME_PAGE: 'https://daringfireball.net/projects/markdown/',
common.MODULE_HOME_PAGE: 'https://github.com/waylan/Python-Markdown',
common.SYNTAX_DOCUMENTATION: 'https://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 extension_name_re.findall(match.group(1))
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 +
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:
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:
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 []
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'
# Determine title
if hasattr(self.md, 'Meta') and 'title' in self.md.Meta:
title = str.join(' ', self.md.Meta['title'])
else:
title = ''
# Determine stylesheet
if any(extension.endswith('codehilite') for extension in self.extensions):
stylesheet = common.get_pygments_stylesheet('.codehilite')
else:
stylesheet = ''
return ConvertedMarkdown(body, title, stylesheet)
class ConvertedMarkdown(ConvertedMarkup):
def get_javascript(self, webenv=False):
if '')
else:
javascript = ''
return javascript
Markups-2.0.1/markups/abstract.py 0000644 0001750 0001750 00000011034 13117570566 017647 0 ustar dmitry dmitry 0000000 0000000 # vim: ts=8:sts=8:sw=8:noexpandtab
# This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2016
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.
: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
@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 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 self.title
def get_document_body(self):
"""
:returns: the contents of the ```` HTML tag
:rtype: str
"""
return self.body
def get_stylesheet(self):
"""
:returns: the contents of ``\n' if include_stylesheet else '')
title = self.get_document_title()
if not title:
title = fallback_title
title_string = ('' + title + '\n') if title else ''
javascript = self.get_javascript(webenv)
return (
'\n'
'\n\n'
'\n'
+ custom_headers + title_string + stylesheet + javascript
+ '\n\n' + body + '\n\n'
)
Markups-2.0.1/markups/common.py 0000644 0001750 0001750 00000001676 13117572641 017343 0 ustar dmitry dmitry 0000000 0000000 # This file is part of python-markups module
# License: BSD
# Copyright: (C) Dmitry Shachnev, 2012-2017
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://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/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-2.0.1/markups/mdx_mathjax.py 0000644 0001750 0001750 00000004572 12633336576 020364 0 ustar dmitry dmitry 0000000 0000000 # 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'(?