diff --git a/bin/pelican b/bin/pelican index 2a8035ce..540a1acc 100755 --- a/bin/pelican +++ b/bin/pelican @@ -14,7 +14,7 @@ parser.add_argument('-t', '--theme-path', dest='theme', parser.add_argument('-o', '--output', dest='output', help='Where to output the generated files. If not specified, a directory' ' will be created, named "output" in the current path.') -parser.add_argument('-m', '--markup', default='rst', dest='markup', +parser.add_argument('-m', '--markup', default='rst, md', dest='markup', help='the markup language to use. Currently only ReSTreucturedtext is' ' available.') parser.add_argument('-s', '--settings', dest='settings', @@ -27,10 +27,11 @@ if __name__ == '__main__': articles = ArticlesGenerator(args.settings) pages = PagesGenerator(args.settings) context = {} - + for gen in articles, pages: + markup = [a.split()[0] for a in args.markup.split(',')] context.update(gen.create_context(args.path, args.theme, args.output, - args.markup)) + markup)) for gen in articles, pages: gen.generate(context) diff --git a/pelican/generators.py b/pelican/generators.py index c25e3978..503e4506 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -27,21 +27,22 @@ class Generator(object): def __init__(self, settings): self.settings = read_settings(settings) - def _init_params(self, path=None, theme=None, output_path=None, fmt=None): + def _init_params(self, path=None, theme=None, output_path=None, + markup=None): """Initialize parameters for this object. :param path: the path where to find the files to parse :param theme: where to search for templates :param output_path: where to output the generated files :param settings: the settings file to use - :param fmt: the format of the files to read. It's a list. + :param markup: the markup of the files to read. It's a list. """ # get the settings self.path = path or self.settings['PATH'] self.theme = theme or self.settings['THEME'] output_path = output_path or self.settings['OUTPUT_PATH'] self.output_path = os.path.realpath(output_path) - self.format = fmt or self.settings['FORMAT'] + self.markup = markup or self.settings['MARKUP'] # get the list of files to parse if not path: @@ -158,7 +159,7 @@ class Generator(object): if e in dirs: dirs.remove(e) files.extend([os.sep.join((root, f)) for f in temp_files - if f.endswith(self.format)]) + if True in [f.endswith(markup) for markup in self.markup]]) return files def is_valid_content(self, content, f): @@ -249,8 +250,9 @@ class ArticlesGenerator(Generator): except OSError: pass - def create_context(self, path=None, theme=None, output_path=None, fmt=None): - self._init_params(path, theme, output_path, fmt) + def create_context(self, path=None, theme=None, output_path=None, + markup=None): + self._init_params(path, theme, output_path, markup) # build the list of articles / categories / etc. self.process_files(self.get_files(path, ['pages',])) @@ -291,8 +293,9 @@ class PagesGenerator(Generator): self.generate_file('pages/%s' % page.url, templates['page'], context, page=page) - def create_context(self, path=None, theme=None, output_path=None, fmt=None): - self._init_params(path, theme, output_path, fmt) + def create_context(self, path=None, theme=None, output_path=None, + markup=None): + self._init_params(path, theme, output_path, markup) self.process_files(self.get_files(os.sep.join((path, 'pages')))) return self._get_context(('pages',)) diff --git a/pelican/readers.py b/pelican/readers.py index 11c22947..38632222 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -1,4 +1,5 @@ from docutils import core +from markdown import Markdown import re # import the directives to have pygments support @@ -38,14 +39,27 @@ class RstReader(object): metadatas['title'] = title return content, metadatas -_EXTENSIONS = {'rst': RstReader} # supported formats +class MarkdownReader(object): + + def read(self, filename): + """Parse content and metadata of markdown files""" + text = open(filename) + md = Markdown(extensions = ['meta']) + content = md.convert(text) + + metadatas = {} + for name, value in md.Meta.items(): + metadatas[name.lower()] = value[0] + return content, metadatas + +_EXTENSIONS = {'rst': RstReader, 'md': MarkdownReader} # supported formats def read_file(filename, fmt=None): """Return a reader object using the given format.""" if not fmt: - fmt = 'rst' + fmt = filename.split('.')[-1] if fmt not in _EXTENSIONS.keys(): - raise TypeError('Pelican does not know how to parse %s files' % fmt) + raise TypeError('Pelican does not know how to parse %s' % filename) reader = _EXTENSIONS[fmt]() return reader.read(filename) diff --git a/pelican/settings.py b/pelican/settings.py index 670584be..814850f8 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -5,7 +5,7 @@ _DEFAULT_THEME = os.sep.join([os.path.dirname(os.path.abspath(__file__)), _DEFAULT_CONFIG = {'PATH': None, 'THEME': _DEFAULT_THEME, 'OUTPUT_PATH': 'output/', - 'MARKUP': 'rst', + 'MARKUP': ('rst', 'md'), 'STATIC_PATHS': ['css', 'images'], 'FEED': 'feeds/all.atom.xml', 'CATEGORY_FEED': 'feeds/%s.atom.xml', diff --git a/pelican/utils.py b/pelican/utils.py index 5824b7b9..1f7b0c4b 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import re from datetime import datetime from codecs import open as _open @@ -41,8 +42,9 @@ def slugify(value): Took from django sources. """ - import unicodedata - value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') + if type(value) == unicode: + import unicodedata + value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) return re.sub('[-\s]+', '-', value) diff --git a/setup.py b/setup.py index 6e365a21..90dada4d 100644 --- a/setup.py +++ b/setup.py @@ -7,11 +7,11 @@ if sys.version_info < (2,7): setup( name = "pelican", - version = '2.1.1', - url = 'http://hg.lolnet.org/pelican/', + version = '2.2', + url = 'http://alexis.notmyidea.org/pelican/', author = 'Alexis Metaireau', author_email = 'alexis@notmyidea.org', - description = "A tool to generate a static blog, with restructured text input files.", + description = "A tool to generate a static blog, with restructured text (or markdown) input files.", long_description=open('README.rst').read(), packages = ['pelican'], include_package_data = True,