Difference between revisions of "MusicBrainz Picard/Documentation/Scripting"

From MusicBrainz Wiki
(manually redirecting anyone naughtily linking to the wiki instead of /doc/)
 
(18 intermediate revisions by 9 users not shown)
Line 1: Line 1:
This page describes the simple scripting language implemented in [[MusicBrainz Picard]].
+
#REDIRECT [[MusicBrainz Picard]]
 
 
==Syntax==
 
 
 
The syntax is derived from [http://wiki.hydrogenaudio.org/index.php?title=Foobar2000:Titleformat_Reference Foobar2000's titleformat]. There are three base elements: '''text''', '''variable''' and '''function'''. Variables consist of alpha-numeric characters enclosed in percent signs (e.g. <code><nowiki>%artist%</nowiki></code>). Functions start with a dollar sign and end with an argument list enclosed in parentheses (e.g. <code><nowiki>$lower(...)</nowiki></code>).
 
 
 
To use parenthesis or commas as-is inside a function call you must escape them with a backslash.
 
 
 
==Metadata Variables==
 
 
 
See [[Picard Tags|Picard tags]] for list of usable variables.
 
 
 
==Technical Variables==
 
 
 
===%_extension%===
 
 
 
* Extension of the file name. For example ''mp3'' for file ''01 Track.mp3''.
 
 
 
==Functions==
 
 
 
===$if(if,then,else)===
 
 
 
* If <code><nowiki>if</nowiki></code> is not empty, it returns <code><nowiki>then</nowiki></code>, otherwise it returns <code><nowiki>else</nowiki></code>.
 
 
 
===$if2(a1,a2,a3,...)===
 
 
 
* Returns first non empty argument.
 
 
 
===$lower(text)===
 
 
 
* Returns <code><nowiki>text</nowiki></code> in lower case.
 
 
 
===$upper(text)===
 
 
 
* Returns <code><nowiki>text</nowiki></code> in upper case.
 
 
 
===$left(text,num)===
 
 
 
* Returns first <code><nowiki>num</nowiki></code> characters from <code><nowiki>text</nowiki></code>.
 
 
 
===$matchedtracks()===
 
''Added in version 0.12''
 
 
 
* Returns the number of matched tracks within a release.
 
 
 
===$right(text,num)===
 
 
 
* Returns last <code><nowiki>num</nowiki></code> characters from <code><nowiki>text</nowiki></code>.
 
 
 
===$num(num,len)===
 
 
 
* Returns <code><nowiki>num</nowiki></code> formatted to <code><nowiki>len</nowiki></code> digits.
 
 
 
===$replace(text,search,replace)===
 
 
 
* Replaces occurrences of <code><nowiki>search</nowiki></code> in <code><nowiki>text</nowiki></code> with value of <code><nowiki>replace</nowiki></code> and returns the resulting string.
 
 
 
===$rsearch(text,pattern)===
 
 
 
* [http://docs.python.org/lib/re-syntax.html Regular expression] search. This function will return the first matching group.
 
 
 
===$rreplace(text,pattern,replace)===
 
 
 
* [http://docs.python.org/lib/re-syntax.html Regular expression] replace.
 
 
 
===$in(x,y)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> contains <code><nowiki>y</nowiki></code>.
 
 
 
===$unset(name)===
 
 
 
* Unsets the variable <code><nowiki>name</nowiki></code>.
 
 
 
===$set(name, value)===
 
 
 
* Sets the variable <code><nowiki>name</nowiki></code> to <code><nowiki>value</nowiki></code>.
 
 
 
Note: To create a variable which can be used for the file naming string, but which will not be written as a tag in the file, prefix the variable name with an underscore.  %something% will create a "something" tag; %_something% will not.
 
 
 
===$get(name)===
 
 
 
* Returns the variable <code><nowiki>name</nowiki></code> (equivalent to <code><nowiki>%name%</nowiki></code>).
 
 
 
===$copy(new,old)===
 
 
 
* Copies metadata from variable <code><nowiki>old</nowiki></code> to <code><nowiki>new</nowiki></code>. The difference between <code><nowiki>$set(new,%old%)</nowiki></code> is that <code><nowiki>$copy(new,old)</nowiki></code> copies multi-value variables without flattening them.
 
 
 
===$trim(text[,char])===
 
 
 
* Trims all leading and trailing whitespaces from <code><nowiki>text</nowiki></code>. The optional second parameter specifies the character to trim.
 
 
 
===$add(x,y)===
 
 
 
* Add <code><nowiki>y</nowiki></code> to <code><nowiki>x</nowiki></code>.
 
 
 
===$sub(x,y)===
 
 
 
* Subtracts <code><nowiki>y</nowiki></code> from <code><nowiki>x</nowiki></code>.
 
 
 
===$div(x,y)===
 
 
 
* Divides <code><nowiki>x</nowiki></code> by <code><nowiki>y</nowiki></code>.
 
 
 
===$mod(x,y)===
 
 
 
* Returns the remainder of <code><nowiki>x</nowiki></code> divided by <code><nowiki>y</nowiki></code>.
 
 
 
===$mul(x,y)===
 
 
 
* Multiplies <code><nowiki>x</nowiki></code> by <code><nowiki>y</nowiki></code>.
 
 
 
===$or(x,y)===
 
 
 
* Returns true, if either <code><nowiki>x</nowiki></code> or <code><nowiki>y</nowiki></code> not empty.
 
 
 
===$and(x,y)===
 
 
 
* Returns true, if both <code><nowiki>x</nowiki></code> and <code><nowiki>y</nowiki></code> are not empty.
 
 
 
===$not(x)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> is empty.
 
 
 
===$eq(x,y)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> equals <code><nowiki>y</nowiki></code>.
 
 
 
===$ne(x,y)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> not equals <code><nowiki>y</nowiki></code>.
 
 
 
===$lt(x,y)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> is lower than <code><nowiki>y</nowiki></code>.
 
 
 
===$lte(x,y)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> is lower than or equals <code><nowiki>y</nowiki></code>.
 
 
 
===$gt(x,y)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> is greater than <code><nowiki>y</nowiki></code>. 
 
 
 
===$gte(x,y)===
 
 
 
* Returns true, if <code><nowiki>x</nowiki></code> is greater than or equals <code><nowiki>y</nowiki></code>.
 
 
 
===$noop(...)===
 
 
 
* Does nothing (useful for comments or disabling a block of code).
 
 
 
===$len(text)===
 
 
 
* Returns the number of characters in text.
 
 
 
===$performer(pattern="",join=", ")===
 
 
 
* Returns the performers where the performance type (e.g. "vocal") matches <code>pattern</code>, joined by <code>join</code>.
 
 
 
===$firstalphachar(text,nonalpha="#")===
 
 
 
* Returns the first character of <code>text</code>. If <code>text</code> is not an alphabetic character <code>nonalpha</code> is returned instead.
 
 
 
===$initials(text)===
 
 
 
* Returns the first character of each word in <code>text</code>, if it is an alphabetic character.
 
 
 
===$truncate(text,length)===
 
 
 
* Truncate <code>text</code> to <code>length</code>.
 
 
 
==Tagger Script Examples==
 
'''''Options'' &rarr; ''Options...'' &rarr; ''Advanced'' &rarr; ''Scripting'''''
 
 
 
Tagger Script usually creates, modifies or deletes metadata variables.
 
 
 
===Use case 1: Artist names===
 
 
 
<pre>$if($search(%album%,(feat. conductor)),
 
  $set(artist,%orchestra%))
 
</pre>
 
* ''Stupid assumption that all classical albums have "feat. conductor" in the title, but it shows the idea. :)''
 
 
 
===Use case 2: Live tracks on live albums===
 
 
 
<pre>$if($and($eq(%releasetype%,live),$not($in(%title%,\(live\)))),$set(title,%title% \(live\)))
 
</pre>
 
 
 
===Remove "feat." from track titles===
 
 
 
<pre>$set(title,$rreplace(%title%,\\s\\\(feat. [^\)]+\\\),))
 
</pre>
 
 
 
===Convert triple-dot to ellipsis===
 
 
 
<pre>$set(title,$replace(%title%,...,…))
 
$set(album,$replace(%album%,...,…))
 
</pre>
 
 
 
This one is useful for people concerned about correct typography and also fixes one problem on Linux: if an album (assuming it's also a directory) is called something like "...for you!", it is considered hidden and therefore might be not accessible from some applications.
 
 
 
==File Naming Examples==
 
'''''Options'' &rarr; ''Options...'' &rarr; ''File naming'''''
 
 
 
===Lower case filenames with underscores===
 
 
 
<pre>$lower($replace(%albumartist%/%album%/$num(%tracknumber%,2) %title%, ,_))
 
</pre>
 
 
 
===(Year) only if available===
 
 
 
<pre>$if(%date%,\($left(%date%,4)\))
 
</pre>
 
 
 
===Use a different naming pattern for NATs===
 
 
 
<pre>$if($eq([non-album tracks],%album%),[non-album tracks]/%tracknumber%. %artist% - ,%artist% - $if(%date%, $left(%date%,4) )- %album%/%tracknumber%.)%title%
 
</pre>
 
 
 
Result: 
 
* Non-Album Tracks: [non-album tracks]/Band Name - Track Name.ext
 
* Tracks in releases: Band Name - year - Release Name/##. Track Name.ext
 
 
 
===Put subdiscs (disc 1, bonus disc, ...) in subdirectory===
 
This one puts all sorts of subdiscs in one directory. For the subalbum it uses the full name.
 
 
 
<pre>$if2(%albumartist%,%artist%)/$if(%date%,\($left(%date%,4)\) )$if($rsearch(%album%,\(\\\([^\\\)]*disc[^\\\)]*\\\)\)),$rreplace(%album%,\\\([^\\\)]*disc[^\\\)]*\\\),)/)%album%/$num(%tracknumber%,2) %artist% - %title%
 
