TitleFormatting 解説

前書き

このページでは、よく使う、または使われると思われるTitle Formattingの記法をなるべく分かりやすいように解説しています。 少し発展的と思われる内容は "Tips" の項に分けて書いています。余裕があるときに読んでください。

間違っている箇所、分かりにくい箇所等は訂正していただけるとありがたいです。

解説の前に

Title Formattingを実際に使いながら覚えたい、という方は Menu > Preference から Display > Default User Interface を選び、そこで編集してみましょう。 なお、Columns UI、Func user interface などを使っている場合は「他の User Interface を使っている~」云々という表示が出て編集することができません。編集する場合は User Interface を Default User Interface に切り替えておきましょう。

up1039.png

念のため、すでに書かれているTitleFormattingをメモ帳などにバックアップしておきましょう。 なお、デフォルトの状態ではめったに起こることはありませんが、カスタマイズを進めている状態だと foobar2000 のデータが消える、ということがたまにあるので、特にカスタマイズ派の方は定期的にバックアップする癖をつけておく事をオススメします。

参考
FAQ: 設定をバックアップしたいんだけどどのファイルを保存すればいい?

文字入力

文字の表示方法

表示したい文字をそのまま入力するだけです。

aaa 123 あいう
aaa 123 あいう

※上が入力する文字、下が実際に表示される文字です。

但し、改行は無視されます。

abc
123
abc123

また、%$()[]'(すべて半角)といった文字があると、うまく表示されない事があります。

aaa%bbb
aaa

(% より後の部分が正常に表示されない) 対処方法は後ほど解説します。

改行の方法

改行するには、2つの方法があります。

  1. $crlf() と入力する
abc$crlf()
123
abc
123
  1. $char(10) と入力する
abc$char(10)
123
abc
123

この2つの違いについては筆者は分かりません。どちらを使っても構わないと思います。 なお、このページではここから改行を $char(10) で統一して表記することにします。

右寄せ

右寄せ(正確には右寄せと言うよりはタブ文字の挿入です)にしたい文字列の前で $tab() または $char(9) と入力します。

abc$tab()123

aaaは元のまま左寄せ、123は右寄せになります。 ただし $tab() または $char(9) と記述しても右寄せにならない箇所もあります。

%$()[]などの文字を表示させる方法

先ほど上のほうで「 %$()[](すべて半角)などといった文字があると、うまく表示されない」と書きました。 これは何故かというと、これらは title formatting においてはスクリプトを記述するために使う特殊な文字だからです。 (どういう意味かは後述します。とりあえず今は、これらは特殊な文字なのだと思ってください) これらを表示するためには、その文字を '(半角シングルクォーテーションマーク)で囲みます。

aaa'%'bbb
aaa%bbb

%$()[] 以外の文字を囲んでもOKです。

'a b' 'a%b'
a b a%b

このように、シングルクォーテーションマークは囲んだ中の文字をそのまま表示させる働きがあります。 シングルクォーテーションマーク自体を表示させたい場合は、' を二文字連続して書くことで表示させることが出来ます。

