GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-6c790bf5c0
parser_html.c
Go to the documentation of this file.
1 /*!
2  \file lib/gis/parser_html.c
3 
4  \brief GIS Library - Argument parsing functions (HTML output)
5 
6  (C) 2001-2024 by the GRASS Development Team
7 
8  This program is free software under the GNU General Public License
9  (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11  \author Original author CERL
12  */
13 
14 #include <stdio.h>
15 #include <string.h>
16 
17 #include <grass/gis.h>
18 #include <grass/glocale.h>
19 
20 #include "parser_local_proto.h"
21 
22 static void print_escaped_for_html(FILE *, const char *);
23 static void print_escaped_for_html_options(FILE *, const char *);
24 static void print_escaped_for_html_keywords(FILE *, const char *);
25 
26 /*!
27  \brief Print module usage description in HTML format.
28  */
29 void G__usage_html(void)
30 {
31  struct Option *opt;
32  struct Flag *flag;
33  const char *type;
34  int new_prompt = 0;
35 
36  new_prompt = G__uses_new_gisprompt();
37 
38  if (!st->pgm_name) /* v.dave && r.michael */
39  st->pgm_name = G_program_name();
40  if (!st->pgm_name)
41  st->pgm_name = "??";
42 
43  fprintf(
44  stdout,
45  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
46  fprintf(stdout, "<html>\n<head>\n");
47  fprintf(stdout, " <meta http-equiv=\"Content-Type\" content=\"text/html; "
48  "charset=utf-8\">\n");
49  fprintf(stdout,
50  " <meta name=\"Author\" content=\"GRASS Development Team\">\n");
51  fprintf(stdout,
52  " <meta http-equiv=\"content-language\" content=\"en-us\">\n");
53  fprintf(stdout, " <meta name=\"viewport\" content=\"width=device-width, "
54  "initial-scale=1\">\n");
55  fprintf(stdout, " <title>%s - GRASS GIS manual</title>\n", st->pgm_name);
56  fprintf(stdout, " <meta name=\"description\" content=\"%s", st->pgm_name);
57  if (st->module_info.description)
58  fprintf(stdout, ": %s\">", st->module_info.description);
59  else
60  fprintf(stderr, "<%s.html> is missing the description", st->pgm_name);
61  fprintf(stdout, "\n");
62  if (st->module_info.keywords) {
63  fprintf(stdout, " <meta name=\"keywords\" content=\"");
64  G__print_keywords(stdout, NULL, FALSE);
65  fprintf(stdout, "\">");
66  fprintf(stdout, "\n");
67  }
68  fprintf(stdout, " <link rel=\"stylesheet\" href=\"grassdocs.css\" "
69  "type=\"text/css\">\n");
70  fprintf(stdout, "</head>\n");
71  fprintf(stdout, "<body bgcolor=\"white\">\n");
72  fprintf(stdout, "<div id=\"container\">\n\n");
73  fprintf(stdout, "<a href=\"index.html\"><img src=\"grass_logo.png\" "
74  "alt=\"GRASS logo\"></a>\n");
75  fprintf(stdout, "<hr class=\"header\">\n\n");
76  fprintf(stdout, "<h2>%s</h2>\n", _("NAME"));
77  fprintf(stdout, "<em><b>%s</b></em> ", st->pgm_name);
78 
79  if (st->module_info.label || st->module_info.description)
80  fprintf(stdout, " - ");
81 
82  if (st->module_info.label)
83  fprintf(stdout, "%s<BR>\n", st->module_info.label);
84 
85  if (st->module_info.description)
86  fprintf(stdout, "%s\n", st->module_info.description);
87 
88  fprintf(stdout, "<h2>%s</h2>\n", _("KEYWORDS"));
89  if (st->module_info.keywords) {
90  G__print_keywords(stdout, print_escaped_for_html_keywords, FALSE);
91  fprintf(stdout, "\n");
92  }
93  fprintf(stdout, "<h2>%s</h2>\n", _("SYNOPSIS"));
94  fprintf(stdout, "<div id=\"name\"><b>%s</b><br></div>\n", st->pgm_name);
95  fprintf(stdout, "<b>%s --help</b><br>\n", st->pgm_name);
96 
97  fprintf(stdout, "<div id=\"synopsis\"><b>%s</b>", st->pgm_name);
98 
99  /* print short version first */
100  if (st->n_flags) {
101  flag = &st->first_flag;
102  fprintf(stdout, " [-<b>");
103  while (flag != NULL) {
104  fprintf(stdout, "%c", flag->key);
105  flag = flag->next_flag;
106  }
107  fprintf(stdout, "</b>] ");
108  }
109  else
110  fprintf(stdout, " ");
111 
112  if (st->n_opts) {
113  opt = &st->first_option;
114 
115  while (opt != NULL) {
116  if (opt->key_desc != NULL)
117  type = opt->key_desc;
118  else
119  switch (opt->type) {
120  case TYPE_INTEGER:
121  type = "integer";
122  break;
123  case TYPE_DOUBLE:
124  type = "float";
125  break;
126  case TYPE_STRING:
127  type = "string";
128  break;
129  default:
130  type = "string";
131  break;
132  }
133  if (!opt->required)
134  fprintf(stdout, " [");
135  fprintf(stdout, "<b>%s</b>=<em>%s</em>", opt->key, type);
136  if (opt->multiple) {
137  fprintf(stdout, "[,<i>%s</i>,...]", type);
138  }
139  if (!opt->required)
140  fprintf(stdout, "] ");
141 
142  opt = opt->next_opt;
143  fprintf(stdout, " ");
144  }
145  }
146  if (new_prompt)
147  fprintf(stdout, " [--<b>overwrite</b>] ");
148 
149  fprintf(stdout, " [--<b>help</b>] ");
150  fprintf(stdout, " [--<b>verbose</b>] ");
151  fprintf(stdout, " [--<b>quiet</b>] ");
152  fprintf(stdout, " [--<b>ui</b>] ");
153 
154  fprintf(stdout, "\n</div>\n");
155 
156  /* now long version */
157  fprintf(stdout, "\n");
158  fprintf(stdout, "<div id=\"flags\">\n");
159  fprintf(stdout, "<h3>%s:</h3>\n", _("Flags"));
160  fprintf(stdout, "<dl>\n");
161  if (st->n_flags) {
162  flag = &st->first_flag;
163  while (st->n_flags && flag != NULL) {
164  fprintf(stdout, "<dt><b>-%c</b></dt>\n", flag->key);
165 
166  if (flag->label) {
167  fprintf(stdout, "<dd>");
168  fprintf(stdout, "%s", flag->label);
169  fprintf(stdout, "</dd>\n");
170  }
171 
172  if (flag->description) {
173  fprintf(stdout, "<dd>");
174  fprintf(stdout, "%s", flag->description);
175  fprintf(stdout, "</dd>\n");
176  }
177 
178  flag = flag->next_flag;
179  fprintf(stdout, "\n");
180  }
181  }
182  if (new_prompt) {
183  fprintf(stdout, "<dt><b>--overwrite</b></dt>\n");
184  fprintf(stdout, "<dd>%s</dd>\n",
185  _("Allow output files to overwrite existing files"));
186  }
187  /* these flags are always available */
188  fprintf(stdout, "<dt><b>--help</b></dt>\n");
189  fprintf(stdout, "<dd>%s</dd>\n", _("Print usage summary"));
190 
191  fprintf(stdout, "<dt><b>--verbose</b></dt>\n");
192  fprintf(stdout, "<dd>%s</dd>\n", _("Verbose module output"));
193 
194  fprintf(stdout, "<dt><b>--quiet</b></dt>\n");
195  fprintf(stdout, "<dd>%s</dd>\n", _("Quiet module output"));
196 
197  fprintf(stdout, "<dt><b>--ui</b></dt>\n");
198  fprintf(stdout, "<dd>%s</dd>\n", _("Force launching GUI dialog"));
199 
200  fprintf(stdout, "</dl>\n");
201  fprintf(stdout, "</div>\n");
202 
203  fprintf(stdout, "\n");
204  fprintf(stdout, "<div id=\"parameters\">\n");
205  if (st->n_opts) {
206  opt = &st->first_option;
207  fprintf(stdout, "<h3>%s:</h3>\n", _("Parameters"));
208  fprintf(stdout, "<dl>\n");
209 
210  while (opt != NULL) {
211  /* TODO: make this a enumeration type? */
212  if (opt->key_desc != NULL)
213  type = opt->key_desc;
214  else
215  switch (opt->type) {
216  case TYPE_INTEGER:
217  type = "integer";
218  break;
219  case TYPE_DOUBLE:
220  type = "float";
221  break;
222  case TYPE_STRING:
223  type = "string";
224  break;
225  default:
226  type = "string";
227  break;
228  }
229  fprintf(stdout, "<dt><b>%s</b>=<em>%s", opt->key, type);
230  if (opt->multiple) {
231  fprintf(stdout, "[,<i>%s</i>,...]", type);
232  }
233  fprintf(stdout, "</em>");
234  if (opt->required) {
235  fprintf(stdout, "&nbsp;<b>[required]</b>");
236  }
237  fprintf(stdout, "</dt>\n");
238 
239  if (opt->label) {
240  fprintf(stdout, "<dd>");
241  print_escaped_for_html(stdout, opt->label);
242  fprintf(stdout, "</dd>\n");
243  }
244  if (opt->description) {
245  fprintf(stdout, "<dd>");
246  print_escaped_for_html(stdout, opt->description);
247  fprintf(stdout, "</dd>\n");
248  }
249 
250  if (opt->options) {
251  fprintf(stdout, "<dd>%s: <em>", _("Options"));
252  print_escaped_for_html_options(stdout, opt->options);
253  fprintf(stdout, "</em></dd>\n");
254  }
255 
256  if (opt->def) {
257  fprintf(stdout, "<dd>%s: <em>", _("Default"));
258  print_escaped_for_html(stdout, opt->def);
259  fprintf(stdout, "</em></dd>\n");
260  }
261 
262  if (opt->descs) {
263  int i = 0;
264 
265  while (opt->opts[i]) {
266  if (opt->descs[i]) {
267  fprintf(stdout, "<dd><b>");
268  if (opt->gisprompt) {
269  char *thumbnails = NULL;
270 
271  if (strcmp(opt->gisprompt,
272  "old,colortable,colortable") == 0)
273  thumbnails = "colortables";
274  else if (strcmp(opt->gisprompt,
275  "old,barscale,barscale") == 0)
276  thumbnails = "barscales";
277  else if (strcmp(opt->gisprompt,
278  "old,northarrow,northarrow") == 0)
279  thumbnails = "northarrows";
280 
281  if (thumbnails)
282  fprintf(stdout,
283  "<img height=\"12\" "
284  "style=\"max-width: 80;\" "
285  "src=\"%s/%s.png\" alt=\"%s\"> ",
286  thumbnails, opt->opts[i], opt->opts[i]);
287  }
288  print_escaped_for_html(stdout, opt->opts[i]);
289  fprintf(stdout, "</b>: ");
290  print_escaped_for_html(stdout, opt->descs[i]);
291  fprintf(stdout, "</dd>\n");
292  }
293  i++;
294  }
295  }
296 
297  opt = opt->next_opt;
298  fprintf(stdout, "\n");
299  }
300  fprintf(stdout, "</dl>\n");
301  }
302  fprintf(stdout, "</div>\n");
303 
304  fprintf(stdout, "</div> <!-- end container -->\n");
305  fprintf(stdout, "</body>\n</html>\n");
306 }
307 
308 /*!
309  * \brief Format text for HTML output
310  */
311 #define do_escape(c, escaped) \
312  case c: \
313  fputs(escaped, f); \
314  break
315 void print_escaped_for_html(FILE *f, const char *str)
316 {
317  const char *s;
318 
319  for (s = str; *s; s++) {
320  switch (*s) {
321  do_escape('&', "&amp;");
322  do_escape('<', "&lt;");
323  do_escape('>', "&gt;");
324  do_escape('\n', "<br>");
325  do_escape('\t', "&nbsp;&nbsp;&nbsp;&nbsp;");
326  default:
327  fputc(*s, f);
328  }
329  }
330 }
331 
332 void print_escaped_for_html_options(FILE *f, const char *str)
333 {
334  const char *s;
335 
336  for (s = str; *s; s++) {
337  switch (*s) {
338  do_escape('&', "&amp;");
339  do_escape('<', "&lt;");
340  do_escape('>', "&gt;");
341  do_escape('\n', "<br>");
342  do_escape('\t', "&nbsp;&nbsp;&nbsp;&nbsp;");
343  do_escape(',', ", ");
344  default:
345  fputc(*s, f);
346  }
347  }
348 }
349 
350 void print_escaped_for_html_keywords(FILE *f, const char *str)
351 {
352  /* generate HTML links */
353 
354  /* HTML link only for second keyword */
355  if (st->n_keys > 1 && strcmp(st->module_info.keywords[1], str) == 0) {
356 
357  const char *s;
358 
359  /* TODO: fprintf(f, _("topic: ")); */
360  fprintf(f, "<a href=\"topic_");
361  for (s = str; *s; s++) {
362  switch (*s) {
363  do_escape(' ', "_");
364  default:
365  fputc(*s, f);
366  }
367  }
368  fprintf(f, ".html\">%s</a>", str);
369  }
370  else { /* first and other than second keyword */
371  if (st->n_keys > 0 && strcmp(st->module_info.keywords[0], str) == 0) {
372  /* command family */
373  const char *s;
374 
375  fprintf(f, "<a href=\"");
376  for (s = str; *s; s++) {
377  switch (*s) {
378  do_escape(' ', "_");
379  default:
380  fputc(*s, f);
381  }
382  }
383  fprintf(f, ".html\">%s</a>", str);
384  }
385  else {
386  /* keyword index */
387  if (st->n_keys > 0 &&
388  strcmp(st->module_info.keywords[2], str) == 0) {
389 
390  /* TODO: fprintf(f, _("keywords: ")); */
391  fprintf(f, "<a href=\"keywords.html#%s\">%s</a>", str, str);
392  }
393  else {
394  fprintf(f, "<a href=\"keywords.html#%s\">%s</a>", str, str);
395  }
396  }
397  }
398 }
399 
400 #undef do_escape
#define NULL
Definition: ccmath.h:32
const char * G_program_name(void)
Return module name.
Definition: progrm_nme.c:28
#define TYPE_STRING
Definition: gis.h:186
#define TYPE_INTEGER
Definition: gis.h:184
#define FALSE
Definition: gis.h:83
#define TYPE_DOUBLE
Definition: gis.h:185
#define _(str)
Definition: glocale.h:10
void G__print_keywords(FILE *fd, void(*format)(FILE *, const char *), int newline)
Print list of keywords (internal use only)
Definition: parser.c:927
int G__uses_new_gisprompt(void)
Definition: parser.c:890
struct state * st
Definition: parser.c:104
#define do_escape(c, escaped)
Format text for HTML output.
Definition: parser_html.c:311
void G__usage_html(void)
Print module usage description in HTML format.
Definition: parser_html.c:29
Structure that stores flag info.
Definition: gis.h:585
struct Flag * next_flag
Definition: gis.h:594
const char * description
Definition: gis.h:591
char key
Definition: gis.h:586
const char * label
Definition: gis.h:590
Structure that stores option information.
Definition: gis.h:554
const char * key
Definition: gis.h:555
struct Option * next_opt
Definition: gis.h:571
const char * key_desc
Definition: gis.h:561
const char ** opts
Definition: gis.h:560
const char * gisprompt
Definition: gis.h:572
const char * label
Definition: gis.h:562
int type
Definition: gis.h:556
const char * def
Definition: gis.h:569
const char * description
Definition: gis.h:563
int required
Definition: gis.h:557
const char ** descs
Definition: gis.h:566
const char * options
Definition: gis.h:559
int multiple
Definition: gis.h:558