or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

code-syntax-extras.mdcore-conversion.mdindex.mdlink-reference-extras.mdprocessor-classes.mdspecial-content-extras.mdstructure-layout-extras.mdtext-processing-extras.md

link-reference-extras.mddocs/

0

# Link and Reference Extras

1

2

Extensions for advanced link processing, auto-linking, reference management, and URL handling that enhance markdown's linking capabilities.

3

4

## Capabilities

5

6

### Auto-Linking Patterns

7

8

Automatically convert text patterns to clickable links using regular expressions.

9

10

```python { .api }

11

# link-patterns extra - auto-link regex patterns

12

link_patterns = [

13

(compiled_regex, replacement_string_or_callable),

14

# More patterns...

15

]

16

extras = {"link-patterns": link_patterns}

17

```

18

19

**Usage Examples:**

20

21

```python

22

import markdown2

23

import re

24

25

# Auto-link issue numbers

26

issue_pattern = (

27

re.compile(r'issue #(\d+)'),

28

r'https://github.com/user/repo/issues/\1'

29

)

30

31

# Auto-link user mentions

32

user_pattern = (

33

re.compile(r'@(\w+)'),

34

lambda m: f'<a href="/users/{m.group(1)}">@{m.group(1)}</a>'

35

)

36

37

# Auto-link bug numbers

38

bug_pattern = (

39

re.compile(r'bug (\d+)'),

40

r'<a href="http://bugs.example.com/\1">bug \1</a>'

41

)

42

43

text = "See issue #123 and @john for bug 456 details"

44

html = markdown2.markdown(

45

text,

46

extras={"link-patterns": [issue_pattern, user_pattern, bug_pattern]}

47

)

48

```

49

50

### Reference Link Shortcuts

51

52

Simplified reference link syntax and shortcut handling.

53

54

```python { .api }

55

# link-shortrefs extra - allow shortcut reference links without []

56

extras = ["link-shortrefs"]

57

```

58

59

**Usage Examples:**

60

61

```python

62

import markdown2

63

64

markdown_text = '''

65

Visit [Google] or [Python].

66

67

[Google]: https://google.com

68

[Python]: https://python.org

69

'''

70

71

# Standard markdown requires [Google][] syntax

72

# With link-shortrefs, [Google] works directly

73

html = markdown2.markdown(markdown_text, extras=["link-shortrefs"])

74

```

75

76

### File Link Processing

77

78

Convert markdown file links to HTML file links automatically.

79

80

```python { .api }

81

# markdown-file-links extra - convert .md links to .html

82

extras = ["markdown-file-links"]

83

84

# With configuration options

85

extras = {

86

"markdown-file-links": {

87

"url_rewrite_func": custom_rewrite_function

88

}

89

}

90

```

91

92

**Usage Examples:**

93

94

```python

95

import markdown2

96

97

markdown_text = '''

98

See the [installation guide](install.md) and [API docs](api/reference.md) for details.

99

'''

100

101

html = markdown2.markdown(markdown_text, extras=["markdown-file-links"])

102

# Converts install.md -> install.html

103

# Converts api/reference.md -> api/reference.html

104

105

# Custom URL rewriting

106

def custom_rewrite(url):

107

if url.endswith('.md'):

108

return url.replace('.md', '.html')

109

return url

110

111

html = markdown2.markdown(

112

markdown_text,

113

extras={"markdown-file-links": {"url_rewrite_func": custom_rewrite}}

114

)

115

```

116

117

### SEO and Security Features

118

119

Add rel="nofollow" attribute to external links for SEO and security.

120

121

```python { .api }

122

# nofollow extra - add rel="nofollow" to <a> tags with href

123

extras = ["nofollow"]

124

```

125

126

**Usage Examples:**

127

128

```python

129

import markdown2

130

131

markdown_text = '''

132

Visit [our site](https://example.com) or [external site](https://external.com).

133

'''

134

135

html = markdown2.markdown(markdown_text, extras=["nofollow"])

136

# Adds rel="nofollow" to all links with href attributes

137

```

138

139

## Advanced Link Processing

140

141

### Custom Link Pattern Functions

142

143

Create sophisticated link processing with callable replacements:

144

145

```python

146

import markdown2

147

import re

148

149

def process_ticket_links(match):

150

"""Convert ticket references to full HTML links with metadata."""

151

ticket_id = match.group(1)

152

return f'''

153

<a href="/tickets/{ticket_id}"

154

class="ticket-link"

155

data-ticket-id="{ticket_id}"

156

title="View ticket #{ticket_id}">

157

Ticket #{ticket_id}

158

</a>

159

'''

160

161

def process_user_mentions(match):

162

"""Convert @username to user profile links."""

163

username = match.group(1)

164

return f'''

165

<a href="/users/{username}"

166

class="user-mention"

167

data-username="{username}">

168

@{username}

169

</a>

170

'''

171

172

patterns = [

173

(re.compile(r'ticket #(\d+)', re.IGNORECASE), process_ticket_links),

174

(re.compile(r'@([a-zA-Z0-9_]+)'), process_user_mentions),

175

]

176

177

text = "User @alice reported ticket #1234 yesterday."

178

html = markdown2.markdown(text, extras={"link-patterns": patterns})

179

```

