-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.py
More file actions
113 lines (97 loc) · 4.24 KB
/
Copy pathexample.py
File metadata and controls
113 lines (97 loc) · 4.24 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import os
import re
def process_tex_file(filepath):
"""
处理单个 .tex 文件,查找并替换题目格式。
"""
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
multi_part_pattern = re.compile(
r'^\s*(\d+)[..]\s*(.*?)\s*\n' +
# Group 3: 捕获整个子问题块。
r'(' +
# 子问题1 (必须存在,单行)
r'^\s*(?:(1)|1\.)[^\n]*\n' +
# 子问题2 (必须存在,单行)
# 使用 `[^\n\r]*` 来匹配到行尾,兼容不同系统的换行符
r'^\s*(?:(2)|2\.)[^\n\r]*' +
# 匹配所有后续的、连续的、格式正确的单行子问题
r'(?:' +
r'\n^\s*(?:(\d+)|\d+\.)[^\n\r]*' +
r')*' +
r')',
re.MULTILINE
)
def replacement_func_multi_part(match):
main_stem = match.group(2).strip() # 大题题干
sub_questions_block = match.group(3).strip() # 整个子问题块
sub_q_parser_pattern = re.compile(
r'^\s*(?:((\d+))|(\d+)\.)\s*([\s\S]*?)(?=\n\s*(?:(\d+)|\d+\.)|\Z)',
re.MULTILINE
)
sub_q_matches = sub_q_parser_pattern.finditer(sub_questions_block)
enumerate_content = []
for sub_match in sub_q_matches:
# 子问题内容总是最后一个捕获组 (Group 3)
sub_q_content = sub_match.group(3).strip()
if sub_q_content: # 确保内容不为空
enumerate_content.append(f' \\item {sub_q_content}')
if not enumerate_content:
return match.group(0)
new_format = (
f'\n\\begin{{example}}\n'
f'{main_stem}\n'
'\\begin{enumerate}\n'
f'{os.linesep.join(enumerate_content)}\n'
'\\end{enumerate}\n'
'\\end{example}'
)
return new_format
single_choice_pattern = re.compile(
r'^\s*(\d+)[..]\s*(.*?)\s*(\s*\)\s*\n+' # 行首可选空白,题号(捕获组1),中英文句号,可选空白,
r'(?:\s*A[..]\s*([\s\S]*?)\n)' # 选项 A (捕获组3),匹配内容直到换行符
r'(?:\s*B[..]\s*([\s\S]*?)\n)' # 选项 B (捕获组4)
r'(?:\s*C[..]\s*([\s\S]*?)\n)' # 选项 C (捕获组5)
r'(?:\s*D[..]\s*([\s\S]*?)\n)', # 选项 D (捕获组6),匹配内容直到换行符
re.DOTALL | re.MULTILINE # DOTALL 使得 . 匹配换行,MULTILINE 使得 ^ 和 $ 匹配每一行的开头和结尾
)
def replacement_func_single_choice(match):
problem_number = match.group(1)
stem = match.group(2).strip()
option_a = match.group(3).strip()
option_b = match.group(4).strip()
option_c = match.group(5).strip()
option_d = match.group(6).strip()
# 构建新的格式
new_format = (
f'\n\\begin{{example}}\n'
f'{stem} (\\qquad)\n'
'\\begin{tasks}(4)\n'
f' \\task {option_a}\n'
f' \\task {option_b}\n'
f' \\task {option_c}\n'
f' \\task {option_d}\n'
'\\end{tasks}\n'
'\\end{example}'
)
return new_format
processed_content = multi_part_pattern.sub(replacement_func_multi_part, content)
processed_content = single_choice_pattern.sub(replacement_func_single_choice, processed_content)
if processed_content != content:
print(f"检测到并修改文件: {filepath}")
with open(filepath, 'w', encoding='utf-8') as f:
f.write(processed_content)
def recursive_find_and_process(root_dir):
"""
递归查找指定目录下的所有 .tex 文件并进行处理。
"""
print(f"开始在目录 '{root_dir}' 中递归查找 .tex 文件...")
for dirpath, _, filenames in os.walk(root_dir):
for filename in filenames:
if filename.endswith('.tex'):
filepath = os.path.join(dirpath, filename)
process_tex_file(filepath)
print("所有 .tex 文件处理完毕。")
if __name__ == "__main__":
target_directory = 'F:\\OneDrive\\Project\\LateX\\SeniorMath\\chapters'
recursive_find_and_process(target_directory)