Difference between revisions of "Expression Language"

From JRiverWiki
Jump to: navigation, search
(Functions - spelling and typo corrections.)
(Formatting Functions)
 
(189 intermediate revisions by 11 users not shown)
Line 1: Line 1:
==Using this page==
+
{{Tocright}}
The 'Contents' box above contains a list of available functions roughly grouped by usage scenario, and each function name gives a fair indication of what it might do. Each of the group headers contain some basic information pertinent to the functions inside the group. Click on a function or function group header in the Contents box to be taken directly to more information about it on the page. At the bottom right of each section there is a "Back to top" link which will take you back up to the Contents box allowing you to quickly get to where on the page you would like to go next.<br>Some of the function descriptions reference other functions to help illustrate their usage. Where this happens, a link to the referenced function is provided if needed. The browser's "Back" button will then return you to the previous place you were at on the page.<br>The page contains some references that link to external pages. Such links can be identified by the little square icon that follows them, [http://yabb.jriver.com/interact like this--->]. These links will not load in new tabs or windows, so, if you would like to keep this page open in your browser, right click on these links and choose to open them in a new tab or window.<br><div style="text-align:right;">([[#top|Back to top)]]</div>
+
Media Center provides a simple programming language that enhances and enriches its overall user interface and usability.
==Overview==
+
This language, commonly called the expression language, is simple to learn, simple to use, and can greatly enhance your experience using Media Center.
  
The J. River Media Core database engine supports Excel-style functions for use in view schemes, searches, displayed columns, and tag editing.
+
Expressions are ubiquitous throughout Media Center, used in areas such as:
 +
:* The categories in a view
 +
:* File list expression columns
 +
:* Theater View
 +
:* Customized view headers, grouping and sort criteria
 +
:* The library field manager (fields with data type Calculated data)
 +
:* File and folder location definitions
 +
:* Auto-import rules
 +
:* Custom DLNA titles
 +
:* The player's display
 +
:* Captions and thumbnail text
 +
:* The link manager (expressions help format link URLs)
 +
:* Rename, Move, & Copy tool
 +
:* Tag assignment
 +
:* Complex search queries
  
