From 0edc99628773bfd0694c8e253bdfe7fdcc2fb9e7 Mon Sep 17 00:00:00 2001 From: Darks Date: Wed, 24 Feb 2021 00:38:26 +0100 Subject: [PATCH] markdown: add linkify extension --- app/utils/bleach_allowlist.py | 2 +- app/utils/filters/markdown.py | 2 + app/utils/markdown_extensions/linkify.py | 56 ++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 app/utils/markdown_extensions/linkify.py diff --git a/app/utils/bleach_allowlist.py b/app/utils/bleach_allowlist.py index 7468380..2d0699a 100644 --- a/app/utils/bleach_allowlist.py +++ b/app/utils/bleach_allowlist.py @@ -16,7 +16,7 @@ markdown_tags = [ markdown_attrs = { "*": ["id", "class"], "img": ["src", "alt", "title"], - "a": ["href", "alt", "title"], + "a": ["href", "alt", "title", "rel"], "form": ["action", "method", "enctype"], "input": ["id", "name", "type", "value"], "label": ["for"], diff --git a/app/utils/filters/markdown.py b/app/utils/filters/markdown.py index bedb234..900cc58 100644 --- a/app/utils/filters/markdown.py +++ b/app/utils/filters/markdown.py @@ -10,6 +10,7 @@ from app.utils.bleach_allowlist import markdown_tags, markdown_attrs from app.utils.markdown_extensions.pclinks import PCLinkExtension from app.utils.markdown_extensions.hardbreaks import HardBreakExtension from app.utils.markdown_extensions.escape_html import EscapeHtmlExtension +from app.utils.markdown_extensions.linkify import LinkifyExtension @app.template_filter('md') @@ -29,6 +30,7 @@ def md(text): EscapeHtmlExtension(), FootnoteExtension(UNIQUE_IDS=True), HardBreakExtension(), + LinkifyExtension(), TocExtension(baselevel=2), PCLinkExtension(), ] diff --git a/app/utils/markdown_extensions/linkify.py b/app/utils/markdown_extensions/linkify.py new file mode 100644 index 0000000..86e9e4b --- /dev/null +++ b/app/utils/markdown_extensions/linkify.py @@ -0,0 +1,56 @@ +# The MIT License (MIT) +# +# Copyright (c) 2013 Raitis Stengrevics +# https://github.com/daGrevis/mdx_linkify +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from bleach.linkifier import Linker + +from markdown.postprocessors import Postprocessor +from markdown.extensions import Extension + + +class LinkifyExtension(Extension): + def __init__(self, **kwargs): + self.config = { + 'linker_options': [{}, 'Options for bleach.linkifier.Linker'], + } + super(LinkifyExtension, self).__init__(**kwargs) + + def extendMarkdown(self, md): + md.postprocessors.register( + LinkifyPostprocessor( + md, + self.getConfig('linker_options'), + ), + "linkify", + 50, + ) + + +class LinkifyPostprocessor(Postprocessor): + def __init__(self, md, linker_options): + super(LinkifyPostprocessor, self).__init__(md) + linker_options.setdefault("skip_tags", ["code"]) + self._linker_options = linker_options + + def run(self, text): + linker = Linker(**self._linker_options) + return linker.linkify(text)