Methods

arara features several helper methods available in directive conditional and rule contexts which provide interesting features for enhancing the user experience, as well as improving the automation itself. This chapter provides a list of such methods. It is important to observe that virtually all classes from the Java runtime environment can be used within MVEL expressions, so your mileage might vary.

A note on writing code
As seen in MVEL, Java and MVEL code be used interchangeably within expressions and orb tags, including instantiation of classes into objects and invocation of methods. However, be mindful of explicitly importing Java packages and classes through the classic import statement, as MVEL does not automatically handle imports, or an exception will surely be raised. Alternatively, you can provide the full qualified name to classes as well.
A file by any other name
As of version 7, we now avoid exposing any Java-specific API. When you see a mention to File, keep in mind that this is actually a wrapper to our new internal representation.

Methods are listed with their complete signatures, including potential parameters and corresponding types. Also, the return type of a method is denoted by type and refers to a typical Java data type (either class or primitive). Do not worry too much, as there are illustrative examples. A method available in the directive conditional context will be marked by [C] next to the corresponding signature. Similarly, an entry marked by [R] denotes that the corresponding method is available in the rule context. At last, an entry marked by [E] denotes that the corresponding method is available in the orb tag expansion within a special options parameter in the directive context.

Files

This section introduces methods related to file handling, searching and hashing. It is important to observe that no exception is thrown in case of an anomalous method call. In this particular scenario, the methods return empty references, when applied.

As the methods presented in this section have transparent error handling, the writing of rules and conditionals becomes more fluent and not too complex for the typical user.

Conditional flow

This section introduces methods related to conditional flow based on natural boolean values, i.e, words that semantically represent truth and falsehood signs. Such concept provides a friendly representation of boolean values and eases the use of switches in directive parameters. The tool relies on the following set of natural boolean values:

All elements from the provided set of natural boolean values can be used interchangeably in directive parameters. It is important to observe that arara throws an exception if a value absent from the set is provided to the methods described in this section.

Supported by the concept of natural boolean values, the methods presented in this section ease the use of switches in directive parameters and can be adopted as valid alternatives for traditional conditional flows, when applied.

Strings

String manipulation constitutes one of the foundations of rule interpretation in our tool. This section introduces methods for handling such types, as a means to offer high level constructs for users.

The string manipulation methods presented in this section constitute an interesting and straightforward approach to handling directive parameters without the usual verbosity in writing typical Java constructs.

Operating systems

This section introduces methods related to the underlying operating system detection, as a means of providing a straightforward approach to writing cross-platform rules.

The methods presented in the section provide useful information to help users write cross-platform rules and thus enhance the automation experience based on specific features of the underlying operating system.

Type checking

In certain scenarios, a plain string representation of directive parameters might be inadequate or insufficient given the rule requirements. To this end, this section introduces methods related to type checking as a means to provide support and verification for common data types.

The methods presented in this section cover the most common types used in directive parameters and should suffice for expressing the rule requirements. If a general approach is needed, please refer to the ❖ checkClass method for checking virtually any type available in the Java environment.

Classes and objects

arara can be extended at runtime with code from JVM languages, such as Groovy, Scala, Clojure and Kotlin. The tool can load classes from class and jar files and even instantiate them. This section introduces methods related to class loading and object instantiation.

Ordered pairs
According to the Wikipedia entry, in mathematics, an ordered pair (a, b) is a pair of objects. The order in which the objects appear in the pair is significant: the ordered pair (a, b) is different from the ordered pair (b, a) unless a = b. In the ordered pair (a, b), the object a is called the first entry, and the object b the second entry of the pair. arara relies on this concept with the helper Pair<A, B> class, in which A and B denote the component classes, i.e, the types associated to the pair elements. In order to access the pair entries, the class provides two property accessors:

  • ❖ first: A: This property accessor, as the name implies, returns the first entry of the ordered pair, as an A object.

  • ❖ second: B: This property accessor, as the name implies, returns the second entry of the ordered pair, as a B object.

