Explorar o código

New plugin: Customized inline html for markdown

Barry Steyn %!s(int64=9) %!d(string=hai) anos
pai
achega
b45ed2fbb8

+ 2 - 0
Readme.rst

@@ -100,6 +100,8 @@ Liquid-style tags         Allows liquid-style tags to be inserted into markdown
 
 Multi parts posts         Allows you to write multi-part posts
 
+Markdown Inline Extend    Enables you to add customize inline patterns to your markdown
+
 Neighbor articles         Adds ``next_article`` (newer) and ``prev_article`` (older) variables to the article's context
 
 Open graph                Generates Open Graph tags for your articles

+ 43 - 0
md_inline_extension/Readme.md

@@ -0,0 +1,43 @@
+Markdown Inline Extension For Pelican
+=====================================
+This plugin lets you customize inline HTML
+within Markdown by extending Python's Markdown module.
+
+Installation
+------------
+To enable, ensure that the `md_inline_extension` plugin is accessible.
+Then add the following to settings.py:
+
+    PLUGINS = ["md_inline_extension"]
+
+Usage
+-----
+By default, any Markdown text inside `[*]...[*]` will get wrapped in
+`span` tags with a class of `pelican-inline`. For example:
+
+`[*]Lorem ipsum dolor sit amet, consectetur adipiscing elit[*]` will
+become `<span class="pelican-inline">Lorem ipsum dolor sit amet, consectetur adipiscing elit</span>`
+
+You can create your own inline patterns and associate them with
+arbitrary classes and styles by using the `MD_INLINE` dictionary in settings.
+The dictionary takes a pattern as key and expects either a string or a tuple
+as a value. If a string is provided, then that will be the CSS class. If
+a tuple is provided, then the first value will be the style, and the second
+value (if present) will be the class. For example:
+
+```
+MD_INLINE = {
+    '+=+': ('color:red;', 'my-test-class'),
+    '|-|': ('color:blue;',),
+    '&^': 'my-other-text-class',
+}
+```
+
+The above defines three new inline patterns:
+
+ 1. **+=+**: Text within `+=+` will be wrapped in `span` tags like so
+: `<span style="color:red;" class="my-test-class">...</span>`
+ 2. **|-|**: Text within `|-|` will be wrapped in
+`<span style="color:blue;">...</span>`. Note - no class is present.
+ 3. **&^**: Text within `&^` will be wrapped in
+`<span class="my-other-text-class">...</span>`. Note - no style present.

+ 1 - 0
md_inline_extension/__init__.py

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

+ 65 - 0
md_inline_extension/inline.py

@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+"""
+Markdown Inline Extension For Pelican
+=====================================
+Extends Pelican's Markdown module
+and allows for customized inline HTML
+"""
+
+import os
+import sys
+
+from pelican import signals
+
+try:
+    from . pelican_inline_markdown_extension import PelicanInlineMarkdownExtension
+except ImportError as e:
+    PelicanInlineMarkdownExtension = None
+    print("\nMarkdown is not installed - inline Markdown extension disabled\n")
+
+def process_settings(pelicanobj):
+    """Sets user specified settings (see README for more details)"""
+
+    # Default settings
+    inline_settings = {}
+    inline_settings['config'] = {'[*]':('', 'pelican-inline')}
+
+    # Get the user specified settings
+    try:
+        settings = pelicanobj.settings['MD_INLINE']
+    except:
+        settings = None
+
+    # If settings have been specified, add them to the config
+    if isinstance(settings, dict):
+        inline_settings['config'].update(settings)
+
+    return inline_settings
+
+def inline_markdown_extension(pelicanobj, config):
+    """Instantiates a customized Markdown extension"""
+
+    # Instantiate Markdown extension and append it to the current extensions
+    try:
+        pelicanobj.settings['MD_EXTENSIONS'].append(PelicanInlineMarkdownExtension(config))
+    except:
+        sys.excepthook(*sys.exc_info())
+        sys.stderr.write("\nError - the pelican Markdown extension failed to configure. Inline Markdown extension is non-functional.\n")
+        sys.stderr.flush()
+
+def pelican_init(pelicanobj):
+    """Loads settings and instantiates the Python Markdown extension"""
+
+    # If there was an error loading Markdown, then do not process any further 
+    if not PelicanInlineMarkdownExtension:
+        return
+
+    # Process settings
+    config = process_settings(pelicanobj)
+
+    # Configure Markdown Extension
+    inline_markdown_extension(pelicanobj, config)
+
+def register():
+    """Plugin registration"""
+    signals.initialized.connect(pelican_init)

+ 69 - 0
md_inline_extension/pelican_inline_markdown_extension.py

@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+"""
+Pelican Inline Markdown Extension
+==================================
+An extension for the Python Markdown module that enables
+the Pelican Python static site generator to add inline patterns.
+"""
+
+import markdown
+import re
+
+from markdown.util import etree
+from markdown.util import AtomicString
+
+class PelicanInlineMarkdownExtensionPattern(markdown.inlinepatterns.Pattern):
+    """Inline Markdown processing"""
+
+    def __init__(self, pelican_markdown_extension, tag, pattern):
+        super(PelicanInlineMarkdownExtensionPattern,self).__init__(pattern)
+        self.tag = tag
+        self.config = pelican_markdown_extension.getConfig('config')
+
+    def handleMatch(self, m):
+        node = markdown.util.etree.Element(self.tag)
+        tag_attributes = self.config.get(m.group('prefix'), ('', 'pelican-inline'))
+        tag_class = 'pelican-inline'  # default class
+        tag_style = ''  # default is for no styling
+
+        if isinstance(tag_attributes, tuple):
+            tag_style = tag_attributes[0]
+            tag_class = tag_attributes[1] if len(tag_attributes) > 1 else ''
+        elif isinstance(tag_attributes, basestring):
+            tag_class = tag_attributes
+
+        if tag_class != '':
+            node.set('class', tag_class)
+        if tag_style!= '':
+            node.set('style', tag_style)
+
+        node.text = markdown.util.AtomicString(m.group('text'))
+
+        return node
+
+class PelicanInlineMarkdownExtension(markdown.Extension):
+    """A Markdown extension enabling processing in Markdown for Pelican"""
+    def __init__(self, config):
+
+        try:
+            # Needed for Markdown versions >= 2.5
+            self.config['config'] = ['{}', 'config for markdown extension']
+            super(PelicanInlineMarkdownExtension,self).__init__(**config)
+        except AttributeError:
+            # Markdown versions < 2.5
+            config['config'] = [config['config'], 'config for markdown extension']
+            super(PelicanInlineMarkdownExtension, self).__init__(config)
+
+    def extendMarkdown(self, md, md_globals):
+        # Regex to detect mathjax
+        config = self.getConfig('config')
+        patterns = []
+
+        # The following mathjax settings can be set via the settings dictionary
+        for key in config:
+            patterns.append(re.escape(key))
+
+        inline_regex = r'(?P<prefix>%s)(?P<text>.+?)\2' % ('|'.join(patterns))
+
+        # Process after escapes
+        md.inlinePatterns.add('texthighlight_inlined', PelicanInlineMarkdownExtensionPattern(self, 'span', inline_regex), '>escape')