1
- import marko as md
1
+ from cfbs .pretty import pretty_file
2
+ import markdown_it
2
3
import os
3
4
import argparse
4
5
import sys
@@ -10,20 +11,25 @@ def extract_inline_code(file_path, languages):
10
11
with open (file_path , "r" ) as f :
11
12
content = f .read ()
12
13
13
- parser = md . parser . Parser ( )
14
- ast = parser .parse (content )
14
+ md = markdown_it . MarkdownIt ( "commonmark" )
15
+ ast = md .parse (content )
15
16
16
- for child in ast . children :
17
+ for child in ast :
17
18
18
- if not isinstance ( child , md . block . FencedCode ) :
19
+ if child . type != "fence" :
19
20
continue
20
21
21
- info_string = child .lang .split ("|" )
22
+ info_string = child .info .split ()
22
23
language = info_string [0 ]
23
24
flags = info_string [1 :]
24
25
25
26
if language in languages :
26
- yield language , child .children [0 ].children , flags
27
+ yield {
28
+ "language" : language ,
29
+ "flags" : flags ,
30
+ "first_line" : child .map [0 ],
31
+ "last_line" : child .map [1 ],
32
+ }
27
33
28
34
29
35
ignored_dirs = [".git" ]
@@ -33,21 +39,33 @@ def get_markdown_files(start, languages):
33
39
"""locate all markdown files and call extract_inline_code on them"""
34
40
35
41
if os .path .isfile (start ):
36
- return {start : list (extract_inline_code (start , languages ))}
42
+ return {
43
+ "files" : {
44
+ start : {"code-blocks" : list (extract_inline_code (start , languages ))}
45
+ }
46
+ }
37
47
38
- return_dict = {}
48
+ return_dict = {"files" : {} }
39
49
for root , dirs , files in os .walk (start ):
40
50
dirs [:] = [d for d in dirs if d not in ignored_dirs ]
41
51
42
52
for f in files :
43
53
if f .endswith (".markdown" ) or f .endswith (".md" ):
44
54
path = os .path .join (root , f )
45
- return_dict [path ] = list (extract_inline_code (path , languages ))
55
+ return_dict ["files" ][path ] = {
56
+ "code-blocks" : list (extract_inline_code (path , languages ))
57
+ }
46
58
47
59
return return_dict
48
60
49
61
50
- def extract (path , i , language , code_snippet ):
62
+ def extract (path , i , language , first_line , last_line ):
63
+
64
+ with open (path , "r" ) as f :
65
+ content = f .read ()
66
+
67
+ code_snippet = "\n " .join (content .split ("\n " )[first_line + 1 : last_line - 1 ])
68
+
51
69
with open (f"{ path } .snippet-{ i } .{ language } " , "w" ) as f :
52
70
f .write (code_snippet )
53
71
@@ -64,8 +82,30 @@ def replace():
64
82
pass
65
83
66
84
67
- def autoformat ():
68
- pass
85
+ def autoformat (path , i , language , first_line , last_line ):
86
+
87
+ match language :
88
+ case "json" :
89
+ file_name = f"{ path } .snippet-{ i } .{ language } "
90
+
91
+ try :
92
+ pretty_file (file_name )
93
+ with open (file_name , "r" ) as f :
94
+ pretty_content = f .read ()
95
+ except :
96
+ print (
97
+ f"[error] Couldn't find the file '{ file_name } '. Run --extract to extract the inline code."
98
+ )
99
+ return
100
+
101
+ with open (path , "r" ) as f :
102
+ origin_content = f .read ()
103
+
104
+ lines = origin_content .split ("\n " )
105
+ lines [first_line + 1 : last_line - 1 ] = pretty_content .split ("\n " )
106
+
107
+ with open (path , "w" ) as f :
108
+ f .write ("\n " .join (lines ))
69
109
70
110
71
111
def parse_args ():
@@ -74,11 +114,10 @@ def parse_args():
74
114
description = "Tool for checking the syntax, the format and the output of markdown inline code" ,
75
115
)
76
116
parser .add_argument (
77
- "--path" ,
78
- "-p" ,
117
+ "path" ,
79
118
help = "path of file or directory to check syntax on" ,
119
+ nargs = "?" ,
80
120
default = "." ,
81
- required = False ,
82
121
)
83
122
parser .add_argument (
84
123
"--languages" ,
@@ -137,22 +176,34 @@ def parse_args():
137
176
)
138
177
sys .exit (- 1 )
139
178
140
- parsed_markdown = get_markdown_files (args .path , args .languages )
179
+ parsed_markdowns = get_markdown_files (args .path , args .languages )
141
180
142
- for path , inline_code_list in parsed_markdown . items ():
143
- for i , ( language , code_snippet , flags ) in enumerate (inline_code_list ):
181
+ for path in parsed_markdowns [ "files" ]. keys ():
182
+ for i , code_block in enumerate (parsed_markdowns [ "files" ][ path ][ "code-blocks" ] ):
144
183
145
- if args .extract and "noextract" not in flags :
146
- extract (path , i + 1 , supported_languages [language ], code_snippet )
184
+ if args .extract and "noextract" not in code_block ["flags" ]:
185
+ extract (
186
+ path ,
187
+ i + 1 ,
188
+ supported_languages [code_block ["language" ]],
189
+ code_block ["first_line" ],
190
+ code_block ["last_line" ],
191
+ )
147
192
148
- if args .syntax_check and "novalidate" not in flags :
193
+ if args .syntax_check and "novalidate" not in code_block [ " flags" ] :
149
194
check_syntax ()
150
195
151
- if args .autoformat and "noautoformat" not in flags :
152
- autoformat ()
196
+ if args .autoformat and "noautoformat" not in code_block ["flags" ]:
197
+ autoformat (
198
+ path ,
199
+ i + 1 ,
200
+ supported_languages [code_block ["language" ]],
201
+ code_block ["first_line" ],
202
+ code_block ["last_line" ],
203
+ )
153
204
154
- if args .replace and "noreplace" not in flags :
205
+ if args .replace and "noreplace" not in code_block [ " flags" ] :
155
206
replace ()
156
207
157
- if args .output_check and "noexecute" not in flags :
208
+ if args .output_check and "noexecute" not in code_block [ " flags" ] :
158
209
check_output ()
0 commit comments