Skip to content

Commit

Permalink
WIP ticket #4: TracWiki-format wiki and ticket links
Browse files Browse the repository at this point in the history
  • Loading branch information
danuker committed Jan 26, 2021
1 parent b2a0efe commit c869b17
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 14 deletions.
2 changes: 2 additions & 0 deletions config.py.sample
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
USER_MAPPING = {
'adi': ('adiroiban', 'Adi Roiban <adi.roiban@chevah.com>'),
}

TRAC_TICKET_PREFIX = 'https://trac.chevah.com/ticket/'
55 changes: 54 additions & 1 deletion test/test_wiki_trac_rst_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from wiki_trac_rst_convert import convert_content


class TracRstToVanillaRst(unittest.TestCase):
class TracToVanillaRst(unittest.TestCase):
"""
Test conversion of content from Trac-flavored reStructuredText to
vanilla reStructuredText, that is supported by GitHub
Expand Down Expand Up @@ -107,6 +107,59 @@ def test_several_trac_wiki_rst_links_with_content(self):
' List of free software used by Chevah Project.'
)

def test_tracwiki_general_link(self):
"""
Process general links from TracWiki format to plain RST links
"""
self.assertConvertedContent(
'`Buildbot <https://chevah.com/buildbot/>`_\n',
'[https://chevah.com/buildbot/ Buildbot]'
)

def test_tracwiki_wiki_link(self):
"""
Process wiki links from TracWiki format to GitHub-compatible
RST wiki links.
There are various combinations of no-link-text, link-text-same-
as-article-name, and link-text-different-from-article-name.
"""
self.assertConvertedContent(
'`Project management and administration <Administrative>`_\n',
'[wiki:Administrative Project management and administration]'
)
self.assertConvertedContent(
'`<Administrative>`_\n',
'[wiki:Administrative Administrative]'
)
self.assertConvertedContent(
'`<Administrative>`_\n',
'[wiki:"Administrative"]'
)
self.assertConvertedContent(
'`<Administrative-AllHandMeeting-Past>`_\n',
'[wiki:"Administrative/AllHandMeeting/Past"]'
)
self.assertConvertedContent(
'`<Infrastructure-Services-FileServer>`_\n',
'`[wiki:Infrastructure/Services/FileServer]`:trac:'
)
self.assertConvertedContent(
'`Overton <Infrastructure-Machines-Overton>`_\n',
'`[wiki:Infrastructure/Machines/Overton Overton]`:trac:'
)

def test_trac_ticket(self):
"""
Trac tickets get forwarded to the correct address.
This use case requires `config.py` with the following setting:
TRAC_TICKET_PREFIX = 'https://trac.chevah.com/ticket/'
"""
self.assertConvertedContent(
'`Trac #738 <https://trac.chevah.com/ticket/738>`_\n',
':trac:`#738`'
)


if __name__ == '__main__':
unittest.main()
99 changes: 86 additions & 13 deletions wiki_trac_rst_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import sys
import os

from config import TRAC_TICKET_PREFIX


def main():
"""
Expand Down Expand Up @@ -44,36 +46,107 @@ def convert_content(text: str):
for seq in to_remove:
text = text.replace(seq, '')
text = text.strip() + '\n'
text = _trac_rst_wiki_to_github_links(text)
text = _trac_to_github_wiki_links(text)
text = _tracwiki_to_rst_links(text)
text = _tracwiki_wiki_link_with_text_to_github_links(text)
text = _trac_ticket_links(text)

return text


def _trac_rst_wiki_to_github_links(text: str):
def _trac_to_github_wiki_links(text: str):
"""
Takes RST content with Trac wiki link directives
and coverts the directives to inline GitHub wiki links.
Takes content with Trac wiki link directives and coverts
the directives to inline GitHub wiki links.
"""

link_matchers =[re.compile(r) for r in [
link_matchers = [re.compile(r) for r in [
# RST markup
':trac:`wiki:(.+?)`',
'`wiki:(.+?)`:trac:'
'`wiki:(.+?)`:trac:',

# TracWiki markup
'`\[wiki:"?([^ ]+?)"?]`:trac:',
'\[wiki:"?([^ ]+?)"?]',
]]

for link_re in link_matchers:
wiki_titles = re.findall(link_re, text)
for title in wiki_titles:
text = re.sub(
link_re,
rf'`<{_wiki_url(title)}>`_',
text,
1
)
text = _sub(link_re, f'`<{_wiki_url(title)}>`_', text)

return text


def _tracwiki_to_rst_links(text: str):
"""
Takes TracWiki markup and converts its links to RST links.
"""

url = '[a-z]+://[^ ]+'
link_text = '[^]]+'
link_re = re.compile(f'\[({url}) ({link_text})]')

matches = re.findall(link_re, text)
for url, link_text in matches:
text = _sub(link_re, f'`{link_text} <{url}>`_', text)

return text


def _wiki_url(title):
def _tracwiki_wiki_link_with_text_to_github_links(text: str):
"""
Takes TracWiki markup and converts its Wiki links which have
explicit link text into RST links.
If the link text is the same as the article name, generate a more
compact syntax.
"""

title = '[^ ]+'
link_text = '[^]]+'

link_matchers = [re.compile(r) for r in [
f'`\[wiki:({title}) ({link_text})]`:trac:',
f'\[wiki:({title}) ({link_text})]',
]]

for link_re in link_matchers:
matches = re.findall(link_re, text)
for title, link_text in matches:
if title == link_text:
text = _sub(link_re, f'`<{_wiki_url(title)}>`_', text)
else:
replacement = f'`{link_text} <{_wiki_url(title)}>`_'
text = _sub(link_re, replacement, text)

return text


def _trac_ticket_links(text: str):
"""
Replace Trac reference to ticket with actual link to the ticket
"""

ticket_re = ':trac:`#([0-9]+)`'
matches = re.findall(ticket_re, text)
for ticket in matches:
text = _sub(
ticket_re,
f'`Trac #{ticket} <{TRAC_TICKET_PREFIX}{ticket}>`_',
text
)
return text


def _sub(link_re: str, replacement: str, text: str):
"""
Substitute one occurrence of `link_re` in `text` with `replacement`.
Return the resulting new text.
"""
return re.sub(link_re, replacement, text, 1)


def _wiki_url(title: str):
"""
GitHub Wiki collapses directory structure.
Expand Down

0 comments on commit c869b17

Please sign in to comment.