diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | match.c | 37 | ||||
-rw-r--r-- | txr.1 | 18 |
3 files changed, 64 insertions, 0 deletions
@@ -1,5 +1,14 @@ 2011-10-25 Kaz Kylheku <kaz@kylheku.com> + * match.c (filter_s): New symbol variable. + (v_filter): New function. + (syms_init): New symbol variable initialized. + (dir_tables_init): New function entered into table. + + * txr.1: Documented new filter directive. + +2011-10-25 Kaz Kylheku <kaz@kylheku.com> + dep.mk: Regenerated. 2011-10-25 Kaz Kylheku <kaz@kylheku.com> @@ -55,6 +55,8 @@ val choose_s, longest_k, shortest_k, greedy_k; val vars_k; val append_k, into_k, var_k, list_k, string_k; +val filter_s; + static val h_directive_table, v_directive_table; static void debugf(val fmt, ...) @@ -2570,6 +2572,38 @@ static val v_deffilter(match_files_ctx c, match_files_ctx *cout) return next_spec_k; } +static val v_filter(match_files_ctx c, match_files_ctx *cout) +{ + spec_bind (specline, spec_linenum, first_spec, c.spec); + val filter_spec = second(first_spec); + val vars = rest(rest(first_spec)); + val filter = get_filter(filter_spec); + + if (!filter) + sem_error(spec_linenum, lit("~s specifies unknown filter"), filter_spec, nao); + + uw_env_begin; + uw_set_match_context(cons(c.spec, c.bindings)); + + for (; vars; vars = cdr(vars)) { + val var = car(vars); + val existing = assoc(c.bindings, var); + + if (!bindable(var)) + sem_error(spec_linenum, lit("filter: ~a is not a variable name"), + var, nao); + + if (!existing) + sem_error(spec_linenum, lit("filter: variable ~a is unbound"), var, nao); + + *cdr_l(existing) = filter_string(filter, cdr(existing)); + } + + uw_env_end; + *cout = c; + return next_spec_k; +} + static val v_eof(match_files_ctx c, match_files_ctx *cout) { if (c.data) { @@ -2859,6 +2893,8 @@ static void syms_init(void) var_k = intern(lit("var"), keyword_package); list_k = intern(lit("list"), keyword_package); string_k = intern(lit("string"), keyword_package); + + filter_s = intern(lit("filter"), user_package); } static void dir_tables_init(void) @@ -2895,6 +2931,7 @@ static void dir_tables_init(void) sethash(v_directive_table, defex_s, cptr((mem_t *) v_defex)); sethash(v_directive_table, throw_s, cptr((mem_t *) v_throw)); sethash(v_directive_table, deffilter_s, cptr((mem_t *) v_deffilter)); + sethash(v_directive_table, filter_s, cptr((mem_t *) v_filter)); sethash(v_directive_table, eof_s, cptr((mem_t *) v_eof)); sethash(h_directive_table, var_s, cptr((mem_t *) h_var)); @@ -1076,6 +1076,10 @@ have different special characters or other syntax, requiring escaping or similar treatment. Note that it is also possible to use a function as a filter. See Function Filters below. +.IP @(filter) +The filder directive passes one or more variables through a given +filter or chain or filters, updating them with the filtered values. + .PP .SS The Next Directive @@ -3157,6 +3161,20 @@ same left hand string with different right hand translations, the later ones take precedence. No warning is issued. +.SS The Filter Directive + +The syntax of the filter directive is: + + @(filter FILTER { VAR }+ } + +A filter is specified, followed by one or more variables whose values +are filtered and stored back into each variable. + +Example: convert a, b, and c to upper case and HTML encode: + + @(filter (:upcase :to_html) a b c) + + .SH EXCEPTIONS .SS Introduction |