An expression is a mixture of text, fields, and functions. A function allows special operations to be performed. Functions are all listed with a name followed by an opening and closing parenthesis. When building expressions, the instructions you wish to pass to the function are placed inside these parenthesis, with multiple instructions separated by commas. When your expression is evaluated, any spaces entered after a comma are ignored. This allows you to compose complex expressions on multiple lines, making it easier to keep track of where you are in your expression. Occasionally, you will find that you want a space, or parenthesis character to be treated literally as part of your instructions, rather than expression syntax, and in these cases, the character is "escaped" by using a preceding forward slash. Examples using this escaping can be seen [[#Clean(...): Returns a cleaned up version of a filled in template|here]] and [[#Replace(...): Replace or remove strings from a value.|here]].
+
An expression is a mixture of ordinary text, pre-defined functions, and a few reserved characters and constructs that have special meaning. An expression is evaluated by Media Center's expression engine and textual output is produced. This output is then used by Media Center to customize the user interface and affect its method of operation.
As you progress with your expression building, you will begin nesting multiple functions into a single expression; always remember that a completed expression must contain a matching number of opening and closing parenthesis in order to work reliably.
 
  
The functions available to us range from highly functional, with a broad range of applicable uses, through specialised, limited use functions that only appeal to a select group of users, to seemingly redundant functions and obscure functions that Media Center uses internally. The functions below are listed with those with the broadest appeal at the top, and the more obscure at the bottom.
+
== The Anatomy of an Expression ==
  
<ins>'''Any given expression can only work on any given single file.  It is not possible to compare a field in one file with a field in another file.'''</ins><br>
+
As mentioned above, an expression is a mixture of text and function calls (and some reserved stuff described shortly).
Batch file operations are possible, and when used in a list, even a grouped list, an expression will be applied to each individual file in turn, not as a group.
+
The simplest expression would be some basic, literal text, such as <span style="font-family: monospace,monospace; font-size:1em;">A good movie</span>.
 +
The expression engine evaluates this expression, finds nothing special, and then outputs the result: <span style="font-family: monospace,monospace; font-size:1em;">A good movie</span>.  Simple.
  
A slightly extended overview  is also available elsewhere in this wiki, titled [http://wiki.jriver.com/index.php/Database_Expressions Database Expressions], and another page attempts to demonstrate Media Center mimicking the [http://wiki.jriver.com/index.php/Database_Expressions_AND_OR_And_XOR "AND",&nbsp;"OR"&nbsp;and&nbsp;"XOR"] database searches.
+
But simple text only has so much utility.
 +
The ability to transform or generate content is much more interesting and useful.
 +
And this is when [[#Functions|functions]] are employed.
 +
Media Center [[#Function Index|provides many functions]], which when called, produce some output.
 +
Most functions require some form of input, called arguments, and most functions generate output.
 +
By supplying a function with various arguments, the function will return some output value which is just more text.
 +
And this output text can be the used by other functions, and so on.
 +
Each function has a unique name, and calling upon a function to do some work requires little more that using its name anywhere in the expression.
  
<div style="text-align:right;">([[#top|Back to top)]]</div>
+
A function call looks like this:
==Using expressions==
 
Expressions are ubiquitous in Media Center, and are useful in a variety of locations such as the following:
 
  
* Player Display (right-click the Player Display , choose "Customize")
+
:{{monospace|<i>functionname</i><b>(</b><i>argument 1</i>, <i>argument 2</i>, ...<b>)</b>}}
* Captions & Thumbnail text
 
* Panes (''aka Categories'')
 
* Expression columns (right-click a column header and choose "Add expression column")
 
* The library field manager (''Create expression-based library fields'')
 
* Theater View
 
* Link manager (''Use expressions to format link URLs'')
 
* Rename, Move, & Copy Files tool
 
  
The syntax of the expression language is generally consistent throughout Media Center. An expression is evaluated, [[#Formatting output|formatting output]] that is used in the context where the expression was evaluated. To perform [[#Tag assignment|Tag assignment]] or [[#Search rule filtering|Search rule filtering]], an expression is modified slightly to work in these contexts.
+
The syntax of the function call is the function's case-insensitive name, immediately followed by an opening parenthesis character, one or more comma-separated arguments, and a closing parenthesis character.
<div style="text-align:right;">([[#top|Back to top)]]</div>
+
Whitespace after the commas is optional, but helps readability and formatting.
 +
And each argument itself is also just an expression. And some arguments are optional.
 +
If an argument is optional, it can be omitted and its default value will be used.
 +
If the argument is omitted, a comma-separator will still be required if additional arguments follow.
 +
The following example uses the [[String_Manipulation_Functions#FixCase|FixCase()]] function to change its input to Title Case:
  
===Formatting output===
+
:{{monospace|fixcase(A good movie)}}
To give usage examples for all of these locations is beyond the scope of this page, so a few tips should suffice to get those interested up and running.
 
  
* Using expressions to produce custom Thumbnail text makes it possible to display only relevant or useful data.
+
The result is <span style="font-family: monospace,monospace; font-size:1em;">A Good Movie</span>.
* Expressions can be used to reduce link bar clutter by conditionally displaying links based on, for example, Media Type.
 
* File and directory paths may be based on expressions; this is especially useful in Options > File Locations, and in the "Rename, Move, & Copy Files" tool.
 
* User-specified library fields may be calculated, based on the output of expressions.
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
===Tag assignment===
+
A slightly more complex expression example consists of both text and a nested function call:
The output of an expression can be used to assign a value to a tag.  This is accomplished by preceding the expression with an "=" character.  The "=" character causes the tagging engine to invoke the expression evaluator first, and then to use its output as the value to assign to the tag.  Without the prepended "=" character, the expression itself (and not its evaluated value) would be stored in the tag.
 
  
An assignment expression can be entered into the Tag Action Window, or by using inline editing in the file list or a pane entry.
+
:{{monospace|Wow! fixcase(replace(A good movie, good, great))}}
  
Note: Undo is supported, reverting each tag to its value prior to the assignment.  Redo is also supported, reapplying the most recent Undo.
+
Inner functions are called before outer functions, so the [[String_Manipulation_Functions#Replace|Replace()]] function is call first:
  
The following screenshots illustrates using an expression for tag assignment:<br>
+
:{{monospace|replace(A good movie, good, great)}}
{| align=center
 
|-
 
|
 
[[image:Inline1.png|frame|Pressing "Enter" copies the Date data into the caption field]]
 
|
 
[[image:Inline2.png|frame|Just like that!]]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
===Search rule filtering===
+
and its output is then supplied as the input to the [[String_Manipulation_Functions#FixCase|FixCase()]] function.
Expressions can be used as search filters, and in order to do so, the expression must be entered into the search field using the following format:<br>
+
[[String_Manipulation_Functions#Replace|Replace()]] does its work substituting {{monospace|good}} with {{monospace|great}}, and returns {{monospace|A great movie}}.
'''[=EXPRESSION]=1''' or '''[=EXPRESSION]=0'''
+
This output is then supplied as the argument to [[String_Manipulation_Functions#FixCase|FixCase()]] which sees only the text {{monospace|A great movie}} (it knows nothing about how it was produced).  So the function call:
  
All files that match the expression will return "1" and all that don't match, return "0". Decide which is required and use "1" or "0" accordingly.
+
:{{monospace|fixcase(A great movie)}}
  
Remember that the search field appears in many places throughout Media Center, places that include:
+
in turn outputs {{monospace|A Great Movie}}.
* The search field itself (in the top right corner of the program)
+
Now that the functions have produced their output, the final output, including the literal {{monospace|Wow!}} leading text is
* A view scheme search list
 
* "Edit Files To Show" area of the Customize View dialogue
 
* Play Radio Files
 
* The last.fm submission filter
 
* The links manager
 
and this method of expression application can be used in all of them.
 
  
An example of an expression formatted for use in the search field would be:
+
:{{monospace|Wow! A Great Movie}}
'''<span style="color:blue">[=<ins>[[#IsEqual(...): Compares two values in one of nine specified modes|isequal]]</ins>(<ins>[[#FormatDate(...): Formats a date value in a specified manner|formatdate]]</ins>([date&nbsp;imported,0],MM//yyyy),formatdate(<ins>[[#Now(...): Retrieve and display the system date|now()]]</ins>,MM//yyyy),1)]=1</span>'''
 
Which will list all files that have been imported this month.
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
==Specify data types for expression based fields==
+
== Fields ==
It is often useful to force Media Center to operate on data of one type as if it were another type. This is useful for changing sort order, or handling list data as a simple string. For example, month names are sorted alphabetically by default, but by setting the data type, sorting can be chronological instead. Data types are forced by appending to an expression the string: '''&datatype=[<span style="color:blue">''DATA TYPE''</span>]''',  where <span style="color:blue">''DATA TYPE''</span> is one of the following values:
+
The expression examples thus far have been limited to static literal text.
 +
Expressions have much more utility when they use data from other sources, such as a file's metadata.
 +
Media Center maintains this metadata in its defined fields.
 +
This data is accessed using the [[Accessing_and_Storing_Functions#Field|Field()]] function, and its first argument is the case-insensitive name of the field to be accessed.
 +
For example, the function call <span style="font-family: monospace,monospace; font-size:1em;">field(album)</span> will return the current* file's value for the album field (* more will be said later about the current file).
 +
If the album field contained the value <span style="font-family: monospace,monospace; font-size:1em;">After Hours</span>, the expression:
  
* '''List''': ''A list of strings, separated by semicolons''
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">fixcase(field(album), 3)</span></div>
* '''String''': ''Sorts as strings (with smart number handling)''
 
* '''Number''': ''Sorts values as numbers (decimal or integer)''
 
* '''Integer''': ''Sorts values as integers''
 
* '''Path''': ''Sorts using a smart filename compare style''
 
* '''Month''': ''Sorts string month names (i.e. January, February, etc.)''
 
  
The following screen images show these data type instructions in action:
+
would produce <span style="font-family: monospace,monospace; font-size:1em;">AFTER HOURS</span>.
 +
First <span style="font-family: monospace,monospace; font-size:1em;">field(album)</span> is evaluated, returning <span style="font-family: monospace,monospace; font-size:1em;">After Hours</span>.
 +
The [[String_Manipulation_Functions#FixCase|FixCase()]] function is supplied with this output as its first argument, and its second argument is <span style="font-family: monospace,monospace; font-size:1em;">3</span>, which happens to specify that it should perform upper-casing.
  
{| align=center
+
Because fields are so frequently used in expressions, an abbreviated form called [[square bracket notation]] exists for accessing their values. This makes it easier to both read and write expressions.
|-valign=top
+
Nonetheless, both forms are equivalent.
! colspan="2" style="background: #ecfeea; color: black; border: 1px solid black" | &DataType=[Month]
+
The abbreviated form is simple: immediately surround the field's name with opening and closing square brackets, for example, <span style="font-family: monospace,monospace; font-size:1em;">[album]</span>.
!
+
The previous example is now written more simply as:
! colspan="2" style="background: #ecfeea; color: black; border: 1px solid black" | &DataType=[List]
 
|-valign=top
 
|
 
[[image:Datatype1.png|left|frame|Used in a pane, '''formatdate([date,0],MMMM)''' returns the months as requested, but the alphabetic order is a little confusing.]]
 
|
 
[[image:Datatype2.png|right|frame|Adding the "month" data type, like so, '''formatdate([date,0],MMMM)&datatype=[month]''', takes care of the order.]]
 
|width=100|&nbsp;&nbsp;&nbsp;
 
|
 
[[image:Datatype3.png|left|frame|No data type has been specified, so the expression results are presented literally, as individual string values.]]
 
|
 
[[image:Datatype4.png|right|frame|Add the "list" data type to the expression and it is then formatted correctly in the pane. Here, the [[#ListBuild(...): Build a list from a series of values|ListBuild]] function has been used to create a nested browsing tree.]]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
==Fields==
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">fixcase([album], 3)</span></div>
  
Any text between brackets [] will be replaced with the corresponding field from your library. As an example, [Artist] would be replaced by Bob Dylan for any Bob Dylan tracks.  If the text between brackets doesn't match any known fields, it will be left alone, [My Fake Artist] will be treated literally, square brackets and all. After the field name, a comma can be placed followed by a 0 or 1 to indicate whether the field should be formatted.  So, [Duration] and [Duration, 1] will give "4:02" while [Duration, 0] will give "242". This is particularly important when working with the "Format" functions, where most times you will want the evaluator to work with the raw field contents rather than the formatted contents you see in the file list.
+
=== Field Values ===
 +
For the sake of simplicity and clarity, the section above glossed over an important detail regarding how
 +
Media Center outputs field values.
 +
Recall that [[Accessing_and_Storing_Functions#Field|Field()]] is the function used to return the value of a specified field.
 +
But [[Accessing_and_Storing_Functions#Field|Field()]] also has a second argument that indicates the format of the value that it returns.
 +
Because field values are used in a variety of situations, the [[Accessing_and_Storing_Functions#Field|Field()]] function can produce output suitably formatted for the requirements.
 +
There are two forms of output: one is a nice, friendly human-readable format suitable for use in views or other display locations; the other is a raw format which returns the representation stored internally by Media Center which is useful when uninterpreted values are necessary.
  
Function and field values in expressions are ''not'' case-sensitive.
+
By default, Media Center <i>always</i> outputs the friendly format, so expressions sometimes need to take this into account and chose the format accordingly.
Available functions with descriptions and examples are listed below.
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
==Functions==
+
Not used earlier because it is optional, the second argument to the [[Accessing_and_Storing_Functions#Field|Field()]] function selects the mode of output:
===Accessing and Storing Functions===
+
the value <span style="font-family: monospace,monospace; font-size:1em;">0</span> selects the raw mode, and the default value of <span style="font-family: monospace,monospace; font-size:1em;">1</span> selects the friendly mode.
 +
Here are two examples using the date field, the first one outputs the date value in raw format, the second in the friendly format:
  
The functions in this section access field values, store and load global variables,
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">field(date, 0)</span></div>
access file tags, and access note fields.
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">field(date, 1)</span></div>
====Field(&hellip;): Returns a field's value====
 
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
==== Field Values: Override the expression, and [This] ====
|- id="Field" valign="top"
+
[[File:ExpressionOverride.png|right]]
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
When creating (or editing) an expression based field, there is an option, shown in the image on the right, to "Allow custom data to override the expression".
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>field(</b><i>name</i><b>, </b><i>mode</i><b>)</b></span>
+
When enabled, it becomes possible to open the tag for editing either inline or in the tag window, just as you would any other regular tag, and replace the expression derived data with any other static data. Complex expression based fields can very easily slow view loading times to a crawl, and in many cases, this option can help speed things up again. Imagine an expression based field that manipulates another, otherwise static field, such the [Date] field. The returned expression values will never change, so why waste time evaluating the same results over and over, when you can simply replace them with static data and so forego any future expression processing?
The [[#Field|Field()]] function returns the value stored in field <i>name</i>.
 
The format of return is selected by <i>mode</i>.
 
  
Available <i>mode</i> values:
+
Media Center 28 saw the introduction of a [https://yabb.jriver.com/interact/index.php/topic,124543.msg906895.html#msg906895 [This]] variable that can also be invoked, so, using the example, ''=removeleft([This], 4)'' would remove four characters from the left of "this field".
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Raw, unformatted data</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Formatted data</td></tr>
 
</table></div>
 
  
Argument <i>mode</i> is optional (defaults to 1).
+
The new [This] variable can be used to override expression data. Select one, or 1000s of files, then edit, either inline or in the tag window, using the simple expression ''=[this]'' and apply to have MC replace the expression result with, the expression result, which from that point forwards, will be static data and the expression will no longer run ''<u>for those files</u>''.
  
|- valign="top"
+
To remove the static data and return to expression evaluated data instead, simply edit again, deleting the static data, which when applied, will cause the expression evaluated result to return.
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>field(album)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the formatted value of field <i>name</i> <span style="font-family: Consolas, monospace;">album</span>.
 
Note that this is equivalent to <span style="font-family: Consolas, monospace;">[album]</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>field(date, 0)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the raw, unformatted value stored in the <span style="font-family: Consolas, monospace;">date</span> field.
 
Note that this is equivalent to <span style="font-family: Consolas, monospace;">[date,0]</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====Load(&hellip;): Outputs the value of a global variable====
+
'''<u>Note:</u>''' Use this "override" option with care. It requires least maintenance when used in situations where ''all'' expression values for all files for that field will be replaced with static data. Currently (October 2022) there is no way to differentiate between static data and expression derived data meaning the potential for things to get very confusing, very quickly, is very high indeed.
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
'''<u>Note 2:</u>''' MC32 comes with the addition of the [[IsOverridden()|IsOverridden(...)]] function that now allows us to filter any given expression based field based on its override status.
|- id="Load" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>load(</b><i>varname</i><b>)</b></span>
 
Loads and outputs the value of the specified global variable <i>varname</i> that has been previously stored with [[#Save|Save()]].
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>load(var1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Loads and outputs the previous stored value of the global variable named <span style="font-family: Consolas, monospace;">var1</span>.
 
If <span style="font-family: Consolas, monospace;">var1</span> has not been previously stored, the output will be empty.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>save(math(1 + 2), sum)load(sum)</nowiki></b></span>
 
<p style="margin-left:20pt;">Saves the output of the [[#Math|Math()]] function into <span style="font-family: Consolas, monospace;">sum</span>, and then loads and outputs the value of <span style="font-family: Consolas, monospace;">sum</span>, which is <span style="font-family: Consolas, monospace;">3</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====Note(&hellip;): Retrieve note fields====
+
==== Field Values: Empty, 0, and 1 ====
 +
The Media Center expression language does not strongly differentiate between the numeric value zero <span style="font-family: monospace,monospace; font-size:1em;">0</span> and emptiness
 +
for numeric field types Integer and Decimal.
 +
And in some cases, the numeric value of <span style="font-family: monospace,monospace; font-size:1em;">1</span> is treated similarly to the empty value.
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
When a value of 0 is entered as a numeric field's value, the raw value will be shown as <span style="font-family: monospace,monospace; font-size:1em;">0</span>,
|- id="Note" valign="top"
+
but the display format (as in the file list) will be shown as empty.
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
The empty display allows for less visual noise in the user interface, since a column full of <span style="font-family: monospace,monospace; font-size:1em;">0</span> values is not usually helpful.
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>note(</b><i>field label</i><b>, </b><i>field type</i><b>, </b><i>occurrence</i><b>)</b></span>
+
In fact, if you attempt to set a numeric field's value to <span style="font-family: monospace,monospace; font-size:1em;">0</span> in the file list, it will immediately be displayed as empty.
The [[#Note|Note()]] function retrieves information from a Media Center Note.
 
Specifically, it returns the contents associated with a <i>field label</i>, of a given <i>field type</i>.
 
The Nth <i>occurrence</i> may be requested.
 
Notes data may be simple text, or associated with defined a <i>field label</i>.
 
Currently the only type of <i>field label</i> is contact information.
 
The first line of a Note is associated with the omnipresent <i>field label</i> <span style="font-family: Consolas, monospace;">Name</span>.
 
  
The <i>field type</i> selects the specific sub-type for a given <i>field label</i>, and <i>occurrence</i> selects which instance of
+
Generally this difference is unimportant, except when testing numeric values with [[Test_and_Comparison_Functions#IsEmpty|IsEmpty()]] or [[Test_and_Comparison_Functions#IsEqual|IsEqual()]].
several <i>field label</i> / <i>field type</i> pairs is returned. The <i>occurrence</i> value is zero-based.
+
It is easy to be fooled when testing such a value if the value shown in a file list is empty.
 +
The values shown in the Tag Action Window will reveal the actual raw value, as will an expression column using the field's raw format.
  
Argument <i>field type</i> is optional (defaults to FIRST AVAILABLE).
+
Another consideration for integer fields is that when sorting, a <span style="font-family: monospace,monospace; font-size:1em;">1</span> value can sometimes sort indistinguishably from an empty value.
 +
The Integer type <span style="font-family: monospace,monospace; font-size:1em;">disc #</span> field is typically empty when an album consists of only one disc, and as such, Media Center will sort
 +
the <span style="font-family: monospace,monospace; font-size:1em;">disc #</span> values of empty (<span style="font-family: monospace,monospace; font-size:1em;">0</span>) and <span style="font-family: monospace,monospace; font-size:1em;">1</span> identically.
  
Argument <i>occurrence</i> is optional (defaults to 0).
+
The friendly output of a field can differ, depending on context.
 +
For example, in a file list, and empty field will be shown as blank, but in the Rename, Move & Copy tool,
 +
it will be output as <span style="font-family: monospace,monospace; font-size:1em;">Unknown Disc #</span> (this ensures no blank values are generated as path components).
 +
To test such a field, always use and test against the raw format, and then expressions will be context agnostic.
  
|- valign="top"
+
===Field Assignment===
! scope="row" style="background: #ecedf3; color: #111; " | Examples
+
<div>
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>note(phone)</nowiki></b></span>
+
The output of an expression can be used to assign a value to a tag.
<p style="margin-left:20pt;">Returns the value found in the first <span style="font-family: Consolas, monospace;">Phone</span> <i>field label</i>.  If no <span style="font-family: Consolas, monospace;">Phone</span> label exists, nothing is returned.</p>
+
This is accomplished by preceding the expression with an <span style="font-family: monospace,monospace; font-size:1em;">=</span> character.
<span style="font-family: Consolas, monospace;"><b><nowiki>note(phone, home)</nowiki></b></span>
+
The <span style="font-family: monospace,monospace; font-size:1em;">=</span> character causes the tagging engine to invoke the expression evaluator first,
<p style="margin-left:20pt;">Returns the value found in the first <span style="font-family: Consolas, monospace;">Home</span> <i>field type</i> from the <span style="font-family: Consolas, monospace;">Phone</span> <i>field label</i>.
+
and then to use its output as the value to assign to the field.
If the <span style="font-family: Consolas, monospace;">Phone</span> label, <span style="font-family: Consolas, monospace;">Home</span> type does not exists, nothing is returned.</p>
+
[[File:Field_Assignment_with_Expression.png|right]]
<span style="font-family: Consolas, monospace;"><b><nowiki>note(phone, home, 1)</nowiki></b></span>
+
Without the prepended <span style="font-family: monospace,monospace; font-size:1em;">=</span> character, the literal expression text itself and not its evaluated value would be stored in the tag.
<p style="margin-left:20pt;">Same as the previous example, but the second instance of the <i>field type</i> is selected instead of the first, since <i>occurrence</i> is zero-based.</p>
+
The expression can refer to the field's own value to modify itself, and this offers a convenient way to perform complex transformations on field values.
|}
+
For example, the assignment expression
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====Save(&hellip;): Saves a value to a global variable====
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">=removeleft([name], 4)</span></div>
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
entered into an edit cell for the  <span style="font-family: monospace,monospace; font-size:1em;">name</span> field would remove
|- id="Save" valign="top"
+
four characters from the left of the <span style="font-family: monospace,monospace; font-size:1em;">name</span> field's current value.
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
An assignment expression can be entered into the Tag Action Window, or by using inline editing in the file list or a pane entry.
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>save(</b><i>value</i><b>, </b><i>variable</i><b>, </b><i>mode</i><b>)</b></span>
+
The image on the right shows in-place field assignment.
This [[#Save|Save()]] function saves the <i>value</i> into the specified global <i>variable</i>, and optionally will return that <i>value</i> if <i>mode</i> is set.
 
Once a global <i>variable</i> has been created using [[#Save|Save()]], that <i>variable</i>'s <i>value</i> is available for use with either [[#Load|Load()]] or the pseudo-field "[<i>variable</i>]".
 
  
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
+
Note: Undo is supported, reverting each tag to its value prior to the assignment.
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Suppress output</td></tr>
+
Redo is also supported, reapplying the most recent Undo.
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Output variables <i>value</i></td></tr>
+
</div>
</table></div>
 
 
 
Argument <i>mode</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>save(Much Money, local_bank)</nowiki></b></span>
 
<p style="margin-left:20pt;">Saves the <i>value</i> <span style="font-family: Consolas, monospace;">Much Money</span> into the global <i>variable</i> <span style="font-family: Consolas, monospace;">local_bank</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>save(More Money, My Bank, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Saves <span style="font-family: Consolas, monospace;">More Money</span> into <span style="font-family: Consolas, monospace;">My Bank</span> and outputs the variables <i>value</i> <span style="font-family: Consolas, monospace;">More Money</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>save(math([duration,0] / 60), durmins)if(compare([durmins], &gt;, 5.0), Long Track, Short Track)</nowiki></b></span>
 
<p style="margin-left:20pt;">Saves the calculated duration in minutes into the <i>variable</i> <span style="font-family: Consolas, monospace;">durmins</span>.
 
Notice that subsequent expressions fragments such as the <span style="font-family: Consolas, monospace;">if(compare()...)</span> may now use the pseudo-field <span style="font-family: Consolas, monospace;">[durmins]</span> as shorthand
 
for <span style="font-family: Consolas, monospace;">load(durmins)</span>.</p>
 
 
 
Additional Examples
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=77826.0 Generating statistics]
 
  
:[http://yabb.jriver.com/interact/index.php?topic=76581.msg518902#msg518902 Generating album track count]
+
== Expression Language Syntax ==
 +
Now that the basics have been covered, the more rigorous rules of the expression language syntax can be described.
  
:[http://yabb.jriver.com/interact/index.php?topic=72049.0 Generating album ratings]
+
:* An expression is any sequence of literal text and any number of function calls.
 +
:* Expressions are read and evaluated left to right. Literal text is output unmodified, function calls are evaluated and their return values output.
 +
:* Fields designated using [[square bracket notation]] are expanded into the equivalent [[Accessing_and_Storing_Functions#Field|Field()]] function call.
 +
:* Nested function calls are evaluated from the innermost function to outermost function, and again, left to right when one function follows another.
 +
:* A function is evaluated and its returned value contextually replaces the function call in the expression
 +
:* Within a function's argument list, whitespace is ignored before and after commas, after an opening parenthesis, and before a closing parenthesis.
 +
:* The forward-slash escape character <span style="font-family: monospace,monospace; font-size:1em;">/</span> disables the special meaning of the character that follows it.
 +
:* The escape sequence <span style="font-family: monospace,monospace; font-size:1em;">/#</span> followed by <span style="font-family: monospace,monospace; font-size:1em;">#/</span> escapes everything inside.
 +
:* The escape sequence <nowiki>/* followed by /*</nowiki> will escape everything inside returning it as given without formatting or processing.
 +
:* To use a literal parenthesis, comma, or whitespace inside of function argument lists, escape them.  Whitespace within an argument's value is literal and does not need to be escaped when it is surrounded by other non-whitespace text.
 +
:* An expression may be split into multiple lines, but when it does not satisfy the conditions above regarding whitespace around function parenthesis and commas, use a forward-slash escape as the last character before the newline.  Extraneous newlines in the expression editor will produce a trailing ellipsis (...) in the output.
  
:[http://yabb.jriver.com/interact/index.php?topic=74116.0 Highlighting playing album]
+
=== How Expressions Are Evaluated ===
|}
+
Expressions are evaluated in the context where they are used.
<div style="text-align:right;">([[#top|Back to top)]]</div>
+
For example, an expression column in a file list is evaluated relative to those files in the file list.
 +
And the general flow is that for each file in the list, the expression is evaluated and produces output.
 +
The expression only has access to the fields available for the file currently being evaluated.
 +
This is important to remember, so it bears repeating.
 +
One file after another, an expression is evaluated against that single file, its output is produced and stored away for use later,
 +
and then the result of that evaluation is entirely forgotten before the next file is evaluated.
 +
This means, the expression evaluator cannot use the results from one file's evaluated expression with the results of another
 +
file's evaluation.
  
====SaveAdd(&hellip;): Adds to a global variable====
+
=== Expressions and Locales ===
 +
Media Center will respect the Windows locale setting for output values produced by certain functions,
 +
and within the values of certain fields.
 +
This is important to consider when writing expressions that consume such values.
 +
Under most circumstances, such values cause no harm.
 +
However special care must be taken with functions that require the use of period as the decimal point.
 +
One such function is [[Miscellaneous_Functions#Math|Math()]], which always uses period as the decimal point.
 +
If your locale uses some other character such as comma, these characters will have to be converted into periods before the
 +
critical function is called.
 +
Handling this problem is not difficult. Before passing to [[Miscellaneous_Functions#Math|Math()]] any floating point number,
 +
use [[String_Manipulation_Functions#Replace|Replace()]] first when necessary to convert the locale's decimal character into a period.
 +
Fields that cause problems are any fields that produce floating-point values,
 +
such as any Date type field in raw format (e.g. <span style="font-family: monospace,monospace; font-size:1em;">[date,0]</span>, <span style="font-family: monospace,monospace; font-size:1em;">[last played,0]</span>, <span style="font-family: monospace,monospace; font-size:1em;">[date modified,0]</span>, and <span style="font-family: monospace,monospace; font-size:1em;">[date imported,0]</span>),
 +
or any textual field that contains floating-point values that will be used for various calculations
 +
(e.g. any of the Dynamic Range variants).
 +
Certain functions such as [[Date_and_Time_Functions#Now|Now()]] and [[Date_and_Time_Functions#ConvertTime|ConvertTime()]] also return localized floating-point values.
 +
Consider also that the expression parser uses comma as the argument separator.
 +
Any literal numeric values specified as a function argument must have any embedded commas escaped.
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
=== A Complex Expression Example ===
|- id="SaveAdd" valign="top"
+
[[File:Expression_Editor.png|right]]
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
Here is a more complex expression example that illustrates the various rules discussed above regarding expressions:
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>saveadd(</b><i>variable</i><b>, </b><i>value</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#SaveAdd|SaveAdd()]] function adds <i>value</i> to a global <i>variable</i> either numerically or as a list item.
 
The <i>mode</i> argument indicates how <i>variable</i> is modified.
 
  
Available <i>mode</i> values:
+
<span style="font-family: monospace,monospace; font-size:1em;">
 +
<div style="margin-left: 20pt">if(  IsEmpty(  [Disc #]  ),</div>
 +
<div style="margin-left: 40pt">Disc number is empty,</div>
 +
<div style="margin-left: 40pt">Delimit(</div>
 +
<div style="margin-left: 60pt">field(disc #) , </div>
 +
<div style="margin-left: 60pt">/)    ,</div>
 +
<div style="margin-left: 60pt">DISC /(</div>
 +
<div style="margin-left: 40pt">)</div>
 +
<div style="margin-left: 20pt">)</div>
 +
</span>
  
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
+
The expression demonstrates that
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Add numeric <i>value</i> (integer or decimal) to <i>variable</i></td></tr>
+
:* whitespace before and after commas or opening and closing parenthesis is ignored
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Append string <i>value</i> as a list item to <i>variable</i></td></tr>
+
:* expressions can be safely split into multiple lines using the whitespace rules just mentioned
<tr><td style="text-align:left; padding-right:20pt"><b>2</b></td><td>Prepend string <i>value</i> as a list item to <i>variable</i></td></tr>
+
:* function and field names are case insensitive
</table></div>
+
:* forward slash is used and required to escape parenthesis (see inside the [[Formatting_Functions#Delimit|Delimit()]] function)
 +
:* whitespace does not require escapement when surrounded by other characters (see after the <span style="font-family: monospace,monospace; font-size:1em;">C</span> in <span style="font-family: monospace,monospace; font-size:1em;">DISC</span>)
 +
:* literal text is output unmodified (<span style="font-family: monospace,monospace; font-size:1em;">Disc number is empty</span>)
 +
:* functions can be nested (Both [[Test_and_Comparison_Functions#IsEmpty|IsEmpty()]] and [[Formatting_Functions#Delimit|Delimit()]] are nested within the [[Conditional_Functions#If|If()]] function, and the [[Accessing_and_Storing_Functions#Field|Field()]] function is nested within [[Formatting_Functions#Delimit|Delimit()]]
  
Argument <i>mode</i> is optional (defaults to 0).
+
When the expression is run, files that have no disc number will produce <span style="font-family: monospace,monospace; font-size:1em;">Disc number is empty</span>,
 +
and files that have, say, a disc number value of <span style="font-family: monospace,monospace; font-size:1em;">3</span> will produce <span style="font-family: monospace,monospace; font-size:1em;">DISC (3)</span>.
  
|- valign="top"
+
== Functions ==
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>saveadd(v, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Numerically increments the global <i>variable</i> <span style="font-family: Consolas, monospace;">v</span> by <span style="font-family: Consolas, monospace;">1</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>saveadd(v, math(2 - 6))</nowiki></b></span>
 
<p style="margin-left:20pt;">Numerically increments the global <i>variable</i> <span style="font-family: Consolas, monospace;">v</span> by the outcome of the [[#Math|Math()]], which is <span style="font-family: Consolas, monospace;">-4</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>load(foo, v)saveadd(v, bar, 1)load(v)</nowiki></b></span>
 
<p style="margin-left:20pt;">Loads <i>value</i> <span style="font-family: Consolas, monospace;">foo</span> into <i>variable</i> <span style="font-family: Consolas, monospace;">v</span>, then appends the <i>value</i> <span style="font-family: Consolas, monospace;">bar</span> as a list item, and the final <span style="font-family: Consolas, monospace;">load(v)</span> expression outputs the
 
result of <span style="font-family: Consolas, monospace;">foo; bar</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>load(That, v)saveadd(v, This, 2)load(v)</nowiki></b></span>
 
<p style="margin-left:20pt;">Similar to the previous example, but using the prepend <i>mode</i>, resulting in the output <span style="font-family: Consolas, monospace;">This; That</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====Tag(&hellip;): Returns a file's physical tag====
+
Functions enable you to transform or generate content automatically. For background information on how functions are used in expressions, refer to [[#The Anatomy of an Expression|The Anatomy of an Expression]] section above.
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
This section describes all the various functions provided by Media Center's Expression Language.
|- id="Tag" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>tag(</b><i>tag name</i><b>)</b></span>
 
The [[#Tag|Tag()]] function reads and returns the value of <i>tag name</i> directly from a file.
 
The Media Center Library database is not used with [[#Tag|Tag()]], and instead the specified file is read for the requested tag.
 
The spelling and letter case of the <i>tag name</i> must match exactly those stored in the file.
 
Performance note: This function must open and read the actual file, so its performance is significantly slower than other functions which
 
operate on database fields.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>tag(My Personal Tag)</nowiki></b></span>
 
<p style="margin-left:20pt;">This will return the value from the tag named <span style="font-family: Consolas, monospace;">My Personal Tag</span> from file referenced by the <span style="font-family: Consolas, monospace;">[filename]</span> field.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>tag(Gapless Header)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the <span style="font-family: Consolas, monospace;">Gapless Header</span> tag value, often contained in an mp3 file.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>tag(exif: Date)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the raw date data from the EXIF data saved inside a jpg file.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
===Conditional Functions===
+
=== Function Arguments ===
  
The functions in this section test one or more arguments to produce either a true or false outcome, and execute specific actions depending upon that result.
+
As discussed [[#The_Anatomy_of_an_Expression|above]], a function call consists of the function's case-insensitive name, immediately followed by an opening parenthesis character, one or more comma-separated arguments, and a closing parenthesis character:
  
The expression language does not directly support AND, OR, and XOR operations.
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;"><i>functionname</i><b>(</b><i>argument 1</i>, <i>argument 2</i>, ...<b>)</b></span></div>
However, these can be easily emulated using any of several techniques. See: [[Database_Expressions_AND_OR_And_XOR]].
 
  
The NOT operator <span style="font-family: Consolas, monospace;"><b>!</b></span> (exclamation point) may be used in a conditional to invert the sense of the conditional test.  Inverting the sense of a test can make reading expressions easier, or support better [[#IfElse|IfElse()]] sequences.
+
Functions may have one or more arguments. In some cases, these arguments are optional, and will automatically use a default value if omitted. For example, these two expressions are equivalent because the mode argument for [[Test_and_Comparison_Functions#IsEmpty|IsEmpty()]] is optional and defaults to 0:
====If(&hellip;): Conditional if-else evaluator====
+
:<span style="font-family: monospace,monospace; font-size:1em;">isempty([comment], 0)</span>
 +
:<span style="font-family: monospace,monospace; font-size:1em;">isempty([comment])</span>
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
In this case, a comma-separator will still be required if additional arguments follow the optional one. Whitespace after the commas is also optional, but helps readability and formatting. However, if any extra arguments are included in a function call which are not valid for that function, they are dropped and omitted from output. This is of particular importance when using string-manipulation functions on text. If the text you enter contains any commas, these must be escaped or the expression engine will consider text after the comma to be additional arguments.
|- id="If" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>if(</b><i>test expression</i><b>, </b><i>true expression</i><b>, </b><i>false expression</i><b>)</b></span>
 
The [[#If|If()]] function is used to evaluate a <i>test expression</i>, and will output the result of the <i>true expression</i> or <i>false expression</i>, depending upon the evaluation result.  The <i>test expression</i> is expected to return a 0 (false value) or a non-zero (true value).
 
Nesting is allowed.
 
If the <i>test expression</i> is preceded by the NOT operator (!, an exclamation point), the sense of the test is inverted.  Non-zero values are inverted to 0, and 0 is inverted to 1.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>if(isequal([artist], bob dylan, 1), Genius, Mediocre)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs <span style="font-family: Consolas, monospace;">Genius</span> when artist is (case insensitive) Bob Dylan and <span style="font-family: Consolas, monospace;">Mediocre</span> otherwise.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(isequal([artist], bob dylan, 1), Genius, if(isequal([album], Joshua Tree, 8), Great Album, Mediocre))</nowiki></b></span>
 
<p style="margin-left:20pt;">This nested [[#If|If()]] expression expands on the previous example, by first evaluating if the artist is Bob Dylan, and outputs <span style="font-family: Consolas, monospace;">Genius</span> if true.
 
When the artist is not Bob Dylan, the album is then tested to see if it is <span style="font-family: Consolas, monospace;">Joshua Tree</span>, and if so outputs <span style="font-family: Consolas, monospace;">Great Album</span>, otherwise outputs <span style="font-family: Consolas, monospace;">Mediocre</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(!isempty([comment]), regex([comment], /#^(\\S+\\s+\\S+\\s+\\S+)#/, 1), *No Comment)</nowiki></b></span>
 
<p style="margin-left:20pt;">Output's the first three words of the comment field; otherwise, outputs *No Comment.  By using the NOT operator, the sense of the conditional is inverted so that the more interesting case is moved ahead of the more mundane case.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====IfElse(&hellip;): Conditional if-elseif evaluator====
+
The arguments themselves are also just expressions, and you can nest multiple functions to achieve complex logic:
 +
:<span style="font-family: monospace,monospace; font-size:1em;">if(isequal([artist], [album], 1), Eponymous, [album])</span>
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
Nested function calls are always treated as a ''single'' argument when used as the input to another function (so that commas in the output of one function do not need to be escaped to be used as input in another function). This includes fields, since they are expanded to the equivalent [[Accessing_and_Storing_Functions#Field|Field()]] function call.
|- id="IfElse" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>ifelse(</b><i>test1</i><b>, </b><i>action1</i><b>, </b><i>test2</i><b>, </b><i>action2</i><b>, </b><i>test3</i><b>, </b><i>action3</i><b>, </b><i>&hellip;</i><b>)</b></span>
 
The [[#IfElse|IfElse()]] conditional provides a convenient mechanism for shortening and more clearly expressing nested conditionals into an alternating sequence of tests and actions.
 
One or more test/action pairs may be specified.
 
  
For example, consider a nested sequence of [[#If|If()]] tests such as the following pseudo-code:
+
:'''''Please Note:''''' In some cases below, such as with [[String_Manipulation_Functions#Unswap|Unswap()]], we have ignored this detail in order to simplify the examples. If you enter any text manually into a function, all commas ''must be'' escaped in order to achieve the correct result. This detail is unimportant in most real-world usages, however, because you will typically use either field values or the output of other functions as the arguments in your expressions. However, if you need to include commas in a string literal argument to a function, you need to escape every one, or block escape the entire argument.
<div style="font-family: Consolas, monospace;">
 
<div style="margin-left: 20pt">if (<i>test1</i>)</div>
 
<div style="margin-left: 40pt"><i>action1</i></div>
 
<div style="margin-left: 20pt">else if (<i>test2</i>)</div>
 
<div style="margin-left: 40pt"><i>action2</i></div>
 
<div style="margin-left: 20pt">else if (<i>test3</i>)</div>
 
<div style="margin-left: 40pt"><i>action3</i></div>
 
</div>
 
  
The [[#IfElse|IfElse()]] statement may be used to more cleanly express the flow of expression by removing the superfluous internal [[#If|If()]] statements, converting the clumsy expression:
+
=== [[Function Index]] ===
 +
Unfortunately, ''when'' these were actually introduced has ''not'' been tracked. The only way to be certain you have access to all of the functions below is to make sure you have the most current build of Media Center installed.<br>
 +
The available functions are grouped below based on the type of operation they might perform. If you prefer, a [[Complete Expression Language Alphabetical List|flat, alphabetically sorted function list is available here.]]<br>
 +
Over time, as Media Center evolves, expression functions are added or changed. Those changes are typically not reflected here immediately. In the list available [https://yabb.jriver.com/interact/index.php/topic,125477.msg868288.html#msg868288 here, on interact], any entries in red text are currently missing from these wiki pages.
  
<div style="margin-left: 20pt"><span style="font-family: Consolas, monospace;">if(<i>test1</i>, <i>action1</i>, if(<i>test2</i>, <i>action2</i>, if(<i>test3</i>, <i>action3</i>)))</span></div>
+
==== [[Accessing and Storing Functions]] ====
 +
* '''[[Accessing_and_Storing_Functions#Field|Field(&hellip;)]]''': Returns a field's value.
 +
* '''[[Accessing_and_Storing_Functions#FieldQuery|FieldQuery(&hellip;)]]''': Return a list of matches based on a list of fields to search, from a selected scope of files.
 +
* '''[[Accessing_and_Storing_Functions#ItemCount|ItemCount(&hellip;)]]''': Counts the number of files that have the exact same value of the given expression as the file the expression runs in the context of.
 +
* '''[[Accessing_and_Storing_Functions#Load|Load(&hellip;)]]''': Outputs the value of a [[global variable]].
 +
* '''[[Accessing_and_Storing_Functions#Note|Note(&hellip;)]]''': Retrieve note fields.
 +
* '''[[Accessing_and_Storing_Functions#Save|Save(&hellip;)]]''': Saves a value to a [[global variable]].
 +
* '''[[Accessing_and_Storing_Functions#SaveAdd|SaveAdd(&hellip;)]]''': Adds to a [[global variable]].
 +
* '''[[Accessing_and_Storing_Functions#SetField|SetField(&hellip;)]]''': Sets a field's value.
 +
* '''[[Accessing_and_Storing_Functions#Tag|Tag(&hellip;)]]''': Returns a file's physical tag.
  
into the more elegant:
+
==== [[Conditional Functions]] ====
 +
* '''[[Conditional Functions#And|And(&hellip;)]]''': Tests a set of values and returns 1 if all are true.
 +
* '''[[Conditional Functions#FirstNotEmpty|FirstNotEmpty(&hellip;)]]''': Returns the first non-empty argument.
 +
* '''[[Conditional Functions#If|If(&hellip;)]]''': Conditional ifelse evaluator.
 +
* '''[[Conditional Functions#IfCase|IfCase(&hellip;)]]''': Functions as a switch or select case statement.
 +
* '''[[Conditional Functions#IfElse|IfElse(&hellip;)]]''': Conditional if-elseif evaluator.
 +
* '''[[Conditional Functions#Not|Not(&hellip;)]]''': Negates the results of funtions.
 +
* '''[[Conditional Functions#Or|Or(&hellip;)]]''': Tests a set of values and returns 1 if any are true.
  
<div style="margin-left: 20pt"><span style="font-family: Consolas, monospace;">ifelse(<i>test1</i>, <i>action1</i>, <i>test2</i>, <i>action2</i>, <i>test3</i>, <i>action3</i>)</span></div>
+
==== [[Date and Time Functions]] ====
 +
* '''[[Date and Time Functions#CompareDates|CompareDates(&hellip;)]]''': Compares two dates, returning a formatted elapsed period between them
 +
* '''[[Date and Time Functions#ConvertDate|ConvertDate(&hellip;)]]''': Converts a human-readable date to the internal format required for use in date fields
 +
* '''[[Date and Time Functions#DateInRange|DateInRange(&hellip;)]]''': Compares a date with a range of dates
 +
* '''[[Date and Time Functions#FormatDate|FormatDate(&hellip;)]]''': Formats a date value in a specified manner
 +
* '''[[Date and Time Functions#Now|Now(&hellip;)]]''': Retrieve and display the system date
 +
* '''[[Date and Time Functions#PlaylistTime|PlaylistTime(&hellip;)]]''': Returns the time of a track in the current playlist (a sum of all previous durations)
  
If any of the test expressions <i>test1</i>, etc. are preceded by the NOT operator (!, an exclamation point), the sense of that test is inverted.  Non-zero values are inverted to 0, and 0 is inverted to 1.
+
==== [[File Path and Identifier Functions]] ====
|- valign="top"
+
* '''[[File Path and Identifier Functions#DBLocation|DBLocation(&hellip;)]]''': Identifies a file's databases
! scope="row" style="background: #ecedf3; color: #111; " | Examples
+
* '''[[File Path and Identifier Functions#Enviro|Enviro(&hellip;)]]''': Returns the full path to a host system variable
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>ifelse(isequal([media type], Audio), Le Tunes, isequal([media type], Video]), Flix)</nowiki></b></span>
+
* '''[[File Path and Identifier Functions#FileDBLocation|FileDBLocation(&hellip;)]]''': Identifies a file's databases
<p style="margin-left:20pt;">If media type is audio, outputs <span style="font-family: Consolas, monospace;">Le Tunes</span>, else if media type is video, outputs <span style="font-family: Consolas, monospace;">Flix</span></p>
+
* '''[[File Path and Identifier Functions#FileFolder|FileFolder(&hellip;)]]''': Returns the name of a file's parent
<span style="font-family: Consolas, monospace;"><b><nowiki>ifelse(isequal([artist], Bob Dylan), Genius, isequal([album], Joshua Tree, 8), Great Album, 1, Mediocre)</nowiki></b></span>
+
* '''[[File Path and Identifier Functions#FileKey|FileKey(&hellip;)]]''': Returns a file's unique internal identifier
<p style="margin-left:20pt;">This example, implements the nested if statements from the If() section above,
+
* '''[[Miscellaneous Functions#FileLookup()|FileLookup()]]''': Looks up a file based on its filename
first testing if the artist is Bob Dylan, and if true, outputs <span style="font-family: Consolas, monospace;">Genius</span>,
+
* '''[[File Path and Identifier Functions#FileName|FileName(&hellip;)]]''': Returns a file's name component
otherwise evaluates the second test to determine if the album is <span style="font-family: Consolas, monospace;">Joshua Tree</span>,
+
* '''[[File Path and Identifier Functions#FilePath|FilePath(&hellip;)]]''': Returns a file's path component
and if true, outputs <span style="font-family: Consolas, monospace;">Great Album</span>, otherwise, performs a final test,
+
* '''[[File Path and Identifier Functions#FileVolume|FileVolume(&hellip;)]]''': Returns a file's volume name component
in this case a degenerate test of 1 (and 1 is always true), thus outputting the value <span style="font-family: Consolas, monospace;">Mediocre</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====FirstNotEmpty(&hellip;): Returns the first non-empty argument====
+
==== [[Formatting Functions]] ====
 +
* '''[[Formatting Functions#Decimal|Decimal(&hellip;)]]''': Standardises the decimal point to be a dot rather than a comma
 +
* '''[[Formatting Functions#Delimit|Delimit(&hellip;)]]''': Outputs a value with head/tail strings when value is non-empty
 +
* '''[[Formatting Functions#FormatBoolean|FormatBoolean(&hellip;)]]''': Formats a boolean (true / false) value in a specified manner
 +
* '''[[Formatting Functions#FormatDuration|FormatDuration(&hellip;)]]''': Presents a duration of seconds in a reader friendly format
 +
* '''[[Formatting Functions#FormatFileSize|FormatFileSize(&hellip;)]]''': Presents a number of bytes in a reader friendly format
 +
* '''[[Formatting Functions#FormatNumber|FormatNumber(&hellip;)]]''': Formats and rounds a number to a specified number of decimal places
 +
* '''[[Formatting Functions#FormatRange|FormatRange(&hellip;)]]''': Formats a value as a range
 +
* '''[[Formatting Functions#Orientation|Orientation(&hellip;)]]''': Outputs the orientation of an image
 +
* '''[[Formatting Functions#PadNumber|PadNumber(&hellip;)]]''': Adds leading zeros to any given number
 +
* '''[[Formatting Functions#RatingStars|RatingStars(&hellip;)]]''': Outputs the value of Rating as a number of star characters
 +
* '''[[Formatting Functions#RatingStars10|RatingStars10(&hellip;)]]''': Outputs the value of a 10 star rating field as a number of star characters
 +
* '''[[Formatting Functions#Watched|Watched(&hellip;)]]''': Outputs a formatted video bookmark
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
==== [[Grouping Functions]] ====
|- id="FirstNotEmpty" valign="top"
+
* '''[[Grouping Functions#GroupCount|GroupCount(&hellip;)]]''': Counts the members of a specified group (in a category or field).
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
* '''[[Grouping Functions#GroupCountQuery|GroupCountQuery(&hellip;)]]''': Globally counts the number of items in a specified group.
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>firstnotempty(</b><i>value1</i><b>, </b><i>value2</i><b>, </b><i>&hellip;</i><b>)</b></span>
+
* '''[[Grouping Functions#GroupSummary|GroupSummary(&hellip;)]]''': Smartly summarizes the members of a specified group (mode, mean, min, max, etc as is most logical for that grouping).
The [[#FirstNotEmpty|FirstNotEmpty()]] function acts as a conditional by returning the first argument from <i>value1</i>, <i>value2</i>, ... that is not empty.
+
* '''[[Grouping Functions#GroupSummaryQuery|GroupSummaryQuery(&hellip;)]]''': Get a summary for the current group of files based on another matching field.
Two or more arguments may be used, and the first non-empty argument is returned.
 
With two arguments, is is functionally equivalent to the sequence such as "if(!isempty(<i>value1</i>), <i>value1</i>, <i>value2</i>)".
 
With more than two arguments, [[#FirstNotEmpty|FirstNotEmpty()]] avoids long nested [[#If|If()]] sequences that simply test for emptiness.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>firstnotempty([media sub type], Misc Video)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the value in <span style="font-family: Consolas, monospace;">media sub type</span> if it is not empty, otherwise returns <span style="font-family: Consolas, monospace;">Music Video</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>firstnotempty([series], [name], Tag your Videos!)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the first non-empty value from the fields <span style="font-family: Consolas, monospace;">series</span> or <span style="font-family: Consolas, monospace;">name</span>, and if both are empty, returns the reminder to
 
<span style="font-family: Consolas, monospace;">Tag your Videos!</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
===Test and Comparison Functions===
+
==== [[List Manipulation Functions]] ====
 +
* '''[[List Manipulation Functions#ListBuild|ListBuild(&hellip;)]]''': Constructs a list from a series of items
 +
* '''[[List Manipulation Functions#ListClean|ListClean(&hellip;)]]''': Various list operations
 +
* '''[[List Manipulation Functions#ListCombine|ListCombine(&hellip;)]]''': Combines two delimited lists into a single delimited list
 +
* '''[[List Manipulation Functions#ListContains|ListContains(&hellip;)]]''': Checks for a value being in a list
 +
* '''[[List Manipulation Functions#ListCount|ListCount(&hellip;)]]''': Returns the number of items in a list
 +
* '''[[List Manipulation Functions#ListEqual|ListEqual(&hellip;)]]''': Checks for equality between two lists
 +
* '''[[List Manipulation Functions#ListFilter|ListFilter(&hellip;)]]''': Filter any list, returning only values within a given range
 +
* '''[[List Manipulation Functions#ListFind|ListFind(&hellip;)]]''': Search a list for a value and return that value, or its index # in the list
 +
* '''[[List Manipulation Functions#ListFormat|ListFormat(&hellip;)]]''': Outputs a given list in a reader friendly format.
 +
* '''[[List Manipulation Functions#ListGrep|ListGrep(&hellip;)]]''': Returns list items containing specified text
 +
* '''[[List Manipulation Functions#ListItem|ListItem(&hellip;)]]''': Returns an item from a location in a list
 +
* '''[[List Manipulation Functions#ListLimit|ListLimit(&hellip;)]]''': Limits the length of a list
 +
* '''[[List Manipulation Functions#ListMath|ListMath(&hellip;)]]''': Perform one of 4 specific math functions on a list containing numbers
 +
* '''[[List Manipulation Functions#ListMix|ListMix(&hellip;)]]''': Combine corresponding values from multiple lists into a new list, using a template to process each item
 +
* '''[[List Manipulation Functions#ListRemove|ListRemove(&hellip;)]]''': Removes a string from a list
 +
* '''[[List Manipulation Functions#ListShuffle|ListShuffle(&hellip;)]]''': Shuffles a list
 +
* '''[[List Manipulation Functions#ListSort|ListSort(&hellip;)]]''': Sort a list of values
  
The functions in this section return a Boolean value of either 1 (true) or 0 (false).
+
==== [[Miscellaneous Functions]] ====
They are generally used to drive an action specified in one of the [[#Conditional Functions|Conditional Functions]].
+
* '''[[Miscellaneous Functions#AlbumArtist|AlbumArtist(&hellip;)]]''': Returns a file's calculated album artist
====Compare(&hellip;): Compares two numbers====
+
* '''[[Miscellaneous Functions#AlbumKey|AlbumKey(&hellip;)]]''': Returns a unique album key for a file
 +
* '''[[Miscellaneous Functions#AlbumType|AlbumType(&hellip;)]]''': Returns the album type for a file
 +
* '''[[Miscellaneous Functions#AudioAnalysisState|AudioAnalysisState(&hellip;)]]''': Returns the state of audio analysis for a file
 +
* '''[[Miscellaneous Functions#Char|Char(&hellip;)]]''': Returns a character from the numeric code of that character
 +
* '''[[Miscellaneous Functions#CustomData|CustomData(&hellip;)]]''': Returns internal data to the expression language
 +
* '''[[Miscellaneous Functions#FileExtension|FileExtension(&hellip;)]]''': Returns the extension of the referenced file
 +
* '''[[Miscellaneous Functions#FilePlaylists()|FilePlaylists(&hellip;)]]''': Returns a list of playlists a file belongs to (Can also be used to search)
 +
* '''[[Miscellaneous Functions#Literal()|Literal(&hellip;)]]''': Returns a string as given without any formatting or processing
 +
* '''[[Miscellaneous Functions#Repeat|Repeat(&hellip;)]]''': Returns any given string repeated the specified number of times
 +
* '''[[Miscellaneous Functions#Row|Row(&hellip;)]]''': Returns the row number of a list entry
 +
* '''[[Miscellaneous Functions#Size|Size(&hellip;)]]''': Returns a file's size in a format specific to the media type
 +
* '''[[Miscellaneous Functions#Translate|Translate(&hellip;)]]''': Converts an English string found in the program to the current language selected in the language menu
 +
* '''[[Miscellaneous Functions#TreeNode|TreeNode(&hellip;)]]''': Returns the selected tree path
 +
* '''[[Miscellaneous Functions#TVInfo|TVInfo(&hellip;)]]''': Miscellaneous television and other pre-formatted information
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
==== [[Number Functions]] ====
|- id="Compare" valign="top"
+
* '''[[Number Functions#Avg|Avg(&hellip;)]]''': Returns the average from a set of numbers
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
* '''[[Number Functions#Counter|Counter(&hellip;)]]''': Counts upwards in specified increments
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>compare(</b><i>value1</i><b>, </b><i>operator</i><b>, </b><i>value2</i><b>)</b></span>
+
* '''[[Number Functions#Math|Math(&hellip;)]]''': Evaluates a given mathematical formula
The [[#Compare|Compare()]] function compares two numeric values <i>value1</i> and <i>value2</i> using the specified <i>operator</i>.
+
* '''[[Number Functions#Max|Max(&hellip;)]]''': Returns the largest value from a set of numbers
 +
* '''[[Number Functions#Min|Min(&hellip;)]]''': Returns the smallest value from a set of numbers
 +
* '''[[Number Functions#Number|Number(&hellip;)]]''': Returns the first number , including decimals, from a given string
 +
* '''[[Number Functions#Rand|Rand(&hellip;)]]''': Returns a random number anywhere between two given numbers
 +
* '''[[Number Functions#Range|Range(&hellip;)]]''': Creates a semi-colon delimited list of numbers in a field
 +
* '''[[Number Functions#Roman|Roman(&hellip;)]]''': Converts any given number to, or from, roman numerals
 +
* '''[[Number Functions#StackCount|StackCount(&hellip;)]]''': Returns the number of files in a stack
 +
* '''[[Number Functions#Sum|Sum(&hellip;)]]''': Returns the sum of a set of numbers
 +
* '''[[Number Functions#TrackNumber|TrackNumber(&hellip;)]]''': Returns a file's track # value
  
Available <i>operator</i> values:
+
==== [[String Manipulation Functions]] ====
 +
* '''[[String Manipulation Functions#Clean|Clean(&hellip;)]]''': Clean a string to be used for various operations
 +
* '''[[String Manipulation Functions#Extract|Extract(&hellip;)]]''': Returns a portion of a string bounded by another substring
 +
* '''[[String Manipulation Functions#Find|Find(&hellip;)]]''': Finds a string or character in another string, returning its zero-based position in that string
 +
* '''[[String Manipulation Functions#FixCase|FixCase(&hellip;)]]''': Changes the case of a given string
 +
* '''[[String Manipulation Functions#FixSpacing|FixSpacing(&hellip;)]]''': Intelligently splits adjacent camel-cased words
 +
* '''[[String Manipulation Functions#Hexify|Hexify(&hellip;)]]''': Hexifies a string to make it suitable for web usage
 +
* '''[[String Manipulation Functions#Left|Left(&hellip;)]]''': Retrieves a specified number of characters from the left of a string
 +
* '''[[String Manipulation Functions#Length|Length(&hellip;)]]''': Returns the number of characters in a string
 +
* '''[[String Manipulation Functions#Letter|Letter(&hellip;)]]''': Returns the starting letter or letters of a given string
 +
* '''[[String Manipulation Functions#Mid|Mid(&hellip;)]]''': Retrieves specified characters from a string
 +
* '''[[String Manipulation Functions#MoveArticles|MoveArticles(&hellip;)]]''': Takes "The Beatles" and reverses it to "Beatles, The"
 +
* '''[[String Manipulation Functions#NoArticles|NoArticles(&hellip;)]]''': Takes "The Beatles" and returns "Beatles"
 +
* '''[[String Manipulation Functions#PadLeft|PadLeft(&hellip;)]]''': Pad any string with any character, to the left
 +
* '''[[String Manipulation Functions#PadRight|PadRight(&hellip;)]]''': Pad any string with any character, to the right
 +
* '''[[String Manipulation Functions#Regex|Regex(&hellip;)]]''': Regular expression pattern matching and capture
 +
* '''[[String Manipulation Functions#RemoveCharacters|RemoveCharacters(&hellip;)]]''': Removes a list of characters from a string
 +
* '''[[String Manipulation Functions#RemoveLeft|RemoveLeft(&hellip;)]]''': Trims characters from the beginning of a string
 +
* '''[[String Manipulation Functions#RemoveRight|RemoveRight(&hellip;)]]''': Trims characters from the end of a string
 +
* '''[[String Manipulation Functions#Replace|Replace(&hellip;)]]''': Replace or remove a string segment
 +
* '''[[String Manipulation Functions#Right|Right(&hellip;)]]''': Retrieves a specified number of characters from the right of a string
 +
* '''[[String Manipulation Functions#Swap|Swap(&hellip;)]]''': Takes Firstname Lastname and swaps to Lastname, Firstname
 +
* '''[[String Manipulation Functions#Trim|Trim(&hellip;)]]''': Removes leading and trailing non-printable characters and new lines from a string
 +
* '''[[String Manipulation Functions#TrimLines|TrimLines(&hellip;)]]''': Removes leading and trailing non-printable characters and new lines from a string
 +
* '''[[String Manipulation Functions#UnMoveArticles|UnMoveArticles(&hellip;)]]''': Takes "Beatles, The" and reverses it to restore the normal word order, "The Beatles"
 +
* '''[[String Manipulation Functions#Unswap|Unswap(&hellip;)]]''': Takes Lastname, Firstname and reverses it to Firstname Lastname
 +
* '''[[String Manipulation Functions#Urlify|Urlify(&hellip;)]]''': Takes a string and applies html formatting for browser consumption
  
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
+
==== [[Test and Comparison Functions]] ====
<tr><td style="text-align:left; padding-right:20pt"><b>=</b></td><td>Equivalence</td></tr>
+
* '''[[Test and Comparison Functions#Compare|Compare(&hellip;)]]''': Compares two numbers
<tr><td style="text-align:left; padding-right:20pt"><b><</b></td><td>Less than</td></tr>
+
* '''[[Test and Comparison Functions#IsDigit|IsDigit(&hellip;)]]''': Determines whether or not a given value is digits
<tr><td style="text-align:left; padding-right:20pt"><b><=</b></td><td>Less than or equal to</td></tr>
+
* '''[[Test and Comparison Functions#IsDriveMissing|IsDriveMissing(&hellip;)]]''': Checks if a drive is missing
<tr><td style="text-align:left; padding-right:20pt"><b>></b></td><td>Greater than</td></tr>
+
* '''[[Test and Comparison Functions#IsEmpty|IsEmpty(&hellip;)]]''': Tests a value for emptiness
<tr><td style="text-align:left; padding-right:20pt"><b>>=</b></td><td>Greater than or equal to</td></tr>
+
* '''[[Test and Comparison Functions#IsEqual|IsEqual(&hellip;)]]''': Compares two values in one of seventeen specified modes
</table></div>
+
* '''[[Test and Comparison Functions#IsInPlayingNow|IsInPlayingNow(&hellip;)]]''': Tests to see if a file is in the Playing Now playlist
 +
* '''[[Test and Comparison Functions#IsLowerCase|IsLowerCase(&hellip;)]]''': Tests to see if a value is lower case
 +
* '''[[Test and Comparison Functions#IsMissing|IsMissing(&hellip;)]]''': Tests to see if a file exists on the system
 +
* '''[[Test and Comparison Functions#IsOverridden|IsOveridden(&hellip;)]]''': Tests if an expression is overridden by a value
 +
* '''[[Test and Comparison Functions#IsPlaying|IsPlaying(&hellip;)]]''': Tests to see if a file is in currently being played
 +
* '''[[Test and Comparison Functions#IsRange|IsRange(&hellip;)]]''': Tests a value for inclusion within a given range
 +
* '''[[Test and Comparison Functions#IsRemovable|IsRemovable(&hellip;)]]''': Tests to see if a file is stored on removable media
 +
* '''[[Test and Comparison Functions#IsUpperCase|IsUpperCase(&hellip;)]]''': Tests to see if a value is upper case
 +
* '''[[Test and Comparison Functions#SearchTags|SearchTags(&hellip;)]]''': Finds all fields that contain a value
  
Outputs 1 if the comparison is true, and 0 otherwise.
+
== Data Types ==
|- valign="top"
+
It was mentioned already that the Media Center expression language is primarily a textual language - it consumes and produces text.
! scope="row" style="background: #ecedf3; color: #111; " | Examples
+
Nonetheless, certain areas of Media Center are influenced by the type of data used or presented,
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>compare([bitrate], &lt;, 320)</nowiki></b></span>
+
and sometimes it is useful or necessary to coerce expression output into one data type or another.
<p style="margin-left:20pt;">Returns 1 when the bit rate is less than 320 (Kbps), and 0 otherwise.</p>
+
Each Media Center field is defined to be of a certain data type,
<span style="font-family: Consolas, monospace;"><b><nowiki>if(compare(math(now() - [date modified, 0]), &gt;, 21), Expired, formatdate([date modified, 0], elapsed))</nowiki></b></span>
+
listed in the [[File_Properties_%28tags%29#Field_Specifications|Field Data Types]] table.
<p style="margin-left:20pt;">Outputs the age of files under 21 days old, or <span style="font-family: Consolas, monospace;">Expired</span> for older files.</p>
+
These types influence how values are output, sorted, and interpreted on input.
|}
+
And expressions always output data of type String.
<div style="text-align:right;">([[#top|Back to top)]]</div>
+
By coercing the data type of an expression, output formatting and sorting can be controlled in various ways.
  
====IsEqual(&hellip;): Compares two values in one of nine specified modes====
+
Data types are forced by appending to an expression the string:
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">&datatype=[<i>type</i>]</span></div>
|- id="IsEqual" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>isequal(</b><i>value1</i><b>, </b><i>value2</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#IsEqual|IsEqual()]] function compares <i>value1</i> with <i>value2</i> using any <i>mode</i> from the list of modes below.
 
Outputs 1 when the comparison succeeds according to the <i>mode</i>, and 0 otherwise.
 
Although the <i>mode</i> is specified as the last argument, the comparison should be mentally read as: <i>value1</i> <i>mode</i> <i>value2</i>.
 
  
Available <i>mode</i> values:
+
where <i><span style="font-family: monospace,monospace; font-size:1em;">type</span></i> is one of the following values:
  
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
+
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse">
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Case-sensitive string compare for equality</td></tr>
+
<tr><td style="text-align:left; padding-right:20pt"><b>list</b></td><td>A list of strings, separated by semicolons</td></tr>
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Case-insensitive string compare for equality</td></tr>
+
<tr><td style="text-align:left; padding-right:20pt"><b>string</b></td><td>Sorts as strings (with smart number handling)</td></tr>
<tr><td style="text-align:left; padding-right:20pt"><b>2</b></td><td>Numeric compare for equality</td></tr>
+
<tr><td style="text-align:left; padding-right:20pt"><b>number</b></td><td>Sorts values as numbers (decimal or integer)</td></tr>
<tr><td style="text-align:left; padding-right:20pt"><b>3</b></td><td>Numeric less than</td></tr>
+
<tr><td style="text-align:left; padding-right:20pt"><b>integer</b></td><td>Sorts values as integers</td></tr>
<tr><td style="text-align:left; padding-right:20pt"><b>4</b></td><td>Numeric less than or equal to</td></tr>
+
<tr><td style="text-align:left; padding-right:20pt"><b>path</b></td><td>Sorts using a smart filename compare style</td></tr>
<tr><td style="text-align:left; padding-right:20pt"><b>5</b></td><td>Numeric greater than</td></tr>
+
<tr><td style="text-align:left; padding-right:20pt"><b>month</b></td><td>Sorts string month names (i.e. January, February, etc.)</td></tr>
<tr><td style="text-align:left; padding-right:20pt"><b>6</b></td><td>Numeric greater than or equal to</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>7</b></td><td>Substring search (case sensitive)</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>8</b></td><td>Substring search (case insensitive)</td></tr>
 
 
</table></div>
 
</table></div>
  
Argument <i>mode</i> is optional (defaults to 0).
+
=== Calculated Fields and Search ===
  
|- valign="top"
+
Media Center's [[Search Language]] supports some simple numeric [[Search Language#Comparison_Operators|comparison operators]].
! scope="row" style="background: #ecedf3; color: #111; " | Examples
+
Because expressions always evaluate as a String type, these operators would be unavailable for use in a search query to compare numeric values from a calculated expression field.
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>isequal([artist], [album], 1)</nowiki></b></span>
+
In order to use the numeric comparison operators, a calculated expression field can be cast into one of the numeric types.
<p style="margin-left:20pt;">If the artist and album values are the same, the output will be 1, otherwise, the output will be 0.</p>
+
In your numeric calculated fields, to allow the use Search's numeric comparison operators, add either of the casts:
<span style="font-family: Consolas, monospace;"><b><nowiki>if(isequal([artist], [album], 1), Eponymous, [album])</nowiki></b></span>
 
<p style="margin-left:20pt;">The [[#If|If()]] function basis its decision on the outcome of [[#IsEqual|IsEqual()]], so if the artist and album values are the same, the output will be Eponymous, otherwise, the output will be the value of album.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(isequal([artist], [album], 1), Eponymous/,, [album]/))</nowiki></b></span>
 
<p style="margin-left:20pt;">This example demonstrates the character escaping mentioned in the overview earlier.
 
Here, we want the output to be either <span style="font-family: Consolas, monospace;">Eponymous,</span> (note the inclusion of the comma) or the album value with a closing parenthesis.
 
In order to achieve this, the comma, and the closing parenthesis, are escaped using a forward-slash character.
 
This informs the expression evaluator that these characters are not part of the expression syntax and are to be treated literally.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(isequal([filename (path)], classical, 8), Classical, Not Classical)</nowiki></b></span>
 
<p style="margin-left:20pt;">Because compare <i>mode</i> 8 has been specified, if the word <span style="font-family: Consolas, monospace;">classical</span> appears anywhere in the case-insensitive file path, the expression will return <span style="font-family: Consolas, monospace;">Classical</span>, and if not it will return <span style="font-family: Consolas, monospace;">Not Classical</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====IsEmpty(&hellip;): Tests a value for emptiness====
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">&datatype=[integer]</span></div>
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">&datatype=[number]</span></div>
|- id="IsEmpty" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>isempty(</b><i>value</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#IsEmpty|IsEmpty()]] function tests the given <i>value</i> for emptiness.  The <i>value</i> passed is typically an Media Center field, so that some action may be taken when the field is or is not empty.
 
Returns 1 when the <i>value</i> is empty, otherwise 0.
 
  
Available <i>mode</i> values:
+
to the end of the field's calculated expression.
  
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
+
=== Lists and Trees ===
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>String test (field must be empty to get a positive result)</td></tr>
+
<div>
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Numerical test (field must be empty, or contain 0 to get a positive result)</td></tr>
+
[[File:Datatype_List.png|right]]
</table></div>
+
The list of output in view categories and pane columns can be modified by forcing the data type to a List type.
 +
Two things happen when the data type is List:
 +
The values within a List type are split into their individual (semicolon-separated) list items
 +
The backslash character takes on a special meaning and becomes another form of separator that creates tree-like hierarchies,
 +
collapsible in panes columns and creates drill-down categories in any category view type (Standard View > Categories, Theater View, DLNA, Gizmo/WebGizmo).
 +
Forcing an expression's type to <span style="font-family: monospace,monospace; font-size:1em;">list</span> causes this list item separation and hierarchy generation.
 +
Alternatively, forcing a List type to <span style="font-family: monospace,monospace; font-size:1em;">string</span> defeats this.
 +
Add the cast:
  
Note that Media Center does not discriminate between a 0 <i>value</i> and an empty <i>value</i> for fields of type Integer and Decimal - both 0 and empty are considered equivalent for these field types.
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">&datatype=[list]</span></div>
This is useful for fields such as the integer field Disc #, where an empty or 0 <i>value</i> implies that Disc # contains no useful data, and should be generally ignored or absent in display output.
 
  
Pay particular attention to the third example offered below, as it covers a caveat that comes with this particular function.
+
to the end of an expression to force an expression's output to be considered as a List type.
 +
Conversely, a List type may be forced into a String type by adding the cast:
  
Argument <i>mode</i> is optional (defaults to 0).
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">&datatype=[string]</span></div>
  
|- valign="top"
+
to the end of an expression.
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>isempty([comment], 0)</nowiki></b></span>
 
<p style="margin-left:20pt;">If the comment field is empty, [[#IsEmpty|IsEmpty()]] returns 1, otherwise 0.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>isempty([track #], 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Performs a numerical test for data in the [track #] field. If the field is empty or 0, a 1 is returned, otherwise 0 is returned.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>ifelse(!isempty([disc #]), [disc #])</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the <i>value</i> of the disc # field when it is not empty.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====IsRange(&hellip;): Tests a value for inclusion within a given range====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="IsRange" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>isrange(</b><i>value</i><b>, </b><i>range</i><b>)</b></span>
 
The [[#IsRange|IsRange()]] function tests if a <i>value</i> falls within a given <i>range</i> of values.
 
If the <i>value</i> falls within the given <i>range</i>, 1 is returned, otherwise 0 is returned.
 
 
 
A <i>range</i> is specified in the form of low-high, where low and high are either letters or numbers.
 
The lowest <i>value</i> comes first, the highest second. Both low and high must be the same kind (letters or numbers).
 
The low and high values are inclusive.
 
 
 
Example Ranges:
 
 
 
<div style="font-family: Consolas, monospace;">
 
<div style="margin-left: 20pt">1-100</div>
 
<div style="margin-left: 20pt">a-z</div>
 
<div style="margin-left: 20pt">c-d</div>
 
<div style="margin-left: 20pt">23-7542 </div>
 
 
</div>
 
</div>
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>isrange([artist], a-c)</nowiki></b></span>
 
<p style="margin-left:20pt;">Artist values of Abba or Blondie will result in a 1, but ZZ Top will return a 0.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(isrange([bitrate], 96-191), Poor Quality, High Quality)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">Poor Quality</span> for any file whose bit rate falls in the <i>range</i> of 96 to 191, and returns <span style="font-family: Consolas, monospace;">High Quality</span> for all bit rates.</p>
 
  
Additional Examples
+
=== Sort Order ===
 +
<div>
 +
[[File:Datatype_Month.png|right]]
 +
Normally strings are sorted ASCII-betically with some smart numeric sorting.
 +
But this form of sort may not always be desired.
  
:[http://wiki.jriver.com/index.php/CD_Reference_Number#Answer_2 Using IsRange() in a Search List.]
+
==== Sorting by Month ====
|}
+
Generally it is more useful to see month names sorting such that January sorts before April, instead of alphabetically where April would sort before January.
<div style="text-align:right;">([[#top|Back to top)]]</div>
+
Forcing an expression's type to Month forces string month values to be treated instead as their equivalent numerical month numbers.
 +
For example, the first month January and the third month March sort before the fourth month April.
 +
Add the cast:
  
====IsMissing(&hellip;): Tests to see if a file exists on the system====
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">&datatype=[month]</span></div>
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
to the end of an expression to force an expression's output to be sorted by numeric month values.
|- id="IsMissing" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>ismissing(</b><i>filepath</i><b>)</b></span>
 
The [[#IsMissing|IsMissing()]] function tests for the existence of a file in the file system.
 
If the file is missing, the function returns 1, otherwise 0 is returned if the file exists.
 
This function is useful for checking for missing files in a Library.
 
[[#IsMissing|IsMissing()]] treats special entries such as ripped Blu-ray or DVDs as single files, even though they physically exist in the file system as several files and directories.
 
  
Note: Any view or list that uses [[#IsMissing|IsMissing()]] will be slow, is Media Center must interrogate each referenced file in the file system.
+
==== Sorting by Path ====
The larger the number of files being queried, the longer it will take to produce results.  Use [[#IsMissing|IsMissing()]] with care.
 
  
Argument <i>filepath</i> is optional (defaults to [filename]).
+
Path data types sort using smart filename comparisons.
  
|- valign="top"
+
XXX: Note: This section is incomplete. I cannot distingish any difference between using a datatype of <span style="font-family: monospace,monospace; font-size:1em;">path</span> vs. <span style="font-family: monospace,monospace; font-size:1em;">string</span>. It seems <span style="font-family: monospace,monospace; font-size:1em;">path</span> sort order is always engaged.
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>ismissing()</nowiki></b></span>
 
<p style="margin-left:20pt;">If the referenced file was not found in the file system, 1 is returned; otherwise 0 is returned.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>ismissing(C:\Music\My Lost File.mp3)</nowiki></b></span>
 
<p style="margin-left:20pt;">Checks for <span style="font-family: Consolas, monospace;">My Lost File.mp3</span> and returns 1 (positive) if the file does not exist, and 0 (negative) if the file does exist.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(ismissing(), File is missing, File exists)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs <span style="font-family: Consolas, monospace;">File is missing</span> or <span style="font-family: Consolas, monospace;">File Exists</span> depending on the result returned by IsMissing().</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>[=ismissing([filename])]=1</nowiki></b></span>
 
<p style="margin-left:20pt;">This example demonstrates how to construct an expression for use as a Media Center search query.
 
If you place this in the search field in the top right corner of the program while viewing all of your library, it will filter the list, leaving only the missing files on view. If all files in library exist, this list will be empty. You could also create a view scheme and use this string in the <span style="font-family: Consolas, monospace;">Set rules for file display</span> search to give you a view that you can visit periodically to check that your library is not missing any files.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====IsRemovable(&hellip;): Tests to see if a file is stored on removable media====
+
Add the cast:
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">&datatype=[path]</span></div>
|- id="IsRemovable" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>isremovable(</b><i>filepath</i><b>)</b></span>
 
The [[#IsRemovable|IsRemovable()]] function tests if a file resides on removable media and if so, returns 1, and if not, returns 0.
 
The Media Center field [Removable] also provides the same value for a given file.
 
  
Argument <i>filepath</i> is optional (defaults to [filename]).
+
to the end of an expression to force an expression's output to be smart-sorted by path components.
  
|- valign="top"
+
</div>
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>isremovable()</nowiki></b></span>
 
<p style="margin-left:20pt;">Checks if the current file is on removable storage, and if so, returns 1, otherwise returns 0.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====IsInPlayingNow(&hellip;): Tests to see if a file is in the Playing Now playlist====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="IsInPlayingNow" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>isinplayingnow(</b><i>filepath</i><b>)</b></span>
 
The [[#IsInPlayingNow|IsInPlayingNow()]] function tests if a file is in any zone's Playing Now list.
 
Used as an expression category, pane or file list column allows distinguishing files that are in the Playing Now list.
 
 
 
Argument <i>filepath</i> is optional (defaults to [filename]).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>isinplayingnow()</nowiki></b></span>
 
<p style="margin-left:20pt;">If the file in the Playing Now list, returns 1, otherwise returns 0.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(isinplayingnow(), Queued, Not queued)</nowiki></b></span>
 
<p style="margin-left:20pt;">If the file in the Playing Now list, returns <span style="font-family: Consolas, monospace;">Queued</span>, otherwise <span style="font-family: Consolas, monospace;">Not queued</span>.</p>
 
 
 
Additional Examples
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=57461.0 How to use IsPlaying() and IsInPlayingNow()]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====IsPlaying(&hellip;): Tests to see if a file is in currently being played====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="IsPlaying" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>isplaying(</b><i>filepath</i><b>)</b></span>
 
The [[#IsPlaying|IsPlaying()]] function tests if a file is playing in any zone.
 
Used as an expression category, pane or file list column allows distinguishing files that are playing now.
 
 
 
Argument <i>filepath</i> is optional (defaults to [filename]).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>IfElse(IsPlaying(), &lt;font color="ff0000"&gt;&#9834;&lt;//font&gt;, IsInPlayingNow(), &#9834;)</nowiki></b></span>
 
<p style="margin-left:20pt;">This expression in a file list expression column shows which files are in the Playing Now list and which are currently playing by outputting a musical note in the column.  The musical note will be displayed in red for any currently playing file.</p>
 
 
 
Additional Examples
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=57461.0 How to use IsPlaying() and IsInPlayingNow()]
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=58137.msg393905#msg393905 How to play an artist's full work when a genre is shuffling?]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
===Formatting Functions===
 
 
 
The functions in this section format their arguments in specific ways.
 
Some functions are used for formatting values for better presentation, or according to some format, while other functions work on Media Center internal "raw" data to convert to user-friendly formats.
 
 
 
Certain Media Center fields are used to store values in ways that are internally convenient or efficient.  But these field values are not terribly useful or meaningful when used directly.
 
 
 
For example, the Duration field holds values as a number seconds of length, while various Date/Time fields such as Date or Last Played store values as floating point numbers specifying a number of days and fractions of a day since a particular epoch time.
 
 
 
Media Center will generally format fields using the "display" format where necessary, such as in panes, file list columns, or various tools such as the Rename, Move & Copy tool.
 
When a function requires a raw field value, or you want to access a raw field value, by sure to use the raw field format.
 
This is done by appending a <span style="font-family: Consolas, monospace;"><b>,0</b></span> to the field's name inside the brackets, for example <span style="font-family: Consolas, monospace;">[Date Imported,0]</span>.
 
====Delimit(&hellip;): Outputs a value with head/tail strings when value is non-empty====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Delimit" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>delimit(</b><i>expression</i><b>, </b><i>tail</i><b>, </b><i>head</i><b>)</b></span>
 
The [[#Delimit|Delimit()]] function outputs the value of <i>expression</i> prepended with a <i>head</i> string and/or appended with a <i>tail</i> string, but only if the value of the <i>expression</i> is non-empty.  Nothing is output when the <i>expression</i> evaluates to empty.
 
 
 
Argument <i>tail</i> is optional (defaults to SPACE).
 
 
 
Argument <i>head</i> is optional (defaults to EMPTY).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>delimit([Track #], .)</nowiki></b></span>
 
<p style="margin-left:20pt;">Appends a period after a track number if [Track #] is not empty, such as <span style="font-family: Consolas, monospace;">12.</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>delimit([Date (year)], {, })</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the year surrounded by curly braces, for example <span style="font-family: Consolas, monospace;">{2012</span>}.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FormatBoolean(&hellip;): Formats a boolean (true / false) value in a specified manner====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FormatBoolean" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>formatboolean(</b><i>conditional</i><b>, </b><i>true string</i><b>, </b><i>false string</i><b>)</b></span>
 
The [[#FormatBoolean|FormatBoolean()]] function outputs <i>true string</i> and <i>false string</i> values to represent the 0 or 1 Boolean output resulting from the <i>conditional</i> expression.
 
When the <i>conditional</i> evaluates to 1, the <i>true string</i> will be output, otherwise the <i>false string</i> will be output.
 
 
 
Argument <i>true string</i> is optional (defaults to True).
 
 
 
Argument <i>false string</i> is optional (defaults to False).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>formatboolean(isempty([number plays]), Never Played, Has Been Played)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">Never Played</span> when the expression [[#IsEmpty|IsEmpty()]] evaluates to 0, and <span style="font-family: Consolas, monospace;">Has Been Played</span> when it evaluates to 1.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatboolean(math([track #] % 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the default True label for odd track numbers, and the default False label for even ones.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FormatDuration(&hellip;): Presents a duration of seconds in a reader friendly format====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FormatDuration" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>formatduration(</b><i>duration value</i><b>)</b></span>
 
The [[#FormatDuration|FormatDuration()]] function formats a <i>duration value</i> into a friendly format. 
 
The <i>duration value</i> argument is expected to be a value representing a number of seconds, typically used for media file duration.
 
Media Center internally stores duration values in seconds.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>formatduration([duration,0])</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs a friendly display of the duration field.  This is the same output shown using the Duration field in a file list.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatduration(600)</nowiki></b></span>
 
<p style="margin-left:20pt;">This will output ten minutes in the format <span style="font-family: Consolas, monospace;">10:00</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FormatFileSize(&hellip;): Presents a number of bytes in a reader friendly format====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FormatFileSize" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>formatfilesize(</b><i>bytes value</i><b>)</b></span>
 
The [[#FormatFileSize|FormatFileSize()]] function formats a <i>bytes value</i> into a friendly format.
 
The <i>bytes value</i> argument is expected to be a value representing a number of bytes, typically used for media file size.
 
Media Center internally stores file size values in bytes.  [[#FormatFileSize|FormatFileSize()]] will convert those byte values into unitized friendly formats such as 50 bytes, 3.2 KB or 10.4 MB.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>formatfilesize([file size,0])</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs a friendly format of the file size field.  This is the same output shown using the File Size field in a file list.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatfilesize(56123456)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the <i>bytes value</i> 56,123,456 as <span style="font-family: Consolas, monospace;">53.5 MB</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FormatNumber(&hellip;): Formats and rounds a number to a specified number of decimal places====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FormatNumber" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>formatnumber(</b><i>value</i><b>, </b><i>decimal places</i><b>, </b><i>label zero</i><b>, </b><i>label plural</i><b>, </b><i>label singular</i><b>)</b></span>
 
The [[#FormatNumber|FormatNumber()]] function formats a numeric <i>value</i> to a specified number of <i>decimal places</i>, rounding its <i>value</i>, and optionally outputs <i>value</i>-dependent labels, which can be used to construct more grammatically-correct output.
 
The <i>value</i> can be any numeric <i>value</i>.
 
The <i>decimal places</i> argument specifies the number of digits to be used after the decimal point.  Use -1 to output as many <i>decimal places</i> as available.
 
 
 
The label selected depends on the original <i>value</i>, not the resulting formatted <i>value</i>.
 
 
 
The <i>label zero</i> argument is output instead of a formatted <i>value</i> when the original <i>value</i> is 0.  When this label is specified as empty, <i>label plural</i> is used.
 
The <i>label plural</i> argument is appended to the formatted <i>value</i> when the original <i>value</i> is more than 1.
 
The <i>label singular</i> argument is appended to the formatted <i>value</i> when the original <i>value</i> is equal to 1.
 
 
 
Note: [[#FormatNumber|FormatNumber()]] will not output additional zero's after the decimal point.  In other words, [[#FormatNumber|FormatNumber()]] rounds fractional values, but does not zero fill.
 
 
 
Argument <i>decimal places</i> is optional (defaults to 0).
 
 
 
Argument <i>label zero</i> is optional (defaults to <i>label plural</i>).
 
 
 
Argument <i>label plural</i> is optional (defaults to 0).
 
 
 
Argument <i>label singular</i> is optional.
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>formatnumber([duration,0], 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns a file's duration (which are in seconds) rounding to two <i>decimal places</i>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatnumber([number plays,0], 0, Unplayed, Plays, Play)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs values in whole number formats (no decimals shown). When the number of plays is 0, the output will be <span style="font-family: Consolas, monospace;">Unplayed</span>.
 
When it is more than one, such as six, outputs <span style="font-family: Consolas, monospace;">6 Plays</span>.
 
And when the number of plays is one, outputs <span style="font-family: Consolas, monospace;">1 Play</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatnumber([number plays,0], 0, , Plays, Play)</nowiki></b></span>
 
<p style="margin-left:20pt;">Same as the previous example, but uses the default <i>value</i> for <i>label zero</i> (which is <i>label plural</i>), so that when number of plays is zero, output is <span style="font-family: Consolas, monospace;">0 Plays</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatnumber([number plays,0], , , , Time)</nowiki></b></span>
 
<p style="margin-left:20pt;">In this example, only <i>label singular</i> argument is specified (as <span style="font-family: Consolas, monospace;">Time</span>), so all other arguments use their defaults values.
 
The output will be <span style="font-family: Consolas, monospace;">0</span> when number of plays is zero, <span style="font-family: Consolas, monospace;">1 Time</span> when number of plays is one, and the actual number of plays for other values (e.g. <span style="font-family: Consolas, monospace;">6</span>).</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FormatRange(&hellip;): Formats a value as a range====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FormatRange" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>formatrange(</b><i>value</i><b>, </b><i>range size</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#FormatRange|FormatRange()]] function creates numerical or alphabetic groupings of size <i>range size</i>, and returns the grouping where <i>value</i> falls.
 
Only the first character of <i>value</i> is considered and used.
 
The <i>range size</i> is a numerical <i>value</i> specifying how wide the range should be.  Numeric ranges are 0-based.
 
The <i>mode</i> specifies the type of range grouping.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 0pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Automatically choose between number / letter grouping</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>    1</b></td><td>Letter grouping</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>    2</b></td><td>Number grouping</td></tr>
 
</table></div>
 
 
 
Argument <i>range size</i> is optional (defaults to 1).
 
 
 
Argument <i>mode</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>formatrange([artist], 3, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the range that the artist's first letter falls within.
 
With a <i>range size</i> of 3 and using <i>mode</i> 1 (letter grouping), ranges will be produced in the form of
 
<span style="font-family: Consolas, monospace;">a-c</span>, <span style="font-family: Consolas, monospace;">d-f</span>, <span style="font-family: Consolas, monospace;">g-i</span>, etc.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatrange([artist])</nowiki></b></span>
 
<p style="margin-left:20pt;">With <i>range size</i> and <i>mode</i> values left unspecified, default values are used, so automatic range groupings of size 1 are output.
 
Hence, the first character of [artist] will be output.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatrange([bitrate], 100, 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">Numeric range groupings of size 100 will be output, for the <i>value</i> of <span style="font-family: Consolas, monospace;">[bitrate]</span>.  Possible outputs are: <span style="font-family: Consolas, monospace;">0-99</span>, <span style="font-family: Consolas, monospace;">100-199</span>, <span style="font-family: Consolas, monospace;">200-299</span>, etc.</p>
 
 
 
Additional Examples
 
 
 
:[http://wiki.jriver.com/index.php/CD_Reference_Number How to produce 1-based range values.]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Orientation(&hellip;): Outputs the orientation of an image====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Orientation" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>orientation(</b><b>)</b></span>
 
The [[#Orientation|Orientation()]] function outputs one of the following words indicating the orientation of an image file:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt">Portrait</td><td>When height > width</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Landscape</td><td>When width > height</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Portrait</td><td>When height = width</td></tr>
 
</table></div>
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>if(isequal(orientation(), Square), Square, Rectangle)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs <span style="font-family: Consolas, monospace;">Square</span> for square images or <span style="font-family: Consolas, monospace;">Rectangle</span> for portrait and landscape images.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====PadNumber(&hellip;): Adds leading zeros to any given number====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="PadNumber" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>padnumber(</b><i>value</i><b>, </b><i>number digits</i><b>)</b></span>
 
The [[#PadNumber|PadNumber()]] function adds leading zeros to any given number <i>value</i>, producing a <i>value</i> of length <i>number digits</i>.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>padnumber([track #], 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">This will pad the track number with leading zeros sufficient to ensure the output is minimally two digits in length.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>padnumber(counter(), 4)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs 4 digits of zero-padded numbers produced by [[#Counter|Counter()]]. For example, <span style="font-family: Consolas, monospace;">0001</span>, <span style="font-family: Consolas, monospace;">0002</span>, <span style="font-family: Consolas, monospace;">0003</span>,
 
etc.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====RatingStars(&hellip;): Outputs the value of Rating as a number of star characters====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="RatingStars" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>ratingstars(</b><b>)</b></span>
 
The [[#RatingStars|RatingStars()]] function outputs the Rating field's value as the equivalent number of black star characters.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>ratingstars()</nowiki></b></span>
 
<p style="margin-left:20pt;">For a file that has a Rating of 4, outputs &#9733;&#9733;&#9733;&#9733;.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Watched(&hellip;): Outputs a formatted video bookmark====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Watched" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>watched(</b><i>mode</i><b>)</b></span>
 
The [[#Watched|Watched()]] function outputs a video's bookmark position in a human-readable format, using a specified <i>mode</i>.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Output a human-readable watched status.</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Output a numeric watched value (see Watched Status Values below)</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>2</b></td><td>Output a watched checkmark &#x2713; if watched</td></tr>
 
</table></div>
 
 
 
Watched Status Values
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt">-1</td><td>File type is not Video</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">0</td><td>Not watched</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">1</td><td>Partially watched</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">2</td><td>Entirely watched</td></tr>
 
</table></div>
 
 
 
Argument <i>mode</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>watched()</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs formatted watched status, such as <span style="font-family: Consolas, monospace;">57% on Sep 25</span>, or <span style="font-family: Consolas, monospace;">Aug 21</span>, or nothing when the video has not been watched.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>ifelse(compare(watched(1), =, 1), Finish Me, compare(watched(1), =, 2), I'm Done)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs <span style="font-family: Consolas, monospace;">Finish Me</span> if the video has been partially watched, and <span style="font-family: Consolas, monospace;">I'm Done</span> when completely watched.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
===String Manipulation Functions===
 
 
 
The functions in this section are used primarily to manipulate strings.  Since the Media Center expression language is primarily string-oriented, these functions provide a means to manipulate field values or the output from other expressions.
 
====Clean(&hellip;): Clean a string to be used for various operations====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Clean" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>clean(</b><i>string</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#Clean|Clean()]] function is generally used to sanitize a <i>string</i> by stripping empty brackets, remove superfluous dash characters, eliminate leading or trailing articles, or replace filesystem-illegal characters.
 
It is typically employed before some operation such as Rename to clean the product of joining various fields, some of which may be empty, or to produce filesystem-safe filenames.  It may be used for a variety of purposes, however.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Removes empty () and [], superfluous dash (-) and whitespace characters and sometimes comma (be careful)</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Removes the article 'the' from the beginning and ', the' from the end</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>2</b></td><td>Removes any article (a, an, the, etc.) from the beginning and end</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>3</b></td><td>Replaces each filesystem-illegal character <span style="font-family: Consolas, monospace;">\ / : * ? " < > |</span> with an underscore <span style="font-family: Consolas, monospace;">_</span>, and replaces each unprintable character with a space</td></tr>
 
</table></div>
 
 
 
Argument <i>mode</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>clean([album] - [date])</nowiki></b></span>
 
<p style="margin-left:20pt;">The concatenation of [Album] - [Date] may leave a dangling <span style="font-family: Consolas, monospace;"> - </span> <i>string</i> when date is empty.  [[#Clean|Clean()]] in the default <i>mode</i> removes this dangling <i>string</i>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>clean(The Beatles, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">For sorting or grouping purposes, it is often desirable to remove the leading article <span style="font-family: Consolas, monospace;">The</span> from a <i>string</i>. [[#Clean|Clean()]] in <i>mode</i> 1 provides a convenient solution, and in this example produces <span style="font-family: Consolas, monospace;">Beatles</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>clean(AC//DC: Back In Black, 3)</nowiki></b></span>
 
<p style="margin-left:20pt;">When an expression is to be used to produce a filename, filesystem-illegal characters must be removed or converted to legal characters.  [[#Clean|Clean()]] in <i>mode</i> 3 will convert such characters into safe underscores.  This example would produce the filesystem-safe value of <span style="font-family: Consolas, monospace;">AC_DC_ Back In Black</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>clean(\//:*?"&lt;&gt;|, 3)</nowiki></b></span>
 
<p style="margin-left:20pt;">This trivial example demonstrates how all filesystem-illegal characters are converted to underscores,
 
producing the nine-character output <span style="font-family: Consolas, monospace;">_________</span> which consists entirely of underscores.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FixCase(&hellip;): Changes the case of a given string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FixCase" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>fixcase(</b><i>string</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#FixCase|FixCase()]] function will convert the supplied text <i>string</i> according to the specified <i>mode</i>.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Title Case</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>All Words</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>2</b></td><td>First Word</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>3</b></td><td>All Uppercase</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>4</b></td><td>All Lowercase</td></tr>
 
</table></div>
 
 
 
Argument <i>mode</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>fixcase(enjoy the silence)</nowiki></b></span>
 
<p style="margin-left:20pt;">The default <i>mode</i> 0 is used, so the output is <span style="font-family: Consolas, monospace;">Enjoy the Silence</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>fixcase(enjoy the silence, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Using <i>mode</i> 1, all words are uppercased, so the output is <span style="font-family: Consolas, monospace;">Enjoy The Silence</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>fixcase(MY ALbUm IS cAlLeD: adam, 4)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs <span style="font-family: Consolas, monospace;">my album is called: adam</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FixSpacing(&hellip;): Intelligently splits adjacent camel-cased words====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FixSpacing" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>fixspacing(</b><i>string</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#FixSpacing|FixSpacing()]] function inserts spaces between adjacent camel-cased words in <i>string</i>.
 
It is useful for helping to clean and convert metadata that favors compactness over standard sentence structure.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Disables conversion</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Enables camel-case conversion</td></tr>
 
</table></div>
 
 
 
Argument <i>mode</i> is optional (defaults to 1).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>fixspacing(OneWorld)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs <span style="font-family: Consolas, monospace;">One World</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>fixspacing([name], 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the name field with any camel-case converted into standard sentence structure.
 
If the value of name was, <span style="font-family: Consolas, monospace;">MiracleOn34thStreet</span>, the output would be <span style="font-family: Consolas, monospace;">Miracle On 34th Street</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>fixspacing(Another [name])</nowiki></b></span>
 
<p style="margin-left:20pt;">Assuming the same [name] as above, this would return <span style="font-family: Consolas, monospace;">Another Miracle On 34th Street</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Hexify(&hellip;): Hexifies a string to make it suitable for web usage====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Hexify" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>hexify(</b><i>string</i><b>)</b></span>
 
The [[#Hexify|Hexify()]] function URI encodes a <i>string</i> to make it useable by a browser or search engine.
 
[[#Hexify|Hexify()]] is typically used by expressions generating or working on URLs in Media Center's Link Manager.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>hexify(Oasis - /(What's The Story/) Morning Glory?)</nowiki></b></span>
 
<p style="margin-left:20pt;">The result is <span style="font-family: Consolas, monospace;">Oasis%20-%20%28What%27s%20The%20Story%29%20Morning%20Glory%3F</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Left(&hellip;): Retrieves a specified number of characters from the left of a string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Left" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>left(</b><i>string</i><b>, </b><i>quantity</i><b>)</b></span>
 
The [[#Left|Left()]] function retrieves no more than <i>quantity</i> characters from the left of the <i>string</i>.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>left([filename], 3)</nowiki></b></span>
 
<p style="margin-left:20pt;">Return the Windows drive letter, colon and first back-slash from the filename.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Length(&hellip;): Returns the number of characters in a string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Length" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>length(</b><i>string</i><b>)</b></span>
 
The [[#Length|Length()]] function returns the number of characters contained in <i>string</i>.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>length(A Simple Plan)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns 13.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(compare(length([filename]), &gt;=, 68), Long, Short)</nowiki></b></span>
 
<p style="margin-left:20pt;">The length of the filename is calculated, and compared against 68, outputting <span style="font-family: Consolas, monospace;">Long</span> when the length is greater than or equal to 68, and <span style="font-family: Consolas, monospace;">Short</span> otherwise.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Mid(&hellip;): Retrieves specified characters from a string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Mid" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>mid(</b><i>string</i><b>, </b><i>start position</i><b>, </b><i>quantity</i><b>)</b></span>
 
The [[#Mid|Mid()]] function returns a specified <i>quantity</i> of characters from the <i>start position</i> in <i>string</i>.
 
 
 
The <i>start position</i> is 0-based (i.e. the first character is considered position 0).
 
A quantify of -1 returns all characters from the start positionning to the end of <i>string</i>.
 
 
 
Argument <i>start position</i> is optional (defaults to 0).
 
 
 
Argument <i>quantity</i> is optional (defaults to 1).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>mid(12345)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">1</span>, using is the default <i>quantity</i> (1) of characters from the default <i>start position</i> of (0 - the beginning of the <i>string</i>).</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>mid(12345, 1, 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns 2 characters beginning at <i>start position</i> 1, which is <span style="font-family: Consolas, monospace;">23</span>.</p>
 
 
 
Additional Examples
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=52809.0 An example that uses Mid() to re-order a date field.]
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=75891.0 An example that uses Mid() to output a number of stars based on an arbitrary rating value.]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Regex(&hellip;): Regular expression pattern matching and capture====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Regex" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>regex(</b><i>string</i><b>, </b><i>regexp</i><b>, </b><i>run mode</i><b>, </b><i>case sensitivity</i><b>)</b></span>
 
The [[#Regex|Regex()]] function performs regular expression (RE) pattern matching on a <i>string</i>.
 
The <i>string</i> is evaluated against the regular expression <i>regexp</i>, and <i>run mode</i> dictates the values output by [[#Regex|Regex()]].
 
The three modes allow for match testing, capture output, or silent operation.
 
 
 
All match captures are placed into special variables referenced as [R1], [R2], ... [R9], which can be used in later in the expression.
 
The contents of the captures [R1] ... [R9] are available until the end of the expression, or [[#Regex|Regex()]] is run again, whereby they are replaced.
 
The regular expression implementation used prior to Media Center 19 is the Microsoft 2010 TR1 engine, and in Media Center 19 it is the Boost engine.
 
 
 
Available <i>run mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Runs in Boolean test mode, returning either a 1 or 0, indicating whether the <i>string</i> matched (1) or did not match (0) the <i>regexp</i>. This <i>run mode</i> is useful within an [[#If|If()]] test, so that different true or false actions may be taken.</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1 to 9</b></td><td>Outputs the specified Nth capture group's contents, where N ranges from 1 to 9. Only a single capture is output in this mode, but all captures are available in the [R1] ... [R9] capture variables. This <i>run mode</i> is used to easily output a single matching sub-<i>string</i>.</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>-1</b></td><td>Runs in silent mode, with no output being produced.  This <i>run mode</i> is useful as a means to capture portions of the <i>string</i> to be later used in subsequent portions of an expression.</td></tr>
 
</table></div>
 
 
 
The <i>case sensitivity</i> argument toggles the case-sensitivity of regular expression matching.
 
Note that case insensitivity does not apply to characters inside a character class <span style="font-family: Consolas, monospace;">[ ]</span>.
 
Use both uppercase and lowercase characters when necessary to match either case (e.g. <span style="font-family: Consolas, monospace;">[aAbB]</span> to match either uppercase or lowercase <span style="font-family: Consolas, monospace;">A</span> or <span style="font-family: Consolas, monospace;">B</span>).
 
 
 
Available <i>case sensitivity</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Ignore case when matching (e.g. the letters E and e are identical)</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Consider case when matching (e.g. the letters E and e are considered different)</td></tr>
 
</table></div>
 
 
 
The regular expression language assigns special meaning to many characters.
 
A few of these meta-characters, such as forward slash <span style="font-family: Consolas, monospace;">/</span>, comma <span style="font-family: Consolas, monospace;">,</span> and both <span style="font-family: Consolas, monospace;">(</span> and <span style="font-family: Consolas, monospace;">)</span> are also reserved and used by the Media Center expression language.
 
To force the Media Center expression engine to ignore the meta-characters in <i>regexp</i>, surround the entire regular expression with <span style="font-family: Consolas, monospace;">/#</span> <span style="font-family: Consolas, monospace;">#/</span>.
 
This is one of Media Center's escapements, which tells the expression engine to ignore everything inside, so that the entire, uninterpreted <i>regexp</i> can be provided to the [[#Regex|Regex()]] regular expression evaluator.
 
Although surrounding <i>regexp</i> by <span style="font-family: Consolas, monospace;">/#</span> <span style="font-family: Consolas, monospace;">#/</span> is not necessary or required when no conflicting characters are in use, and you may manually escape the expression languages meta-characters with a forward slash <span style="font-family: Consolas, monospace;">/</span>, it is probably a safe practice to always encase every <i>regexp</i> within <span style="font-family: Consolas, monospace;">/#</span> <span style="font-family: Consolas, monospace;">#/</span>.
 
 
 
Argument <i>run mode</i> is optional (defaults to 0).
 
 
 
Argument <i>case sensitivity</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>ifelse(regex([name], /#^(the|an|a)\b#/, 0, 1), Fix your case!)</nowiki></b></span>
 
<p style="margin-left:20pt;">Searches the name field for any of the lowercase articles <span style="font-family: Consolas, monospace;">the</span>, <span style="font-family: Consolas, monospace;">and</span> and <span style="font-family: Consolas, monospace;">a</span> at the beginning of name, and outputs <span style="font-family: Consolas, monospace;">Fix your case!</span> when the match succeeds.
 
The <i>run mode</i> is 0 which is a test and capture mode, and <i>case sensitivity</i> is enabled.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>if(regex([artist], /#([[:punct:]])#/, 0), [R1] --&gt; [Artist], No Punctuation)</nowiki></b></span>
 
<p style="margin-left:20pt;">Using the default mode 0, [[#Regex|Regex()]] will output a Boolean for use inside a conditional to cause some action to occur based on the match success or failure.
 
This example matches against the artist field looking for any punctuation character.
 
If the match succeeds (a punctuation character was found), that character is output followed by the <i>string</i> <span style="font-family: Consolas, monospace;"> --> </span> and the artist. In there was no match, the <i>string</i> <span style="font-family: Consolas, monospace;">No Punctuation</span> is output.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>regex(D03T02 some track.mp3, /#^D(\d+)T(\d+)#/, 1)Disc: [R1], Track: [R2]</nowiki></b></span>
 
<p style="margin-left:20pt;">The <i>string</i> is matched against the <i>regexp</i> that is looking for a <span style="font-family: Consolas, monospace;">D</span> followed by any number of digits, followed by a <span style="font-family: Consolas, monospace;">T</span> and then more digits.
 
Those digits were captured, and later used to output the value <span style="font-family: Consolas, monospace;">Disc: 03, Track: 02</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>regex([filename (name)], /#^(\d+)-#/, -1)Track number is [R1]</nowiki></b></span>
 
<p style="margin-left:20pt;">Using <i>run mode</i> -1, the file's name is pattern tested against the <i>regexp</i> which is looking for leading digits followed by a dash.
 
Those digits are captured in buffer [R1] which is used later in the expression.  If the file name was <span style="font-family: Consolas, monospace;">2-foo.mp3</span>, the output would be <span style="font-family: Consolas, monospace;">Track number is 2</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>regex([filename], /#(\d{1,2})\.(\d{1,2}).(\d{4})#/, -1)[R3]//[R1]//[R2]</nowiki></b></span>
 
<p style="margin-left:20pt;">Matches and captures a date formatted as dd.mm.yyyy anywhere within the filename, and rearranges it in a standard format of yyyy/mm/dd.
 
Since <i>run mode</i> is -1, no output occurs.
 
However, captured match segments are made available for subsequent use.
 
The three captures, [R1], [R2] and [R3] are arranged in the textual output so that we get the desired year/month/day ordering, such as <span style="font-family: Consolas, monospace;">2011/08/19</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====RemoveCharacters(&hellip;): Removes a list of characters from a string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="RemoveCharacters" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>removecharacters(</b><i>string</i><b>, </b><i>character list</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#RemoveCharacters|RemoveCharacters()]] function will remove from <i>string</i> any characters in the <i>character list</i>.  The characters removed depend upon the <i>mode</i> specified.
 
The function operates in a case-sensitive manner.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Remove all instances</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Remove from the beginning only</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>2</b></td><td>Remove from the end only</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>3</b></td><td>Remove from each end</td></tr>
 
</table></div>
 
 
 
Argument <i>mode</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>removecharacters(Paper, Ppr)</nowiki></b></span>
 
<p style="margin-left:20pt;">Removes <span style="font-family: Consolas, monospace;">P</span>, <span style="font-family: Consolas, monospace;">p</span>, and <span style="font-family: Consolas, monospace;">r</span> from <span style="font-family: Consolas, monospace;">Paper</span>, resulting in <span style="font-family: Consolas, monospace;">ae</span>.
 
The default <i>mode</i> 0 is in effect, removing all instances of the characters specified in the <i>character list</i>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>removecharacters(Paper, Ppr, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">With <i>mode</i> 1 set, only the initial character <span style="font-family: Consolas, monospace;">P</span> is removed, resulting in <span style="font-family: Consolas, monospace;">aper</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>removecharacters(Paper, Ppr, 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">In <i>mode</i> 2, only one character from the end of the <i>string</i> are removed, leaving "Pape.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>removecharacters(Paper, Ppr, 3)</nowiki></b></span>
 
<p style="margin-left:20pt;">Both the front and back are affected in <i>mode</i> 3, causing the removal of the leading <span style="font-family: Consolas, monospace;">P</span> and trailing <span style="font-family: Consolas, monospace;">r</span> resulting in <span style="font-family: Consolas, monospace;">ape</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>removecharacters([artist], /(/))</nowiki></b></span>
 
<p style="margin-left:20pt;">Removes any <span style="font-family: Consolas, monospace;">(</span> and <span style="font-family: Consolas, monospace;">)</span> characters from anywhere within the [artist] field.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====RemoveLeft(&hellip;): Trims characters from the beginning of a string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="RemoveLeft" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>removeleft(</b><i>string</i><b>, </b><i>quantity</i><b>)</b></span>
 
The [[#RemoveLeft|RemoveLeft()]] function removes a specified <i>quantity</i> of characters from the left side of a <i>string</i>.
 
If the <i>quantity</i> is larger than the length of the <i>string</i>, the output will be empty.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>removeleft(Good Deeds, 5)</nowiki></b></span>
 
<p style="margin-left:20pt;">Removes the first 5 characters from resulting in <span style="font-family: Consolas, monospace;">Deeds</span> being output.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====RemoveRight(&hellip;): Trims characters from the end of a string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="RemoveRight" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>removeright(</b><i>string</i><b>, </b><i>quantity</i><b>)</b></span>
 
The [[#RemoveRight|RemoveRight()]] function removes a specified <i>quantity</i> of characters from the right side of a <i>string</i>.
 
If the <i>quantity</i> is larger than the length of the <i>string</i>, the output will be empty.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>removeright(03-02-1959,5)</nowiki></b></span>
 
<p style="margin-left:20pt;">Removes the last 5 characters from the given date, leaving only the month and year <span style="font-family: Consolas, monospace;">03-02</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Replace(&hellip;): Replace or remove a string segment====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Replace" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>replace(</b><i>string</i><b>, </b><i>old</i><b>, </b><i>new</i><b>)</b></span>
 
The [[#Replace|Replace()]] function replaces all instances of <i>old</i> within <i>string</i> with <i>new</i>.
 
If <i>new</i> is unspecified, it defaults to an empty value, causing <i>old</i> to be removed.
 
[[#Replace|Replace()]] operates in a case-sensitive manner.
 
 
 
Argument <i>new</i> is optional (defaults to EMPTY).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>replace(The Daily Show with John Oliver, hn Oliver, n Stewart)</nowiki></b></span>
 
<p style="margin-left:20pt;">Now that John Oliver has completed his summer stand-in for Jon Stewart, it is time for a replacement.
 
The <i>old</i> sequence <span style="font-family: Consolas, monospace;">hn Oliver</span> will be replaced with the <i>new</i> sequence <span style="font-family: Consolas, monospace;">n Stewart</span>, resulting in
 
<span style="font-family: Consolas, monospace;">The Daily Show with Jon Stewart</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>replace(Sample String, s, Replaced)</nowiki></b></span>
 
<p style="margin-left:20pt;">In this example, the original <i>string</i> does not contain the <i>old</i> value <span style="font-family: Consolas, monospace;">s</span> anywhere,
 
so no replacement occurs and the original <i>string</i> is returned.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>replace(Led Zeppelin.[remastered], .[remastered])</nowiki></b></span>
 
<p style="margin-left:20pt;">Removes the trailing <i>old</i> value <span style="font-family: Consolas, monospace;">.[remastered]</span> from the original <i>string</i>, resulting in <span style="font-family: Consolas, monospace;">Led Zeppelin</span>.
 
Because no <i>new</i> <i>string</i> is specified, the default empty value is used as a replacement,
 
effectively stripping the <i>old</i> value.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Right(&hellip;): Retrieves a specified number of characters from the right of a string====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Right" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>right(</b><i>string</i><b>, </b><i>quantity</i><b>)</b></span>
 
The [[#Right|Right()]] function retrieves the specified <i>quantity</i> of characters from the right of the <i>string</i>.
 
If <i>quantity</i> is larger than the length of <i>string</i>, the original <i>string</i> is returned.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>right([filename], 3)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the last three characters from the filename (typically this is the file's suffix).</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
===List Manipulation===
 
Media Center supports several different types of fields, one of them being the List type.
 
A List type is a library field of type List, or an expression coerced into a list type.
 
 
 
The functions in this section provide the ability to manipulate lists and list items.
 
A list is a sequence of strings, each separated from one another by an arbitrary delimiter.
 
The default delimiter is a semicolon.
 
Media Center does not make a strict distinction between a string and a list of strings.
 
In fact, a list is just a string, and it is safe to think of a string as a list with zero or more
 
arbitrary delimiter sequences.
 
For example, the string "2013-08-17" can be thought of as a dash-delimited list with the three items "2013", "08" and "17".
 
 
 
This weak typing is very useful since a list,
 
for example, "John; Sally" that contains the two items "John" and "Sally" can be manipulated not only using the
 
list functions in this section, but because it is just a string, it can also be manipulated with string functions.
 
For example, taking the same list above and combining it with the string "; Joe" adds a new item
 
to the list "John; Sally; Joe", and removing the first 6 characters with [[#RemoveLeft|RemoveLeft()]] would
 
produce a now shortened string/list "Sally; Joe".
 
The list manipulation functions make this job easier, especially when using the default semicolon delimiter.
 
Furthermore, since any character or sequence of characters can be considered as a list delimiter,
 
any string can be treated as a list, and the functions in this section can be used on any string as needed.
 
 
 
In some areas such as a panes column, or a category view, Media Center gives special treatment to List types.
 
For example, using semicolon as the delimiter, a List will be automatically split apart into its individual items.
 
====ListBuild(&hellip;): Constructs a list from a series of items====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="ListBuild" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>listbuild(</b><i>mode</i><b>, </b><i>delimiter</i><b>, </b><i>item1</i><b>, </b><i>item2</i><b>, </b><i>&hellip;</i><b>)</b></span>
 
The [[#ListBuild|ListBuild()]] function constructs a list from <i>item1</i>, <i>item2</i>, ... using a supplied <i>delimiter</i> to separate the individual items in the resulting list.
 
The construction <i>mode</i> affects how empty items are handled - they can be included or excluded.
 
The <i>mode</i> typically used exclude empty items, so that lists do not contain empty slots.
 
However, there are occasions when retaining empty slots is useful, such as when using a list to act like an array where data is stored in particular slots so that the [[#ListItem|ListItem()]] function may later retrieve values at a given index.
 
It can also be useful when calculating several expressions and combining the results into a single list for presentation; by including all items, items can be made to line-up for visual inspection in a column.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Include empty values</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Exclude empty values</td></tr>
 
</table></div>
 
 
 
The <i>delimiter</i> argument specifies the character or character sequence to be inserted in between items in the list.
 
An unspecified <i>delimiter</i> will result in a <i>delimiter</i>-less concatenation of the supplied arguments <i>item1</i>, <i>item2</i>, etc.
 
 
 
Argument <i>delimiter</i> is optional (defaults to EMPTY).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>listbuild(1, ;, Bennie, June)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns a standard semicolon-separated list containing two items <span style="font-family: Consolas, monospace;">Bennie; June</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listbuild(1, \, [album artist (auto)], [album])</nowiki></b></span>
 
<p style="margin-left:20pt;">Builds a backslash-separated list combining the two fields album artist (auto) and album.
 
This is useful for building panes column or categories hierarchies in a view.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====ListClean(&hellip;): Various list operations====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="ListClean" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>listclean(</b><i>list</i><b>, </b><i>mode</i><b>, </b><i>delimiter</i><b>)</b></span>
 
The [[#ListClean|ListClean()]] function performs one of the operations specified by <i>mode</i> on the given <i>list</i>.
 
The specified <i>delimiter</i> separates <i>list</i> items.
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Remove duplicates</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>2</b></td><td>Reverse the order of items</td></tr>
 
</table></div>
 
 
 
Argument <i>delimiter</i> is optional (defaults to SEMICOLON).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>listclean(c;b;c;a, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Removes duplicates from the <i>list</i>, returning <span style="font-family: Consolas, monospace;">c;b;a</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listclean(d;c;b;a, 2) </nowiki></b></span>
 
<p style="margin-left:20pt;">Reverses the <i>list</i> items, returning <span style="font-family: Consolas, monospace;">a;b;c;d</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listclean(\a\x\x\x\z, 1, \) </nowiki></b></span>
 
<p style="margin-left:20pt;">Removes duplicates from a backslash-separated <i>list</i>, returning <span style="font-family: Consolas, monospace;">\a\x\z</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====ListCombine(&hellip;): Combines two delimited lists into a single delimited list====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="ListCombine" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>listcombine(</b><i>list1</i><b>, </b><i>list2</i><b>, </b><i>input delimiter</i><b>, </b><i>output delimiter</i><b>, </b><i>mode</i><b>)</b></span>
 
The [[#ListCombine|ListCombine()]] function returns a single list after performing the operation specified by <i>mode</i> on the two lists <i>list1</i> and <i>list2</i>.
 
An <i>input delimiter</i> and an <i>output delimiter</i> may be specified.
 
The <i>input delimiter</i> is effective for both <i>list1</i> and <i>list2</i>, and the <i>output delimiter</i> will be used in the returned list, replacing the
 
<i>input delimiter</i> from both <i>list1</i> and <i>list2</i>.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Combine lists removing duplicates (order is preserved).</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Output only items contained in both lists (order is preserved).</td></tr>
 
</table></div>
 
 
 
Argument <i>input delimiter</i> is optional (defaults to SEMICOLON).
 
 
 
Argument <i>output delimiter</i> is optional (defaults to SEMICOLON).
 
 
 
Argument <i>mode</i> is optional (defaults to 0).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>listcombine(a;b;e, a;b;c;d)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">a;b;e;c;d</span>.
 
This example uses the default <i>mode</i> 0 to combine <i>list1</i> with <i>list2</i>, preserving the order of items.
 
The default <span style="font-family: Consolas, monospace;">;</span> <i>input delimiter</i> and <i>output delimiter</i> is used.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listcombine(a;b;e, a;b;c;d, ;, ;, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">a;b</span>.
 
The <i>input delimiter</i> and <i>output delimiter</i> are both specified as <span style="font-family: Consolas, monospace;">;</span>,
 
and <i>mode</i> 1 is used to produce a list of only items that exist in both <i>list1</i> and <i>list2</i>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listcombine(a-c, c-f, -, ..., 0)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">a...c...f</span>. The <i>input delimiter</i> is <span style="font-family: Consolas, monospace;">-</span>, while the <i>output delimiter</i> is <span style="font-family: Consolas, monospace;">...</span>, and <i>mode</i> 0 combines both lists.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listcombine(a#@#c, c#@#f, #@#, ., 0)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">a.c.f</span>. This example demonstrates how to combine two lists with duplicates removed while replacing a multi-character <i>input delimiter</i> <span style="font-family: Consolas, monospace;">#@#</span> with a single-character <i>output delimiter</i> <span style="font-family: Consolas, monospace;">.</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listcombine([people], [places])&amp;datatype=[list]</nowiki></b></span>
 
<p style="margin-left:20pt;">The result here would be a single, semicolon delimited list containing all the list items from the [people] and [places] fields.
 
For example, if [people] contains <span style="font-family: Consolas, monospace;">Family\Mum; Family\Dad; Family\Gran</span>, and [places] contains <span style="font-family: Consolas, monospace;">UK\Scotland\Edinburgh; UK\Scotland\Edinburgh\Edinburgh Castle</span>,
 
the output list would be <span style="font-family: Consolas, monospace;">Family\Mum; Family\Dad; Family\Gran; UK\Scotland\Edinburgh; UK\Scotland\Edinburgh\Edinburgh Castle</span>.
 
Using the <span style="font-family: Consolas, monospace;">&datatype=[list]</span> cast makes the expression split individual list items in a panes or categories view.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====ListCount(&hellip;): Returns the number of items in a list====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="ListCount" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>listcount(</b><i>list</i><b>, </b><i>delimiter</i><b>)</b></span>
 
The [[#ListCount|ListCount()]] function returns the number of items that exist in a <i>list</i> delimited by <i>delimiter</i>.
 
 
 
Argument <i>delimiter</i> is optional (defaults to SEMICOLON).
 
  
|- valign="top"
+
== Expressions and Search ==
! scope="row" style="background: #ecedf3; color: #111; " | Examples
+
The expression language is fully available to the search query engine (Search, Set rules for file display, etc.).
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>listcount([keywords])</nowiki></b></span>
+
This allows creation of more complex search queries than would otherwise be possible.
<p style="margin-left:20pt;">Returns the number of keywords for the file.</p>
+
An expression-based search query is any valid expression that produces a zero or non-zero numeric output.
<span style="font-family: Consolas, monospace;"><b><nowiki>listcount([filename (path)], \)</nowiki></b></span>
+
The syntax of the query is:
<p style="margin-left:20pt;">Returns the number of the directories in a Windows drive-based file path.
 
The example demonstrates that non-List type fields can be used with the functions in this section.
 
While the <i>delimiter</i> specified here is <span style="font-family: Consolas, monospace;">\</span>, an escaped forward slash <span style="font-family: Consolas, monospace;">//</span> could be used when applicable.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====ListItem(&hellip;): Returns an item from a location in a list====
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;"><b>[=</b><i>expression</i><b>]=</b><i>numval</i></span></div>
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
where expression is any valid expression, and numval is the expected numeric output produced by the expression.
|- id="ListItem" valign="top"
+
The expression is evaluated against the current list of available files and the expression output numerically compared against numval.
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
All files for which the comparison is true are returned as part of the file list produced by the query and all files that fail the comparison are winnowed from the file list.
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>listitem(</b><i>list</i><b>, </b><i>position</i><b>, </b><i>delimiter</i><b>)</b></span>
 
The [[#ListItem|ListItem()]] function returns the item from the specified <i>position</i> in the <i>list</i>.
 
Items in a <i>list</i> are zero-based, so the first item in the <i>list</i> is located at <i>position</i> 0.
 
Nothing is returned with the <i>position</i> is outside the bounds of the <i>list</i>.
 
  
Argument <i>delimiter</i> is optional (defaults to SEMICOLON).
+
The following example illustrates an expression-based search query:
  
|- valign="top"
+
<div style="margin-left: 20pt"><span style="font-family: monospace,monospace; font-size:1em;">[=ismissing([filename (path)]\Folder.jpg)]=1</span></div>
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>listitem(a;b;c, 1)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">b</span>, since <i>position</i> 1 is the second item in the <i>list</i> <span style="font-family: Consolas, monospace;">a;b;c</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listitem(1:04:47, 2, :)</nowiki></b></span>
 
<p style="margin-left:20pt;">Using the <i>delimiter</i> <span style="font-family: Consolas, monospace;">:</span>, returns item at <i>position</i> 2, which is the seconds value <span style="font-family: Consolas, monospace;">47</span> from the time <span style="font-family: Consolas, monospace;">1:04:47</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
  
====ListSort(&hellip;): Sort a list of values====
+
The [[Test_and_Comparison_Functions#IsMissing|IsMissing()]] function is run using the file name argument <span style="font-family: monospace,monospace; font-size:1em;">[filename (path)]</span> appended by <span style="font-family: monospace,monospace; font-size:1em;">\Folder.jpg</span>,
 +
and returns a Boolean value <span style="font-family: monospace,monospace; font-size:1em;">1</span> for files that are missing, and this <span style="font-family: monospace,monospace; font-size:1em;">1</span> is compared against the value <i>numval</i>.
 +
All these files where there was a successful comparison are returned in the file list,
 +
and all those for which the expression produced <span style="font-family: monospace,monospace; font-size:1em;">0</span> are filtered from the file list.
 +
By inverting the comparison and using a <span style="font-family: monospace,monospace; font-size:1em;">0</span> numval, the set of files remaining in the file list would be those that did not match.
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
== HTML Font Properties ==
|- id="ListSort" valign="top"
+
The expression language recognizes a limited set of HTML font properties and attributes. These can be used to set font styles in most text drawing areas, such as captions, thumbnail text and in the configuration of Theater View.
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
+
HTML tags are used by surrounding the desired content with an opening and closing tag, in the form of:
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>listsort(</b><i>list</i><b>, </b><i>mode</i><b>, </b><i>delimiter</i><b>)</b></span>
 
The [[#ListSort|ListSort()]] function sorts a <i>list</i> in the order according to <i>mode</i>, using the specified <i>delimiter</i>.
 
  
Available <i>mode</i> values:
+
: <span style="font-family: monospace,monospace; font-size:1em;"><<i>tag</i>><i>desired content</i><//<i>tag</i>></span>
  
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
+
The supported HTML tags are:
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Ascending sort</td></tr>
+
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse">
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Descending sort</td></tr>
+
<tr><td style="text-align:left; padding-right:20pt"><b><nowiki><b></nowiki></b></td><td>Bold</td></tr>
 +
<tr><td style="text-align:left; padding-right:20pt"><b><nowiki><i></nowiki></b></td><td>Italics</td></tr>
 +
<tr><td style="text-align:left; padding-right:20pt"><b><nowiki><u></nowiki></b></td><td>Underline</td></tr>
 +
<tr><td style="text-align:left; padding-right:20pt"><b><nowiki><font></nowiki></b></td><td>Font properties (see attributes below)</td></tr>
 
</table></div>
 
</table></div>
  
Argument <i>mode</i> is optional (defaults to 0).
+
The <b>font</b> tag supports the following attributes:
 
+
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse">
Argument <i>delimiter</i> is optional (defaults to SEMICOLON).
+
<tr><td style="text-align:left; padding-right:20pt"><b>alpha</b></td><td>Sets alpha-blending percentage (0 - 100)</td></tr>
 
+
<tr><td style="text-align:left; padding-right:20pt"><b>color</b></td><td>Sets the foreground color (RGB hex values from 00 to ff in the form of rrggbb)</td></tr>
|- valign="top"
+
<tr><td style="text-align:left; padding-right:20pt"><b>bgcolor</b></td><td>Sets the background color (same values as color)</td></tr>
! scope="row" style="background: #ecedf3; color: #111; " | Examples
+
<tr><td style="text-align:left; padding-right:20pt"><b>face</b></td><td>Sets the font face (a font name)</td></tr>
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>listsort(c;a;b)</nowiki></b></span>
+
<tr><td style="text-align:left; padding-right:20pt"><b>size</b></td><td>Sets the font size (a percentage scaling value)</td></tr>
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">a;b;c</span>, using the default ascending <i>mode</i> and (<span style="font-family: Consolas, monospace;">:</span>) <i>delimiter</i>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listsort(Joe Baxter/, Sally Henson/, Sue Smith, 1, /,)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">Sue Smith,Sally Henson,Joe Baxter</span>.
 
Note the requirement to escape the <span style="font-family: Consolas, monospace;">,</span> characters within the <i>list</i> string and in the specified <i>delimiter</i> itself.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>listsort([artist];[composer])</nowiki></b></span>
 
<p style="margin-left:20pt;">Sorts the combined artist and composer lists in ascending order.
 
Note the simple manual construction of a single List by combining the two List type fields, and forcing a <span style="font-family: Consolas, monospace;">;</span> between the two.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
===Date and Time Functions===
 
 
 
Media Center provides several functions for the conversion, formatting and generation of dates and times.
 
Date and time for a Date-type field is stored internally as a single floating-point number,
 
where the integer portion represents the number of days since the Epoch, and the decimal portion represents the fraction of a day in seconds.
 
The Epoch is defined as December 30th, 1899 at 00:00:01.
 
Certain fractional values and whole numbers are used to encode Time-only and Year-only values.
 
For example, the internal Date value of "2" is considered as 1900, without a time when converted using the DateTime conversion format of [[#FormatDate|FormatDate()]], whereas adding a small fraction and using "2.001" instead produces a value of "1/1/1900 12:01 am".
 
These details are only relevant if you are doing conversions.
 
 
 
The Windows locale setting will affect the interpretation and formatting of date and time information.
 
====ConvertDate(&hellip;): Converts a human-readable date to the internal format required for use in date fields====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="ConvertDate" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>convertdate(</b><i>date_time string</i><b>)</b></span>
 
Converts a human-readable <i>date_time string</i> into the internal floating-point representation used by Media Center to store a date and time.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>convertdate(3//6//2012)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the value <span style="font-family: Consolas, monospace;">40974</span>, which is the internal floating-point representation of the date string <span style="font-family: Consolas, monospace;">3/6/2012</span>.
 
This value can used by any field of type Date, or in any function that requires as input a Date type value.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatdate(convertdate(12//2//1985), decade))</nowiki></b></span>
 
<p style="margin-left:20pt;">Converts the date string <span style="font-family: Consolas, monospace;">12/2/1985</span> (note: December 2nd, not February 12th) into a Date type value,
 
and then formats the result as a decades grouping, returning <span style="font-family: Consolas, monospace;">1980's</span>.
 
This might be used for creating decade groupings.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FormatDate(&hellip;): Formats a date value in a specified manner====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FormatDate" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>formatdate(</b><i>date value</i><b>, </b><i>format specifier</i><b>, </b><i>empty label</i><b>)</b></span>
 
The [[#FormatDate|FormatDate()]] function provides custom formatting of date and time values through the use of a <i>format specifier</i>.
 
Output will be formatted according to <i>format specifier</i>.
 
 
 
The <i>date value</i> is a Media Center internal floating-point date/time representation, stored in Date fields,
 
and output from various functions such as [[#Now|Now()]] and [[#ConvertDate|ConvertDate()]].
 
To pass a field of type Date to [[#FormatDate|FormatDate()]], use the raw (unformatted) field specification, such as "[Date Imported,0]".
 
 
 
The <i>format specifier</i> provides a recipe for converting the internal value into a human-readable string.
 
Supported are a variety of Windows style, strftime() style, and Media Center-specific formats specifiers.
 
Construct the <i>format specifier</i> from any number or combination of those defined in the following table.
 
Additionally, any non-format characters will be output without interpretation.
 
This allows creating rich date/time output strings.
 
To output a word that is a reserved <i>format specifier</i>, surround the word with double-quotes.
 
 
 
The <i>empty label</i> argument will be output if the <i>date value</i> is empty.
 
 
 
<blockquote>
 
{| style="background: #f9f9f9;" border="1" cellpadding="1" cellspacing="0"
 
| style="background: #ecedf3;" | || colspan="3" align="center" style="background: #ecedf3;" | '''Specifier''' || style="background: #ecedf3;" | '''Description'''
 
|-
 
| rowspan="7" width="100" | '''Day'''
 
| align="center" width="65" | d || || Day || Day of the month as digits without leading zeros for single-digit days.
 
|-
 
| align="center" | dd  || %d ||        || Day of the month as digits with leading zeros for single-digit days.
 
|-
 
| align="center" | ddd  || %a ||        || Day of the week, abbreviated to three letters.
 
|-
 
| align="center" | dddd || %A || Dayname || Day of the week.
 
|-
 
| align="center" |      || %w ||        || Day of the week as a decimal number, Sunday as 0 (0-6).
 
|-
 
| align="center" |      || %j ||        || Day of the year (001-366)
 
|-
 
| align="center" |      || %j ||Dayordinal|| Ordinal day of the month (e.g. 1st, 2nd, etc.).
 
|-
 
| rowspan="4" | '''Month'''
 
| align="center" | M    ||    ||        || Month as digits without leading zeros for single-digit months.
 
|-
 
| align="center" | MM  || %m ||        || Month as digits with leading zeros for single-digit months.
 
|-
 
| align="center" | MMM  || %b ||        || Abbreviated month name, three letters (e.g. Apr, Nov).
 
|-
 
| align="center" | MMMM || %B || Month  || Full Month name (e.g. April, November).
 
|-
 
| rowspan="4" | '''Year'''
 
| align="center" | y    ||    ||        || Year represented only by the last digit.
 
|-
 
| align="center" | yy  || %y ||        || Year represented only by the last two digits. A leading zero is added for single-digit years.
 
|-
 
| align="center" | yyyy || %Y || Year    || Year represented by a full four or five digits.
 
|-
 
| align="center" |      ||    || Decade  || Year expressed as a decade (e.g. 1970's, 2010's)
 
|-
 
| rowspan="4" | '''Hour'''
 
| align="center" | h    ||    || Hour    || Hours with no leading zero for single-digit hours; 12-hour clock.
 
|-
 
| align="center" | hh  || %I ||        || Hours with leading zero for single-digit hours; 12-hour clock.
 
|-
 
| align="center" | H    ||    ||        || Hours with no leading zero for single-digit hours; 24-hour clock.
 
|-
 
| align="center" | HH  || %H ||        || Hours with leading zero for single-digit hours; 24-hour clock.
 
|-
 
| rowspan="2" | '''Minute'''
 
| align="center" | m    ||    || Minute  || Minutes with no leading zero for single-digit minutes.
 
|-
 
| align="center" | mm  || %M ||        || Minutes with leading zero for single-digit minutes.
 
|-
 
| rowspan="2" | '''Second'''
 
| align="center" | s    ||    || Second  || Seconds with no leading zero for single-digit seconds.
 
|-
 
| align="center" | ss  || %S ||        || Seconds with leading zero for single-digit seconds.
 
|-
 
| rowspan="2" | '''AM/PM'''
 
| align="center" | t    ||    ||        || One character time marker string, such as A or P.
 
|-
 
| align="center" | tt  || %p ||        || Multi-character time marker string, such as AM or PM.
 
|-
 
| rowspan="5" | '''Combined'''
 
| align="center" |      || %x || Date    || Date expressed in the system's format.
 
|-
 
| align="center" |      || %X || Time    || Time expressed in the system's format.
 
|-
 
| align="center" |      || %c || DateTime|| Date and time expressed in the system's format.
 
|-
 
| align="center" |      ||    || ShortDate|| Age-conditional date formatted as one of "Year", "MMM d", or "MMM d Year".
 
|-
 
| align="center" |      ||    || ShortDateTime || Date in ShortDate format plus Time.
 
|-
 
| rowspan="2" | '''Week Number'''
 
| align="center" |      || %U ||        || Week number with the first Sunday as the first day of week one (00-53).
 
|-
 
| align="center" |      || %W ||        || Week number with the first Monday as the first day of week one (00-53).
 
|-
 
| rowspan="4" | '''Miscellaneous'''
 
| align="center" |      ||    || Elapsed || Time expressed as elapsed time (e.g. 2.5 hours).
 
|-
 
| align="center" |      ||    ||ElapsedAgo|| Time expressed as elapsed time ago (e.g. 2.5 hours ago).
 
|-
 
| align="center" |      ||    || Filename|| Date and time expressed in filename-friendly format, includes seconds to avoid filename collisions (e.g. 20040521-032221).
 
|-
 
| align="center" |      || %% ||        || A percent (%) character.
 
|-
 
|}
 
</blockquote>
 
 
 
Argument <i>date value</i> is optional (defaults to [date,0]).
 
 
 
Argument <i>empty label</i> is optional (defaults to EMPTY).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>formatdate(year-month)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the file's date formatted as Year-Month, such as <span style="font-family: Consolas, monospace;">2012-April</span>. The default <i>date value</i> of <span style="font-family: Consolas, monospace;">[Date,0]</span> is used.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatdate([last played,0], yyyy//MM//dd, Not Yet)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the file's last played date as year/month/day without the time, ignoring the system locale setting.
 
If a file has no last played value, the expression will output <span style="font-family: Consolas, monospace;">Not Yet</span> instead.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatdate([date modified,0], month %Y)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the file's modification date/time in the form of a long month name and a four-digit year, such as <span style="font-family: Consolas, monospace;">December 2010</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatdate([date imported,0], The "year" is year)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs the <span style="font-family: Consolas, monospace;">The year is ####</span>, where #### is the year the file was imported into the Library.
 
Note that the word <span style="font-family: Consolas, monospace;">year</span> must be surrounded in double-quotes to have it considered as literal text,
 
and not the <span style="font-family: Consolas, monospace;"><b>Year</b></span> <i>format specifier</i>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatdate([date imported,0], month)&amp;datatype=[month]</nowiki></b></span>
 
<p style="margin-left:20pt;">This examples is the same as the previous example, but includes a cast to the Month type <span style="font-family: Consolas, monospace;">&datatype=[month]</span>.
 
This cast can be used to cause chronological month-sorting, rather than month name alphabetic-sorting, in a panes or category view.
 
Data-type coercion is discussed [[#Specify_data_types_for_expression_based_fields|above]].</p>
 
 
 
Additional Examples
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=71000.msg479314#msg479314 Date formatting development discussion, usage tips and examples.]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Now(&hellip;): Retrieve and display the system date====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Now" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>now(</b><b>)</b></span>
 
The [[#Now|Now()]] function returns a floating-point value representing the current system date and time.
 
It is generally useful for performing date arithmatic in expressions that desire to figure out elapsed time.
 
Any raw date field or value representing a date can be subtracted from [[#Now|Now()]] to realize an elapsed time delta.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>now()</nowiki></b></span>
 
<p style="margin-left:20pt;">When run on Aug 17, 2013 at 19:28:00, returns approximately <span style="font-family: Consolas, monospace;">41503.811115995</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatdate(now(), date)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the current date, without a time component, formatted according to the system's locale settings.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>formatdate(math(now() - 3, dddd dd MMMM yyyy H:mm)</nowiki></b></span>
 
<p style="margin-left:20pt;">The date from three days ago is formatted as something like <span style="font-family: Consolas, monospace;">Wednesday 14 August 2013 19:35</span>.
 
This is accomplished by subtracting the value <span style="font-family: Consolas, monospace;">3</span>, which would be days, from [[#Now|Now()]], and its output formatted by [[#FormatDate|FormatDate()]].</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
===File Path and Identifier Functions===
 
 
 
The functions in this section provide specific file-related information such as
 
a file's name, path, volume, and other Media Center internal information.
 
====FileDBLocation(&hellip;): Identifies a file's databases====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FileDBLocation" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>filedblocation(</b><i>format</i><b>)</b></span>
 
The [[#FileDBLocation|FileDBLocation()]] function returns identifiers in the specified <i>format</i> specified that indicate to which internal database(s) a file belongs.
 
Media Center maintains several internal databases to track a file's disposition.
 
This function is primarily for technical use only, and will have little utility for most users.
 
 
 
Available <i>format</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Semicolon-separated list of formatted database names</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Numeric value of OR'd database bit flags</td></tr>
 
 
</table></div>
 
</table></div>
  
The table below provides common values output from [[#FileDBLocation|FileDBLocation()]]:
+
Any combination of HTML tags and font attributes can be used.
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9" border="1">
+
An HTML tag must have an opening and closing tag.
<tr><td style="text-align:left; padding-right:20pt">Database name</td><td>Bit position</td></tr>
+
Nesting is allowed, but be sure to properly balance like opening and closing tags.
<tr><td style="text-align:left; padding-right:20pt">Main</td><td>0</td></tr>
+
Attribute values must be double quoted. The closing tag's forward slash requires escapement with an extra forward slash.
<tr><td style="text-align:left; padding-right:20pt">Playing Now</td><td>1</td></tr>
+
The following examples illustrate using HTML font properties:
<tr><td style="text-align:left; padding-right:20pt">CD</td><td>2</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Explorer</td><td>3</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Other (16)</td><td>5</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Other (6)</td><td>6</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Grouping</td><td>7</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Removed</td><td>8</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Podcast</td><td>10</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Other (4096)</td><td>12</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Stacks</td><td>14</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Category Images</td><td>18</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Bad</td><td>19</td></tr>
 
</table></div>
 
  
Argument <i>format</i> is optional (defaults to 0).
+
: <span style="font-family: monospace,monospace; font-size:1em;"><nowiki><i>This is in italics<//i></nowiki></span>
  
|- valign="top"
+
: <span style="font-family: monospace,monospace; font-size:1em;"><nowiki><i><b>And this is bold and italic<//b><//i></nowiki></span>
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>filedblocation()</nowiki></b></span>
 
<p style="margin-left:20pt;">For a file in the <span style="font-family: Consolas, monospace;">Main</span> and <span style="font-family: Consolas, monospace;">Other (4096)</span> databases, the result would be <span style="font-family: Consolas, monospace;">Main; Other (4096)</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filedblocation(1)</nowiki></b></span>
 
<p style="margin-left:20pt;">The result from the same file would be <span style="font-family: Consolas, monospace;">4096</span> (bit 0 and bit 12 set).</p>
 
  
Additional Examples
+
: <span style="font-family: monospace,monospace; font-size:1em;"><nowiki><b>The<font color=&quot;ff0000&quot; size=&quot;80&quot; alpha=&quot;50&quot;> Great <//font>Gatsby<//b></nowiki></span>
  
:[http://yabb.jriver.com/interact/index.php?topic=77896.msg539271#msg539271 Sample expression that uses FileDBLocation() to show a file's databases.]
+
== Expression Editors ==
|}
+
There are a couple of variations of dialog or edit field used to enter expressions.
<div style="text-align:right;">([[#top|Back to top)]]</div>
+
Some allow multi-line expressions, while others are single line, but can be expanded to multi-line editors.
 +
Unfortunately, some single-line editors flatten multi-line expressions into a single line, replacing the newlines with spaces.
  
====FileFolder(&hellip;): Returns the name of a file's parent====
+
== Acknowledgements ==
 +
A big tip of hat to [[User:Marko|marko]] who tackled the enormous challenge of documenting the MC Expression Language in detail. His work was instrumental and through which has brought clarity and great assistance to Media Center users worldwide.
  
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
+
Also, a huge thanks to user [[User:MrC|MrC]] who built [[Expression_Language_Archive|the amazing and long-lived previous version of this page]], upon which this is still heavily based.
|- id="FileFolder" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>filefolder(</b><i>filepath</i><b>, </b><i>level</i><b>)</b></span>
 
The [[#FileFolder|FileFolder()]] function returns parent sub-folder name for <i>filepath</i>.
 
The <i>level</i> argument specifies which parent sub-folder name to return,
 
working the <i>filepath</i> from right-to-left (i.e. bottom of the folder tree upwards to the top).
 
A value of 0 specifies a file's immediate parent, 1 its grandparent, etc., up to the root of the <i>filepath</i>.
 
A value of <span style="font-family: Consolas, monospace;">Unassigned</span> will be returned when the specified <i>level</i> exceeds the root of the <i>filepath</i>.
 
  
Argument <i>filepath</i> is optional (defaults to [filename]).
+
The current caretaker of this documentation is forever in their debts.
  
Argument <i>level</i> is optional (defaults to 0).
+
[[Category:Frequently Asked Questions]]
 
+
[[Category:Developer]]
|- valign="top"
+
[[Category:Expression Language]]
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>filefolder()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the name of the file's parent folder.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filefolder([filename,0], 0)</nowiki></b></span>
 
<p style="margin-left:20pt;">Same as the previous example.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filefolder(c:\some\folder\for\a\file.ape, 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the great grandparent sub-folder named <span style="font-family: Consolas, monospace;">folder</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filefolder(c:\some\other\folder\a\, 2)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the folder named <span style="font-family: Consolas, monospace;">other</span>.
 
Notice the file name is not required in the <i>filepath</i>.
 
[[#FileFolder|FileFolder()]] works by looking from the end of the <i>filepath</i> until it finds a backslash <span style="font-family: Consolas, monospace;">\</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FileKey()(&hellip;): Returns a file's unique internal identifier====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FileKey" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>filekey()(</b><b>)</b></span>
 
The [[#FileKey|FileKey()()]] function returns the unique identifier associated with a file.
 
Media Center assigns a unique identifier to each file in the Library.
 
It is useful in expressions when referring to individual files is necessary.
 
Services such as MCWS use this value to reference a file.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>filekey()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns a integer value, such as <span style="font-family: Consolas, monospace;">22029495</span>, unique for each file in the Library.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FileName(&hellip;): Returns a file's name component====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FileName" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>filename(</b><i>filepath</i><b>, </b><i>include suffix</i><b>)</b></span>
 
This function returns the file name part of <i>filepath</i>. Inclusion of the file's suffix depends on the <i>include suffix</i> argument.
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>0</b></td><td>Suppress file suffix</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>1</b></td><td>Include file suffix</td></tr>
 
</table></div>
 
 
 
Argument <i>filepath</i> is optional (defaults to [filename]).
 
 
 
Argument <i>include suffix</i> is optional (defaults to 1).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>filename(C:\Music\File.mp3)</nowiki></b></span>
 
<p style="margin-left:20pt;">The output is <span style="font-family: Consolas, monospace;">File.mp3</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filename(C:\Music\File 2.wav, 0)</nowiki></b></span>
 
<p style="margin-left:20pt;">The output does not include the file suffix, and is <span style="font-family: Consolas, monospace;">File 2</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filename()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the value contained in the field [filename (name)].</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FilePath(&hellip;): Returns a file's path component====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FilePath" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>filepath(</b><i>filepath</i><b>)</b></span>
 
This function will return the path portion of the specified file path.
 
 
 
The <i>filepath</i> should be a rooted path.  For Windows, this includes the drive letter or leading <span style="font-family: Consolas, monospace;">\\</span> for UNC paths.
 
For *nix-based systems, this includes the root <span style="font-family: Consolas, monospace;">/</span>.
 
The field [filename (path)] is equivalent to [[#FilePath|FilePath()]], and is generally preferred.
 
 
 
Argument <i>filepath</i> is optional (defaults to [filename]).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>filepath(C:\Music\File.mp3)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns <span style="font-family: Consolas, monospace;">C:\Music</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filepath()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the value contained in the field [filename (path)].</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====FileVolume(&hellip;): Returns a file's volume name component====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="FileVolume" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>filevolume(</b><i>filepath</i><b>)</b></span>
 
The [[#FileVolume|FileVolume()]] function returns the volume name component of the specified file path.
 
The path should be a rooted path (see the same comment above for [[#FilePath|FilePath()]].  For *nix-based systems, the output is empty.
 
The field [volume name] is equivalent to [[#FileVolume|FileVolume()]], and is generally preferred.
 
 
 
Argument <i>filepath</i> is optional (defaults to [filename]).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>filevolume(C:\Music\File.mp3)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs <span style="font-family: Consolas, monospace;">C:</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>filevolume()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the value contained in the field [volume name].</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
===Miscellaneous Functions===
 
 
 
The functions in this section are varied and have specialized applicability.
 
Some are primarily used internally by MC to generate values available in various Library fields.
 
====AlbumArtist(&hellip;): Returns a file's calculated album artist====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="AlbumArtist" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>albumartist(</b><b>)</b></span>
 
This function calculates the album artist value used in various views and fields.
 
It is used to populate the Library field <span style="font-family: Consolas, monospace;">album artist (auto)</span> with its value.
 
Either the field or [[#AlbumArtist|AlbumArtist()]] can be used.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>albumartist()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the value present in the <span style="font-family: Consolas, monospace;">album artist (auto)</span> field.</p>
 
 
 
Additional Examples
 
 
 
:[http://wiki.jriver.com/index.php/Album_Artist_and_Album_Artist_%28Auto%29 Describes the algorithm used by AlbumArtist() to calculate the "album artist (auto)" field's value.]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====AlbumKey(&hellip;): Returns a unique album key for a file====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="AlbumKey" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>albumkey(</b><b>)</b></span>
 
The [[#AlbumKey|AlbumKey()]] function returns "[album artist (auto)] - [album]".
 
It is a convenience function, used to return the generally unique album / artist combination string used to distinguish
 
between two like-named albums such as "Greatest Hits".
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>albumkey()</nowiki></b></span>
 
<p style="margin-left:20pt;">For an album named <span style="font-family: Consolas, monospace;">Greatest Hits</span> and an album artist (auto) of <span style="font-family: Consolas, monospace;">The Eagles</span>, returns <span style="font-family: Consolas, monospace;">The Eagles - Greatest Hits</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====AlbumType(&hellip;): Returns the album type for a file====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="AlbumType" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>albumtype(</b><b>)</b></span>
 
The [[#AlbumType|AlbumType()]] function returns a description regarding an album's completeness and its quantity of artists.
 
It is used to populate the Library field <span style="font-family: Consolas, monospace;">album type</span> with its value.
 
Either the field or [[#AlbumType|AlbumType()]] can be used.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>albumtype()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns, for example, <span style="font-family: Consolas, monospace;">Single artist (complete)</span>, or <span style="font-family: Consolas, monospace;">Multiple artists (incomplete)</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Counter(&hellip;): Counts upwards in specified increments====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Counter" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>counter(</b><i>start value</i><b>, </b><i>increment</i><b>)</b></span>
 
The [[#Counter|Counter()]] function outputs a monotonically increasing number (more simply stated, it counts) from a <i>start value</i>,
 
and each time called, increases by the <i>increment</i> value.
 
It is useful for sequentially numbering fields.
 
The [[#Counter|Counter()]] function maintains an internal counter, and it resets itself to zero after five seconds of inactivity.
 
 
 
Because [[#Counter|Counter()]] continues to count, it should only be used in single-use situations such as assigning its output to some field through field value assignment, for example, <span style="font-family: Consolas, monospace;">=counter()</span>.
 
With proper care, it can be used as part of an expression in the Rename, Move & Copy tool, but see also [[#CustomData|CustomData()]].
 
 
 
It is not recommended for use in any context that continually refreshes its content, such as in a panes column, file list, or expression-based custom query.
 
Probably the best way to understand the results is to test the first example below as an expression column in a file list, and move the mouse around over that column.
 
 
 
Argument <i>start value</i> is optional (defaults to 1).
 
 
 
Argument <i>increment</i> is optional (defaults to 1).
 
 
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>counter()</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs values starting at <span style="font-family: Consolas, monospace;">1</span>, and incrementing by one, it will return <span style="font-family: Consolas, monospace;">1</span>, <span style="font-family: Consolas, monospace;">2</span>, <span style="font-family: Consolas, monospace;">3</span>, ... until no longer called.
 
This might be used, for example, to assign to the [Track #] field of several tracks using the field assignment expression <span style="font-family: Consolas, monospace;">=counter()</span>.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>padnumber(counter(370, 2), 4)</nowiki></b></span>
 
<p style="margin-left:20pt;">Outputs numbers beginning from 370, incremented by two each, and padded to four digits.  For example, <span style="font-family: Consolas, monospace;">0370</span>, <span style="font-family: Consolas, monospace;">0372</span>, <span style="font-family: Consolas, monospace;">0374</span>, etc.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====CustomData(&hellip;): Returns internal data to the expression language====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="CustomData" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>customdata(</b><i>mode</i><b>)</b></span>
 
The [[#CustomData|CustomData()]] function supports returning Media Center internal data to the expression language.
 
Currently there is only one supported use, which is to use [[#CustomData|CustomData()]] in the Rename, Move & Copy tool to assist in numbering files.
 
 
 
Available <i>mode</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>#</b></td><td>Returns a file's row number in the Rename, Move & Copy tool</td></tr>
 
</table></div>
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>Spring_Break_Bash_padnumber(customdata(#), 4)</nowiki></b></span>
 
<p style="margin-left:20pt;">In the Rename, Move & Copy tool, each consecutive file would be named <span style="font-family: Consolas, monospace;">Spring_Break_Bash_</span> followed by a four digit, zero-padded number starting at <span style="font-family: Consolas, monospace;">0001</span>.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Math(&hellip;): Evaluates a given mathematical formula====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Math" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>math(</b><i>expression</i><b>)</b></span>
 
The [[#Math|Math()]] function performs mathematical calculations.
 
Standard arithmetic operators are supported, as are various numerical, trigonometric, and comparative functions.
 
Simple variables are supported, as are multiple statements.
 
 
 
<blockquote>
 
{| style="background: #f9f9f9;" border="1" cellpadding="1" cellspacing="0"
 
| rowspan="6" width="100" valign="top" | '''Arithmetic Operators'''
 
| align="center" width="65" | + || Addition
 
|-
 
| align="center" | - || Subtraction
 
|-
 
| align="center" | * || Multiplication
 
|-
 
| align="center" | / || Division
 
|-
 
| align="center" | ^ || Power
 
|-
 
| align="center" | % || Modulo
 
|-
 
| rowspan="3" | '''Boolean Operators'''
 
| align="center" | ! || NOT
 
|-
 
| align="center" | & || AND
 
|-
 
| align="center" | <nowiki>|</nowiki> || OR
 
|-
 
| rowspan="1" | '''Grouping Operators'''
 
| align="center" | ( ) || Precedence grouping
 
|-
 
| rowspan="4" | '''Comparison Operators'''
 
| align="center" | } || Absolute value maximum (i.e. x or y that is maximum distance from 0).
 
|-
 
| align="center" | { || Absolute value minimum (i.e. x or y that is minimum distance from 0).
 
|-
 
| align="center" |  > || Distance between x and y, positive when x greater than y, negative otherwise.
 
|-
 
| align="center" | < || Distance between x and y, positive when x less than y, negative otherwise.
 
|-
 
| rowspan="7" | '''Functions'''
 
| align="center" | abs(x) || Returns the absolute value of x.
 
|-
 
| align="center" | sign(x) || Returns the sign of x (1 when x >= 0, -1 when x < 0).
 
|-
 
| align="center" | log(x) || Returns the natural logarithm (base e) of x.
 
|-
 
| align="center" | log10(x) || Returns the common logarithm (base 10) of x.
 
|-
 
| align="center" | pow(x,y) || Returns x raised to the y-th power.
 
|-
 
| align="center" | rand(x) || Returns a random value ranging between 0 to x.
 
|-
 
| align="center" | randn(x) || Returns a random value ranging between -x and x.
 
|-
 
| rowspan="5" | '''Comparison Functions'''
 
| align="center" | min(x,y) || Returns the minimum value of x and y.
 
|-
 
| align="center" | max(x,y) || Returns the maximum value of x and y.
 
|-
 
| align="center" | equal(x,y) || Returns 1 when x = y, 0 otherwise.
 
|-
 
| align="center" | below(x,y) || Returns 1 when x < y, 0 otherwise.
 
|-
 
| align="center" | above(x,y) || Returns 1 when x > y, 0 otherwise.
 
|-
 
| rowspan="4" | '''Formatting Functions'''
 
| align="center" | int(x) || Returns the integer portion of x.
 
|-
 
| align="center" | frac(x) || Returns the fractional portion of x.
 
|-
 
| align="center" | round(x) || Returns x rounded to the nearest whole number.
 
|-
 
| align="center" | trunc(x,n) || Returns x truncated to n decimal places.
 
|-
 
| rowspan="6" | '''Trigonometric Functions'''
 
| align="center" | atan(x) || Returns the arctangent of x.
 
|-
 
| align="center" | cos(x) || Returns the cosine of x.
 
|-
 
| align="center" | sin(x) || Returns the sine of x.
 
|-
 
| align="center" | tan(x) || Returns the tangent of x.
 
|-
 
| align="center" | abscos(x) || Returns the absolute value of cosine(x).
 
|-
 
| align="center" | abssin(x) || Returns the absolute value of sin(x).
 
|}
 
</blockquote>
 
 
 
The order of operator precedence is summarized as follows, from top to bottom:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>(&nbsp;&nbsp;&nbsp;)</b></td><td>&nbsp;</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>&nbsp;&nbsp;!</b></td><td>&nbsp;</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>&nbsp;&nbsp;^</b></td><td>&nbsp;</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>*&nbsp;&nbsp;&nbsp;/</b></td><td>Left to right</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>+&nbsp;&nbsp;&nbsp;-</b></td><td>Left to right</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b><nowiki>|</nowiki>&nbsp;&nbsp;&nbsp;&amp;</b></td><td>Left to right</td></tr>
 
</table></div>
 
 
 
Variables may be assigned and used by specifying a simple string of letters. Examples: <span style="font-family: Consolas, monospace;">math(val=2)</span> or <span style="font-family: Consolas, monospace;">math(x=pow(2,3))</span>.
 
 
 
Multiple equations may be specified, each separated by a semicolon.
 
Expressions are evaluated left to right.
 
The final value of the [[#Math|Math()]] function will be the result of the right-most equation. For example, the equation <span style="font-family: Consolas, monospace;">math(x=4; pow(2^x))</span> will output 16.
 
 
 
<b>Note</b>: Empty fields
 
 
 
Fields used inside of [[#Math|Math()]] are expanded (interpolated) directly.
 
Fields with empty values may produce incomplete [[#Math|Math()]] statements.
 
For example, if the field [number plays] is empty, an <i>expression</i> such as <span style="font-family: Consolas, monospace;">math([number plays] + 2)</span> would be seen
 
by [[#Math|Math()]] as <span style="font-family: Consolas, monospace;"> + 2</span>.
 
This incomplete <i>expression</i> would produce a syntax error.  See the Additional Examples for more information.
 
 
 
<b>Note</b>: Locales and Commas
 
 
 
Special care must be taken with the [[#Math|Math()]] function and locales that use <span style="font-family: Consolas, monospace;">,</span> (comma) as a decimal separator.
 
Many Media Center fields and the return values from functions may contain comma as the decimal point.
 
Your expressions will need to [[#Replace|Replace()]] these before passing the values to [[#Math|Math()]],
 
which always uses dot <span style="font-family: Consolas, monospace;">.</span> as the numeric decimal point.
 
 
 
For example, the <i>expression</i> <span style="font-family: Consolas, monospace;">math(1,5 + 1,5)</span> will fail since [[#Math|Math()]] does not consider <span style="font-family: Consolas, monospace;">1,5</span> to be a valid number.
 
 
 
Fields that cause problems are any fields that produce floating-point values, such as any Date type field in raw format
 
(e.g. <span style="font-family: Consolas, monospace;">[date,0]</span>, <span style="font-family: Consolas, monospace;">[last played,0]</span>, <span style="font-family: Consolas, monospace;">[date modified,0]</span>, and <span style="font-family: Consolas, monospace;">[date imported,0]</span>), or any textual field that contains
 
floating-point values that will be used for various calculations (e.g. any of the Dynamic Range variants).
 
Certain functions such as [[#Now|Now()]] and [[#ConvertTime|ConvertTime()]] also return localized floating-point values.
 
 
 
Handling this problem is not difficult.
 
Before passing any floating point number to [[#Math|Math()]], use [[#Replace|Replace()]] first.  See the examples below.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>math(10 + 4)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns 14.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>math(10 + 2 * 25)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns 60, demonstrating that multiplication has higher precedence than addition.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>math((10 + 2) * 25)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns 300, demonstrating that parenthesis grouping has higher precedence than multiplication.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>math(replace(now(), /,, .) - replace([last played,0], /,, .))</nowiki></b></span>
 
<p style="margin-left:20pt;">The <span style="font-family: Consolas, monospace;">,</span> is replaced by a <span style="font-family: Consolas, monospace;">.</span> in the output of both [[#Now|Now()]] and in the raw field value <span style="font-family: Consolas, monospace;">[last played,0]</span>.
 
Note that the comma must be escaped so that it is seen as an argument and not as an argument separator.</p>
 
<span style="font-family: Consolas, monospace;"><b><nowiki>math(replace(now() - [last layed,0], /,, .))</nowiki></b></span>
 
<p style="margin-left:20pt;">The same as the previous example, but is more efficient and simpler since it calls [[#Replace|Replace()]] just once on the entire string to be passed to [[#Math|Math()]].</p>
 
 
 
Additional Examples
 
 
 
:[http://yabb.jriver.com/interact/index.php?topic=58110.0 An explanation and some solutions for fields that evaluate to empty within Math().]
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====Size(&hellip;): Returns a file's size in a format specific to the media type====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="Size" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>size(</b><b>)</b></span>
 
The [[#Size|Size()]] function returns media size information specific to the particular media type.
 
It is used to populate the Library fields <span style="font-family: Consolas, monospace;">duration</span> and <span style="font-family: Consolas, monospace;">dimensions</span> with their values.
 
Either the field or [[#Size|Size()]] can be used.
 
 
 
Type of information reported by size for the file's media type:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt">Audio</td><td>Duration</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Video</td><td>Duration</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Image</td><td>Dimensions</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt">Data</td><td>No information returned.</td></tr>
 
</table></div>
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>size()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns values such as <span style="font-family: Consolas, monospace;">400x225</span> for images, or <span style="font-family: Consolas, monospace;">3:09</span> for audio files.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====TrackNumber(&hellip;): Returns a file's track # value====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="TrackNumber" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>tracknumber(</b><b>)</b></span>
 
The [[#TrackNumber|TrackNumber()]] function returns a file's track #, or 0 if the no value exists.
 
It is used to populate the Library field <span style="font-family: Consolas, monospace;">track #</span> with its value.
 
Either the field or [[#TrackNumber|TrackNumber()]] can be used.
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>tracknumber()</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns the value present in the <span style="font-family: Consolas, monospace;">track #</span> field.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 
 
 
====TVInfo(&hellip;): Miscellaneous television and other pre-formatted information====
 
 
 
{| style="width: 100%; border: 2px solid black;" align="top" cellpadding="3"
 
|- id="TVInfo" valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " width=100 | Description
 
| style="background: #f9f9f9; color: #111; " width=1200 | <span style="font-family: Consolas, monospace; color:#0f3f8d; font-size:110%"><b>tvinfo(</b><i>type</i><b>)</b></span>
 
The [[#TVInfo|TVInfo()]] function is multi-purpose, and returns a specific <i>type</i> of information about television recordings, programs,
 
and pre-formatted informational strings for use in captions, thumbnails, grouping, etc.
 
 
 
Available <i>type</i> values:
 
 
 
<div style="margin-left: 20pt;"><table style="border-spacing:0px; border-collapse:collapse; background: #f9f9f9">
 
<tr><td style="text-align:left; padding-right:20pt"><b>IsProgram</b></td><td>Returns 1 if the file is a program, 0 otherwise</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>IsGuideProgram</b></td><td>Returns 1 if the file is a guide program, 0 otherwise</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>IsRecordedProgram</b></td><td>Returns 1 if the file is a recorded program, 0 otherwise</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>Channel</b></td><td>Returns Returns the channel name, given a channel number</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>ChannelKeywords</b></td><td>Returns channel keywords</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>Date</b></td><td>Returns a program's date</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>DateNoTime</b></td><td>Same as Date, but without the time.</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>NameDisplay</b></td><td>Returns [name]: [series] or just [name]</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>NameDisplayWithDate</b></td><td>NameDisplay + ([year])</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>Record</b></td><td>Returns 1 if the program is scheduled to be recorded, 0 otherwise</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>RecordMark</b></td><td>Returns a red dot if the program is schedule to be recorded.</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>SeriesDisplay</b></td><td>Returns [series] or [name]</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>SeasonDisplay</b></td><td>Returns [season]</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>SeasonEpisode</b></td><td>Returns [season].[episode]</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>TimeDisplay</b></td><td>Returns program start time (system time format), or "Showing" if program on now</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>TimeDisplayNoOnNow</b></td><td>TimeDisplay without on now handling</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>SizeDisplay</b></td><td>Returns [duration] ([file size]) or [dimensions] ([file size])</td></tr>
 
<tr><td style="text-align:left; padding-right:20pt"><b>WatchedDisplay</b></td><td>Returns Watched() information, such as No, Yes, 80%, etc.</td></tr>
 
</table></div>
 
|- valign="top"
 
! scope="row" style="background: #ecedf3; color: #111; " | Examples
 
|style="background: #f9f9f9; color: #111; " | <span style="font-family: Consolas, monospace;"><b><nowiki>tvinfo(namedisplay)</nowiki></b></span>
 
<p style="margin-left:20pt;">Returns formatted name and series output.  If the file has no <span style="font-family: Consolas, monospace;">[series]</span> value, only <span style="font-family: Consolas, monospace;">[name]</span> is output.</p>
 
|}
 
<div style="text-align:right;">([[#top|Back to top)]]</div>
 

Latest revision as of 05:24, 23 March 2024

Media Center provides a simple programming language that enhances and enriches its overall user interface and usability. This language, commonly called the expression language, is simple to learn, simple to use, and can greatly enhance your experience using Media Center.

Expressions are ubiquitous throughout Media Center, used in areas such as:

  • The categories in a view
  • File list expression columns
  • Theater View
  • Customized view headers, grouping and sort criteria
  • The library field manager (fields with data type Calculated data)
  • File and folder location definitions
  • Auto-import rules
  • Custom DLNA titles
  • The player's display
  • Captions and thumbnail text
  • The link manager (expressions help format link URLs)
  • Rename, Move, & Copy tool
  • Tag assignment
  • Complex search queries

An expression is a mixture of ordinary text, pre-defined functions, and a few reserved characters and constructs that have special meaning. An expression is evaluated by Media Center's expression engine and textual output is produced. This output is then used by Media Center to customize the user interface and affect its method of operation.

The Anatomy of an Expression

As mentioned above, an expression is a mixture of text and function calls (and some reserved stuff described shortly). The simplest expression would be some basic, literal text, such as A good movie. The expression engine evaluates this expression, finds nothing special, and then outputs the result: A good movie. Simple.

But simple text only has so much utility. The ability to transform or generate content is much more interesting and useful. And this is when functions are employed. Media Center provides many functions, which when called, produce some output. Most functions require some form of input, called arguments, and most functions generate output. By supplying a function with various arguments, the function will return some output value which is just more text. And this output text can be the used by other functions, and so on. Each function has a unique name, and calling upon a function to do some work requires little more that using its name anywhere in the expression.

A function call looks like this:

functionname(argument 1, argument 2, ...)

The syntax of the function call is the function's case-insensitive name, immediately followed by an opening parenthesis character, one or more comma-separated arguments, and a closing parenthesis character. Whitespace after the commas is optional, but helps readability and formatting. And each argument itself is also just an expression. And some arguments are optional. If an argument is optional, it can be omitted and its default value will be used. If the argument is omitted, a comma-separator will still be required if additional arguments follow. The following example uses the FixCase() function to change its input to Title Case:

fixcase(A good movie)

The result is A Good Movie.

A slightly more complex expression example consists of both text and a nested function call:

Wow! fixcase(replace(A good movie, good, great))

Inner functions are called before outer functions, so the Replace() function is call first:

replace(A good movie, good, great)

and its output is then supplied as the input to the FixCase() function. Replace() does its work substituting good with great, and returns A great movie. This output is then supplied as the argument to FixCase() which sees only the text A great movie (it knows nothing about how it was produced). So the function call:

fixcase(A great movie)

in turn outputs A Great Movie. Now that the functions have produced their output, the final output, including the literal Wow! leading text is

Wow! A Great Movie

Fields

The expression examples thus far have been limited to static literal text. Expressions have much more utility when they use data from other sources, such as a file's metadata. Media Center maintains this metadata in its defined fields. This data is accessed using the Field() function, and its first argument is the case-insensitive name of the field to be accessed. For example, the function call field(album) will return the current* file's value for the album field (* more will be said later about the current file). If the album field contained the value After Hours, the expression:

fixcase(field(album), 3)

would produce AFTER HOURS. First field(album) is evaluated, returning After Hours. The FixCase() function is supplied with this output as its first argument, and its second argument is 3, which happens to specify that it should perform upper-casing.

Because fields are so frequently used in expressions, an abbreviated form called square bracket notation exists for accessing their values. This makes it easier to both read and write expressions. Nonetheless, both forms are equivalent. The abbreviated form is simple: immediately surround the field's name with opening and closing square brackets, for example, [album]. The previous example is now written more simply as:

fixcase([album], 3)

Field Values

For the sake of simplicity and clarity, the section above glossed over an important detail regarding how Media Center outputs field values. Recall that Field() is the function used to return the value of a specified field. But Field() also has a second argument that indicates the format of the value that it returns. Because field values are used in a variety of situations, the Field() function can produce output suitably formatted for the requirements. There are two forms of output: one is a nice, friendly human-readable format suitable for use in views or other display locations; the other is a raw format which returns the representation stored internally by Media Center which is useful when uninterpreted values are necessary.

By default, Media Center always outputs the friendly format, so expressions sometimes need to take this into account and chose the format accordingly.

Not used earlier because it is optional, the second argument to the Field() function selects the mode of output: the value 0 selects the raw mode, and the default value of 1 selects the friendly mode. Here are two examples using the date field, the first one outputs the date value in raw format, the second in the friendly format:

field(date, 0)
field(date, 1)

Field Values: Override the expression, and [This]

ExpressionOverride.png

When creating (or editing) an expression based field, there is an option, shown in the image on the right, to "Allow custom data to override the expression". When enabled, it becomes possible to open the tag for editing either inline or in the tag window, just as you would any other regular tag, and replace the expression derived data with any other static data. Complex expression based fields can very easily slow view loading times to a crawl, and in many cases, this option can help speed things up again. Imagine an expression based field that manipulates another, otherwise static field, such the [Date] field. The returned expression values will never change, so why waste time evaluating the same results over and over, when you can simply replace them with static data and so forego any future expression processing?

Media Center 28 saw the introduction of a [This] variable that can also be invoked, so, using the example, =removeleft([This], 4) would remove four characters from the left of "this field".

The new [This] variable can be used to override expression data. Select one, or 1000s of files, then edit, either inline or in the tag window, using the simple expression =[this] and apply to have MC replace the expression result with, the expression result, which from that point forwards, will be static data and the expression will no longer run for those files.

To remove the static data and return to expression evaluated data instead, simply edit again, deleting the static data, which when applied, will cause the expression evaluated result to return.

Note: Use this "override" option with care. It requires least maintenance when used in situations where all expression values for all files for that field will be replaced with static data. Currently (October 2022) there is no way to differentiate between static data and expression derived data meaning the potential for things to get very confusing, very quickly, is very high indeed.

Note 2: MC32 comes with the addition of the IsOverridden(...) function that now allows us to filter any given expression based field based on its override status.

Field Values: Empty, 0, and 1

The Media Center expression language does not strongly differentiate between the numeric value zero 0 and emptiness for numeric field types Integer and Decimal. And in some cases, the numeric value of 1 is treated similarly to the empty value.

When a value of 0 is entered as a numeric field's value, the raw value will be shown as 0, but the display format (as in the file list) will be shown as empty. The empty display allows for less visual noise in the user interface, since a column full of 0 values is not usually helpful. In fact, if you attempt to set a numeric field's value to 0 in the file list, it will immediately be displayed as empty.

Generally this difference is unimportant, except when testing numeric values with IsEmpty() or IsEqual(). It is easy to be fooled when testing such a value if the value shown in a file list is empty. The values shown in the Tag Action Window will reveal the actual raw value, as will an expression column using the field's raw format.

Another consideration for integer fields is that when sorting, a 1 value can sometimes sort indistinguishably from an empty value. The Integer type disc # field is typically empty when an album consists of only one disc, and as such, Media Center will sort the disc # values of empty (0) and 1 identically.

The friendly output of a field can differ, depending on context. For example, in a file list, and empty field will be shown as blank, but in the Rename, Move & Copy tool, it will be output as Unknown Disc # (this ensures no blank values are generated as path components). To test such a field, always use and test against the raw format, and then expressions will be context agnostic.

Field Assignment

The output of an expression can be used to assign a value to a tag. This is accomplished by preceding the expression with an = character. The = character causes the tagging engine to invoke the expression evaluator first, and then to use its output as the value to assign to the field.

Field Assignment with Expression.png

Without the prepended = character, the literal expression text itself and not its evaluated value would be stored in the tag. The expression can refer to the field's own value to modify itself, and this offers a convenient way to perform complex transformations on field values. For example, the assignment expression

=removeleft([name], 4)

entered into an edit cell for the name field would remove four characters from the left of the name field's current value. An assignment expression can be entered into the Tag Action Window, or by using inline editing in the file list or a pane entry. The image on the right shows in-place field assignment.

Note: Undo is supported, reverting each tag to its value prior to the assignment. Redo is also supported, reapplying the most recent Undo.

Expression Language Syntax

Now that the basics have been covered, the more rigorous rules of the expression language syntax can be described.

  • An expression is any sequence of literal text and any number of function calls.
  • Expressions are read and evaluated left to right. Literal text is output unmodified, function calls are evaluated and their return values output.
  • Fields designated using square bracket notation are expanded into the equivalent Field() function call.
  • Nested function calls are evaluated from the innermost function to outermost function, and again, left to right when one function follows another.
  • A function is evaluated and its returned value contextually replaces the function call in the expression
  • Within a function's argument list, whitespace is ignored before and after commas, after an opening parenthesis, and before a closing parenthesis.
  • The forward-slash escape character / disables the special meaning of the character that follows it.
  • The escape sequence /# followed by #/ escapes everything inside.
  • The escape sequence /* followed by /* will escape everything inside returning it as given without formatting or processing.
  • To use a literal parenthesis, comma, or whitespace inside of function argument lists, escape them. Whitespace within an argument's value is literal and does not need to be escaped when it is surrounded by other non-whitespace text.
  • An expression may be split into multiple lines, but when it does not satisfy the conditions above regarding whitespace around function parenthesis and commas, use a forward-slash escape as the last character before the newline. Extraneous newlines in the expression editor will produce a trailing ellipsis (...) in the output.

How Expressions Are Evaluated

Expressions are evaluated in the context where they are used. For example, an expression column in a file list is evaluated relative to those files in the file list. And the general flow is that for each file in the list, the expression is evaluated and produces output. The expression only has access to the fields available for the file currently being evaluated. This is important to remember, so it bears repeating. One file after another, an expression is evaluated against that single file, its output is produced and stored away for use later, and then the result of that evaluation is entirely forgotten before the next file is evaluated. This means, the expression evaluator cannot use the results from one file's evaluated expression with the results of another file's evaluation.

Expressions and Locales

Media Center will respect the Windows locale setting for output values produced by certain functions, and within the values of certain fields. This is important to consider when writing expressions that consume such values. Under most circumstances, such values cause no harm. However special care must be taken with functions that require the use of period as the decimal point. One such function is Math(), which always uses period as the decimal point. If your locale uses some other character such as comma, these characters will have to be converted into periods before the critical function is called. Handling this problem is not difficult. Before passing to Math() any floating point number, use Replace() first when necessary to convert the locale's decimal character into a period. Fields that cause problems are any fields that produce floating-point values, such as any Date type field in raw format (e.g. [date,0], [last played,0], [date modified,0], and [date imported,0]), or any textual field that contains floating-point values that will be used for various calculations (e.g. any of the Dynamic Range variants). Certain functions such as Now() and ConvertTime() also return localized floating-point values. Consider also that the expression parser uses comma as the argument separator. Any literal numeric values specified as a function argument must have any embedded commas escaped.

A Complex Expression Example

Expression Editor.png

Here is a more complex expression example that illustrates the various rules discussed above regarding expressions:

if( IsEmpty( [Disc #] ),
Disc number is empty,
Delimit(
field(disc #) ,
/) ,
DISC /(
)
)

The expression demonstrates that

  • whitespace before and after commas or opening and closing parenthesis is ignored
  • expressions can be safely split into multiple lines using the whitespace rules just mentioned
  • function and field names are case insensitive
  • forward slash is used and required to escape parenthesis (see inside the Delimit() function)
  • whitespace does not require escapement when surrounded by other characters (see after the C in DISC)
  • literal text is output unmodified (Disc number is empty)
  • functions can be nested (Both IsEmpty() and Delimit() are nested within the If() function, and the Field() function is nested within Delimit()

When the expression is run, files that have no disc number will produce Disc number is empty, and files that have, say, a disc number value of 3 will produce DISC (3).

Functions

Functions enable you to transform or generate content automatically. For background information on how functions are used in expressions, refer to The Anatomy of an Expression section above.

This section describes all the various functions provided by Media Center's Expression Language.

Function Arguments

As discussed above, a function call consists of the function's case-insensitive name, immediately followed by an opening parenthesis character, one or more comma-separated arguments, and a closing parenthesis character:

functionname(argument 1, argument 2, ...)

Functions may have one or more arguments. In some cases, these arguments are optional, and will automatically use a default value if omitted. For example, these two expressions are equivalent because the mode argument for IsEmpty() is optional and defaults to 0:

isempty([comment], 0)
isempty([comment])

In this case, a comma-separator will still be required if additional arguments follow the optional one. Whitespace after the commas is also optional, but helps readability and formatting. However, if any extra arguments are included in a function call which are not valid for that function, they are dropped and omitted from output. This is of particular importance when using string-manipulation functions on text. If the text you enter contains any commas, these must be escaped or the expression engine will consider text after the comma to be additional arguments.

The arguments themselves are also just expressions, and you can nest multiple functions to achieve complex logic:

if(isequal([artist], [album], 1), Eponymous, [album])

Nested function calls are always treated as a single argument when used as the input to another function (so that commas in the output of one function do not need to be escaped to be used as input in another function). This includes fields, since they are expanded to the equivalent Field() function call.

Please Note: In some cases below, such as with Unswap(), we have ignored this detail in order to simplify the examples. If you enter any text manually into a function, all commas must be escaped in order to achieve the correct result. This detail is unimportant in most real-world usages, however, because you will typically use either field values or the output of other functions as the arguments in your expressions. However, if you need to include commas in a string literal argument to a function, you need to escape every one, or block escape the entire argument.

Function Index

Unfortunately, when these were actually introduced has not been tracked. The only way to be certain you have access to all of the functions below is to make sure you have the most current build of Media Center installed.
The available functions are grouped below based on the type of operation they might perform. If you prefer, a flat, alphabetically sorted function list is available here.
Over time, as Media Center evolves, expression functions are added or changed. Those changes are typically not reflected here immediately. In the list available here, on interact, any entries in red text are currently missing from these wiki pages.

Accessing and Storing Functions

Conditional Functions

  • And(…): Tests a set of values and returns 1 if all are true.
  • FirstNotEmpty(…): Returns the first non-empty argument.
  • If(…): Conditional ifelse evaluator.
  • IfCase(…): Functions as a switch or select case statement.
  • IfElse(…): Conditional if-elseif evaluator.
  • Not(…): Negates the results of funtions.
  • Or(…): Tests a set of values and returns 1 if any are true.

Date and Time Functions

  • CompareDates(…): Compares two dates, returning a formatted elapsed period between them
  • ConvertDate(…): Converts a human-readable date to the internal format required for use in date fields
  • DateInRange(…): Compares a date with a range of dates
  • FormatDate(…): Formats a date value in a specified manner
  • Now(…): Retrieve and display the system date
  • PlaylistTime(…): Returns the time of a track in the current playlist (a sum of all previous durations)

File Path and Identifier Functions

Formatting Functions

Grouping Functions

  • GroupCount(…): Counts the members of a specified group (in a category or field).
  • GroupCountQuery(…): Globally counts the number of items in a specified group.
  • GroupSummary(…): Smartly summarizes the members of a specified group (mode, mean, min, max, etc as is most logical for that grouping).
  • GroupSummaryQuery(…): Get a summary for the current group of files based on another matching field.

List Manipulation Functions

Miscellaneous Functions

  • AlbumArtist(…): Returns a file's calculated album artist
  • AlbumKey(…): Returns a unique album key for a file
  • AlbumType(…): Returns the album type for a file
  • AudioAnalysisState(…): Returns the state of audio analysis for a file
  • Char(…): Returns a character from the numeric code of that character
  • CustomData(…): Returns internal data to the expression language
  • FileExtension(…): Returns the extension of the referenced file
  • FilePlaylists(…): Returns a list of playlists a file belongs to (Can also be used to search)
  • Literal(…): Returns a string as given without any formatting or processing
  • Repeat(…): Returns any given string repeated the specified number of times
  • Row(…): Returns the row number of a list entry
  • Size(…): Returns a file's size in a format specific to the media type
  • Translate(…): Converts an English string found in the program to the current language selected in the language menu
  • TreeNode(…): Returns the selected tree path
  • TVInfo(…): Miscellaneous television and other pre-formatted information

Number Functions

  • Avg(…): Returns the average from a set of numbers
  • Counter(…): Counts upwards in specified increments
  • Math(…): Evaluates a given mathematical formula
  • Max(…): Returns the largest value from a set of numbers
  • Min(…): Returns the smallest value from a set of numbers
  • Number(…): Returns the first number , including decimals, from a given string
  • Rand(…): Returns a random number anywhere between two given numbers
  • Range(…): Creates a semi-colon delimited list of numbers in a field
  • Roman(…): Converts any given number to, or from, roman numerals
  • StackCount(…): Returns the number of files in a stack
  • Sum(…): Returns the sum of a set of numbers
  • TrackNumber(…): Returns a file's track # value

String Manipulation Functions

  • Clean(…): Clean a string to be used for various operations
  • Extract(…): Returns a portion of a string bounded by another substring
  • Find(…): Finds a string or character in another string, returning its zero-based position in that string
  • FixCase(…): Changes the case of a given string
  • FixSpacing(…): Intelligently splits adjacent camel-cased words
  • Hexify(…): Hexifies a string to make it suitable for web usage
  • Left(…): Retrieves a specified number of characters from the left of a string
  • Length(…): Returns the number of characters in a string
  • Letter(…): Returns the starting letter or letters of a given string
  • Mid(…): Retrieves specified characters from a string
  • MoveArticles(…): Takes "The Beatles" and reverses it to "Beatles, The"
  • NoArticles(…): Takes "The Beatles" and returns "Beatles"
  • PadLeft(…): Pad any string with any character, to the left
  • PadRight(…): Pad any string with any character, to the right
  • Regex(…): Regular expression pattern matching and capture
  • RemoveCharacters(…): Removes a list of characters from a string
  • RemoveLeft(…): Trims characters from the beginning of a string
  • RemoveRight(…): Trims characters from the end of a string
  • Replace(…): Replace or remove a string segment
  • Right(…): Retrieves a specified number of characters from the right of a string
  • Swap(…): Takes Firstname Lastname and swaps to Lastname, Firstname
  • Trim(…): Removes leading and trailing non-printable characters and new lines from a string
  • TrimLines(…): Removes leading and trailing non-printable characters and new lines from a string
  • UnMoveArticles(…): Takes "Beatles, The" and reverses it to restore the normal word order, "The Beatles"
  • Unswap(…): Takes Lastname, Firstname and reverses it to Firstname Lastname
  • Urlify(…): Takes a string and applies html formatting for browser consumption

Test and Comparison Functions

Data Types

It was mentioned already that the Media Center expression language is primarily a textual language - it consumes and produces text. Nonetheless, certain areas of Media Center are influenced by the type of data used or presented, and sometimes it is useful or necessary to coerce expression output into one data type or another. Each Media Center field is defined to be of a certain data type, listed in the Field Data Types table. These types influence how values are output, sorted, and interpreted on input. And expressions always output data of type String. By coercing the data type of an expression, output formatting and sorting can be controlled in various ways.

Data types are forced by appending to an expression the string:

&datatype=[type]

where type is one of the following values:

listA list of strings, separated by semicolons
stringSorts as strings (with smart number handling)
numberSorts values as numbers (decimal or integer)
integerSorts values as integers
pathSorts using a smart filename compare style
monthSorts string month names (i.e. January, February, etc.)

Calculated Fields and Search

Media Center's Search Language supports some simple numeric comparison operators. Because expressions always evaluate as a String type, these operators would be unavailable for use in a search query to compare numeric values from a calculated expression field. In order to use the numeric comparison operators, a calculated expression field can be cast into one of the numeric types. In your numeric calculated fields, to allow the use Search's numeric comparison operators, add either of the casts:

&datatype=[integer]
&datatype=[number]

to the end of the field's calculated expression.

Lists and Trees

Datatype List.png

The list of output in view categories and pane columns can be modified by forcing the data type to a List type. Two things happen when the data type is List: The values within a List type are split into their individual (semicolon-separated) list items The backslash character takes on a special meaning and becomes another form of separator that creates tree-like hierarchies, collapsible in panes columns and creates drill-down categories in any category view type (Standard View > Categories, Theater View, DLNA, Gizmo/WebGizmo). Forcing an expression's type to list causes this list item separation and hierarchy generation. Alternatively, forcing a List type to string defeats this. Add the cast:

&datatype=[list]

to the end of an expression to force an expression's output to be considered as a List type. Conversely, a List type may be forced into a String type by adding the cast:

&datatype=[string]

to the end of an expression.

Sort Order

Datatype Month.png

Normally strings are sorted ASCII-betically with some smart numeric sorting. But this form of sort may not always be desired.

Sorting by Month

Generally it is more useful to see month names sorting such that January sorts before April, instead of alphabetically where April would sort before January. Forcing an expression's type to Month forces string month values to be treated instead as their equivalent numerical month numbers. For example, the first month January and the third month March sort before the fourth month April. Add the cast:

&datatype=[month]

to the end of an expression to force an expression's output to be sorted by numeric month values.

Sorting by Path

Path data types sort using smart filename comparisons.

XXX: Note: This section is incomplete. I cannot distingish any difference between using a datatype of path vs. string. It seems path sort order is always engaged.

Add the cast:

&datatype=[path]

to the end of an expression to force an expression's output to be smart-sorted by path components.

Expressions and Search

The expression language is fully available to the search query engine (Search, Set rules for file display, etc.). This allows creation of more complex search queries than would otherwise be possible. An expression-based search query is any valid expression that produces a zero or non-zero numeric output. The syntax of the query is:

[=expression]=numval

where expression is any valid expression, and numval is the expected numeric output produced by the expression. The expression is evaluated against the current list of available files and the expression output numerically compared against numval. All files for which the comparison is true are returned as part of the file list produced by the query and all files that fail the comparison are winnowed from the file list.

The following example illustrates an expression-based search query:

[=ismissing([filename (path)]\Folder.jpg)]=1

The IsMissing() function is run using the file name argument [filename (path)] appended by \Folder.jpg, and returns a Boolean value 1 for files that are missing, and this 1 is compared against the value numval. All these files where there was a successful comparison are returned in the file list, and all those for which the expression produced 0 are filtered from the file list. By inverting the comparison and using a 0 numval, the set of files remaining in the file list would be those that did not match.

HTML Font Properties

The expression language recognizes a limited set of HTML font properties and attributes. These can be used to set font styles in most text drawing areas, such as captions, thumbnail text and in the configuration of Theater View. HTML tags are used by surrounding the desired content with an opening and closing tag, in the form of:

<tag>desired content<//tag>

The supported HTML tags are:

<b>Bold
<i>Italics
<u>Underline
<font>Font properties (see attributes below)

The font tag supports the following attributes:

alphaSets alpha-blending percentage (0 - 100)
colorSets the foreground color (RGB hex values from 00 to ff in the form of rrggbb)
bgcolorSets the background color (same values as color)
faceSets the font face (a font name)
sizeSets the font size (a percentage scaling value)

Any combination of HTML tags and font attributes can be used. An HTML tag must have an opening and closing tag. Nesting is allowed, but be sure to properly balance like opening and closing tags. Attribute values must be double quoted. The closing tag's forward slash requires escapement with an extra forward slash. The following examples illustrate using HTML font properties:

<i>This is in italics<//i>
<i><b>And this is bold and italic<//b><//i>
<b>The<font color="ff0000" size="80" alpha="50"> Great <//font>Gatsby<//b>

Expression Editors

There are a couple of variations of dialog or edit field used to enter expressions. Some allow multi-line expressions, while others are single line, but can be expanded to multi-line editors. Unfortunately, some single-line editors flatten multi-line expressions into a single line, replacing the newlines with spaces.

Acknowledgements

A big tip of hat to marko who tackled the enormous challenge of documenting the MC Expression Language in detail. His work was instrumental and through which has brought clarity and great assistance to Media Center users worldwide.

Also, a huge thanks to user MrC who built the amazing and long-lived previous version of this page, upon which this is still heavily based.

The current caretaker of this documentation is forever in their debts.