3 * Configurable terminal colour support
5 * (c) 2024 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the mLib utilities library.
12 * mLib is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Library General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
17 * mLib is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 #ifndef MLIB_TTYCOLOUR_H
29 #define MLIB_TTYCOLOUR_H
35 /*----- Header files ------------------------------------------------------*/
37 #ifndef MLIB_GPRINTF_H
49 /*----- Functions provided ------------------------------------------------*/
51 struct ttycolour_style {
52 /* Table of style tokens and their defaults. The table is terminated with
53 * a null @tok@ pointer.
56 const char *tok; /* style token name */
57 const struct tty_attrlist *dflt; /* default attribute value */
60 /* Machinery for building the constants and tables.
62 * The caller should define the styles it supports in a macro taking two
63 * arguments, conventionally named @_st@ and @_@. It should apply the second
64 * argument, @_@, to quadruples @(_st, tag, tok, dflt)@, where @_st@ is the
65 * argument provided, @tag@ is a constant-name suffix, @tok@ is a string
66 * naming the capability token to be read from the user string, and @dflt@ is
67 * the default attribute for the style.
70 /* --- @TTYCOLOUR_DEFENUM@ --- *
72 * Arguments: @styles@ = style-list macro, as described above
73 * @pre@ = prefix for constant names
75 * Use: Define constants @pretag@ for each @tag@ listed in the list
76 * macro @styles@, having sequential values starting from zero,
77 * in the same order as the list macro.
80 #define TTYCOLOUR__ENUMPREFIX(pre) pre
81 #define TTYCOLOUR__FULLENUM(_st, tag) GLUE(TTYCOLOUR__ENUMPREFIX _st, tag)
83 #define TTYCOLOUR__DEFENUM(_st, tag, tok, dflt) \
84 TTYCOLOUR__FULLENUM(_st, tag),
85 #define TTYCOLOUR_DEFENUM(styles, pre) enum { \
86 styles((pre), TTYCOLOUR__DEFENUM) \
90 /* --- @TTYCOLOUR_INITTAB@ --- *
92 * Arguments: @styles@ = style-list macro, as described above
94 * Use: Expand to an initializer for a table of
95 * @struct ttycolour_style@ values. The table entries
96 * correspond one-for-one with the entries in the list macro, in
100 #define TTYCOLOUR__DEFENTRY(_st, tag, tok, dflt) { tok, dflt },
101 #define TTYCOLOUR_INITTAB(styles) { \
102 styles((pre), TTYCOLOUR__DEFENTRY) \
106 /* --- @ttycolour_enablep@ --- *
108 * Arguments: @unsigned f@ = flags
110 * Returns: Nonzero if colours should be applied to output, otherwise
113 * Use: This function determines whether it's generally a good idea
114 * to produce output in pretty colours. Set @TCEF_TTY@ if the
115 * output stream is -- or should be considered to be --
116 * interactive (e.g., according to @isatty@); set @TCEF_DFLT@ if
117 * the application prefers to produce coloured output if
120 * The detailed behaviour is as follows. (Since the purpose of
121 * this function is to abide by common conventions and to be
122 * convenient for users, these details may change in future.)
124 * * If the %|NO_COLOR|% environment variable is non-empty,
125 * colour is disabled (%%\url{https://no-color.org/}%%).
127 * * If the %|TERM|% variable is set to %|dumb|%, then colour
128 * is disabled (Emacs).
130 * * If the %|FORCE_COLOR|% environment variable is non-empty,
131 * then colour is enabled, unless the value is 0, in which
132 * case colour is disabled (apparently from the Node
133 * community, %%\url{%%https://force-color.org/}%% and
134 * %%\url{https://nodejs.org/api/tty.html#writestreamgetcolordepthenv}%%).
136 * * If the %|CLICOLOR_FORCE|% environment variable is
137 * non-empty, then colour is enabled (apparently from
138 * Mac OS, (%%\url{http://bixense.com/clicolors/}%%).
140 * * If the @TCEF_TTY@ flag is clear, then colour is disabled.
142 * * If the @TCEF_DFLT@ flag is set, then colour is enabled.
144 * * If the %|CLICOLOR|% environment variable is non-empty,
145 * then colour is enabled (again, apparently from Mac OS,
146 * (%%\url{http://bixense.com/clicolors/}%%).
148 * * Otherwise, colour is disabled.
151 #define TCEF_TTY 1u /* output is interactive */
152 #define TCEF_DFLT 2u /* turn on by default */
153 extern int ttycolour_enablep(unsigned /*f*/);
155 /* --- @ttycolour_config@ --- *
157 * Arguments: @ttycolour_attr *attr@ = pointer to attribute table
158 * @const char *user@ = the user-specified string or environment
160 * @unsigned f@ = flags (@TCIF_...@)
161 * @const struct ttycolour_style *tab@ = table initialized using
162 * @TTYCOLOUR_INITTAB@
164 * Returns: Zero on success, %$-1$% on error.
166 * Use: Initialize the table @attr@ with the attributes configured
167 * for the styles defined in the table.
169 * A user string is determined. If @f@ has @TCIF_GETENV@ set,
170 * then the user string is the value of the environment variable
171 * named by @user@; otherwise, the user string is @user@ itself.
172 * The user string consists of a sequence of capability
173 * defintiions separated by colons. Each definition has the
174 * form %%\syntax{<tok>"="<codes>}%%,
177 #define TCIF_GETENV 1u
178 #define TCIF_REPORT 2u
179 extern int ttycolour_config(struct tty_attr */*attr*/,
180 const char */*user*/, unsigned /*f*/,
182 const struct ttycolour_style */*tab*/);
184 /*----- That's all, folks -------------------------------------------------*/