Keep in mind that the entries in the Pair class, once defined, cannot be modified to other values. The initial values are set during instantiation and, therefore, only entry getters are available to the user during the object life cycle.

Status for class loading and instantiation
The class loading and instantiation methods provided by arara typically return a pair composed of an integer value and a class or object reference. This integer value acts as a status of the underlying operation itself and might indicate potential issues. The possible values are:

  • 0: Successful execution
  • 1: File does not exist
  • 2: File URL is incorrect
  • 3: Class was not found
  • 4: Access policy violation
  • 5: Instantiation exception

Please make sure to always check the returned integer status when using class loading and instantiation methods in directive and rule contexts. This feature is quite powerful yet tricky and subtle!

This section presented class loading and instantiation methods which may significantly enhance the expressiveness of rules and directives. However, make sure to use such feature with great care and attention.

Dialog boxes

A dialog box is a graphical control element, typically a small window, that communicates information to the user and prompts them for a response. This section introduces UI methods related to such interactions.

UI elements
The graphical elements are provided by the Swing toolkit from the Java runtime environment. Note that the default look and feel class reference can be modified through a key in the configuration file, as seen in Configuration. It is important to observe that the methods presented in this section require a graphical interface. If arara is being executed in a headless environment (i.e, an environment with no graphical display available), an exception will be thrown when trying to use such UI methods in either directive or rule contexts.

Each dialog box provided by the UI methods of arara requires the specification of an associated icon. An icon is a pictogram displayed on a computer screen in order to help the user quickly identify the message by conveying its meaning through a visual resemblance to a physical object. Our tool features five icon types, illustrated below, to be used with dialog boxes. Observe that each icon type is associated with a unique integer value which is provided later on to the actual method call. Also, it is worth mentioning that the visual appearance of such icons is based on the underlying Java virtual machine and the current look and feel, so your mileage might vary.

As good practice, make sure to provide descriptive messages to be placed in dialog boxes in order to ease and enhance the user experience. It is also highly advisable to always provide an associated icon, so avoid the plain option whenever possible.

Message text width
arara sets the default message text width to 250 pixels. Feel free to override this value according to your needs. Please refer to the appropriate method signatures for specifying a new width.

The UI method signatures are followed by a visual representation of the provided dialog box. For the sake of simplicity, each parameter index refers to the associated number in the figure.

UI 1

This method shows a message box according to the provided parameters. The dialog box is disposed when the user either presses the confirmation button or closes the window. It is important to observe that arara temporarily interrupts the execution and waits for the dialog box disposal. Also note that the total time includes the idle period as well.

showMessage(250, 2, 'My title', 'My message');

The UI methods presented in this section can be used for writing TeX tutorials and assisted compilation workflows based on user interactions, including visual input and feedback through dialog boxes.

Commands

arara features the Command object, a new approach for handling system commands based on a high level structure with explicit argument parsing.

The anatomy of a command
From the user perspective, a Command object is simply a good old list of Object objects, in which the list head (i.e, the first element) is the underlying system command, and the list tail (i.e, the remaining elements), if any, contains the associated command line arguments. For instance, given [ 'pdflatex', '--shell-escape', '--synctex=1', 'thesis.tex' ], we have:

  • Head: 'pdflatex'
  • Tail: [ '--shell-escape', '--synctex=1', 'thesis.tex' ]

From the previous example, it is important to observe that a potential file name quoting is not necessary. The underlying system command execution library handles the provided arguments accordingly.

Behind the scenes, however, arara employs a different workflow when constructing a Command object. The tool sets the working directory path for the current command to USER_DIR which is based on the current execution. The working directory path can be explicitly set through specific method calls, described later on in this section.

