diff --git a/docs/internals.rst b/docs/internals.rst
index 303a327f..b267df76 100644
--- a/docs/internals.rst
+++ b/docs/internals.rst
@@ -50,7 +50,10 @@ Take a look at the Markdown reader::
def read(self, source_path):
"""Parse content and metadata of markdown files"""
text = pelican_open(source_path)
- md = Markdown(extensions = ['meta', 'codehilite'])
+ md_extensions = {'markdown.extensions.meta': {},
+ 'markdown.extensions.codehilite': {}}
+ md = Markdown(extensions=md_extensions.keys(),
+ extension_configs=md_extensions)
content = md.convert(text)
metadata = {}
diff --git a/docs/settings.rst b/docs/settings.rst
index 61fd8521..0f7280fa 100644
--- a/docs/settings.rst
+++ b/docs/settings.rst
@@ -112,15 +112,15 @@ Setting name (followed by default value, if any)
of these patterns will be ignored by the processor. For example,
the default ``['.#*']`` will ignore emacs lock files, and
``['__pycache__']`` would ignore Python 3's bytecode caches.
-``MD_EXTENSIONS =`` ``['codehilite(css_class=highlight)','extra']`` A list of the extensions that the Markdown processor
- will use. Refer to the Python Markdown documentation's
+``MD_EXTENSIONS =`` ``{...}`` A dict of the extensions that the Markdown processor
+ will use, with extensions' settings as the values.
+ Refer to the Python Markdown documentation's
`Extensions section `_
- for a complete list of supported extensions. (Note that
- defining this in your settings file will override and
- replace the default values. If your goal is to *add*
- to the default values for this setting, you'll need to
- include them explicitly and enumerate the full list of
- desired Markdown extensions.)
+ for a complete list of supported extensions and their options.
+ Default is ``{'markdown.extensions.codehilite' : {'css_class': 'highlight'},
+ 'markdown.extensions.extra': {}, 'markdown.extensions.meta': {}}``.
+ (Note that the dictionary defined in your settings file will
+ update this default one.)
``OUTPUT_PATH = 'output/'`` Where to output the generated files.
``PATH`` Path to content directory to be processed by Pelican. If undefined,
and content path is not specified via an argument to the ``pelican``
diff --git a/pelican/readers.py b/pelican/readers.py
index 4ea234bb..e3b1012a 100644
--- a/pelican/readers.py
+++ b/pelican/readers.py
@@ -246,9 +246,8 @@ class MarkdownReader(BaseReader):
def __init__(self, *args, **kwargs):
super(MarkdownReader, self).__init__(*args, **kwargs)
- self.extensions = list(self.settings['MD_EXTENSIONS'])
- if 'meta' not in self.extensions:
- self.extensions.append('meta')
+ self.extensions = self.settings['MD_EXTENSIONS']
+ self.extensions.setdefault('markdown.extensions.meta', {})
self._source_path = None
def _parse_metadata(self, meta):
@@ -284,7 +283,8 @@ class MarkdownReader(BaseReader):
"""Parse content and metadata of markdown files"""
self._source_path = source_path
- self._md = Markdown(extensions=self.extensions)
+ self._md = Markdown(extensions=self.extensions.keys(),
+ extension_configs=self.extensions)
with pelican_open(source_path) as text:
content = self._md.convert(text)
diff --git a/pelican/settings.py b/pelican/settings.py
index d1b1648b..82c50c03 100644
--- a/pelican/settings.py
+++ b/pelican/settings.py
@@ -101,7 +101,11 @@ DEFAULT_CONFIG = {
'PELICAN_CLASS': 'pelican.Pelican',
'DEFAULT_DATE_FORMAT': '%a %d %B %Y',
'DATE_FORMATS': {},
- 'MD_EXTENSIONS': ['codehilite(css_class=highlight)', 'extra'],
+ 'MD_EXTENSIONS': {
+ 'markdown.extensions.codehilite': {'css_class': 'highlight'},
+ 'markdown.extensions.extra': {},
+ 'markdown.extensions.meta': {},
+ },
'JINJA_EXTENSIONS': [],
'JINJA_FILTERS': {},
'LOG_FILTER': [],
@@ -362,6 +366,14 @@ def configure_settings(settings):
PATH_KEY)
settings[PATH_KEY] = DEFAULT_CONFIG[PATH_KEY]
+ # Save people from declaring MD_EXTENSIONS as a list rather than a dict
+ if not isinstance(settings.get('MD_EXTENSIONS', {}), dict):
+ logger.warning('The format of the MD_EXTENSIONS setting has '
+ 'changed. It should now be a dict mapping '
+ 'fully-qualified extension names to their '
+ 'configurations. Falling back to the default.')
+ settings['MD_EXTENSIONS'] = DEFAULT_CONFIG['MD_EXTENSIONS']
+
# Add {PAGE,ARTICLE}_PATHS to {ARTICLE,PAGE}_EXCLUDES
mutually_exclusive = ('ARTICLE', 'PAGE')
for type_1, type_2 in [mutually_exclusive, mutually_exclusive[::-1]]:
diff --git a/pelican/tests/test_pelican.py b/pelican/tests/test_pelican.py
index b88ad287..75d644bc 100644
--- a/pelican/tests/test_pelican.py
+++ b/pelican/tests/test_pelican.py
@@ -207,3 +207,19 @@ class TestPelican(LoggedTestCase):
count=2,
msg="Writing .*",
level=logging.INFO)
+
+ def test_md_extensions_list_deprecation(self):
+ """Test that a warning is issued if MD_EXTENSIONS is a list"""
+ settings = read_settings(path=None, override={
+ 'PATH': INPUT_PATH,
+ 'OUTPUT_PATH': self.temp_path,
+ 'CACHE_PATH': self.temp_cache,
+ 'MD_EXTENSIONS': ['meta'],
+ })
+ pelican = Pelican(settings=settings)
+ mute(True)(pelican.run)()
+ self.assertIsInstance(pelican.settings['MD_EXTENSIONS'], dict)
+ self.assertLogCountEqual(
+ count=1,
+ msg="The format of the MD_EXTENSIONS setting has changed",
+ level=logging.WARNING)
diff --git a/pelican/tests/test_readers.py b/pelican/tests/test_readers.py
index db4aa44f..ad73a58b 100644
--- a/pelican/tests/test_readers.py
+++ b/pelican/tests/test_readers.py
@@ -471,7 +471,12 @@ class MdReaderTest(ReaderTest):
# expected
page = self.read_file(
path='article_with_markdown_markup_extensions.md',
- MD_EXTENSIONS=['toc', 'codehilite', 'extra'])
+ MD_EXTENSIONS={
+ 'markdown.extensions.toc': {},
+ 'markdown.extensions.codehilite': {},
+ 'markdown.extensions.extra': {}
+ }
+ )
expected = ('