Source code for pythonimmediate.textopy

from __future__ import annotations
import traceback
import os
import sys
import typing
import atexit

[docs]def main()->None: """ This side does not receive the user-provided arguments directly, instead some parts of the configuration is decided by the pytotex side and forwarded to this half. The arguments are re-parsed here anyway to provide a "temporary" configuration for the engine to work with before getting the real configuration. """ from .engine import ParentProcessEngine, EngineStatus from . import PTTBlock, PTTVerbatimLine, run_error_finish, default_engine, surround_delimiter, substitute_private, get_bootstrap_code, run_main_loop, run_none_finish from .pytotex import parse_args from .communicate import GlobalConfiguration, Communicator args=parse_args() pseudo_config=GlobalConfiguration.from_args(args, typing.cast(Communicator, None)) def atexit_callback()->None: if engine.status==EngineStatus.waiting: run_none_finish() # correspond to the final \pythonimmediatelisten in \AtEndDocument # we use atexit_callback to let user register other atexit callbacks if engine.config.sanity_check_extra_line: assert not engine._read(), "Internal error: TeX sends extra line" engine=ParentProcessEngine(pseudo_config) atexit.register(atexit_callback) default_engine.set_engine(engine) try: run_main_loop() # if this returns cleanly TeX has no error. Otherwise some readline() will reach eof and print out a stack trace # returned cleanly → AtEndDocument sends a 'r'. assert engine.status==EngineStatus.running # by design, AtEndDocument will listen one last time engine.status=EngineStatus.waiting except: # see also documentation of run_error_finish. sys.stderr.write("\n") traceback.print_exc(file=sys.stderr) full_error = "".join(traceback.format_exc()) # to be printed on TeX's log file # the short_error will be printed on the terminal, so make sure it's not too long. type_, value, tb = sys.exc_info() short_error = "".join( traceback.format_exception_only(type_, value) + ["--\n"] + traceback.format_tb(tb, limit=-1) ).strip() # force limit the line width of the error message import textwrap short_error="\n".join( wrapped_line for paragraph in short_error.splitlines() for wrapped_line in textwrap.wrap(paragraph, width=40) ) if engine.status==EngineStatus.waiting: run_error_finish(PTTBlock.coerce(full_error), PTTBlock.coerce(short_error))
if __name__=="__main__": main()