0
# Link Processing
1
2
Transform system for automatically shortening and styling GitHub and GitLab repository links in documentation, making them more readable and visually consistent.
3
4
## Capabilities
5
6
### Link Shortening Transform
7
8
Transforms GitHub and GitLab links to shorter, more readable formats.
9
10
```python { .api }
11
class ShortenLinkTransform(SphinxPostTransform):
12
"""
13
Transform to shorten GitHub/GitLab links.
14
15
Automatically processes external links to GitHub and GitLab repositories,
16
converting full URLs to shortened, readable formats. Only transforms links
17
where the display text matches the URL (meaning the user hasn't customized
18
the link text).
19
20
Attributes:
21
- default_priority (int): Transform priority (400)
22
- formats (tuple): Supported output formats ('html',)
23
- supported_platform (ClassVar[dict]): Mapping of domains to platform names
24
- platform (str): Current platform being processed
25
"""
26
27
def run(self, **kwargs):
28
"""
29
Run the Transform object.
30
31
Processes all reference nodes in the document, checking for GitHub
32
and GitLab URLs that can be shortened. Only modifies links where
33
the display text equals the URL.
34
35
Parameters:
36
- **kwargs: Additional arguments (unused)
37
"""
38
39
def parse_url(self, uri: ParseResult) -> str:
40
"""
41
Parse the content of the url with respect to the selected platform.
42
43
Converts full repository URLs to shortened formats based on the
44
platform (GitHub or GitLab) and the type of content being linked.
45
46
Parameters:
47
- uri (ParseResult): Parsed URL components
48
49
Returns:
50
str: Shortened, formatted URL text
51
"""
52
```
53
54
## Supported Platforms
55
56
### GitHub Links
57
- **Domain**: `github.com`
58
- **CSS Class**: `github`
59
60
### GitLab Links
61
- **Domain**: `gitlab.com`
62
- **CSS Class**: `gitlab`
63
64
## Link Transformations
65
66
### GitHub Examples
67
68
**Repository Links**:
69
```
70
https://github.com/pydata/pydata-sphinx-theme
71
→ pydata/pydata-sphinx-theme
72
```
73
74
**Issue Links**:
75
```
76
https://github.com/pydata/pydata-sphinx-theme/issues/123
77
→ pydata/pydata-sphinx-theme#123
78
```
79
80
**Pull Request Links**:
81
```
82
https://github.com/pydata/pydata-sphinx-theme/pull/456
83
→ pydata/pydata-sphinx-theme#456
84
```
85
86
**Discussion Links**:
87
```
88
https://github.com/pydata/pydata-sphinx-theme/discussions/789
89
→ pydata/pydata-sphinx-theme#789
90
```
91
92
**Project Board Links**:
93
```
94
https://github.com/orgs/pydata/projects/5
95
→ pydata/projects#5
96
```
97
98
### GitLab Examples
99
100
**Repository Links**:
101
```
102
https://gitlab.com/group/subgroup/project
103
→ group/subgroup/project
104
```
105
106
**Issue Links**:
107
```
108
https://gitlab.com/group/project/-/issues/123
109
→ group/project#123
110
```
111
112
**Merge Request Links**:
113
```
114
https://gitlab.com/group/project/-/merge_requests/456
115
→ group/project!456
116
```
117
118
**Complex Group Structure**:
119
```
120
https://gitlab.com/group/subgroup1/subgroup2/project/-/issues/789
121
→ group/subgroup1/subgroup2/project#789
122
```
123
124
## Usage Examples
125
126
### Automatic Processing
127
128
Links are automatically processed when they appear in reStructuredText:
129
130
```rst
131
See the issue at https://github.com/pydata/pydata-sphinx-theme/issues/123 for details.
132
133
Check out this merge request: https://gitlab.com/mygroup/myproject/-/merge_requests/45
134
```
135
136
Results in:
137
```html
138
<a class="reference external github" href="https://github.com/pydata/pydata-sphinx-theme/issues/123">
139
pydata/pydata-sphinx-theme#123
140
</a>
141
142
<a class="reference external gitlab" href="https://gitlab.com/mygroup/myproject/-/merge_requests/45">
143
mygroup/myproject!45
144
</a>
145
```
146
147
### Custom Link Text (No Processing)
148
149
Links with custom text are left unchanged:
150
151
```rst
152
`Custom link text <https://github.com/pydata/pydata-sphinx-theme/issues/123>`_
153
```
154
155
Results in:
156
```html
157
<a class="reference external" href="https://github.com/pydata/pydata-sphinx-theme/issues/123">
158
Custom link text
159
</a>
160
```
161
162
### Platform Detection
163
164
```rst
165
Links to different platforms:
166
167
- https://github.com/user/repo → github class added
168
- https://gitlab.com/user/repo → gitlab class added
169
- https://bitbucket.org/user/repo → no processing (not supported)
170
```
171
172
## CSS Styling
173
174
The transform adds CSS classes for styling:
175
176
```css
177
/* Example custom styling */
178
a.github {
179
color: #24292f;
180
font-weight: 500;
181
}
182
183
a.github::before {
184
content: "🐙 ";
185
}
186
187
a.gitlab {
188
color: #fc6d26;
189
font-weight: 500;
190
}
191
192
a.gitlab::before {
193
content: "🦊 ";
194
}
195
196
/* Dark theme variants */
197
html[data-theme="dark"] a.github {
198
color: #f0f6fc;
199
}
200
201
html[data-theme="dark"] a.gitlab {
202
color: #fca326;
203
}
204
```
205
206
## Advanced Configuration
207
208
### Custom Platform Support
209
210
While the transform only supports GitHub and GitLab by default, you can extend it:
211
212
```python
213
# Custom extension (hypothetical)
214
from pydata_sphinx_theme.short_link import ShortenLinkTransform
215
216
class CustomShortenLinkTransform(ShortenLinkTransform):
217
supported_platform = {
218
"github.com": "github",
219
"gitlab.com": "gitlab",
220
"bitbucket.org": "bitbucket", # Add Bitbucket support
221
"codeberg.org": "codeberg", # Add Codeberg support
222
}
223
224
def parse_url(self, uri):
225
if self.platform == "bitbucket":
226
# Custom Bitbucket parsing logic
227
pass
228
elif self.platform == "codeberg":
229
# Custom Codeberg parsing logic
230
pass
231
else:
232
return super().parse_url(uri)
233
```
234
235
### Disable Link Processing
236
237
If you want to disable automatic link shortening:
238
239
```python
240
# conf.py - Remove the transform (advanced)
241
def setup(app):
242
# Remove the post-transform if already added
243
transforms = app.registry.get_post_transforms()
244
# Custom logic to remove ShortenLinkTransform
245
pass
246
```
247
248
## Integration with Other Extensions
249
250
The link processing works well with other Sphinx extensions:
251
252
### With `sphinx.ext.extlinks`
253
254
```python
255
# conf.py
256
extlinks = {
257
'gh': ('https://github.com/%s', 'GitHub: %s'),
258
'gl': ('https://gitlab.com/%s', 'GitLab: %s'),
259
}
260
```
261
262
```rst
263
Use :gh:`pydata/pydata-sphinx-theme/issues/123` for short links.
264
265
Or use the full URL https://github.com/pydata/pydata-sphinx-theme/issues/123 for automatic processing.
266
```
267
268
### With Link Checking
269
270
```python
271
# conf.py
272
extensions = [
273
'sphinx.ext.linkcheck',
274
# other extensions
275
]
276
277
# Link checking works normally with shortened links
278
linkcheck_ignore = [
279
r'https://github\.com/.*/issues/\d+', # Skip checking GitHub issues
280
]
281
```
282
283
## Technical Details
284
285
### Transform Priority
286
287
The transform runs with priority 400 in the post-transform phase, after most content processing but before final HTML generation.
288
289
### URL Parsing
290
291
The transform uses Python's `urllib.parse.urlparse()` for robust URL parsing and reconstruction.
292
293
### Node Processing
294
295
The transform uses the theme's compatibility function `traverse_or_findall()` to work with different docutils versions.
296
297
### Performance
298
299
- **Minimal overhead**: Only processes external reference nodes
300
- **Smart detection**: Only transforms links where display text matches URL
301
- **CSS classes**: Adds styling hooks without requiring JavaScript