fix
Browse files- app.py +14 -9
- posterbuilder/convert.py +23 -1
app.py
CHANGED
|
@@ -227,7 +227,6 @@ def _apply_meeting_logo(OUTPUT_DIR: Path, meeting_logo_file, logs):
|
|
| 227 |
return False
|
| 228 |
|
| 229 |
def _apply_theme_rgb(OUTPUT_DIR: Path, rgb_tuple, logs):
|
| 230 |
-
"""Update \\definecolor{<name>}{RGB}{r,g,b} or {HTML}{RRGGBB} in poster_output.tex."""
|
| 231 |
if not rgb_tuple:
|
| 232 |
return False
|
| 233 |
|
|
@@ -239,22 +238,27 @@ def _apply_theme_rgb(OUTPUT_DIR: Path, rgb_tuple, logs):
|
|
| 239 |
try:
|
| 240 |
content = tex_path.read_text(encoding="utf-8")
|
| 241 |
r, g, b = rgb_tuple
|
| 242 |
-
# names we might use in template
|
| 243 |
name_pattern = r"(?:nipspurple|neuripspurple|themecolor)"
|
| 244 |
|
| 245 |
-
# 1) Try RGB form
|
| 246 |
rgb_pat = rf"(\\definecolor\{{{name_pattern}\}}\{{RGB\}}\{{)\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(\}})"
|
| 247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
|
| 249 |
if n == 0:
|
| 250 |
-
|
| 251 |
-
from_str = f"{r:02X}{g:02X}{b:02X}"
|
| 252 |
html_pat = rf"(\\definecolor\{{{name_pattern}\}}\{{HTML\}}\{{)[0-9A-Fa-f]{{6}}(\}})"
|
| 253 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
|
| 255 |
if n > 0:
|
| 256 |
tex_path.write_text(new_content, encoding="utf-8")
|
| 257 |
-
logs.append(f"🎨 Theme color updated to RGB {{{r},{g},{b}}}
|
| 258 |
return True
|
| 259 |
else:
|
| 260 |
logs.append("ℹ️ No \\definecolor target found.")
|
|
@@ -265,6 +269,7 @@ def _apply_theme_rgb(OUTPUT_DIR: Path, rgb_tuple, logs):
|
|
| 265 |
return False
|
| 266 |
|
| 267 |
|
|
|
|
| 268 |
def _apply_left_logo(OUTPUT_DIR: Path, logo_files, logs):
|
| 269 |
"""
|
| 270 |
Use the first institutional logo uploaded by the user:
|
|
@@ -557,7 +562,7 @@ def run_pipeline(arxiv_url, pdf_file, openai_key, logo_files, meeting_logo_file,
|
|
| 557 |
|
| 558 |
except Exception as e:
|
| 559 |
logs.append(f"❌ Failed to create zip: {e}")
|
| 560 |
-
|
| 561 |
# ====== Prepare Overleaf base64 payload (optional) ======
|
| 562 |
overleaf_zip_b64 = ""
|
| 563 |
try:
|
|
|
|
| 227 |
return False
|
| 228 |
|
| 229 |
def _apply_theme_rgb(OUTPUT_DIR: Path, rgb_tuple, logs):
|
|
|
|
| 230 |
if not rgb_tuple:
|
| 231 |
return False
|
| 232 |
|
|
|
|
| 238 |
try:
|
| 239 |
content = tex_path.read_text(encoding="utf-8")
|
| 240 |
r, g, b = rgb_tuple
|
|
|
|
| 241 |
name_pattern = r"(?:nipspurple|neuripspurple|themecolor)"
|
| 242 |
|
|
|
|
| 243 |
rgb_pat = rf"(\\definecolor\{{{name_pattern}\}}\{{RGB\}}\{{)\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(\}})"
|
| 244 |
+
|
| 245 |
+
def repl_rgb(m):
|
| 246 |
+
return f"{m.group(1)}{r},{g},{b}{m.group(2)}"
|
| 247 |
+
|
| 248 |
+
new_content, n = re.subn(rgb_pat, repl_rgb, content, flags=re.MULTILINE)
|
| 249 |
|
| 250 |
if n == 0:
|
| 251 |
+
hexval = f"{r:02X}{g:02X}{b:02X}"
|
|
|
|
| 252 |
html_pat = rf"(\\definecolor\{{{name_pattern}\}}\{{HTML\}}\{{)[0-9A-Fa-f]{{6}}(\}})"
|
| 253 |
+
|
| 254 |
+
def repl_html(m):
|
| 255 |
+
return f"{m.group(1)}{hexval}{m.group(2)}"
|
| 256 |
+
|
| 257 |
+
new_content, n = re.subn(html_pat, repl_html, content, flags=re.MULTILINE)
|
| 258 |
|
| 259 |
if n > 0:
|
| 260 |
tex_path.write_text(new_content, encoding="utf-8")
|
| 261 |
+
logs.append(f"🎨 Theme color updated to RGB {{{r},{g},{b}}}")
|
| 262 |
return True
|
| 263 |
else:
|
| 264 |
logs.append("ℹ️ No \\definecolor target found.")
|
|
|
|
| 269 |
return False
|
| 270 |
|
| 271 |
|
| 272 |
+
|
| 273 |
def _apply_left_logo(OUTPUT_DIR: Path, logo_files, logs):
|
| 274 |
"""
|
| 275 |
Use the first institutional logo uploaded by the user:
|
|
|
|
| 562 |
|
| 563 |
except Exception as e:
|
| 564 |
logs.append(f"❌ Failed to create zip: {e}")
|
| 565 |
+
|
| 566 |
# ====== Prepare Overleaf base64 payload (optional) ======
|
| 567 |
overleaf_zip_b64 = ""
|
| 568 |
try:
|
posterbuilder/convert.py
CHANGED
|
@@ -517,6 +517,27 @@ def figures_to_latex(fig_list, out_tex_path: pathlib.Path, images_parent: pathli
|
|
| 517 |
)
|
| 518 |
return "\n".join(chunks)
|
| 519 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
# ===================== 主流程 =====================
|
| 521 |
def build():
|
| 522 |
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
|
@@ -562,7 +583,8 @@ def build():
|
|
| 562 |
# 注意:要先处理上面的大括号再处理反斜杠,否则会提前破坏结构
|
| 563 |
cleaned_tex = cleaned_tex.replace(r"\\\\", r"\\") # 避免双转义干扰
|
| 564 |
cleaned_tex = cleaned_tex.replace(r"\\", "\\") # 最终将 \\ → \
|
| 565 |
-
cleaned_tex = cleaned_tex.replace(r"\t\t", "\\t")
|
|
|
|
| 566 |
|
| 567 |
OUTPUT_PATH.write_text(cleaned_tex, encoding="utf-8")
|
| 568 |
print(f"✅ Wrote: {OUTPUT_PATH.relative_to(ROOT_DIR)}")
|
|
|
|
| 517 |
)
|
| 518 |
return "\n".join(chunks)
|
| 519 |
|
| 520 |
+
|
| 521 |
+
def strip_stray_t(tex: str) -> str:
|
| 522 |
+
_T_ALLOWED_PREFIXES = (
|
| 523 |
+
# 常见 text 系
|
| 524 |
+
"ext", "extbf", "extit", "exttt", "extsc", "extsf",
|
| 525 |
+
"extcolor", "extsuperscript", "extsubscript",
|
| 526 |
+
"extwidth", "extheight",
|
| 527 |
+
# beamer/tikz 等
|
| 528 |
+
"itle", "hanks", "ikz", "ikzpicture", "ikzset", "ikzstyle",
|
| 529 |
+
# 表格/书签等
|
| 530 |
+
"ab", "abular", "able", "abularx", "abcolsep",
|
| 531 |
+
# 其他常见
|
| 532 |
+
"iny", "ttfamily", "oday", "he", "ypeout",
|
| 533 |
+
"oprule", "midrule", "bottomrule", # booktabs
|
| 534 |
+
"ocs", "ocsection", "ocsubsection"
|
| 535 |
+
)
|
| 536 |
+
_T_NONCOMMAND_RE = re.compile(
|
| 537 |
+
r'\\([tT])(?!(' + '|'.join(_T_ALLOWED_PREFIXES) + r')|\{)'
|
| 538 |
+
)
|
| 539 |
+
return _T_NONCOMMAND_RE.sub(lambda m: m.group(1), tex)
|
| 540 |
+
|
| 541 |
# ===================== 主流程 =====================
|
| 542 |
def build():
|
| 543 |
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
| 583 |
# 注意:要先处理上面的大括号再处理反斜杠,否则会提前破坏结构
|
| 584 |
cleaned_tex = cleaned_tex.replace(r"\\\\", r"\\") # 避免双转义干扰
|
| 585 |
cleaned_tex = cleaned_tex.replace(r"\\", "\\") # 最终将 \\ → \
|
| 586 |
+
cleaned_tex = cleaned_tex.replace(r"\t\t", "\\t")
|
| 587 |
+
cleaned_tex = strip_stray_t(cleaned_tex)
|
| 588 |
|
| 589 |
OUTPUT_PATH.write_text(cleaned_tex, encoding="utf-8")
|
| 590 |
print(f"✅ Wrote: {OUTPUT_PATH.relative_to(ROOT_DIR)}")
|