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

From MusicBrainz Wiki
m ($copymerge(new,old))
(manually redirecting anyone naughtily linking to the wiki instead of /doc/)
 
(10 intermediate revisions by 6 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>.
 
 
 
===$inmulti(x,y)===
 
* Returns true, if multi-value variable <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.
 
 
 
===$setmulti(name, value, separator="; ")===
 
 
 
* Sets the variable <code><nowiki>name</nowiki></code> to <code><nowiki>value</nowiki></code>, using the separator (or "; " if not passed) to coerce the value back into a proper multi-valued tag. This can be used to operator on multi-valued tags as a string, and then set them back as proper multi-valued tags, e.g
 
<pre>$setmulti(genre,$lower(%genre%))</pre>
 
 
 
 
 
===$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.
 
 
 
===$copymerge(new,old)===
 
 
 
* Merges metadata from variable <code><nowiki>old</nowiki></code> into <code><nowiki>new</nowiki></code>, removing duplicates and appending to the end, so retaining the original ordering. Like <code><nowiki>$copy</nowiki></code>, this will also copy multi-valued 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.
 
 
 
===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. :)''
 
 
 
=== 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
 
 
 
===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>
 
 
 
===Merge writers into both composer and lyricist tags===
 
 
 
Suppose you want to add anyone involved in writing to both the composer and lyricist tags.
 
 
 
<pre>$copymerge(composer,writer)
 
$copymerge(lyricist,writer)
 
$unset(writer)</pre>
 
 
 
===Organize by alphabetical folders excluding leading The===
 
 
 
To keep music organized by initial letter of artist's name you must first set the directory where saved files are to be stored in Options --> Moving Files.
 
Then under Options --> File Naming check Rename files when saving. This script will then move saved files to your Moving Files location using the following hierarchy:
 
A/Artist Name, The/Year - Album Name/Artist - Album - Track - Song Title
 
<pre>$firstalphachar(
 
  $if(
 
$eq($left($lower(%artist%),4),the ),
 
$right($upper(%artist%), $sub($len(%artist%),4)),
 
$upper(%artist%)
 
  ))/
 
 
 
$if(
 
$eq($left($lower(%artist%),4),the ),
 
$right(%artist%, $sub($len(%artist%),4))\, The,
 
%artist%
 
)/
 
 
 
$if(%date%,$left(%date%,4) - )%album%/
 
 
 
%artist% - %album% - $if($gt(%totaldiscs%,1),Disk %discnumber% - ,)$num(%tracknumber%,2) - %title%
 
</pre>
 
 
 
[[Category:MusicBrainz Picard]] [[Category:How To]] [[Category:WikiDocs Page]]
 

Latest revision as of 21:16, 25 November 2014

Redirect to: