Major refactor, bordering on rewrite

- Rename the plugin (md_yaml -> md_metayaml)
- Rework directory structure for easier integration into Pelican
- Change markdown extension libary to a submodule
- Remove ugly path hacks
- Make the reader do less work (leverage the MarkdownReader class)
This commit is contained in:
pR0Ps 2014-12-25 00:08:52 -05:00
parent e4f7a2817c
commit 67e080a663
9 changed files with 34 additions and 204 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "markdown_metayaml"]
path = markdown_metayaml
url = git@github.com:pR0Ps/markdown_metayaml.git

1
__init__.py Normal file
View File

@ -0,0 +1 @@
from .md_metayaml import *

1
markdown_metayaml Submodule

@ -0,0 +1 @@
Subproject commit 201a20e1c3cf6f89cb7d38fbb2a7da3f81923091

29
md_metayaml.py Normal file
View File

@ -0,0 +1,29 @@
from pelican import signals
from pelican.readers import MarkdownReader
from .markdown_metayaml.meta_yaml import MetaYamlExtension
class MarkdownYAMLReader(MarkdownReader):
"""Reader for Markdown files with YAML metadata"""
def __init__(self, *args, **kwargs):
super(MarkdownYAMLReader, self).__init__(*args, **kwargs)
self.extensions.append(MetaYamlExtension())
def _parse_metadata(self, meta):
"""Return the dict containing document metadata"""
# MarkdownReader _parse_metadata() expects a list of length 1
# containing a string of comma-seperated values for authors and tags
for x in ("tags", "authors"):
if x in meta:
meta[x] = [",".join(meta[x])]
return super(MarkdownYAMLReader, self)._parse_metadata(meta)
def add_reader(readers):
for k in MarkdownYAMLReader.file_extensions:
readers.reader_classes[k] = MarkdownYAMLReader
def register():
signals.readers_init.connect(add_reader)

View File

@ -1 +0,0 @@
from .md_yaml import *

View File

@ -1,63 +0,0 @@
import sys
import os
from pelican import signals
from pelican.readers import BaseReader
from pelican.utils import pelican_open
try:
from markdown import Markdown
except ImportError:
Markdown = False
class MarkdownYAMLReader(BaseReader):
"""Reader for Markdown files with YAML metadata"""
enabled = bool(Markdown)
file_extensions = ['md', 'markdown', 'mkd', 'mdown']
def __init__(self, *args, **kwargs):
super(MarkdownYAMLReader, self).__init__(*args, **kwargs)
self.settings = args[0]
self.extensions = list(self.settings['MD_EXTENSIONS'])
if 'meta_yaml' not in self.extensions:
self.extensions.append('meta_yaml')
def _parse_metadata(self, meta):
"""Return the dict containing document metadata"""
output = {}
for name, value in meta.items():
name = name.lower()
output[name] = value
return output
def read(self, source_path):
"""Parse content and metadata of Markdown files with YAML metadata"""
self.__set_plugin_path()
self._md = Markdown(extensions=self.extensions)
with pelican_open(source_path) as text:
content = self._md.convert(text)
metadata = self._parse_metadata(self._md.Meta)
self.__unset_plugin_path()
return content, metadata
def __set_plugin_path(self):
self.__sys_path_old = sys.path[:]
for pluginpath in self.settings['PLUGIN_PATHS']:
sys.path.insert(0, pluginpath)
sys.path.insert(0, os.path.join(pluginpath, 'md_yaml'))
def __unset_plugin_path(self):
sys.path = self.__sys_path_old
def add_reader(readers):
for k in MarkdownYAMLReader.file_extensions:
readers.reader_classes[k] = MarkdownYAMLReader
def register():
signals.readers_init.connect(add_reader)

View File

@ -1,30 +0,0 @@
Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
Copyright 2004 Manfred Stienstra (the original version)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of the <organization> 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 PYTHON MARKDOWN PROJECT ''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 ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT
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.

View File

@ -1,10 +0,0 @@
# -*- coding: utf-8 -*-
from mdx_meta_yaml.extension import MetaYamlExtension
def makeExtension(configs=None):
if isinstance(configs, list):
configs = dict(configs)
elif configs is None:
configs = {}
return MetaYamlExtension(configs=configs)

View File

@ -1,100 +0,0 @@
"""
# YAML Meta Data Extension for [Python-Markdown](https://github.com/waylan/Python-Markdown)
This extension adds YAML meta data handling to markdown.
As in the original, meta data is parsed but not used in processing.
(YAML meta data is used e.g. by [pandoc](http://johnmacfarlane.net/pandoc/))
Dependencies: [PyYAML](http://pyyaml.org/)
Basic Usage:
>>> import markdown
>>> text = '''---
... Title: Test Doc.
... Author: Waylan Limberg
... Blank_Data:
... ...
...
... The body. This is paragraph one.
... '''
>>> md = markdown.Markdown(['meta_yaml'])
>>> print(md.convert(text))
<p>The body. This is paragraph one.</p>
>>> print(md.Meta) # doctest: +SKIP
{'blank_data': [''], 'author': ['Waylan Limberg'], 'title': ['Test Doc.']}
Make sure text without Meta Data still works (markdown < 1.6b returns a <p>).
>>> text = ' Some Code - not extra lines of meta data.'
>>> md = markdown.Markdown(['meta_yaml'])
>>> print(md.convert(text))
<pre><code>Some Code - not extra lines of meta data.
</code></pre>
>>> md.Meta
{}
Copyright 2014 Bernhard Fisseni
Based on the meta data extension included with Python-Markdown,
Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
License: BSD (see LICENSE.md for details)
"""
from __future__ import absolute_import
from __future__ import unicode_literals
from markdown import Extension
from markdown.preprocessors import Preprocessor
import yaml
# from yaml.scanner import ScannerError
class MetaYamlExtension (Extension):
"""Extension for parsing YAML-Metadata with Python-Markdown."""
def extendMarkdown(self, md, md_globals):
"""Add MetaYamlPreprocessor to Markdown instance."""
md.preprocessors.add('meta_yaml', MetaYamlPreprocessor(md), "_begin")
class MetaYamlPreprocessor(Preprocessor):
"""
Get Meta-Data.
A YAML block is delimited by
- a line '---' at the start
- and a '...' or '---' line
at the end.
"""
def run(self, lines):
""" Parse Meta-Data and store in Markdown.Meta. """
in_yaml = False
yaml_block = []
line = lines.pop(0)
if line == '---':
in_yaml = True
else:
lines.insert(0, line)
while in_yaml and lines:
line = lines.pop(0)
if line == '---' or line == '...':
break
yaml_block.append(line)
if yaml_block:
yaml_block = "\n".join(yaml_block)
meta = yaml.load(yaml_block)
self.markdown.Meta = meta
return lines