Skip to content

Commit d6c12b8

Browse files
committed
issue2551108 - fix markdown formatted designator links
Designators like 'issue1' are automatically hyperlinked. However if typed as [issue1](issue1) or [issue1](https://example.com/issue1) they get mangled. Stop that mangling.
1 parent 78a9cd4 commit d6c12b8

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ Fixed:
7070
with postgresql. This turns of client-side cursor handling and avoids
7171
*large* roundup process (or wsgi process) in case of large results.
7272
Fixes issue2551114.
73+
- issue2551108 - fix handling of designator links when formatted
74+
as markdown links. (Reported by Cedric Krier; John Rouillard)
7375

7476
Features:
7577
- issue2550522 - Add 'filter' command to command-line

roundup/cgi/templating.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,6 +1691,23 @@ def _hyper_repl_markdown(self, match):
16911691
s = match.group(group)
16921692
return '<%s>' % s
16931693
if match.group('id') and len(match.group('id')) < 10:
1694+
# Pass through markdown style links:
1695+
# [issue1](https://....)
1696+
# [issue1](issue1)
1697+
# as 'issue1'. Don't convert issue1 into a link.
1698+
# https://issues.roundup-tracker.org/issue2551108
1699+
start = match.start('item') - 1
1700+
end = match.end('item')
1701+
if start >= 0:
1702+
prefix = match.string[start]
1703+
if end < len(match.string):
1704+
suffix = match.string[end]
1705+
if (prefix, suffix) in {('[', ']')}:
1706+
if match.string[end+1] == '(': # find following (
1707+
return match.group(0)
1708+
if (prefix, suffix) in {('(',')')}:
1709+
if match.string[start-1] == ']':
1710+
return match.group(0)
16941711
return self._hyper_repl_item(match,'[%(item)s](%(cls)s%(id)s)')
16951712
else:
16961713
# just return the matched text

test/test_templating.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444

4545
class MockDatabase(MockNull):
4646
def getclass(self, name):
47+
# Class returned must have hasnode(id) method that returns true
48+
# otherwise designators like 'issue1' can't be hyperlinked.
49+
self.classes[name].hasnode = lambda id: True
4750
return self.classes[name]
4851

4952
# setup for csrf testing of otks database api
@@ -468,6 +471,34 @@ def test_string_markdown_link(self):
468471
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A link <http://localhost>'))
469472
self.assertEqual(p.markdown().strip(), u2s(u'<p>A link <a href="http://localhost">http://localhost</a></p>'))
470473

474+
def test_string_markdown_link_item(self):
475+
""" The link formats for the different markdown engines changes.
476+
Order of attributes, value for rel (noopener, nofollow etc)
477+
is different. So most tests check for a substring that indicates
478+
success rather than the entire returned string.
479+
"""
480+
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'An issue1 link'))
481+
self.assertIn( u2s(u'href="issue1"'), p.markdown().strip())
482+
# just verify that plain linking is working
483+
self.assertIn( u2s(u'href="issue1"'), p.plain(hyperlink=1))
484+
485+
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'An [issue1](issue1) link'))
486+
self.assertIn( u2s(u'href="issue1"'), p.markdown().strip())
487+
# just verify that plain linking is working
488+
self.assertIn( u2s(u'href="issue1"'), p.plain(hyperlink=1))
489+
490+
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'An [issue1](https://example.com/issue1) link'))
491+
self.assertIn( u2s(u'href="https://example.com/issue1"'), p.markdown().strip())
492+
493+
p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'An [issue1] (https://example.com/issue1) link'))
494+
self.assertIn( u2s(u'href="issue1"'), p.markdown().strip())
495+
if type(self) == MistuneTestCase:
496+
# mistune makes the https url into a real link
497+
self.assertIn( u2s(u'href="https://example.com/issue1"'), p.markdown().strip())
498+
else:
499+
# the other two engines leave the parenthesized url as is.
500+
self.assertIn( u2s(u' (https://example.com/issue1) link'), p.markdown().strip())
501+
471502
def test_string_markdown_link(self):
472503
# markdown2 and markdown escape the email address
473504
try:

0 commit comments

Comments
 (0)