</pre>
 
 
 
Result:
 
*Band Name/(year) Release Name/Release Name (disc #: Subname)/## Band Name - Track Name.ext
 
*Band Name/(year) Release Name/Release Name (bonus disc: Subname)/## Band Name - Track Name.ext
 
 
 
So a tree could look something like:
 
<pre>
 
Ayreon/
 
  (2000) Universal Migrator/
 
    Universal Migrator (disc 1_ The Dream Sequencer)/
 
      01 ...
 
    Universal Migrator (disc 2_ Flight of the Migrator)/
 
      01 ...
 
</pre>
 
Or:
 
<pre>
 
Belle and Sebastian/
 
  (2008) The BBC Sessions/
 
    The BBC Sessions (bonus disc_ Live in Belfast, 2001)/
 
      01 Belle and Sebastian - Here Comes the Sun.mp3
 
      02 ...
 
    01 Belle and Sebastian - The State I Am In.mp3
 
    02 ...
 
</pre>
 
 
 
It only doensn't handle colons nicely. Also it catches every 'disc' between parentheses, so there could be albums where it goes wrong, for example if an album is named "Groovy Beats (disco mix)" it will end up in a double directory.
 
 
 
===Remove "Various Artists" on compilations===
 
By default, Picard marks various-artist compilations with an album artist called "Various Artists". Even if you don't have anything by [http://musicbrainz.org/artist/4e46dd54-81a6-4a75-a666-d0e447861e3f.html Torsten Pröfrock], it still means that you player will sort your comps between Vangelis and VCR instead of down at the end, which you may not want.
 
 
 
This is easy to fix:
 
 
 
<pre>$if($and($eq(%compilation%,1), $eq(%albumartist%,Various Artists)), $unset(albumartist) $unset(albumartistsort))</pre>
 
 
 
[[Category:MusicBrainz Picard]] [[Category:How To]]
 

Latest revision as of 21:16, 25 November 2014

Redirect to: