Expression Language: Difference between revisions

From wiki.jriver.com
Jump to navigation Jump to search
(Added ListCombine & ListItem changes made in 15.0.102)
(Page re-write complete - 07/10/10)
Line 1: Line 1:
==Using this page==
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>
==Overview==
==Overview==


The J. River Media Core database engine supports Excel-style functions for use in view schemes, searches, displayed columns, and tag editing.
The J. River Media Core database engine supports Excel-style functions for use in view schemes, searches, displayed columns, and tag editing.


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 text, fields, and functions.
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.
Examples:
This is simple text
This is an artist: [Artist]
The song [Name] is rated [Rating] stars
The file is FormatBoolean(IsMissing(), missing from, on) your machine


<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>
====Fields====
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.
<div style="text-align:right;">([[#top|Back to top)]]</div>
==When, Where and How to use expressions==
The use of expressions in MEDIA CENTER can be broken into three distinct categories:


* [[#Tag or filename editing|Tag or filename editing.]] ('''''<ins><span style="color:red">Data is physically altered by the expression</span></ins>''''')
Any text between brackets [] will be replaced with the corresponding field. 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. After the field name, a comma can be placed followed by a 0 or 1 for whether the field should get formatted. So, [Duration] and [Duration, 1] will give "4:02" while [Duration, 0] will give "242".
* [[#Filtering a list of files using a search rule|Filtering a list of files using a search rule.]] (''No data is altered'')
* [[#Change how existing data is displayed|Change how existing data is displayed.]] (''No data is altered'')


The implementation of the expression differs between each of these three categories, differences which are outlined below.
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Tag or filename editing====
Expressions can be used to simplify the batch editing of file tags, or if required, physical filenames too. It is important to remember that when using expressions in this way, file tags are physically altered, and if the expression is applied to a "filename" field, then the physical name or path of the file will be changed on the hard drive.<br>
Expression functions that are typically used for these kind of tasks are grouped together in the [[#Functions for filename and field manipulation |list of functions]]. The grouping is provided as a rough guide only, as any function that gets the job done can be used.<br>
When using expressions for this kind of task, the expression is either entered into the tag window, or by using inline editing in the file list, and a preceding "=" sign must be inserted to instruct the tagging engine to invoke the expression evaluator, rather than apply the expression as physical tag data. The following screen pictures will help to illustrate using expressions in this way:<br>
{| align=center
|-
|
[[image:Inline1.png|frame|Pressing "Enter" copies the Date data into the caption field]]
|
[[image:Inline2.png|frame|Just like that!]]
|}

Next, using the [filename (name)] field and expressions to directly edit the file name on the hard disk:
{| align=center
|-
|
[[image:Inline4.png|frame|Pressing "Enter" renames and renumbers the selected files]]
|
[[image:Inline5.png|frame|Just like that!]]
|}
''Worth noting that any mistakes made using expressions in this way can be undone by pressing '''Ctrl+Z'''''
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Filtering a list of files using a search rule====
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>
'''[=EXPRESSION]=1''' or '''[=EXPRESSION]=0'''

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.

Remember that the search field appears in many places throughout MEDIA CENTER, places that include:
* The search field itself (in the top right corner of the program)
* 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:
'''<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>
====Change how existing data is displayed====
As well as the search field detailed above, expressions can also be used in many other places within MEDIA CENTER. Places that you might consider using expressions include:

* The player information bar (right click the information bar, choose "Customize")
* The image playback caption
* The "Rename, Move or Copy Files" tool
* Panes (''aka categories'')
* List columns (right click a column header and choose "Add expression column" from the menu)
* Thumbnail text
* The library field manager (''Create expression based library fields'')
* Theatre View
* The links manager (''Use expressions to format the URLs for your links'')

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.

* For photos and videos, thumbnail text can be extremely useful, with the slight drawback that space there is a bit on the limited side. Using expressions here can be very productive indeed, for example, by using expressions, it is possible to instruct MEDIA CENTER to only display selected data if it actually exists, effectively getting rid of any of those "unknown ..." entries in the list.
* Expressions can be used in link properties (accessed via the link manager) so that a link will only be displayed if certain criteria are met, helping to keep the links bar uncluttered, populated with just those links that pertain to the current file list or selection. [http://yabb.jriver.com/interact/index.php?topic=59322.0 This topic] contains a couple of interesting "Link Manager" tips that some might find useful.
* Some users choose to keep media files stored on drives, or in paths, dependent upon media type. The "Base path", "Directory" and "Filename" fields in the "Rename, Move or Copy Files" all accept expressions, offering the user powerful control over how the tool deals with files, dependent upon how they are tagged.
* Expressions can be saved as library fields in their own right. See [[Changing_the_number_of_plays|Editable expression fields]] and this [http://yabb.jriver.com/interact/index.php?topic=54226.msg374211#msg374211 "Eureka moment"] for a couple of related tips.
<div style="text-align:right;">([[#top|Back to top)]]</div>
==Specify data types for expression based fields==
Now and again (or always, in the case of "[[#Functions for the manipulation and creation of list type fields|List type]]" expressions), an expression based pane or library field may not sort correctly, or rather, may not sort as desired. Think about things like months... should they be sorted alphabetically or chronologically? They will sort alphabetically by default, so no problems there, but, if a chronological order is required, then a "Data Type" for the expression must be specified. Data types are set by appending the following string to an expression: '''&datatype=[<span style="color:blue">''DATA TYPE''</span>]''', where <span style="color:blue">''DATA TYPE''</span> is one of the following five values:

* '''List''': ''A list of strings, separated by semicolons''
* '''String''': ''Sorts as strings (with smart number handling)''
* '''Number''': ''Sorts values as numbers (decimal or integer)''
* '''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:

{| align=center
|-valign=top
! colspan="2" style="background: #ecfeea; color: black; border: 1px solid black" | &DataType=[Month]
!
! 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==

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.

Function and field values in expressions are ''not'' case-sensitive.
Available functions with descriptions and examples are listed below.
<div style="text-align:right;">([[#top|Back to top)]]</div>
==Functions==
==Functions==


===If(...): Ask closed questions and control output dependent upon result.===
A function allows special operations to be performed. A list of functions follows:

{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" width=100 | If()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This will be the function you will likely use more than any other. It is typically used in conjunction with one or more other functions and allows you to give specific instructions depending upon whether the result is positive (1) or negative (0). The positive instruction is always given first.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''if(''expression to test'',instructions if positive,''instructions if negative'')'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''if(isequal([artist],bob dylan,1),Genius,Mediocre)'''<br>''Wherever this expression is applied, be it as an expression column or category, as part of a renaming rule, thumbnail text, if the artist tag is Bob Dylan, MEDIA CENTER will produce Genius, and for all other artists, it will produce Mediocre.'' The "IsEqual()" function is described in the first table below.
<br>
'''if(isequal([artist],bob dylan,1),Genius,if(isequal([album],Joshua Tree,8),Great Album,Mediocre))'''
<br>''Here, we have two nested "If" functions. First we ask if the artist is Bob Dylan, if the result is positive, write "Genius". If the artist is not Dylan, we then ask if the album is "Joshua Tree", if yes, write "Great Album", and if no, write mediocre''

<br>On it's own, "If()" is rather boring and not a lot of use. When used in conjunction with other functions, however, it becomes very powerful indeed. In the two examples above, the numbers 1 and 8 have been used. These are comparison mode switches used by the IsEqual function. There are 9 different compare modes in total, all of which are detailed below. Note how the second example ends with two closing parenthesis, one for each "If" function.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>

===Query, Test and Compare using "Is" Functions===
All of the functions in this section, when used on their own, will only ever return one of two values, 1 (true) or 0 (false). There is a "[[#FormatBoolean(...): Formats a boolean (true / false) value in a specified manner|FormatBoolean()]]" function that can be wrapped around these and allows us to specify the output for each case and is discussed in more depth in the Format section. The real power and versatility of these "Is" functions is released when they are wrapped inside the If() function discussed above.

====IsEqual(...): Compares two values in one of nine specified modes====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | IsEqual()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Compares two values in one of nine specified modes ("exact match", "Is greater than" etc.) and outputs 1 for a positive match and 0 for a negative match. If no compare mode is specified, the compare will default to 0.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''isequal(''1st value to compare'',2nd value to compare'',compare mode)'''

''Available Compare Modes:''
* 0: ''case-sensitive string compare for equality''
* 1: ''case-insensitive string compare for equality''
* 2: ''numeric compare for equality''
* 3: ''numeric less than''
* 4: ''numeric less than or equal to''
* 5: ''numeric greater than''
* 6: ''numeric greater than or equal to''
* 7: ''substring search (case sensitive)''
* 8: ''substring search (case insensitive)''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''isequal([artist],[album],1)'''<br>''If the 'artist' and 'album' values are the same, the output will be 1, otherwise, the output will be 0.''

<br>'''if(isequal([artist],[album],1),Self Titled,[album])'''
<br>''Wrapped inside an 'If' function, if the 'artist' and 'album' values are the same, the output will be 'Self Titled', otherwise, the output will be the 'album' value.''

<br>'''if(isequal([artist],[album],1),Self Titled/,,[album]/))'''
<br>''This example demonstrates the character 'escaping' mentioned in the [[#Overview|overview]] earlier. Here, we want the output to be either "Self Titled," (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 preceding forward-slash character. This informs the expression evaluator that these characters are not part of the expression syntax and are to be treated literally''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====IsEmpty(...): Tests to see if a field is empty====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | IsEmpty()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Tests any given field for data. If the field is empty, the function returns 1, and if populated, the function returns 0. There are two different test modes available, a "string" test, and a "number" test. This is because as far as MEDIA CENTER is concerned, fields designated as containing numerical values that are populated with the number zero, are empty. If no test mode is specified, the function will default to 0.
Pay particular attention to the third example offered below, as it covers a caveat that comes with this particular function.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''isempty([field to test],test mode)'''
''Available test modes:''
* 0: ''String test (field must be empty to get a positive result)''
* 1: ''Numerical test (field must be empty, or contain 0 to get a positive result)''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''isempty([comment],0)'''<br>''If the comment field is empty, this expression will return 1, but if the comment field contains data, the expression will return 0.''

<br>'''isempty([track #],1)'''
<br>''This expression will perform a numerical test for data in the [track #] field. If the field is empty, or contains 0, the expression will return a positive result, 1, otherwise, the result will be negative, 0.''

<br>'''if(isempty([disc #]),,[disc #])'''
<br>''Here, by not entering any instructions to carry out for a positive result, the expression will do just that, and output nothing, but if the [disc #] field does contain data, the expression will write that out. Upon first look, you would think that this could work really well in the "Rename, Move and Copy Files" tool for only creating a \Disc #\ directory if needed. This will not work. When asking the rename tool to create directories from field data, it is smart enough to know that directories with no name are illegal in Windows, so when it encounters an empty field, it automatically converts it to "Unknown&nbsp;[Field&nbsp;Name]". It does this before the expression engine gets to see it, which means that the IsEmpty function will always return a negative result when used in the rename tool, even when the specified field is indeed empty. As we now know that empty fields are passed through the rename tool as "Unknown&nbsp;[field&nbsp;name]" we can use '''if([[#IsEqual(...): Compares two values in one of nine specified modes|isequal]]([disc&nbsp;#],unknown,8),,[disc&nbsp;#])''' to achieve the desired result. Note that this only applies when using the rename files tool.''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====IsRange(...): Tests a value for inclusion within a given range====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | IsRange()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | IsRange allows us to test if any given field falls inside any given range of values. If the field falls inside the given range, the function returns 1, and if outside the given range, the function returns 0.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''IsRange([Field to Test],Specified-Range)'''
''The range to test for can be letters or numbers, separated by a hyphen, without spaces, lowest value first, highest second. Letters and numbers cannot be mixed, the range can only be one or the other''
* ''1-100''
* ''a-z''
* ''c-d''
* ''23-7542''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''isrange([artist],a-c)'''<br>''Abba or Blondie will return 1 (positive), and ZZ Top will return 0 (negative).''

<br>'''if(isrange([bitrate],96-191),Poor Quality,High Quality)'''
<br>''This expression will output "Poor Quality" for any file where the bitrate falls between 96 and 191, and "High Quality" for all others. Note that expressions are only as good as the instructions given, and that the above expression would label files with bitrates less than 96kbps as "High Quality". If this expression were used to add a category to a view, there would be two selectable choices in the category, Low Quality, and High Quality. Selecting either one would then filter the file list accordingly.''

<br>'''[http://yabb.jriver.com/interact/index.php?topic=38566.msg262229#msg262229 This post]''' ''on Interact shows the use of IsRange in a Search List. (right click the link, open in new tab to keep this page open). The expression format in that post shows how to form expressions for use in standard MEDIA CENTER searches, something that was covered earlier'' [[#When, Where and How to use expressions|on this page.]]
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====IsMissing(...): Tests to see if a file exists on the system====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | IsMissing()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function checks to see if a file exists on the system. If the file is missing, the function returns 1 (positive), and if the file is found, the function returns 0 (negative). It is possible to specify a specific file to check for, but if you know that much, it will be quicker to fire up explorer and check yourself. This function comes in handy for checking the integrity of your MEDIA CENTER library as you can use it to produce a list of any files in your library that MEDIA CENTER cannot find. However, be aware that the larger your library, the longer this list will take to produce as MEDIA CENTER will need to physically check each files' existance in turn.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''IsMissing(Full Path To File)'''
''If no file path is specified, the function will default to checking the current file.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''ismissing()'''<br>''Checks if the current file exists, and returns 1 (positive) if the file does not exist, and 0 (negative) if the file does exist.''

<br>'''ismissing(C:\Music\My Lost File.mp3)'''
<br>''Checks for "My Lost File.mp3" and returns 1 (positive) if the file does not exist, and 0 (negative) if the file does exist.''

<br>'''[=ismissing([filename])]=1'''
<br>''This example also demonstrates how to construct an expression for use as a MEDIA CENTER search string. 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 your library is in good order, this list should be empty. You could also create a view scheme and use this string in the "Set rules for file display" search to give you a view that you can visit periodically to check that your library is intact

<br>'''if(ismissing(),File is missing,File exists)'''
<br>''Wrapped inside an "If()" function, the expression outputs "File is missing" or "File Exists" depending on the result returned by IsMissing()''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====IsRemovable(...): Tests to see if a file is stored on removable media====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | IsRemovable()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Checks to see if a file resides on removable media and if so, returns 1 (positive), and if not, returns 0 (negative). There is not a lot to say about this function, especially since MEDIA CENTER comes equipped with a [Removable] field by default that is automatically populated with 1 for all files in the library that are on removable storage. The function works in exactly the same way as the IsMissing function described above, returning 1 (positive) if the file is on removable storage, and 0 (negative) if not.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''IsRemovable(Full Path To File)'''

''If no file path is specified, the function will default to checking the current file.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''isremovable()'''<br>''Checks if the current file is on removable storage, and if so, returns 1 (positive), if not, the function returns 0 (negative).''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====IsInPlayingNow & IsPlaying(...): Tests to see if a file is in the Playing Now playlist or currently being played====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | IsInPlayingNow()
| rowspan="2" style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | These two functions will be dealt with together as from their names, they are self-explanatory. One checks to see if a file has been added to the playing now list in any zone, and the other checks if a file in a list is currently playing or not, in any zone. With this in mind, their most practical use is as expression columns in a file list. To add an expression column to a list, right click on any existing column header and click on the "Add expression column" option.
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | IsPlaying()
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''IsInPlayingNow()'''<br>''Checks the current file, and if in the Playing Now list, returns 1 (positive), and if not, returns 0 (negative).

<br>'''IsPlaying()'''
<br>''Checks the current file, and if currently playing, returns 1 (positive), and if not, returns 0 (negative).
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''if(isinplayingnow(),Selected,Not Selected)'''<br>''As mentioned in the description, the ideal place for these functions is as 'expression columns'. If this example were used in an expression column, then files added to Playing Now will show as "Selected" and all other files would show as "Not Selected". If the idea here is to be able to quickly see which files have been added, this might look a bit 'busy' and defeat the purpose, to which end, it is perfectly acceptable to tell the expression that if a file is not in Playing Now, to output nothing, by simply not giving any instructions for the negative result, like so: '''if(isinplayingnow(),Selected,)'''. Now, this expression column will only show "Selected" against files that are in Playing Now, leaving all others empty, giving a much easier column to read.

<br>Use'' IsPlaying ''in exactly the same way as IsInPlayingNow()''

<br>''On the Interact support forum,'' '''[http://yabb.jriver.com/interact/index.php?topic=57461.0 mark_h describes how he puts these two functions to work for him]''', ''and rick.ca shows how he tweaked the idea when he answers the question:'' '''"[http://yabb.jriver.com/interact/index.php?topic=58137.msg393905#msg393905 is it possible to play an artist's full work when a genre is shuffling?]"'''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
<br><br>
===Change how existing data is displayed using Format functions===
All of these functions (with the exception of FormatBoolean) take raw data from the library and allow us to present that data in a way that we choose. What does "raw data" mean? MEDIA CENTER stores duration information in seconds and converts that information into hours (if needed), minutes and seconds for display in the Duration column in a file list. Likewise, file size information is stored in bytes and is converted into Mb for display in the file list. Dates are stored using a UNIX system (use google if you want to know more about that) which means that the date field could contain 40121.8272916666683159 and MEDIA CENTER will display that as 04/11/2009 19:51 (if that is how your Windows locale setting displays date and time). So there you have it, raw data. The following section gives some idea of what is possible using the raw data and the Format functions. '''''To&nbsp;instruct the expression evaluator to use raw data, a zero is added to the library field, inside the square brackets, like so: [Date Imported,0]'''''
====FormatDate(...): Formats a date value in a specified manner====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FormatDate()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | As mentioned in the [[#Change how existing data is displayed using Format functions|section introduction above]], MEDIA CENTER stores date information in a UNIX style, and converts that information into legible date/time information we can understand. By default, MEDIA CENTER presents dates using the system locale settings. This function can be applied to any default library field that contains date information in order to have that information displayed in a non-default format.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''formatdate([date field,0],Format,Output if date is empty)'''

''Available format choices:''

* Year ''Returns the full year, i.e. 2010''
* Month ''Returns the full month, i.e. April, November.''
* Day ''Returns the day in number format, i.e. 23 (note that single numbers have no leading zero)''
* Filename ''Returns a filename friendly date format that also includes the seconds&nbsp;information to help avoid file names clashing, i.e. 20040521-032221''
* Elapsed ''Returns "how long ago" information, i.e. 2.43 Days or 1.85 Years''
* Date ''Returns the date using the system format on the machine running the expression.''
* DateTime ''Returns the date and time using the system format on the machine running the expression.''
* hour ''Returns the hour from dates with time information. (note that single numbers have no leading zero)''
* minute ''Returns minutes from dates with time information. (note that single numbers have no leading zero)''

''Flexible formatting is also available: ('''Note that these <ins>are case sensitive</ins>)'''''

* yy ''Returns the last two digits of the year''
* yyyy ''Returns the full year''
* MM ''Returns the month as two digits''
* MMM ''Returns the month as three letter abbreviations''
* MMMM ''Returns the month in full''
* dd ''Returns the day as two digits''
* ddd ''Returns the day as three letter abbreviations''
* dddd ''Returns the full day''

Output if date is empty: ''If the date is empty, anything placed here will be output instead. This could be plain text, such as "No Date", or a library field. This value is optional, and if not given, the expression will default to return nothing if the date is empty.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''formatdate([last played,0],yyyy//MM//dd,Not Yet)'''<br>''This will return the last played date as year/month/day without the time, and regardless of the system locale setting. If a file has no last played info, the expression will output "Not&nbsp;Yet" instead.''

<br>'''formatdate([date imported,0],month)'''
<br>''This will return the month a file was imported, written in full. For example, December, as opposed to 12.

<br>'''formatdate([date imported,0],month)&datatype=[month]'''
<br>''If you were to use the previous expression to create a view category that contained the months your files were imported, it would list the months alphabetically, with April first and September last. Thankfully, we can specify "data types" for expressions which further fine tune how MEDIA CENTER displays the results. In this case, a data type of month has been specified, therefore MEDIA CENTER will list the months in the correct chronological order. Data types were discussed [[#Specify data types for expression based fields|earlier on this page]].
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====FormatNumber(...): Formats a number to a specified number of decimal places====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FormatNumber()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | '''FormatNumber()''' allows to format any given value to a set number of decimal places.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FormatNumber(Value to format,Number of decimal places,Output if value is zero,Label if value is greater than 1,Label if value equals 1)'''

* "Value to format" ''This could be a library field, such as [replay gain] or the result of a [[#Math(...): Evaluates a given mathematical formula|Math()]] expression. Any numerical value you encounter where you would like to limit the number of decimal places displayed can have this function applied.''
* "Number of decimal places" ''This is optional. If not specified, the function will default to zero decimal places. Use -1 to output as many decimal places as necessary.''
* "Output if value is zero" ''This is optional. If not specified, the function will return zero.''
* "Label if value is greater than 1" ''This is optional. If not specified, the function will not return anything, if specified, and the formatted number is greater than 1, the function will return with the number, plus this label.''
* "Label if value equals 1" ''This is optional, as detailed below..''
** If not specified, but a label for greater than 1 has been specified, then this "greater than 1" label will always be used.
** If neither are specified, the function will not return anything.
** If both are specified, and the formatted number equals 1, the function will return with the number, plus this label.''

''Note that even if you are only interested in applying a label for those results that equal 1, you must also indicate the preceding instructions, if only to instruct the evaluator to ignore them, as shown in the examples below.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''formatnumber([duration,0],2)'''<br>''This will return the duration of a track, in seconds, shown to two decimal places.''

<br>'''formatnumber([number plays,0],0,Not played this one yet,Plays,Play)'''
* "0" decimal places has been specified, therefore the result will be a whole number with no decimals shown.
* ''If [number plays] is zero, the result will be "Not played this one yet"''
* ''If [number plays] is greater than 1, lets say 6, the result will be "6 Plays"''
* ''If [number plays] is 1, the result will be "1 Play"''

<br>'''formatnumber([number plays,0],,,,Time)'''
''Here, the function will fall back to its defaults for everything except when the number equals one:''
* ''No decimal places have been specified, the result will default to a whole number with no decimals shown.''
* ''If [number plays] is zero, the result will be "0"''
* ''If [number plays] is greater than 1, lets say 6, the result will be "6"''
* ''If [number plays] is 1, the result will be "1 Time"''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====PadNumber(...): Adds leading zeros to any given number====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | PadNumber()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function is not a 'Format' function by name, but is by nature, hence its inclusion in this section. PadNumber is a nice, simple function that is used to add leading zeros to any given number value.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''PadNumber(Field to pad,Total number of digits required)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''padnumber([track #],2)'''<br>''This will add a leading zero to all track numbers between one and nine.''

<br>'''padnumber([[#Counter(...): Counts upwards in specified increments|counter()]],4)'''
<br>''here, the output from the counter() function will be 'padded' to 4 characters: 0001, 0002, 0003, etc. etc.''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====FormatDuration(...): Presents a duration of seconds in a reader friendly format====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FormatDuration()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | MEDIA CENTER stores duration data in seconds, at up to sixteen decimal places. The value shown in the default "Duration" column in a file list is an internally formatted interpretation of this raw "Duration" data. As MEDIA CENTER automatically applies this formatting for us, there is not a lot of call for this particular function.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FormatDuration(Value to format)'''


''"Value to format" can be either the raw duration data, or a given number of seconds''
===Field(...): Outputs the value for a given field.===
|- valign="top"
'''Field name:''' the name of the field to evaluate (i.e. Artist, Album, Name, etc.)<br>
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
'''Format for display:''' 0 to use raw data, 1 to use data formatted for display (optional: defaults to 1)
|style="background: #ecfeea; color: black; border: 1px solid black" | '''formatduration([duration,0])'''<br>''This expression will duplicate the contents of the default [duration] field as shown in a file list''


<br>'''formatduration(600)'''
Notes:<br>
<br>''This will output ten minutes in the format 10:00''
You can use brackets around a field to accomplish the same thing. For example, GetField(Artist) can be replaced by [Artist] and GetField(Artist, 0) can be replaced by [Artist, 0].
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====FormatFileSize(...): Presents a number of bytes in a reader friendly format====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FormatFilesize()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | MEDIA CENTER stores file size data internally in bytes. This function will convert those byte values into reader-friendly values, 3.2 Kb or 10.4 Mb, for example. The function will also accept a byte value directly.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FormatFileSize(Value to format)'''


''"Value to format" can be either the raw [File Size] data or a given number of bytes.
Examples:
|- valign="top"
Field(Artist)
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
Field(Artist, 0)
|style="background: #ecfeea; color: black; border: 1px solid black" | '''formatfilesize([file size,0])'''<br>''This expression will duplicate the contents of the default [file size] field as shown in a file list''


<br>'''formatfilesize(56123456)'''
===If(...): Outputs different values depending on the value of the first parameter.===
<br>''This expression will convert 56,123,456 bytes and the output will be 53.5 MB''
'''Test Expression:''' the value that gets tested<br>
|}
'''True:''' the value used if the test expression equals 1<br>
<div style="text-align:right;">([[#top|Back to top)]]</div>
'''False:''' the value used if the test expression does not equal 1<br>
====FormatRange(...): Formats a value as a range====
Examples:
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
If(1, 1, 0)
|- valign="top"
If(IsMissing(), The file is missing., The file is here.)
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FormatRange()
If(IsEqual([Artist], Abba, 1), Too embarrassing, [Artist])
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function places any given value into its place in any given range.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FormatRange(Value to format,Range size,Mode)'''
'''Value to format:''' ''This could be a specific word or number, or any library field''
<br>'''Range Size:''' ''A numerical value dependent on how you wish to set up your range. If not specified, this will default to 1''
<br>'''Mode:''' ''There are three possible modes, detailed below. If not specified, this will default to zero.''
* '''0:''' ''Automatically choose between number / letter grouping''
* '''1:''' ''Specifies that letter grouping should be used''
* '''2:''' ''Specifies that number grouping should be used''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''formatrange([artist])'''<br>''This will return the first letter from the [artist] field. Note that as '''range size''' and '''mode''' values were not specified, the function defaulted to one and automatic respectively.''


<br>'''formatrange([artist],3,1)'''<br>''This will take the first letter from the artist field and place it in the appropriate letter range. In this case, a range size of three has been specified, therefore the output will be in the form of "a-c", "d-f", "g-i" etc. etc.''
===IsMissing(...): Checks to see if a file exists on the system.===
'''Filename:''' the filename to check (optional: defaults to this file)
Examples:
IsMissing()
IsMissing([Filename])


<br>'''formatrange([bitrate],100,2)'''<br>''This will take the bitrate and place it in the appropriate number range. In this case a range of 100 has been specified, therefore the output will be in the form of "0-99", "100-199", "200-299" etc. etc.''
===IsRemovable(...): Checks to see if a file resides on removable media.===
'''Filename:''' the filename to check (optional: defaults to this file)
Examples:
IsRemovable()
IsRemovable([Filename])


Note that this function always starts number ranges from zero, 0-9, 10-19, etc, etc.. If you really need a number grouping that starts from 1, 1-10, 11-20, 21-30,etc. etc., you can use expressions to create a pseudo range. Full details, with a helpful explanation, of "1 based grouping" can be found [[CD_Reference_Number|on this page]].
===IsEqual(...): Compares values and outputs a "1" if the values pass the test, and "0" if they don't pass the test.===
|}
'''Value 1:''' the first value<br>
<div style="text-align:right;">([[#top|Back to top)]]</div>
'''Value 2:''' the second value<br>
'''Compare type:''' the mode to compare (optional: defaults to case-sensitive string compare)<br>
:'''0:''' case-sensitive string compare for equality<br>
:'''1:''' case-insensitive string compare for equality<br>
:'''2:''' numeric compare for equality<br>
:'''3:''' numeric less than<br>
:'''4:''' numeric less than or equal to<br>
:'''5:''' numeric greater than<br>
:'''6:''' numeric greater than or equal to<br>
:'''7:''' substring search (case sensitive)<br>
:'''8:''' substring search (case insensitive)<br>
Examples:
IsEqual([Artist], [Album], 1)
IsEqual([Duration, 0], [Bitrate, 0], 2)


===IsEmpty(...): Tests to see if a value is empty and outputs a "1" if the value is empty, and "0" if it's not empty.===
====FormatBoolean(...): Formats a boolean (true / false) value in a specified manner====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
'''Value:''' the value to test<br>
|- valign="top"
'''Mode:''' the mode to test (optional: defaults to 0)
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FormatBoolean()
:'''0:''' string style, so "" is empty<br>
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function is wrapped around another function and will return specified strings for true and false values returned by that other function.
:'''1:''' number style, so "" or 0 is empty
|- valign="top"
Examples:
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
IsEmpty([Artist])
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FormatBoolean(True/False Test,String to use if true,String to use if false)'''
IsEmpty([Duration], 1)
* '''True/False Test''' ''Other functions perform their respective tests and return 1 to indicate a true result, and 0 to indicate a false result''
* '''String to use if true,String to use if false''' ''If these are not specified, the function will default to using "True" and "False"''


|- valign="top"
===IsRange(...): Compares a value against a range and outputs a "1" if the values is inside the range, and "0" if not.===
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
'''Value:''' the value to test<br>
|style="background: #ecfeea; color: black; border: 1px solid black" | '''formatboolean(isempty([number plays]),Never Played,Has Been Played)'''<br>''On it's own, the function'' isempty([number plays]) ''will return either 1 or 0. When wrapped inside a'' formatboolean ''function as shown here, the output for a true result will be "Never Played", and for a false result, the output will be "Has Been Played".
'''Range:''' the range of values (in the form: a-z or 1-100)<br>


<br>'''formatboolean(isempty([number plays]))'''<br>''Here, there are no strings specified for the true/false results, therefore the function will default to using "True" and "False"''
Examples:
|}
IsRange([Artist], a-b)
<div style="text-align:right;">([[#top|Back to top)]]</div>
IsRange([Bitrate], 128-192)
<br><br>
===Functions for filename and field manipulation===
The primary use of the functions in this section is to manipulate the data associated with any given file or files. When used with direct editing in the file list, or in the action window, as decribed [[#When, Where and How to use expressions|here]], they offer extremely fast and efficient methods for batch editing the actual tag data associated with multiple files.<br>Note that when used indirectly, in expression based columns, categories or library fields, the referred fields are not altered in any way, the data is merely presented in the expression field formatted as requested.
====Clean(...): Returns a cleaned up version of a filled in template====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Clean()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | The official description for this function is simply "Returns a cleaned up version of a filled in template". This function is better explained through demonstration in the examples below.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Clean(template to clean)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''Clean([Artist] - [Album] /([Genre]/))'''
* First of all, note that this example uses the "forward slash" escaping, as discussed in the [[#Overview|Expressions Overview]] earlier. The result here will be that the [Genre] will be returned wrapped in parenthesis. Without the escaping, the function would fail as the evaluator attempts to read the parenthesis as an integral part of the expression.


* Imagine the template without the Clean() function around it. ''[Artist] - [Album] /([Genre]/)''<br>If used as an expression, this string, quite predictably, will return things such as: "AC/DC - Back In Black (Rock)", but, what if one or more of the specified fields contains no data? The result would be rather untidy, such as: "- Back In Black ()" if there were no [artist] or [genre] data.<br>Wrap the template inside the Clean() function to tidy these cases up, so, "- Back In Black ()" would become "Back In Black"
===FilePath(...): Returns the path from a filename.===
|}
'''Filename:''' the filename to check (optional: defaults to this file)
<div style="text-align:right;">([[#top|Back to top)]]</div>
====FixCase(...): Changes the case of a given string====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FixCase()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function will output any given text string in one of five specified case modes.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FixCase(String to modify,Case mode to apply)'''<br>''The ''"String to modify"'' can be plain text, a library field, or a combination of the two.''


The five modes available are:
Examples:
* '''0:''' ''Title Case''
FilePath()
* '''1:''' ''All Words''
FilePath([Filename])
* '''2:''' ''First word''
* '''3:''' ''ALL UPPERCASE''
* '''4:''' ''all lowercase''


''If no case mode is specified, the function will default to using "Title Case". Title case will start each principal word with a capital. More detail regarding title case can be found [http://www.grammar-monster.com/lessons/capital_letters_title_case.htm here]''
===FileName(...): Returns the name from a filename. ===
'''Filename:''' the filename to check (optional: defaults to this file)


|- valign="top"
Examples:
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
FileName()
|style="background: #ecfeea; color: black; border: 1px solid black" | '''fixcase([album])'''<br>This will take the contents of the [album] field and present it with the specified capitalisation. As there is no specified mode here, the function defaults to 0, so, if an album is entered in the library as "Time Out Of Mind", the function will return "Time Out of Mind" (note the lower case "of")
FileName([Filename])


<br>'''fixcase(MY ALbUm IS cAlLeD [album],4)'''<br>This would return "my album is called time out of mind"
===FileVolume(...): Returns the volume name from a filename.===
|}
'''Filename:''' the filename to check (optional: defaults to this file)
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Length(...): Returns the number of characters in a string====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Length()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function returns the number of characters in any given string.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Length(String to count characters from)'''<br>''The ''"String to count characters from"'' can be plain text, a library field, or a combination of the two.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''length([filename])'''<br>''This will count the characters in the [filename] field and return the result. Spaces count as characters, so, C:\My File.mp3 would return 14.


<br>'''if(isequal(length([filename]),68,6),68 Characters or more,Less than 68 Characters)'''<br>''Here, Length() has been combined with another two functions, "If()" and "IsEqual()". The expression compares the length of the filename against the number 68. If there are 68 or more characters in the filename, the expression will return "68 Characters or more", otherwise, it will return "Less than 68 Characters". If you are working with a device with filename length limitations, these functions can be used to create extremely useful expressions that could help with your device management.''
Examples:
|}
FileVolume()
<div style="text-align:right;">([[#top|Back to top)]]</div>
FileVolume([Filename])
====Left(...): Retrieves a specified number of characters from the left of a value====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Left()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function retrieves a specified number of characters from the left of any given value.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Left(Value to get characters from,Number of characters to get)'''<br>''"Value to get characters from" can be plain text, a library field, or combination of both. If more characters than exist are requested, all available characters are returned.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''left([filename],3)'''<br>''This will return the drive letter, colon and first back-slash from the filename. If asked to show more characters than actually exist, the expression will return the entire value, also, remember that spaces count as characters too.''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Right(...): Retrieves a specified number of characters from the right of a value====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Right()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function retrieves a specified number of characters from the right of any given value.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Right(Value to get characters from,Number of characters to get)'''<br>''"Value to get characters from" can be plain text, a library field, or combination of both. If more characters than exist are requested, all available characters are returned.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''right([filename],3)'''<br>''This will return the last three characters from the filename. If asked to show more characters than actually exist, the expression will return the entire value, also, remember that spaces count as characters too.''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====RemoveLeft(...): Trims characters from the start of a value====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | RemoveLeft()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | The output from this function will remove a specified number of characters from the start of any given value.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''RemoveLeft(Value to remove characters from,Number of characters to remove)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''removeleft([name],5)'''<br>''This would show the name field, with the first five characters removed. If asked to remove more characters than actually exist, the output will be blank, also, remember that spaces count as characters too.''.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====RemoveRight(...): Trims characters from the end of a value====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | RemoveRight()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | The output from this function will remove a specified number of characters from the end of any given value.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''RemoveRight(Value to remove characters from,Number of characters to remove)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''removeright([name],5)'''<br>''This would show the name field, with the last five characters removed. If asked to remove more characters than actually exist, the output will be blank, also, remember that spaces count as characters too.''.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Mid(...): Retrieves specified characters from a value.====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Mid()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Mid() retrieves a specified number of characters from a specified starting point in any given string.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Mid(Value to get characters from,Character to start at,Number of characters to get)'''
* '''Value to get characters from''': ''This can be a library field, plain text, or a combination of both.
* '''Character to start at''': ''This is a numerical pointer, and rather confusingly, the function treats the first character as zero and begins from there. If not specified, the function will default to zero.
* '''Number of characters to get''': ''If this value is not specified, the function will default to 1. -1 can be used to retrieve all available characters after the specified start point.


|- valign="top"
===FormatNumber(...): Formats a number in a specified manner.===
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
'''Value:''' the number to format<br>
|style="background: #ecfeea; color: black; border: 1px solid black" | '''mid(12345)'''<br>''As values for "Character to start at" and "Number of characters to get" have not been specified, they default to 0 and 1 respectively and the function returns the first character in the string, 1.''
'''Number of decimal places:''' specifies how many decimals to use (-1 uses as many as necessary) (optional: defaults to 0)
Examples:
FormatNumber(3.123224, 0)
FormatNumber([Replay Gain, 0], 3)
FormatNumber([Duration, 0])
===FormatDate(...): Formats a date value in a specified manner.===
'''Value:''' the date to format<br>
'''Formatting:''' formatting style
:'''Year:''' 1997
:'''Month:''' March
:'''Day:''' 12
:'''Filename:''' 20040521-032221
:'''Elapsed:''' 3.2 days ago
:'''Other:''' flexible formatting (i.e. yy-MMMM-dd)
No Date Output: the output when the date is empty (optional: defaults to nothing)
Examples:
FormatDate([Date Imported, 0], elapsed)
FormatDate([Date, 0], MMMM: d, no date)
===FormatBoolean(...): Formats a boolean (true / false) value in a specified manner.===
'''Value:''' the boolean to format (optional: defaults to false)<br>
'''True display:''' string to display for true (optional: defaults to "True")<br>
'''False display:''' string to display for false (optional: defaults to "False")
Examples:
FormatBoolean(1)
FormatBoolean(IsMissing(), File missing, File exists)
===FormatDuration(...): Formats a duration in seconds to a readable string.===
'''Value:''' the value to format
Examples:
FormatDuration(60)
FormatDuration([Duration, 0])
===FormatFileSize(...): Formats a number of bytes as a readable string.===
'''Value:''' the value to format
Examples:
FormatFileSize(1024)
FormatFileSize([File Size, 0])
===FormatRange(...): Formats a value as a range.===
'''Value:''' the value to format<br>
'''Range size:''' the number of letters / numbers to put in a grouping (optional: defaults to 1)<br>
'''Mode:''' the mode to perform the grouping (optional: defaults to 0)
:0: automatically choose between number / letter grouping
:1: use letter grouping
:2: use number grouping
Examples:
FormatRange(Abba, 3)
FormatRange([Artist])
FormatRange([Bitrate, 0], 100, 2)
===AlbumArtist(...): Returns the calculated album artist for a file.===
No parameters
Examples:
AlbumArtist()
===AlbumType(...): Returns the album type for a file.===
No parameters
Examples:
AlbumType()
===Size(...): Returns the size of a file in a media-type independent manner.===
No parameters
Examples:
Size()
===CustomData(...): Returns custom data stored in a file array. (used primarily for internal uses)===
'''Field:''' a field name ("#" gets the array sequence number)
Examples:
CustomData(#)
CustomData(My Special List Data Field)
===Clean(...): Returns a cleaned up version of a filled in template.===
'''Value:''' the value to clean
Examples:
Clean(Size())
Clean([Artist] - [Album] /([Genre]/))
===FixCase(...): Changes the case of a string.===
'''Value:''' the value to change<br>
'''Mode:''' case mode (optional: defaults to title case)
:0: title case
:1: all words
:2: first word
:3: all uppercase
:4: all lowercase
Examples:
FixCase(MaKe ME PreTTy, 0)
FixCase([File Type], 3)
===Mid(...): Retrieves specified characters from a value.===
'''Value:''' the value to get characters from<br>
'''Start:''' the character to start at (optional: defaults to 0)<br>
'''Characters:''' the number of characters to get (-1 returns all) (optional: defaults to 1)
Examples:
Mid(Abba)
Mid(Abba, 0, 2)
Mid([Artist], 3, -1)


<br>'''mid(12345,1,2)'''<br>''The start point has been specified as the second character in, and 2 characters have been asked for, the result here will be 23.''
===PadNumber(...): Use to add leading zeros to a number.===
'''Field:''' the field to pad<br>
'''Value:''' the number of digits you require in the number.
Examples:
PadNumber([track #],3)


<br>An example of Mid() being used to re-order a date field was given in answer to the question "[http://yabb.jriver.com/interact/index.php?topic=52809.0 Can I include seconds in "import date"?]"
===RemoveLeft(...) and RemoveRight(...): Use to trim characters from the start or end of a field===
|}
'''Field:''' the field to trim.<br>
<div style="text-align:right;">([[#top|Back to top)]]</div>
'''Value:''' how many characters to trim. (spaces count as characters)
====Replace(...): Replace or remove strings from a value.====
Examples:
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
RemoveRight(abba abc,4) returns abba
|- valign="top"
RemoveRight([filename (name)],4) returns the file name without the extension. (picture.jpg becomes picture)
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Replace()
RemoveLeft([name],3) returns '''Tangled Up In Blue''' from '''01 Tangled Up In Blue'''
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Quite simply, this function allows to search for a specified string in a specified value, and if found, remove the specified string, or replace it with another.
Note that you can select all desired files, then simply enter the expression into the [Name] field in the tag window as '''=removeleft([name],3)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Replace(Value to check,String to check for,String to replace with)'''
* '''Value to check''': ''This can be plain text, a library field, or combination of both.
* '''String to check for''': ''Note that this check is <ins>case-sensitive</ins>''
* '''String to replace with''': ''Any instance of the "String to check for" will be replaced by this string. If not specified, any instance of the "String to check for" will be removed.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''replace(My Sample String,S,Replaced )'''<br>''All instances of upper-case "S" will be replaced by the text "Replaced ", (note the trailing space), resulting in'' "My Replaced ample Replaced tring"


<br>'''replace(My Sample String,s,Replaced )'''<br>''The "Value to check" does not contain any lower-case "s", resulting in unchanged output, "My Sample String"''
===Counter(...): Use to return a value that starts at one and counts up with each use===
'''1st Value:''' Where to start counting from. (optional. starts at 1 if not specified)<br>
'''2nd Value:''' Incremental value. (optional. counts in increments of 1 if not specified)
Examples:
Counter() returns 0
Select 10 files, pick 'Rename' from the right click menu on the Track # field and type '=Counter(1)' to number tracks sequentially
Use with text:
Select files, right click in the field to edit and choose rename. Type =TEXT-counter(150,2) and press enter to have the selected fields filled<br> sequentially as TEXT-150, TEXT-152, TEXT-154 etc. etc.


<br>'''replace(My Sample String,/ Sample,stic)'''<br>''In this example, the space preceding the word Sample is to be included in the "String to check for". Remembering that, as discussed in the [[#Overview|Overview]], spaces that follow a comma are ignored unless escaped, an escaping forward slash is used to force the inclusion of the space in the check. The result here will be "Mystic String".
Notes:
|}
The counter function resets back to one after five seconds of inactivity.
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Counter(...): Counts upwards in specified increments====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Counter()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function can be used to number objects sequentially, from a specified starting point, in specified increments. The counter resets itself to zero after five seconds of inactivity.<br>Counter() can exhibit a touch of wierdness when used in certain situations, which will be covered in the examples, that demonstrate why this one is not really a 'fits all' function.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Counter(Number to start counting from,Increments to count up in)'''


* '''Number to start counting from''': ''This is optional. If not specified, the counter will start from one. If specified, the start value is inclusive, meaning that if a start value of five is specified, the first value the function returns will be five.''
===Now(...): Use to return the current date===
* '''Increments to count up in''': ''This optional. If not specified, the counter will count up in increments of 1''
Examples:
|- valign="top"
FormatDate(Now()) formats the current date according to the system setting
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
FormatDate(Now(), year) returns the current year
|style="background: #ecfeea; color: black; border: 1px solid black" | '''counter()'''<br>This shows the function in its simplest form. The counter will start at one and count upwards in increments of 1.


<br>'''[[#PadNumber(...): Adds leading zeros to any given number|padnumber]](counter(370,2),4)'''<br>This expression shows a combined use of functions. Counter() will count up, in two's, starting from 370, and the padnumber function will pad the results to four figures, giving output values of 0370, 0372, 0374, etc. etc..
===ListItem(...): Use to return a value from a delimited list===
'''List:''' List<br>
'''Index:''' Index (starts at 0)<br>
'''Delimiter:''' Delimiter (optional -- defaults to semi-colon)<br>


<br>'''Weirdness'''<br>Counter() works really really well, and really really efficiently when used to sequentially number static data fields. It is not designed to be used in a dynamically changing expression column in a file list. To demonstrate this, right click on a list column header and choose the option to "Add expression column". Use the first, simple expression above, and press OK. The column is presented and all the items in the list are now numbered in this column, but, see what happens when you run the cursor up and down the list? The counter function just keeps on going and going. Right click on the expression column header, and it will appear at the top of the selectable columns list with a tick beside it, click on it to remove the column. This same anomally appears when counter() is used in the "Rename, Move and Copy Files" tool. There may be a possible solution to this effect as seen in the renaming tool by using the CustomData(#) function, but only if the count is to start from 1.<br>Some interesting reading regarding the use of Counter() can be found in answer to "[http://yabb.jriver.com/interact/index.php?topic=48659.0 how to fill the NAME field with incrementing numbers?]" and "[http://yabb.jriver.com/interact/index.php?topic=50622.0 Prepending a consecutive number to titles as I copy them from MC13 to mp3 player]".
Notes:
|}
Beginning with version 150.0.102, whitespace surrounding delimiters is removed when building / analyzing lists.
<div style="text-align:right;">([[#top|Back to top)]]</div>
<br><br>
===Functions for the manipulation and creation of list type fields===
The default MEDIA CENTER library contains many fields that are referred to as "list type" fields. Users are also able to add their own "list type" fields to their libraries. A list type field contains one or more text items seperated by semi-colons. The semi-colons are referred to as the 'delimiter' and when displayed in a view category, text items seperated by semi-colons are displayed in a list of seprately selectable items. The "Keywords" field is a classic example of a list type field, which demonstrates how list type fields allow a single file to be tagged with many different keywords, as opposed to a 'standard' field, such as 'Genre', where a single file can only be tagged with a single genre. The following functions provide the ability to combine or build custom list type fields using the default semi-colon delimiter, or a specified delimiter, count the number of items contained in a given list, or extract a numbered entry from within a list. Two of the functions listed in this section are used to create "list type" data from two or more existing sources and could reasonably be considered to be functions more suited to those who are very familiar with MEDIA CENTER and how it gets its job done. If these functions are used to create a new 'calculated data' library field, they will not function as 'list type' fields unless the field is first created as a "User Data" field, with "List Type" specified. After creating the field in this way, it is possible to go back and edit the field, changing it to "calculated data" and entering an expression to be used. The [http://yabb.jriver.com/interact/index.php?topic=54226.msg374211#msg374211 "Eureka moment"] occurred in November 2009.
====ListBuild(...): Build a list from a series of values====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | ListBuild()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function provides the ability to create a single list from many different sources and allows a list delimiter to be specified. It has two modes that can be applied and are detailed below. Of these two modes, mode "0" (Combine all values) should be avoided. It has been included for 'function completeness' only, and when used, can produce some very strange results that do not filter as expected. In order for the data generated by this function to be treated as list data, the [[#Specify data types for expression based fields|'datatype']] must be specified as [list].
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''ListBuild(Mode,Delimiter,Items,To,Include)'''<br>
'''Mode:''' ''There are two different modes available:
* '''0''': ''combine all values. NOTE: <ins>This mode should be avoided as there is no recorded practical use for it, and it's behaviour can be unpredictable.</ins>''
* '''1''': ''combine non-empty values''


'''Delimiter''': ''The character used here will be used as a delimiter between each of the specified list items. To be clear, the keywords field uses a semi-colon delimiter by default; if a list is built using keywords and genre, and the specified delimiter is a back slash, it will be used between the keywords and genre fields when joining them, the semi-colons in the keywords field would not be altered. For example, if [keywords] contained "these;are;keywords" and [genre] contained "Rock", and these two were joined using ListBuild with a "\" specified as the delimiter, the resulting data would be "These;are;keywords\Rock". The real beauty and power of this function can be released when expressions are nested into the ListBuild instructions. For example, "listbuild(1,\,replace([keywords],;,\),[genre]" would return the data "These\are\keywords\Rock"''
Examples:
<br>'''Items To Include''': ''This can be any number of specified text entries, expressions, or library fields, seperated by commas''
ListItem([People], 1)
|- valign="top"
ListItem([Filename (path)], 2, \)
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''listbuild(1,;,[keywords],[genre])&datatype=[list]'''<br>''This will return a semi-colon delimited list containing all keywords and genres. If either keyords or genre is empty, they will be ignored, so, the data returned for a file with no keywords, and a genre of "Rock" would be simply "Rock".''


<br>'''listbuild(1,\,[genre],[album artist (auto)],[album])&datatype=[list]'''<br>''When MEDIA CENTER encounters a back slash character in a list type field, it 'nests' the data in the list. Think of this in exactly the same way as Windows reads file paths, each back slash is another folder along the file path, and in a MEDIA CENTER list type view category, each back slash creates a virtual folder, and each semi-colon starts a new list entry, which means that effective browsing trees can be created using this knowledge. In the example shown here, a list of genres would be created, and each genre is able to be expanded to reveal a list of artists, which in turn can be expanded to reveal albums by that particular artist in that genre. So, now that this is getting interesting, there's an issue with this example. If a file has no specified [genre], the value is ignored, and the [album artist (auto)] value is placed on the root of the virtual tree, which means that the completely collapsed list contains a mixture of [genre] and [album artist (auto)]. The next example demonstrates how to clean that up.''
===ListCount(...): Use to return the number of items in a delimited list===
'''List:''' List<br>
'''Delimiter:''' Delimiter (optional -- defaults to semi-colon)<br>


<br>'''listbuild(1,\,if([[#IsEmpty(...): Tests to see if a field is empty|isempty]]([genre]),!No Genre Applied,[genre]),[album artist (auto)],[album])&datatype=[list]'''<br>''Here, the previous example has been improved by nesting an [[#IsEmpty(...): Tests to see if a field is empty|IsEmpty()]] function into the listbuild function. The result is that all files without a specified genre are placed in a group at the top of the virtual tree called "!No Genre Applied", and the rest of the root consists of existing genre values, which is much tidier.
Examples:
|}
ListCount([People])
<div style="text-align:right;">([[#top|Back to top)]]</div>
ListCount([Filename (path)], \)
====ListCombine(...): Combines two delimited lists into a single delimited list====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | ListCombine()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Unlike the [[#ListBuild(...): Build a list from a series of values|ListBuild]] function above, which can be used to create a list from any number of varying sources, ListCombine() is used to merge two specified lists into one. In order for the data generated by this function to be treated as list data, the [[#Specify data types for expression based fields|'datatype']] must be specified as [list].
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''ListCombine(First list,Second list,Input Delimiter,Output Delimiter)'''<br>
'''First List''' ''and'' '''Second List''' are specified library fields.


'''Input Delimiter''': ''This is the value that will be used to join the two specified lists. The value is optional, and if not specified, the function will default to using a semi-colon.''
===Replace(...): Use to find string items and replace or remove them===
'''Field:''' The field to search in
'''String:''' What to find
'''replace with:''' What to replace with (optional, defaults to empty)


'''Output Delimiter''': ''This value is also optional. If specified, the function parses the output list (the result of the two lists, joined by the input delimiter) and replaces each occurrence of the input delimiter with the specified output delimiter.
Examples:
|- valign="top"
replace([artist],featuring,ft.) changes "Mark Ronson feat. Amy Winehouse" to "Mark Ronson ft. Amy Winehouse"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''listcombine([people],[places])&datatype=[list]'''<br>''The result here would be a single, semi-colon delimited list containing all the values from the [people] and [places] fields.''


* [people] contains ''Family\Mum;Family\Dad;Family\Gran''
Notes:
* [places] contains ''United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle''
All occurrences of the search are replaced, and searches are case sensitive, so:
* The output list from the above expression would be: ''Family\Mum;Family\Dad;Family\Gran'''<ins>;</ins>'''United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle'' (the specified "listcombine delimiter" shown in bold and underlined)
replace([artist],a) changes "Abba" to "Abb"
replace([artist],A) changes "ABBA" to "BB"


<br>'''listcombine([people],[places],\)&datatype=[list]'''<br>''Here, the resulting list will be the [people] and [places] lists joined using a back slash. Remember that MEDIA CENTER interprets back slashes as a folder hierarchy when displaying list type fields in a view category pane.''
===ListCombine(...): Use to merge one list type field into another===
''ListCombine(List1, List2, Delimiter, DelimterOutput)''<br />
'''List1 and List2:''' the two list type fields to combine<br />
'''Delimiter:''' Optional - Input/Output delimiter. Default: semicolon.<br />
'''DelimiterOutput:''' Optional - Output delimiter, if specified.


* [people] contains ''Family\Mum;Family\Dad;Family\Gran''
Examples:
* [places] contains ''United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle''
listcombine([keywords],[people])
* The output list from the above expression would be: ''Family\Mum;Family\Dad;Family\Gran'''<ins>\</ins>'''United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle'' (the specified "listcombine delimiter" shown in bold and underlined)


<br>'''listcombine([people],[places],\,;)&datatype=[list]'''<br>''Finally, a semi-colon output delimiter has been specified, therefore, all back slashes will be replaced by semi-colons, and the resulting list will be a single, flat list containing all the text entries from each field:''
Notes:
If used in the keywords field, the people list will be added to the keywords field and vice-versa.
If used in a new field, the two lists will be added to the new field.
If you specify a delimiter, the chosen delimiter is only used to seperate the two lists. So, if [keywords]=on drugs;hilarious;rainbow and [people]=rod;jane;freddy .
The given example will return on drugs;hilarious;rainbow;rod;jane;freddy and listcombine([keywords],[people],~) will return on drugs;hilarious;rainbow~rod;jane;freddy .
Beginning with version 150.0.102, an empty string no longer outputs an empty list item.
Beginning with version 150.0.102, whitespace surrounding delimiters is removed when building / analyzing lists.


* [people] contains ''Family\Mum;Family\Dad;Family\Gran''
===Tag(...): Reads in the physical file tag rather than looking in the database===
* [places] contains ''United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle''
''Tag([field])''<br>
* The output list from the above expression would be: ''Family;Mum;Family;Dad;Family;Gran'''<ins>;</ins>'''United Kingdom;Scotland;Edinburgh;United Kingdom;Scotland;Edinburgh;Edinburgh Castle'' (the specified "listcombine delimiter" shown in bold and underlined)
'''[field]:''' The physical file tag to read into the database.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====ListCount(...): Returns the number of items in a delimited list====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | ListCount()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | ListCount is used to return the number of items that exist in any given field, using any given delimiter.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''ListCount([Field to count],Delimiter to use)'''<br>
'''Field to count''': ''Typically, this will be a list type field, but this is not compulsory. The data in any field can be parsed using any chosen delimiter''


'''Delimiter to use''': ''This is optional. If not specified, the function will default to using a semi-colon delimiter. Anything can be specified as a delimiter, from a single character to a whole word or words.''
Notes:
|- valign="top"
.jpg files can contain EXIF, XMP, IPTC and MJMD tag blocks. When parsing file tags, MC does so in this order:
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
IPTC
|style="background: #ecfeea; color: black; border: 1px solid black" | '''listcount([People])'''<br>
XMP
''No delimiter has been specified here, therefore the function will default to using a semi-colon. The result here will match the number of people shown in a properly tagged photo. Note that the function is smart, so, if a file has no [People] tag, the function will return zero (0), and if it has [People] data, but no semi-colon, the function will return one (1).''
MJMD
EXIF
Except for dates, where the order becomes:
IPTC
XMP
EXIF
MJMD
You can force MC to read in a tag from a specific .jpg tag block by using the format: tag(EXIF: Date) to read the EXIF date, and so on.
When using this function, capitalisation is important when it comes to defining the file tag to read in...
tag(exif: date) will ''not'' work, tag(exif: Date) will.


<br>'''listcount([filename (path)],\)'''<br>
===AlbumKey(...): Returns a unique album key for the file===
''This function can be used to count the directories in a filepath by specifying a back slash as the delimiter.''
Examples:
AlbumKey()


<br>'''listcount([keywords],!People)'''<br>
===Hexify(...): Hexifies a string to make it suitable for website usage===
''This basic expression can be used as a building block to create a more complex expression to count the number of people tagged in a photo. the full expression can be seen [http://yabb.jriver.com/interact/index.php?topic=43975.msg301390#msg301390 here]. That thread is actually the release thread for the 'new' nesting feature, introduced in 2007, and although 2 pages long, is worth a read as it contains some quite useful information.''
'''value:''' the value to hexify
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====ListItem(...): Returns a specified value from a delimited list====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | ListItem()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function numbers list items starting from zero and returns the value of a specifically numbered item.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''ListItem([Field],Number of item to retrieve,Field delimiter to use)'''


* '''Field''': ''The function will accept any given field, though is more typically used with list type fields.''
Examples:
* '''Number of item to retrieve''': ''The number of the item in the list to retrieve. The list items are numbered starting from zero.''
Hexify([Artist])
* '''Field delimiter to use''': ''This is optional. If not specified, the function will default to using a semi-colon delimiter. Anything can be specified as a delimiter, from a single character to a whole word or words.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''listitem([filename],0,\)'''<br>''This function will return a file's drive letter plus colon. Note that the same result could be achieved by using '''[[#Left(...): Retrieves a specified number of characters from the left of a value|left]]([filename],2)''', there is no 'right' or 'wrong' with these things, just personal preference, or 'what works for you'. A good rule of thumb is to use the simplest possible way to get to your goal, as less typing is better, and the more simple the expression, the easier it is to follow.''


<br>'''listitem([filename],2,\)'''<br>''Here, the result will be the name of the second directory along a file's folder path from the drive root. C:\Folder1\Folder2\ are itemised as 0\1\2\, so rather confusingly, the second directory is actually the third item in the back slash delimited path.''
===IsPlaying(...): Determines if a file is currently playing in any zone===


<br>'''listitem([filename (path)],math(listcount([filename (path)],\)-1),\)'''<br>''This expression uses the [[#Math(...): Evaluates a given mathematical formula|math()]] and [[#ListCount(...): Returns the number of items in a delimited list|listcount()]] functions to find the "Number of item to retrieve" value. listcount() returns the total number of directories in the path, and the math function subtracts one from this number (because listcount() starts counting at one, but listitem starts counting from zero), this number is then used by the listitem function. The result will be the name of the parent folder of each file. Setting the expression up in this way means that the result will always be reliable regardless of the number of folders in the filepath as the expression will work all of this out for itself.''
Examples:
|}
IsPlaying()
<div style="text-align:right;">([[#top|Back to top)]]</div>
<br><br>
===Functions that perform specific tasks===
The functions in this group, with the possible exception of the math() function, are used to carry out very specific tasks, or for use in very specific areas of MEDIA CENTER.
====Now(...): Retrieve and display the system date====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Now()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Now() will return the raw system date. "raw" data is discussed in the [[#Field|Field]] description, and also in the introduction to the [[#Change how existing data is displayed using Format functions|"Format"]] functions. As MEDIA CENTER's raw date data is illegible, this function needs to be used with the "[[#FormatDate(...): Formats a date value in a specified manner|FormatDate()]]" function, which allows the current date, and time, if desired, to be presented in many different styles.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Now()'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''formatdate(now(),date)'''<br>''Returns the current date, without the time, formatted according to the system settings on which the function is running.''


<br>'''formatdate(now(),dddd dd MMMM yyyy) [[#PadNumber(...): Adds leading zeros to any given number|padnumber]](formatdate(now(),hour),2):[[#PadNumber(...): Adds leading zeros to any given number|padnumber]](formatdate(now(),minute),2)'''<br>
''Here, three seperate expressions have been strung together to return a fully formatted current date and time:'' '''''Sunday 26 September 2010 14:04'''''


<br>'''[=isequal(formatdate([date imported,0],MM//yyyy),formatdate(now(),MM//yyyy)]=1 ~sort=[Date Imported]-d'''<br>
===IsInPlayingNow(...): Determines if a file is in Playing Now in any zone===
''MEDIA CENTER comes with a stock smartlist titled "Imported This Month". On the face of it, this could be a handy list of files, but is actually rather misleading. Closer inspection of this stock smartlist reveals that it is not actually listing files "Imported This Month", but instead, listing those files that have been imported in the past 31 days by using the following rule: [Date&nbsp;Imported]=<31d&nbsp;~sort=[Date&nbsp;Imported]-d<br>
This would mean that if you were to view that list on the second of March, you could potentially be looking at a list of files imported during three different months. The example in bold above corrects this anomaly by comparing the month/year imported with the current month/year, and only lists the file if the two match.<br>
This is also an example of how to use an expression in a search rule, as detailed in "[[#When, Where and How to use expressions|When, Where and How to use expressions]]"


<br>''<ins>[http://yabb.jriver.com/interact/index.php?topic=56487.0 This topic]</ins> expands on the example above a little by showing how to construct rules that return files that have been played or imported today or yesterday.''
Examples:
|}
IsInPlayingNow()
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Math(...): Evaluates a given mathematical formula====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Math()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Math() can perform mathematical functions from the most simple to very complex. On the face of it, this might not appear to be all that useful, after all, Windows ships with Calc.exe does it not? However, where this comes into its own, is that the numbers to be used for the math formula can be derived from expressions nested within the Math() function, and now this particular function gets a little more interesting.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Math(Formula to evaluate)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''math(10+4)'''<br>''This will return the answer, 14. Hardly earth shattering, but demonstrates the function working at its simplest level.


<br>'''math(10+2*25)''' & '''math((10+2)*25)'''<br>''The results here are 60 & 300 respectively, demonstrating that the math() function correctly honours the priorities of mathematical operators.''
===Left(...) and Right(...): Retrieves specified number of characters from the left(right) of a value===
'''value:''' the value to get characters from<br>
'''characters:''' the number of characters to get


<br>'''listitem([filename (path)],<ins>''math(listcount([filename (path)],\)-1)''</ins>,\)'''<br>''Here, a combination of math() and [[#ListCount(...): Returns the number of items in a delimited list|ListCount()]] are used to generate the number required by the [[#ListItem(...): Returns a specified value from a delimited list|ListItem()]] function. The math function has been asked to subtract 1 from the number returned by the ListCount() function, and the result is then used by ListItem to output its result, which in this case, would be the parent folder name for the specific file.''
Examples:
Left(Abba, 2)
Left([Artist], 3)
Right([Album],4)


<br>'''MEDIA CENTER and "Zero = Null"'''<br>MEDIA CENTER makes special use of the number zero in integer fields. All of that, and the work around to use, can be found in <ins>[http://yabb.jriver.com/interact/index.php?topic=58110.0 this topic]</ins>.
===Length(...): Returns the number of characters in a value===
|}
'''value:''' the value to get number of characters from<br>
<div style="text-align:right;">([[#top|Back to top)]]</div>
'''characters:''' the number of characters to get
====Hexify(...): Hexifies a string to make it suitable for website usage====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Hexify()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | ''The only place this function is likely to be used is in the "Link Manager". Websites often don't like spaces in their addresses, and punctuation could confuse a site's search engine. Hexify attempts to take care of this by replacing spaces and punctuation with web friendly alternatives. For example, Bob Dylan would become Bob%20Dylan.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Hexify(Value to hexify)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''hexify([artist] - [album])'''<br>Oasis - (What's The Story) Morning Glory? becomes: ''Oasis%20-%20%28What%27s%20The%20Story%29%20Morning%20Glory%3F''
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====CustomData(...): Sequence numbering when renaming files====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | CustomData()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | The official description for this function goes as follows: ''"Returns custom data stored in a file array (used primarily for internal uses)."'' There is no recorded practical use for this function, with the exception of using it with a hash symbol in the library tool called "Rename, Move, & Copy Files...". When used in the directory or filename rules of this tool, this function will number the files in the list from first to last, starting at number one. As long as any desired numbering is to begin at one, this function is a reasonable alternative to combat the wierdness demonstrated by the [[#Counter(...): Counts upwards in specified increments|Counter()]] function, and could be particularly useful when renaming image files. If the numbering is required to start counting from anywhere other than one, then [[#Counter(...): Counts upwards in specified increments|Counter()]] will need to be used, taking the wierdness and its work arounds into account.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''CustomData(#)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''[[#PadNumber(...): Adds leading zeros to any given number|padnumber]](customdata(#),4)_Christmas Party 2007'''<br>''It's important to remember that this function will only work when used as part of the renaming rule for either filename or directory (or both) within the "Rename, Move, & Copy Files..." tool. In this example, imagine 324 photos from the Christmas party of 2007 were selected for renaming, and this expression was entered into the filename field. The resulting filenames would be 0001_Christmas Party 2007.jpg through to 0324_Christmas Party 2007.jpg. Note how the "[[#PadNumber(...): Adds leading zeros to any given number|padnumber()]]" function has been used to add the leading zeros.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Tag(...): Returns a physical file tag (rather than looking in the database)====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Tag()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function originally came into being as a need arose for there to be a way to re-import the exif date information from image files without affecting any other tags. To that end, the function works well, but that's really where it's functionality ends. Success with any other fields has been extremely limited indeed. The main reason for this is because, when using this function to query specific tag data blocks in an image file, the fields referenced by the tag() function must be spelled ''exactly'' as they appear in the tag block within the file, and yes, they ''are'' case sensitive. It is also extremely important to know that when building a file list that contains a "Tag()" derived column, MEDIA CENTER will be inordinately slower, <ins>1000's of times slower</ins>, in building that list than it would be without the "Tag()" column. This is because each and every file in the list must be queried individually for the contents of the specified tag. This particular function is best used using the "inline editing" method outlined in the "[[#When, Where and How to use expressions|When, Where and How to use expressions]]" section of this page, to pull the desired data into the main library database and then reference the information from the database.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Tag(Field to read from the file)'''<br>Specific tag data blocks from jpg files can also be referenced:<br>'''Tag(Tag Block To Query: Field to read from the tag block)'''


* Field to read from the file: Not case sensitive in all scenarios, but always case sensitive when targetting specific tag data blocks within jpg files.
Examples:
* Tag blocks that can be queried from within jpg files are:
Length(Abba)
** EXIF
Length([Artist])
** XMP
** IPTC
** MJMD
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''tag(artist)'''<br>''This will return the artist information from a file if that file contains the artist tag''


<br>'''tag(Gapless Header)''' or '''tag(Gapless Footer)'''<br>''These two expressions allow gapless information to be queried from mp3 files.''
===ListBuild(...): Build a list from a series of values, possibly suppressing empty items===
'''mode:''' the mode to use when building the list<br>
'''delimiter:''' the delimiter to be used in the list<br>
'''list:''' the list of items (any number)


<br>'''tag(exif: Date)'''<br>''This will return the raw date data from the EXIF data saved inside a jpg file. If this expression is used to import the data into MEDIA CENTER's default [Date] field, MEDIA CENTER will format the info into legible date information automatically. If importing into a custom field, wrap the tag() function inside a [[#FormatDate(...): Formats a date value in a specified manner|FormatDate()]] function like so: '''formatdate(tag(exif: Date),datetime)'''.''<br>''Note that "tag(exif: date)" will not return any result as the tag to query value is case sensitive and must be entered as "Date"''
mode = 0: combine all values
|}
mode = 1: combine non-empty values
<div style="text-align:right;">([[#top|Back to top)]]</div>
====TVInfo(...): Returns television-specific information about a file====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | TVInfo()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Used to retieve and display specified televison information for a file.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''TVInfo(Information to retrieve)'''
'''Information to retrieve''': ''The options available for use here are:''


* '''IsProgram''': ''Tests whether the file is a program or not. (Returns 0 or 1)''
Examples:
* '''IsGuideProgram''': ''Tests whether the file is a guide program or not. (Returns 0 or 1)''
ListBuild(1, ;, a, ,b, ,c)
* '''IsRecordedProgram''': ''Tests whether the file is a recorded program or not. (Returns 0 or 1)''
* '''NameDisplay''': ''Returns the name.''
* '''NameDisplayWithDate''': ''Returns the name + date.''
* '''SeriesDisplay''': ''Returns the series name.''
* '''TimeDisplay''': ''Shows the start time of a program using the system time format, but uses "Showing" if the program is on now.''
* '''TimeDisplayNoOnNow''': ''Shows the start time of a program using the system time format, without special handling for programs on now''
* '''SizeDisplay''': ''Returns the duration, formatted nicely for a television program.''
* '''WatchedDisplay''': ''Watched information, like no, yes, 80%, etc.''


|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''TVInfo(namedisplay)'''<br>Click on "<ins>T</ins>ools > Options > Theater View", then click on "Customize file info panel", then choose "Television Program" from the drop-list at the top. It is then possible to use this function to tailor the information displayed on screen in Theater view when looking at TV programs. Some of the default items already utilise this function offering real world, real time examples of their usage.
* TV programs use the field "Date Recorded" to store the program time.
* The "Date" field is the original air / production date.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Note(...): Retrieve information from a note====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Note()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Since build 14.0.111, [http://yabb.jriver.com/interact/index.php?topic=54548.0 MEDIA CENTER has shipped with a "Notes" feature.] One of the many uses available via notes is the ability to store contact information, and that information can be labelled. Labels are typical contact information labels such as "Home phone", "Work phone", "Email" etc. etc.. This function can retrieve and display the contents of specified labels from a note.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Note(Field Label,Field Type,Occurrance)'''


* '''Field Label''': ''There are too many labels to list here. To see the available labels, select some text in a note and right click that selected text, then hover the cursor over "Set Field" to see the list of available labels.''
===Math(...): Evaluates a mathematical expression===
* '''Field Type''': ''If the specified label was, for example, "Phone", then the "Type" could be "Home" or "Business" or any of the other available "Phone" types. This value is optional, and if not specified, the function will default to the first type encountered.''
'''Expression:''' the expression to evaluate<br>
* '''Occurrance''': ''If a note contained two home phone numbers, they would be "occurrance 0" and "occurrance 1". If "occurrance 1" was required, the function requires this to be specified. This value is optional, and if not specified, the function will default to using zero.''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''note(phone)'''<br>'''note(phone,home)'''<br>'''note(phone,home,1)'''<br>''Here are three sample notes expressions. In the image below, they have been used to create expression list columns, with each expression used shown in the column header. The note, with labels on show, is visible on the right hand end of the image. When comparing the note with the data returned by each expression, it should become apparent how each expression is working.''
[[image:Notes.png|thumb|left|500px|alt=note image|A note + expression columns (''click to enlarge)'']]
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
<br><br>
===Redundant Functions?===
Taken at face value, all of the functions in this section would appear to be a little on the redundant side, falling neatly into the "a long way for a shortcut" category. MEDIA CENTER could possibly rely on these functions internally, exalting their status to "highly useful" or "essential" even, but as this page is designed for end users, not MEDIA CENTER, end users will find these functions redundant, and they are included here in the name of completeness only.
====Field(...): Returns the value of a library field====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Field()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Place the name of any library field inside this function, and it will return the contents of that library field for each file. Entering the field name inside square brackets as normal, without the function, returns the same data.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Field(Field name to retrieve)'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''field(duration)'''<br>''Returns the formatted duration value for each file. '''field(duration,0)''' would return the raw duration data. Simply entering [duration] or [duration,0] returns the same result.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====FilePath(...): Returns the path from a specified filename====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FilePath()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function will return the file path information from root to parent folder for all files in a list, or for any specified file. MEDIA CENTER has a [Filename (Path)] library field by default, which is probably easier to use or reference than this function.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FilePath(Filename to check)'''


* Filename to check ''This is optional. If not specified, the function defaults to the current file.''
Examples:
|- valign="top"
Math(3 + 4)
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
Math((3 + 4) / 2)
|style="background: #ecfeea; color: black; border: 1px solid black" | '''filepath(C:\Music\File.mp3)'''<br>''The result here would be... "C:\Music"''
Math([ListCount([Artists] % 10))
Math((Length([Artist]) + Length([Album]) / 2)
Left([Artist], Math(Length([Artist]) - 1))


<br>'''filepath()'''<br>''Returns the filepath for each file in the list. The [filename (path)] field returns the same information.
===Note(...): Gets information from a note===
|}
'''field:''' the field name<br>
<div style="text-align:right;">([[#top|Back to top)]]</div>
'''type:''' the field type (optional: defaults to any type)<br>
====FileName(...): Returns the name from a specified filename====
'''occurrence:''' the occurrence (optional: defaults to 0)
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FileName()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function will return the file name information for all files in a list, or for any specified file. MEDIA CENTER has a [Filename (Name)] library field by default, which is probably easier to use or reference than this function.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FileName(Filename to check)'''


* Filename to check ''This is optional. If not specified, the function defaults to the current file.''
Examples:
|- valign="top"
Note(Phone)
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
Note(Phone, Work)
|style="background: #ecfeea; color: black; border: 1px solid black" | '''filepath(C:\Music\File.mp3)'''<br>''The result here would be... "File.mp3"''
Note(Phone, Work, 1)


<br>'''filepath()'''<br>''Returns the file name for each file in the list. The [filename (Name)] field returns the same information.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====FileVolume(...): Returns the volume name from a specified filename====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | FileVolume()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function will return the volume name information for all files in a list, or for any specified file. MEDIA CENTER has a [Volume Name] library field by default, which is probably easier to use or reference than this function.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''FileVolume(Filename to check)'''


* Filename to check ''This is optional. If not specified, the function defaults to the current file.''
===TrackNumber(...): ===
|- valign="top"
TBD
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''filevolume(C:\Music\File.mp3)'''<br>''The result here would be... "C:"''


<br>'''filevolume()'''<br>''Returns the file name for each file in the list. The [Volume Name] field returns the same information.
===TVInfo(...): Returns television-specific information about a file===
|}
'''field:''' field to load<br>
<div style="text-align:right;">([[#top|Back to top)]]</div>
'''program:''' whether the file is a program (0 or 1)<br>
====AlbumKey(...): Returns a unique album key for a file====
'''isGuideProgram:''' whether the file is a guide program (0 or 1))<br>
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
'''IsRecordedProgram:''' whether the file is a recorded program (0 or 1)<br>
|- valign="top"
'''NameDisplay:''' name display<br>
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | AlbumKey()
'''NameDisplayWithDate:''' name display with date<br>
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Testing reveals that this function simply returns an "'''[album artist (auto)] - [album]'''" string for each file. If two different albums happen to have the same [album&nbsp;artist&nbsp;(auto)] and [album] data, their respective AlbumKey() will not be unique.
'''SeriesDisplay:''' series display<br>
|- valign="top"
'''TimeDisplay:''' time display<br>
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
'''TimeDisplayNoOnNow:''' time display without special handling for programs on now<br>
| style="background: #ecfeea; color: black; border: 1px solid black" | '''AlbumKey()'''
'''SizeDisplay:''' size display, formatted nicely for a television program<br>
|- valign="top"
'''WatchedDisplay:''' watched information, like no, yes, 80%, etc.<br>
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''AlbumKey()'''<br>''Create a new expression column in a list using this function and the result will be a column populated with the [album artist (auto)] - [album] data for each file.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====AlbumArtist(...): Returns the calculated album artist for a file====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | AlbumArtist()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function simply returns the "'''[album artist (auto)]'''" data for each file.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''AlbumArtist()'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''AlbumArtist()'''<br>''Create a new expression column in a list using this function and the result will be a column populated with the [album artist (auto)] data for each file.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====AlbumType(...): Returns the album type for a file====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | AlbumType()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function simply returns the "'''[album type]'''" for each file. [album type] is a default MEDIA CENTER library field that informs the user of an album's status in the library, such as "Single artist (complete)" or "Multiple artists (incomplete)"
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''AlbumType()'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''AlbumType()'''<br>''Create a new expression column in a list using this function and the result will be a column populated with the [album type] data for each file. The [album type] library field will work just as well, and return the same information.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====Size(...): Returns the size of a file in a media type independent manner====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | Size()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | Dependent on media type, this function returns the following information:


* Audio: ''Duration''
Examples:
* Video: ''Duration''
TVInfo(TimeDisplay)
* Image: ''Dimensions''
* Data: ''No information returned.''


|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''Size()'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''Size()'''<br>''Create a new expression column in a list using this function and the result will be a column populated with media type dependent data for each file as listed in the function description above.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>
====TrackNumber(...): Returns the track # of a file====
{| style="width: 100%; border: 1px solid black" align="top" border="1" cellpadding="3"
|- valign="top"
! scope="row" style="white-space:nowrap; background: #A8E4A0; color: black; border: 1px solid black;" width=100 | TrackNumber()
| style="background: #ecfeea; color: black; border: 1px solid black" width=1200 | This function simply returns the track # of a file. If a file has no track # assigned, the function returns zero.<br>This function has no real use and is actually flagged as "For internal use only", so, not one for end users, and again, only included here for the sake of completeness.
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Construction
| style="background: #ecfeea; color: black; border: 1px solid black" | '''TrackNumber()'''
|- valign="top"
! scope="row" style="background: #A8E4A0; color: black; border: 1px solid black;" | Examples
|style="background: #ecfeea; color: black; border: 1px solid black" | '''TrackNumber()'''<br>''Create a new expression column in a list using this function and the result will be a column populated with the track # information for each file.
|}
<div style="text-align:right;">([[#top|Back to top)]]</div>


[[User:Marko|marko]] 13:20, 7 October 2010 (CDT)
==Notes==
*To use a special character (bracket, parenthesis) as regular text in a function, place a / before it. Change / to // to output an actual slash. Example: Clean([Artist] - [Album] /([Genre]/))
*Case (upper vs. lower) does not matter for function names, field names, and most parameters.
*Spaces are interpreted literally in all areas, except immediately after a comma in a function.
*To specify a data type (for sorting, etc.), add &DataType=[...] to the end of the expression where ... is one of these values:
::String: sorts as strings (with smart number handling)
::List: a list of strings, separated by semicolons
::Number: sorts values as numbers (decimal or integer)
::Path: sorts using a smart filename compare style
::Month: sorts string month names (i.e. January, February, etc.)
Examples:
FormatDate([Date, 0], Month)&DataType=[Month]
*It is possible to use an expression in the search bar (or smartlist or step 4 of the View Scheme Editor). Use the following format:
::[=<type your expression here>]=1 ''(or 0. =1 will return all files for which the expression is true, and =0 will return all files for which it is false.)''
Examples:
[=isequal([people],jane,1)]=1
An interesting point regarding expressions such as this in the search field, is that when using it to match list type fields such as people, the search is an 'exact match' type search, so the results from the above example would only contain pictures of jane on her own.
*It is possible to use an expression when editing values in a file list or in the Tag Action Window. This works like Excel formulas -- simply prepend an equal sign to the front of the edited text and it will be interpreted as an expression. (use '= to output an actual equal)
Examples:
Select 10 files, and in Tag Action Window, edit 'Comment' to be "=[Name] by [Artist]" (Ctrl+Z to undo)


[[Category:Frequently_Asked_Questions]]
[[Category:Frequently_Asked_Questions]]

Revision as of 18:20, 7 October 2010

Using this page

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.
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.
The page contains some references that link to external pages. Such links can be identified by the little square icon that follows them, 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.

(Back to top)

Overview

The J. River Media Core database engine supports Excel-style functions for use in view schemes, searches, displayed columns, and tag editing.

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 here and here. 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.

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.
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.

(Back to top)

When, Where and How to use expressions

The use of expressions in MEDIA CENTER can be broken into three distinct categories:

The implementation of the expression differs between each of these three categories, differences which are outlined below.

(Back to top)

Tag or filename editing

Expressions can be used to simplify the batch editing of file tags, or if required, physical filenames too. It is important to remember that when using expressions in this way, file tags are physically altered, and if the expression is applied to a "filename" field, then the physical name or path of the file will be changed on the hard drive.
Expression functions that are typically used for these kind of tasks are grouped together in the list of functions. The grouping is provided as a rough guide only, as any function that gets the job done can be used.
When using expressions for this kind of task, the expression is either entered into the tag window, or by using inline editing in the file list, and a preceding "=" sign must be inserted to instruct the tagging engine to invoke the expression evaluator, rather than apply the expression as physical tag data. The following screen pictures will help to illustrate using expressions in this way:

Pressing "Enter" copies the Date data into the caption field
Just like that!

Next, using the [filename (name)] field and expressions to directly edit the file name on the hard disk:

Pressing "Enter" renames and renumbers the selected files
Just like that!

Worth noting that any mistakes made using expressions in this way can be undone by pressing Ctrl+Z

(Back to top)

Filtering a list of files using a search rule

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:
[=EXPRESSION]=1 or [=EXPRESSION]=0

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.

Remember that the search field appears in many places throughout MEDIA CENTER, places that include:

  • The search field itself (in the top right corner of the program)
  • 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: [=isequal(formatdate([date imported,0],MM//yyyy),formatdate(now(),MM//yyyy),1)]=1 Which will list all files that have been imported this month.

(Back to top)

Change how existing data is displayed

As well as the search field detailed above, expressions can also be used in many other places within MEDIA CENTER. Places that you might consider using expressions include:

  • The player information bar (right click the information bar, choose "Customize")
  • The image playback caption
  • The "Rename, Move or Copy Files" tool
  • Panes (aka categories)
  • List columns (right click a column header and choose "Add expression column" from the menu)
  • Thumbnail text
  • The library field manager (Create expression based library fields)
  • Theatre View
  • The links manager (Use expressions to format the URLs for your links)

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.

  • For photos and videos, thumbnail text can be extremely useful, with the slight drawback that space there is a bit on the limited side. Using expressions here can be very productive indeed, for example, by using expressions, it is possible to instruct MEDIA CENTER to only display selected data if it actually exists, effectively getting rid of any of those "unknown ..." entries in the list.
  • Expressions can be used in link properties (accessed via the link manager) so that a link will only be displayed if certain criteria are met, helping to keep the links bar uncluttered, populated with just those links that pertain to the current file list or selection. This topic contains a couple of interesting "Link Manager" tips that some might find useful.
  • Some users choose to keep media files stored on drives, or in paths, dependent upon media type. The "Base path", "Directory" and "Filename" fields in the "Rename, Move or Copy Files" all accept expressions, offering the user powerful control over how the tool deals with files, dependent upon how they are tagged.
  • Expressions can be saved as library fields in their own right. See Editable expression fields and this "Eureka moment" for a couple of related tips.
(Back to top)

Specify data types for expression based fields

Now and again (or always, in the case of "List type" expressions), an expression based pane or library field may not sort correctly, or rather, may not sort as desired. Think about things like months... should they be sorted alphabetically or chronologically? They will sort alphabetically by default, so no problems there, but, if a chronological order is required, then a "Data Type" for the expression must be specified. Data types are set by appending the following string to an expression: &datatype=[DATA TYPE], where DATA TYPE is one of the following five values:

  • List: A list of strings, separated by semicolons
  • String: Sorts as strings (with smart number handling)
  • Number: Sorts values as numbers (decimal or integer)
  • 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:

&DataType=[Month] &DataType=[List]
Used in a pane, formatdate([date,0],MMMM) returns the months as requested, but the alphabetic order is a little confusing.
Adding the "month" data type, like so, formatdate([date,0],MMMM)&datatype=[month], takes care of the order.
   
No data type has been specified, so the expression results are presented literally, as individual string values.
Add the "list" data type to the expression and it is then formatted correctly in the pane. Here, the ListBuild function has been used to create a nested browsing tree.
(Back to top)

Fields

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.

Function and field values in expressions are not case-sensitive. Available functions with descriptions and examples are listed below.

(Back to top)

Functions

If(...): Ask closed questions and control output dependent upon result.

If() This will be the function you will likely use more than any other. It is typically used in conjunction with one or more other functions and allows you to give specific instructions depending upon whether the result is positive (1) or negative (0). The positive instruction is always given first.
Construction if(expression to test,instructions if positive,instructions if negative)
Examples if(isequal([artist],bob dylan,1),Genius,Mediocre)
Wherever this expression is applied, be it as an expression column or category, as part of a renaming rule, thumbnail text, if the artist tag is Bob Dylan, MEDIA CENTER will produce Genius, and for all other artists, it will produce Mediocre. The "IsEqual()" function is described in the first table below.


if(isequal([artist],bob dylan,1),Genius,if(isequal([album],Joshua Tree,8),Great Album,Mediocre))
Here, we have two nested "If" functions. First we ask if the artist is Bob Dylan, if the result is positive, write "Genius". If the artist is not Dylan, we then ask if the album is "Joshua Tree", if yes, write "Great Album", and if no, write mediocre


On it's own, "If()" is rather boring and not a lot of use. When used in conjunction with other functions, however, it becomes very powerful indeed. In the two examples above, the numbers 1 and 8 have been used. These are comparison mode switches used by the IsEqual function. There are 9 different compare modes in total, all of which are detailed below. Note how the second example ends with two closing parenthesis, one for each "If" function.

(Back to top)

Query, Test and Compare using "Is" Functions

All of the functions in this section, when used on their own, will only ever return one of two values, 1 (true) or 0 (false). There is a "FormatBoolean()" function that can be wrapped around these and allows us to specify the output for each case and is discussed in more depth in the Format section. The real power and versatility of these "Is" functions is released when they are wrapped inside the If() function discussed above.

IsEqual(...): Compares two values in one of nine specified modes

IsEqual() Compares two values in one of nine specified modes ("exact match", "Is greater than" etc.) and outputs 1 for a positive match and 0 for a negative match. If no compare mode is specified, the compare will default to 0.
Construction isequal(1st value to compare,2nd value to compare,compare mode)

Available Compare Modes:

  • 0: case-sensitive string compare for equality
  • 1: case-insensitive string compare for equality
  • 2: numeric compare for equality
  • 3: numeric less than
  • 4: numeric less than or equal to
  • 5: numeric greater than
  • 6: numeric greater than or equal to
  • 7: substring search (case sensitive)
  • 8: substring search (case insensitive)
Examples isequal([artist],[album],1)
If the 'artist' and 'album' values are the same, the output will be 1, otherwise, the output will be 0.


if(isequal([artist],[album],1),Self Titled,[album])
Wrapped inside an 'If' function, if the 'artist' and 'album' values are the same, the output will be 'Self Titled', otherwise, the output will be the 'album' value.


if(isequal([artist],[album],1),Self Titled/,,[album]/))
This example demonstrates the character 'escaping' mentioned in the overview earlier. Here, we want the output to be either "Self Titled," (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 preceding forward-slash character. This informs the expression evaluator that these characters are not part of the expression syntax and are to be treated literally

(Back to top)

IsEmpty(...): Tests to see if a field is empty

IsEmpty() Tests any given field for data. If the field is empty, the function returns 1, and if populated, the function returns 0. There are two different test modes available, a "string" test, and a "number" test. This is because as far as MEDIA CENTER is concerned, fields designated as containing numerical values that are populated with the number zero, are empty. If no test mode is specified, the function will default to 0.

Pay particular attention to the third example offered below, as it covers a caveat that comes with this particular function.

Construction isempty([field to test],test mode)

Available test modes:

  • 0: String test (field must be empty to get a positive result)
  • 1: Numerical test (field must be empty, or contain 0 to get a positive result)
Examples isempty([comment],0)
If the comment field is empty, this expression will return 1, but if the comment field contains data, the expression will return 0.


isempty([track #],1)
This expression will perform a numerical test for data in the [track #] field. If the field is empty, or contains 0, the expression will return a positive result, 1, otherwise, the result will be negative, 0.


if(isempty([disc #]),,[disc #])
Here, by not entering any instructions to carry out for a positive result, the expression will do just that, and output nothing, but if the [disc #] field does contain data, the expression will write that out. Upon first look, you would think that this could work really well in the "Rename, Move and Copy Files" tool for only creating a \Disc #\ directory if needed. This will not work. When asking the rename tool to create directories from field data, it is smart enough to know that directories with no name are illegal in Windows, so when it encounters an empty field, it automatically converts it to "Unknown [Field Name]". It does this before the expression engine gets to see it, which means that the IsEmpty function will always return a negative result when used in the rename tool, even when the specified field is indeed empty. As we now know that empty fields are passed through the rename tool as "Unknown [field name]" we can use if(isequal([disc #],unknown,8),,[disc #]) to achieve the desired result. Note that this only applies when using the rename files tool.

(Back to top)

IsRange(...): Tests a value for inclusion within a given range

IsRange() IsRange allows us to test if any given field falls inside any given range of values. If the field falls inside the given range, the function returns 1, and if outside the given range, the function returns 0.
Construction IsRange([Field to Test],Specified-Range)

The range to test for can be letters or numbers, separated by a hyphen, without spaces, lowest value first, highest second. Letters and numbers cannot be mixed, the range can only be one or the other

  • 1-100
  • a-z
  • c-d
  • 23-7542
Examples isrange([artist],a-c)
Abba or Blondie will return 1 (positive), and ZZ Top will return 0 (negative).


if(isrange([bitrate],96-191),Poor Quality,High Quality)
This expression will output "Poor Quality" for any file where the bitrate falls between 96 and 191, and "High Quality" for all others. Note that expressions are only as good as the instructions given, and that the above expression would label files with bitrates less than 96kbps as "High Quality". If this expression were used to add a category to a view, there would be two selectable choices in the category, Low Quality, and High Quality. Selecting either one would then filter the file list accordingly.


This post on Interact shows the use of IsRange in a Search List. (right click the link, open in new tab to keep this page open). The expression format in that post shows how to form expressions for use in standard MEDIA CENTER searches, something that was covered earlier on this page.

(Back to top)

IsMissing(...): Tests to see if a file exists on the system

IsMissing() This function checks to see if a file exists on the system. If the file is missing, the function returns 1 (positive), and if the file is found, the function returns 0 (negative). It is possible to specify a specific file to check for, but if you know that much, it will be quicker to fire up explorer and check yourself. This function comes in handy for checking the integrity of your MEDIA CENTER library as you can use it to produce a list of any files in your library that MEDIA CENTER cannot find. However, be aware that the larger your library, the longer this list will take to produce as MEDIA CENTER will need to physically check each files' existance in turn.
Construction IsMissing(Full Path To File)

If no file path is specified, the function will default to checking the current file.

Examples ismissing()
Checks if the current file exists, and returns 1 (positive) if the file does not exist, and 0 (negative) if the file does exist.


ismissing(C:\Music\My Lost File.mp3)
Checks for "My Lost File.mp3" and returns 1 (positive) if the file does not exist, and 0 (negative) if the file does exist.


[=ismissing([filename])]=1
This example also demonstrates how to construct an expression for use as a MEDIA CENTER search string. 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 your library is in good order, this list should be empty. You could also create a view scheme and use this string in the "Set rules for file display" search to give you a view that you can visit periodically to check that your library is intact


if(ismissing(),File is missing,File exists)
Wrapped inside an "If()" function, the expression outputs "File is missing" or "File Exists" depending on the result returned by IsMissing()

(Back to top)

IsRemovable(...): Tests to see if a file is stored on removable media

IsRemovable() Checks to see if a file resides on removable media and if so, returns 1 (positive), and if not, returns 0 (negative). There is not a lot to say about this function, especially since MEDIA CENTER comes equipped with a [Removable] field by default that is automatically populated with 1 for all files in the library that are on removable storage. The function works in exactly the same way as the IsMissing function described above, returning 1 (positive) if the file is on removable storage, and 0 (negative) if not.
Construction IsRemovable(Full Path To File)

If no file path is specified, the function will default to checking the current file.

Examples isremovable()
Checks if the current file is on removable storage, and if so, returns 1 (positive), if not, the function returns 0 (negative).
(Back to top)

IsInPlayingNow & IsPlaying(...): Tests to see if a file is in the Playing Now playlist or currently being played

IsInPlayingNow() These two functions will be dealt with together as from their names, they are self-explanatory. One checks to see if a file has been added to the playing now list in any zone, and the other checks if a file in a list is currently playing or not, in any zone. With this in mind, their most practical use is as expression columns in a file list. To add an expression column to a list, right click on any existing column header and click on the "Add expression column" option.
IsPlaying()
Construction IsInPlayingNow()
Checks the current file, and if in the Playing Now list, returns 1 (positive), and if not, returns 0 (negative).


IsPlaying()
Checks the current file, and if currently playing, returns 1 (positive), and if not, returns 0 (negative).

Examples if(isinplayingnow(),Selected,Not Selected)
As mentioned in the description, the ideal place for these functions is as 'expression columns'. If this example were used in an expression column, then files added to Playing Now will show as "Selected" and all other files would show as "Not Selected". If the idea here is to be able to quickly see which files have been added, this might look a bit 'busy' and defeat the purpose, to which end, it is perfectly acceptable to tell the expression that if a file is not in Playing Now, to output nothing, by simply not giving any instructions for the negative result, like so: if(isinplayingnow(),Selected,). Now, this expression column will only show "Selected" against files that are in Playing Now, leaving all others empty, giving a much easier column to read.


Use IsPlaying in exactly the same way as IsInPlayingNow()


On the Interact support forum, mark_h describes how he puts these two functions to work for him, and rick.ca shows how he tweaked the idea when he answers the question: "is it possible to play an artist's full work when a genre is shuffling?"

(Back to top)



Change how existing data is displayed using Format functions

All of these functions (with the exception of FormatBoolean) take raw data from the library and allow us to present that data in a way that we choose. What does "raw data" mean? MEDIA CENTER stores duration information in seconds and converts that information into hours (if needed), minutes and seconds for display in the Duration column in a file list. Likewise, file size information is stored in bytes and is converted into Mb for display in the file list. Dates are stored using a UNIX system (use google if you want to know more about that) which means that the date field could contain 40121.8272916666683159 and MEDIA CENTER will display that as 04/11/2009 19:51 (if that is how your Windows locale setting displays date and time). So there you have it, raw data. The following section gives some idea of what is possible using the raw data and the Format functions. To instruct the expression evaluator to use raw data, a zero is added to the library field, inside the square brackets, like so: [Date Imported,0]

FormatDate(...): Formats a date value in a specified manner

FormatDate() As mentioned in the section introduction above, MEDIA CENTER stores date information in a UNIX style, and converts that information into legible date/time information we can understand. By default, MEDIA CENTER presents dates using the system locale settings. This function can be applied to any default library field that contains date information in order to have that information displayed in a non-default format.
Construction formatdate([date field,0],Format,Output if date is empty)

Available format choices:

  • Year Returns the full year, i.e. 2010
  • Month Returns the full month, i.e. April, November.
  • Day Returns the day in number format, i.e. 23 (note that single numbers have no leading zero)
  • Filename Returns a filename friendly date format that also includes the seconds information to help avoid file names clashing, i.e. 20040521-032221
  • Elapsed Returns "how long ago" information, i.e. 2.43 Days or 1.85 Years
  • Date Returns the date using the system format on the machine running the expression.
  • DateTime Returns the date and time using the system format on the machine running the expression.
  • hour Returns the hour from dates with time information. (note that single numbers have no leading zero)
  • minute Returns minutes from dates with time information. (note that single numbers have no leading zero)

Flexible formatting is also available: (Note that these are case sensitive)

  • yy Returns the last two digits of the year
  • yyyy Returns the full year
  • MM Returns the month as two digits
  • MMM Returns the month as three letter abbreviations
  • MMMM Returns the month in full
  • dd Returns the day as two digits
  • ddd Returns the day as three letter abbreviations
  • dddd Returns the full day

Output if date is empty: If the date is empty, anything placed here will be output instead. This could be plain text, such as "No Date", or a library field. This value is optional, and if not given, the expression will default to return nothing if the date is empty.

Examples formatdate([last played,0],yyyy//MM//dd,Not Yet)
This will return the last played date as year/month/day without the time, and regardless of the system locale setting. If a file has no last played info, the expression will output "Not Yet" instead.


formatdate([date imported,0],month)
This will return the month a file was imported, written in full. For example, December, as opposed to 12.


formatdate([date imported,0],month)&datatype=[month]
If you were to use the previous expression to create a view category that contained the months your files were imported, it would list the months alphabetically, with April first and September last. Thankfully, we can specify "data types" for expressions which further fine tune how MEDIA CENTER displays the results. In this case, a data type of month has been specified, therefore MEDIA CENTER will list the months in the correct chronological order. Data types were discussed earlier on this page.

(Back to top)

FormatNumber(...): Formats a number to a specified number of decimal places

FormatNumber() FormatNumber() allows to format any given value to a set number of decimal places.
Construction FormatNumber(Value to format,Number of decimal places,Output if value is zero,Label if value is greater than 1,Label if value equals 1)
  • "Value to format" This could be a library field, such as [replay gain] or the result of a Math() expression. Any numerical value you encounter where you would like to limit the number of decimal places displayed can have this function applied.
  • "Number of decimal places" This is optional. If not specified, the function will default to zero decimal places. Use -1 to output as many decimal places as necessary.
  • "Output if value is zero" This is optional. If not specified, the function will return zero.
  • "Label if value is greater than 1" This is optional. If not specified, the function will not return anything, if specified, and the formatted number is greater than 1, the function will return with the number, plus this label.
  • "Label if value equals 1" This is optional, as detailed below..
    • If not specified, but a label for greater than 1 has been specified, then this "greater than 1" label will always be used.
    • If neither are specified, the function will not return anything.
    • If both are specified, and the formatted number equals 1, the function will return with the number, plus this label.

Note that even if you are only interested in applying a label for those results that equal 1, you must also indicate the preceding instructions, if only to instruct the evaluator to ignore them, as shown in the examples below.

Examples formatnumber([duration,0],2)
This will return the duration of a track, in seconds, shown to two decimal places.


formatnumber([number plays,0],0,Not played this one yet,Plays,Play)

  • "0" decimal places has been specified, therefore the result will be a whole number with no decimals shown.
  • If [number plays] is zero, the result will be "Not played this one yet"
  • If [number plays] is greater than 1, lets say 6, the result will be "6 Plays"
  • If [number plays] is 1, the result will be "1 Play"


formatnumber([number plays,0],,,,Time) Here, the function will fall back to its defaults for everything except when the number equals one:

  • No decimal places have been specified, the result will default to a whole number with no decimals shown.
  • If [number plays] is zero, the result will be "0"
  • If [number plays] is greater than 1, lets say 6, the result will be "6"
  • If [number plays] is 1, the result will be "1 Time"
(Back to top)

PadNumber(...): Adds leading zeros to any given number

PadNumber() This function is not a 'Format' function by name, but is by nature, hence its inclusion in this section. PadNumber is a nice, simple function that is used to add leading zeros to any given number value.
Construction PadNumber(Field to pad,Total number of digits required)
Examples padnumber([track #],2)
This will add a leading zero to all track numbers between one and nine.


padnumber(counter(),4)
here, the output from the counter() function will be 'padded' to 4 characters: 0001, 0002, 0003, etc. etc.

(Back to top)

FormatDuration(...): Presents a duration of seconds in a reader friendly format

FormatDuration() MEDIA CENTER stores duration data in seconds, at up to sixteen decimal places. The value shown in the default "Duration" column in a file list is an internally formatted interpretation of this raw "Duration" data. As MEDIA CENTER automatically applies this formatting for us, there is not a lot of call for this particular function.
Construction FormatDuration(Value to format)

"Value to format" can be either the raw duration data, or a given number of seconds

Examples formatduration([duration,0])
This expression will duplicate the contents of the default [duration] field as shown in a file list


formatduration(600)
This will output ten minutes in the format 10:00

(Back to top)

FormatFileSize(...): Presents a number of bytes in a reader friendly format

FormatFilesize() MEDIA CENTER stores file size data internally in bytes. This function will convert those byte values into reader-friendly values, 3.2 Kb or 10.4 Mb, for example. The function will also accept a byte value directly.
Construction FormatFileSize(Value to format)

"Value to format" can be either the raw [File Size] data or a given number of bytes.

Examples formatfilesize([file size,0])
This expression will duplicate the contents of the default [file size] field as shown in a file list


formatfilesize(56123456)
This expression will convert 56,123,456 bytes and the output will be 53.5 MB

(Back to top)

FormatRange(...): Formats a value as a range

FormatRange() This function places any given value into its place in any given range.
Construction FormatRange(Value to format,Range size,Mode)

Value to format: This could be a specific word or number, or any library field
Range Size: A numerical value dependent on how you wish to set up your range. If not specified, this will default to 1
Mode: There are three possible modes, detailed below. If not specified, this will default to zero.

  • 0: Automatically choose between number / letter grouping
  • 1: Specifies that letter grouping should be used
  • 2: Specifies that number grouping should be used
Examples formatrange([artist])
This will return the first letter from the [artist] field. Note that as range size and mode values were not specified, the function defaulted to one and automatic respectively.


formatrange([artist],3,1)
This will take the first letter from the artist field and place it in the appropriate letter range. In this case, a range size of three has been specified, therefore the output will be in the form of "a-c", "d-f", "g-i" etc. etc.


formatrange([bitrate],100,2)
This will take the bitrate and place it in the appropriate number range. In this case a range of 100 has been specified, therefore the output will be in the form of "0-99", "100-199", "200-299" etc. etc.

Note that this function always starts number ranges from zero, 0-9, 10-19, etc, etc.. If you really need a number grouping that starts from 1, 1-10, 11-20, 21-30,etc. etc., you can use expressions to create a pseudo range. Full details, with a helpful explanation, of "1 based grouping" can be found on this page.

(Back to top)

FormatBoolean(...): Formats a boolean (true / false) value in a specified manner

FormatBoolean() This function is wrapped around another function and will return specified strings for true and false values returned by that other function.
Construction FormatBoolean(True/False Test,String to use if true,String to use if false)
  • True/False Test Other functions perform their respective tests and return 1 to indicate a true result, and 0 to indicate a false result
  • String to use if true,String to use if false If these are not specified, the function will default to using "True" and "False"
Examples formatboolean(isempty([number plays]),Never Played,Has Been Played)
On it's own, the function isempty([number plays]) will return either 1 or 0. When wrapped inside a formatboolean function as shown here, the output for a true result will be "Never Played", and for a false result, the output will be "Has Been Played".


formatboolean(isempty([number plays]))
Here, there are no strings specified for the true/false results, therefore the function will default to using "True" and "False"

(Back to top)



Functions for filename and field manipulation

The primary use of the functions in this section is to manipulate the data associated with any given file or files. When used with direct editing in the file list, or in the action window, as decribed here, they offer extremely fast and efficient methods for batch editing the actual tag data associated with multiple files.
Note that when used indirectly, in expression based columns, categories or library fields, the referred fields are not altered in any way, the data is merely presented in the expression field formatted as requested.

Clean(...): Returns a cleaned up version of a filled in template

Clean() The official description for this function is simply "Returns a cleaned up version of a filled in template". This function is better explained through demonstration in the examples below.
Construction Clean(template to clean)
Examples Clean([Artist] - [Album] /([Genre]/))
  • First of all, note that this example uses the "forward slash" escaping, as discussed in the Expressions Overview earlier. The result here will be that the [Genre] will be returned wrapped in parenthesis. Without the escaping, the function would fail as the evaluator attempts to read the parenthesis as an integral part of the expression.
  • Imagine the template without the Clean() function around it. [Artist] - [Album] /([Genre]/)
    If used as an expression, this string, quite predictably, will return things such as: "AC/DC - Back In Black (Rock)", but, what if one or more of the specified fields contains no data? The result would be rather untidy, such as: "- Back In Black ()" if there were no [artist] or [genre] data.
    Wrap the template inside the Clean() function to tidy these cases up, so, "- Back In Black ()" would become "Back In Black"
(Back to top)

FixCase(...): Changes the case of a given string

FixCase() This function will output any given text string in one of five specified case modes.
Construction FixCase(String to modify,Case mode to apply)
The "String to modify" can be plain text, a library field, or a combination of the two.

The five modes available are:

  • 0: Title Case
  • 1: All Words
  • 2: First word
  • 3: ALL UPPERCASE
  • 4: all lowercase

If no case mode is specified, the function will default to using "Title Case". Title case will start each principal word with a capital. More detail regarding title case can be found here

Examples fixcase([album])
This will take the contents of the [album] field and present it with the specified capitalisation. As there is no specified mode here, the function defaults to 0, so, if an album is entered in the library as "Time Out Of Mind", the function will return "Time Out of Mind" (note the lower case "of")


fixcase(MY ALbUm IS cAlLeD [album],4)
This would return "my album is called time out of mind"

(Back to top)

Length(...): Returns the number of characters in a string

Length() This function returns the number of characters in any given string.
Construction Length(String to count characters from)
The "String to count characters from" can be plain text, a library field, or a combination of the two.
Examples length([filename])
This will count the characters in the [filename] field and return the result. Spaces count as characters, so, C:\My File.mp3 would return 14.


if(isequal(length([filename]),68,6),68 Characters or more,Less than 68 Characters)
Here, Length() has been combined with another two functions, "If()" and "IsEqual()". The expression compares the length of the filename against the number 68. If there are 68 or more characters in the filename, the expression will return "68 Characters or more", otherwise, it will return "Less than 68 Characters". If you are working with a device with filename length limitations, these functions can be used to create extremely useful expressions that could help with your device management.

(Back to top)

Left(...): Retrieves a specified number of characters from the left of a value

Left() This function retrieves a specified number of characters from the left of any given value.
Construction Left(Value to get characters from,Number of characters to get)
"Value to get characters from" can be plain text, a library field, or combination of both. If more characters than exist are requested, all available characters are returned.
Examples left([filename],3)
This will return the drive letter, colon and first back-slash from the filename. If asked to show more characters than actually exist, the expression will return the entire value, also, remember that spaces count as characters too.
(Back to top)

Right(...): Retrieves a specified number of characters from the right of a value

Right() This function retrieves a specified number of characters from the right of any given value.
Construction Right(Value to get characters from,Number of characters to get)
"Value to get characters from" can be plain text, a library field, or combination of both. If more characters than exist are requested, all available characters are returned.
Examples right([filename],3)
This will return the last three characters from the filename. If asked to show more characters than actually exist, the expression will return the entire value, also, remember that spaces count as characters too.
(Back to top)

RemoveLeft(...): Trims characters from the start of a value

RemoveLeft() The output from this function will remove a specified number of characters from the start of any given value.
Construction RemoveLeft(Value to remove characters from,Number of characters to remove)
Examples removeleft([name],5)
This would show the name field, with the first five characters removed. If asked to remove more characters than actually exist, the output will be blank, also, remember that spaces count as characters too..
(Back to top)

RemoveRight(...): Trims characters from the end of a value

RemoveRight() The output from this function will remove a specified number of characters from the end of any given value.
Construction RemoveRight(Value to remove characters from,Number of characters to remove)
Examples removeright([name],5)
This would show the name field, with the last five characters removed. If asked to remove more characters than actually exist, the output will be blank, also, remember that spaces count as characters too..
(Back to top)

Mid(...): Retrieves specified characters from a value.

Mid() Mid() retrieves a specified number of characters from a specified starting point in any given string.
Construction Mid(Value to get characters from,Character to start at,Number of characters to get)
  • Value to get characters from: This can be a library field, plain text, or a combination of both.
  • Character to start at: This is a numerical pointer, and rather confusingly, the function treats the first character as zero and begins from there. If not specified, the function will default to zero.
  • Number of characters to get: If this value is not specified, the function will default to 1. -1 can be used to retrieve all available characters after the specified start point.
Examples mid(12345)
As values for "Character to start at" and "Number of characters to get" have not been specified, they default to 0 and 1 respectively and the function returns the first character in the string, 1.


mid(12345,1,2)
The start point has been specified as the second character in, and 2 characters have been asked for, the result here will be 23.


An example of Mid() being used to re-order a date field was given in answer to the question "Can I include seconds in "import date"?"

(Back to top)

Replace(...): Replace or remove strings from a value.

Replace() Quite simply, this function allows to search for a specified string in a specified value, and if found, remove the specified string, or replace it with another.
Construction Replace(Value to check,String to check for,String to replace with)
  • Value to check: This can be plain text, a library field, or combination of both.
  • String to check for: Note that this check is case-sensitive
  • String to replace with: Any instance of the "String to check for" will be replaced by this string. If not specified, any instance of the "String to check for" will be removed.
Examples replace(My Sample String,S,Replaced )
All instances of upper-case "S" will be replaced by the text "Replaced ", (note the trailing space), resulting in "My Replaced ample Replaced tring"


replace(My Sample String,s,Replaced )
The "Value to check" does not contain any lower-case "s", resulting in unchanged output, "My Sample String"


replace(My Sample String,/ Sample,stic)
In this example, the space preceding the word Sample is to be included in the "String to check for". Remembering that, as discussed in the Overview, spaces that follow a comma are ignored unless escaped, an escaping forward slash is used to force the inclusion of the space in the check. The result here will be "Mystic String".

(Back to top)

Counter(...): Counts upwards in specified increments

Counter() This function can be used to number objects sequentially, from a specified starting point, in specified increments. The counter resets itself to zero after five seconds of inactivity.
Counter() can exhibit a touch of wierdness when used in certain situations, which will be covered in the examples, that demonstrate why this one is not really a 'fits all' function.
Construction Counter(Number to start counting from,Increments to count up in)
  • Number to start counting from: This is optional. If not specified, the counter will start from one. If specified, the start value is inclusive, meaning that if a start value of five is specified, the first value the function returns will be five.
  • Increments to count up in: This optional. If not specified, the counter will count up in increments of 1
Examples counter()
This shows the function in its simplest form. The counter will start at one and count upwards in increments of 1.


padnumber(counter(370,2),4)
This expression shows a combined use of functions. Counter() will count up, in two's, starting from 370, and the padnumber function will pad the results to four figures, giving output values of 0370, 0372, 0374, etc. etc..


Weirdness
Counter() works really really well, and really really efficiently when used to sequentially number static data fields. It is not designed to be used in a dynamically changing expression column in a file list. To demonstrate this, right click on a list column header and choose the option to "Add expression column". Use the first, simple expression above, and press OK. The column is presented and all the items in the list are now numbered in this column, but, see what happens when you run the cursor up and down the list? The counter function just keeps on going and going. Right click on the expression column header, and it will appear at the top of the selectable columns list with a tick beside it, click on it to remove the column. This same anomally appears when counter() is used in the "Rename, Move and Copy Files" tool. There may be a possible solution to this effect as seen in the renaming tool by using the CustomData(#) function, but only if the count is to start from 1.
Some interesting reading regarding the use of Counter() can be found in answer to "how to fill the NAME field with incrementing numbers?" and "Prepending a consecutive number to titles as I copy them from MC13 to mp3 player".

(Back to top)



Functions for the manipulation and creation of list type fields

The default MEDIA CENTER library contains many fields that are referred to as "list type" fields. Users are also able to add their own "list type" fields to their libraries. A list type field contains one or more text items seperated by semi-colons. The semi-colons are referred to as the 'delimiter' and when displayed in a view category, text items seperated by semi-colons are displayed in a list of seprately selectable items. The "Keywords" field is a classic example of a list type field, which demonstrates how list type fields allow a single file to be tagged with many different keywords, as opposed to a 'standard' field, such as 'Genre', where a single file can only be tagged with a single genre. The following functions provide the ability to combine or build custom list type fields using the default semi-colon delimiter, or a specified delimiter, count the number of items contained in a given list, or extract a numbered entry from within a list. Two of the functions listed in this section are used to create "list type" data from two or more existing sources and could reasonably be considered to be functions more suited to those who are very familiar with MEDIA CENTER and how it gets its job done. If these functions are used to create a new 'calculated data' library field, they will not function as 'list type' fields unless the field is first created as a "User Data" field, with "List Type" specified. After creating the field in this way, it is possible to go back and edit the field, changing it to "calculated data" and entering an expression to be used. The "Eureka moment" occurred in November 2009.

ListBuild(...): Build a list from a series of values

ListBuild() This function provides the ability to create a single list from many different sources and allows a list delimiter to be specified. It has two modes that can be applied and are detailed below. Of these two modes, mode "0" (Combine all values) should be avoided. It has been included for 'function completeness' only, and when used, can produce some very strange results that do not filter as expected. In order for the data generated by this function to be treated as list data, the 'datatype' must be specified as [list].
Construction ListBuild(Mode,Delimiter,Items,To,Include)

Mode: There are two different modes available:

  • 0: combine all values. NOTE: This mode should be avoided as there is no recorded practical use for it, and it's behaviour can be unpredictable.
  • 1: combine non-empty values

Delimiter: The character used here will be used as a delimiter between each of the specified list items. To be clear, the keywords field uses a semi-colon delimiter by default; if a list is built using keywords and genre, and the specified delimiter is a back slash, it will be used between the keywords and genre fields when joining them, the semi-colons in the keywords field would not be altered. For example, if [keywords] contained "these;are;keywords" and [genre] contained "Rock", and these two were joined using ListBuild with a "\" specified as the delimiter, the resulting data would be "These;are;keywords\Rock". The real beauty and power of this function can be released when expressions are nested into the ListBuild instructions. For example, "listbuild(1,\,replace([keywords],;,\),[genre]" would return the data "These\are\keywords\Rock"
Items To Include: This can be any number of specified text entries, expressions, or library fields, seperated by commas

Examples listbuild(1,;,[keywords],[genre])&datatype=[list]
This will return a semi-colon delimited list containing all keywords and genres. If either keyords or genre is empty, they will be ignored, so, the data returned for a file with no keywords, and a genre of "Rock" would be simply "Rock".


listbuild(1,\,[genre],[album artist (auto)],[album])&datatype=[list]
When MEDIA CENTER encounters a back slash character in a list type field, it 'nests' the data in the list. Think of this in exactly the same way as Windows reads file paths, each back slash is another folder along the file path, and in a MEDIA CENTER list type view category, each back slash creates a virtual folder, and each semi-colon starts a new list entry, which means that effective browsing trees can be created using this knowledge. In the example shown here, a list of genres would be created, and each genre is able to be expanded to reveal a list of artists, which in turn can be expanded to reveal albums by that particular artist in that genre. So, now that this is getting interesting, there's an issue with this example. If a file has no specified [genre], the value is ignored, and the [album artist (auto)] value is placed on the root of the virtual tree, which means that the completely collapsed list contains a mixture of [genre] and [album artist (auto)]. The next example demonstrates how to clean that up.


listbuild(1,\,if(isempty([genre]),!No Genre Applied,[genre]),[album artist (auto)],[album])&datatype=[list]
Here, the previous example has been improved by nesting an IsEmpty() function into the listbuild function. The result is that all files without a specified genre are placed in a group at the top of the virtual tree called "!No Genre Applied", and the rest of the root consists of existing genre values, which is much tidier.

(Back to top)

ListCombine(...): Combines two delimited lists into a single delimited list

ListCombine() Unlike the ListBuild function above, which can be used to create a list from any number of varying sources, ListCombine() is used to merge two specified lists into one. In order for the data generated by this function to be treated as list data, the 'datatype' must be specified as [list].
Construction ListCombine(First list,Second list,Input Delimiter,Output Delimiter)

First List and Second List are specified library fields.

Input Delimiter: This is the value that will be used to join the two specified lists. The value is optional, and if not specified, the function will default to using a semi-colon.

Output Delimiter: This value is also optional. If specified, the function parses the output list (the result of the two lists, joined by the input delimiter) and replaces each occurrence of the input delimiter with the specified output delimiter.

Examples listcombine([people],[places])&datatype=[list]
The result here would be a single, semi-colon delimited list containing all the values from the [people] and [places] fields.
  • [people] contains Family\Mum;Family\Dad;Family\Gran
  • [places] contains United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle
  • The output list from the above expression would be: Family\Mum;Family\Dad;Family\Gran;United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle (the specified "listcombine delimiter" shown in bold and underlined)


listcombine([people],[places],\)&datatype=[list]
Here, the resulting list will be the [people] and [places] lists joined using a back slash. Remember that MEDIA CENTER interprets back slashes as a folder hierarchy when displaying list type fields in a view category pane.

  • [people] contains Family\Mum;Family\Dad;Family\Gran
  • [places] contains United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle
  • The output list from the above expression would be: Family\Mum;Family\Dad;Family\Gran\United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle (the specified "listcombine delimiter" shown in bold and underlined)


listcombine([people],[places],\,;)&datatype=[list]
Finally, a semi-colon output delimiter has been specified, therefore, all back slashes will be replaced by semi-colons, and the resulting list will be a single, flat list containing all the text entries from each field:

  • [people] contains Family\Mum;Family\Dad;Family\Gran
  • [places] contains United Kingdom\Scotland\Edinburgh;United Kingdom\Scotland\Edinburgh\Edinburgh Castle
  • The output list from the above expression would be: Family;Mum;Family;Dad;Family;Gran;United Kingdom;Scotland;Edinburgh;United Kingdom;Scotland;Edinburgh;Edinburgh Castle (the specified "listcombine delimiter" shown in bold and underlined)
(Back to top)

ListCount(...): Returns the number of items in a delimited list

ListCount() ListCount is used to return the number of items that exist in any given field, using any given delimiter.
Construction ListCount([Field to count],Delimiter to use)

Field to count: Typically, this will be a list type field, but this is not compulsory. The data in any field can be parsed using any chosen delimiter

Delimiter to use: This is optional. If not specified, the function will default to using a semi-colon delimiter. Anything can be specified as a delimiter, from a single character to a whole word or words.

Examples listcount([People])

No delimiter has been specified here, therefore the function will default to using a semi-colon. The result here will match the number of people shown in a properly tagged photo. Note that the function is smart, so, if a file has no [People] tag, the function will return zero (0), and if it has [People] data, but no semi-colon, the function will return one (1).


listcount([filename (path)],\)
This function can be used to count the directories in a filepath by specifying a back slash as the delimiter.


listcount([keywords],!People)
This basic expression can be used as a building block to create a more complex expression to count the number of people tagged in a photo. the full expression can be seen here. That thread is actually the release thread for the 'new' nesting feature, introduced in 2007, and although 2 pages long, is worth a read as it contains some quite useful information.

(Back to top)

ListItem(...): Returns a specified value from a delimited list

ListItem() This function numbers list items starting from zero and returns the value of a specifically numbered item.
Construction ListItem([Field],Number of item to retrieve,Field delimiter to use)
  • Field: The function will accept any given field, though is more typically used with list type fields.
  • Number of item to retrieve: The number of the item in the list to retrieve. The list items are numbered starting from zero.
  • Field delimiter to use: This is optional. If not specified, the function will default to using a semi-colon delimiter. Anything can be specified as a delimiter, from a single character to a whole word or words.
Examples listitem([filename],0,\)
This function will return a file's drive letter plus colon. Note that the same result could be achieved by using left([filename],2), there is no 'right' or 'wrong' with these things, just personal preference, or 'what works for you'. A good rule of thumb is to use the simplest possible way to get to your goal, as less typing is better, and the more simple the expression, the easier it is to follow.


listitem([filename],2,\)
Here, the result will be the name of the second directory along a file's folder path from the drive root. C:\Folder1\Folder2\ are itemised as 0\1\2\, so rather confusingly, the second directory is actually the third item in the back slash delimited path.


listitem([filename (path)],math(listcount([filename (path)],\)-1),\)
This expression uses the math() and listcount() functions to find the "Number of item to retrieve" value. listcount() returns the total number of directories in the path, and the math function subtracts one from this number (because listcount() starts counting at one, but listitem starts counting from zero), this number is then used by the listitem function. The result will be the name of the parent folder of each file. Setting the expression up in this way means that the result will always be reliable regardless of the number of folders in the filepath as the expression will work all of this out for itself.

(Back to top)



Functions that perform specific tasks

The functions in this group, with the possible exception of the math() function, are used to carry out very specific tasks, or for use in very specific areas of MEDIA CENTER.

Now(...): Retrieve and display the system date

Now() Now() will return the raw system date. "raw" data is discussed in the Field description, and also in the introduction to the "Format" functions. As MEDIA CENTER's raw date data is illegible, this function needs to be used with the "FormatDate()" function, which allows the current date, and time, if desired, to be presented in many different styles.
Construction Now()
Examples formatdate(now(),date)
Returns the current date, without the time, formatted according to the system settings on which the function is running.


formatdate(now(),dddd dd MMMM yyyy) padnumber(formatdate(now(),hour),2):padnumber(formatdate(now(),minute),2)
Here, three seperate expressions have been strung together to return a fully formatted current date and time: Sunday 26 September 2010 14:04


[=isequal(formatdate([date imported,0],MM//yyyy),formatdate(now(),MM//yyyy)]=1 ~sort=[Date Imported]-d
MEDIA CENTER comes with a stock smartlist titled "Imported This Month". On the face of it, this could be a handy list of files, but is actually rather misleading. Closer inspection of this stock smartlist reveals that it is not actually listing files "Imported This Month", but instead, listing those files that have been imported in the past 31 days by using the following rule: [Date Imported]=<31d ~sort=[Date Imported]-d
This would mean that if you were to view that list on the second of March, you could potentially be looking at a list of files imported during three different months. The example in bold above corrects this anomaly by comparing the month/year imported with the current month/year, and only lists the file if the two match.
This is also an example of how to use an expression in a search rule, as detailed in "When, Where and How to use expressions"


This topic expands on the example above a little by showing how to construct rules that return files that have been played or imported today or yesterday.

(Back to top)

Math(...): Evaluates a given mathematical formula

Math() Math() can perform mathematical functions from the most simple to very complex. On the face of it, this might not appear to be all that useful, after all, Windows ships with Calc.exe does it not? However, where this comes into its own, is that the numbers to be used for the math formula can be derived from expressions nested within the Math() function, and now this particular function gets a little more interesting.
Construction Math(Formula to evaluate)
Examples math(10+4)
This will return the answer, 14. Hardly earth shattering, but demonstrates the function working at its simplest level.


math(10+2*25) & math((10+2)*25)
The results here are 60 & 300 respectively, demonstrating that the math() function correctly honours the priorities of mathematical operators.


listitem([filename (path)],math(listcount([filename (path)],\)-1),\)
Here, a combination of math() and ListCount() are used to generate the number required by the ListItem() function. The math function has been asked to subtract 1 from the number returned by the ListCount() function, and the result is then used by ListItem to output its result, which in this case, would be the parent folder name for the specific file.


MEDIA CENTER and "Zero = Null"
MEDIA CENTER makes special use of the number zero in integer fields. All of that, and the work around to use, can be found in this topic.

(Back to top)

Hexify(...): Hexifies a string to make it suitable for website usage

Hexify() The only place this function is likely to be used is in the "Link Manager". Websites often don't like spaces in their addresses, and punctuation could confuse a site's search engine. Hexify attempts to take care of this by replacing spaces and punctuation with web friendly alternatives. For example, Bob Dylan would become Bob%20Dylan.
Construction Hexify(Value to hexify)
Examples hexify([artist] - [album])
Oasis - (What's The Story) Morning Glory? becomes: Oasis%20-%20%28What%27s%20The%20Story%29%20Morning%20Glory%3F
(Back to top)

CustomData(...): Sequence numbering when renaming files

CustomData() The official description for this function goes as follows: "Returns custom data stored in a file array (used primarily for internal uses)." There is no recorded practical use for this function, with the exception of using it with a hash symbol in the library tool called "Rename, Move, & Copy Files...". When used in the directory or filename rules of this tool, this function will number the files in the list from first to last, starting at number one. As long as any desired numbering is to begin at one, this function is a reasonable alternative to combat the wierdness demonstrated by the Counter() function, and could be particularly useful when renaming image files. If the numbering is required to start counting from anywhere other than one, then Counter() will need to be used, taking the wierdness and its work arounds into account.
Construction CustomData(#)
Examples padnumber(customdata(#),4)_Christmas Party 2007
It's important to remember that this function will only work when used as part of the renaming rule for either filename or directory (or both) within the "Rename, Move, & Copy Files..." tool. In this example, imagine 324 photos from the Christmas party of 2007 were selected for renaming, and this expression was entered into the filename field. The resulting filenames would be 0001_Christmas Party 2007.jpg through to 0324_Christmas Party 2007.jpg. Note how the "padnumber()" function has been used to add the leading zeros.
(Back to top)

Tag(...): Returns a physical file tag (rather than looking in the database)

Tag() This function originally came into being as a need arose for there to be a way to re-import the exif date information from image files without affecting any other tags. To that end, the function works well, but that's really where it's functionality ends. Success with any other fields has been extremely limited indeed. The main reason for this is because, when using this function to query specific tag data blocks in an image file, the fields referenced by the tag() function must be spelled exactly as they appear in the tag block within the file, and yes, they are case sensitive. It is also extremely important to know that when building a file list that contains a "Tag()" derived column, MEDIA CENTER will be inordinately slower, 1000's of times slower, in building that list than it would be without the "Tag()" column. This is because each and every file in the list must be queried individually for the contents of the specified tag. This particular function is best used using the "inline editing" method outlined in the "When, Where and How to use expressions" section of this page, to pull the desired data into the main library database and then reference the information from the database.
Construction Tag(Field to read from the file)
Specific tag data blocks from jpg files can also be referenced:
Tag(Tag Block To Query: Field to read from the tag block)
  • Field to read from the file: Not case sensitive in all scenarios, but always case sensitive when targetting specific tag data blocks within jpg files.
  • Tag blocks that can be queried from within jpg files are:
    • EXIF
    • XMP
    • IPTC
    • MJMD
Examples tag(artist)
This will return the artist information from a file if that file contains the artist tag


tag(Gapless Header) or tag(Gapless Footer)
These two expressions allow gapless information to be queried from mp3 files.


tag(exif: Date)
This will return the raw date data from the EXIF data saved inside a jpg file. If this expression is used to import the data into MEDIA CENTER's default [Date] field, MEDIA CENTER will format the info into legible date information automatically. If importing into a custom field, wrap the tag() function inside a FormatDate() function like so: formatdate(tag(exif: Date),datetime).
Note that "tag(exif: date)" will not return any result as the tag to query value is case sensitive and must be entered as "Date"

(Back to top)

TVInfo(...): Returns television-specific information about a file

TVInfo() Used to retieve and display specified televison information for a file.
Construction TVInfo(Information to retrieve)

Information to retrieve: The options available for use here are:

  • IsProgram: Tests whether the file is a program or not. (Returns 0 or 1)
  • IsGuideProgram: Tests whether the file is a guide program or not. (Returns 0 or 1)
  • IsRecordedProgram: Tests whether the file is a recorded program or not. (Returns 0 or 1)
  • NameDisplay: Returns the name.
  • NameDisplayWithDate: Returns the name + date.
  • SeriesDisplay: Returns the series name.
  • TimeDisplay: Shows the start time of a program using the system time format, but uses "Showing" if the program is on now.
  • TimeDisplayNoOnNow: Shows the start time of a program using the system time format, without special handling for programs on now
  • SizeDisplay: Returns the duration, formatted nicely for a television program.
  • WatchedDisplay: Watched information, like no, yes, 80%, etc.
Examples TVInfo(namedisplay)
Click on "Tools > Options > Theater View", then click on "Customize file info panel", then choose "Television Program" from the drop-list at the top. It is then possible to use this function to tailor the information displayed on screen in Theater view when looking at TV programs. Some of the default items already utilise this function offering real world, real time examples of their usage.
  • TV programs use the field "Date Recorded" to store the program time.
  • The "Date" field is the original air / production date.
(Back to top)

Note(...): Retrieve information from a note

Note() Since build 14.0.111, MEDIA CENTER has shipped with a "Notes" feature. One of the many uses available via notes is the ability to store contact information, and that information can be labelled. Labels are typical contact information labels such as "Home phone", "Work phone", "Email" etc. etc.. This function can retrieve and display the contents of specified labels from a note.
Construction Note(Field Label,Field Type,Occurrance)
  • Field Label: There are too many labels to list here. To see the available labels, select some text in a note and right click that selected text, then hover the cursor over "Set Field" to see the list of available labels.
  • Field Type: If the specified label was, for example, "Phone", then the "Type" could be "Home" or "Business" or any of the other available "Phone" types. This value is optional, and if not specified, the function will default to the first type encountered.
  • Occurrance: If a note contained two home phone numbers, they would be "occurrance 0" and "occurrance 1". If "occurrance 1" was required, the function requires this to be specified. This value is optional, and if not specified, the function will default to using zero.
Examples note(phone)
note(phone,home)
note(phone,home,1)
Here are three sample notes expressions. In the image below, they have been used to create expression list columns, with each expression used shown in the column header. The note, with labels on show, is visible on the right hand end of the image. When comparing the note with the data returned by each expression, it should become apparent how each expression is working.
note image
A note + expression columns (click to enlarge)
(Back to top)



Redundant Functions?

Taken at face value, all of the functions in this section would appear to be a little on the redundant side, falling neatly into the "a long way for a shortcut" category. MEDIA CENTER could possibly rely on these functions internally, exalting their status to "highly useful" or "essential" even, but as this page is designed for end users, not MEDIA CENTER, end users will find these functions redundant, and they are included here in the name of completeness only.

Field(...): Returns the value of a library field

Field() Place the name of any library field inside this function, and it will return the contents of that library field for each file. Entering the field name inside square brackets as normal, without the function, returns the same data.
Construction Field(Field name to retrieve)
Examples field(duration)
Returns the formatted duration value for each file. field(duration,0) would return the raw duration data. Simply entering [duration] or [duration,0] returns the same result.
(Back to top)

FilePath(...): Returns the path from a specified filename

FilePath() This function will return the file path information from root to parent folder for all files in a list, or for any specified file. MEDIA CENTER has a [Filename (Path)] library field by default, which is probably easier to use or reference than this function.
Construction FilePath(Filename to check)
  • Filename to check This is optional. If not specified, the function defaults to the current file.
Examples filepath(C:\Music\File.mp3)
The result here would be... "C:\Music"


filepath()
Returns the filepath for each file in the list. The [filename (path)] field returns the same information.

(Back to top)

FileName(...): Returns the name from a specified filename

FileName() This function will return the file name information for all files in a list, or for any specified file. MEDIA CENTER has a [Filename (Name)] library field by default, which is probably easier to use or reference than this function.
Construction FileName(Filename to check)
  • Filename to check This is optional. If not specified, the function defaults to the current file.
Examples filepath(C:\Music\File.mp3)
The result here would be... "File.mp3"


filepath()
Returns the file name for each file in the list. The [filename (Name)] field returns the same information.

(Back to top)

FileVolume(...): Returns the volume name from a specified filename

FileVolume() This function will return the volume name information for all files in a list, or for any specified file. MEDIA CENTER has a [Volume Name] library field by default, which is probably easier to use or reference than this function.
Construction FileVolume(Filename to check)
  • Filename to check This is optional. If not specified, the function defaults to the current file.
Examples filevolume(C:\Music\File.mp3)
The result here would be... "C:"


filevolume()
Returns the file name for each file in the list. The [Volume Name] field returns the same information.

(Back to top)

AlbumKey(...): Returns a unique album key for a file

AlbumKey() Testing reveals that this function simply returns an "[album artist (auto)] - [album]" string for each file. If two different albums happen to have the same [album artist (auto)] and [album] data, their respective AlbumKey() will not be unique.
Construction AlbumKey()
Examples AlbumKey()
Create a new expression column in a list using this function and the result will be a column populated with the [album artist (auto)] - [album] data for each file.
(Back to top)

AlbumArtist(...): Returns the calculated album artist for a file

AlbumArtist() This function simply returns the "[album artist (auto)]" data for each file.
Construction AlbumArtist()
Examples AlbumArtist()
Create a new expression column in a list using this function and the result will be a column populated with the [album artist (auto)] data for each file.
(Back to top)

AlbumType(...): Returns the album type for a file

AlbumType() This function simply returns the "[album type]" for each file. [album type] is a default MEDIA CENTER library field that informs the user of an album's status in the library, such as "Single artist (complete)" or "Multiple artists (incomplete)"
Construction AlbumType()
Examples AlbumType()
Create a new expression column in a list using this function and the result will be a column populated with the [album type] data for each file. The [album type] library field will work just as well, and return the same information.
(Back to top)

Size(...): Returns the size of a file in a media type independent manner

Size() Dependent on media type, this function returns the following information:
  • Audio: Duration
  • Video: Duration
  • Image: Dimensions
  • Data: No information returned.
Construction Size()
Examples Size()
Create a new expression column in a list using this function and the result will be a column populated with media type dependent data for each file as listed in the function description above.
(Back to top)

TrackNumber(...): Returns the track # of a file

TrackNumber() This function simply returns the track # of a file. If a file has no track # assigned, the function returns zero.
This function has no real use and is actually flagged as "For internal use only", so, not one for end users, and again, only included here for the sake of completeness.
Construction TrackNumber()
Examples TrackNumber()
Create a new expression column in a list using this function and the result will be a column populated with the track # information for each file.
(Back to top)

marko 13:20, 7 October 2010 (CDT)