pythonimmediate.lowlevel module
- class pythonimmediate.lowlevel.PTTBalancedTokenList(data: 'BalancedTokenList')[source]
Bases:
PyToTeXData- read_code() str
- class pythonimmediate.lowlevel.PTTBlock(data: 'str')[source]
Bases:
PyToTeXData- static coerce(s: str) PTTBlock[source]
Construct a block from arbitrary string, delete some content if needed.
- static ignore_last_space(s: str) PTTBlock[source]
Construct a block from arbitrary string, deleting trailing spaces on each line.
- read_code() str
- class pythonimmediate.lowlevel.PTTInt(data: 'int')[source]
Bases:
PyToTeXData- read_code() str
- class pythonimmediate.lowlevel.PTTTeXLine(data: str)[source]
Bases:
PyToTeXDataRepresents a line to be tokenized in TeX’s current catcode regime. The trailing newline is not included, i.e. it’s tokenized under
\endlinechar=-1.- read_code() str
- class pythonimmediate.lowlevel.PTTVerbatimLine(data: 'str')[source]
Bases:
PyToTeXData- read_code() str
- class pythonimmediate.lowlevel.PTTVerbatimRawLine(data: bytes)[source]
Bases:
PyToTeXDataRepresents a line to be tokenized verbatim. Internally the
\readlineprimitive is used, as such, any trailing spaces are stripped. The trailing newline is not included, i.e. it’s read under\endlinechar=-1.- read_code() str
- class pythonimmediate.lowlevel.PyToTeXData[source]
Bases:
ABCInternal class (for now). Represent a data type that can be sent from Python to \(\TeX\).
- class pythonimmediate.lowlevel.PythonCallTeXSyncFunctionType(*args, **kwargs)[source]
Bases:
PythonCallTeXFunctionType,Protocol
- class pythonimmediate.lowlevel.Python_call_TeX_data(TeX_code: 'str', recursive: 'bool', finish: 'bool', sync: 'Optional[bool]')[source]
Bases:
object
- class pythonimmediate.lowlevel.Python_call_TeX_extra(ptt_argtypes: 'Tuple[Type[PyToTeXData], ...]', ttp_argtypes: 'Union[Type[TeXToPyData], Tuple[Type[TeXToPyData], ...]]')[source]
Bases:
object
- pythonimmediate.lowlevel.Python_call_TeX_local(TeX_code: str, *, recursive: bool = True, sync: Optional[bool] = None, finish: bool = False) Callable[source]
Internal function. See
scan_Python_call_TeX().
- class pythonimmediate.lowlevel.TTPBlock[source]
Bases:
TeXToPyData,str- static read() TTPBlock[source]
Given that \(\TeX\) has just sent the data, read into a Python object.
- send_code() str
- send_code_var() str
- class pythonimmediate.lowlevel.TTPEBlock[source]
Bases:
TeXToPyData,strA kind of argument that interprets “escaped string” and fully expand anything inside. For example,
{\\}sends a single backslash to Python,{\{}sends a single{to Python.Done by fully expand the argument in
\escapechar=-1and convert it to a string. Additional precaution is needed, see the note above (TODO write documentation).Refer to Note on argument expansion of estr-type functions for more details.
- static read() TTPEBlock[source]
Given that \(\TeX\) has just sent the data, read into a Python object.
- send_code() str
- send_code_var() str
- class pythonimmediate.lowlevel.TTPELine[source]
Bases:
TeXToPyData,strSame as
TTPEBlock, but for a single line only.- static read() TTPELine[source]
Given that \(\TeX\) has just sent the data, read into a Python object.
- send_code() str
- send_code_var() str
- class pythonimmediate.lowlevel.TTPEmbeddedLine[source]
Bases:
TeXToPyData,str- static read() TTPEmbeddedLine[source]
Given that \(\TeX\) has just sent the data, read into a Python object.
- class pythonimmediate.lowlevel.TTPLine[source]
Bases:
TeXToPyData,str- static read() TTPLine[source]
Given that \(\TeX\) has just sent the data, read into a Python object.
- send_code() str
- send_code_var() str
- class pythonimmediate.lowlevel.TTPRawLine[source]
Bases:
TeXToPyData,bytes- static read() TTPRawLine[source]
Given that \(\TeX\) has just sent the data, read into a Python object.
- send_code() str
- send_code_var() str
- class pythonimmediate.lowlevel.TeXToPyData[source]
Bases:
ABCInternal class (for now). Represent a data type that can be sent from \(\TeX\) to Python.
- abstract static read() TeXToPyData[source]
Given that \(\TeX\) has just sent the data, read into a Python object.
- pythonimmediate.lowlevel.bootstrap_code_functions: list[Callable[[Engine], str]]
Internal constant. Contains functions that takes an engine object and returns some code before
substitute_private()is applied on it.
- pythonimmediate.lowlevel.build_Python_call_TeX(T: Type, TeX_code: str, *, recursive: bool = True, sync: Optional[bool] = None, finish: bool = False) None[source]
Internal function. See
scan_Python_call_TeX().T has the form Callable[[T1, T2], Tuple[U1, U2]] where the Tx are subclasses of PyToTeXData and the Ux are subclasses of TeXToPyData
The Tuple[…] can optionally be a single type, then it is almost equivalent to a tuple of one element It can also be None
- pythonimmediate.lowlevel.can_be_mangled_to(original: str, mangled: str) bool[source]
Internal functions, used to implemented
pycode()environment.If original is put in a \(\TeX\) file, read in other catcode regime (possibly drop trailing spaces/tabs), and then sent through
\write(possibly convert control characters to^^-notation), is it possible that the written content is equal to mangled?The function is somewhat tolerant (might return
Truein some cases whereFalseshould be returned), but not too tolerant.Example:
>>> can_be_mangled_to("a\n", "a\n") True >>> can_be_mangled_to("\n", "\n") True >>> can_be_mangled_to("\t\n", "\n") True >>> can_be_mangled_to("\t\n", "\t\n") True >>> can_be_mangled_to("\t\n", "^^I\n") True >>> can_be_mangled_to("\ta\n", "^^Ia\n") True >>> can_be_mangled_to("a b\n", "a b\n") True >>> can_be_mangled_to("a b \n", "a b\n") True >>> can_be_mangled_to("a\n", "b\n") False
- pythonimmediate.lowlevel.check_line(line: str, *, braces: bool, newline: bool, continue_: Optional[bool]) None[source]
check user-provided line before sending to TeX for execution
- pythonimmediate.lowlevel.define_Python_call_TeX(TeX_code: str, ptt_argtypes: List[Type[PyToTeXData]], ttp_argtypes: List[Type[TeXToPyData]], *, recursive: bool = True, sync: Optional[bool] = None, finish: bool = False) Tuple[Callable[[Engine], str], PythonCallTeXFunctionType][source]
Internal function.
TeX_codeshould be some expl3 code that defines a function with name%name%that when called should:run some \(\TeX\)-code (which includes reading the arguments, if any)
do the following if
sync: * sendrto Python (equivalently write %sync%) * send whatever needed for the output (as inttp_argtypes)call
\pythonimmediatelisteniff notfinish.
This is allowed to contain the following:
%name%: the name of the function to be defined as explained above.
%read_arg0(var_name)%, %read_arg1(…)%: will be expanded to code that reads the input.
%send_arg0(…)%, %send_arg1(…)%: will be expanded to code that sends the content.
%send_arg0_var(var_name)%, %send_arg1_var(…)%: will be expanded to code that sends the content in the variable.
%optional_sync%: expanded to code that writes
r(to sync), ifsyncis True.%naive_flush% and %naive_inline%: as explained in
mark_bootstrap_naive_replace(). (although usually you don’t need to explicitly write this, it’s embedded in thesend*()command of the last argument, or%sync%)
- Parameters
ptt_argtypes – list of argument types to be sent from Python to TeX (i.e. input of the TeX function)
ttp_argtypes – list of argument types to be sent from TeX to Python (i.e. output of the TeX function)
recursive – whether the TeX_code might call another Python function. Default to True. It does not hurt to always specify True, but performance would be a bit slower.
sync – whether the Python function need to wait for the TeX function to finish. Required if
ttp_argtypesis not empty. This should be left to be the default None most of the time. (which will make it always sync ifdebugging, otherwise only sync if needed i.e. there’s some output)finish – Include this if and only if
\pythonimmediatelistenis omitted. Normally this is not needed, but it can be used as a slight optimization; and it’s needed internally to implementrun_none_finishamong others. For each TeX-call-Python layer, emph{exactly one}finishcall can be made. If the function itself doesn’t call anyfinishcall (which happens most of the time), then the wrapper will callrun_none_finish.
- Returns
some TeX code to be executed, and a Python function object that when called will call the TeX function on the passed-in TeX engine and return the result.
Note that the TeX_code must eventually be executed on the corresponding engine for the program to work correctly.
Possible optimizations:
the
ris not needed if not recursive andttp_argtypesis nonempty (the output itself tells Python when the \(\TeX\)-code finished)the first line of the output may be on the same line as the
ritself (done, useTTPEmbeddedLinetype, although a bit hacky)
- pythonimmediate.lowlevel.define_TeX_call_Python(f: Callable[[...], None], name: Optional[str] = None, argtypes: Optional[List[Type[TeXToPyData]]] = None, identifier: Optional[str] = None) Callable[[Engine], str][source]
This function setups some internal data structure, and returns the \(\TeX\)-code to be executed on the \(\TeX\)-side to define the macro.
- Parameters
f – the Python function to be executed. It should take some arguments plus a keyword argument
engineand eventually (optionally) call one of the_finishfunctions.name – the macro name on the \(\TeX\)-side. This should only consist of letter characters in
expl3catcode regime.argtypes – list of argument types. If it’s None it will be automatically deduced from the function
f’s signature.identifier – should be obtained by
get_random_Python_identifier().
- Returns
some code (to be executed in
expl3catcode regime) as explained above.
- pythonimmediate.lowlevel.define_internal_handler(f: FunctionType) FunctionType[source]
Define a TeX function with TeX name =
f.__name__that calls f().This does not define the specified function in any particular engine, just add them to the
bootstrap_code.
- pythonimmediate.lowlevel.get_bootstrap_code(engine: Engine) str[source]
Return the bootstrap code for an engine.
This is before the call to
substitute_private().
- pythonimmediate.lowlevel.mark_bootstrap_naive_replace(code: str) None[source]
Similar to
mark_bootstrap(), but code may contain one of the following:%naive_inline: replaced with^^J \__naive_flush_data:if
Engine.config.naive_flushisTrue, else become empty
%naive_flush%: replaced with\__send_content:e {\__naive_flush_data:}if
Engine.config.naive_flushisTrue
- pythonimmediate.lowlevel.run_error_finish(full_error: PTTBlock, short_error: PTTBlock) None[source]
Internal function.
run_error_finishis fatal to \(\TeX\), so we only run it when it’s fatal to Python.We want to make sure the Python traceback is printed strictly before run_error_finish() is called, so that the Python traceback is not interleaved with \(\TeX\) error messages.
- pythonimmediate.lowlevel.scan_Python_call_TeX(sourcecode: str, filename: Optional[str] = None) None[source]
Internal function.
Scan the file in filename for occurrences of
typing.cast(T, Python_call_TeX_local(...)), then callbuild_Python_call_TeX(T, ...)for each occurrence.The way the whole thing work is:
In the Python code, some
typing.cast(T, Python_call_TeX_local(...))are used.This function is called on all the library source codes to scan for those occurrences, build necessary data structures for the
Python_call_TeX_local()function calls to work correctly.When
Python_call_TeX_local()is actually called, it does some magic to return the correct function.
Done this way, the type checking works correctly and it’s not necessary to define global temporary variables.
Don’t use this function on untrusted code.