Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/markdown_it/utils.py: 63%

110 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:15 +0000

1from __future__ import annotations 

2 

3from collections.abc import MutableMapping as MutableMappingABC 

4from pathlib import Path 

5from typing import Any, Callable, Iterable, MutableMapping, TypedDict, cast 

6 

7EnvType = MutableMapping[str, Any] # note: could use TypeAlias in python 3.10 

8"""Type for the environment sandbox used in parsing and rendering, 

9which stores mutable variables for use by plugins and rules. 

10""" 

11 

12 

13class OptionsType(TypedDict): 

14 """Options for parsing.""" 

15 

16 maxNesting: int 

17 """Internal protection, recursion limit.""" 

18 html: bool 

19 """Enable HTML tags in source.""" 

20 linkify: bool 

21 """Enable autoconversion of URL-like texts to links.""" 

22 typographer: bool 

23 """Enable smartquotes and replacements.""" 

24 quotes: str 

25 """Quote characters.""" 

26 xhtmlOut: bool 

27 """Use '/' to close single tags (<br />).""" 

28 breaks: bool 

29 """Convert newlines in paragraphs into <br>.""" 

30 langPrefix: str 

31 """CSS language prefix for fenced blocks.""" 

32 highlight: Callable[[str, str, str], str] | None 

33 """Highlighter function: (content, lang, attrs) -> str.""" 

34 

35 

36class PresetType(TypedDict): 

37 """Preset configuration for markdown-it.""" 

38 

39 options: OptionsType 

40 """Options for parsing.""" 

41 components: MutableMapping[str, MutableMapping[str, list[str]]] 

42 """Components for parsing and rendering.""" 

43 

44 

45class OptionsDict(MutableMappingABC): # type: ignore 

46 """A dictionary, with attribute access to core markdownit configuration options.""" 

47 

48 # Note: ideally we would probably just remove attribute access entirely, 

49 # but we keep it for backwards compatibility. 

50 

51 def __init__(self, options: OptionsType) -> None: 

52 self._options = cast(OptionsType, dict(options)) 

53 

54 def __getitem__(self, key: str) -> Any: 

55 return self._options[key] # type: ignore[literal-required] 

56 

57 def __setitem__(self, key: str, value: Any) -> None: 

58 self._options[key] = value # type: ignore[literal-required] 

59 

60 def __delitem__(self, key: str) -> None: 

61 del self._options[key] # type: ignore 

62 

63 def __iter__(self) -> Iterable[str]: # type: ignore 

64 return iter(self._options) 

65 

66 def __len__(self) -> int: 

67 return len(self._options) 

68 

69 def __repr__(self) -> str: 

70 return repr(self._options) 

71 

72 def __str__(self) -> str: 

73 return str(self._options) 

74 

75 @property 

76 def maxNesting(self) -> int: 

77 """Internal protection, recursion limit.""" 

78 return self._options["maxNesting"] 

79 

80 @maxNesting.setter 

81 def maxNesting(self, value: int) -> None: 

82 self._options["maxNesting"] = value 

83 

84 @property 

85 def html(self) -> bool: 

86 """Enable HTML tags in source.""" 

87 return self._options["html"] 

88 

89 @html.setter 

90 def html(self, value: bool) -> None: 

91 self._options["html"] = value 

92 

93 @property 

94 def linkify(self) -> bool: 

95 """Enable autoconversion of URL-like texts to links.""" 

96 return self._options["linkify"] 

97 

98 @linkify.setter 

99 def linkify(self, value: bool) -> None: 

100 self._options["linkify"] = value 

101 

102 @property 

103 def typographer(self) -> bool: 

104 """Enable smartquotes and replacements.""" 

105 return self._options["typographer"] 

106 

107 @typographer.setter 

108 def typographer(self, value: bool) -> None: 

109 self._options["typographer"] = value 

110 

111 @property 

112 def quotes(self) -> str: 

113 """Quote characters.""" 

114 return self._options["quotes"] 

115 

116 @quotes.setter 

117 def quotes(self, value: str) -> None: 

118 self._options["quotes"] = value 

119 

120 @property 

121 def xhtmlOut(self) -> bool: 

122 """Use '/' to close single tags (<br />).""" 

123 return self._options["xhtmlOut"] 

124 

125 @xhtmlOut.setter 

126 def xhtmlOut(self, value: bool) -> None: 

127 self._options["xhtmlOut"] = value 

128 

129 @property 

130 def breaks(self) -> bool: 

131 """Convert newlines in paragraphs into <br>.""" 

132 return self._options["breaks"] 

133 

134 @breaks.setter 

135 def breaks(self, value: bool) -> None: 

136 self._options["breaks"] = value 

137 

138 @property 

139 def langPrefix(self) -> str: 

140 """CSS language prefix for fenced blocks.""" 

141 return self._options["langPrefix"] 

142 

143 @langPrefix.setter 

144 def langPrefix(self, value: str) -> None: 

145 self._options["langPrefix"] = value 

146 

147 @property 

148 def highlight(self) -> Callable[[str, str, str], str] | None: 

149 """Highlighter function: (content, langName, langAttrs) -> escaped HTML.""" 

150 return self._options["highlight"] 

151 

152 @highlight.setter 

153 def highlight(self, value: Callable[[str, str, str], str] | None) -> None: 

154 self._options["highlight"] = value 

155 

156 

157def read_fixture_file(path: str | Path) -> list[list[Any]]: 

158 text = Path(path).read_text(encoding="utf-8") 

159 tests = [] 

160 section = 0 

161 last_pos = 0 

162 lines = text.splitlines(keepends=True) 

163 for i in range(len(lines)): 

164 if lines[i].rstrip() == ".": 

165 if section == 0: 

166 tests.append([i, lines[i - 1].strip()]) 

167 section = 1 

168 elif section == 1: 

169 tests[-1].append("".join(lines[last_pos + 1 : i])) 

170 section = 2 

171 elif section == 2: 

172 tests[-1].append("".join(lines[last_pos + 1 : i])) 

173 section = 0 

174 

175 last_pos = i 

176 return tests