|
1 | | -import os |
2 | 1 | import fileinput |
| 2 | +import os |
3 | 3 | from subprocess import call |
4 | 4 |
|
5 | | -call_pdflatex_l = ['pdflatex', '-synctex=1', |
6 | | - '-interaction=nonstopmode', 'main.tex'] |
| 5 | +call_pdflatex_l = ["pdflatex", "-synctex=1", "-interaction=nonstopmode", "main.tex"] |
| 6 | + |
7 | 7 |
|
8 | 8 | def clear_tex_binaries(): |
9 | 9 | # Clean up auxiliary LaTeX files |
10 | | - for file in os.listdir('.'): |
11 | | - if file.startswith('main'): |
12 | | - if not file.endswith(('.tex', '.pdf')): |
| 10 | + for file in os.listdir("."): |
| 11 | + if file.startswith("main"): |
| 12 | + if not file.endswith((".tex", ".pdf")): |
13 | 13 | os.remove(file) |
14 | 14 |
|
| 15 | + |
15 | 16 | def build_pdf(with_solution): |
16 | 17 | # Modify and build the main.tex file |
17 | 18 | clear_tex_binaries() |
18 | 19 |
|
19 | 20 | # Flag to ensure documentclass line is modified correctly |
20 | 21 | docclass_modified = False |
21 | | - |
22 | | - with fileinput.input('main.tex', inplace=True) as f: |
| 22 | + |
| 23 | + with fileinput.input("main.tex", inplace=True) as f: |
23 | 24 | for line in f: |
24 | | - if 'includeonly{' in line: |
| 25 | + if "includeonly{" in line: |
25 | 26 | # Comment out the includeonly flag |
26 | | - print(f'%{line}', end='') |
| 27 | + print(f"%{line}", end="") |
27 | 28 | # Look for the documentclass line |
28 | | - elif '\\documentclass' in line and 'examClass' in line: |
| 29 | + elif "\\documentclass" in line and "examClass" in line: |
29 | 30 | docclass_modified = True # Set the flag that we have modified the line |
30 | 31 |
|
31 | 32 | # Split documentclass into its components |
32 | | - preamble, class_info = line.split('{', 1) |
33 | | - class_name = class_info.rstrip('}\n') # Remove the trailing } |
34 | | - |
| 33 | + preamble, class_info = line.split("{", 1) |
| 34 | + class_name = class_info.rstrip("}\n") # Remove the trailing } |
| 35 | + |
35 | 36 | if with_solution: |
36 | 37 | # Add the [solution] option if not present |
37 | | - if '[' not in preamble: |
38 | | - preamble = preamble.replace('\\documentclass', '\\documentclass[solution]') |
| 38 | + if "[" not in preamble: |
| 39 | + preamble = preamble.replace( |
| 40 | + "\\documentclass", "\\documentclass[solution]" |
| 41 | + ) |
39 | 42 | else: |
40 | | - preamble = preamble.replace('[', '[solution, ') |
| 43 | + preamble = preamble.replace("[", "[solution, ") |
41 | 44 | else: |
42 | 45 | # Remove the [solution] option if present |
43 | | - preamble = preamble.replace('[solution, ', '[').replace('[solution]', '') |
| 46 | + preamble = preamble.replace("[solution, ", "[").replace( |
| 47 | + "[solution]", "" |
| 48 | + ) |
44 | 49 |
|
45 | 50 | # Reassemble the documentclass line |
46 | | - print(f'{preamble}{{{class_name}}}', end='\n') |
| 51 | + print(f"{preamble}{{{class_name}}}", end="\n") |
47 | 52 | else: |
48 | | - print(line, end='') |
49 | | - |
| 53 | + print(line, end="") |
| 54 | + |
50 | 55 | # If we didn't modify the documentclass, raise an exception for debugging |
51 | 56 | if not docclass_modified: |
52 | | - raise ValueError("documentclass line with 'examClass' not found or not modified.") |
| 57 | + raise ValueError( |
| 58 | + "documentclass line with 'examClass' not found or not modified." |
| 59 | + ) |
53 | 60 |
|
54 | 61 | # Run pdflatex twice for proper compilation |
55 | 62 | call(call_pdflatex_l) |
56 | 63 | call(call_pdflatex_l) |
57 | 64 |
|
| 65 | + |
58 | 66 | def process_directory(dir_path): |
59 | 67 | os.chdir(dir_path) |
60 | | - |
| 68 | + |
61 | 69 | # Check if main.tex exists |
62 | | - if not os.path.exists('main.tex'): |
63 | | - os.chdir('..') # Go back to the parent directory if no main.tex |
| 70 | + if not os.path.exists("main.tex"): |
| 71 | + os.chdir("..") # Go back to the parent directory if no main.tex |
64 | 72 | return |
65 | | - |
| 73 | + |
66 | 74 | # Build with solutions |
67 | 75 | build_pdf(with_solution=True) |
68 | | - os.makedirs('../built', exist_ok=True) |
69 | | - os.replace('main.pdf', os.path.join('../../built', f'{os.path.basename(dir_path)}_with_solution.pdf')) |
70 | | - |
| 76 | + os.makedirs("../built", exist_ok=True) |
| 77 | + os.replace( |
| 78 | + "main.pdf", |
| 79 | + os.path.join("../../built", f"{os.path.basename(dir_path)}_with_solution.pdf"), |
| 80 | + ) |
| 81 | + |
71 | 82 | # Build without solutions |
72 | 83 | build_pdf(with_solution=False) |
73 | | - os.replace('main.pdf', os.path.join('../../built', f'{os.path.basename(dir_path)}.pdf')) |
74 | | - |
75 | | - os.chdir('..') |
| 84 | + os.replace( |
| 85 | + "main.pdf", os.path.join("../../built", f"{os.path.basename(dir_path)}.pdf") |
| 86 | + ) |
| 87 | + |
| 88 | + os.chdir("..") |
| 89 | + |
76 | 90 |
|
77 | 91 | def traverse_and_build(root_dir): |
78 | 92 | for subdir, _, _ in os.walk(root_dir): |
79 | | - if os.path.exists(os.path.join(subdir, 'main.tex')): |
| 93 | + if os.path.exists(os.path.join(subdir, "main.tex")): |
80 | 94 | process_directory(subdir) |
81 | 95 |
|
| 96 | + |
82 | 97 | if __name__ == "__main__": |
83 | 98 | # Start the traversal from the current directory |
84 | 99 | root_directory = os.getcwd() # You can also specify a different directory if needed |
|
0 commit comments