Keep LaTeX markers untouched in plain mode
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
GREEK_AND_SYMBOLS = {
|
||||
r"\alpha": "α",
|
||||
@@ -53,14 +52,6 @@ SUBSCRIPT = str.maketrans({
|
||||
})
|
||||
|
||||
_SCRIPT_PATTERN = re.compile(r"([_^])\(([^()]+)\)|([_^])\{([^{}]+)\}|([_^])([A-Za-z0-9+\-=])")
|
||||
EQUATION_OPEN = "[EQ]"
|
||||
EQUATION_CLOSE = "[/EQ]"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class MathSegment:
|
||||
kind: str
|
||||
value: str
|
||||
|
||||
|
||||
def _translate_script(value: str, marker: str) -> str:
|
||||
@@ -76,11 +67,15 @@ def _replace_script(match: re.Match[str]) -> str:
|
||||
|
||||
|
||||
def format_math_text(text: str, mode: str = "plain") -> str:
|
||||
"""Optional legacy text-only math formatting for non-Word targets."""
|
||||
"""Format the AI answer before key stepping.
|
||||
|
||||
plain keeps the response unchanged, which is the recommended mode for LaTeX
|
||||
markers such as [EQ]\\frac{a}{b}[/EQ].
|
||||
"""
|
||||
if mode == "plain":
|
||||
return text
|
||||
if mode not in {"unicode", "unicode_math"}:
|
||||
raise ValueError("math_text_format doit être 'plain', 'unicode' ou 'word_equation'")
|
||||
raise ValueError("math_text_format doit être 'plain' ou 'unicode'")
|
||||
|
||||
formatted = text
|
||||
for command, replacement in sorted(GREEK_AND_SYMBOLS.items(), key=lambda item: len(item[0]), reverse=True):
|
||||
@@ -91,43 +86,3 @@ def format_math_text(text: str, mode: str = "plain") -> str:
|
||||
previous = formatted
|
||||
formatted = _SCRIPT_PATTERN.sub(_replace_script, formatted)
|
||||
return formatted
|
||||
|
||||
|
||||
def split_word_equation_segments(text: str) -> list[MathSegment]:
|
||||
"""Split explicit [EQ]...[/EQ] blocks into Word equation actions.
|
||||
|
||||
No automatic math guessing is done here: the model decides where an equation
|
||||
starts and ends by returning [EQ] before the expression and [/EQ] after it.
|
||||
"""
|
||||
segments: list[MathSegment] = []
|
||||
cursor = 0
|
||||
|
||||
while cursor < len(text):
|
||||
start = text.find(EQUATION_OPEN, cursor)
|
||||
if start == -1:
|
||||
if cursor < len(text):
|
||||
segments.append(MathSegment("text", text[cursor:]))
|
||||
break
|
||||
|
||||
if start > cursor:
|
||||
segments.append(MathSegment("text", text[cursor:start]))
|
||||
|
||||
expression_start = start + len(EQUATION_OPEN)
|
||||
end = text.find(EQUATION_CLOSE, expression_start)
|
||||
if end == -1:
|
||||
expression = text[expression_start:].strip()
|
||||
cursor = len(text)
|
||||
else:
|
||||
expression = text[expression_start:end].strip()
|
||||
cursor = end + len(EQUATION_CLOSE)
|
||||
|
||||
if expression:
|
||||
segments.append(MathSegment("equation", expression))
|
||||
|
||||
merged: list[MathSegment] = []
|
||||
for segment in segments:
|
||||
if merged and segment.kind == "text" and merged[-1].kind == "text":
|
||||
merged[-1] = MathSegment("text", merged[-1].value + segment.value)
|
||||
else:
|
||||
merged.append(segment)
|
||||
return merged
|
||||
|
||||
Reference in New Issue
Block a user