14

(Apologies if I have the terminology incorrect.)

I want to write a directive for arara that can take an argument. The directive should set the name of the output file according to the following rules:

  1. If no argument is given, use a default value.
  2. If the argument is given but has no value, use the file variable.
  3. If an argument is given, use that.

I thought that the right way to do this would be:

command: 'echo @{ name == "" ? "default" : name }'
arguments:
- identifier: name
  flag: '@{value == "" ? file : value }'

but I get: ERROR: Parsing rule '<rulename>' failed. It might be a malformed directive or orb tag syntax. if I don't pass an actual argument.

Here's a MWE:

!config
# test rule for arara
# author: Andrew Stacey
identifier: echo
name: Echo the value of the argument
command: 'echo @{ name == "" ? "default" : name }'
arguments:
- identifier: name
  flag: '@{value == "" ? file : value }'

Then in my test document I try one of:

% arara: echo
% arara: echo: {name: 'something'}
% arara: echo: {name: }
% arara: echo: {name: ''}

The first two work, the second two don't.

Is this possible?

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751

1 Answers1

13

With the new 3.x series, we can easily add a default value to the argument expansion.

Here's the new echo rule:

!config
# test rule for arara
# author: Andrew Stacey
# requires arara 3.0+
identifier: echo
name: Echo the value of the argument
command: <arara> echo @{name}
arguments:
- identifier: name
  flag: <arara> @{ isTrue( isEmpty( parameters.name ), file, parameters.name ) }
  default: <arara> @{file}

New concepts:

  • value was replaced by a map named parameters. If we want to access, say, the one directive argument, we simply call parameters.one instead of value assuming the value in the rule argument context.
  • <arara> is used at the beginning of the values just to save a few quotes. The expansion mechanism can detect this keyword and safely remove it. You can still use quotes, there's no problem.
  • Now a rule argument can have a default value, which is the first to be evaluated when the argument is processed. If no default is provided, the mechanism sets the value to '' (empty string).
  • We now have several built-in functions in the rule context that might help us write more concise code:
    • string isTrue(boolean b, string s1, string s2): returns s1 if b is true, or s2 otherwise.
    • boolean isEmpty(string s): checks if s is empty and returns a boolean value: true if s is empty, false otherwise.

It's important to observe that @{file} now expands to the filename instead of the basename. If we still want to get the basename, there's also a built-in function for it: string getBasename(string s), @{ getBasename( file ) } does that.

Now, let's see the execution:

First rule: if no argument is given, use a default value.

% arara: echo
\documentclass{article}
...

  __ _ _ __ __ _ _ __ __ _
 / _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
 \__,_|_|  \__,_|_|  \__,_|

Running Echo the value of the argument...

teste.tex
Status: SUCCESS

Second rule: if the argument is given but has no value, use the file variable.

% arara: echo: { name: '' }
\documentclass{article}
...

  __ _ _ __ __ _ _ __ __ _
 / _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
 \__,_|_|  \__,_|_|  \__,_|

Running Echo the value of the argument...

teste.tex
Status: SUCCESS

Third rule: if an argument is given, use that.

% arara: echo: { name: duck }
\documentclass{article}
...

  __ _ _ __ __ _ _ __ __ _
 / _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
 \__,_|_|  \__,_|_|  \__,_|

Running Echo the value of the argument...

duck
Status: SUCCESS

The comment in the original answer about % arara: echo: { name: } still holds. Since name has no argument value, the extractor will fail.


Original answer left for historical purposes. It applies to arara 2.x

How did I miss the tag? :)

Sadly, you encountered an annoyance that went unnoticed during my test suites for releasing the 2.x series: the only variable available for expansion in the arguments context is the value itself. So unfortunatelly file - and any other variables - won't work and arara will raise an error. Hopefully, the upcoming version will solve this issue.

Also in the next release, I have a plan of a default fallback for arguments, so we won't need to write conditionals to check if the value is set. But that's another story, hopefully for the new 3.x series. :)

For now, the only way of making the echo rule work is to check the variables in the command context:

command: 'echo @{ name == "" ? file : name }'
arguments:
- identifier: name
  flag: '@{value}'

In the new release, we will be able to write this:

command: 'echo @{name}'
arguments:
- identifier: name
  flag: '@{value}'
  default: '@{file}'

The directives

% arara: echo
% arara: echo: {name: 'something'}
% arara: echo: {name: something}
% arara: echo: {name: ''}

should work (the last one has to work, unless you found another annoyance). :) Now,

% arara: echo: {name: }

has no argument value, so the extractor will fail.

Paulo Cereda
  • 44,220