M src/wiki/core/markdown/__init__.py => src/wiki/core/markdown/__init__.py +58 -2
@@ 23,8 23,8 @@ class ArticleMarkdown(markdown.Markdown):
def get_markdown_extensions(self):
extensions = list(settings.MARKDOWN_KWARGS.get("extensions", []))
- extensions += self.core_extensions()
- extensions += plugin_registry.get_markdown_extensions()
+ extensions = self.core_extensions()
+ extensions = plugin_registry.get_markdown_extensions()
return extensions
def convert(self, text, *args, **kwargs):
@@ 51,3 51,59 @@ class ArticleMarkdown(markdown.Markdown):
def article_markdown(text, article, *args, **kwargs):
md = ArticleMarkdown(article, *args, **kwargs)
return md.convert(text)
+
+
+def add_to_registry(processor, key, value, location):
+ """Utility function to register a key by location to Markdown's registry.
+
+ Parameters:
+ * `processor`: Markdown Registry instance
+ * `key`: A string used to reference the item.
+ * `value`: The item being registered.
+ * `location`: Where to register the new key
+
+ location can be one of the strings below:
+ * _begin (registers the key as the highest priority)
+ * _end (registers the key as the lowest priority)
+ * a string that starts with `<` or `>` (sets priority halfway between existing priorities)
+
+ Returns: None
+ Raises: ValueError if location is an invalid string.
+ """
+
+ if len(processor) == 0:
+ # This is the first item. Set priority to 50.
+ priority = 50
+ elif location == "_begin":
+ processor._sort()
+ # Set priority 5 greater than highest existing priority
+ priority = processor._priority[0].priority + 5
+ elif location == "_end":
+ processor._sort()
+ # Set priority 5 less than lowest existing priority
+ priority = processor._priority[-1].priority - 5
+ elif location.startswith("<") or location.startswith(">"):
+ # Set priority halfway between existing priorities.
+ i = processor.get_index_for_name(location[1:])
+ if location.startswith("<"):
+ after = processor._priority[i].priority
+ if i > 0:
+ before = processor._priority[i - 1].priority
+ else:
+ # Location is first item`
+ before = after + 10
+ else:
+ # location.startswith('>')
+ before = processor._priority[i].priority
+ if i < len(processor) - 1:
+ after = processor._priority[i + 1].priority
+ else:
+ # location is last item
+ after = before - 10
+ priority = before - ((before - after) / 2)
+ else:
+ raise ValueError(
+ 'Not a valid location: "%s". Location key '
+ 'must start with a ">" or "<".' % location
+ )
+ processor.register(value, key, priority)
M src/wiki/core/markdown/mdx/codehilite.py => src/wiki/core/markdown/mdx/codehilite.py +5 -2
@@ 5,6 5,7 @@ from markdown.extensions.codehilite import CodeHilite
from markdown.extensions.codehilite import CodeHiliteExtension
from markdown.preprocessors import Preprocessor
from markdown.treeprocessors import Treeprocessor
+from wiki.core.markdown import add_to_registry
logger = logging.getLogger(__name__)
@@ 107,7 108,7 @@ class WikiCodeHiliteExtension(CodeHiliteExtension):
"'codehilite' from WIKI_MARKDOWN_KWARGS"
)
del md.treeprocessors["hilite"]
- md.treeprocessors.add("hilite", hiliter, "<inline")
+ add_to_registry(md.treeprocessors, "hilite", hiliter, "<inline")
if "fenced_code_block" in md.preprocessors:
logger.warning(
@@ 117,7 118,9 @@ class WikiCodeHiliteExtension(CodeHiliteExtension):
del md.preprocessors["fenced_code_block"]
hiliter = WikiFencedBlockPreprocessor(md)
hiliter.config = self.getConfigs()
- md.preprocessors.add("fenced_code_block", hiliter, ">normalize_whitespace")
+ add_to_registry(
+ md.preprocessors, "fenced_code_block", hiliter, ">normalize_whitespace"
+ )
md.registerExtension(self)
M src/wiki/core/markdown/mdx/previewlinks.py => src/wiki/core/markdown/mdx/previewlinks.py +2 -1
@@ 1,5 1,6 @@
import markdown
from markdown.treeprocessors import Treeprocessor
+from wiki.core.markdown import add_to_registry
class PreviewLinksExtension(markdown.Extension):
@@ 7,7 8,7 @@ class PreviewLinksExtension(markdown.Extension):
"""Markdown Extension that sets all anchor targets to _blank when in preview mode"""
def extendMarkdown(self, md):
- md.treeprocessors.add("previewlinks", PreviewLinksTree(md), "_end")
+ add_to_registry(md.treeprocessors, "previewlinks", PreviewLinksTree(md), "_end")
class PreviewLinksTree(Treeprocessor):
M src/wiki/core/markdown/mdx/responsivetable.py => src/wiki/core/markdown/mdx/responsivetable.py +4 -1
@@ 1,13 1,16 @@
from xml.etree import ElementTree as etree
import markdown
from markdown.treeprocessors import Treeprocessor
+from wiki.core.markdown import add_to_registry
class ResponsiveTableExtension(markdown.Extension):
"""Wraps all tables with Bootstrap's table-responsive class"""
def extendMarkdown(self, md):
- md.treeprocessors.add("responsivetable", ResponsiveTableTree(md), "_end")
+ add_to_registry(
+ md.treeprocessors, "responsivetable", ResponsiveTableTree(md), "_end"
+ )
class ResponsiveTableTree(Treeprocessor):
M src/wiki/plugins/attachments/markdown_extensions.py => src/wiki/plugins/attachments/markdown_extensions.py +7 -3
@@ 4,6 4,7 @@ import markdown
from django.contrib.auth.models import AnonymousUser
from django.template.loader import render_to_string
from django.urls import reverse
+from wiki.core.markdown import add_to_registry
from wiki.core.permissions import can_read
from wiki.plugins.attachments import models
@@ 19,9 20,12 @@ class AttachmentExtension(markdown.Extension):
def extendMarkdown(self, md):
""" Insert AbbrPreprocessor before ReferencePreprocessor. """
- md.preprocessors.add(
- "dw-attachments", AttachmentPreprocessor(md), ">html_block"
- )
+ add_to_registry(
+ md.preprocessors,
+ "dw-attachments",
+ AttachmentPreprocessor(md),
+ ">html_block",
+ )
class AttachmentPreprocessor(markdown.preprocessors.Preprocessor):
M src/wiki/plugins/editsection/markdown_extensions.py => src/wiki/plugins/editsection/markdown_extensions.py +3 -2
@@ 4,6 4,7 @@ from xml.etree import ElementTree as etree
from django.urls import reverse
from markdown import Extension
from markdown.treeprocessors import Treeprocessor
+from wiki.core.markdown import add_to_registry
from . import settings
@@ 18,10 19,10 @@ class EditSectionExtension(Extension):
}
super().__init__(**kwargs)
- def extendMarkdown(self, md, md_globals):
+ def extendMarkdown(self, md):
ext = EditSectionProcessor(md)
ext.config = self.config
- md.treeprocessors.add("editsection", ext, "_end")
+ add_to_registry(md.treeprocessors, "editsection", ext, "_end")
def get_header_id(header):
M src/wiki/plugins/images/markdown_extensions.py => src/wiki/plugins/images/markdown_extensions.py +7 -2
@@ 4,6 4,7 @@ import markdown
from django.template.loader import render_to_string
from wiki.plugins.images import models
from wiki.plugins.images import settings
+from wiki.core.markdown import add_to_registry
IMAGE_RE = (
r"(?:"
@@ 32,8 33,12 @@ class ImageExtension(markdown.Extension):
"""Images plugin markdown extension for django-wiki."""
def extendMarkdown(self, md):
- md.inlinePatterns.add("dw-images", ImagePattern(IMAGE_RE, md), ">link")
- md.postprocessors.add("dw-images-cleanup", ImagePostprocessor(md), ">raw_html")
+ add_to_registry(
+ md.inlinePatterns, "dw-images", ImagePattern(IMAGE_RE, md), ">link"
+ )
+ add_to_registry(
+ md.postprocessors, "dw-images-cleanup", ImagePostprocessor(md), ">raw_html"
+ )
class ImagePattern(markdown.inlinepatterns.Pattern):
M src/wiki/plugins/macros/mdx/macro.py => src/wiki/plugins/macros/mdx/macro.py +4 -1
@@ 4,6 4,7 @@ import markdown
from django.template.loader import render_to_string
from django.utils.translation import gettext as _
from wiki.plugins.macros import settings
+from wiki.core.markdown import add_to_registry
# See:
# http://stackoverflow.com/questions/430759/regex-for-managing-escaped-characters-for-items-like-string-literals
@@ 20,7 21,9 @@ class MacroExtension(markdown.Extension):
"""Macro plugin markdown extension for django-wiki."""
def extendMarkdown(self, md):
- md.inlinePatterns.add("dw-macros", MacroPattern(MACRO_RE, md), ">link")
+ add_to_registry(
+ md.inlinePatterns, "dw-macros", MacroPattern(MACRO_RE, md), ">link"
+ )
class MacroPattern(markdown.inlinepatterns.Pattern):
M src/wiki/plugins/macros/mdx/wikilinks.py => src/wiki/plugins/macros/mdx/wikilinks.py +2 -1
@@ 8,6 8,7 @@ import markdown
from django.urls import reverse
from markdown.extensions import Extension
from markdown.extensions import wikilinks
+from wiki.core.markdown import add_to_registry
def build_url(label, base, end, md):
@@ 42,7 43,7 @@ class WikiLinkExtension(Extension):
WIKILINK_RE = r"\[\[([\w0-9_ -]+)\]\]"
wikilinkPattern = WikiLinks(WIKILINK_RE, self.getConfigs())
wikilinkPattern.md = md
- md.inlinePatterns.add("wikilink", wikilinkPattern, "<not_strong")
+ add_to_registry(md.inlinePatterns, "wikilink", wikilinkPattern, "<not_strong")
class WikiLinks(wikilinks.WikiLinksInlineProcessor):
M src/wiki/plugins/redlinks/mdx/redlinks.py => src/wiki/plugins/redlinks/mdx/redlinks.py +2 -1
@@ 6,6 6,7 @@ from markdown.extensions import Extension
from markdown.postprocessors import AndSubstitutePostprocessor
from markdown.treeprocessors import Treeprocessor
from wiki.models import URLPath
+from wiki.core.markdown import add_to_registry
def urljoin_internal(base, url):
@@ 107,7 108,7 @@ class LinkExtension(Extension):
md.registerExtension(self)
self.md = md
ext = self.TreeProcessorClass(md, self.getConfigs())
- md.treeprocessors.add("redlinks", ext, ">inline")
+ add_to_registry(md.treeprocessors, "redlinks", ext, ">inline")
def makeExtension(*args, **kwargs):