#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Timestamp: 2026-02-08 # File: scripts/python/tex_snippet2full.py """Build a complete LaTeX document from body content with color mode support. Usage: python tex_snippet2full.py --body-file body.tex --output out.tex --color-mode dark python tex_snippet2full.py --body-text "\\section{Test}" --output out.tex python tex_snippet2full.py --body-file full.tex --output out.tex --complete-document """ import argparse import os import re import sys from pathlib import Path # Dark theme colors from config env vars (DRY with config/*.yaml) MONACO_BG = os.environ.get("SCITEX_WRITER_DARK_BG", "1E1E1E") MONACO_FG = os.environ.get("SCITEX_WRITER_DARK_FG", "D4D4D4") LINK_INTERNAL = os.environ.get("SCITEX_WRITER_DARK_LINK_INTERNAL", "90C695") LINK_CITATION = os.environ.get("SCITEX_WRITER_DARK_LINK_CITATION", "87CEEB") LINK_URL = os.environ.get("SCITEX_WRITER_DARK_LINK_URL", "DEB887") DARK_MODE_COMMANDS = f"""\ % Dark mode styling - matches Monaco/VS Code editor (#{MONACO_BG}) \\definecolor{{MonacoBg}}{{HTML}}{{{MONACO_BG}}} \\definecolor{{MonacoFg}}{{HTML}}{{{MONACO_FG}}} \\definecolor{{DarkGreen}}{{HTML}}{{{LINK_INTERNAL}}} \\definecolor{{DarkCyan}}{{HTML}}{{{LINK_CITATION}}} \\definecolor{{DarkOrange}}{{HTML}}{{{LINK_URL}}} \\pagecolor{{MonacoBg}} \\color{{MonacoFg}} \\makeatletter \\@ifpackageloaded{{hyperref}}{{% \\hypersetup{{ colorlinks=true, linkcolor=DarkGreen, citecolor=DarkCyan, urlcolor=DarkOrange, }}% }}{{}} \\makeatother""" DOCUMENT_TEMPLATE = """\ \\documentclass[11pt]{{article}} % Essential packages \\usepackage[english]{{babel}} \\usepackage[T1]{{fontenc}} \\usepackage[utf8]{{inputenc}} \\usepackage[table,svgnames]{{xcolor}} \\usepackage{{amsmath, amssymb}} \\usepackage{{graphicx}} \\usepackage{{booktabs}} \\usepackage{{hyperref}} \\usepackage{{geometry}} \\geometry{{margin=1in}} \\usepackage{{pagecolor}} \\begin{{document}} {color_commands} {body_content} \\end{{document}} """ def get_color_commands(color_mode: str) -> str: """Get LaTeX color commands for the specified mode.""" if color_mode == "dark": return DARK_MODE_COMMANDS return "" def inject_color_into_document(latex_content: str, color_mode: str) -> str: """Inject color mode styling into an existing complete LaTeX document.""" color_commands = get_color_commands(color_mode) if not color_commands: return latex_content pattern = r"(\\begin\{document\})" match = re.search(pattern, latex_content) if match: pos = match.end() return latex_content[:pos] + "\n" + color_commands + "\n" + latex_content[pos:] return color_commands + "\n" + latex_content def wrap_body_content(body_content: str, color_mode: str) -> str: """Wrap body content into a complete LaTeX document.""" color_commands = get_color_commands(color_mode) return DOCUMENT_TEMPLATE.format( color_commands=color_commands, body_content=body_content, ) def main(): parser = argparse.ArgumentParser( description="Build LaTeX document from body content with color mode." ) group = parser.add_mutually_exclusive_group(required=True) group.add_argument("--body-file", help="File containing LaTeX body content") group.add_argument("--body-text", help="Inline LaTeX body content") parser.add_argument("--output", required=True, help="Output .tex file path") parser.add_argument( "--color-mode", default="light", choices=["light", "dark"], help="Color mode (default: light)", ) parser.add_argument( "--complete-document", action="store_true", help="Input is a complete document (inject color only)", ) args = parser.parse_args() # Read body content if args.body_file: body_path = Path(args.body_file) if not body_path.exists(): print(f"ERROR: Body file not found: {args.body_file}", file=sys.stderr) sys.exit(1) content = body_path.read_text(encoding="utf-8") else: content = args.body_text # Build document if args.complete_document: result = inject_color_into_document(content, args.color_mode) else: result = wrap_body_content(content, args.color_mode) # Write output output_path = Path(args.output) output_path.parent.mkdir(parents=True, exist_ok=True) output_path.write_text(result, encoding="utf-8") print(f"Document written: {args.output}") if __name__ == "__main__": main() # EOF