Moving wiki mentions to an extension
parent
db91acb065
commit
f6ea608a04
|
@ -10,6 +10,7 @@ from . import spaced_link
|
|||
from . import strikethrough
|
||||
from . import wikilinks
|
||||
from . import emojify
|
||||
from . import mentions
|
||||
|
||||
AutolinkExtension = autolink.AutolinkExtension
|
||||
AutomailExtension = automail.AutomailExtension
|
||||
|
@ -19,3 +20,4 @@ SpacedLinkExtension = spaced_link.SpacedLinkExtension
|
|||
StrikethroughExtension = strikethrough.StrikethroughExtension
|
||||
WikiLinkExtension = wikilinks.WikiLinkExtension
|
||||
EmojifyExtension = emojify.EmojifyExtension
|
||||
MentionsExtension = mentions.MentionsExtension
|
||||
|
|
|
@ -159,6 +159,8 @@ class EmojifyExtension(Extension):
|
|||
class EmojifyPreprocessor(Preprocessor):
|
||||
|
||||
def run(self, lines):
|
||||
pattern = re.compile(':([a-z0-9\+\-_]+):')
|
||||
|
||||
new_lines = []
|
||||
|
||||
def emojify(match):
|
||||
|
@ -173,7 +175,7 @@ class EmojifyPreprocessor(Preprocessor):
|
|||
|
||||
for line in lines:
|
||||
if line.strip():
|
||||
line = re.sub(r':([a-z0-9\+\-_]+):', emojify, line, flags=re.UNICODE)
|
||||
line = pattern.sub(emojify, line)
|
||||
|
||||
new_lines.append(line)
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#-*- coding: utf-8 -*-
|
||||
|
||||
# Tested on Markdown 2.3.1
|
||||
#
|
||||
# Copyright (c) 2014, Esteban Castro Borsani
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
from markdown.extensions import Extension
|
||||
from markdown.preprocessors import Preprocessor
|
||||
|
||||
|
||||
class MentionsExtension(Extension):
|
||||
|
||||
def extendMarkdown(self, md, md_globals):
|
||||
md.registerExtension(self)
|
||||
md.preprocessors.add('emojify',
|
||||
MentionsPreprocessor(md),
|
||||
'_end')
|
||||
|
||||
|
||||
class MentionsPreprocessor(Preprocessor):
|
||||
|
||||
def run(self, lines):
|
||||
new_lines = []
|
||||
pattern = re.compile('(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9]+)')
|
||||
|
||||
def make_mention_link(m):
|
||||
name = m.group(1)
|
||||
|
||||
if not User.objects.filter(username=name):
|
||||
return "@{name}".format(name=name)
|
||||
|
||||
tpl = ('[@{name}](/#/profile/{name} "@{name}")')
|
||||
return tpl.format(name=name)
|
||||
|
||||
for line in lines:
|
||||
if line.strip():
|
||||
line = pattern.sub(make_mention_link, line)
|
||||
|
||||
new_lines.append(line)
|
||||
|
||||
return new_lines
|
||||
|
||||
|
||||
def makeExtension(configs=None):
|
||||
return MentionsExtension(configs=configs)
|
|
@ -1,52 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012, lepture.com
|
||||
# Copyright (c) 2014, taiga.io
|
||||
#
|
||||
# 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 author 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "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 THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS 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.
|
||||
|
||||
import re
|
||||
|
||||
from taiga.users.models import User
|
||||
|
||||
def mentions(text):
|
||||
pattern = re.compile('(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9]+)')
|
||||
|
||||
def make_mention_link(m):
|
||||
name = m.group(1)
|
||||
|
||||
if not User.objects.filter(username=name):
|
||||
return "@{name}".format(name=name)
|
||||
|
||||
tpl = ('[@{name}](/#/profile/{name} "@{name}")')
|
||||
return tpl.format(name=name)
|
||||
|
||||
text = pattern.sub(make_mention_link, text)
|
||||
return text
|
||||
|
||||
__all__ = ['mentions']
|
|
@ -15,8 +15,8 @@ from .gfm import SpacedLinkExtension
|
|||
from .gfm import StrikethroughExtension
|
||||
from .gfm import WikiLinkExtension
|
||||
from .gfm import EmojifyExtension
|
||||
from .gfm import MentionsExtension
|
||||
|
||||
from .processors.mentions import mentions
|
||||
from .processors.references import references
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@ def _make_extensions_list(wikilinks_config=None):
|
|||
StrikethroughExtension(),
|
||||
WikiLinkExtension(wikilinks_config),
|
||||
EmojifyExtension(),
|
||||
MentionsExtension(),
|
||||
"extra",
|
||||
"codehilite"]
|
||||
|
||||
|
@ -61,7 +62,7 @@ def _render_markdown(project, text):
|
|||
|
||||
|
||||
def _preprocessors(project, text):
|
||||
pre = F() >> mentions >> F(references, project)
|
||||
pre = F() >> F(references, project)
|
||||
return pre(text)
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ from unittest import mock
|
|||
import pytest
|
||||
|
||||
import taiga.base
|
||||
from taiga.mdrender.processors import emoji
|
||||
from taiga.mdrender.processors import mentions
|
||||
from taiga.mdrender.gfm import mentions
|
||||
from taiga.mdrender.gfm import emojify
|
||||
from taiga.mdrender.processors import references
|
||||
from taiga.mdrender.service import render
|
||||
|
||||
|
@ -16,12 +16,12 @@ dummy_project.id = 1
|
|||
dummy_project.slug = "test"
|
||||
|
||||
def test_proccessor_valid_emoji():
|
||||
result = emoji.emoji("<b>:smile:</b>")
|
||||
assert result == '<b><img class="emoji" title="smile" alt="smile" height="20" width="20" src="http://localhost:8000/static/img/emojis/smile.png" align="top"></b>'
|
||||
result = emojify.EmojifyPreprocessor().run(["**:smile:**"])
|
||||
assert result == ["****"]
|
||||
|
||||
def test_proccessor_invalid_emoji():
|
||||
result = emoji.emoji("<b>:notvalidemoji:</b>")
|
||||
assert result == "<b>:notvalidemoji:</b>"
|
||||
result = emojify.EmojifyPreprocessor().run(["**:notvalidemoji:**"])
|
||||
assert result == ["**:notvalidemoji:**"]
|
||||
|
||||
def test_proccessor_valid_user_mention():
|
||||
DummyModel = DummyClass()
|
||||
|
@ -30,8 +30,8 @@ def test_proccessor_valid_user_mention():
|
|||
|
||||
mentions.User = DummyModel
|
||||
|
||||
result = mentions.mentions("**@user1**")
|
||||
assert result == '**[@user1](/#/profile/user1 "@user1")**'
|
||||
result = mentions.MentionsPreprocessor().run(["**@user1**"])
|
||||
assert result == ["**[@user1](/#/profile/user1 \"@user1\")**"]
|
||||
|
||||
def test_proccessor_invalid_user_mention():
|
||||
DummyModel = DummyClass()
|
||||
|
@ -40,8 +40,8 @@ def test_proccessor_invalid_user_mention():
|
|||
|
||||
mentions.User = DummyModel
|
||||
|
||||
result = mentions.mentions("**@notvaliduser**")
|
||||
assert result == '**@notvaliduser**'
|
||||
result = mentions.MentionsPreprocessor().run(["**@notvaliduser**"])
|
||||
assert result == ['**@notvaliduser**']
|
||||
|
||||
|
||||
def test_proccessor_valid_us_reference():
|
||||
|
|
Loading…
Reference in New Issue