miscs
This commit is contained in:
1 parent
0d8970061e
commit
c30aac0572
14 files changed
+343
-48
No files matched your search
@@ -32,7 +32,7 @@ def fetch_and_save_sub_text(ex_id, indices, label, text_path):
|
||||
try:
|
||||
with urllib.request.urlopen(url) as response:
|
||||
content = response.read().decode('utf-8')
|
||||
content = replace_dots(content.strip("\n"))
|
||||
content = prepare_latex_fragment(content.strip("\n"))
|
||||
with open(os.path.join(text_path, f"{label}.tex"), 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
# Compile PDF
|
||||
@@ -52,7 +52,7 @@ def fetch_and_save_sub_sol(ex_id, indices, label, sol_path):
|
||||
try:
|
||||
with urllib.request.urlopen(url) as response:
|
||||
content = response.read().decode('utf-8')
|
||||
content = replace_dots(content.strip("\n"))
|
||||
content = prepare_latex_fragment(content.strip("\n"))
|
||||
with open(os.path.join(sol_path, f"{label}.tex"), 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
# Compile PDF
|
||||
@@ -70,13 +70,39 @@ def replace_dots(text):
|
||||
# (?m) enables multiline mode so ^ matches start of each line
|
||||
return re.sub(r"(?m)^(\s*.)\.", r"\1)", text)
|
||||
|
||||
def replace_problem_labels(text):
|
||||
|
||||
def prepare_latex_fragment(text):
|
||||
"""Keep counter-only extracted lists valid before an enumitem resume."""
|
||||
# Extraction can omit every item before a context block while retaining
|
||||
# the list and its counters for resume*. An unnumbered item makes that
|
||||
# empty list legal without advancing the resumed question number.
|
||||
return re.sub(
|
||||
r'(\\begin\{enumerate\}(?:\[[^\]\n]*\])?)'
|
||||
r'(\s*(?:\\stepcounter\{[^{}]+\}\s*)*)'
|
||||
r'(\\end\{enumerate\})',
|
||||
r'\1\\item[]\2\3',
|
||||
replace_dots(text),
|
||||
)
|
||||
|
||||
def replace_problem_labels(text, numbering="problem"):
|
||||
"""Replaces labels according to spaces depth when problem=True."""
|
||||
def repl(m):
|
||||
spaces = m.group(1)
|
||||
label = m.group(2)
|
||||
n = len(spaces)
|
||||
try:
|
||||
if numbering == "problem_abc":
|
||||
if n == 1 and label.isdigit():
|
||||
return f"{spaces}{ROMANS_CAP[int(label)]})"
|
||||
if n == 4 and label.isalpha():
|
||||
return f"{spaces}{label.upper()})"
|
||||
if n == 7 and label.isdigit():
|
||||
return m.group(0)
|
||||
if n == 10 and label.isdigit():
|
||||
return f"{spaces}{chr(96 + int(label))})"
|
||||
if n == 13 and label.isdigit():
|
||||
return f"{spaces}{ROMANS_LOW[int(label)]})"
|
||||
return m.group(0)
|
||||
if n == 1 and label.isdigit(): # 1 space: 1) -> I)
|
||||
return f"{spaces}{ROMANS_CAP[int(label)]})"
|
||||
elif n == 4 and label.isalpha(): # 4 spaces: a) -> 1)
|
||||
@@ -92,7 +118,17 @@ def replace_problem_labels(text):
|
||||
# Matches start of line, spaces, alphanumeric label, and closing parenthesis
|
||||
return re.sub(r"(?m)^([ \t]+)([a-zA-Z0-9]+)\)", repl, text)
|
||||
|
||||
def format_indices(indices, problem=False):
|
||||
def format_indices(indices, problem=False, *, numbering=None):
|
||||
if numbering is not None:
|
||||
if numbering not in {"exercise", "problem", "problem_abc"}:
|
||||
raise ValueError(f"Unknown SHEETINFO numbering scheme: {numbering!r}")
|
||||
problem = numbering != "exercise"
|
||||
if numbering == "problem_abc":
|
||||
formatters = (lambda n: ROMANS_CAP[n], lambda n: chr(64 + n), str,
|
||||
lambda n: chr(96 + n), lambda n: ROMANS_LOW[n])
|
||||
if len(indices) > len(formatters):
|
||||
raise ValueError("Too many question levels for problem_abc numbering")
|
||||
return "".join(formatter(index) + ")" for formatter, index in zip(formatters, indices))
|
||||
if not indices: return ""
|
||||
if not problem:
|
||||
res = f"{indices[0]})"
|
||||
@@ -200,6 +236,11 @@ def process_directory(workspace: EvaluationWorkspace) -> ExitCode:
|
||||
|
||||
try:
|
||||
data = json.loads(json_str)
|
||||
numbering = data.get('numbering')
|
||||
if numbering is not None:
|
||||
# Validate even exercises without question indexes.
|
||||
format_indices([], numbering=numbering)
|
||||
problem = numbering != 'exercise'
|
||||
block_labels = []
|
||||
# Construct 'ids' parameter
|
||||
ex_id = str(data['id'])
|
||||
@@ -222,7 +263,7 @@ def process_directory(workspace: EvaluationWorkspace) -> ExitCode:
|
||||
fetch_and_save_sub_sol(ids, [], label, paths['Sol2'])
|
||||
else:
|
||||
for item in indexes:
|
||||
suffix = format_indices(item['indices'], problem)
|
||||
suffix = format_indices(item['indices'], problem, numbering=numbering)
|
||||
label = f"Ex {current_ex_num}" + (f" : {suffix}" if suffix else "")
|
||||
validate_windows_labels([label])
|
||||
block_labels.append(label)
|
||||
@@ -252,9 +293,9 @@ def process_directory(workspace: EvaluationWorkspace) -> ExitCode:
|
||||
|
||||
# Apply hierarchy depth replace if problem context
|
||||
if problem:
|
||||
t_text = replace_problem_labels(t_text)
|
||||
s_text = replace_problem_labels(s_text)
|
||||
p_text = replace_problem_labels(p_text)
|
||||
t_text = replace_problem_labels(t_text, numbering or 'problem')
|
||||
s_text = replace_problem_labels(s_text, numbering or 'problem')
|
||||
p_text = replace_problem_labels(p_text, numbering or 'problem')
|
||||
|
||||
base_filename = f"Ex {current_ex_num}"
|
||||
|
||||
|
||||
Reference in new issue
Block a user