1 /* Color and styling handling.
2 Copyright (C) 2006-2008 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
28 #include <sys/types.h>
31 #include "term-ostream.h"
33 #include "relocatable.h"
35 #include "concat-filename.h"
38 /* Whether to output a test page. */
42 enum color_option color_mode = color_tty;
44 /* Style to use when coloring. */
45 const char *style_file_name;
47 /* --color argument handling. Return an error indicator. */
49 handle_color_option (const char *option)
53 if (strcmp (option, "never") == 0 || strcmp (option, "no") == 0)
54 color_mode = color_no;
55 else if (strcmp (option, "auto") == 0 || strcmp (option, "tty") == 0)
56 color_mode = color_tty;
57 else if (strcmp (option, "always") == 0 || strcmp (option, "yes") == 0)
58 color_mode = color_yes;
59 else if (strcmp (option, "html") == 0)
60 color_mode = color_html;
61 else if (strcmp (option, "test") == 0)
62 color_test_mode = true;
65 fprintf (stderr, "invalid --color argument: %s\n", option);
70 /* --color is equivalent to --color=yes. */
71 color_mode = color_yes;
75 /* --style argument handling. */
77 handle_style_option (const char *option)
79 style_file_name = option;
82 /* Print a color test page. */
86 /* Code copied from test-term-ostream.c. */
87 static struct { const char *name; term_color_t c; int r; int g; int b; }
90 { "black", -2, 0, 0, 0 },
91 { "blue", -2, 0, 0, 255 },
92 { "green", -2, 0, 255, 0 },
93 { "cyan", -2, 0, 255, 255 },
94 { "red", -2, 255, 0, 0 },
95 { "magenta", -2, 255, 0, 255 },
96 { "yellow", -2, 255, 255, 0 },
97 { "white", -2, 255, 255, 255 },
98 { "default", COLOR_DEFAULT }
100 term_ostream_t stream;
103 stream = term_ostream_create (1, "stdout");
105 for (i = 0; i < 8; i++)
107 term_ostream_rgb_to_color (stream, colors[i].r, colors[i].g, colors[i].b);
109 ostream_write_str (stream, "Colors (foreground/background):\n");
110 ostream_write_str (stream, " ");
111 for (col = 0; col <= 8; col++)
113 const char *name = colors[col].name;
114 ostream_write_str (stream, "|");
115 ostream_write_str (stream, name);
116 ostream_write_mem (stream, " ", 7 - strlen (name));
118 ostream_write_str (stream, "\n");
119 for (row = 0; row <= 8; row++)
121 const char *name = colors[row].name;
122 ostream_write_str (stream, name);
123 ostream_write_mem (stream, " ", 7 - strlen (name));
124 for (col = 0; col <= 8; col++)
126 term_color_t row_color = colors[row].c;
127 term_color_t col_color = colors[col].c;
129 ostream_write_str (stream, "|");
130 term_ostream_set_color (stream, row_color);
131 term_ostream_set_bgcolor (stream, col_color);
132 if (!(term_ostream_get_color (stream) == row_color
133 && term_ostream_get_bgcolor (stream) == col_color))
135 ostream_write_str (stream, " Words ");
136 term_ostream_set_color (stream, COLOR_DEFAULT);
137 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
138 if (!(term_ostream_get_color (stream) == COLOR_DEFAULT
139 && term_ostream_get_bgcolor (stream) == COLOR_DEFAULT))
142 ostream_write_str (stream, "\n");
144 ostream_write_str (stream, "\n");
146 ostream_write_str (stream, "Colors (hue/saturation):\n");
147 /* Hue from 0 to 1. */
148 for (row = 0; row <= 17; row++)
150 ostream_write_str (stream, row == 0 ? "red: " : " ");
151 for (col = 0; col <= 64; col++)
154 int b = (int) (255.0f / 64.0f * col + 0.5f);
155 int g = b + (int) (row / 17.0f * (r - b) + 0.5f);
156 term_color_t c = term_ostream_rgb_to_color (stream, r, g, b);
157 term_ostream_set_bgcolor (stream, c);
158 ostream_write_str (stream, " ");
159 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
161 ostream_write_str (stream, "\n");
163 /* Hue from 1 to 2. */
164 for (row = 17; row >= 0; row--)
166 ostream_write_str (stream, row == 17 ? "yellow: " : " ");
167 for (col = 0; col <= 64; col++)
170 int b = (int) (255.0f / 64.0f * col + 0.5f);
171 int r = b + (int) (row / 17.0f * (g - b) + 0.5f);
172 term_color_t c = term_ostream_rgb_to_color (stream, r, g, b);
173 term_ostream_set_bgcolor (stream, c);
174 ostream_write_str (stream, " ");
175 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
177 ostream_write_str (stream, "\n");
179 /* Hue from 2 to 3. */
180 for (row = 0; row <= 17; row++)
182 ostream_write_str (stream, row == 0 ? "green: " : " ");
183 for (col = 0; col <= 64; col++)
186 int r = (int) (255.0f / 64.0f * col + 0.5f);
187 int b = r + (int) (row / 17.0f * (g - r) + 0.5f);
188 term_color_t c = term_ostream_rgb_to_color (stream, r, g, b);
189 term_ostream_set_bgcolor (stream, c);
190 ostream_write_str (stream, " ");
191 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
193 ostream_write_str (stream, "\n");
195 /* Hue from 3 to 4. */
196 for (row = 17; row >= 0; row--)
198 ostream_write_str (stream, row == 17 ? "cyan: " : " ");
199 for (col = 0; col <= 64; col++)
202 int r = (int) (255.0f / 64.0f * col + 0.5f);
203 int g = r + (int) (row / 17.0f * (b - r) + 0.5f);
204 term_color_t c = term_ostream_rgb_to_color (stream, r, g, b);
205 term_ostream_set_bgcolor (stream, c);
206 ostream_write_str (stream, " ");
207 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
209 ostream_write_str (stream, "\n");
211 /* Hue from 4 to 5. */
212 for (row = 0; row <= 17; row++)
214 ostream_write_str (stream, row == 0 ? "blue: " : " ");
215 for (col = 0; col <= 64; col++)
218 int g = (int) (255.0f / 64.0f * col + 0.5f);
219 int r = g + (int) (row / 17.0f * (b - g) + 0.5f);
220 term_color_t c = term_ostream_rgb_to_color (stream, r, g, b);
221 term_ostream_set_bgcolor (stream, c);
222 ostream_write_str (stream, " ");
223 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
225 ostream_write_str (stream, "\n");
227 /* Hue from 5 to 6. */
228 for (row = 17; row >= 0; row--)
230 ostream_write_str (stream, row == 17 ? "magenta: " :
231 row == 0 ? "red: " : " ");
232 for (col = 0; col <= 64; col++)
235 int g = (int) (255.0f / 64.0f * col + 0.5f);
236 int b = g + (int) (row / 17.0f * (r - g) + 0.5f);
237 term_color_t c = term_ostream_rgb_to_color (stream, r, g, b);
238 term_ostream_set_bgcolor (stream, c);
239 ostream_write_str (stream, " ");
240 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
242 ostream_write_str (stream, "\n");
244 ostream_write_str (stream, "\n");
246 ostream_write_str (stream, "Weights:\n");
247 term_ostream_set_weight (stream, WEIGHT_NORMAL);
248 if (term_ostream_get_weight (stream) != WEIGHT_NORMAL)
250 ostream_write_str (stream, "normal, ");
251 term_ostream_set_weight (stream, WEIGHT_BOLD);
252 if (term_ostream_get_weight (stream) != WEIGHT_BOLD)
254 ostream_write_str (stream, "bold, ");
255 term_ostream_set_weight (stream, WEIGHT_DEFAULT);
256 if (term_ostream_get_weight (stream) != WEIGHT_DEFAULT)
258 ostream_write_str (stream, "default \n");
259 ostream_write_str (stream, "\n");
261 ostream_write_str (stream, "Postures:\n");
262 term_ostream_set_posture (stream, POSTURE_NORMAL);
263 if (term_ostream_get_posture (stream) != POSTURE_NORMAL)
265 ostream_write_str (stream, "normal, ");
266 term_ostream_set_posture (stream, POSTURE_ITALIC);
267 if (term_ostream_get_posture (stream) != POSTURE_ITALIC)
269 ostream_write_str (stream, "italic, ");
270 term_ostream_set_posture (stream, POSTURE_DEFAULT);
271 if (term_ostream_get_posture (stream) != POSTURE_DEFAULT)
273 ostream_write_str (stream, "default \n");
274 ostream_write_str (stream, "\n");
276 ostream_write_str (stream, "Text decorations:\n");
277 term_ostream_set_underline (stream, UNDERLINE_OFF);
278 if (term_ostream_get_underline (stream) != UNDERLINE_OFF)
280 ostream_write_str (stream, "normal, ");
281 term_ostream_set_underline (stream, UNDERLINE_ON);
282 if (term_ostream_get_underline (stream) != UNDERLINE_ON)
284 ostream_write_str (stream, "underlined, ");
285 term_ostream_set_underline (stream, UNDERLINE_DEFAULT);
286 if (term_ostream_get_underline (stream) != UNDERLINE_DEFAULT)
288 ostream_write_str (stream, "default \n");
289 ostream_write_str (stream, "\n");
291 ostream_write_str (stream, "Colors (foreground) mixed with attributes:\n");
292 for (row = 0; row <= 8; row++)
294 const char *name = colors[row].name;
295 ostream_write_str (stream, name);
296 ostream_write_mem (stream, " ", 7 - strlen (name));
297 term_ostream_set_color (stream, colors[row].c);
298 ostream_write_str (stream, "|normal|");
299 term_ostream_set_weight (stream, WEIGHT_BOLD);
300 ostream_write_str (stream, "bold");
301 term_ostream_set_weight (stream, WEIGHT_NORMAL);
302 ostream_write_str (stream, "|normal|");
303 term_ostream_set_posture (stream, POSTURE_ITALIC);
304 ostream_write_str (stream, "italic");
305 term_ostream_set_posture (stream, POSTURE_NORMAL);
306 ostream_write_str (stream, "|normal|");
307 term_ostream_set_underline (stream, UNDERLINE_ON);
308 ostream_write_str (stream, "underlined");
309 term_ostream_set_underline (stream, UNDERLINE_OFF);
310 ostream_write_str (stream, "|normal|");
311 term_ostream_set_color (stream, COLOR_DEFAULT);
312 ostream_write_str (stream, "\n ");
313 term_ostream_set_color (stream, colors[row].c);
314 ostream_write_str (stream, "|normal|");
315 term_ostream_set_weight (stream, WEIGHT_BOLD);
316 term_ostream_set_posture (stream, POSTURE_ITALIC);
317 ostream_write_str (stream, "bold+italic");
318 term_ostream_set_weight (stream, WEIGHT_NORMAL);
319 term_ostream_set_posture (stream, POSTURE_NORMAL);
320 ostream_write_str (stream, "|normal|");
321 term_ostream_set_weight (stream, WEIGHT_BOLD);
322 term_ostream_set_underline (stream, UNDERLINE_ON);
323 ostream_write_str (stream, "bold+underl");
324 term_ostream_set_weight (stream, WEIGHT_NORMAL);
325 term_ostream_set_underline (stream, UNDERLINE_OFF);
326 ostream_write_str (stream, "|normal|");
327 term_ostream_set_posture (stream, POSTURE_ITALIC);
328 term_ostream_set_underline (stream, UNDERLINE_ON);
329 ostream_write_str (stream, "italic+underl");
330 term_ostream_set_posture (stream, POSTURE_NORMAL);
331 term_ostream_set_underline (stream, UNDERLINE_OFF);
332 ostream_write_str (stream, "|normal|");
333 term_ostream_set_color (stream, COLOR_DEFAULT);
334 ostream_write_str (stream, "\n");
336 ostream_write_str (stream, "\n");
338 ostream_write_str (stream, "Colors (background) mixed with attributes:\n");
339 for (row = 0; row <= 8; row++)
341 const char *name = colors[row].name;
342 ostream_write_str (stream, name);
343 ostream_write_mem (stream, " ", 7 - strlen (name));
344 term_ostream_set_bgcolor (stream, colors[row].c);
345 ostream_write_str (stream, "|normal|");
346 term_ostream_set_weight (stream, WEIGHT_BOLD);
347 ostream_write_str (stream, "bold");
348 term_ostream_set_weight (stream, WEIGHT_NORMAL);
349 ostream_write_str (stream, "|normal|");
350 term_ostream_set_posture (stream, POSTURE_ITALIC);
351 ostream_write_str (stream, "italic");
352 term_ostream_set_posture (stream, POSTURE_NORMAL);
353 ostream_write_str (stream, "|normal|");
354 term_ostream_set_underline (stream, UNDERLINE_ON);
355 ostream_write_str (stream, "underlined");
356 term_ostream_set_underline (stream, UNDERLINE_OFF);
357 ostream_write_str (stream, "|normal|");
358 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
359 ostream_write_str (stream, "\n ");
360 term_ostream_set_bgcolor (stream, colors[row].c);
361 ostream_write_str (stream, "|normal|");
362 term_ostream_set_weight (stream, WEIGHT_BOLD);
363 term_ostream_set_posture (stream, POSTURE_ITALIC);
364 ostream_write_str (stream, "bold+italic");
365 term_ostream_set_weight (stream, WEIGHT_NORMAL);
366 term_ostream_set_posture (stream, POSTURE_NORMAL);
367 ostream_write_str (stream, "|normal|");
368 term_ostream_set_weight (stream, WEIGHT_BOLD);
369 term_ostream_set_underline (stream, UNDERLINE_ON);
370 ostream_write_str (stream, "bold+underl");
371 term_ostream_set_weight (stream, WEIGHT_NORMAL);
372 term_ostream_set_underline (stream, UNDERLINE_OFF);
373 ostream_write_str (stream, "|normal|");
374 term_ostream_set_posture (stream, POSTURE_ITALIC);
375 term_ostream_set_underline (stream, UNDERLINE_ON);
376 ostream_write_str (stream, "italic+underl");
377 term_ostream_set_posture (stream, POSTURE_NORMAL);
378 term_ostream_set_underline (stream, UNDERLINE_OFF);
379 ostream_write_str (stream, "|normal|");
380 term_ostream_set_bgcolor (stream, COLOR_DEFAULT);
381 ostream_write_str (stream, "\n");
383 ostream_write_str (stream, "\n");
385 ostream_free (stream);
388 /* Lookup the location of the style file. */
390 style_file_lookup (const char *file_name)
392 if (!IS_PATH_WITH_DIR (file_name))
394 /* It's a file name without a directory specification.
395 If it does not exist in the current directory... */
398 if (stat (file_name, &statbuf) < 0)
400 /* ... but it exists in the styles installation location... */
401 const char *gettextstylesdir = relocate (GETTEXTDATADIR "/styles");
402 char *possible_file_name =
403 xconcatenated_filename (gettextstylesdir, file_name, NULL);
405 if (stat (possible_file_name, &statbuf) >= 0)
407 /* ... then use the file in the styles installation directory. */
408 return possible_file_name;
410 free (possible_file_name);
413 /* Let the CSS library show a warning. */
418 /* Assign a default value to style_file_name if necessary. */
420 style_file_prepare ()
422 if (style_file_name == NULL)
424 const char *user_preference = getenv ("PO_STYLE");
426 if (user_preference != NULL && user_preference[0] != '\0')
427 style_file_name = style_file_lookup (xstrdup (user_preference));
430 const char *gettextdatadir;
432 /* Make it possible to override the po-default.css location. This is
433 necessary for running the testsuite before "make install". */
434 gettextdatadir = getenv ("GETTEXTDATADIR");
435 if (gettextdatadir == NULL || gettextdatadir[0] == '\0')
436 gettextdatadir = relocate (GETTEXTDATADIR);
439 xconcatenated_filename (gettextdatadir, "styles/po-default.css",
444 style_file_name = style_file_lookup (style_file_name);