Coverage for src/markdown_include_variants/_main.py: 100%
231 statements
« prev ^ index » next coverage.py v7.6.1, created at 2026-10-15 15:22 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2026-10-15 15:22 +0000
1import re 2pbqb
2from dataclasses import dataclass 2pbqb
3from pathlib import Path 2pbqb
4from typing import Any, Literal, Union 2pbqb
6from markdown import Extension, Markdown 2pbqb
7from markdown.preprocessors import Preprocessor 2pbqb
9AN = "_an" 2pbqb
10PY39 = "_py39" 2pbqb
11PY310 = "_py310" 2pbqb
12PY311 = "_py311" 2pbqb
14SUFFIXES_TO_REMOVE = ["_an", "_py39", "_py310", "_py311"] 2pbqb
17@dataclass(frozen=True) 2pbqb
18class Variant: 2pbqb
19 path: Path 2pbqb
20 title: str 2pbqb
21 is_annotated: Union[bool, None] 2pbqb
22 version: Literal["py38", "py39", "py310", "py311"] 2pbqb
25def remove_suffixes(base_name: str, suffixes: list[str]) -> str: 2pbqb
26 for suffix in suffixes: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
27 if base_name.endswith(suffix): 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
28 base_name = base_name[: -len(suffix)] 2i j e f [ a b G ] fblb` jbC gbk l g h ^ c d H _ hbmb{ kbD ib
29 return remove_suffixes(base_name, suffixes) 2i j e f [ a b G ] fblb` jbC gbk l g h ^ c d H _ hbmb{ kbD ib
30 return base_name 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
33def calculate_variants(base_path: Path) -> dict[tuple[str, Union[bool, None]], Variant]: 2pbqb
34 preferred_name = base_path.stem 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
35 base_name = remove_suffixes(preferred_name, SUFFIXES_TO_REMOVE) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
36 base_dir = base_path.parent 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
38 an_p311_path = base_dir / f"{base_name}{AN}{PY311}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
39 an_p310_path = base_dir / f"{base_name}{AN}{PY310}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
40 an_p39_path = base_dir / f"{base_name}{AN}{PY39}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
41 an_p38_path = base_dir / f"{base_name}{AN}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
42 p311_path = base_dir / f"{base_name}{PY311}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
43 p310_path = base_dir / f"{base_name}{PY310}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
44 p39_path = base_dir / f"{base_name}{PY39}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
45 p38_path = base_dir / f"{base_name}.py" 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
47 return _create_variants( 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
48 an_p311_path=an_p311_path,
49 an_p310_path=an_p310_path,
50 an_p39_path=an_p39_path,
51 an_p38_path=an_p38_path,
52 p311_path=p311_path,
53 p310_path=p310_path,
54 p39_path=p39_path,
55 p38_path=p38_path,
56 )
59def calculate_variants_folder( 2pbqb
60 base_path: Path,
61) -> dict[tuple[str, Union[bool, None]], Variant]:
62 file_name = base_path.name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
63 folder = base_path.parent 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
64 base_dir = folder.parent 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
65 base_name = remove_suffixes(folder.name, SUFFIXES_TO_REMOVE) 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
67 an_p311_path = base_dir / f"{base_name}{AN}{PY311}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
68 an_p310_path = base_dir / f"{base_name}{AN}{PY310}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
69 an_p39_path = base_dir / f"{base_name}{AN}{PY39}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
70 an_p38_path = base_dir / f"{base_name}{AN}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
71 p311_path = base_dir / f"{base_name}{PY311}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
72 p310_path = base_dir / f"{base_name}{PY310}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
73 p39_path = base_dir / f"{base_name}{PY39}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
74 p38_path = base_dir / f"{base_name}" / file_name 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
76 return _create_variants( 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
77 an_p311_path=an_p311_path,
78 an_p310_path=an_p310_path,
79 an_p39_path=an_p39_path,
80 an_p38_path=an_p38_path,
81 p311_path=p311_path,
82 p310_path=p310_path,
83 p39_path=p39_path,
84 p38_path=p38_path,
85 )
88def _create_variants( 2pbqb
89 an_p311_path: Path,
90 an_p310_path: Path,
91 an_p39_path: Path,
92 an_p38_path: Path,
93 p311_path: Path,
94 p310_path: Path,
95 p39_path: Path,
96 p38_path: Path,
97) -> dict[tuple[str, Union[bool, None]], Variant]:
98 variants: dict[tuple[str, Union[bool, None]], Variant] = {} 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
99 if an_p311_path.exists(): 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
100 v = Variant( 1ijef[abG]klgh^cdH_
101 path=an_p311_path,
102 title="Python 3.11+",
103 is_annotated=True,
104 version="py311",
105 )
106 variants[(v.version, v.is_annotated)] = v 1ijef[abG]klgh^cdH_
107 if p311_path.exists(): 1ijef[abG]klgh^cdH_
108 v = Variant( 1ijef[abG]klgh^cdH_
109 path=p311_path,
110 title="Python 3.11+ - non-Annotated",
111 is_annotated=False,
112 version="py311",
113 )
114 variants[(v.version, v.is_annotated)] = v 1ijef[abG]klgh^cdH_
115 elif p311_path.exists(): 2a b G fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbc d H hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
116 v = Variant( 2jbkb
117 path=p311_path,
118 title="Python 3.11+",
119 is_annotated=None,
120 version="py311",
121 )
122 variants[(v.version, v.is_annotated)] = v 2jbkb
123 if an_p310_path.exists(): 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
124 v = Variant( 2i j e f [ a b G ] fblbk l g h ^ c d H _ hbmb
125 path=an_p310_path,
126 title="Python 3.10+",
127 is_annotated=True,
128 version="py310",
129 )
130 variants[(v.version, v.is_annotated)] = v 2i j e f [ a b G ] fblbk l g h ^ c d H _ hbmb
131 if p310_path.exists(): 2i j e f [ a b G ] fblbk l g h ^ c d H _ hbmb
132 v = Variant( 2i j e f [ a b G ] fblbk l g h ^ c d H _ hbmb
133 path=p310_path,
134 title="Python 3.10+ - non-Annotated",
135 is_annotated=False,
136 version="py310",
137 )
138 variants[(v.version, v.is_annotated)] = v 2i j e f [ a b G ] fblbk l g h ^ c d H _ hbmb
139 elif p310_path.exists(): 2a b G / ` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbc d H : { kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
140 v = Variant( 2` jb{ kb
141 path=p310_path,
142 title="Python 3.10+",
143 is_annotated=None,
144 version="py310",
145 )
146 variants[(v.version, v.is_annotated)] = v 2` jb{ kb
147 if an_p39_path.exists(): 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
148 v = Variant( 2i j e f [ a b G ] C gbk l g h ^ c d H _ D ib
149 path=an_p39_path,
150 title="Python 3.9+",
151 is_annotated=True,
152 version="py39",
153 )
154 variants[(v.version, v.is_annotated)] = v 2i j e f [ a b G ] C gbk l g h ^ c d H _ D ib
155 if p39_path.exists(): 2i j e f [ a b G ] C gbk l g h ^ c d H _ D ib
156 v = Variant( 2i j e f [ a b G ] C gbk l g h ^ c d H _ D ib
157 path=p39_path,
158 title="Python 3.9+ - non-Annotated",
159 is_annotated=False,
160 version="py39",
161 )
162 variants[(v.version, v.is_annotated)] = v 2i j e f [ a b G ] C gbk l g h ^ c d H _ D ib
163 elif p39_path.exists(): 2a b G fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = c d H hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @
164 v = Variant( 2jbkb
165 path=p39_path,
166 title="Python 3.9+",
167 is_annotated=None,
168 version="py39",
169 )
170 variants[(v.version, v.is_annotated)] = v 2jbkb
171 if an_p38_path.exists(): 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
172 v = Variant( 2i j e f [ a b G ] fbC gbk l g h ^ c d H _ hbD ib
173 path=an_p38_path,
174 title="Python 3.8+",
175 is_annotated=True,
176 version="py38",
177 )
178 variants[(v.version, v.is_annotated)] = v 2i j e f [ a b G ] fbC gbk l g h ^ c d H _ hbD ib
179 if p38_path.exists(): 2i j e f [ a b G ] fbC gbk l g h ^ c d H _ hbD ib
180 v = Variant( 2i j e f [ a b G ] fbC gbk l g h ^ c d H _ hbD ib
181 path=p38_path,
182 title="Python 3.8+ - non-Annotated",
183 is_annotated=False,
184 version="py38",
185 )
186 variants[(v.version, v.is_annotated)] = v 2i j e f [ a b G ] fbC gbk l g h ^ c d H _ hbD ib
187 elif p38_path.exists(): 2a b G / lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = c d H : mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @
188 v = Variant( 2a b G / ` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
189 path=p38_path,
190 title="Python 3.8+",
191 is_annotated=None,
192 version="py38",
193 )
194 variants[(v.version, v.is_annotated)] = v 2a b G / ` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
195 return variants 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
198def parse_lines_index(include_lines_config: str) -> list[tuple[int, int]]: 2pbqb
199 lines = [] 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoumCklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypznD
200 for line in include_lines_config.strip().split(","): 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoumCklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypznD
201 clean_line = line.strip() 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoumCklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypznD
202 if ":" in clean_line: 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoumCklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypznD
203 start, end = clean_line.split(":") 1ijefab'(STIUJVKLXEqArstoumCklghcd)*Z0N1O2PQ4FvBwxypznD
204 lines.append((int(start), int(end))) 1ijefab'(STIUJVKLXEqArstoumCklghcd)*Z0N1O2PQ4FvBwxypznD
205 else:
206 lines.append((int(line), int(line))) 1/+S,KWL6M7Y89qom:-Z.P3Q!R#5$%vpn
207 lines.sort() 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoumCklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypznD
208 return lines 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoumCklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypznD
211@dataclass 2pbqb
212class IncludeInfo: 2pbqb
213 start: int 2pbqb
214 end: int 2pbqb
215 offset: int 2pbqb
216 hl_lines: list[tuple[int, int]] 2pbqb
218 def computed_hl_lines(self) -> list[tuple[int, int]]: 2pbqb
219 return [ 1ijefabEqArstoumCklghcdFvBwxypznD
220 (
221 hl_line[0] - self.start + self.offset + 1,
222 hl_line[1] - self.start + self.offset + 1,
223 )
224 for hl_line in self.hl_lines
225 ]
228def calculate_includes( 2pbqb
229 lines_to_include: list[tuple[int, int]], hl_lines: list[tuple[int, int]]
230) -> dict[tuple[int, int], IncludeInfo]:
231 lines_groups: dict[tuple[int, int], IncludeInfo] = {} 1ijefabEqArstoumCklghcdFvBwxypznD
232 offset = 0 1ijefabEqArstoumCklghcdFvBwxypznD
233 for i, line_group in enumerate(lines_to_include): 1ijefabEqArstoumCklghcdFvBwxypznD
234 if line_group[0] > 1: 1ijefabEqArstoumCklghcdFvBwxypznD
235 if i == 0: 1ijefabqArstoumCklghcdvBwxypznD
236 offset = 2 1ijefabArstoumCklghcdBwxypznD
237 else:
238 offset += 3 1qrstoumvwxypzn
239 info = IncludeInfo( 1ijefabEqArstoumCklghcdFvBwxypznD
240 start=line_group[0],
241 end=line_group[1],
242 offset=offset,
243 hl_lines=[],
244 )
245 offset += line_group[1] - line_group[0] + 1 1ijefabEqArstoumCklghcdFvBwxypznD
246 for hl_line in hl_lines: 1ijefabEqArstoumCklghcdFvBwxypznD
247 if hl_line[0] >= line_group[0] and hl_line[1] <= line_group[1]: 1ijefabEqArstoumCklghcdFvBwxypznD
248 info.hl_lines.append(hl_line) 1ijefabEqArstoumCklghcdFvBwxypznD
249 lines_groups[line_group] = info 1ijefabEqArstoumCklghcdFvBwxypznD
250 return lines_groups 1ijefabEqArstoumCklghcdFvBwxypznD
253def generate_hl_string(hl_lines: list[tuple[int, int]]) -> str: 2pbqb
254 hl_lines_strs: list[str] = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
255 for hl_line in hl_lines: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
256 if hl_line[0] == hl_line[1]: 1ijefab'(+S,EqArstoumCklghcd)*-Z.FvBwxypznD
257 hl_lines_strs.append(str(hl_line[0])) 1+S,qom-Z.vpn
258 else:
259 hl_lines_strs.append(f"{hl_line[0]}-{hl_line[1]}") 1ijefab'(SEqArstumCklghcd)*ZFvBwxyznD
260 return " ".join(hl_lines_strs) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
263re_line = r"^\{\*\s*(\S+)\s*(.*)\*\}$" 2pbqb
264re_config = r"(\w+)\[([^\]]+)\]" 2pbqb
267class IncludeVariantsPreprocessor(Preprocessor): 2pbqb
268 def run(self, lines: list[str]) -> list[str]: 2pbqb
269 new_lines = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ rbnbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbsbobeb? @ D ib
270 for line in lines: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ rbnbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbsbobeb? @ D ib
271 line_match = re.match(re_line, line) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ rbnbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbsbobeb? @ D ib
272 if not line_match: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ rbnbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbsbobeb? @ D ib
273 new_lines.append(line) 2rbsb
274 continue 2rbsb
275 block_lines = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
276 src_file_str = line_match.group(1) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
277 base_path = Path(src_file_str) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
279 configs_str = line_match.group(2).strip() 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
280 include_lines: list[tuple[int, int]] = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
281 highlight_lines: list[tuple[int, int]] = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
282 title: Union[str, None] = None 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
283 for config_match in re.finditer(re_config, configs_str): 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
284 if config_match: 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoum;=Cklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypzn?@D
285 name = config_match.group(1) 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoum;=Cklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypzn?@D
286 value_str = config_match.group(2) 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoum;=Cklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypzn?@D
287 if name == "ln": 1ijefab/'(+S,TIUJVKWL6XM7Y89EqArstoum;=Cklghcd:)*-Z.0N1O2P3Q!4R#5$%FvBwxypzn?@D
288 include_lines.extend(parse_lines_index(value_str)) 1ijefab/TIUJVKWL6XM7Y89EqArstoumCklghcd:0N1O2P3Q!4R#5$%FvBwxypznD
289 elif name == "hl": 1ijefab'(+S,EqArstoum;=Cklghcd)*-Z.FvBwxypzn?@D
290 highlight_lines.extend(parse_lines_index(value_str)) 1ijefab'(+S,EqArstoumCklghcd)*-Z.FvBwxypznD
291 elif name == "title": 1ef;=gh?@
292 assert value_str.startswith('"') and value_str.endswith('"') 1ef;=gh?@
293 title = value_str[1:-1] 1ef;=gh?@
294 use_hl_lines: list[tuple[int, int]] = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
295 if highlight_lines: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
296 if include_lines: 1ijefab'(+S,EqArstoumCklghcd)*-Z.FvBwxypznD
297 include_infos = calculate_includes(include_lines, highlight_lines) 1ijefabEqArstoumCklghcdFvBwxypznD
298 for info in include_infos.values(): 1ijefabEqArstoumCklghcdFvBwxypznD
299 use_hl_lines.extend(info.computed_hl_lines()) 1ijefabEqArstoumCklghcdFvBwxypznD
300 else:
301 use_hl_lines = highlight_lines 1'(+S,)*-Z.
302 use_hl_lines_str = generate_hl_string(use_hl_lines) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
304 variants = calculate_variants(base_path) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
305 if len(variants) == 0: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ nbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbobeb? @ D ib
306 raise FileNotFoundError(f"Could not find any variants for {base_path}") 2nbob
307 if len(variants) == 1: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
308 folder_variants = calculate_variants_folder(base_path) 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
309 if len(folder_variants) > 1: 2a b G / ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = c d H : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
310 variants = folder_variants 1abGcdH
311 elif len(folder_variants) == 1: 2/ ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
312 file_variant_is_default = variants.get(("py38", None)) is not None 2/ ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
313 folder_variant_is_default = ( 2/ ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
314 folder_variants.get(("py38", None)) is not None
315 )
316 # File name doesn't contain any suffixes, but folder does - use variants from folder
317 if file_variant_is_default and not folder_variant_is_default: 2/ ` ' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = : { ) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @
318 variants = folder_variants 1`{
319 sorted_variants: list[Variant] = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
320 preferred_variant = None 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
321 for an in [True, False, None]: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
322 for version in ["py311", "py310", "py39", "py38"]: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
323 v = variants.get((version, an)) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
324 if v: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
325 if v.path == base_path: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
326 assert preferred_variant is None 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
327 preferred_variant = v 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
328 else:
329 sorted_variants.append(v) 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
330 assert preferred_variant is not None 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
331 content_lines = preferred_variant.path.read_text().splitlines() 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
333 internal_block_lines: list[str] = [] 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
334 if not include_lines: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
335 internal_block_lines.append( 2[ G ] fblb` jb' ( + S , | } ~ ab; = gb^ H _ hbmb{ kb) * - Z . bbcbdbeb? @ ib
336 f"{{!{preferred_variant.path}!}}",
337 )
338 if include_lines != [(0, 0)]: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
339 for i, line_group in enumerate(include_lines): 2i j e f [ a b G ] fblb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hbmb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
340 if i == 0 and line_group[0] > 1: 1ijefabTIUJVKWL6XM7Y89EqArstoumCklghcd0N1O2P3Q!4R#5$%FvBwxypznD
341 internal_block_lines.extend( 1ijefabIUMY9ArstoumCklghcdN1R5%BwxypznD
342 [
343 "# Code above omitted 👆",
344 "",
345 ]
346 )
347 if i >= 1: 1ijefabTIUJVKWL6XM7Y89EqArstoumCklghcd0N1O2P3Q!4R#5$%FvBwxypznD
348 internal_block_lines.extend( 1JVKWL6MqrstoumO2P3Q!Rvwxypzn
349 [
350 "",
351 "# Code here omitted 👈",
352 "",
353 ]
354 )
355 internal_block_lines.append( 1ijefabTIUJVKWL6XM7Y89EqArstoumCklghcd0N1O2P3Q!4R#5$%FvBwxypznD
356 f"{{!{preferred_variant.path}[ln:{line_group[0]}-{line_group[1]}]!}}"
357 )
358 if i == len(include_lines) - 1 and line_group[1] < len( 1ijefabTIUJVKWL6XM7Y89EqArstoumCklghcd0N1O2P3Q!4R#5$%FvBwxypznD
359 content_lines
360 ):
361 internal_block_lines.extend( 1ijefabTIJWXM7Y8EACklghcd0NO34R#5$FBD
362 [
363 "",
364 "# Code below omitted 👇",
365 ]
366 )
367 first_line = "```python" 2i j e f [ a b G ] fblb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hbmb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
368 if use_hl_lines: 2i j e f [ a b G ] fblb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hbmb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
369 first_line += f' hl_lines="{use_hl_lines_str}"' 1ijefab'(+S,EqArstoumCklghcd)*-Z.FvBwxypznD
370 if title: 2i j e f [ a b G ] fblb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hbmb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
371 first_line += f' title="{title}"' 1ef;=gh?@
373 block_lines.extend( 2i j e f [ a b G ] fblb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hbmb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
374 [
375 f"//// tab | {preferred_variant.title}",
376 first_line,
377 *internal_block_lines,
378 "```",
379 "",
380 "////",
381 "",
382 ]
383 )
384 if include_lines: 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
385 first_line_full = "```python" 1ijefab/TIUJVKWL6XM7Y89EqArstoumCklghcd:0N1O2P3Q!4R#5$%FvBwxypznD
386 if highlight_lines: 1ijefab/TIUJVKWL6XM7Y89EqArstoumCklghcd:0N1O2P3Q!4R#5$%FvBwxypznD
387 hl_lines_full_str = generate_hl_string(highlight_lines) 1ijefabEqArstoumCklghcdFvBwxypznD
388 first_line_full += f' hl_lines="{hl_lines_full_str}"' 1ijefabEqArstoumCklghcdFvBwxypznD
389 if title: 1ijefab/TIUJVKWL6XM7Y89EqArstoumCklghcd:0N1O2P3Q!4R#5$%FvBwxypznD
390 first_line_full += f' title="{title}"' 1efgh
391 block_lines.extend( 1ijefab/TIUJVKWL6XM7Y89EqArstoumCklghcd:0N1O2P3Q!4R#5$%FvBwxypznD
392 [
393 "///// details | 👀 Full file preview",
394 "",
395 f"//// tab | {preferred_variant.title}",
396 "",
397 first_line_full,
398 f"{{!{preferred_variant.path}!}}",
399 "```",
400 "",
401 "////",
402 "",
403 "/////",
404 "",
405 ]
406 )
407 if len(sorted_variants): 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
408 first_line_variant = "```python" 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
409 if title: 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
410 first_line_variant += f' title="{title}"' 1efgh
411 block_lines.extend( 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
412 [
413 "///// details | 🤓 Other versions and variants",
414 "",
415 ]
416 )
418 for variant in sorted_variants: 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
419 block_lines.extend([f"//// tab | {variant.title}", ""]) 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
420 if variant.is_annotated is False: 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
421 block_lines.extend( 2i j e f [ a b G ] fblbC gbk l g h ^ c d H _ hbmbD ib
422 [
423 "/// tip",
424 "",
425 "Prefer to use the `Annotated` version if possible.",
426 "",
427 "///",
428 "",
429 ]
430 )
432 block_lines.extend( 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
433 [
434 first_line_variant,
435 f"{{!{variant.path}!}}",
436 "```",
437 "////",
438 ]
439 )
441 block_lines.extend( 2i j e f [ a b G ] fblbjbC gbk l g h ^ c d H _ hbmbkbD ib
442 [
443 "",
444 "/////",
445 "",
446 ]
447 )
448 new_lines.extend(block_lines) 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ ab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbeb? @ D ib
449 return new_lines 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ rbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbsbeb? @ D ib
452class IncludeVariantsExtension(Extension): 2pbqb
453 def extendMarkdown(self, md: Markdown) -> None: 2pbqb
454 md.preprocessors.register( 2i j e f [ a b G ] fb/ lb` jb' ( + S , T I U J V K W L 6 X M 7 Y 8 9 E q A r s t o u m | } ~ rbnbab; = C gbk l g h ^ c d H _ hb: mb{ kb) * - Z . 0 N 1 O 2 P 3 Q ! 4 R # 5 $ % F v B w x y p z n bbcbdbsbobeb? @ D ib
455 IncludeVariantsPreprocessor(md), "include_variants", 110
456 )
459def makeExtension( 2pbqb
460 *args: Any, **kwargs: Any 2pbqb
461) -> IncludeVariantsExtension: # pragma: no cover 2pbqb
462 return IncludeVariantsExtension(*args, **kwargs)