Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MagicLink: change processing to use x instead of twitter #2450

Merged
merged 1 commit into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)