\input texinfo          @c -*-texinfo-*-
@c %**start of header
@setfilename libtextstyle.info
@c The @ifset makeinfo ... @end ifset conditional evaluates to true in makeinfo
@c for info and html output, but to false in texi2html.
@ifnottex
@ifclear texi2html
@set makeinfo
@end ifclear
@end ifnottex
@settitle GNU @code{libtextstyle}
@finalout
@c Indices:
@c   cp = concept         @cindex
@c   fn = function        @findex
@c   vr = variable        @vindex
@c Unused predefined indices:
@c   ky = keystroke       @kindex
@c   pg = program         @pindex
@c   tp = type            @tindex
@ifclear texi2html
@firstparagraphindent insert
@end ifclear
@c %**end of header

@include version.texi

@ifinfo
@dircategory Software development
@direntry
* GNU libtextstyle: (libtextstyle).     Output of styled text.
@end direntry
@end ifinfo

@ifinfo
This manual provides documentation for the GNU @code{libtextstyle} library.

@copying
Copyright (C) 2018-2019 Free Software Foundation, Inc.

This manual is free documentation.  It is dually licensed under the
GNU FDL and the GNU GPL.  This means that you can redistribute this
manual under either of these two licenses, at your choice.

This manual is covered by the GNU FDL.  Permission is granted to copy,
distribute and/or modify this document under the terms of the
GNU Free Documentation License (FDL), either version 1.2 of the
License, or (at your option) any later version published by the
Free Software Foundation (FSF); with no Invariant Sections, with no
Front-Cover Text, and with no Back-Cover Texts.
A copy of the license is at @url{https://www.gnu.org/licenses/fdl.html}.

This manual is covered by the GNU GPL.  You can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL), either
version 2 of the License, or (at your option) any later version published
by the Free Software Foundation (FSF).
A copy of the license is at @url{https://www.gnu.org/licenses/gpl.html}.
@end copying
@end ifinfo

@titlepage
@title GNU libtextstyle, version @value{VERSION}
@subtitle Output of styled text
@subtitle updated @value{UPDATED}
@author Bruno Haible

@ifnothtml
@page
@vskip 0pt plus 1filll
@c @insertcopying
Copyright (C) 2018-2019 Free Software Foundation, Inc.

This manual is free documentation.  It is dually licensed under the
GNU FDL and the GNU GPL.  This means that you can redistribute this
manual under either of these two licenses, at your choice.

This manual is covered by the GNU FDL.  Permission is granted to copy,
distribute and/or modify this document under the terms of the
GNU Free Documentation License (FDL), either version 1.2 of the
License, or (at your option) any later version published by the
Free Software Foundation (FSF); with no Invariant Sections, with no
Front-Cover Text, and with no Back-Cover Texts.
A copy of the license is at @url{https://www.gnu.org/licenses/fdl.html}.

This manual is covered by the GNU GPL.  You can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL), either
version 2 of the License, or (at your option) any later version published
by the Free Software Foundation (FSF).
A copy of the license is at @url{https://www.gnu.org/licenses/gpl.html}.
@end ifnothtml
@end titlepage

@c Table of Contents
@contents

@ifnottex
@node Top
@top GNU libtextstyle

This manual documents the GNU libtextstyle library, version
@value{VERSION}.

@menu
* Introduction::                Introduction
* The user's view::             The user's perspective
* The programmer's view::       The programmer's perspective
* Licenses::
* Function Index::
* Variable Index::
* Index::
@end menu

@end ifnottex

@node Introduction
@chapter Introduction

Text is easier to read when it is accompanied with styling information,
such as color, font attributes (weight, posture), or underlining, and
this styling is customized appropriately for the output device.

GNU libtextstyle provides an easy way to add styling to programs that
produce output to a console or terminal emulator window.  It does this
in a way that allows the end user to customize the styling using the
industry standard, namely Cascading Style Sheets (CSS).

@menu
* Style definitions::
* Built-in versus separate styling::
@end menu

@node Style definitions
@section Style definitions

Let's look at the traditional way styling is done for specific programs.

Browsers, when they render HTML, use CSS styling.

The older approach to user-customizable text styling is that the user
associates patterns with escape sequences in an environment variable or a
command-line argument.  This is the approach used, for example, by the
GNU @samp{ls} program in combination with the @samp{dircolors} program.
The processing is distributed across several steps:
@enumerate
@item
There is default style definition that is hard-coded in the
@samp{dircolors} program.  The user can also define their own definitions
in a file such as @file{~/.dir_colors}.  This style definition contains
explicit terminal escape sequences; thus, it can only be used with
consoles and terminal emulators, and each style definition applies only
to a certain class of mostly-compatible terminal emulators.
@item
The @command{dircolors} program, when invoked, translates such a style
definition to a sequence of shell statements that sets an environment
variable @code{LS_COLORS}.
@item
The shell executes these statements, and thus sets the environment
variable @code{LS_COLORS}.
@item
The program looks at the environment variable and emits the listed escape
sequences.
@end enumerate

In contrast, this library implements styling as follows:
@enumerate
@item
There is a default style definition in a CSS file that is part of the
same package as the stylable program.  The user can also define their own
definitions in a CSS file, and set an environment environment variable to
point to it.
@item
The program looks at the environment variable, parses the CSS file,
translates the styling specifications to the form that is appropriate for
the output device (escape sequences for terminal emulators, inline CSS
and @code{<span>} elements for HTML output), and emits it.
@end enumerate

Thus, with GNU libtextstyle, the styling has the following properties:
@itemize @bullet
@item
It is easier for the user to define their own styling, because the file
format is standardized and supported by numerous syntax aware editors.
@item
A styling file does not depend on the particular output device.  An HTML
output and a black-on-white terminal emulator can use the same styling
file.  A white-on-black (or even green-on-black) terminal emulator will
need different styling, though.
@item
It is simpler: There is no need for a program that converts the style
specification from one format to another.
@end itemize

@node Built-in versus separate styling
@section Built-in versus separate styling

There are generally two approaches for adding styling to text:
@itemize @bullet
@item
The program that generates the text adds the styling.  It does so through
interleaved statements that turn on or off specific attributes.
@item
The styling gets added by a separate program, that postprocesses the
output.  This separate program usually uses regular expressions to
determine which text regions to style with a certain set of text
attributes.
@end itemize

The first approach produces a styling that is 100% correct, regardless of
the complexity of the text that is being output.  This is the preferred
approach for example for JSON, XML, or programming language text.

The second approach works well if the output has a simple, easy-to-parse
format.  It may produce wrong styling in some cases when the text format
is more complex.  This approach is often used for viewing log files.

GNU libtextstyle supports both approaches; it includes an example program
for each of the two approaches.

@node The user's view
@chapter The end user's perspective

Styled output can viewed fine in a console or terminal emulator window.

The stylable program will typically have the following options:
@table @code
@item --color
Use colors and other text attributes always.
@item --color=@var{when}
Use colors and other text attributes if @var{when}.  @var{when} may be
@code{always}, @code{never}, @code{auto}, or @code{html}.
@item --style=@var{style-file}
Specify the CSS style rule file for @code{--color}.
@end table

For more details, see the sections @ref{The --color option} and
@ref{The --style option} below.

If the output does not fit on a screen, you can use @samp{less -R} to
scroll around in the styled output.  For example:
@smallexample
@var{program} --color @var{arguments} | less -R
@end smallexample

@menu
* The TERM variable::
* The NO_COLOR variable::
* The NO_TERM_HYPERLINKS variable::
* Emacs::
* The --color option::
* The --style option::
@end menu

@node The TERM variable
@section The environment variable @code{TERM}

@vindex TERM@r{, environment variable}
The environment variable @code{TERM} contains a identifier for the text
window's capabilities.  You can get a detailed list of these cababilities
by using the @samp{infocmp} command (for example: @code{infocmp -L1 xterm}),
using @samp{man 5 terminfo} as a reference.

When producing text with embedded color directives, a
@code{libtextstyle}-enabled program looks at the @code{TERM} variable.
Text windows today typically support at least 8 colors.  Often, however,
the text window supports 16 or more colors, even though the @code{TERM}
variable is set to a identifier denoting only 8 supported colors.  It
can be worth setting the @code{TERM} variable to a different value in
these cases.

After setting @code{TERM}, you can verify how well it works by invoking
@samp{@var{program} --color=test}, where @code{@var{program}} is any
@code{libtextstyle}-enabled program, and seeing whether the output looks
like a reasonable color map.

@menu
* Terminal emulators::
* Consoles::
@end menu

@node Terminal emulators
@subsection Terminal emulator programs

The following terminal emulator programs support 256 colors and set
@code{TERM=xterm-256color} accordingly:

@itemize @bullet
@item
In GNOME: @code{gnome-terminal}, @code{tilda}.
@item
@code{rxvt-unicode} (sets @code{TERM=rxvt-unicode-256color}).
@item
@code{st} (sets @code{TERM=st-256color}).
@item
@code{QTerminal}.
@item
On macOS: @code{Terminal}, @code{iTerm2}.
@end itemize

The following terminal emulator programs support 256 colors.  You only
need to set @code{TERM=xterm-256color} or similar; the programs by default
set @code{TERM} to a value that supports only 8 colors.

@itemize @bullet
@item
@code{xterm} is in many cases built with support for 256 colors.  But it
sets @code{TERM=xterm}.  You need to set @code{TERM=xterm-256color}.
@item
In GNOME: @code{guake} (sets @code{TERM=xterm}).  You need to set
@code{TERM=xterm-256color}.
@item
In KDE: @code{konsole} (sets @code{TERM=xterm}).  You need to set
@code{TERM=xterm-256color} or @code{TERM=konsole-256color}.
@item
In KDE: @code{yakuake} (sets @code{TERM=xterm}).  You need to set
@code{TERM=xterm-256color}.
@item
In Enlightenment: @code{Eterm} (sets @code{TERM=Eterm}).  You need to set
@code{TERM=Eterm-256color}.
@item
@code{mlterm} (sets @code{TERM=mlterm}).  You need to set
@code{TERM=mlterm-256color}.
@item
On Windows: @code{PuTTY} (sets @code{TERM=xterm}).  You need to set
@code{TERM=xterm-256color} or @code{TERM=putty-256color}.
@item
On Windows: @code{TeraTerm} (sets @code{TERM=xterm}).  You need to set
@code{TERM=xterm-256color}.
@end itemize

A couple of terminal emulator programs support even the entire RGB color
space (16 million colors).  To get this to work, at this date (2019), you
need three things:
@itemize @bullet
@item
The @code{ncurses} library version 6.1 or newer must be installed.
@item
You need a recent version of the respective terminal emulator program.
See @url{https://gist.github.com/XVilka/8346728} for the most recent
developments in this area.
@item
You need to set the @code{TERM} environment variable to the corresponding
value:
@code{TERM=xterm-direct} instead of
@code{TERM=xterm} or @code{TERM=xterm-256color},
@code{TERM=konsole-direct} in @code{konsole},
@code{TERM=st-direct} in @code{st},
@code{TERM=mlterm-direct} in @code{mlterm},
or @code{TERM=iterm2-direct} in @code{iTerm2} on macOS.
@end itemize

@node Consoles
@subsection Consoles

On OpenBSD 6 consoles, @code{TERM=xterm} produces better results than the
default @code{TERM=vt220}.

On NetBSD 8 consoles, @code{TERM=netbsd6} produces better results than the
default @code{TERM=vt100}.

On Windows consoles, no @code{TERM} setting is needed.

@node The NO_COLOR variable
@section The environment variable @code{NO_COLOR}

@vindex NO_COLOR@r{, environment variable}
@c The name of this environment variable is specified by https://no-color.org/.
The environment variable @code{NO_COLOR} can be used to suppress styling
in the textual output.  When this environment variable is set (to any value),
@code{libtextstyle}-enabled programs will not emit colors and other text
styling.

This environment variable can be overridden by passing the command-line option
@samp{--color=always} (see @ref{The --color option}).

@node The NO_TERM_HYPERLINKS variable
@section The environment variable @code{NO_TERM_HYPERLINKS}

@vindex NO_TERM_HYPERLINKS@r{, environment variable}
The environment variable @code{NO_TERM_HYPERLINKS} can be used to suppress
hyperlinks in the textual output.  When this environment variable is set
(to any value), @code{libtextstyle}-enabled programs will not emit
hyperlinks.  This may be useful for terminal emulators which produce
garbage output when they receive the escape sequence for a hyperlink.
Currently (as of 2019), this affects some versions of
@c                    https://qa.debian.org/popcon.php
@code{konsole},    @c 11%
@code{emacs},      @c 7%
@code{lxterminal}, @c 6%
@code{guake},      @c 1.3%
@code{yakuake},    @c 1.1%
@code{rxvt}.       @c 0.9%

@node Emacs
@section Emacs as a terminal emulator

Emacs has several terminal emulators: @code{M-x shell} and
@code{M-x term}.  @code{M-x term} has good support for styling, whereas
in @code{M-x shell} most of the styling gets lost.

@node The --color option
@section The @code{--color} option

@cindex @code{--color} option
The @samp{--color=@var{when}} option specifies under which conditions
styled (colorized) output should be generated.  The @var{when} part can
be one of the following:

@table @code
@item always
@itemx yes
The output will be colorized.

@item never
@itemx no
The output will not be colorized.

@item auto
@itemx tty
The output will be colorized if the output device is a tty, i.e.@: when
the output goes directly to a text screen or terminal emulator window.

@item html
The output will be colorized and be in HTML format.  This value is only
supported by some programs.

@item test
This is a special value, understood only by some programs.  It is
explained in the section (@ref{The TERM variable}) above.
@end table

@noindent
@samp{--color} is equivalent to @samp{--color=yes}.  The default is
@samp{--color=auto}.

Thus, a command that invokes a @code{libtextstyle}-enabled program will
produce colorized output when called by itself in a command window.
Whereas in a pipe, such as @samp{@var{program} @var{arguments} | less -R},
it will not produce colorized output.  To get colorized output in this
situation nevertheless, use the command
@samp{@var{program} --color @var{arguments} | less -R}.

The @samp{--color=html} option will produce output that can be viewed in
a browser.  This can be useful, for example, for Indic languages,
because the renderic of Indic scripts in browsers is usually better than
in terminal emulators.

Note that the output produced with the @code{--color} option is
@emph{not} consumable by programs that expect the raw text.  It contains
additional terminal-specific escape sequences or HTML tags.  For example,
an XML parser will give a syntax error when confronted with a colored XML
output.  Except for the @samp{--color=html} case, you therefore normally
don't need to save output produced with the @code{--color} option in a
file.

@node The --style option
@section The @code{--style} option

@cindex @code{--style} option
The @samp{--style=@var{style_file}} option specifies the style file to
use when colorizing.  It has an effect only when the @code{--color}
option is effective.

If the @code{--style} option is not specified, the program may consider
the value of an environment variable.  It is meant to point to the user's
preferred style for such output.  The name of such an environment
variable, if supported, is documented in the documentation of the
@code{libtextstyle}-enabled program.

You can also design your own styles.  This is described in the next
section.

@menu
* Style rules::                 How to create a style file
* Debugging style files::       How to debug a style file
@end menu

@node Style rules
@subsection Creating your own style files

The same style file can be used for styling a certain type of output, for
terminal output and for HTML output.  It is written in CSS
(Cascading Style Sheet) syntax.  See
@url{https://www.w3.org/TR/css2/cover.html} for a formal definition of
CSS.  Many HTML authoring tutorials also contain explanations of CSS.

In the case of HTML output, the style file is embedded in the HTML output.
In the case of text output, the style file is interpreted by the
@code{libtextstyle}-enabled program.

You should avoid @code{@@import} statements, because
@itemize @minus
@item
In the case of HTML output, the files referenced by the @code{@@import}
statements would not be embedded in the HTML output.  In fact, relative
file names would be interpreted relative to the resulting HTML file.
@item
In the case of text output, @code{@@import}s are not supported, due to a
limitation in @code{libcroco}.
@end itemize

CSS rules are built up from selectors and declarations.  The declarations
specify graphical properties; the selectors specify when they apply.

GNU libtextstyle supports simple selectors based on "CSS classes", see
the CSS2 spec, section 5.8.3.  The set of CSS classes that are supported
by a @code{libtextstyle}-enabled program are documented in the
documentation of that program.

These selectors can be combined to hierarchical selectors.  For example,
assume a program supports the CSS classes @code{string} (that matches a
string) and @code{non-ascii} (that matches a word with non-ASCII
characters), you could write

@smallexample
.string .non-ascii @{ color: red; @}
@end smallexample

@noindent
to highlight only the non-ASCII words inside strings.

In text mode, pseudo-classes (CSS2 spec, section 5.11) and
pseudo-elements (CSS2 spec, section 5.12) are not supported.

The declarations in HTML mode are not limited; any graphical attribute
supported by the browsers can be used.

The declarations in text mode are limited to the following properties.
Other properties will be silently ignored.

@table @asis
@item @code{color} (CSS2 spec, section 14.1)
@itemx @code{background-color} (CSS2 spec, section 14.2.1)
These properties are supported.  Colors will be adjusted to match the
terminal's capabilities.  Note that many terminals support only 8 colors.

@item @code{font-weight} (CSS2 spec, section 15.2.3)
This property is supported, but most terminals can only render two
different weights: @code{normal} and @code{bold}.  Values >= 600 are
rendered as @code{bold}.

@item @code{font-style} (CSS2 spec, section 15.2.3)
This property is supported.  The values @code{italic} and @code{oblique}
are rendered the same way.

@item @code{text-decoration} (CSS2 spec, section 16.3.1)
This property is supported, limited to the values @code{none} and
@code{underline}.
@end table

@node Debugging style files
@subsection Debugging style files

@cindex Debugging
If you want to understand why the style rules in a style file produce
the output that you see, you can do so in three steps:

@enumerate
@item
Run the program with the command-line option @code{--color=html},
redirecting the output to a file.
@item
Open the resulting HTML file in a browser.
@item
Use the browser's built-in CSS debugging tool.
@itemize @bullet
@item
In Firefox: From the pop-up menu, select "Inspect Element".
Click somewhere in the DOM tree ("Inspector" tab) and look at the
CSS declarations in the "Rules" tab.
@item
In Chromium: From the pop-up menu, select "Inspect".
Click somewhere in the DOM tree ("Elements" tab) and look at the
CSS declarations in the "Styles" tab.
@end itemize
@end enumerate

This technique allows you, in particular, to see which CSS declarations
override which other CSS declarations from other CSS rules.

@node The programmer's view
@chapter The programmer's perspective

As a programmer, enabling styling consists of the following tasks:
@enumerate
@item
Define the command-line options and environment variable that the user
can use to control the styling.
@item
Define the CSS classes that the user can use in the CSS file.  Each CSS
class corresponds to a text role; each CSS class can be given a different
styling by the user.
@item
Change the output routines so that they take an @samp{ostream_t} object
as argument instead of a @samp{FILE *}.
@item
Insert paired invocations to @code{styled_ostream_begin_css_class},
@code{styled_ostream_end_css_class} around each run of text with a
specific text role.
@item
Link with @code{libtextstyle}.  If your package is using GNU autoconf,
you can use the @code{libtextstyle.m4} macro from Gnulib.
@item
Prepare a default style file.
@item
Update the documentation of your package.
@end enumerate

The following sections go into more detail.

@menu
* Basic use::
* Include files::
* Link options::
* Command-line options::
* The output stream hierarchy::
* Debugging the styling code::
* What to document::
@end menu

@node Basic use
@section Basic use of libtextstyle

Source code that makes use of GNU libtextstyle needs an include statement:

@smallexample
#include <textstyle.h>
@end smallexample

Basic use of GNU libtextstyle consists of statements like these:

@smallexample
  styled_ostream_t stream =
    styled_ostream_create (STDOUT_FILENO, "(stdout)", TTYCTL_AUTO,
                           style_file_name);
  ...
  styled_ostream_begin_use_class (stream, css_class);
  ...
  ostream_write_str (stream, string);
  ...
  styled_ostream_end_use_class (stream, css_class);
  ...
  styled_ostream_free (stream);
@end smallexample

Before this snippet, your code needs to determine the name of the style
file to use (@code{style_file_name}).  If no styling is desired -- the
precise condition depends on the value of @code{color_mode} but also on
your application logic --, you should set @code{style_file_name} to
@code{NULL}.

An object of type @code{styled_ostream_t} is allocated.  The function
@code{styled_ostream_create} allocates it; the function
@code{styled_ostream_free} deallocates it.

Such @code{styled_ostream_t} supports output operations
(@code{ostream_write_str}), interleaved with adding and removing CSS
classes.  The CSS class in effect when an output operation is performed
determines, through the style file, the text attributes associated with
that piece of text.

@menu
* Hyperlinks::
@end menu

@node Hyperlinks
@subsection Hyperlinks

Text output may contain hyperlinks.  These hyperlinks are encoded through
an escape sequence, specified at
@url{https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda,
Hyperlinks in terminal emulators}.  Currently (as of 2019), they are
displayed only in @code{gnome-terminal} version 3.26 or above.  More
terminal emulators will support hyperlinks in the future.  Terminal
emulators which don't support hyperlinks ignore it, except for a few
terminal emulators, for which users may need to disable the hyperlinks
(see @ref{The NO_TERM_HYPERLINKS variable}) if the heuristic built into
@code{libtextstyle} does not already disable them.

To emit a hyperlink, use code like this:

@smallexample
  styled_ostream_t stream = ...
  ...
  /* Start a hyperlink.  */
  styled_ostream_set_hyperlink (stream, url, NULL);
  ...
  /* Emit the anchor text.  This can be styled text.  */
  ostream_write_str (stream, "Click here!");
  ...
  /* End the current hyperlink.  */
  styled_ostream_set_hyperlink (stream, NULL, NULL);
@end smallexample

The anchor text can be styled.  But the hyperlinks themselves cannot be
styled; they behave as implemented by the terminal emulator.

@node Include files
@section Include files

@cindex Include file
@cindex @code{<textstyle.h>}
The include file @code{<textstyle.h>} declares all facilities defined by
the library.

@node Link options
@section Link options

The library to link with is called @code{libtextstyle}, with a
system-dependent suffix.  You link with it though link options of the
form @code{-ltextstyle} for a library installed in system locations, or
@code{-L@var{libdir} -ltextstyle} for a static library installed in other
locations, or @code{-L@var{libdir} -ltextstyle -Wl,-rpath,@var{libdir}}
for a shared library installed in other locations (assuming a GCC
compatible compiler and linker and no @code{libtool}), or
@code{-L@var{libdir} -ltextstyle -R@var{libdir}} for a shared library
installed in other locations (with @code{libtool}).  Additionally, the
link options may need to include the dependencies: @code{-lm}, and
@code{-lncurses} or (on NetBSD) @code{-ltermcap} or (on AIX)
@code{-lxcurses} or (on HP-UX) @code{-lcurses}, and on some systems also
@code{-liconv}.

It is a bit complicated to determine the right link options in a portable
way.  Therefore an Autoconf macro is provided in the file
@code{libtextstyle.m4} in Gnulib, that makes this task easier.  Assuming
the build system of your package is based on GNU Autoconf, you invoke it
through @code{gl_LIBTEXTSTYLE}.  It searches for an installed
@code{libtextstyle}.  If found, it sets and AC_SUBSTs
@code{HAVE_LIBTEXTSTYLE=yes} and the @code{LIBTEXTSTYLE} and
@code{LTLIBTEXTSTYLE} variables, and augments the @code{CPPFLAGS}
variable, and #defines @code{HAVE_LIBTEXTSTYLE} to 1.  Otherwise, it sets
and AC_SUBSTs @code{HAVE_LIBTEXTSTYLE=no} and @code{LIBTEXTSTYLE} and
@code{LTLIBTEXTSTYLE} to empty.  In link commands that use @code{libtool},
use @code{LTLIBTEXTSTYLE}; in link commands that don't use @code{libtool},
use @code{LIBTEXTSTYLE}.

If you use GNU Automake, the proper place to use the link options is
@code{@var{program}_LDADD} for programs and @code{@var{library}_LIBADD}
for libraries.

@node Command-line options
@section Command-line options

While you are free to provide any command-line option to enable the
styling of the output, it is good if different GNU programs use the same
command-line options for this purpose.  These options are described in
the sections @ref{The --color option} and @ref{The --style option}.  To
achieve this, use the following API (declared in @code{<textstyle.h>}):

@deftypevr Variable bool color_test_mode
True if a @code{--color} option with value @code{test} has been seen.
@end deftypevr

@deftypevr Variable {enum@tie{}color_option} color_mode
Stores the value of the @code{--color} option.
@end deftypevr

@deftypevr Variable {const@tie{}char@tie{}*} style_file_name
Stores the value of the @code{--style} option.
@end deftypevr

Note: These variables, like any variables exported from shared libraries,
can only be used in executable code.  You @emph{cannot} portably use
their address in initializers of global or static variables.  This is a
restriction that is imposed by the Windows, Cygwin, and Android platforms.

@deftypefn Function bool handle_color_option (const@tie{}char@tie{}*@var{option})
You invoke this function when, during argument parsing, you have
encountered a @code{--color} or @code{--color=...} option.  The return
value is an error indicator: @code{true} means an invalid option.
@end deftypefn

@deftypefn Function void handle_style_option (const@tie{}char@tie{}*@var{option})
You invoke this function when, during argument parsing, you have
encountered a @code{--style} or @code{--style=...} option.
@end deftypefn

@deftypefn Function void print_color_test (void)
Prints a color test page.  You invoke this function after argument
parsing, when the @code{color_test_mode} variable is true.
@end deftypefn

@deftypefn Function void style_file_prepare (const@tie{}char@tie{}*@var{style_file_envvar}, const@tie{}char@tie{}*@var{stylesdir_envvar}, const@tie{}char@tie{}*@var{stylesdir_after_install}, const@tie{}char@tie{}*@var{default_style_file})
Assigns a default value to @code{style_file_name} if necessary.  You
invoke this function after argument parsing, when @code{color_test_mode}
is false.

@code{@var{style_file_envvar}} is an environment variable that, when set
to a non-empty value, specifies the style file to use.  This environment
variable is meant to be set by the user.

@code{@var{stylesdir_envvar}} is an environment variable that, when set
to a non-empty value, specifies the directory with the style files, or
@code{NULL}.  This is necessary for running the testsuite before
@samp{make install}.

@code{@var{stylesdir_after_install}} is the directory with the style
files after @samp{make install}.

@code{@var{default_style_file}} is the file name of the default style
file, relative to @var{stylesdir}.
@end deftypefn

@node The output stream hierarchy
@section The output stream hierarchy

There are various classes of output streams, some of them with styling
support.  These ``classes'' are defined in an object-oriented programming
style that resembles C++ or Java, but are actually implemented in C with
a little bit of object orientation syntax.  These definitions are
preprocessed down to C.  As a consequence, GNU libtextstyle is a C
library and does not need to link with the C++ standard library.

All these classes are declared in @code{<textstyle.h>}.

The base output stream type is @samp{ostream_t}.  It is a pointer type to
a (hidden) implementation type.  Similarly for the subclasses.

When we say that @samp{some_ostream_t} is a subclass of @samp{ostream_t},
what we mean is:
@itemize @bullet
@item
Every @samp{some_ostream_t} object can be converted to an
@samp{ostream_t}, by virtue of a simple assignment.  No cast is needed.
@item
The opposite conversion, from @samp{ostream_t} to @samp{some_ostream_t},
can also be performed, provided that the object is actually an instance
of @samp{some_ostream_t}.
@item
Every method @samp{ostream_@var{foobar}} exists also as a method
@samp{some_ostream_@var{foobar}} with compatible argument types and a
compatible return type.
@end itemize

@menu
* The ostream class::
* The styled_ostream class::
* ostream subclasses without styling::
* styled_ostream subclasses::
@end menu

@node The ostream class
@subsection The abstract @code{ostream} class

The base output stream type is @samp{ostream_t}.

It has the following methods:

@deftypefn Function void ostream_write_mem (ostream_t@tie{}@var{stream}, const@tie{}void@tie{}*@var{data}, size_t@tie{}@var{len})
Writes a sequence of bytes to a stream.
@end deftypefn

@deftypefn Function void ostream_write_str (ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{string})
Writes a string's contents to a stream.
@end deftypefn

@deftypefn Function ptrdiff_t ostream_printf (ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{format}, ...)
@deftypefnx Function ptrdiff_t ostream_vprintf (ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{format}, va_list args)
Writes formatted output to a stream.

These functions return the size of formatted output, or a negative value
in case of an error.
@end deftypefn

@deftypefn Function void ostream_flush (ostream_t@tie{}@var{stream}, ostream_flush_scope_t@tie{}@var{scope})
Brings buffered data to its destination.
@end deftypefn

@deftypefn Function void ostream_free (ostream_t@tie{}@var{stream})
Closes and frees a stream.
@end deftypefn

@node The styled_ostream class
@subsection The abstract @code{styled_ostream} class

The type for a styled output stream is @samp{styled_ostream_t}.  It is a
subclass of @samp{ostream_t} that adds the following methods:

@deftypefn Function void styled_ostream_begin_use_class (styled_ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{classname})
Starts a run of text belonging to @code{@var{classname}}.  The
@code{@var{classname}} is the name of a CSS class.  It can be chosen
arbitrarily and customized through the CSS file.
@end deftypefn

@deftypefn Function void styled_ostream_end_use_class (styled_ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{classname})
Ends a run of text belonging to @code{@var{classname}}.  The
@code{styled_ostream_begin_use_class} /
@code{styled_ostream_end_use_class} calls must match properly.
@end deftypefn

@deftypefn Function {const char *} styled_ostream_get_hyperlink_ref (styled_ostream_t@tie{}@var{stream})
Returns the referred URL of the currently set hyperlink, or @code{NULL}
if no hyperlink attribute is currently set.

Note: The returned string is only valid up to the next invocation of
@code{styled_ostream_set_hyperlink}.
@end deftypefn

@deftypefn Function {const char *} styled_ostream_get_hyperlink_id (styled_ostream_t@tie{}@var{stream})
Returns the id of the currently set hyperlink, or @code{NULL} if no
hyperlink attribute is currently set.

Note: The returned string is only valid up to the next invocation of
@code{styled_ostream_set_hyperlink}.
@end deftypefn

@deftypefn Function void styled_ostream_set_hyperlink (styled_ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{ref}, const@tie{}char@tie{}*@var{id})
Sets or removes a hyperlink attribute.

To set a hyperlink attribute, pass a non-@code{NULL} @var{ref}.
@var{ref} is an URL; it should be at most 2083 bytes long.  Non-ASCII
characters should be URI-escaped (using the %nn syntax).  @var{id} is
an optional identifier.  On terminal output, multiple hyperlinks with
the same @var{id} will be highlighted together.  If specified, @var{id}
should be at most 250 bytes long.

To remove a hyperlink attribute, pass @code{NULL} for @var{ref} and @var{id}.

Hyperlinks don't nest.  That is, a hyperlink attribute is enabled only
up to the next invocation of @code{styled_ostream_set_hyperlink}.
@end deftypefn

@deftypefn Function void styled_ostream_flush_to_current_style (styled_ostream_t@tie{}@var{stream})
This function acts like @code{ostream_flush (@var{stream}, FLUSH_THIS_STREAM)},
except that it leaves the destination with the current text style enabled,
instead of with the default text style.

After calling this function, you can output strings without newlines(!) to the
underlying stream, and they will be rendered like strings passed to
@code{ostream_write_mem}, @code{ostream_write_str}, or @code{ostream_printf}.
@end deftypefn

@node ostream subclasses without styling
@subsection Concrete ostream subclasses without styling

@menu
* The file_ostream class::      Output to a FILE stream.
* The fd_ostream class::        Output to a file descriptor.
* The term_ostream class::      Output to a terminal.
* The html_ostream class::      Output to an HTML file.
* The memory_ostream class::    Output to a memory buffer,
* The iconv_ostream class::     Output with character encoding conversion.
@end menu

@node The file_ostream class
@subsubsection The @code{file_ostream} class

The @code{file_ostream} class supports output to an @code{<stdio.h>}
@code{FILE} stream.  Its type is @samp{file_ostream_t}.  It is a subclass
of @samp{ostream_t} that adds no methods.

It can be instantiated through this function:

@deftypefn Function file_ostream_t file_ostream_create (FILE@tie{}*@var{fp})
Creates an output stream referring to @code{@var{fp}}.

Note: The resulting stream must be closed before @code{@var{fp}} can be
closed.
@end deftypefn

@node The fd_ostream class
@subsubsection The @code{fd_ostream} class

The @code{file_ostream} class supports output to a file descriptor.  Its
type is @samp{fd_ostream_t}.  It is a subclass of @samp{ostream_t} that
adds no methods.

It can be instantiated through this function:

@deftypefn Function fd_ostream_t fd_ostream_create (int@tie{}@var{fd}, const@tie{}char@tie{}*@var{filename}, bool@tie{}@var{buffered})
Creates an output stream referring to the file descriptor @code{@var{fd}}.

@code{@var{filename}} is used only for error messages.

Note: The resulting stream must be closed before @code{@var{fd}} can be
closed.
@end deftypefn

@node The term_ostream class
@subsubsection The @code{term_ostream} class

The @code{term_ostream} class supports output to a file descriptor that
is connected to a terminal emulator or console.  Its type is
@samp{term_ostream_t}.  It is a subclass of @samp{ostream_t}.

It can be instantiated through this function:

@deftypefn Function term_ostream_t term_ostream_create (int@tie{}@var{fd}, const@tie{}char@tie{}*@var{filename}, ttyctl_t@tie{}@var{tty_control})
Creates an output stream referring to the file descriptor @code{@var{fd}}.

@code{@var{filename}} is used only for error messages.

@code{@var{tty_control}} specifies the amount of control to take over the
underlying tty.

The resulting stream will be line-buffered.

Note: The resulting stream must be closed before @code{@var{fd}} can be
closed.
@end deftypefn

The class adds the following methods:

@deftypefn Function term_color_t term_ostream_rgb_to_color (term_ostream_t@tie{}@var{stream}, int@tie{}@var{red}, int@tie{}@var{green}, int@tie{}@var{blue})
Converts an RGB value
(@code{@var{red}}, @code{@var{green}}, @code{@var{blue}} in [0..255]) to
a color, valid for this stream only.
@end deftypefn

@deftypefn Function term_color_t term_ostream_get_color (term_ostream_t@tie{}@var{stream})
@deftypefnx Function void term_ostream_set_color (term_ostream_t@tie{}@var{stream}, term_color_t@tie{}@var{color})
Gets/sets the text color.
@end deftypefn

@deftypefn Function term_color_t term_ostream_get_bgcolor (term_ostream_t@tie{}@var{stream})
@deftypefnx Function void term_ostream_set_bgcolor (term_ostream_t@tie{}@var{stream}, term_color_t@tie{}@var{color})
Gets/sets the background color.
@end deftypefn

@deftypefn Function term_weight_t term_ostream_get_weight (term_ostream_t@tie{}@var{stream})
@deftypefnx Function void term_ostream_set_weight (term_ostream_t@tie{}@var{stream}, term_weight_t@tie{}@var{weight})
Gets/sets the font weight.
@end deftypefn

@deftypefn Function term_posture_t term_ostream_get_posture (term_ostream_t@tie{}@var{stream})
@deftypefnx Function void term_ostream_set_posture (term_ostream_t@tie{}@var{stream}, term_posture_t@tie{}@var{posture})
Gets/sets the font posture.
@end deftypefn

@deftypefn Function term_underline_t term_ostream_get_underline (term_ostream_t@tie{}@var{stream})
@deftypefnx Function void term_ostream_set_underline (term_ostream_t@tie{}@var{stream}, term_underline_t@tie{}@var{underline})
Gets/sets the text underline decoration.
@end deftypefn

@deftypefn Function {const char *} term_ostream_get_hyperlink_ref (term_ostream_t@tie{}@var{stream})
Returns the referred URL of the currently set hyperlink, or @code{NULL}
if no hyperlink attribute is currently set.

Note: The returned string is only valid up to the next invocation of
@code{term_ostream_set_hyperlink}.
@end deftypefn

@deftypefn Function {const char *} term_ostream_get_hyperlink_id (term_ostream_t@tie{}@var{stream})
Returns the id of the currently set hyperlink, or @code{NULL} if no
hyperlink attribute is currently set.

Note: The returned string is only valid up to the next invocation of
@code{term_ostream_set_hyperlink}.
@end deftypefn

@deftypefn Function void term_ostream_set_hyperlink (term_ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{ref}, const@tie{}char@tie{}*@var{id})
Sets or removes a hyperlink attribute.

To set a hyperlink attribute, pass a non-@code{NULL} @var{ref}.
@var{ref} is an URL; it should be at most 2083 bytes long.  Non-ASCII
characters should be URI-escaped (using the %nn syntax).  @var{id} is
an optional identifier.  Multiple hyperlinks with the same @var{id}
will be highlighted together.  If specified, @var{id} should be at most
250 bytes long.

To remove a hyperlink attribute, pass @code{NULL} for @var{ref} and @var{id}.

Hyperlinks don't nest.  That is, a hyperlink attribute is enabled only
up to the next invocation of @code{styled_ostream_set_hyperlink}.
@end deftypefn

@deftypefn Function void term_ostream_flush_to_current_style (term_ostream_t@tie{}@var{stream})
This function acts like @code{ostream_flush (@var{stream}, FLUSH_THIS_STREAM)},
except that it leaves the terminal with the current text attributes enabled,
instead of with the default text attributes.

After calling this function, you can output strings without newlines(!) to the
underlying file descriptor, and they will be rendered like strings passed to
@code{ostream_write_mem}, @code{ostream_write_str}, or @code{ostream_printf}.
@end deftypefn

@node The html_ostream class
@subsubsection The @code{html_ostream} class

The @code{html_ostream} class supports output to any destination, in HTML
syntax.  Its type is @samp{html_ostream_t}.  It is a subclass of
@samp{ostream_t}.

It can be instantiated through this function:

@deftypefn Function html_ostream_t html_ostream_create (ostream_t@tie{}@var{destination})
Creates an output stream that takes input in the UTF-8 encoding and
writes it in HTML form on @code{@var{destination}}.

This stream produces a sequence of lines.  The caller is responsible for
opening the @code{<body><html>} elements before and for closing them
after the use of this stream.

Note: The resulting stream must be closed before @code{@var{destination}}
can be closed.
@end deftypefn

The class adds the following methods:

@deftypefn Function void html_ostream_begin_span (html_ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{classname})
Starts a @code{<span class="@var{classname}">} element.  The
@code{@var{classname}} is the name of a CSS class.  It can be chosen
arbitrarily and customized through the CSS file.
@end deftypefn

@deftypefn Function void html_ostream_end_span (html_ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{classname})
Ends a @code{<span class="@var{classname}">} element.

The @code{html_ostream_begin_span} / @code{html_ostream_end_span} calls
must match properly.
@end deftypefn

@deftypefn Function {const char *} html_ostream_get_hyperlink_ref (html_ostream_t@tie{}@var{stream})
Returns the referred URL of the currently set hyperlink, or @code{NULL}
if no hyperlink attribute is currently set.

Note: The returned string is only valid up to the next invocation of
@code{html_ostream_set_hyperlink_ref}.
@end deftypefn

@deftypefn Function void html_ostream_set_hyperlink_ref (html_ostream_t@tie{}@var{stream}, const@tie{}char@tie{}*@var{ref})
Sets or removes a hyperlink attribute.

To set a hyperlink attribute, pass a non-@code{NULL} @var{ref}.
@var{ref} is an URL; it should be at most 2083 bytes long.  Non-ASCII
characters should be URI-escaped (using the %nn syntax).

To remove a hyperlink attribute, pass @code{NULL} for @var{ref}.

Hyperlinks don't nest.  That is, a hyperlink attribute is enabled only
up to the next invocation of @code{html_ostream_set_hyperlink_ref}.
@end deftypefn

@deftypefn Function void html_ostream_flush_to_current_style (html_ostream_t@tie{}@var{stream})
This function acts like @code{ostream_flush (@var{stream}, FLUSH_THIS_STREAM)},
except that it leaves the destination with the current text style enabled,
instead of with the default text style.

After calling this function, you can output strings without newlines(!) to the
underlying stream, and they will be rendered like strings passed to
@code{ostream_write_mem}, @code{ostream_write_str}, or @code{ostream_printf}.
@end deftypefn

@node The memory_ostream class
@subsubsection The @code{memory_ostream} class

The @code{memory_ostream} class supports output to an in-memory buffer.
Its type is @samp{memory_ostream_t}.  It is a subclass of
@samp{ostream_t}.

It can be instantiated through this function:

@deftypefn Function memory_ostream_t memory_ostream_create (void)
Creates an output stream that accumulates the output in a memory buffer.
@end deftypefn

The class adds the following method:

@deftypefn Function void memory_ostream_contents (memory_ostream_t@tie{}@var{stream}, const@tie{}void@tie{}**@var{bufp}, size_t@tie{}*@var{buflenp})
Returns a pointer to the output accumulated so far and its size.  It
stores them in @code{*@var{bufp}} and @code{*@var{buflenp}}, respectively.

Note: These two return values become invalid when more output is done to
the stream or when the stream is freed.
@end deftypefn

@node The iconv_ostream class
@subsubsection The @code{iconv_ostream} class

The @code{iconv_ostream} class supports output to any destination.  Its
type is @samp{iconv_ostream_t}.  It is a subclass of @samp{ostream_t}
that adds no methods.

It can be instantiated through this function:

@deftypefn Function iconv_ostream_t iconv_ostream_create (const@tie{}char@tie{}*@var{from_encoding}, const@tie{}char@tie{}*@var{to_encoding}, ostream_t@tie{}@var{destination})
Creates an output stream that converts from @code{@var{from_encoding}} to
@code{@var{to_encoding}}, writing the result to @code{@var{destination}}.

Note: The resulting stream must be closed before @code{@var{destination}}
can be closed.
@end deftypefn

@node styled_ostream subclasses
@subsection Concrete @code{styled_ostream} subclasses

@menu
* The term_styled_ostream class::  Styled output to a terminal.
* The html_styled_ostream class::  Styled output to an HTML file.
* The noop_styled_ostream class::  No-op styling.
@end menu

@node The term_styled_ostream class
@subsubsection The @code{term_styled_ostream} class

The @code{term_styled_ostream} class supports styled output to a file
descriptor that is connected to a terminal emulator or console.  Its type
is @samp{term_styled_ostream_t}.  It is a subclass of
@samp{styled_ostream_t}.

It can be instantiated through this function:

@deftypefn Function term_styled_ostream_t term_styled_ostream_create (int@tie{}@var{fd}, const@tie{}char@tie{}*@var{filename}, ttyctl_t@tie{}@var{tty_control}, const@tie{}char@tie{}*@var{css_filename})
Creates an output stream referring to the file descriptor @code{@var{fd}},
styled with the file @code{@var{css_filename}}.

@code{@var{filename}} is used only for error messages.

@code{@var{tty_control}} specifies the amount of control to take over the
underlying tty.

Note: The resulting stream must be closed before @code{@var{fd}} can be
closed.

Returns @code{NULL} upon failure.
@end deftypefn

The following is a variant of this function.  Upon failure, it does not
return @code{NULL}; instead, it returns a styled @code{fd_stream} on
which the styling operations exist but are no-ops.

@deftypefn Function styled_ostream_t styled_ostream_create (int@tie{}@var{fd}, const@tie{}char@tie{}*@var{filename}, ttyctl_t@tie{}@var{tty_control}, const@tie{}char@tie{}*@var{css_filename})
Creates an output stream referring to the file descriptor @code{@var{fd}},
styled with the file @code{@var{css_filename}} if possible.

@code{@var{filename}} is used only for error messages.

@code{@var{tty_control}} specifies the amount of control to take over the
underlying tty.

Note: The resulting stream must be closed before @code{@var{fd}} can be
closed.
@end deftypefn

@node The html_styled_ostream class
@subsubsection The @code{html_styled_ostream} class

The @code{html_styled_ostream} class supports styled output to any
destination, in HTML syntax.  Its type is @samp{html_styled_ostream_t}.
It is a subclass of @samp{styled_ostream_t}.

It can be instantiated through this function:

@deftypefn Function html_styled_ostream_t html_styled_ostream_create (ostream_t@tie{}@var{destination}, const@tie{}char@tie{}*@var{css_filename})
Creates an output stream that takes input in the UTF-8 encoding and
writes it in HTML form on @code{@var{destination}}, styled with the file
@code{@var{css_filename}}.

Note: The resulting stream must be closed before @code{@var{destination}}
can be closed.
@end deftypefn

@node The noop_styled_ostream class
@subsubsection The @code{noop_styled_ostream} class

The @code{noop_styled_ostream} class supports the styled output operations
to any destination.  The text is output to the given destination; the
styling operations, however, do nothing.  Its type is
@samp{noop_styled_ostream_t}.  It is a subclass of @samp{styled_ostream_t}.

It can be instantiated through this function:

@deftypefn Function noop_styled_ostream_t noop_styled_ostream_create (ostream_t@tie{}@var{destination}, bool@tie{}@var{pass_ownership})
Creates an output stream that delegates to @code{@var{destination}} and
that supports the styling operations as no-ops.

If @code{@var{pass_ownership}} is @code{true}, closing the resulting
stream will automatically close the @code{@var{destination}}.

Note: If @code{@var{pass_ownership}} is @code{false}, the resulting stream
must be closed before @code{@var{destination}} can be closed.
@end deftypefn

@node Debugging the styling code
@section Debugging the text styling support

@cindex Debugging
If you want to understand which output of your program is associated with
which CSS classes, the simplest way is as follows:

@enumerate
@item
Run the program with the command-line option @code{--color=html},
redirecting the output to a file.
@item
Then inspect this output.  Text regions associated with a CSS class are
surrounded by @code{<span class="@var{css-class}">}...@code{</span>}.
@end enumerate

@node What to document
@section Documenting the text styling support

To make the text styling support available to the end user of your
package, the following need to be documented:
@itemize @bullet
@item
The command-line options.  This typically needs to be done in several
places: in the @samp{--help} output, in the @code{man} pages (if present),
and in the documentation.
@item
Which programs support @samp{--color=test}?
@item
The list of CSS classes and their meaning.  This is necessary, so that
the user can create their own style file; the CSS classes are part of the
selectors in the CSS rules.
@item
The location of the default style file.  This is a convenience, so that
the user, when creating their own style file, can start from the default
one.
@item
The environment variable, called @code{@var{style_file_envvar}} above,
that, when set to a non-empty value, specifies the style file to use.
@end itemize

@node Licenses
@appendix Licenses
@cindex Licenses

The files of this package are covered by the licenses indicated in each
particular file or directory.  Here is a summary:

@itemize @bullet
@item
The @code{libtextstyle} library and the example programs
are covered by the GNU General Public License (GPL).
A copy of the license is included in @ref{GNU GPL}.

@item
This manual is free documentation.  It is dually licensed under the
GNU FDL and the GNU GPL.  This means that you can redistribute this
manual under either of these two licenses, at your choice.
@*
This manual is covered by the GNU FDL.  Permission is granted to copy,
distribute and/or modify this document under the terms of the
GNU Free Documentation License (FDL), either version 1.2 of the
License, or (at your option) any later version published by the
Free Software Foundation (FSF); with no Invariant Sections, with no
Front-Cover Text, and with no Back-Cover Texts.
A copy of the license is included in @ref{GNU FDL}.
@*
This manual is covered by the GNU GPL.  You can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL), either
version 3 of the License, or (at your option) any later version published
by the Free Software Foundation (FSF).
A copy of the license is included in @ref{GNU GPL}.
@end itemize

@menu
* GNU GPL::                     GNU General Public License
* GNU FDL::                     GNU Free Documentation License
@end menu

@page
@node GNU GPL
@appendixsec GNU GENERAL PUBLIC LICENSE
@cindex GPL, GNU General Public License
@cindex License, GNU GPL
@include gpl.texi
@page
@node GNU FDL
@appendixsec GNU Free Documentation License
@cindex FDL, GNU Free Documentation License
@cindex License, GNU FDL
@include fdl.texi

@node Function Index
@unnumbered Function Index

@printindex fn

@node Variable Index
@unnumbered Variable Index

@printindex vr

@node Index
@unnumbered General Index

@printindex cp

@bye

@c Local variables:
@c texinfo-column-for-description: 32
@c End:
