Concepts ======== .. _render-styles: Render Styles ------------- See :term:`render style`. All render style classes are designed to share a common interface (with some having extensions), making the usage of one class directly compatible with another, except when using style-specific features. Hence, the factory functions :py:class:`~term_image.image.AutoImage`, :py:class:`~term_image.image.from_file` and :py:class:`~term_image.image.from_url` provide a means of render-style-agnostic usage of the library. These functions automatically detect the best render style supported by the :term:`active terminal`. There are two main categories of render styles: .. _text-based: Text-based Render Styles ^^^^^^^^^^^^^^^^^^^^^^^^ Represent images using ASCII or Unicode symbols, and in some cases, with escape sequences to reproduce color. Render style classes in this category are subclasses of :py:class:`~term_image.image.TextImage`. These include: * :py:class:`~term_image.image.BlockImage` .. _graphics-based: Graphics-based Render Styles ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Represent images with actual pixels, using terminal graphics protocols. Render style classes in this category are subclasses of :py:class:`~term_image.image.GraphicsImage`. These include: * :py:class:`~term_image.image.KittyImage` * :py:class:`~term_image.image.ITerm2Image` .. _render-methods: Render Methods ^^^^^^^^^^^^^^ A :term:`render style` may implement multiple :term:`render methods`. See the **Render Methods** section in the description of a render style class (that implements multiple render methods), for the description of its render methods. .. _auto-cell-ratio: Auto Cell Ratio --------------- .. note:: This concerns :ref:`text-based` only. The is a feature which when supported, can be used to determine the :term:`cell ratio` directly from the terminal emulator itself. With this feature, it is possible to always produce images of text-based render styles with correct **aspect ratio**. When using either mode of :py:class:`~term_image.AutoCellRatio`, it's important to note that some terminal emulators (most non-graphics-capable ones) might have queried. See :ref:`terminal-queries`. If the program will never expect any useful input, particularly **while an image's size is being set/calculated**, then using :py:attr:`~term_image.AutoCellRatio.DYNAMIC` mode is OK. For an image with :term:`dynamic size`, this includes when it's being rendered and when its :py:attr:`~term_image.image.BaseImage.rendered_size`, :py:attr:`~term_image.image.BaseImage.rendered_width` or :py:attr:`~term_image.image.BaseImage.rendered_height` property is invoked. Otherwise i.e if the program will be expecting input, use :py:attr:`~term_image.AutoCellRatio.FIXED` mode and use :py:func:`~term_image.utils.read_tty_all` to read all currently unread input just before calling :py:func:`~term_image.set_cell_ratio`. .. _active-terminal: The Active Terminal ------------------- See :term:`active terminal`. The following streams/files are checked in the following order (along with the rationale behind the ordering): * ``STDOUT``: Since it's where images will most likely be drawn. * ``STDIN``: If output is redirected to a file or pipe and the input is a terminal, then using it as the :term:`active terminal` should give the expected result i.e the same as when output is not redirected. * ``STDERR``: If both output and input are redirected, it's usually unlikely for errors to be. * ``/dev/tty``: Finally, if all else fail, fall back to the process' controlling terminal, if any. The first one that is ascertained to be a terminal device is used for all :ref:`terminal-queries` and to retrieve the terminal (and window) size on some terminal emulators. .. note:: If none of the streams/files is a TTY device, then a :py:class:`~term_image.exceptions.TermImageWarning` is issued and dependent functionality is disabled. .. _terminal-queries: Terminal Queries ---------------- Some features of this library require the acquisition of certain information from the :term:`active terminal`. A single iteration of this acquisition procedure is called a **query**. A query involves three major steps: 1. Clear all unread input from the terminal 2. Write to the terminal 3. Read from the terminal For this procedure to be successful, it must not be interrupted. About #1 If the program is expecting input, use :py:func:`~term_image.utils.read_tty_all` to read all currently unread input (**without blocking**) just before any operation involving a query. About #2 and #3 After sending a request to the terminal, its response is awaited. The default wait time is :py:data:`~term_image.DEFAULT_QUERY_TIMEOUT` but can be changed using :py:func:`~term_image.set_query_timeout`. If the terminal emulator responds after the set timeout, this can result in the application program receiving what would seem to be garbage or ghost input (see this :ref:`FAQ `). If the program includes any other function that could write to the terminal OR especially, read from the terminal or modify it's attributes, while a query is in progress (as a result of asynchronous execution e.g multithreading or multiprocessing), decorate it with :py:func:`~term_image.utils.lock_tty` to ensure it doesn't interfere. For example, an :github:repo:`image viewer ` based on this project uses `urwid `_ which reads from the terminal using :py:meth:`urwid.raw_display.Screen.get_available_raw_input`. To prevent this method from interfering with terminal queries, it uses :py:class:`~term_image.widget.UrwidImageScreen` which overrides and wraps the method like:: class UrwidImageScreen(Screen): @lock_tty def get_available_raw_input(self): return super().get_available_raw_input() Also, if the :term:`active terminal` is not the controlling terminal of the process using this library (e.g output is redirected to another TTY device), ensure no process that can interfere with a query (e.g a shell or REPL) is currently running in the active terminal. For instance, such a process can be temporarily put to sleep. .. _queried-features: Features that require terminal queries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In parentheses are the outcomes when the terminal doesn't support queries or when queries are disabled. - :ref:`auto-cell-ratio` (determined to be unsupported) - Support checks for :ref:`graphics-based` (determined to be unsupported) - Auto background color (black is used) - Alpha blend for pixels above the alpha threshold in transparent renders with :ref:`text-based` (black is used) - Workaround for background colors in text-based renders on the Kitty terminal (the workaround is disabled) .. note:: This list might not always be complete. In case you notice - any difference with any unlisted feature when terminal queries are enabled versus when disabled, or - a behaviour different from the one specified for the listed features, when terminal queries are disabled, please open an issue `here `_.