Brother John’s Projects: Foobar2000 Scripting

Introduction to Tagz Scripting

Tagz is the scripting language used by Foobar2000 not only to design the playlist layout but pretty much for every function offering advanced user configuration. At the end of the tutorial you will be able to easily use the language in all of those situations. But let’s start with the basics of Tagz.

Accessing Fields

In its simplest form Tagz just retrieves information from tag fields of your music files. Like this:

%artist%

Foobar2000 looks for the artist tag of the song and hopefully returns the name of the song’s artist. If the artist field is missing you just get a question mark (?). Everything enclosed in percent signs (%) is treated like this, no matter how the field is called. Should you tag your files with a custom field called my field, just use %my field% to access the information stored there.

Additionally the same syntax is used for accessing information of a more technical nature: e.g. %bitrate% returns the file’s bitrate or %_ispaused% tells you, if the song’s playback is suspended. For a full list of Tagz’s functionality have a look at the titleformat reference in the Foobar2000 knowledgebase.

Field Remappings

Let’s stay with the %artist% field a little longer. Since Foobar2000 0.9 it is in fact a short form of:

$if3($meta(artist),$meta(album artist),$meta(composer),$meta(performer))

For now don’t worry about the intricacies of this expression. In simple words it says: Look for the artist tag. If that is not present use the album artist tag instead. If that again is not present try composer and then performer.

The really important thing to know is that behind a lot of common tags lie field remappings like this. For a complete list again refer to the titleformat reference. They were introduced to make life easier for script programmers. Most of the remappings are so common that the respective %field% command was hardly ever used in its bare form but rather in an expression like above all the time.

While remapping indeed makes writing scripts more convenient, sometimes we need access to a raw untampered field value. And we’ve already seen how this is done. To access the raw artist field use:

$meta(artist)

Note that there are no percent signs around the field name this time. You can use this syntax for any field referring to tags of your music files. But don’t use it on technical fields like %bitrate%.

This is all too confusing? Don’t worry, it will become clearer once we start developing a real script. I guess returning to this page then and reading it again, would be a good idea.

Functions

The other general syntax in Tagz are functions, which are used for computing a large variety of expressions. Simply put you feed some pieces of data to the function, which processes this data and returns a result. Let’s look at an example.

$repeat('f',10)

Every function starts with a dollar sign ($) followed by the function’s name. The data you input to the function (called arguments) is put in brackets behind the function name. If more than one argument is necessary use commas to separate them. And always remember that there are no spaces in the whole construction.

The function above repeats the letter f ten times. You’ll find out why the f is quoted and the 10 is not further down, when we’re talking about strings.

Note that also functions without any arguments require the brackets. E.g. there is a function called $rgb(), which resets the colour to its default value. Writing just $rgb will produce an error.

Control Flow: The $if() Function

If you have ever worked with formulas in a spreadsheet program you certainly are familiar with if commands. What they do is evaluating a condition and performing different actions based on the result: If condition is met, do something. Otherwise do something else.

In Tagz the usual function syntax is used for if commands.

$if(%title%,%title%,%filename%)

You see it’s a standard function call with three arguments. Foobar2000 tries to find the title tag. If it is found the command after the first comma is executed and the title of the song displayed. If there is no title tag the filename is shown instead.

If statements can get as complicated as you like. The commands to be executed can be single fields like above; they could as well be several hundred lines of script each.

As with field remapping Tagz provides the means to make our scripting a little easier. The if statement above could be shortened to:

$if2(%title%,%filename%)

Meaning exactly the same thing. And there’s other shortcuts. You may omit the otherwise part.

$if(%title%,%title%)

This would show the title if present and do nothing if the tag is absent. But it’s possible to shorten this even more.

[%title%]

Just put the field name in square brackets. However, this shortcut only works with field names, not with more complex conditions. As a general guideline you should only use it in simple ways like shown here.

Control Flow: The $select() Function

Another function quite similar to $if is called $select(), which evaluates numbers.

$select(%tracknumber%,
%artist%,
%album%)

The first argument (%tracknumber%) is the one to be evaluated and must be numerical. $Select checks the value of this expression and acts accordingly. If %tracknumber% equals one the first following command is executed (%artist%, showing the artist’s name). If %tracknumber% equals two, the second command (%album%) is executed, and so on. You can put as many commands in there as you need.

Commenting the Code

In Tagz a line starting with // is a comment and is ignored completely. You can put anything you like in there. Usually comments describe tricky parts of the code where it might not be obvious on first glance, what the script actually does. And of course they are a great help when you look at your script in half a year.

$select(%tracknumber%,
%artist%,
// This is a comment line
%album%)

For those of you with experience in a ‘real’ programming language it is important to know that only full lines can be made a comment. Therefore:

%artist% // This is NOT a comment

is illegal in Tagz.

String Handling

This is the last section of the introduction, but it might be the most important one, especially if you have some programming experience. The main reason why Tagz scripts always look messier than the source code of a real programming language is Foobar2000’s string handling.

If you input text that is just text and not a function or any other reserved word, Foobar2000 displays that text without any processing. Thus the famous hello-world program looks really boring in Tagz.

Hello, world!

Optionally you may enclose strings in single quotes.

'Hello, world!'

The output will be exactly the same. There are circumstances when the quotes are required, and in my opinion clearly marking strings makes for clearer code. Therefore I enclose all strings in quotes, no matter if those are necessary or not.

While optional quotes may seem quite comfortable at first glance, they have a major drawback. You cannot use indentation to structure your code. Look at these two scripts:

$if(%album tracks%,
  $select(%tracknumber%,
    %artist%,
    %album%,
    %date%
  ),
  $if2(%artist%,%filename%)
)
$if(%album tracks%,
$select(%tracknumber%,
%artist%,
%album%,
%date%
),
$if2(%artist%,%filename%)
)

Deciding, which one is easier to read, should be easy. I can’t imagine anyone not picking the first one. Unfortunately you cannot work with indentation like this in Tagz because Foobar2000 interprets the spaces not as indentation but as actual characters. For tracknumber one of an album the indented version wouldn’t only output the artist’s name but the artist’s name with six leading spaces. Not quite what we intended to do. Take your time to understand where exactly the six spaces come from.

What we learn from this is: Even when it looks ugly, don’t use indentation in Tagz scripts. And this indeed is the last lesson for the introduction. It’s getting serious now.