.. include:: ../global.inc .. _decorators.transform: .. index:: pair: @transform; Syntax See :ref:`Decorators ` for more decorators ######################## @transform ######################## .. |tasks_or_file_names| replace:: `tasks_or_file_names` .. _tasks_or_file_names: `decorators.transform.tasks_or_file_names`_ .. |extra_parameters| replace:: `extra_parameters` .. _extra_parameters: `decorators.transform.extra_parameters`_ .. |output_pattern| replace:: `output_pattern` .. _output_pattern: `decorators.transform.output_pattern`_ .. |matching_regex| replace:: `matching_regex` .. _matching_regex: `decorators.transform.matching_regex`_ .. |suffix_string| replace:: `suffix_string` .. _suffix_string: `decorators.transform.suffix_string`_ ********************************************************************************************************************************************************************************************************************* *@transform* ( |tasks_or_file_names|_, :ref:`suffix 1.o # 2.c -> 2.o compile("1.c", "1.o") compile("2.c", "2.o") **Escaping regular expression patterns** A string like ``universal.h`` in ``add_inputs`` will added *as is*. ``r"\1.h"``, however, performs suffix substitution, with the special form ``r"\1"`` matching everything up to the suffix. Remember to 'escape' ``r"\1"`` otherwise Ruffus will complain and throw an Exception to remind you. The most convenient way is to use a python "raw" string. **Parameters:** .. _decorators.transform.tasks_or_file_names: * *tasks_or_file_names* can be a: #. Task / list of tasks (as in the example above). File names are taken from the output of the specified task(s) #. (Nested) list of file name strings. File names containing ``*[]?`` will be expanded as a |glob|_. E.g.:``"a.*" => "a.1", "a.2"`` .. _decorators.transform.suffix_string: * *suffix_string* must be wrapped in a :ref:`suffix my_path/1.o # 2.c -> my_path/2.o compile("1.c", "my_path/1.o") compile("2.c", "my_path/2.o") For convenience and visual clarity, the ``"\1"`` can be omitted from the output parameter. However, the ``"\1"`` is mandatory for string substitutions in additional parameters, . @transform(["1.c", "2.c"], suffix(".c"), [r"\1.o", ".o"], "Compiling \1", "verbatim") def compile(infile, outfile): pass Results in the following function calls: :: compile("1.c", ["1.o", "1.o"], "Compiling 1", "verbatim") compile("2.c", ["2.o", "2.o"], "Compiling 2", "verbatim") Since r"\1" is optional for the output parameter, ``"\1.o"`` and ``".o"`` are equivalent. However, strings in other parameters which do not contain r"\1" will be included verbatim, much like the string ``"verbatim"`` in the above example. .. _decorators.transform.matching_regex: * *matching_regex* is a python regular expression string, which must be wrapped in a :ref:`regex`_ documentation for details of regular expression syntax Each output file name is created using regular expression substitution with ``output_pattern`` .. _decorators.transform.output_pattern: * *output_pattern* Specifies the resulting output file name(s). .. _decorators.transform.extra_parameters: * [*extra_parameters, ...*] Any extra parameters are passed to the task function. If ``regex(matching_regex)`` parameter is used, then regular expression substitution is first applied to (even nested) string parameters. Other data types are passed verbatim. For example:: @transform(["a.c", "b.c"], regex(r"(.*).c"), r"\1.o", r"\1") def compile(infile, outfile): pass will result in the following function calls:: compile("a.c", "a.o", "a") compile("b.c", "b.o", "b") See :ref:`here ` for more advanced uses of transform.