diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..7f2493494310dfec3c49d7200eedfe7b259b6d44 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,36 @@ +image: ikus060/docker-debian-py2-py3:stretch + +stages: +- test +- publish + +test:py27: + stage: test + script: + # Register the plugin entry point and run the test + - python2 setup.py develop + - python2 setup.py nosetests + +test:py3: + stage: test + script: + # Register the plugin entry point and run the test + - python3 setup.py develop + - python3 setup.py nosetests + +publish_pypi: + stage: publish + only: + - tags + script: + - pip install wheel twine --upgrade + - python setup.py sdist bdist_wheel + - twine upload dist/* -u $PYPI_USR -p $PYPI_PWD + +github_push: + stage: publish + only: + - branches + script: + - git push --force https://${GITHUB_USR}:${GITHUB_PWD}@github.com/ikus060/lektor-python-markdown.git refs/remotes/origin/${CI_COMMIT_REF_NAME}:refs/heads/${CI_COMMIT_REF_NAME} + - git push https://${GITHUB_USR}:${GITHUB_PWD}@github.com/ikus060/lektor-python-markdown.git --tags diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index e4796c64abbe976215ca5c9ddc1331db1ae510f1..ad6d94ad52749fd3d3a43d794e154492e2a3df90 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ eclipse.preferences.version=1 -encoding/lektor_asciidoc.py=utf-8 +encoding/lektor_pythonmarkdown.py=utf-8 diff --git a/README.md b/README.md index 5aba1cbec1b928a99cb4b28da4800930be462234..9cf6cac6995bee1bf686d8e2fd4fae8b7fd487a5 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,80 @@ -# Lektor AsciiDoc Plugin +# Lektor Python-Markdown Plugin -A [Lektor](https://www.getlektor.com/) plugin to add an AsciiDoc field type. +[![pipeline status](http://git.patrikdufresne.com/pdsl/lektor-python-markdown/badges/master/pipeline.svg)](http://git.patrikdufresne.com/pdsl/lektor-python-markdown/commits/master) + +A [Lektor](https://www.getlektor.com/) plugin to parse markdown using +[Python-Markdown](https://python-markdown.github.io/). By default, lektor +uses [mistune](http://mistune.readthedocs.io/en/latest/) to parse markdown +field. +With this plugin, you can chose which parser is to be used by setting a +different type on the field. Either: `markdown` or `pythonmarkdown` ## Installation -Add lektor-asciidoc to your project from command line: +Add lektor-pythonmarkdown to your project from command line: + +``` +lektor plugins add lektor-pythonmarkdown +``` + +## Usage + +In your model, you need to define the type of field as follow: +``` +[model] +name = Page + +[fields.body] +label = Body +type = pythonmarkdown + +``` + +# Warning ! + +This plugins is is obviously incompatible with all of the mistune-specific events and plugins. Namely, all of `markdown-*` events and the plugins built around them. + + +# Advance configuration + +This lektor plugins provide a nice way to configure python-markdown. For instance, it's possible to explicitly define the extentions to be enabled and to configure each of them seperatly. +For an advance configuration, you need to create a file named `pythonmarkdown.ini` in the `configs` folder. + +In that file you may write something similar to the following: ``` -lektor plugins add lektor-asciidoc +[markdown] +# Define the configuration of python-markdown. +# Reference: https://python-markdown.github.io/reference/#markdown + +#output_format = xhtml1 +#tab_length = 4 +#safe_mode = False +#enable_attributes = False +#smart_emphasis = True +#lazy_ol = True + +[extensions] +# List extensions to be enabled. +markdown.extensions.extra = 1 +markdown.extensions.admonition = 1 +markdown.extensions.codehilite = 1 +markdown.extensions.headerid = 1 +markdown.extensions.meta = 1 +markdown.extensions.nl2br = 1 +markdown.extensions.sane_lists = 1 +markdown.extensions.smarty = 1 +markdown.extensions.toc = 1 +markdown.extensions.wikilinks = 1 + +[markdown.extensions.codehilite] +# Specific configuration for an extension. +# Reference: https://python-markdown.github.io/extensions/code_hilite/#usage +linenums = True +#guess_lang = True +#css_class = codehilite +#pygments_style = default +#noclasses = False +#use_pygments = True + ``` diff --git a/lektor_asciidoc.py b/lektor_asciidoc.py deleted file mode 100644 index b650bd26e0a6d8b83ad0e24aeeee81e86c58d6ae..0000000000000000000000000000000000000000 --- a/lektor_asciidoc.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -from subprocess import PIPE, Popen - -from lektor.pluginsystem import Plugin -from lektor.types import Type - - -def asciidoc_to_html(text): - p = Popen(['asciidoc', '--no-header-footer', '--backend=html5', '-'], - stdin=PIPE, stdout=PIPE, stderr=PIPE) - - out, err = p.communicate(text) - if p.returncode != 0: - raise RuntimeError('asciidoc: "%s"' % err) - - return out - - -# Wrapper with an __html__ method prevents Lektor from escaping HTML tags. -class HTML(object): - def __init__(self, html): - self.html = html - - def __html__(self): - return self.html - - -class AsciiDocType(Type): - widget = 'multiline-text' - - def value_from_raw(self, raw): - return HTML(asciidoc_to_html(raw.value or u'')) - - -class AsciiDocPlugin(Plugin): - name = u'AsciiDoc' - description = u'Adds AsciiDoc field type to Lektor.' - - def on_setup_env(self, **extra): - self.env.add_type(AsciiDocType) diff --git a/lektor_pythonmarkdown.py b/lektor_pythonmarkdown.py new file mode 100644 index 0000000000000000000000000000000000000000..5374719e13695e07921af842e8222a6d2dd4702f --- /dev/null +++ b/lektor_pythonmarkdown.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +''' +Created on Jun 8, 2018 + +@author: Patrik Dufresne +''' +from lektor.pluginsystem import Plugin +from lektor.types import Type +import markdown + +SECTION_EXTENSIONS = "extensions" +SECTION_MARKDOWN = "markdown" + +DEFAULT_EXTENTIONS = [ + "markdown.extensions.extra", + "markdown.extensions.admonition", + "markdown.extensions.codehilite", + "markdown.extensions.headerid", + "markdown.extensions.meta", + "markdown.extensions.nl2br", + "markdown.extensions.sane_lists", + "markdown.extensions.smarty", + "markdown.extensions.toc", + "markdown.extensions.wikilinks", +] + + +def pythonmarkdown_to_html(text, cfg): + # TODO Call events. + return markdown.markdown(text, **cfg.options) + + +# Wrapper with an __html__ method prevents Lektor from escaping HTML tags. +class HTML(object): + + def __init__(self, html): + self.html = html + + def __html__(self): + return self.html + + +def _value(v): + "This function tries to convert the configuration value to a sane type." + if v.lower() in ['true', 'false']: + return v.lower() == 'true' + try: + return int(v) + except: + return v + + +class PythonMarkdownConfig(object): + """ + Define configuration of python-markdown. + """ + + def _section_as_dict(self, name): + return {k: _value(v) for k, v in self.plugin_config.section_as_dict(name).items()} + + def _extensions(self): + return [ + e + for e, v in (self._section_as_dict(SECTION_EXTENSIONS) or DEFAULT_EXTENTIONS).items() + if v] + + def __init__(self, plugin_config): + self.plugin_config = plugin_config + self.options = self._section_as_dict(SECTION_MARKDOWN) + self.options.update({ + "extensions": self._extensions(), + "extension_configs": {e: self._section_as_dict(e) for e in self._extensions()}, + }) + + +class PythonMarkdownPlugin(Plugin): + name = u'pythonmarkdown' + description = u'Adds AsciiDoc field type to Lektor.' + + def on_setup_env(self, **extra): + plugin_config = self.get_config() + + # We declare this type as an internal class inside the plugin to get + # access to the get_config() function from the Type. + # + # The name of the class is used a key for the fields type. + class PythonMarkdownType(Type): + widget = 'multiline-text' + + def value_from_raw(self, raw): + """ + Called to convert the raw value (markdown) into html. + """ + cfg = PythonMarkdownConfig(plugin_config) + return HTML(pythonmarkdown_to_html(raw.value or u'', cfg)) + + self.env.add_type(PythonMarkdownType) diff --git a/setup.py b/setup.py index c77427f48d8401178f597e458b1e8fd9d8ddbad8..0440a3d42ca44861d0991a67be3da8d84523a674 100644 --- a/setup.py +++ b/setup.py @@ -9,23 +9,25 @@ with io.open('README.md', 'rt', encoding="utf8") as f: _description_re = re.compile(r'description\s+=\s+(?P.*)') -with open('lektor_asciidoc.py', 'rb') as f: +with open('lektor_pythonmarkdown.py', 'rb') as f: description = str(ast.literal_eval(_description_re.search( f.read().decode('utf-8')).group(1))) setup( - author=u'A. Jesse Jiryu Davis', - author_email='jesse@emptysquare.net', + author='Patrik Dufresne Service Logiciel inc.', + author_email='info@patrikdufresne.com', description=description, - keywords='Lektor plugin static-site blog asciidoc', + keywords='Lektor plugin static-site blog Python-Markdown', license='MIT', long_description=readme, long_description_content_type='text/markdown', - name='lektor-asciidoc', - py_modules=['lektor_asciidoc'], - tests_require=['pytest'], - version='0.3', - url='https://github.com/nixjdm/lektor-asciidoc', + name='lektor-pythonmarkdown', + py_modules=['lektor_pythonmarkdown'], + install_requires=['markdown'], + tests_require=['lektor'], + setup_requires=['setuptools_scm'], + use_scm_version=True, + url='https://github.com/ikus060/lektor-python-markdown', classifiers=[ 'Environment :: Plugins', 'Environment :: Web Environment', @@ -35,7 +37,7 @@ setup( ], entry_points={ 'lektor.plugins': [ - 'asciidoc = lektor_asciidoc:AsciiDocPlugin', + 'pythonmarkdown = lektor_pythonmarkdown:PythonMarkdownPlugin', ] } ) diff --git a/tests/demo-project/configs/pythonmarkdown.ini b/tests/demo-project/configs/pythonmarkdown.ini new file mode 100644 index 0000000000000000000000000000000000000000..8403dffafca71036a4e64723c8972e1c52b5bded --- /dev/null +++ b/tests/demo-project/configs/pythonmarkdown.ini @@ -0,0 +1,27 @@ +[markdown] +#output_format = xhtml1 +#tab_length = 4 +#safe_mode = False +#enable_attributes = False +#smart_emphasis = True +#lazy_ol = True + +[extensions] +markdown.extensions.extra = 1 +markdown.extensions.admonition = 1 +markdown.extensions.codehilite = 1 +markdown.extensions.headerid = 1 +markdown.extensions.meta = 1 +markdown.extensions.nl2br = 1 +markdown.extensions.sane_lists = 1 +markdown.extensions.smarty = 1 +markdown.extensions.toc = 1 +markdown.extensions.wikilinks = 1 + +[markdown.extensions.codehilite] +linenums = True +#guess_lang = True +#css_class = codehilite +#pygments_style = default +#noclasses = False +#use_pygments = True diff --git a/tests/demo-project/content/contents.lr b/tests/demo-project/content/contents.lr index f8223144aea0dd8753b3b5e584c9e6b2ed99ad08..570ab7b55d0f6aa5c0de3c379cc7cd8c08f21329 100644 --- a/tests/demo-project/content/contents.lr +++ b/tests/demo-project/content/contents.lr @@ -1,9 +1,9 @@ body: -== Header 1 +# Header 1 -Some text. +## Header 2 {: .customclass} ------ +``` code here ------ +``` diff --git a/tests/demo-project/models/page.ini b/tests/demo-project/models/page.ini index 42b9068165579c0278bd155d1ef14defe1b74831..e77517ecfbe5689a354493a7af46363af1b13f54 100644 --- a/tests/demo-project/models/page.ini +++ b/tests/demo-project/models/page.ini @@ -3,4 +3,4 @@ name = Page [fields.body] label = Body -type = asciidoc +type = pythonmarkdown diff --git a/tests/test_lektor_asciidoc.py b/tests/test_lektor_pythonmarkdown.py similarity index 71% rename from tests/test_lektor_asciidoc.py rename to tests/test_lektor_pythonmarkdown.py index a58f8c8e545bdebccd6ee7cbd23d562509f3e683..c52d16a29a231ce53dc706b48a2119a4dd390ca2 100644 --- a/tests/test_lektor_asciidoc.py +++ b/tests/test_lektor_pythonmarkdown.py @@ -1,8 +1,10 @@ + ''' Created on Jun 8, 2018 -@author: ikus060 +@author: Patrik Dufresne ''' + from lektor.builder import Builder from lektor.db import Database from lektor.environment import Environment @@ -33,8 +35,11 @@ class TestLektorAsciidoc(unittest.TestCase): assert not failures page_path = os.path.join(self.builder.destination_path, 'index.html') html = open(page_path).read() - assert '

Header 1

' in html - assert '
code here
' in html + print(html) + assert '

Header 1

' in html + assert '

Header 2

' in html + # The output changes depending on the version of python-markdown uses. + assert '
code here
' in html if __name__ == "__main__":