*************************** The coloring-stream Library *************************** .. current-library:: coloring-stream .. current-module:: coloring-stream The ``coloring-stream`` module provides a means for writing text to the console or terminal with colors and varying intensity. On Unix, this is typically done via ANSI codes. Windows support is yet to be implemented. Usage ***** It is implemented as a :class:``, so it can wrap any given stream. While it can be created via :drm:`make`, it is easiest to just call :gf:`colorize-stream` on a stream to get back a :class:`` wrapper that can be used to output color. If the underlying stream doesn't support color, then the returned :class:`` will silently drop all text attributes. Once you have a :class:``, you can set text attributes by writing instances of :class:``. Text attributes are created with :gf:`text-attributes`. Text can have a foreground color, a background color and an intensity: .. code-block:: dylan let error-attributes = text-attributes(foreground: $color-red); let blinding-attributes = text-attributes(foreground: $color-green, background: $color-red, intensity: $bright-intensity); To reset text back to the defaults, use the predefined :const:`$reset-attributes` constant. Text attributes can be stored and used repeatedly. This lets you set up some stylized text attributes and re-use them. The text attributes can be written to the stream in two different ways: * Via :gf:`format` * Via :gf:`print` or :gf:`print-object` Once you have a :class:``, then you can write colorized text to it with :gf:`format`: .. code-block:: dylan let error-attributes = text-attributes(foreground: $color-red); let cs = colorize-stream(*standard-output*); format(cs, "%=Error:%= %s", error-attributes, $reset-attributes, error-message); This is implemented by providing an implementation of :gf:`print` specialized on :class:`` and :class:``. This can be used directly as well: .. code-block:: dylan let error-attributes = text-attributes(foreground: $color-red); let cs = colorize-stream(*standard-output*); print(error-attributes, cs); print("Error:", cs); print($reset-attributes, cs); print(' ', cs); print(error-message, cs); The coloring-stream Module ************************** .. class:: :abstract: :superclasses: :class:`` :description: :class:`` is the abstract wrapper stream that is used to determine whether or not a stream supports color output to avoid having to check at every write. .. generic-function:: colorize-stream :signature: colorize-stream (stream #key force-ansi?) => (coloring-stream) :parameter stream: An instance of :class:``. :parameter #key force-ansi?: An instance of :drm:``. :value coloring-stream: An instance of :class:``. :description: Wrap a *stream* with an appropriate instance of :class:``. It uses :gf:`stream-supports-color?` to determine whether or not the underlying stream supports color output. When *force-ansi?* is :drm:`#t`, then the usual checks are skipped and a coloring stream that generates ANSI output is created. This is useful when outputting to a string prior to writing the text to :var:`*standard-output*` or when writing a network server where the user may have an ANSI-capable client. When called on a :class:``, if *force-ansi?* is set and the stream is not an ANSI coloring stream, then the stream will be unwrapped and a new ANSI coloring stream wrapper will be created. Otherwise, calling ``colorize-stream`` on a :class:`` will return the same stream. :example: .. code-block:: dylan let stream = colorize-stream(*standard-output*); Or, using ``force-ansi?``: .. code-block:: dylan let text = with-output-to-string (s :: ) let force-ansi? = stream-supports-color?(*standard-output*); let s = colorize-stream(s, force-ansi?: force-ansi?); ... end with-output-to-string; write(*standard-output*, text); .. generic-function:: stream-supports-color? :open: :signature: stream-supports-color? (stream) => (well?) :parameter stream: An instance of :class:``. :value well?: An instance of :drm:``. :description: Return whether or not the underlying stream supports color output. This checks that: * The stream is a :class:``. * :gf:`stream-console?` is true. (On Unix, this means that ``isatty`` is true for the stream.) * The ``TERM`` environment variable is not ``"dumb"``. * The ``EMACS`` environment variable is not ``"t"``. .. generic-function:: stream-supports-ansi-color? :open: :signature: stream-supports-ansi-color? (stream) => (well?) :parameter stream: An instance of :class:``. :value well?: An instance of :drm:``. :description: Return whether or not the underlying stream might support ANSI color output, assuming that the underlying stream supports color output at all. On Unix, this will always return :drm:`#t`. On Windows, this attempts to detect situations where ANSI output would be permissible, such as running within an alternate console window like ConEMU. .. note:: This does NOT check to see if the stream actually supports coloring. It is meant to be used in conjunction with :gf:`stream-supports-color?`. Text Attributes =============== .. class:: :superclasses: :drm:`` :keyword background: An instance of ``false-or()``. :keyword foreground: An instance of ``false-or()``. :keyword intensity: An instance of ``false-or()``. :description: Instances of ```` are used for representing the desired text appearance. They can be passed to :gf:`format` when writing to a :class:``. *background* and *foreground*, if given, should be one of the color constants like :const:`$color-red`, :const:`$color-green`, etc. *intensity*, if given, should be one of :const:`$bright-intensity`, :const:`$dim-intensity` or :const:`$normal-intensity`. Values that are omitted are set to the default values for the terminal. .. function:: text-attributes :signature: text-attributes (#key foreground background intensity) => (attributes) :parameter #key foreground: An instance of ``false-or()``. :parameter #key background: An instance of ``false-or()``. :parameter #key intensity: An instance of ``false-or()``. :value attributes: An instance of :class:``. :description: ``text-attributes`` provides an easy wrapper for creating instances of :class:``. *background* and *foreground*, if given, should be one of the color constants like :const:`$color-red`, :const:`$color-green`, etc. *intensity*, if given, should be one of :const:`$bright-intensity`, :const:`$dim-intensity` or :const:`$normal-intensity`. Values that are omitted are set to the default values for the terminal. :example: .. code-block:: dylan let error-attributes = text-attributes(foreground: $color-red); .. constant:: $reset-attributes :type: :class:`` :description: A predefined constant to reset the text back to the default attributes. This is equivalent to ``text-attributes(intensity: $normal-intensity)``. Text Intensity -------------- .. constant:: $bright-intensity .. constant:: $dim-intensity :description: .. note:: Not all terminals support dimmed text. .. constant:: $normal-intensity Text Colors ----------- .. constant:: $color-black .. constant:: $color-blue .. constant:: $color-cyan .. constant:: $color-default .. constant:: $color-green .. constant:: $color-magenta .. constant:: $color-red .. constant:: $color-white .. constant:: $color-yellow