2222SpacesBeforeTrailingComments: 2
2323"""
2424CLANG_FORMAT_STYLE = (
25- "{" + ", " .join (filter (lambda x : x != "" , CLANG_FORMAT_STYLE .split ("\n " ))) + "}"
25+ "{" + ", " .join (filter (lambda x : x != "" , CLANG_FORMAT_STYLE .split ("\n " ))) + "}"
2626)
2727
2828
2929def lead_white (line ):
30- return len (line ) - len (line .lstrip ())
30+ return len (line ) - len (line .lstrip ())
3131
3232
3333def match_indentation (line , prog_line ):
34- return prog_line [min (lead_white (line ), lead_white (prog_line )) :]
34+ return prog_line [min (lead_white (line ), lead_white (prog_line )) :]
3535
3636
3737def contains_banned_terms (prog : List [str ]):
38- banned = ["while (???)" ] # "CodeSnip",
39- return any (ban in prog_line for ban in banned for prog_line in prog )
38+ banned = ["while (???)" ] # "CodeSnip",
39+ return any (ban in prog_line for ban in banned for prog_line in prog )
4040
4141
4242def format_prog_py (prog : List [str ]):
43- try :
44- prog = black .format_file_contents (
45- "" .join (prog ), fast = True , mode = black .FileMode ()
46- ).splitlines (True )
47- except black .report .NothingChanged :
48- pass
49- return prog
43+ try :
44+ prog = black .format_file_contents (
45+ "" .join (prog ), fast = True , mode = black .FileMode ()
46+ ).splitlines (True )
47+ except black .report .NothingChanged :
48+ pass
49+ return prog
5050
5151
5252def format_prog_clang (lang : str , prog : List [str ]):
53- tmp_file = tempfile .NamedTemporaryFile (suffix = f".{ lang } " )
54- with open (tmp_file .name , "w" ) as f :
55- f .write ("" .join (prog ))
56- subprocess .check_output (
57- [f"clang-format -i -style='{ CLANG_FORMAT_STYLE } ' { f .name } " ],
58- shell = True ,
59- )
60- with open (tmp_file .name , "r" ) as f :
61- return f .readlines ()
53+ fd , tmp_path = tempfile .mkstemp (suffix = f".{ lang } " )
54+ try :
55+ os .close (fd ) # Must close before reopening on Windows
56+ with open (tmp_path , "w" , encoding = "utf-8" ) as f :
57+ f .write ("" .join (prog ))
58+ subprocess .check_output (
59+ ["clang-format" , "-i" , f"-style={ CLANG_FORMAT_STYLE } " , tmp_path ],
60+ )
61+ with open (tmp_path , "r" , encoding = "utf-8" ) as f :
62+ return f .readlines ()
63+ finally :
64+ try :
65+ os .unlink (tmp_path )
66+ except OSError :
67+ pass
6268
6369
6470def format_prog (lang : str , prog : List [str ]):
65- if lang == "py" :
66- return format_prog_py (prog )
67- else :
68- assert lang in ["cpp" , "java" ]
69- return format_prog_clang (lang , prog )
71+ if lang == "py" :
72+ return format_prog_py (prog )
73+ else :
74+ assert lang in ["cpp" , "java" ]
75+ return format_prog_clang (lang , prog )
7076
7177
7278def denotes_lang (line : str ):
73- line = line .strip ()
74- return (
75- line .startswith ("```" )
76- and len (line ) > 3
77- and line .count ("`" ) != len (line )
78- and "sh" not in line
79- )
79+ line = line .strip ()
80+ return (
81+ line .startswith ("```" )
82+ and len (line ) > 3
83+ and line .count ("`" ) != len (line )
84+ and "sh" not in line
85+ )
8086
8187
8288def comment_for_lang (lang : str ):
83- if lang in ["cpp" , "java" ]:
84- return "//"
85- else :
86- assert lang in ["py" ]
87- return "#"
89+ if lang in ["cpp" , "java" ]:
90+ return "//"
91+ else :
92+ assert lang in ["py" ]
93+ return "#"
8894
8995
9096def comment_codesnip (lang : str , line : str ):
91- line_stripped = line .lstrip ()
92- cs = "CodeSnip"
93- if any (line_stripped .startswith (word ) for word in [cs , "Begin" + cs , "End" + cs ]):
94- return (
95- line [: len (line ) - len (line_stripped )]
96- + comment_for_lang (lang )
97- + " "
98- + line_stripped
99- )
100- else :
101- return line
97+ line_stripped = line .lstrip ()
98+ cs = "CodeSnip"
99+ if any (line_stripped .startswith (word ) for word in [cs , "Begin" + cs , "End" + cs ]):
100+ return (
101+ line [: len (line ) - len (line_stripped )]
102+ + comment_for_lang (lang )
103+ + " "
104+ + line_stripped
105+ )
106+ else :
107+ return line
102108
103109
104110def format_path (path : str ):
105- # print("formatting", path)
106- with open (path , "r" ) as f :
107- lines = f .readlines ()
108- lang = None
109- nlines = []
110- prog = []
111- for line in lines :
112- if denotes_lang (line ): # start of lang block
113- lang = line .strip ()[3 :].strip ()
114- if lang == "python" :
115- lang = "py"
116- if lang not in ["cpp" , "py" , "java" ]:
117- raise ValueError (f"Unrecognized formatting lang: { line .strip ()[3 :]} " )
118- nlines .append (line [: line .find ("```" )] + f"```{ lang } \n " )
119- elif line .strip () == "```" :
120- if lang is not None : # end of lang block
121- # if contains_banned_terms(prog): # don't format
122- # print(f"skipping formatting {path}")
123- # nlines += prog
124- # else:
125- prog = [comment_codesnip (lang , prog_line ) for prog_line in prog ]
126- prog = [match_indentation (line , prog_line ) for prog_line in prog ]
127- ori_prog = prog
128- prog = format_prog (lang , prog )
129- if ori_prog != prog :
130- print ("formatted" , path )
131- whitespace = line [: line .find ("```" )]
132- nlines += [whitespace + line for line in prog ]
133- prog = []
134- lang = None
135- nlines .append (line )
136- elif lang is not None : # program block
137- prog .append (line )
138- else : # outside of program block
139- nlines .append (line )
140- with open (path , "w" ) as f :
141- f .write ("" .join (nlines ))
142- assert lang is None
111+ # print("formatting", path)
112+ with open (path , "r" , encoding = "utf-8 " ) as f :
113+ lines = f .readlines ()
114+ lang = None
115+ nlines = []
116+ prog = []
117+ for line in lines :
118+ if denotes_lang (line ): # start of lang block
119+ lang = line .strip ()[3 :].strip ()
120+ if lang == "python" :
121+ lang = "py"
122+ if lang not in ["cpp" , "py" , "java" ]:
123+ raise ValueError (f"Unrecognized formatting lang: { line .strip ()[3 :]} " )
124+ nlines .append (line [: line .find ("```" )] + f"```{ lang } \n " )
125+ elif line .strip () == "```" :
126+ if lang is not None : # end of lang block
127+ # if contains_banned_terms(prog): # don't format
128+ # print(f"skipping formatting {path}")
129+ # nlines += prog
130+ # else:
131+ prog = [comment_codesnip (lang , prog_line ) for prog_line in prog ]
132+ prog = [match_indentation (line , prog_line ) for prog_line in prog ]
133+ ori_prog = prog
134+ prog = format_prog (lang , prog )
135+ if ori_prog != prog :
136+ print ("formatted" , path )
137+ whitespace = line [: line .find ("```" )]
138+ nlines += [whitespace + line for line in prog ]
139+ prog = []
140+ lang = None
141+ nlines .append (line )
142+ elif lang is not None : # program block
143+ prog .append (line )
144+ else : # outside of program block
145+ nlines .append (line )
146+ with open (path , "w" , encoding = "utf-8 " ) as f :
147+ f .write ("" .join (nlines ))
148+ assert lang is None
143149
144150
145151def format_dir (dir ):
146- # https://stackoverflow.com/questions/2212643/python-recursive-folder-read
147- for root , subdirs , files in os .walk (dir ):
148- for file in files :
149- if file .endswith (".mdx" ):
150- path = os .path .join (root , file )
151- format_path (path )
152+ # https://stackoverflow.com/questions/2212643/python-recursive-folder-read
153+ for root , subdirs , files in os .walk (dir ):
154+ for file in files :
155+ if file .endswith (".mdx" ):
156+ path = os .path .join (root , file )
157+ format_path (path )
152158
153159
154160if __name__ == "__main__" :
155- """
156- Args: paths of files to format
157- """
158- from importlib .metadata import version
159-
160- print (f"Clang-Format Version = { version ('clang-format' )} " )
161- paths = sys .argv [1 :]
162- print (f"Formatting { len (paths )} paths" )
163- for path in paths :
164- format_path (path )
165- print ("Done!" )
161+ """
162+ Args: paths of files to format
163+ """
164+ from importlib .metadata import version
165+
166+ print (f"Clang-Format Version = { version ('clang-format' )} " )
167+ paths = sys .argv [1 :]
168+ print (f"Formatting { len (paths )} paths" )
169+ for path in paths :
170+ format_path (path )
171+ print ("Done!" )
0 commit comments