The list of objects is then completely flattened and all elements are mapped to their string representations through corresponding ❖ toString calls. Finally, the proper Command object is constructed. Keep in mind that, although a command takes a list (or even an array) of objects, which can be of any type, the internal representation is always a list of strings.

A list of objects might contain nested lists, i.e, a list within another list. As previously mentioned, arara employs list flattening when handling a list of objects during a Command object instantiation. As a means to illustrate this handy feature, consider the following list of integers:

[ 1, 2, [ 3, 4 ], 5, [ [ 6, 7 ], 8 ], 9, [ [ 10 ] ]

Note that the above list of integers contains nested lists. When applying list flattening, arara recursively adds the elements of nested lists to the original list and then removes the nested occurrences. Please refer to the source code for implementation details. The new flattened list is presented as follows.

[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

List flattening and string mapping confer expressiveness and flexibility to the Command object construction, as users can virtually use any data type to describe the underlying rule logic and yet obtain a consistent representation.

The methods presented in this section constitute the foundations of underlying system command execution. In particular, whenever possible, it is highly advisable to use Command objects through proper ❖ getCommand method calls, as the plain string approach used in previous versions of our tool is marked as deprecated and will be removed in future versions.

Others

This section introduces assorted methods provided by arara as a means to improve the automation itself with expressive rules and enhance the user experience. Such methods are properly described as follows.

Session
Rules are designed under the encapsulation notion, such that the direct access to internal workings of such structures is restricted. However, as a means to support framework awareness, arara provides a mechanism for data sharing across rule contexts, implemented as a Session object. In practical terms, this particular object is a global, persistent map composed of String keys and Object values available throughout the entire execution. The public methods of a session are described as follows:

  • ❖ put(String key, Object value): void This method, as the name implies, inserts an object into the session, indexed by the provided key. Observe that, if the session previously contained a mapping for the provided key, the old value is replaced by the specified value.

  • ❖ remove(String key): void This method, as the name implies, removes the mapping for the provided key from the session. Be mindful that an attempt to remove a mapping for a nonexistent key will raise an exception.

  • ❖ contains(String key): boolean This method, as the name implies, returns a boolean value according to whether the session contains a mapping for the provided key. It is highly advisable to use this method before attempting to remove a mapping from the session.

  • ❖ get(String key): Object This method, as the name implies, returns the object value to which the specified key is mapped. Be mindful that an attempt to return a value for a nonexistent key will raise an exception.

  • ❖ forget(): void This method, as the name implies, removes all of the existing mappings from the session. The session object will be effectively empty after this call returns.

It is important to observe that the Session object provided by our tool follows the singleton pattern, i.e, a software design pattern that restricts the instantiation of a class to one object. Therefore, the same session is consistently shared across rule contexts.

Flags and reserved storage in a session
From version 6.0 on, there are three reserved namespaces within a session. They are described as follows:

  • environment This namespace is quite intuitive: arara will store the current state of the systems environment variables in its session. You may alter these values in the session storage but they will not be written back to the system configuration. To access an environment variable, you can use its usual name prefixed by environment::

    path = getSession().get('environment:PATH');
    
  • arara This namespace provides flags that control the underlying behaviour of arara. Flags are used in rules and may be manipulated by the user. Be aware that every change in this namespace will result in the tool acting like you know what you did. Use this power with care. Currently, there is only one relevant flag: arara:FILENAME:halt. This will stop the currently run command execution on the file with the specified file name. The value of this map entry is the exit status you want arara to have.

    getSession().put('arara:myfile.tex:halt', 42);
    
  • arg This namespace acts as a bridge between contexts and the command line by providing access to key/value pairs defined at runtime by --call-property command line flags.

    key = getSession().get('arg:key');
    

Please refer to Command line for more details on the --call-property command line flag.

The methods presented in this section provide interesting features for persistent data sharing, error handling, early command execution, and templating. It is important to note that more classes, objects and methods can be incorporated into arara through class loading and object instantiation, extending the features and enhancing the overall user experience.