@@ -26,10 +26,10 @@ static void print_python_long_flag(FILE *file, const char *key,
2626 const char * label , const char * description ,
2727 const char * indent );
2828static void print_python_option (FILE * file , const struct Option * opt ,
29- const char * indent );
29+ const char * indent , bool tools_api );
3030static void print_python_example (FILE * file , const char * python_function ,
3131 const char * output_format_default ,
32- const char * indent );
32+ const char * indent , bool tools_api );
3333static void print_python_tuple (FILE * file , const char * type , int num_items );
3434
3535void print_python_short_flag (FILE * file , const char * key , const char * label ,
@@ -90,7 +90,7 @@ void print_python_tuple(FILE *file, const char *type, int num_items)
9090}
9191
9292void print_python_option (FILE * file , const struct Option * opt ,
93- const char * indent )
93+ const char * indent , bool tools_api )
9494{
9595 const char * type ;
9696
@@ -108,6 +108,19 @@ void print_python_option(FILE *file, const struct Option *opt,
108108 type = "str" ;
109109 break ;
110110 }
111+
112+ char age [KEYLENGTH ];
113+ char element [KEYLENGTH ];
114+ char prompt_description [KEYLENGTH ];
115+ if (opt -> gisprompt ) {
116+ G__split_gisprompt (opt -> gisprompt , age , element , prompt_description );
117+ if (tools_api && !opt -> multiple && opt -> type == TYPE_STRING &&
118+ G_strncasecmp ("old" , age , 3 ) == 0 &&
119+ G_strncasecmp ("file" , element , 4 ) == 0 ) {
120+ type = "str | io.StringIO" ;
121+ }
122+ }
123+
111124 fprintf (file , "%s**%s** : " , indent , opt -> key );
112125 int tuple_items = G__option_num_tuple_items (opt );
113126 if (opt -> multiple ) {
@@ -169,10 +182,6 @@ void print_python_option(FILE *file, const struct Option *opt,
169182 fprintf (file , "%s: " , _ ("Used as" ));
170183 }
171184 if (opt -> gisprompt ) {
172- char age [KEYLENGTH ];
173- char element [KEYLENGTH ];
174- char desc [KEYLENGTH ];
175- G__split_gisprompt (opt -> gisprompt , age , element , desc );
176185 if (strcmp (age , "new" ) == 0 )
177186 fprintf (file , "output, " );
178187 else if (strcmp (age , "old" ) == 0 )
@@ -181,7 +190,7 @@ void print_python_option(FILE *file, const struct Option *opt,
181190 // used given that the parser may read that information, desc
182191 // is meant as a user-facing representation of the same
183192 // information.
184- fprintf (file , "%s" , desc );
193+ fprintf (file , "%s" , prompt_description );
185194 }
186195 if (opt -> gisprompt && opt -> key_desc ) {
187196 fprintf (file , ", " );
@@ -252,12 +261,24 @@ void print_python_option(FILE *file, const struct Option *opt,
252261}
253262
254263void print_python_example (FILE * file , const char * python_function ,
255- const char * output_format_default , const char * indent )
264+ const char * output_format_default , const char * indent ,
265+ bool tools_api )
256266{
257267 fprintf (file , "\n%sExample:\n" , indent );
258268
259269 fprintf (file , "\n%s```python\n" , indent );
260- fprintf (file , "%sgs.%s(\"%s\"" , indent , python_function , st -> pgm_name );
270+ bool first_parameter_printed = false;
271+ if (tools_api ) {
272+ char * tool_name = G_store (st -> pgm_name );
273+ G_strchg (tool_name , '.' , '_' );
274+ fprintf (file , "%stools = Tools()\n" , indent );
275+ fprintf (file , "%stools.%s(" , indent , tool_name );
276+ G_free (tool_name );
277+ }
278+ else {
279+ fprintf (file , "%sgs.%s(\"%s\"" , indent , python_function , st -> pgm_name );
280+ first_parameter_printed = true;
281+ }
261282
262283 const struct Option * first_required_rule_option =
263284 G__first_required_option_from_rules ();
@@ -287,7 +308,10 @@ void print_python_example(FILE *file, const char *python_function,
287308 }
288309 if (opt -> required || first_required_rule_option == opt ||
289310 (strcmp (opt -> key , "format" ) == 0 && output_format_default )) {
290- fprintf (file , ", %s=" , opt -> key );
311+ if (first_parameter_printed ) {
312+ fprintf (file , ", " );
313+ }
314+ fprintf (file , "%s=" , opt -> key );
291315
292316 char * value = NULL ;
293317 if (opt -> answer ) {
@@ -333,6 +357,7 @@ void print_python_example(FILE *file, const char *python_function,
333357 fprintf (file , "\"%s\"" , type );
334358 }
335359 }
360+ first_parameter_printed = true;
336361 G_free (value );
337362 }
338363 opt = opt -> next_opt ;
@@ -341,7 +366,8 @@ void print_python_example(FILE *file, const char *python_function,
341366 fprintf (file , ")\n%s```\n" , indent );
342367}
343368
344- void G__md_print_python_short_version (FILE * file , const char * indent )
369+ void G__md_print_python_short_version (FILE * file , const char * indent ,
370+ bool tools_api )
345371{
346372 struct Option * opt ;
347373 struct Flag * flag ;
@@ -387,24 +413,36 @@ void G__md_print_python_short_version(FILE *file, const char *indent)
387413 flag = flag -> next_flag ;
388414 }
389415 }
390- if (output_format_option || (!new_prompt && shell_eval_flag )) {
391- python_function = "parse_command" ;
392- // We know this is can be parsed, but we can't detect just plain file
393- // because we can't distinguish between plain text outputs and
394- // modifications of data.
416+ bool first_parameter_printed = false;
417+ if (tools_api ) {
418+ char * tool_name = G_store (st -> pgm_name );
419+ G_strchg (tool_name , '.' , '_' );
420+ fprintf (file , "%s*grass.tools.Tools.%s*(" , indent , tool_name );
421+ G_free (tool_name );
395422 }
396423 else {
397- python_function = "run_command" ;
424+ if (output_format_option || (!new_prompt && shell_eval_flag )) {
425+ python_function = "parse_command" ;
426+ // We know this can be parsed, but we don't detect just plain
427+ // text output to use read_command because we can't distinguish
428+ // between plain text outputs and modifications of data.
429+ }
430+ else {
431+ python_function = "run_command" ;
432+ }
433+ fprintf (file , "%s*grass.script.%s*(\"***%s***\"," , indent ,
434+ python_function , st -> pgm_name );
435+ fprintf (file , "\n" );
436+ first_parameter_printed = true;
398437 }
399- fprintf (file , "%s*grass.script.%s*(\"***%s***\"," , indent , python_function ,
400- st -> pgm_name );
401- fprintf (file , "\n" );
402438
403439 if (st -> n_opts ) {
404440 opt = & st -> first_option ;
405441
406442 while (opt != NULL ) {
407- fprintf (file , "%s " , indent );
443+ if (first_parameter_printed ) {
444+ fprintf (file , "%s " , indent );
445+ }
408446 if (!opt -> required && !opt -> answer ) {
409447 fprintf (file , "**%s**=*None*" , opt -> key );
410448 }
@@ -427,7 +465,7 @@ void G__md_print_python_short_version(FILE *file, const char *indent)
427465 }
428466 }
429467 fprintf (file , ",\n" );
430-
468+ first_parameter_printed = true;
431469 opt = opt -> next_opt ;
432470 }
433471 }
@@ -445,10 +483,18 @@ void G__md_print_python_short_version(FILE *file, const char *indent)
445483 fprintf (file , "%s **quiet**=%s,\n" , indent , flag_default );
446484 fprintf (file , "%s **superquiet**=%s)\n" , indent , flag_default );
447485
448- print_python_example (file , python_function , output_format_default , indent );
486+ print_python_example (file , python_function , output_format_default , indent ,
487+ tools_api );
488+ if (tools_api ) {
489+ fprintf (file ,
490+ "\n%sThis grass.tools API is experimental in version 8.5 "
491+ "and expected to be stable in version 8.6.\n" ,
492+ indent );
493+ }
449494}
450495
451- void G__md_print_python_long_version (FILE * file , const char * indent )
496+ void G__md_print_python_long_version (FILE * file , const char * indent ,
497+ bool tools_api )
452498{
453499 struct Option * opt ;
454500 struct Flag * flag ;
@@ -460,7 +506,7 @@ void G__md_print_python_long_version(FILE *file, const char *indent)
460506 if (st -> n_opts ) {
461507 opt = & st -> first_option ;
462508 while (opt != NULL ) {
463- print_python_option (file , opt , indent );
509+ print_python_option (file , opt , indent , tools_api );
464510 opt = opt -> next_opt ;
465511 fprintf (file , MD_NEWLINE );
466512 fprintf (file , "\n" );
0 commit comments