Skip to content

Commit

Permalink
MagicLink: change processing to use x instead of twitter (#2450)
Browse files Browse the repository at this point in the history
twitter is still available but deprecated and will be removed in the
future.
  • Loading branch information
facelessuser authored Sep 8, 2024
1 parent c077781 commit 047b27b
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 27 deletions.
5 changes: 5 additions & 0 deletions docs/src/markdown/about/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 10.10

- **NEW**: MagicLink: Change social process to support `x` instead of `twitter`. `twitter` is still recognized but is
now deprecated and will be removed at a future time.

## 10.9

- **NEW**: Officially support Python 3.13.
Expand Down
12 changes: 6 additions & 6 deletions docs/src/markdown/extensions/magiclink.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ requests (!13{.magiclink-ignore}), GitHub Discussion (?1173{.magiclink-ignore}),
(7d1b1902ea7fe00043a249564ed5032f08dd7152{.magiclink-ignore}), and compares
(e2ed7e0b3973f3f9eb7a26b8ef7ae514eebfe0d2...90b6fb8711e75732f987982cc024e9bb0111beac{.magiclink-ignore}). You can also
reference repositories (@facelessuser/pymdown-extensions{.magiclink-ignore}) and users
(@facelessuser{.magiclink-ignore}). Mentions also works for social media (only Twitter is supported at this time).
(@facelessuser{.magiclink-ignore}). Mentions also works for social media (only X is supported at this time).
```

The syntax used is actually very similar to GitLab's syntax. GitLab was chosen as its syntax bridges the gaps between
Expand Down Expand Up @@ -127,7 +127,7 @@ default, use the format `@{provider}:{user}`
```text title="Mentions"
@facelessuser
@twitter:twitter
@x:x
```

/// html | div.result
Expand All @@ -149,7 +149,7 @@ extension_configs:
---
@facelessuser
@twitter:twitter
@x:x
```
///

Expand Down Expand Up @@ -496,7 +496,7 @@ Compares | `magiclink-compare`
GitHub | `magiclink-github`
Bitbucket | `magiclink-bitbucket`
GitLab | `magiclink-gitlab`
Twitter | `magiclink-twitter`
X | `magiclink-x`

/// tip | Styling Links
With a little bit of CSS^[](#_fn_1)^, you can also add icons in front: 7d1b1902ea7fe00043a249564ed5032f08dd7152,
Expand All @@ -515,7 +515,7 @@ Option | Type | Default | Descrip
------------------------------- | ------ | --------------------------- | -----------
`hide_protocol` | bool | `#!py3 False` | If `True`, links are displayed without the initial `ftp://`, `http://`, `https://`, or `ftps://`.
`repo_url_shortener` | bool | `#!py3 False` | If `True`, GitHub, Bitbucket, and GitLab commit, pull, and issue links are are rendered in a shorthand syntax.
`social_url_shortener` | bool | `#!py3 False` | if `True`, Twitter user links are rendered in a shorthand syntax.
`social_url_shortener` | bool | `#!py3 False` | if `True`, X user links are rendered in a shorthand syntax.
`shortener_user_exclude` | dict | [See below](#user-excludes) | Specifies a list of user names to avoid when attempting to shorten links. See [User Excludes](#user-excludes) for more info.
`repo_url_shorthand` | bool | `#!py3 False` | If `True`, you can directly use a shorthand syntax to represent commit, pull, issue, and mention links for repository providers and they will be auto-linked.
`social_url_shorthand` | bool | `#!py3 False` | If `True`, you can directly use a shorthand syntax to represent mention links for social media providers and they will be auto-linked.
Expand All @@ -534,7 +534,7 @@ Defaults for `shortener_user_exclude`:
"bitbucket": ['dashboard', 'account', 'plans', 'support', 'repo'],
"github": ['marketeplace', 'notifications', 'issues', 'pull', 'sponsors', 'settings', 'support'],
"gitlab": ['dashboard', '-', 'explore', 'help', 'projects'],
"twitter": ['i', 'messages', 'bookmarks', 'home']
"x": ['i', 'messages', 'bookmarks', 'home']
}
```

Expand Down
2 changes: 1 addition & 1 deletion pymdownx/__meta__.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,5 @@ def parse_version(ver, pre=False):
return Version(major, minor, micro, release, pre, post, dev)


__version_info__ = Version(10, 9, 0, "final")
__version_info__ = Version(10, 10, 0, "final")
__version__ = __version_info__._get_canonical()
34 changes: 28 additions & 6 deletions pymdownx/magiclink.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from markdown import Extension
from markdown.treeprocessors import Treeprocessor
from markdown import util as md_util
from .util import warn_deprecated
import xml.etree.ElementTree as etree
from . import util
import re
Expand All @@ -38,7 +39,8 @@
"bitbucket": ['dashboard', 'account', 'plans', 'support', 'repo'],
"github": ['marketeplace', 'notifications', 'issues', 'pull', 'sponsors', 'settings', 'support'],
"gitlab": ['dashboard', '-', 'explore', 'help', 'projects'],
"twitter": ['i', 'messages', 'bookmarks', 'home']
"twitter": ['i', 'messages', 'bookmarks', 'home'],
"x": ['i', 'messages', 'bookmarks', 'home']
}

# Bare link/email detection
Expand Down Expand Up @@ -68,6 +70,7 @@

# Provider specific user regex rules
RE_TWITTER_USER = r'\w{1,15}'
RE_X_USER = r'\w{1,15}'
RE_GITHUB_USER = r'[a-zA-Z\d](?:[-a-zA-Z\d_]{0,37}[a-zA-Z\d])?'
RE_GITLAB_USER = r'[\.a-zA-Z\d_](?:[-a-zA-Z\d_\.]{0,37}[-a-zA-Z\d_])?'
RE_BITBUCKET_USER = r'[-a-zA-Z\d_]{1,39}'
Expand All @@ -94,6 +97,7 @@ def create_ext_mentions(name, provider_type):
return fr'{name}:{RE_BITBUCKET_USER}'

RE_TWITTER_EXT_MENTIONS = fr'twitter:{RE_TWITTER_USER}'
RE_X_EXT_MENTIONS = fr'x:{RE_X_USER}'
RE_GITHUB_EXT_MENTIONS = create_ext_mentions('github', 'github')
RE_GITLAB_EXT_MENTIONS = create_ext_mentions('gitlab', 'gitlab')
RE_BITBUCKET_EXT_MENTIONS = create_ext_mentions('bitbucket', 'bitbucket')
Expand Down Expand Up @@ -245,13 +249,14 @@ def create_user_link_pattern(provider, host, www=True):
RE_SOCIAL_LINK = re.compile(
r'''(?xi)
^(?:
(?P<twitter>(?P<twitter_base>https://(?:w{{3}}\.)?twitter\.com/(?P<twitter_user>{})))
(?P<twitter>(?P<twitter_base>https://(?:w{{3}}\.)?twitter\.com/(?P<twitter_user>{}))) |
(?P<x>(?P<x_base>https://(?:w{{3}}\.)?x\.com/(?P<x_user>{})))
)/?$
'''.format(RE_TWITTER_USER)
'''.format(RE_TWITTER_USER, RE_X_USER)
)

# Provider specific info (links, names, specific patterns, etc.)
SOCIAL_PROVIDERS = {'twitter'}
SOCIAL_PROVIDERS = {'x', 'twitter'}

# Templates for providers
PROVIDER_TEMPLATES = {
Expand Down Expand Up @@ -295,6 +300,12 @@ def create_user_link_pattern(provider, host, www=True):
"url": "{}",
"user_pattern": RE_TWITTER_USER
},
"x": {
"provider": "X",
"type": "x",
"url": "{}",
"user_pattern": RE_X_USER
}
}


Expand All @@ -311,6 +322,7 @@ def create_provider(provider, host):

PROVIDER_INFO = {
"twitter": create_provider('twitter', "https://twitter.com"),
"x": create_provider('x', "https://x.com"),
"gitlab": create_provider('gitlab', 'https://gitlab.com'),
"bitbucket": create_provider('bitbucket', "https://bitbucket.org"),
"github": create_provider('github', "https://github.com")
Expand Down Expand Up @@ -643,6 +655,9 @@ def get_social_provider(self, match):

if match.group('twitter'):
provider = 'twitter'

elif match.group('x'):
provider = 'x'
return provider

def get_type(self, provider, match):
Expand Down Expand Up @@ -802,6 +817,8 @@ def run(self, root):
m = RE_SOCIAL_LINK.match(href)
if m:
provider = self.get_social_provider(m)
if provider == 'twitter':
warn_deprecated("The 'twitter' social provider has been deprecated, please use 'x' instead")
self.my_repo = self.is_my_repo(provider, m)
self.my_user = self.my_repo or self.is_my_user(provider, m)
value, link_type = self.get_type(provider, m)
Expand Down Expand Up @@ -896,6 +913,9 @@ def handleMatch(self, m, data):
provider = self.provider
mention = parts[0]

if provider == 'twitter':
warn_deprecated("The 'twitter' social provider has been deprecated, please use 'x' instead")

el = etree.Element("a")
el.set('href', '{}/{}'.format(self.provider_info[provider]['url'], mention))
el.set(
Expand Down Expand Up @@ -1041,7 +1061,8 @@ def __init__(self, *args, **kwargs):
"bitbucket": ['dashboard', 'account', 'plans', 'support', 'repo'],
"github": ['marketeplace', 'notifications', 'issues', 'pull', 'sponsors', 'settings', 'support'],
"gitlab": ['dashboard', '-', 'explore', 'help', 'projects'],
"twitter": ['i', 'messages', 'bookmarks', 'home']
"twitter": ['i', 'messages', 'bookmarks', 'home'],
"x": ['i', 'messages', 'bookmarks', 'home']
},
"A list of user names to exclude from URL shortening."
],
Expand All @@ -1055,7 +1076,7 @@ def __init__(self, *args, **kwargs):
],
'provider': [
'github',
'The base provider to use (github, gitlab, bitbucket, twitter) - Default: "github"'
'The base provider to use (github, gitlab, bitbucket, x) - Default: "github"'
],
'labels': [
{},
Expand Down Expand Up @@ -1294,6 +1315,7 @@ def extendMarkdown(self, md):
self.ext_mentions.extend(external_users)

if self.social_short:
self.ext_mentions.append(RE_X_EXT_MENTIONS)
self.ext_mentions.append(RE_TWITTER_EXT_MENTIONS)
self.int_mentions = self.provider_info[self.provider]['user_pattern']
self.setup_shorthand(md)
Expand Down
2 changes: 1 addition & 1 deletion tests/extensions/magiclink/magiclink (shorthand).html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<p>Commit <a class="magiclink magiclink-gitlab magiclink-commit" href="https://gitlab.com/some-user/some-repo/-/commit/3f6b07a8eeaa9d606115758d90f55fec565d4e2a" title="GitLab Commit: some-user/some-repo@3f6b07a8">some-user/some-repo@3f6b07a8</a></p>
<p>Compare <a class="magiclink magiclink-gitlab magiclink-compare" href="https://gitlab.com/some-user/some-repo/-/compare/e2ed7e0b3973f3f9eb7a26b8ef7ae514eebfe0d2...90b6fb8711e75732f987982cc024e9bb0111beac" title="GitLab Compare: some-user/some-repo@e2ed7e0b...90b6fb87">some-user/some-repo@e2ed7e0b...90b6fb87</a></p>
<hr />
<p><a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/username" title="Twitter User: username">@username</a></p>
<p><a class="magiclink magiclink-x magiclink-mention" href="https://x.com/username" title="X User: username">@username</a></p>
<hr />
<p>No issue #33</p>
<p>No issue &#35;</p>
Expand Down
2 changes: 1 addition & 1 deletion tests/extensions/magiclink/magiclink (shorthand).txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Compare gitlab:some-user/some-repo@e2ed7e0b3973f3f9eb7a26b8ef7ae514eebfe0d2...90

---

@twitter:username
@x:username

---

Expand Down
8 changes: 4 additions & 4 deletions tests/extensions/magiclink/magiclink (shorthand-social).html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p>Mention <a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/some" title="Twitter User: some">@some</a>-bodies_name</p>
<p>Not a repo mention <a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/some" title="Twitter User: some">@some</a>-bodies_name/some_repository</p>
<p>Not a repo mention <a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/facelessuser" title="Twitter User: facelessuser">@facelessuser</a>/some_repository</p>
<p>Mention <a class="magiclink magiclink-x magiclink-mention" href="https://x.com/some" title="X User: some">@some</a>-bodies_name</p>
<p>Not a repo mention <a class="magiclink magiclink-x magiclink-mention" href="https://x.com/some" title="X User: some">@some</a>-bodies_name/some_repository</p>
<p>Not a repo mention <a class="magiclink magiclink-x magiclink-mention" href="https://x.com/facelessuser" title="X User: facelessuser">@facelessuser</a>/some_repository</p>
<p>No Commit some-bodies_name/some_repository@3f6b07a8eeaa9d606115758d90f55fec565d4e2a</p>
<p>No Issue some-bodies_name/some_repository#33</p>
<p>No Pull request some-bodies_name/some_repository!33</p>
Expand All @@ -17,7 +17,7 @@
<p>Pull request <a class="magiclink magiclink-bitbucket magiclink-pull" href="https://bitbucket.org/some-user/some-repo/pull-requests/2" title="Bitbucket Pull Request: some-user/some-repo #2">some-user/some-repo!2</a></p>
<p>Commit <a class="magiclink magiclink-gitlab magiclink-commit" href="https://gitlab.com/some-user/some-repo/-/commit/3f6b07a8eeaa9d606115758d90f55fec565d4e2a" title="GitLab Commit: some-user/some-repo@3f6b07a8">some-user/some-repo@3f6b07a8</a></p>
<hr />
<p><a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/username" title="Twitter User: username">@username</a></p>
<p><a class="magiclink magiclink-x magiclink-mention" href="https://x.com/username" title="X User: username">@username</a></p>
<hr />
<p>No issue #33</p>
<p>No pull request !33</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Commit gitlab:some-user/some-repo@3f6b07a8eeaa9d606115758d90f55fec565d4e2a

---

@twitter:username
@x:username

---

Expand Down
2 changes: 1 addition & 1 deletion tests/extensions/magiclink/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ magiclink (shorthand-social):
repo_url_shortener: true
repo_url_shorthand: true
social_url_shorthand: true
provider: twitter
provider: x
user: facelessuser
repo: pymdown-extensions

Expand Down
71 changes: 65 additions & 6 deletions tests/test_extensions/test_magiclink.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Test cases for MagicLink."""
from .. import util
import markdown
import warnings


class TestMagicLinkShortner(util.MdCase):
Expand Down Expand Up @@ -38,8 +39,8 @@ def test_no_social(self):
"""Test that social shortening does not happen."""

self.check_markdown(
r'https://twitter.com/someuser',
r'<p><a href="https://twitter.com/someuser">https://twitter.com/someuser</a></p>'
r'https://x.com/someuser',
r'<p><a href="https://x.com/someuser">https://x.com/someuser</a></p>'
)

def test_excluded_user(self):
Expand Down Expand Up @@ -142,8 +143,8 @@ def test_user(self):

# Test #! original syntax
self.check_markdown(
r'https://twitter.com/someuser',
r'<p><a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/someuser" title="Twitter User: someuser">@someuser</a></p>' # noqa: E501
r'https://x.com/someuser',
r'<p><a class="magiclink magiclink-x magiclink-mention" href="https://x.com/someuser" title="X User: someuser">@someuser</a></p>' # noqa: E501
)

def test_no_repo(self):
Expand All @@ -158,8 +159,8 @@ def test_excluded(self):
"""Test excluded user."""

self.check_markdown(
r'https://twitter.com/home',
r'<p><a href="https://twitter.com/home">https://twitter.com/home</a></p>'
r'https://x.com/home',
r'<p><a href="https://x.com/home">https://x.com/home</a></p>'
)


Expand Down Expand Up @@ -340,3 +341,61 @@ def test_bad_name(self):

with self.assertRaises(ValueError):
markdown.markdown('', extensions=extension, extension_configs=extension_configs)

class TestMagicLinkWarning(util.MdCase):
"""Test cases for social link shortener."""

extension = [
'pymdownx.magiclink'
]

extension_configs = {
'pymdownx.magiclink': {
'social_url_shortener': True,
'social_url_shorthand': True
}
}

def test_deprecated_twitter(self):
"""Test deprecation warning."""

with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.

# Trigger a warning.
warnings.simplefilter("always")
self.check_markdown(
'@twitter:user',
'<p><a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/user" title="Twitter User: user">@user</a></p>' # noqa: E501
)
target = "The 'twitter' social provider has been deprecated, please use 'x' instead"
for warn in w:
if target in str(warn.message):
found = True
break
# Verify some things
self.assertTrue(len(w) == 1)
self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
self.assertTrue(found)

def test_deprecated_twitter_shortener(self):
"""Test shortener deprecation warning."""

with warnings.catch_warnings(record=True) as w:
# Cause all warnings to always be triggered.

# Trigger a warning.
warnings.simplefilter("always")
self.check_markdown(
'https://twitter.com/user',
'<p><a class="magiclink magiclink-twitter magiclink-mention" href="https://twitter.com/user" title="Twitter User: user">@user</a></p>' # noqa: E501
)
target = "The 'twitter' social provider has been deprecated, please use 'x' instead"
for warn in w:
if target in str(warn.message):
found = True
break
# Verify some things
self.assertTrue(len(w) == 1)
self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
self.assertTrue(found)

0 comments on commit 047b27b

Please sign in to comment.