-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix_md.py
More file actions
83 lines (65 loc) · 2.56 KB
/
fix_md.py
File metadata and controls
83 lines (65 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import os
import re
FILES = ["README.md", "dsa.md", "INDEX.md"]
def process_file(filepath):
if not os.path.exists(filepath):
return
with open(filepath, 'r') as f:
lines = f.read().splitlines()
out_lines = []
# Pass 1: Trailing spaces, horizontal rules, trailing punctuation in headings, lists
for i, line in enumerate(lines):
# Allow 2 spaces for hard breaks, otherwise strip all trailing whitespaces
if line.endswith(" ") and not line.endswith(" "):
pass
else:
line = line.rstrip(" \t")
# MD035: Horizontal rule style
if line == "----":
line = "---"
# MD026: Trailing punctuation in heading
if line.startswith("# "):
# We strip common punctuation at the end of headings
match = re.search(r'^(#+\s+.*)([\.\:\!\?\;]+)$', line)
if match:
line = match.group(1).rstrip()
# MD029: Ordered list item prefix
# We enforce "1. " instead of "5. " or "9. "
match = re.search(r'^(\s*)(\d+)\.\s+(.*)$', line)
if match:
# We replace it with 1.
line = f"{match.group(1)}1. {match.group(3)}"
out_lines.append(line)
# Pass 2: Blank lines around headers and code fences
# MD022: Headings surrounded by blank lines
# MD031: Fences surrounded by blank lines
in_code_block = False
final_lines = []
for i, line in enumerate(out_lines):
is_fence = line.startswith("```")
if is_fence:
in_code_block = not in_code_block
is_heading = line.startswith("#") and not in_code_block
# Ensure blank line above
if is_fence or is_heading:
if final_lines and final_lines[-1].strip() != "":
final_lines.append("")
final_lines.append(line)
# Ensure blank line below
if is_fence or is_heading:
# Don't add blank if it's EOF or the next line is already blank
if i + 1 < len(out_lines) and out_lines[i+1].strip() != "":
final_lines.append("")
# Pass 3: Collapse multiple consecutive blank lines to 1
collapsed = []
for line in final_lines:
if line.strip() == "":
if collapsed and collapsed[-1].strip() == "":
continue
collapsed.append(line)
# Write back, ensuring single trailing newline
with open(filepath, 'w') as f:
content = "\n".join(collapsed)
f.write(content + "\n")
for f in FILES:
process_file(f)