2 std_io.c - MaLa standard IO module parsers
4 Copyright (C) 2005, Christian Thaeter <chth@gmx.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
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, contact me.
28 mala_actioninit std_io
[] =
31 MALA_PARSER_SIMPLE("--PRINT", mala_print_parser
),
32 // MALA_PARSER_BRIEF("--PRINT", "prints to stdout"),
33 // MALA_PARSER_HELP("--PRINT", ("TODO")),
34 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
35 // MALA_PARSER_RESULT_USAGE("--", ("")),
36 //MALA_PARSER_SIGNATURE_TYPE("--PRINT", ("WORD-OR-BLOCK")),
37 //MALA_PARSER_RESULT_TYPE("--PRINT", ("VOID")),
39 MALA_PARSER_SIMPLE("--NL", mala_newline_parser
),
40 //MALA_PARSER_BRIEF("--NL", "prints a newline"),
41 // MALA_PARSER_HELP("--NL", ("TODO")),
42 //MALA_PARSER_RESULT_USAGE("--NL", ("")),
45 MALA_PARSER_MACRO("--PRINTL",("--PRINT", "--LITERAL", "%1", "--NL")),
46 //MALA_PARSER_BRIEF("--PRINTL", "prints a textline to stdout"),
47 // MALA_PARSER_HELP("--PRINTL", ("TODO")),
48 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
49 // MALA_PARSER_RESULT_USAGE("--", ("")),
50 //MALA_PARSER_SIGNATURE_TYPE("--PRINTL", ("WORD-OR-BLOCK")),
51 //MALA_PARSER_RESULT_TYPE("--PRINTL", ("VOID")),
54 MALA_PARSER_SIMPLE("--PRINTWRAPED",mala_printwraped_parser
),
55 //MALA_PARSER_BRIEF("--PRINTWRAPED", "prints formatted text"),
56 //TODO MALA_PARSER_HELP("--PRINTWRAPED", ("Wraps some text to fit nicely on the screen. Tabulators become aligned. The last tabulator delimited field of a line will be printed word-wraped and indented.")),
57 //TODO MALA_PARSER_SIGNATURE_USAGE("--PRINTWRAPED",
58 // ("Columns available on the screen",
59 // "Lines available on the screen",
60 // "Indent of the block in characters",
61 // "Tabwidth to be used",
62 // "Text to be printed")),
63 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
64 //TODO MALA_PARSER_SIGNATURE_TYPE("--PRINTWRAPED",
74 struct mala_printwraped_context
;
77 mala_newline_parser (MalaProgram prg
)
83 mala_program_action_done (prg
, 0);
84 return MALA_STATEMENT
;
88 mala_print_parser (MalaProgram prg
)
90 mala_state state
= mala_program_eval_arg (prg
, 1, MALA_LITERAL
, NULL
);
91 if (state
> MALA_START
)
94 TODO("use dst in arg_eval");
96 PLANNED("print blocks ?");
99 printf("%s",mala_string_cstr (mala_stringlist_string (mala_stringlist_next (mala_program_pptr (prg
)))));
102 mala_program_action_done (prg
, 1);
103 return MALA_STATEMENT
;
108 mala_estimate_tabwidth (struct mala_printwraped_context
* pwc
);
111 mala_insert_space (struct mala_printwraped_context
* pwc
, int stop
);
114 mala_ltab (struct mala_printwraped_context
* pwc
);
117 mala_rtab (struct mala_printwraped_context
* pwc
);
120 mala_wrap_words (struct mala_printwraped_context
* pwc
);
123 mala_print_wraped (struct mala_printwraped_context
* pwc
);
126 mala_put_word (struct mala_printwraped_context
* pwc
);
129 struct mala_printwraped_context
140 const char * out_itr
;
141 const char * parse_itr
;
145 int wrap_indent_locked
;
146 const char * lastspace
;
151 nobug_mala_printwraped_context_dump (const struct mala_printwraped_context
* self
,
159 DUMP_LOG ("columns %d", self
->columns
);
160 DUMP_LOG ("lines %d", self
->lines
);
161 DUMP_LOG ("indent %d", self
->indent
);
162 DUMP_LOG ("tabwidth %d", self
->tabwidth
);
163 for (int current_tab
= 0; current_tab
< 19; ++current_tab
)
164 DUMP_LOG_IF (self
->tabstops
[current_tab
], "tab %d %d", current_tab
, self
->tabstops
[current_tab
]);
170 mala_estimate_tabwidth (struct mala_printwraped_context
* pwc
)
176 TRACE (mala_module_std
);
177 for (current_tab
= 19; current_tab
; --current_tab
)
178 pwc
->tabstops
[current_tab
] = 0;
180 pwc
->tabstops
[0] = pwc
->indent
;
184 for (pwc
->parse_itr
= pwc
->text
, pwc
->pos
= pwc
->indent
;
188 switch (*pwc
->parse_itr
)
191 if (*(pwc
->parse_itr
+1) != ' ')
198 if (pwc
->tabstops
[ltab_cnt
] < pwc
->pos
)
200 pwc
->tabstops
[ltab_cnt
] = pwc
->indent
+
201 (pwc
->pos
- 1 + pwc
->tabwidth
) -
202 ((pwc
->pos
- 1 + pwc
->tabwidth
) % pwc
->tabwidth
);
205 pwc
->pos
= pwc
->tabstops
[ltab_cnt
];
207 if (pwc
->pos
+ pwc
->tabwidth
>= pwc
->columns
&& pwc
->tabwidth
> 2)
210 TRACE(mala_module_std
, "tab decreased to %d",pwc
->tabwidth
);
219 pwc
->pos
= pwc
->indent
;
230 mala_insert_space (struct mala_printwraped_context
* pwc
, int stop
)
232 while (pwc
->pos
< stop
)
240 mala_ltab (struct mala_printwraped_context
* pwc
)
242 TRACE (mala_module_std
);
243 while(*pwc
->lastspace
== ' ')
247 if (pwc
->ltab_itr
< 19)
250 pwc
->wrap_indent
= pwc
->tabstops
[pwc
->ltab_itr
] -
251 (pwc
->parse_itr
- pwc
->lastspace
) - 1;
254 pwc
->wrap_indent_locked
= 0;
260 mala_rtab (struct mala_printwraped_context
* pwc
)
262 TRACE (mala_module_std
);
263 const char * tmp_itr
;
265 if (pwc
->pos
< pwc
->columns
)
272 while (isblank (*pwc
->parse_itr
))
275 pwc
->lastspace
= pwc
->parse_itr
;
277 tmp_itr
= pwc
->parse_itr
;
278 while (*tmp_itr
!= '\0' && *tmp_itr
!= '\n')
281 int length
= tmp_itr
- pwc
->parse_itr
;
283 pwc
->wrap_indent
= pwc
->columns
- length
;
284 pwc
->wrap_indent_locked
= 0;
288 mala_put_word (struct mala_printwraped_context
* pwc
)
293 TRACE (mala_module_std
);
298 length
= stop
- pwc
->lastspace
;
299 left
= pwc
->columns
- pwc
->pos
;
301 if (pwc
->pos
+ length
> pwc
->columns
)
303 while(*pwc
->lastspace
== ' ')
306 if (length
> pwc
->columns
- pwc
->wrap_indent
)
308 stop
= pwc
->lastspace
+ pwc
->columns
- pwc
->wrap_indent
- 1;
311 if (isalpha (*(pwc
->lastspace
- 1)))
318 if (pwc
->pos
< pwc
->wrap_indent
)
319 mala_insert_space (pwc
, pwc
->wrap_indent
);
321 if (pwc
->wrap_indent
>= pwc
->columns
- 1)
322 pwc
->wrap_indent
= pwc
->columns
- 2;
324 while (pwc
->lastspace
< stop
)
326 if (isalpha (*pwc
->lastspace
))
327 pwc
->wrap_indent_locked
= 1;
328 else if (!pwc
->wrap_indent_locked
)
331 putchar (*pwc
->lastspace
);
336 while (stop
< pwc
->out_itr
);
340 mala_wrap_words (struct mala_printwraped_context
* pwc
)
342 /* prints all text until the next \t \n or \0 linewraped */
343 TRACE (mala_module_std
);
344 for (; pwc
->out_itr
< pwc
->parse_itr
; ++pwc
->out_itr
)
346 if (*pwc
->out_itr
== ' ')
355 mala_print_wraped (struct mala_printwraped_context
* pwc
)
358 - a line consists of many tab delimited fields with one optional right aligned field at the
359 end introduced with tab-space "\t "
360 - the last normal tab field gets word wraped and aligned the first alphabetic character of this
361 field. Too long words become (simple) hyphenated.
362 - tabs are aligned every 'tabwidth' characters, when the terminal is too small, tabwidth is
363 gradually decremented until the data fits more nicely until tabwidth = 2.
364 - care is taken that even if the output isn't displayable (too less columns) at least something
365 ugly will be presented, never failing.
368 "foo \tbar\n\n\tfoo\t- foo explanation which gets word wraped because this text is long\n\tbaz\t- baz explanation\t [note]"
370 becomes something like:
374 foo - foo explanation which gets word wraped
375 because this text is long
376 baz - baz explanation [note]
379 TRACE (mala_module_std
);
381 for (pwc
->lastspace
= pwc
->out_itr
= pwc
->parse_itr
= pwc
->text
,
386 switch (*pwc
->parse_itr
)
389 mala_wrap_words (pwc
);
390 if (*(pwc
->parse_itr
+1) != ' ')
396 mala_wrap_words (pwc
);
399 pwc
->wrap_indent
= pwc
->indent
;
400 pwc
->wrap_indent_locked
= 0;
407 mala_wrap_words (pwc
);
413 mala_printwraped_parser (MalaProgram prg
)
415 TRACE (mala_module_std
);
417 struct mala_printwraped_context pwc
;
422 state
= mala_program_eval_arg_fmt (prg
, 1, "%d", &pwc
.columns
, NULL
);
423 if (state
> MALA_START
)
428 /* Lines _ignored for now_ */
429 PLANNED("paged output");
430 state
= mala_program_eval_arg_fmt (prg
, 2, "%d", &pwc
.lines
, NULL
);
431 if (state
> MALA_START
)
437 state
= mala_program_eval_arg_fmt (prg
, 3, "%d", &pwc
.indent
, NULL
);
438 if (state
> MALA_START
)
440 if (pwc
.indent
>= pwc
.columns
- 2)
445 state
= mala_program_eval_arg_fmt (prg
, 4, "%d", &pwc
.tabwidth
, NULL
);
446 if (state
> MALA_START
)
448 if (pwc
.tabwidth
< 2)
452 MalaStringList textnode
;
453 state
= mala_program_eval_arg (prg
, 5, MALA_LITERAL
, &textnode
);
454 if (state
> MALA_START
)
457 pwc
.text
= mala_stringlist_cstr (textnode
);
462 pwc
.wrap_indent_locked
= 0;
463 pwc
.wrap_indent
= pwc
.indent
;
465 mala_estimate_tabwidth (&pwc
);
466 mala_print_wraped (&pwc
);
470 mala_program_action_done (prg
, 5);
471 return MALA_STATEMENT
;
476 mala_module_std_io_init (MalaEngine self
)
478 return mala_engine_actions_register (self
, std_io
);
485 // c-file-style: "gnu"
487 // arch-tag: 3d2a15ac-145d-42d7-98a5-14dc9b7d2003