Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/mdit_py_plugins/myst_role/index.py: 86%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

42 statements  

1from collections.abc import Sequence 

2import re 

3from typing import TYPE_CHECKING 

4 

5from markdown_it import MarkdownIt 

6from markdown_it.common.utils import escapeHtml 

7from markdown_it.rules_inline import StateInline 

8 

9if TYPE_CHECKING: 

10 from markdown_it.renderer import RendererProtocol 

11 from markdown_it.token import Token 

12 from markdown_it.utils import EnvType, OptionsDict 

13 

14VALID_NAME_PATTERN = re.compile(r"^\{([a-zA-Z0-9\_\-\+\:]+)\}") 

15 

16 

17def myst_role_plugin(md: MarkdownIt) -> None: 

18 """Parse ``{role-name}`content```""" 

19 md.inline.ruler.before("backticks", "myst_role", myst_role) 

20 md.add_render_rule("myst_role", render_myst_role) 

21 

22 

23def myst_role(state: StateInline, silent: bool) -> bool: 

24 # note ``\{`` escaping is handled by the core ``escape`` rule, 

25 # which runs before this rule 

26 

27 # check name 

28 match = VALID_NAME_PATTERN.match(state.src[state.pos :]) 

29 if not match: 

30 return False 

31 name = match.group(1) 

32 

33 # scan opening tick length 

34 start = pos = state.pos + match.end() 

35 try: 

36 while state.src[pos] == "`": 

37 pos += 1 

38 except IndexError: 

39 return False 

40 

41 tick_length = pos - start 

42 if not tick_length: 

43 return False 

44 

45 # search for closing ticks 

46 match = re.search("`" * tick_length, state.src[pos + 1 :]) 

47 if not match: 

48 return False 

49 content = state.src[pos : pos + match.start() + 1].replace("\n", " ") 

50 

51 if not silent: 

52 token = state.push("myst_role", "", 0) 

53 token.meta = {"name": name} 

54 token.content = content 

55 

56 state.pos = pos + match.end() + 1 

57 

58 return True 

59 

60 

61def render_myst_role( 

62 self: "RendererProtocol", 

63 tokens: Sequence["Token"], 

64 idx: int, 

65 options: "OptionsDict", 

66 env: "EnvType", 

67) -> str: 

68 token = tokens[idx] 

69 name = token.meta.get("name", "unknown") 

70 return f'<code class="myst role">{{{name}}}[{escapeHtml(token.content)}]</code>'