180

181

### Combining Link Extras

182

183

Use multiple link extras together for comprehensive link processing:

184

185

```python

186

import markdown2

187

import re

188

189

# GitHub-style link processing

190

github_patterns = [

191

# Issue references: #123

192

(re.compile(r'#(\d+)'), r'https://github.com/owner/repo/issues/\1'),

193

194

# Pull request references: PR #123

195

(re.compile(r'PR #(\d+)'), r'https://github.com/owner/repo/pull/\1'),

196

197

# Commit references: abc1234

198

(re.compile(r'\b([a-f0-9]{7,40})\b'), r'https://github.com/owner/repo/commit/\1'),

199

200

# User mentions: @username

201

(re.compile(r'@([a-zA-Z0-9-]+)'), r'https://github.com/\1'),

202

]

203

204

markdown_text = '''

205

# Project Documentation

206

207

See the [setup guide](setup.md) for installation.

208

209

Bug reported by @john in #123, fixed in commit abc1234.

210

Also see PR #456 for related changes.

211

212

External reference: [Stack Overflow](https://stackoverflow.com)

213

'''

214

215

html = markdown2.markdown(

216

markdown_text,

217

extras={

218

"link-patterns": github_patterns,

219

"markdown-file-links": None,

220

"link-shortrefs": None,

221

"nofollow": None,

222

"header-ids": None

223

}

224

)

225

```

226

227

## Configuration Options

228

229

### Link Pattern Configuration

230

231

Link patterns are specified as tuples of `(pattern, replacement)`:

232

233

```python

234

import re

235

236

# String replacement with capture groups

237

pattern1 = (re.compile(r'bug (\d+)'), r'<a href="/bugs/\1">Bug \1</a>')

238

239

# Callable replacement for complex processing

240

def custom_replacer(match):

241

return f"<custom>{match.group(0)}</custom>"

242

243

pattern2 = (re.compile(r'CUSTOM-(\w+)'), custom_replacer)

244

245

# Multiple patterns

246

patterns = [pattern1, pattern2]

247

extras = {"link-patterns": patterns}

248

```

249

250

### File Link Rewriting

251

252

Customize how markdown file links are converted:

253

254

```python

255

def custom_md_rewriter(url):

256

"""Custom function to rewrite .md URLs."""

257

if url.endswith('.md'):

258

# Convert to .html and add version parameter

259

return url.replace('.md', '.html') + '?v=latest'

260

return url

261

262

extras = {

263

"markdown-file-links": {

264

"url_rewrite_func": custom_md_rewriter

265

}

266

}

267

```

268

269

## Integration Examples

270

271

### Documentation Site Processing

272

273

```python

274

import markdown2

275

import re

276

277

# Documentation site with cross-references

278

doc_patterns = [

279

# API references: {{api:function_name}}

280

(re.compile(r'\{\{api:([^}]+)\}\}'), r'<a href="/api/\1" class="api-link">\1</a>'),

281

282

# Tutorial references: {{tutorial:name}}

283

(re.compile(r'\{\{tutorial:([^}]+)\}\}'), r'<a href="/tutorials/\1" class="tutorial-link">\1</a>'),

284

285

# External docs: {{external:name}}

286

(re.compile(r'\{\{external:([^}]+)\}\}'), r'<a href="https://docs.example.com/\1" rel="nofollow">\1</a>'),

287

]

288

289

processor = markdown2.Markdown(

290

extras={

291

"link-patterns": doc_patterns,

292

"markdown-file-links": None,

293

"header-ids": None,

294

"toc": None,

295

"tables": None

296

}

297

)

298

299

documentation_html = processor.convert(doc_content)

300

```

301

302

### External Link Behavior

303

304

Control how external links are opened by adding target attributes automatically.

305

306

```python { .api }

307

# target-blank-links extra - add target="_blank" to external links

308

extras = ["target-blank-links"]

309

```

310

311

**Usage Examples:**

312

313

```python

314

import markdown2

315

316

content = '''

317

# Links Demo

318

319

[Internal link](./local-page.md)

320

[External link](https://example.com)

321

[Another external](https://github.com/user/repo)

322

'''

323

324

html = markdown2.markdown(content, extras=["target-blank-links"])

325

# External links get target="_blank" attribute automatically

326

# Internal/relative links remain unchanged

327

```

328

329

### Blog Processing with Auto-Links

330

331

```python

332

import markdown2

333

import re

334

335

# Blog-style auto-linking

336

blog_patterns = [

337

# Tag links: #tag

338

(re.compile(r'(?<!\w)#([a-zA-Z0-9_]+)'), r'<a href="/tags/\1" class="tag-link">#\1</a>'),

339

340

# Category links: [category:name]

341

(re.compile(r'\[category:([^]]+)\]'), r'<a href="/category/\1" class="category-link">\1</a>'),

342

]

343

344

blog_processor = markdown2.Markdown(

345

extras={

346

"link-patterns": blog_patterns,

347

"nofollow": None, # Add nofollow to external links

348

"smarty-pants": None, # Nice typography

349

"break-on-newline": None # GitHub-style line breaks

350

}

351

)

352

353

blog_html = blog_processor.convert(blog_post_content)

354

```