例1
'' aaa
' aaa
例2
''' aaa
'
('' と ' aaa に分けて認識される。' aaa の部分は終わりの ' が無いので表示されない)
例3
'''' aaa
'' aaa
('' が2セットある)
例4
''aaa' bbb
'aaa
(''aaa と ' bbb に分けて認識される。' bbb の部分は終わりの ' が無いので正常に表示されない)

例2~4を見るとややこしそうですが、こんなことまで考える場面は実際にはめったに無いので無理して理解しようとしなくて大丈夫です。 重要なことは、' を二文字連続して書くことでシングルクォーテーションマーク自身を表示させることが出来るということ、これだけを理解してもらえば十分です。

Tips: シングルクォーテーションマーク自体を表示する際の注意点

'Monkey''s Audio'

これは一見、Monkey's Audio と表示されそうですが、実際には

Monkeys Audio

と表示されます。これは、'Monkey'と's Audio'に分けて認識されてしまうためです。 これを防ぐためには、

Monkey''s Audio

または、

'Monkey'''s Audio

としてください。なお、下の文では 'Monkey' と ''s Audio に分けて認識されています。

参考
TitleFormatting FAQ: $strcmp(%__codec%,'Monkey''s Audio') で"1"が返ってこない!

コメント行

行頭に // と書くと、その行はコメント行になります。

例1
abc$char(10)
// ここはコメント行 好きなことが書けます。
123
abc
123
行頭に書かないとコメント行になりません。注意してください。
例2
abc // ここはコメント行ではない。$char(10)
123
abc // ここはコメント行ではない。
123

まとめ

% ~ % (フィールド関連)

まずは、この文を入力してみてください。

%_filename_ext%

?などと表示された場合は、適当な曲を再生してみてください。 再生中のファイル名が表示されましたか? 同様に、

%__bitrate%

も試してみてください。曲のビットレートが表示されると思います。

このように、TitleFormatting では% ~ %で~の情報を取得する働きがあります。 % の文字はそのままではうまく表示できないのは、このように % には曲の情報を取得する働きがあるからです。 このような文字を設定しておかないと、情報を得る方法が無く、ただのテキストと同じになってしまいますからね。

なお、% ~ %には

これら3つの働きがあります。また、これらをまとめてフィールドといいます。 ちなみに、上の方で挙げた %_filename_ext% は三つ目、%__bitrate%は二つ目のグループに属します。

タグの情報(Meta data)の取得

この文を入力してみてください。

%artist%

おそらく、「曲のアーティスト名が表示された」という方と「再生しても?のままだ」 という方の2パターンに分かれると思います。 これは何をしたかというと、タグの artist にある情報を取得したのです。その曲のタグの artist に情報が無かった場合は、? が表示されます。 %album% と入力すれば、タグの album フィールドにある情報が返ってきます。

これが % ~ % の~のタグの情報を取得する働きです。 なお、基本的には % ~ % は $meta( ~ ) と同意*1です。

%lyric%
$meta(lyric)
と同意。

音楽ファイルそのものに関する情報(Technical info)の取得

%__ ~ %(はじめにアンダーバーが2個)の形になります。$info( ~ )と同意です。 Technical info の例は以下。

%__codec%曲のファイル形式例: MP3,Monkey's Audio
%__codec_profile%ファイル形式の設定例: CBR
%__samplerate%サンプリングレート例: 44100
%__bitrate%ビットレート例: 128
%__tool%使われたエンコーダーの種類を推測例: LAME3.97
%__encoding%ロスレスかロスレスでないかlossless,lossy
%__channels%チャンネル数例: 2
%__bitspersample%量子化ビット数例: 16
%__tagtype%タグの種類例: id3v2
%__cue_embedded%キューシートの有無例: no
%__md5%md5の値。ファイルが破損していないかの確認に使う
%__ENC_DELAY%enc_delayの値を取得LAMEでエンコードされたmp3専用
%__ENC_PADDING%enc_paddingの値を取得同上
%__MP3_ACCURATE_LENGTH%mp3_accurate_lengthの有無を取得同上
%__MP3_STEREO_MODE%mp3ファイルのステレオの種類mp3専用 例: joint stereo
%__VERSION%エンコーダーのバージョン例: 3.99
%__FLAGS%flagsの値を取得

この他にも様々なものがあります。

%__ ~% は、$info(~) と書くこともできます。 例えば、ビットレートは

%__bitrate%

または、

$info(bitrate)

で取得できます。どちらも同じ意味ですが、上の書き方が多く使われます。

なお、ReplayGainの情報の取得方法は少し特殊で、$info()は使えません。

Technical infoの一覧はFile info boxのTechnical info欄などで確認できます。

up320.png

その他の情報(Special field)の取得

%_ ~ %の形になります。アンダーバーが一つ入るのが特徴です。 以下に例を挙げます。

%_path%拡張子付きのファイル名をパス付きで挿入します。
%_filename%拡張子無しのファイル名を挿入します。
%_filename_ext%拡張子付きのファイル名を挿入します。
%_directoryname%ディレクトリの名前を挿入します。
%_length%曲の長さを単位ごとに分けて挿入します。
%_filesize%ファイルサイズをバイト単位で挿入します。
%_isplaying%ファイルが演奏中のときは "1" を返し、それ以外のときは何も返しません。
%_ispaused%再生状態が「paused」のときは "1" を返し、それ以外のときは何も返しません。
%_time_elapsed%演奏経過時間を返します。

他にも様々なものがあります。ここのフィールド、スペシャルフィールドの部分や、Title formatting reference 日本語訳を参照してください。 この他にもさらに、特定のコンポーネントでしか使えないものがあります。 *2

さて、ここで "~ のときに 1 を返す" というものは何の意味があるんだ?と思った方もいるかも知れません。これは if 構文 というものに使います。if 構文については次の項で解説します。

Tips: Special field の取得方法の変更点(v0.9以降)

foobar2000のv0.9からSpecial field の新しい取得方法が追加されました。なお、上記であげた%_ ~ %を使う方法でも引き続き取得できます。

%_filename%%filename%
%_filename_ext%%filename_ext%
%_directoryname%%directoryname%
%_path%%path%
%_path_raw%%path_raw%
%_subsong%%subsong%
(v0.9から追加)%last_modified%ファイルの最終更新日時を取得。
%_ ~ %$extra( ~ )

まとめ

% ~ %には

これら3つの働きがある。

Tips: field remapping(% ~ % で特殊な動作をするもの)

前に、「 %artist%でタグのartistにある情報を取得できる」と書きましたが、実はこれは厳密に言うと間違いです。 %artist%は、少し特殊な動きをします。%artist%の本当の意味は、

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

になります。($if3()の説明) このような動作をするのは、ユーザー側にとって便利になるように、という製作者の配慮によるものです。 このような特殊な動作をするものをまとめると、

になります。特に%album artist%,%title%を使う際には気を付けて下さい。

純粋に album artist のタグ情報のみを取得したいような場合には、

$meta(album artist)

と、$meta() を使って記述してください。

制御構造

$if(a,b,c)

今までテキスト、および曲のデータを表示する方法を紹介してきましたが、ただ何かを表示するだけでは味気がありません。「○○のときはこんな表示を、××のときはあんな表示をする」と、条件によって表示する内容を変えることもしてみたくなるでしょう。それには if 構文というものを利用します。 if 構文とは、if という単語からも想像できるように、「もし ~ ならば ~ をする」という処理をしたい場合に用いる構文です。 title formatting で最も基本的な if 構文は

$if(a,b,c)

で、「もし a に何か値を返すものがあれば b を表示し、なければ c を表示する」という意味になります。 b,c の部分に更に $if() などを使うこともできます。

いくつか例を挙げます。まず、この文を見てみましょう。

$if(%artist%,アーティストの情報あり,アーティストの情報なし)

少し見にくいですが、これはこういう意味になります。

もし、artistというタグに何かあれば、"アーティストの情報あり" と表示し、無ければ "アーティストの情報なし" と表示する

では、次の文を見てみましょう。

$if(%comment%,Comment: %comment%,)

comment と言う字ばかりで見難いですが、どんな動作をするか予想してみてください。 これは、

もし、commentというタグに何かあれば、"Comment: (commentタグの内容)" を表示し、無ければ何も表示しない

という意味になります。

次はこちら。

$if(%_isplaying%,再生,停止)

なお、%_isplaying% とは、 前にも少しふれましたが、再生中(一時停止も含む)に1を、そうでなければ何も返さない、という意味です。 そうすると、このスクリプトは

もし再生中(一時停止も含む)ならば "再生" と表示、そうでなければ(つまり停止中ならば)"停止" と表示する

という意味です。(Display > TitleFormatting のPreview欄では常に停止中とみなされ、うまく動作しません)

このように、○○の時には1を、そうでなければ何も返さない、というフィールドは if 構文のために使います。

なお、$if(a,b,c)のaには複数の関数などを書くことができます。その場合には a に一つでも有効なフィールドがある場合に b を、全てなければ c を返します。

$if(%lyric%%lyrics%,歌詞がある,歌詞は無い)

また、$if(a,b,) は $if(a,b) と同意です。このページでは前者の方で統一します。

よく分からなければ、タグを編集しながら実際に確認してみてください。百聞は一見に如かずです。 カンマ、括弧、$の付け忘れに注意してください。

$if2(a,b)

$if(a,a,b)のように、一つ目と二つ目の文が同じ場合は特別に

$if2(a,b)

と書くこともできます。

$if(%artist%,%artist%,Unknown Artist)
は、一個目の%artist%と二個目の%artist%が同じです。これは
$if2(%artist%,Unknown Artist)
と書くこともできます。

[...]

[...]内に一つでも有効なフィールドがある場合、[...]内を返します。 ない場合は、[...]内は無視されます。 [a] は $if(a,a,) や $if2(a,) と同意です。

例1
[%artist]
例2
[アーティスト: %artist%]

$if3(a,b,c,d...)

aが無ければbを返す。bが無ければcを返す。cが無ければdを返す・・・という処理を行います。

$if3(%lyric%,%lyrics%,No Lyric)

$ifequal(a,b,c,d)

もし数字 a が数字 b と等しい場合、c を表示し、それ以外の場合 d を表示します。 a と b は数字でなければなりません。数字でなく文字列を比較する場合は$stricmp(x,y)などを使います。

$ifequal(%totaltracks%,1,,Track: %tracknumber% '/' %totaltracks%)

$ifgreater(a,b,c,d)

もし数字 a が数字 b 以上の場合、 c を表示します。それ以外の場合 d を表示します。 a=b の時は d を表示します。a≧b の時に c を表示したい場合は、aとb、cとdを入れ替えて

$ifgreater(b,a,d,c)

とすれば短く記述することができます。

$iflonger(a,b,c,d)

もし文字列 a が b 文字より長い場合、c を表示します。それ以外の場合 d を表示します。 2 バイト文字も 1 文字として扱われますが、v0.9.4.5 以前では設定によって 2バイト文字を 2 文字として扱うようにすることもできます。設定を変更している場合は注意してください。 2バイト文字の文字数について

まとめ

$if(a,b,c)もし a が最低1個の有効なタグなどを含んでいる場合、 b を実行/表示します。それ以外の場合 c を実行/表示します。"$if(%artist%,%artist%,unknown artist)" はアーティストの名前が存在する場合はその名前を表示し、存在しない場合は "unknown artist" を表示します。 注:"$if(a,a,)" は "[a]" と同等です。(下記を参照)
$if2(a,b)$if(a,a,b) と同等です。$if2(%title%,%_filename%)
$if3(a,b,c,..)1番はじめのTRUEもしくは空白ではない値を返します。
$ifequal(a,b,c,d)もし数字 a が数字 b と等しい場合、 c を実行/表示します。それ以外の場合 d を実行/表示します。
$ifgreater(a,b,c,d)もし数字 a が数字 b より大きい場合、 c を実行/表示します。それ以外の場合 d を実行/表示します。
$iflonger(a,b,c,d)もし文字列 a が b 文字より長い場合、 c を実行/表示します。それ以外の場合 d を実行/表示します。

その他の制御構造

$select(n,a,b,c,....)引数 a,b,c... の n 番目のものを返します。$select(3,'qwer','asdf','zxcv') なら 'zxcv' を返します。
$shortest(a,b,c,....)引数 a,b,c... を比較し最も短いものを返します。$shortest(%title%,%comment%)
$longest(a,b,c,....)a,b,c... が返す値を比較し、もっとも長い値を表示します。$longest(%title%,%comment%)

変数

変数とは

変数とは、「中身を自由に入れ替えられる入れ物」みたいな物です。 例えば、「hondana」という名前の入れ物に「syosetsu」という文字を入れておき、必要なときに「syosetsu」という文字を取り出すということが可能です。 特定の文字列を何度も使う場合、複雑な文を書く場合などに便利です。

$puts(a,b) (入れ物に文字を入れる)

$puts(a,b) でaという名前の入れ物にbという文字を入れることができます。 a の名前は自由に決められます。a の部分は大文字と小文字を区別しません。

$puts(hensu,mojiretsu)
これで、 hensu という名前の入れ物に mojiretsu という文字を入れた、ということになります。 $if() などを使っていても、処理されれば文字列となるものは b の部分に入れることができます。
$puts(artist,$if(%artist%,Artist: %artist%,No artist info))

$put(a,b)

aという名前の入れ物にbを入れ、さらにbを返します。 しかし、分かりにくくなるので $puts(a,b) を使ったほうがいいと思います。

$put(hensu,mojiretsu)
mojiretsu
さらに、 hensu という名前の入れ物に mojiretsu という文字が入ります。

$get(a) (入れ物から文字を取り出す)

$get(a) でaの中に入っていた文字を取り出すことができます。 何回でも取り出すことが可能です。

Line1: $puts(foo,bar)$char(10)
Line2: $get(foo)$char(10)
Line1:
Line2: bar
一行目でfooという名前の入れ物にbarという文字を入れ、二行目でfooという入れ物の中に入っていた文字を取り出した、ということになります。 なお、Line1: , Line2: という文字は分かりやすくするために書いたものですので、特に意味はありません。

まとめ: $puts(a,b),$get(a)の動作例

Line1: $puts(foo,bar)$char(10)
Line2: $get(foo)$char(10)
Line3: $get(Foo)$char(10)
Line4: $get(foo)$char(10)
Line5: $puts(foo,2000)$char(10)
Line6: $get(foo)$char(10)
Line1:
Line2: bar
Line3: bar
Line4:
Line5:
Line6: 2000

一行目でfooという入れ物にbarという文字を入れます。 二行目でfooという入れ物に入っている文字を呼び出しました。よってbarが返されます。 入れ物の名前は大小文字を区別しないというルールがあるので、三行目でもbarが返されます。 ただし全角半角は区別するので、四行目では「そんな名前の入れ物は知らない」ということになり、何も返しません。 五行目では、fooという入れ物に2000という文字を入れ直します。よって六行目では2000が返されます。 この例からも分かるように、$puts(a,b)$get(a)は上の行から順に処理されます。 よって、例えば

$get(foo)
$puts(foo,bar)

のように上下逆にすると何も表示されませんので注意してください。

Tips: 記入ミスを減らすために

慣れてくると複雑なコードを書けるようになりますが、その分見づらくもなってきます。 改行して分かりやすくなるようにしましょう。ミスも減ります。 ※これらはあくまでも例です。このように書かなければいけないということではありません

$if(%_isplaying%,$if(%title%,Title: %title% )$if(%artist%,Artist: %artist% )$if(%album%,Album: %album%),Stopped.)
$if(
%_isplaying%
,
$if(%title%,Title: %title% ,)
$if(%artist%,Artist: %artist% ,)
$if(%album%,Album: %album%,)
,
Stopped.
)

変数コメント行も効果的です。

$puts(track,Track: $meta(tracknumber)[ '/' %totaltracks%])
//↑トラックの表示方法

$ifequal(%totaltracks%,1,Single,$get(track))
//↑トラックの表示条件
こうすることで得られるメリットは、書く際のミスが少なくなるだけでなく、後にカスタマイズする際に分かりやすくもなることです。

なお、コメント行を

//*****
//Title
//*****

Title: $if2($meta(title),%_filename%)

$char(10)

//******
//Artist
//******

Artist: [$meta(artist)][' ('$meta(album artist)')']

例えばこのように使うとさらに分かりやすくなります。長い複雑な文ではこれらのテクニックは非常に重要なものになると思います。 一時的に使わなくなった文は

//Artist: [$meta(artist)][' ('$meta(album artist)')']

のようにコメント扱いにします(この行為をコメントアウトと言う)。 もし文が数行にわたっていて // を入力するのが大変という場合には、少し荒業になりますが

//ここから非表示
$if(0,

Title: %title%
$char(10)
$char(10)

$if(%artist%,
Artist: %artist%
$char(10)
$char(10)
,)

$if(%album%,
Album: %album%
$char(10)
$char(10)
,)

,)
//ここまで非表示

のように、$if() などを使って表示させないこともできます。

なお、Track info panel modSingle Column Playlist など一部のコンポーネントでは行頭の半角スペースが無視されるため、わかりやすく書くことができます。 さらに、Func user interface などは関数以外の文字列は解釈されないため、スペースやタブ文字などをあらゆるところに使えるのでさらに可読性が増します。

その他の関数

その他の関数については、Title formatting reference 日本語訳Title Formatting Helpを見てください。 以下では、その中から便利なもの、説明が必要と思われるものなどをピックアップしていきます。

$and(x,y...)

x,y...の全てがTRUEならば1を返します。ふつう $if などと合わせて使います。

$if(
$and($meta(tracknumber),$meta(totaltracks)),
'Track: '$meta(tracknumber)' / '$meta(totaltracks),
)

$or(x,y...)

x,y...のうちどれか一つでもTRUEならば1を返します。ふつう $if などと合わせて使います。

$if($or(%lyric%,%lyrics%),
歌詞がある,
歌詞は無い
)

ちなみに、上の例は

 $if(%lyric%%lyrics%,歌詞がある,歌詞は無い)

と同意です。

$not(x)

xがTRUEでない場合に1を返し、xがTRUEのときは何も返しません。 主に $and(x,y...) , $or(x,y...) などと組み合わせて使います。

$replace(x,a1,a2,b1,b2,...)

xという文字に含まれるa1という文字をa2に変え、b1という文字をb2に変え...ということをします。

例1
$replace(りんご すいか みかん,みかん,ぶどう)
りんご すいか ぶどう
例2
$replace(abc 123,abc,ABC,123,0)
ABC 0

Title Formatting Helpでは $replace(a,b,c) という形になっていますが、上記のように複数の文字列を置き換えることもできます。

この関数は、うまく使うと複雑なスクリプトを書く手間を省ける場合があります。例えば 「チャンネル数を出したいが、1ch のときは "Monoral" 、2ch のときは "Stereo" という文字を出したい」という場合には、$ifequal() を使って

$ifequal(%__channel%,1,Monoral,
$ifequal(%__channel%,2,Stereo,
%__channel%'ch'))

のように表すこともできますが、$replace() を使って

$replace(%__channel%'ch',1ch,Monoral,2ch,Stereo)

または

$replace(%channel%'ch',monoch,Monoral,stereoch,Stereo)

とすると、少しトリッキーですが簡単に表すことが出来ます。

文字列が長くなる場合に、文字列を切り詰める ($left(x,y))

$left(x,y) で、xという文字列をy文字に切り詰めます。

$left(%title%,20)

文字を表示させたいが、決められた文字数を超えた場合に切り詰めて文字の最後に"…"という文字をつけたい場合は

$puts(title,%title%)
$puts(yokomojisu,20)
$puts(addchar,…)

$ifgreater(
$len2($get(title)),
$get(yokomojisu),
$left($get(title),$sub($get(yokomojisu),$len2($get(addchar))))$get(addchar),
$get(title)
)

のようにします。 yokomojisu に文字数、 addchar に末尾に付ける文字を設定してください。 なお、 $puts(title,%title%) とわざわざ置いたのは、後にカスタマイズをしやすくするためです。

なお、2バイト文字も1文字として扱われます。2文字として扱うことは基本的にはできません。

ソートに $num(a,n) を使う

foobar2000 は、ソートする際に文字数にかかわらず左から順に文字を判別していくため、数字の桁数が統一されていない場合、思うようにソートしてくれない場合があります。 例えば "play_count" というタグにそれぞれ 1,2,6,10,15,21 という数が入っている6つの音楽ファイルを "%play_count%" でソートすると、デフォルトでは

1
10
15
2
21
6

この順番でソートされてしまいます。 これを防ぐには、"$num(x,y)" を使います。

$num(x,y)x を10進法の数として返しゼロで y 桁まで桁取りします。

例えばソート方法を "$num(%tracknumber%,2)" とすると、先ほどの例は

01
02
06
10
15
21

このように内部で処理され、うまくソートされます。 桁数が大きくなる場合は、 "$num(%_length_seconds%,6)" のように桁取りする値を大きくしてください。

なお、"%track%" と "%tracknumber%" に関してはリマッピングが行われるため、 $num() を使う必要はありません。

最後に

このような拙い解説を最後まで読んでいただきありがとうございました。


*1 wikiには% ~ %は複数行だった場合切り詰める、と書いてありましたが、おそらく間違い
*2 プレイリストの%_playlist_number%,Track Info Panelの%_trackinfo_mode%など

Last-modified: 2016-02-03 (水) 23:00:00