1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
import re
from ..util import unikey
from ..helpers import parse_link, parse_link_label
RUBY_PATTERN = r'\[(?:\w+\(\w+\))+\]'
_ruby_re = re.compile(RUBY_PATTERN)
def parse_ruby(inline, m, state):
text = m.group(0)[1:-2]
items = text.split(')')
tokens = []
for item in items:
rb, rt = item.split('(')
tokens.append({
'type': 'ruby',
'raw': rb,
'attrs': {'rt': rt}
})
end_pos = m.end()
next_match = _ruby_re.match(state.src, end_pos)
if next_match:
for tok in tokens:
state.append_token(tok)
return parse_ruby(inline, next_match, state)
# repeat link logic
if end_pos < len(state.src):
link_pos = _parse_ruby_link(inline, state, end_pos, tokens)
if link_pos:
return link_pos
for tok in tokens:
state.append_token(tok)
return end_pos
def _parse_ruby_link(inline, state, pos, tokens):
c = state.src[pos]
if c == '(':
# standard link [text](<url> "title")
attrs, link_pos = parse_link(state.src, pos + 1)
if link_pos:
state.append_token({
'type': 'link',
'children': tokens,
'attrs': attrs,
})
return link_pos
elif c == '[':
# standard ref link [text][label]
label, link_pos = parse_link_label(state.src, pos + 1)
if label and link_pos:
ref_links = state.env['ref_links']
key = unikey(label)
env = ref_links.get(key)
if env:
attrs = {'url': env['url'], 'title': env.get('title')}
state.append_token({
'type': 'link',
'children': tokens,
'attrs': attrs,
})
else:
for tok in tokens:
state.append_token(tok)
state.append_token({
'type': 'text',
'raw': '[' + label + ']',
})
return link_pos
def render_ruby(renderer, text, rt):
return '<ruby><rb>' + text + '</rb><rt>' + rt + '</rt></ruby>'
def ruby(md):
"""A mistune plugin to support ``<ruby>`` tag. The syntax is defined
at https://lepture.com/en/2022/markdown-ruby-markup:
.. code-block:: text
[漢字(ㄏㄢˋㄗˋ)]
[漢(ㄏㄢˋ)字(ㄗˋ)]
[漢字(ㄏㄢˋㄗˋ)][link]
[漢字(ㄏㄢˋㄗˋ)](/url "title")
[link]: /url "title"
:param md: Markdown instance
"""
md.inline.register('ruby', RUBY_PATTERN, parse_ruby, before='link')
if md.renderer and md.renderer.NAME == 'html':
md.renderer.register('ruby', render_ruby)
|