Commit 4943adb7 authored by Patrik Dufresne's avatar Patrik Dufresne

Make the plugins configurable.

Following recommendation made by nixjdm, make the plugin configurable
using a config file. Load configuration for the engine, extensions to be
enabled and also load their respective configuration.

Add note to the README file about incompatibility with `markdown-*`
events and any plugin build around them.
parent 2f5b92d5
......@@ -26,4 +26,53 @@ name = Page
label = Body
type = pythonmarkdown
```
\ No newline at end of file
```
# 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:
```
[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
```
......@@ -8,7 +8,10 @@ from lektor.pluginsystem import Plugin
from lektor.types import Type
import markdown
EXTENTIONS = [
SECTION_EXTENSIONS = "extensions"
SECTION_MARKDOWN = "markdown"
DEFAULT_EXTENTIONS = [
"markdown.extensions.extra",
"markdown.extensions.admonition",
"markdown.extensions.codehilite",
......@@ -22,8 +25,9 @@ EXTENTIONS = [
]
def pythonmarkdown_to_html(text):
return markdown.markdown(text, EXTENTIONS)
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.
......@@ -35,13 +39,38 @@ class HTML(object):
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.
"""
# The name of the class is used a key for the fields type.
class PythonMarkdownType(Type):
widget = 'multiline-text'
def _section_as_dict(self, name):
return {k: _value(v) for k, v in self.plugin_config.section_as_dict(name).items()}
def value_from_raw(self, raw):
return HTML(pythonmarkdown_to_html(raw.value or u''))
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):
......@@ -49,4 +78,20 @@ class PythonMarkdownPlugin(Plugin):
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)
[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
......@@ -39,7 +39,7 @@ class TestLektorAsciidoc(unittest.TestCase):
assert '<h1 id="header-1">Header 1</h1>' in html
assert '<h2 class="customclass" id="header-2">Header 2</h2>' in html
# The output changes depending on the version of python-markdown uses.
assert '<pre class="codehilite"><code>code here</code></pre>' in html
assert '<pre class="codehilite"><code class="linenums">code here</code></pre>' in html
if __name__ == "__main__":
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment