calibre テンプレート言語

calibre テンプレート言語は、ファイルパスの指定、値の整形、ユーザ指定の列の値の計算などのタスクのために calibre 全体で使用される calibre 固有の言語です。例を挙げると:

  • calibre ライブラリからディスクまたは電子書籍リーダにファイルを保存するときに、フォルダ構造とファイル名を指定します。

  • calibre の本のリストにアイコンと色を追加するためのルールを定義します。

  • 他の列からのデータを含む 仮想列 を定義します。

  • 高度なライブラリ検索。

  • 高度なメタデータの検索と置換。

この言語は、使用する本の書誌、その書誌の計算、およびそのフォーマット方法を指定する テンプレート の概念に基づいて構築されています。

基本テンプレート

基本テンプレートは、ひとつ以上の テンプレート表現 で構成されます。テンプレート表現 は、中括弧 ({}) 内のテキストと名前で構成され、処理中の本の対応する書誌に置き換えられます。たとえば、本をデバイスに保存するために使用される calibre のデフォルトのテンプレートには、次の 4 つのテンプレート式があります。

{author_sort}/{title}/{title} - {authors}

著者 "Isaac Asimov” の タイトル "The Foundation" という本の場合、テンプレートは以下のようになります:

Asimov, Isaac/The Foundation/The Foundation - Isaac Asimov

中括弧 {} の中に入っていませんので、スラッシュは テンプレート表現 ではありません。この文字は残って表示されます。例えば、テンプレートが以下だとすると:

{author_sort} Some Important Text {title}/{title} - {authors}

本"The Foundation" ではテンプレートは次のように生成します:

Asimov, Isaac Some Important Text The Foundation/The Foundation - Isaac Asimov

テンプレート表現 は、列の ルックアップ名 を使用して、カスタム列 (自分で作成した列) を含む、calibre で使用可能なすべての書誌にアクセスできます。 (フィールド と呼ばれることもあります) のルックアップ名を見つけるには、マウスを calibre の本リストの列ヘッダに合わせます。カスタム列のルックアップ名は常に # で始まります。シリーズタイプの列の場合、シリーズ内のその本のシリーズインデックスである #ルックアップ名_index という名前の追加フィールドがあります。たとえば、#myseries という名前のカスタムシリーズ列がある場合、#myseries_index という名前の列もあります。標準のシリーズ列のインデックスの名前は series_index です。

標準の列ベースのフィールドに加えて、次のものも使用できます:

  • {formats} - calibre ライブラリで利用可能な本の形式のリスト

  • {identifiers:select(isbn)} - 本の ISBN

特定の本のフィールドの書誌が定義されていない場合、テンプレートのフィールドは空の文字列 ('') に置き換えられます。たとえば、次のテンプレートについて考えてみましょう:

{author_sort}/{series}/{title} {series_index}

Asimov の本 "Second Foundation" がシリーズ "Foundation" に含まれている場合、テンプレートは次のように生成します:

Asimov, Isaac/Foundation/Second Foundation 3

本のシリーズが入力されていない場合、テンプレートは次のように生成します:

Asimov, Isaac/Second Foundation

テンプレートプロセッサは、複数のスラッシュと先頭または末尾のスペースを自動的に削除します。

高度な整形

書誌の置換に加えて、テンプレートには条件付きで追加のテキストを含め、置換されたデータの整形方法を制御できます。

条件つきでテキストを含める

フィールドが空でない場合にのみ、出力にテキストを表示したいというような場合があります。よくあるケースは seriesseries_index に対し、何も表示しないか、ハイフンで区切られた 2 つの値を連結して表示するかの切替です。 calibre は、特殊な テンプレート表現 の構文を使用してこのケースを処理します。

たとえば、上記の Foundation の例を使用して、テンプレートで Foundation - 3 - Second Foundation を生成するとします。このテンプレートはその出力を生成します:

{series} - {series_index} - {title}

ただし本にシリーズがない場合、テンプレートは - - タイトル を生成することになりますが、これはおそらくあなたが望むものではないでしょう。一般的に人々は、無意味なハイフンの無いただのタイトルとなることを望むものです。これは、次のテンプレート構文を使用すれば達成できます:

{field:|prefix_text|suffix_text}

この テンプレート表現field の値が XXXX の場合、結果は prefix_textXXXXXsuffix_text になることを示しています。field が空 (値がない) 場合、プレフィックスとサフィックスが無視されるため、結果は空の文字列 (なし) となります。プレフィックスとサフィックスには空白を含めることができます。

プレフィックスとサフィックスには、サブテンプレート ( `{ ... }` ) や関数 (下を参照) を使用しないでください。

この構文を使用すると、テンプレートで上記のシリーズなしの問題を解決できます。

{series}{series_index:| - | - }{title}

ハイフンは、本にシリーズインデックスがある場合にのみ含まれます。シリーズインデックスはシリーズがある場合にのみ含まれます。 Foundationの例を再び続けると、テンプレートは Foundation - 1 - Second Foundation を生成します。

メモ:

  • プレフィックスやサフィックスを使用している場合は、 ルックアップ名 の後にコロンを含める必要があります。

  • | の文字は、使用しないか両方使用するかのどちらかです。{field:| - } のようなひとつだけの使用は許されません。

  • プレフィックスやサフィックスにテキストを指定せず、 {series:|| - } にしてもかまいません。テンプレート {title:||}{title} と同じです。

書式設定

series_index を先行ゼロ付きの 3 桁に整形したいとします。次のようにすればそうできます:

{series_index:0>3s} - 先行ゼロ付きの 3 桁

後置ゼロには、次を使います:

{series_index:0<3s} - 後置ゼロ付きの 3 桁

1.1 などの小数値のシリーズインデックスを使用する場合は、小数点の位置を揃えたい場合があります。たとえば、インデックス 1 と 2.5 を 01.00 と 02.50 として表示して、辞書順に並べ替えを行うデバイスで正しく並べ替えられるようにすることができます。これを行うには、次を使用します:

{series_index:0>5.2f} - 先行ゼロ付きの 2 桁、小数点、および小数点以下 2 桁で構成される 5 文字。

データの最初の 2 文字だけが必要な場合は、次を使用します:

{author_sort:.2} - 著者読みの最初の 2 文字のみ

calibre テンプレート言語のフォーマットの多くは Python のものです。これらの高度なフォーマット操作の構文の詳細については、 Python documentation を参照してください。

テンプレートを使用してカスタム列を定義する

テンプレートを使用すると、calibre の書誌にない情報を表示したり、calibre の通常の形式とは異なる方法で書誌を表示したりできます。たとえば、calibre が表示しないフィールドである ISBN を表示したいことがあるかもしれません。これは、他の列から構築された列 タイプ (以降、複合列と呼びます) を使用してカスタム列を作成し、表示されるテキストを生成するためのテンプレートを提供することで実現できます。この列には、テンプレートの評価結果が表示されます。たとえば、ISBN を表示するには、列を作成し、テンプレートボックスに {identifiers:select(isbn)} と入力します。 2 つのシリーズカスタム列の値をカンマで区切って含む列を表示するには、{#series1:||,}{#series2} を使用します。

複合列は、書式設定を含む任意のテンプレートオプションを使用できます。

注: 複合列に表示されているデータを編集することはできません。代わりに、ソース列を編集します。複合列を編集する場合、たとえばダブルクリックした場合、calibreは、基になるデータではなく、編集用のテンプレートを開きます。

テンプレートとプラグボード

プラグボードは、デバイスへの送信およびディスクへの保存操作中に本に書き込まれる書誌を変更するために使用されます。プラグボードを使用すると、本の書誌に書き込むデータを提供するテンプレートを指定できます。プラグボードを使用すると authors, author_sort, language, publisher, tags, title, title_sort のフィールドを変更できます。この機能は、デバイス上の本で別の書誌を使用して、並べ替えや表示の問題を解決したい人に役立ちます。

プラグボードを作成するときは、プラグボードを使用する形式とデバイスを指定します。形式を保存するときに使用される特別なデバイス save_to_disk が提供されます (デバイスに送信するのではありません)。形式とデバイスを選択したら、変更する書誌フィールドを選択し、新しい値を提供するためのテンプレートを提供します。これらのテンプレートは宛先フィールドに 接続 されているため、プラグボードという名前が付けられています。これらのテンプレートでは、もちろん複合列を使用できます。

プラグボードは非常に柔軟性が高く、単関数モード、テンプレートプログラム モード、一般プログラム モード、または Python テンプレートモードでも記述できます。

プラグボードが適用される可能性がある場合 (コンテンツサーバ、ディスクに保存、またはデバイスに送信)、calibre は定義されたプラグボードを検索して、指定された形式とデバイスに適したプラグボードを選択します。たとえば、ANDROID デバイスに送信される EPUB ブックに適切なプラグボードを見つけるために、calibre は次の検索順でプラグボードを検索します:

  • 形式とデバイスが完全に一致するプラグボード。例: EPUB かつ ANDROID

  • 形式が完全に一致し、特別な 任意のデバイス を選択できるプラグボード。例: EPUB かつ 任意のデバイス

  • 特別な 任意のフォーマット を選択し、デバイス上で完全に一致するプラグボード。例: 任意のフォーマット かつ ANDROID

  • 任意のフォーマット任意のデバイス を備えたプラグボード

タグフィールドと著者フィールドはどちらも複数のアイテムを保持できるため、特殊な扱いとなります。本にはいくつものタグと何人もの著者を含めることができます。これら 2 つのフィールドのいずれかを変更するように指定すると、テンプレートの結果に複数の項目がないか確認されます。タグの場合、calibre はカンマを見つけるたびに結果を分割します。たとえばテンプレートが値 Thriller, Horror を生成すると、結果は2つのタグ、ThrillerHorror になります。タグの途中にカンマを入れる方法はありません。

著者にも同じことが起こりますが、分割に別の文字、カンマの代わりに & (アンパサンド) を使用します。たとえばテンプレートが値 Blogs, Joe&Posts, Susan を生成すると、本の著者は Blogs, JoePosts, Susan の 2 人になります。テンプレートが Blogs, Joe;Posts, Susan という値を生成すると、その本の著者はかなり変わった名前の 1 人となります。

プラグボードは、本がディスクに保存されるとき、またはデバイスに書き込まれるときに、本に書き込まれる書誌に影響を与えます。プラグボードは、ファイル名を作成するための ディスクに保存デバイスに送信 によって使われる書誌には影響しません。代わりに、ファイル名は、適切な設定ウィンドウに入力されたテンプレートを使用して作成されます。

テンプレートでの関数の使用 - 単関数モード

あるフィールドが通常はタイトルケースで、その値を大文字で表示したいと仮定します。テンプレート関数 を使用すれば、それが可能です。たとえば、タイトルを大文字で表示するには uppercase 関数を使用して、 {title:uppercase()} とします。タイトルケースで表示するには {title:titlecase()} を使用します。

関数は、テンプレートのフォーマット部分に入ります。それは : の後、かつ最初の | またはプレフィックス/サフィックスが使われていれば閉じ括弧 } の前です。フォーマットと関数参照の両方がある場合、関数は 2 個目の : の後に来ます。関数は、テンプレートで指定された列の値を適切に変更して返します。

関数を使用するための構文は、次のいずれかです:

{lookup_name:function(arguments)}
{lookup_name:format:function(arguments)}
{lookup_name:function(arguments)|prefix|suffix}
{lookup_name:format:function(arguments)|prefix|suffix}

関数名の後には、必ず開き括弧と閉じ括弧を付ける必要があります。一部の関数は追加の値 (引数) を必要とし、これらは括弧内に入ります。引数はカンマで区切ります。リテラルコンマ (引数の区切り文字ではなくテキストとしてのカンマ) の前には、バックスラッシュ (\) を付ける必要があります。最後の (または唯一の) 引数には、テキストの閉じ括弧を含めることはできません。

関数は、フォーマット指定とプレフィックス/サフィックスの前に評価されます。フォーマットと関数の両方を使用する例については、さらに下を参照してください。

重要: プログラミングの経験がある場合は、単関数モード の構文が思ったものと違うことに注意してください。文字列は引用符で囲まれておらず、スペースは重要です。すべての引数は定数と見なされます。式はありません。

サブテンプレート ( `{ ... }` ) を関数の引数として使用しないでください。 代わりに テンプレートプログラムモード および 一般プログラムモード を使用してください。

単関数モードでの関数の呼び出しに関する注意:

  • 関数を単関数モードで使用する場合、最初のパラメータである value は、テンプレートで指定されたフィールドの内容に自動的に置き換えられます。例えば、テンプレート {title:capitalize()} が処理される場合、 title フィールドの内容がパラメータ value としてcapitalize関数に渡されます。

  • 関数ドキュメントにおいて、 [something]* という表記は、 something が0回以上繰り返されることを意味します。 [something]+ という表記は、 something が1回以上繰り返されること(少なくとも1回は存在する必要があること)を意味します。

  • 一部の関数は正規表現を使用します。テンプレート言語における正規表現の一致判定では、大文字と小文字を区別しません。

関数については、 テンプレート関数リファレンス に記載されています。このドキュメントには、各関数が必要とする引数と、その関数の機能が説明されています。例えば、以下は ifempty 関数のドキュメントです。

  • ifempty(value, text_if_empty) -- value が空でない場合はその value を返し、そうでない場合は text_if_empty を返します。

この関数には valuetext_if_empty という2つの引数が必要です。ただし、今回は単関数モードを使用しているため、value 引数を省略し、text_if_empty のみを渡します。例えば、このテンプレートは次のようになります:

{tags:ifempty(No tags on this book)}

この項目には、タグがあれば、本に付けられたタグが表示されます。タグが付けられていない場合は、「この本にはタグがありません」と表示されます。

以下の関数は、最初のパラメータが value であるため、単関数モードで使用可能です。

  • capitalize(value) -- 指定された value の最初の文字を大文字に、それ以外の文字を小文字にして返します。

  • ceiling(value) -- value 以上の最小の整数を返します。

  • cmp(value, y, lt, eq, gt) -- value``y``の両方を数値に変換してから比較します。

  • contains(value, pattern, text_if_match, text_if_not_match) -- 値が正規表現 pattern に一致するかどうかをチェックします。

  • date_arithmetic(value, calc_spec, fmt) -- value を基に calc_spec を使用して新しい日付を計算します。

  • encode_for_url(value, use_plus) -- use_plus``で指定された方法で、URLで使用できるように``value``をエンコードして返します。最初に、値はURLエンコードされます。次に、``use_plus0 の場合は、スペースが '+' (プラス記号) に置き換えられます。use_plus1 の場合は、スペースが %20 に置き換えられます。

  • floor(value) -- value 以下の最大の整数を返します。

  • format_date(value, format_string) -- 日付文字列である valueformat_string を使用してフォーマットし、文字列として返します。

  • format_duration(value, template, [largest_unit]) -- 秒数を表す数値valueを、週、日、時、分、秒を示す文字列にフォーマットします。valueが浮動小数点数の場合は、最も近い整数に丸められます。

  • format_number(value, template) -- value を数値として解釈し、{0:5.2f}{0:,d}${0:5,.2f} などの Python フォーマットテンプレートを使用してその数値をフォーマットします。

  • fractional_part(value) -- 値の小数点以下の部分を返します。

  • human_readable(value) -- 引数 ``value``は数値を想定しており、その数値をKB、MB、GBなどの単位で表した文字列を返します。

  • ifempty(value, text_if_empty) -- value が空でない場合はその value を返し、そうでない場合は text_if_empty を返します。

  • language_strings(value, localize) -- ``value``で渡された言語コード(言語名とコードはこちらを参照 )に対応する言語名を返します。

  • list_contains(value, separator, [ pattern, found_val, ]* not_found_val) -- interpret the value as a list of items separated by separator, checking the pattern against each item in the list.

  • list_count(value, separator) -- value を指定された区切り文字( separator )で区切られた項目リストとして解釈し、項目数を返します。

  • list_count_matching(value, pattern, separator) -- valueseparator で区切られた項目のリストとして解釈し、正規表現 pattern に一致するリスト内の項目の数を返します。

  • list_item(value, index, separator) -- interpret the value as a list of items separated by separator, returning the 'index'th item.

  • list_sort(value, direction, separator) -- return value sorted using a case-insensitive lexical sort.

  • lookup(value, [ pattern, key, ]* else_key) -- The patterns will be checked against the value in order.

  • lowercase(value) -- 指定された value を小文字に変換して返します。

  • mod(value, y) -- ``value / y``の剰余の小数点以下を切り捨てた値を返します。

  • rating_to_stars(value, use_half_stars) -- Returns the value as string of star () characters.

  • re(value, pattern, replacement) -- return the value after applying the regular expression.

  • re_group(value, pattern [, template_for_group]*) -- return a string made by applying the regular expression pattern to value and replacing each matched instance

  • round(value) -- ``value``に最も近い整数を返します。

  • select(value, key) -- interpret the value as a comma-separated list of items with each item having the form id:id_value (the calibre identifier format).

  • shorten(value, left_chars, middle_text, right_chars) -- Return a shortened version of the value

  • str_in_list(value, separator, [ string, found_val, ]+ not_found_val) -- interpret the value as a list of items separated by separator then compare string against each value in the list.

  • subitems(value, start_index, end_index) -- This function breaks apart lists of tag-like hierarchical items such as genres.

  • sublist(value, start_index, end_index, separator) -- interpret the value as a list of items separated by separator, returning a new list made from the items from start_index to end_index.

  • substr(value, start, end) -- returns the start'th through the end'th characters of value.

  • swap_around_articles(value, separator) -- returns the value with articles moved to the end, separated by a semicolon.

  • swap_around_comma(value) -- given a value of the form B, A, return A B.

  • switch(value, [patternN, valueN,]+ else_value) -- for each patternN, valueN pair, checks if the value matches the regular expression patternN

  • test(value, text_if_not_empty, text_if_empty) -- return text_if_not_empty if the value is not empty, otherwise return text_if_empty.

  • titlecase(value) -- returns the value in title case.

  • transliterate(value) -- Return a string in a latin alphabet formed by approximating the sound of the words in value.

  • uppercase(value) -- returns the value in upper case.

同じテンプレートで関数と書式を使用する

整数のカスタム列 #myint003 のように先行ゼロ付きで表示したいと仮定します。これを実現する方法のひとつは 0>3s という書式を使用することです。ただしデフォルトでは数値 (整数または浮動小数点) がゼロに等しい場合には、その値は空の文字列として表示されるため、値ゼロは 000 ではなく空の文字列となります。値を 000 と表示したいのであれば、書式文字列と ifempty 関数を両方使用して空の値をゼロに戻してやります。そのテンプレートは次のようになるでしょう:

{#myint:0>3s:ifempty(0)}

プレフィックスとサフィックスも使用できます。もし数字を [003][000] のように表示したいのであれば、次のテンプレートを使用します:

{#myint:0>3s:ifempty(0)|[|]}

一般プログラムモード

一般プログラムモード (GPM) は テンプレート表現テンプレート言語 で記述したプログラムに置き換えます。言語の構文は、次の文法で定義されます:

program         ::= 'program:' expression_list
expression_list ::= top_expression [ ';' top_expression ]*
top_expression  ::= or_expression
or_expression   ::= and_expression [ '||' and_expression ]*
and_expression  ::= not_expression [ '&&' not_expression ]*
not_expression  ::= [ '!' not_expression ]* | concatenate_expr
concatenate_expr::= compare_expr [ '&' compare_expr ]*
compare_expr    ::= add_sub_expr [ compare_op add_sub_expr ]
compare_op      ::= '==' | '!=' | '>=' | '>' | '<=' | '<' |
                    'in' | 'inlist' | 'inlist_field' |
                    '==#' | '!=#' | '>=#' | '>#' | '<=#' | '<#'
add_sub_expr    ::= times_div_expr [ add_sub_op times_div_expr ]*
add_sub_op      ::= '+' | '-'
times_div_expr  ::= unary_op_expr [ times_div_op unary_op_expr ]*
times_div_op    ::= '*' | '/'
unary_op_expr   ::= [ add_sub_op unary_op_expr ]* | expression
expression      ::= identifier | constant | function | assignment | field_reference |
                    if_expr | for_expr | break_expr | continue_expr | return_stmt
                    '(' expression_list ')' | function_def
field_reference ::= '$' [ '$' ] [ '#' ] identifier
identifier      ::= id_start [ id_rest ]*
id_start        ::= letter | underscore
id_rest         ::= id_start | digit
constant        ::= " string " | ' string ' | number
function        ::= identifier '(' expression_list [ ',' expression_list ]* ')'
function_def    ::= 'def' identifier '(' top_expression [ ',' top_expression ]* ')' ':'
                    expression_list 'fed'
assignment      ::= identifier '=' top_expression
if_expr         ::= 'if' condition 'then' expression_list
                    [ elif_expr ] [ 'else' expression_list ] 'fi'
condition       ::= top_expression
elif_expr       ::= 'elif' condition 'then' expression_list elif_expr | ''
for_expr        ::= for_list | for_range
for_list        ::= 'for' identifier 'in' list_expr
                    [ 'separator' separator_expr ] ':' expression_list 'rof'
for_range       ::= 'for' identifier 'in' range_expr ':' expression_list 'rof'
range_expr      ::= 'range' '(' [ start_expr ',' ] stop_expr
                    [ ',' step_expr [ ',' limit_expr ] ] ')'
with_expr       ::= 'with' top_expression ':' expression_list 'htiw'
list_expr       ::= top_expression
break_expr      ::= 'break'
continue_expr   ::= 'continue'
return_stmt     ::= 'return' top_expression
separator_expr  ::= top_expression
start_expr      ::= top_expression
stop_expr       ::= top_expression
step_expr       ::= top_expression
limit_expr      ::= top_expression

メモ:

  • top_expression には常に値があります。expression_list の値は、リストの最後の top_expression の値です。たとえば、式リストの値 1;2;'foobar';33 です。

  • 論理的なコンテキストでは、空でない値はすべて True

  • 論理的なコンテキストでは、空の値はすべて False

  • 文字列と数字は同じ意味で使用できます。たとえば 10'10' は同じものです。

  • コメントは、 '#' 文字で始まる複数行で、その前に空白またはタブが入っていても構いません。

演算子の優先順位

演算子の優先順位 (評価する順) の最高 (最初に評価) から最低 (最後に評価) までは、次のとおりです:

  • 関数呼び出し、定数、括弧で囲まれた式、比較演算式、代入式、フィールド参照。

  • 単項プラス (+) およびマイナス (-)。これらの演算子は右から左に評価します。

    これらおよび他のすべての算術演算子は、式の小数部がゼロならば整数を返します。たとえば式が 3.0 を返す場合、それは 3 に変更されます。

  • 乗算 (*) と除算 (/)。これらの演算子は結合性があり、左から右に評価します。評価の順序を変更する場合は、括弧を使用してください。

  • 加算 (+) と減算 (-)。これらの演算子は結合性があり、左から右に評価します。

  • 数値と文字列の比較。これらの演算子は、比較が成功した場合は '1' を返し、それ以外の場合は空の文字列 ('')を返します。比較は結合的ではありません。 a < b < c は構文エラーです。

  • 文字列の連結 (&)。& 演算子は、左辺と右辺の式を連結して形成された文字列を返します。例: 'aaa' & 'bbb''aaabbb' を返します。演算子は結合性があり、左から右に評価します。

  • 単項論理否定 (!)。この演算子は、式が False (空の文字列に評価される) なら '1' を返し、そうでなければ '' を返します。

  • 論理積 (&&)。この演算子は、左辺と右辺の両方の式が True のときに '1' を返し、どちらかが False なら空の文字列 '' を返します。これは結合的で、左から右に評価し、 短絡評価 を行います。

  • 論理和 (||)。この演算子は、左辺または右辺の式のいずれかが True であれば '1' を返し、両方とも False なら '' を返します。これは結合的で、左から右に評価し、 短絡評価 を行います。 これは 包含的論理和 で、左辺または右辺の式の両方が True のときに '1' を返します。

フィールド参照

field_reference は、 $ または $$ に続くルックアップ名で指定された書誌データフィールドの値を評価します。 $ を使用することは、 field 関数を使用することと同等です。 $$ を使用することは、 raw_field 関数を使用することと同等です。例:

* $authors ==> field('authors')
* $#genre ==> field('#genre')
* $$pubdate ==> raw_field('pubdate')
* $$#my_int ==> raw_field('#my_int')

if 文

If 文は最初に condition を評価します。condition が True (空でない値) であれば、then 句の中にある expression_list が評価されます。False なら elif または else 句の中に expression_list があればそれが評価されます。elifelse の部分はオプションです。if, then, elif, else, および fi は予約語です。識別子の名前として使用することはできません。 意味のあるところならどこにでも改行と空白を置くことができます。conditiontop_expression であって expression_list ではありません。セミコロンは使用できません。expression_liststop_expressions のセミコロン区切りのシーケンスです。if 文は評価した expression_list の中で最後の top_expression を返し、評価したものがなければ空の文字列を返します。

例:

* program: if field('series') then 'yes' else 'no' fi
* program:
      if field('series') then
          a = 'yes';
          b = 'no'
      else
          a = 'no';
          b = 'yes'
      fi;
      strcat(a, '-', b)

入れ子になった if の例:

program:
  if field('series') then
    if check_yes_no(field('#mybool'), '', '', '1') then
      'yes'
    else
      'no'
    fi
  else
    'no series'
  fi

上で説明したように if は値を生成します。これは、次のすべてが同等であることを意味します:

* program: if field('series') then 'foo' else 'bar' fi
* program: if field('series') then a = 'foo' else a = 'bar' fi; a
* program: a = if field('series') then 'foo' else 'bar' fi; a

たとえば、このプログラムは、本にシリーズがある場合は series 列の値を返し、そうでない場合は title 列の値を返します。

program: field(if field('series') then 'series' else 'title' fi)

for 文

for 式は値のリストを順番に繰り返し、値を1個づつ処理します。 list_expression は、書誌データフィールドの「ルックアップ名」(例: tags#genre )または値のリストのいずれかを評価する必要があります。 range は数値のリストを生成します。結果が有効な ルックアップ名 である場合、そのフィールドの値が取得され、そのフィールドタイプに指定された区切り文字が使用されます。結果が有効なルックアップ名でない場合は、値のリストとみなされます。リストは、オプションのキーワード separator が指定されていない限り、カンマで区切られているとみなされます。指定されている場合は、 separator_expr を評価した結果でリストの値が区切られている必要があります。 range() によって生成されたリストには、区切り文字を使用できません。リスト内の各値は指定された変数に代入され、その後 expression_list が評価されます。 break を使用してループから抜け出すことができ、 continue を使用して次の反復処理のためにループの先頭に戻ることができます。

例: このテンプレートは、ジャンル (#genre) の各値の最初の階層名を削除し、新しい名前でリストを作成します:

program:
  new_tags = '';
  for i in '#genre':
    j = re(i, '^.*?\.(.*)$', '\1');
    new_tags = list_union(new_tags, j, ',')
  rof;
  new_tags

元のジャンルが History.Military, Science Fiction.Alternate History, ReadMe の場合、テンプレートは Military, Alternate History, ReadMe を返します。このテンプレートを calibre の 書誌を一括編集  →  検索と置換検索template を設定して階層の最初のレベルを取り除き、結果の値をジャンルに割り当てます。

注: この場合、テンプレートの最後の行である new_tags は必ずしも必要ではありません。これは、for が式リストの最後の top_expression の値を返すためです。割り当ての値はその式の値であるため、for 文の値は new_tags に割り当てられたものです。

with式

with 式:

  1. カレントの本を、top_expression` を評価して算出した calibre book id (整数値) を持つ本に変更します。

  2. expression_list を実行

  3. その後、カレントの本を元に戻します。

with 式は、評価された expression_list 内の最後の top_expression の結果を返します。式リストが評価されなかった場合は空の文字列を返します。

たとえば、このテンプレートは GUI で選択された複数の本のタイトルのリストを返します:

program:
  res = '';
  ids = selected_books();
  for id in ids:
      with id:
          res = (if res then res & ', ' fi) & $title
      htiw
  rof;
  res

Return 文

の値を返します。関数内で実行された場合は、式の値を呼び出し元に返します。最上位のコンテキスト(テンプレート)で実行された場合は、テンプレートの値が式の値に設定され、テンプレートの実行が終了します。

関数の定義

テンプレート内に繰り返し出現するコードを、ローカル関数にまとめることもできます。関数の定義は def キーワードで始まり、その後に関数名、引数リスト、そして関数内のコードが続きます。関数の定義は fed キーワードで終了します。

引数はキーワード引数です。関数が呼び出されると、指定された引数が定義されたパラメータに対して左から右に照合され、引数の値がパラメータに割り当てられます。定義されたパラメータよりも多くの引数を指定するとエラーになります。パラメータには、a = 25 などのデフォルト値を設定できます。そのパラメータに引数が指定されていない場合はデフォルト値が使用され、それ以外の場合はパラメータが空の文字列に設定されます。

return 文はローカル関数の中で使用できます。

関数は、使用する前に定義する必要があります。

例: このテンプレートは、日数から年、月、日でおおよその期間を計算します。関数 to_plural()` は、計算された値を整形します。ただしこの例では & 演算子も使用しています::eo

program:
      days = 2112;
      years = floor(days/360);
      months = floor(mod(days, 360)/30);
      days = days - ((years*360) + (months * 30));

      def to_plural(v, str):
              if v == 0 then return '' fi;
              return v & ' ' & (if v == 1 then str else str & 's' fi) & ' '
      fed;

      to_plural(years, 'year') & to_plural(months, 'month') & to_plural(days,'day')

関係演算子

関係演算子は、比較が真の場合は '1' を返し、それ以外の場合は空文字列( '' )を返します。

関係演算子は 2 種類あり、それは文字列比較と数値比較です。

文字列比較は、辞書順に基づいた大文字小文字を区別しない比較を行います。サポートされている文字列比較演算子は、 ==!=<<=>>=ininlist 、および inlist_field です。 ininlist 、および inlist_field 演算子の場合、左辺の式の評価結果は正規表現パターンとして解釈されます。これらの演算子は、左辺の正規表現が右辺の値に一致する場合に真となります。正規表現は、大文字小文字を区別しません。

inlist 演算子は、左側の正規表現が右側のカンマ区切りリスト内のいずれかの項目に一致する場合に真となります。 inlist_field 演算子は、左側の正規表現が右側の式で指定されたフィールド(列)内のいずれかの項目に一致する場合に真となります。この場合、フィールドに定義された区切り文字が使用されます。注: inlist_field 演算子は、右側の式がフィールド名に評価されることを必要としますが、 inlist 演算子は、右側の式がカンマ区切りリストを含む文字列に評価されることを必要とします。この違いにより、 inlist_field は文字列変換やリスト構築が行われないため、inlist よりも大幅に高速です。

数値比較演算子は、==#, !=#, <#, <=#, >#, >=# です。左と右の式は、2 つの例外を除いて数値に評価される必要があります。文字列値 "None" (未定義のフィールド) と空の文字列の両方が値ゼロに評価されます。

例:

  • program: field('series') == 'foo' は、本のシリーズが foo であれば '1' を返し、そうでなければ '' を返します。

  • program: 'f.o' in field('series') は、本のシリーズが正規表現 f.o (例: foo, Off Onyx, など) とマッチすれば '1' を返し、そうでなければ '' を返します。

  • program: 'science' inlist $#genre は、本のジャンルから取得された値のいずれかが正規表現  science に一致する場合(例: ScienceHistory of ScienceScience Fiction など)は 1 を返し、そうでない場合は '' を返します。

  • program: '^science$' inlist $#genre は、本のジャンルのいずれかが正規表現 ^science$ に完全に一致する場合(例: Science )は '1' を返し、そうでない場合は '' を返します。 ジャンルが History of ScienceScience Fiction は一致しません。

  • program: 'asimov' inlist $authors は、いずれかの著者が正規表現 asimov に一致する場合(例: Asimov, IsaacIsaac Asimov )、'1' を返し、そうでない場合は '' を返します。

  • program: 'asimov' inlist_field 'authors' は、いずれかの著者が正規表現 asimov に一致する場合(例:Asimov, IsaacIsaac Asimov )、'1' を返し、そうでない場合は '' を返します。

  • program: 'asimov$' inlist_field 'authors' は、いずれかの著者が正規表現 asimov$ に一致する場合(例: Isaac Asimov )は '1' を返し、そうでない場合は '' を返します。正規表現に $ アンカーが含まれているため、Asimov, Isaac には一致しません。

  • program: if field('series') != 'foo' then 'bar' else 'mumble' fi は 本のシリーズが foo と等しくない場合は 'bar' を返し、そうでない場合は 'mumble' を返します。

  • program: if field('series') == 'foo' || field('series') == '1632' then 'yes' else 'no' fi は 本のシリーズが foo か、1632 と等しい場合は 'yes' を返し、そうでない場合は 'no' を返します。

  • program: if '^(foo|1632)$' in field('series') then 'yes' else 'no' fi は 本のシリーズが foo か、1632 と等しい場合は 'yes' を返し、そうでない場合は 'no' を返します。

  • program: if 11 > 2 then 'yes' else 'no' fi'no' を返します。なぜなら > 演算子が辞書比較を行うからです。

  • program: if 11 ># 2 then 'yes' else 'no' fi'yes' を返します。なぜなら ># 演算子は数値比較を行うからです。

一般プログラムモードの関数

テンプレート言語に組み込まれている関数の一覧については、テンプレート関数リファレンス を参照してください。

メモ:

  • 単関数モードとは異なり、一般プログラムモードでは、最初のパラメータである value を指定する必要があります。

  • すべてのパラメータは式リストです(上記の文法を参照)。

より複雑なテンプレート表現のプログラム - テンプレートプログラムモード

テンプレートプログラムモード (TPM) は、 一般プログラムモード and 単関数モード を組み合わせたものです。 TPM は、他の書誌フィールドを参照し、ネストされた関数を使用し、変数を変更し、算術演算を実行するテンプレート式を記述できるという点で、単関数モードとは異なります。このテンプレートが {} 文字の間に置かれ、program: という部分で始まらないという点で、一般プログラムモード とは異なります。テンプレートのプログラム部分は、一般プログラムモードの式リストです。

例: テンプレートで、ある本がシリーズものならシリーズを表示し、そうでなければカスタムフィールド #genre の値を表示したいと仮定します。単関数モード ではテンプレートの式の中からは別の書誌フィールドを参照できないため、この処理は実現できません。 TPM でなら可能です。次の式のようにします:

{series:'ifempty($, $#genre)'}

例からはいくつかのことがわかります:

  • 式が :' で始まり '} で終わる場合は TPM が使用されます。それ以外の場合は、:ref:`単関数モード`であるとみなされます。

    テンプレートにプレフィックスとサフィックスが含まれている場合、式は '| で終わります。ここで | はプレフィックスの区切り文字です。例:

    {series:'ifempty($, $#genre)'|prefix | suffix}
    
  • 関数にはすべての引数を指定する必要があります。例えば、標準の組み込み関数には、最初のパラメータである value を指定する必要があります。

  • 変数 $value 引数として使用され、テンプレートで指定されたフィールド(この場合は series )の値を示します。

  • 空白は無視され、式の中のどこでも使用できます。

  • 定数文字列は対になる引用符、' または " のいずれかで囲まれます。

TPM では、文字列リテラル内で {} の文字を使用すると、テンプレートプロセッサがこれらの文字をテンプレート式の区切り文字として認識してしまうため、エラーや予期せぬ結果が発生する可能性があります。場合によっては、 { を `` [[`` に、 }]] に置き換えることで対応できます。アドバイス:プログラムに {} の文字が含まれている場合は、 一般プログラムモード を使用してください。

Python テンプレートモード

Pythonテンプレートモード(PTM)を使用すると、ネイティブPythonと calibre API を使ってテンプレートを作成できます。データベースAPIがもっともよく使われますが、詳細については、このマニュアルの範囲外です。PTMテンプレートは高速で、より複雑な処理を実行できますが、calibre APIを使用してPythonでコードを書く方法を知っている必要があります。

PTM テンプレートは次で始まります:

python:
def evaluate(book, context):
    # book is a calibre metadata object
    # context is an instance of calibre.utils.formatter.PythonTemplateContext,
    # which currently contains the following attributes:
    # db: a calibre legacy database object.
    # globals: the template global variable dictionary.
    # arguments: is a list of arguments if the template is called by a GPM template, otherwise None.
    # funcs: used to call Built-in/User functions and Stored GPM/Python templates.
    # Example: context.funcs.list_re_group()

    # your Python code goes here
    return 'a string'

上記のテキストは、通常右クリックで表示されるコンテキストメニューを使用してテンプレートに追加できます。コメントは本質的ではないため、削除しても構いません。Pythonのインデント規則に従う必要があります。

コンテキストオブジェクトは、コンテキストの内容を文字列として返す str(context) と、コンテキスト内の属性名のリストを返す context.attributes をサポートしています。

context.funcs 属性を使用すると、組み込みテンプレート関数、ユーザー定義テンプレート関数、および保存済みのGPM/Pythonテンプレートを呼び出すことができ、コード内で直接実行できます。関数は名前を使用して取得されます。名前がPythonのキーワードと競合する場合は、名前の末尾にアンダースコアを追加してください。例:

context.funcs.list_re_group()
context.funcs.assert_()

これは、シリーズのすべての著者のリストを作成するPTMテンプレートの例です。このリストは、他の列から構築された列(タグのように動作する)`に保存されます。これは :guilabel:`本の詳細 セクションに表示され、個別の行に表示 オプションがオンになっています( 環境設定  →  外観  →  本の詳細 )。このオプションでは、リストがカンマ区切りである必要があります。この要件を満たすために、テンプレートは著者名に含まれるカンマをセミコロンに変換してから、カンマ区切りの著者リストを作成します。その後、著者はソートされるため、テンプレートでは author_sort を使用しています。

python:
def evaluate(book, context):
    if book.series is None:
        return ''
    db = context.db.new_api
    ans = set()
    # Get the list of books in the series
    ids = db.search(f'series:"={book.series}"', '')
    if ids:
        # Get all the author_sort values for the books in the series
        author_sorts = (v for v in db.all_field_for('author_sort', ids).values())
        # Add the names to the result set, removing duplicates
        for aus in author_sorts:
            ans.update(v.strip() for v in aus.split('&'))
    # Make a sorted comma-separated string from the result set
    return ', '.join(v.replace(',', ';') for v in sorted(ans))

本の詳細 の出力はこのようです:

電子書籍変換ダイアログ

テンプレートとURL

テンプレートを使用してURLを構築することができます。ここでは2つのケースについて説明します:

  • カスタム列 書籍詳細 検索URL

  • calibre URLスキーム

カスタム列書籍詳細検索URL

カスタム列を作成する際、テンプレートを使用して 書籍詳細 で使用するURLを指定できます。たとえば、翻訳者 用のカスタム列を作成する場合、翻訳者向けのウェブサイトにアクセスできるURLを定義できます。書籍詳細検索用URLは、テキスト列挙型シリーズ他の列から構築された列 の各列タイプで指定可能です。

書籍詳細検索テンプレート が設定された項目をクリックすると、そのテンプレートが評価されます。テンプレートには通常の本の書誌データに加え、以下の3つの追加フィールドが提供されます:

  • item_value: クリックされた項目の値

  • item_value_quoted: クリックされたアイテムの値。URLエンコードされています。特殊文字はURLで有効になるようにエスケープされ、スペースは '+' (プラス) 記号に置き換えられます。

  • item_value_no_plus: クリックされたアイテムの値。URLエンコード済み。特殊文字はURLで有効になるようにエスケープされ、スペースはプラス記号ではなく``%20`` に置き換えられます。

URLを構築する方法はいくつかあります。以下ではWikipediaを例として説明します。

一番単純なのは基本テンプレートです:

https://en.wikipedia.org/w/index.php?search={item_value_encoded}

場合によっては、さらに高度な処理が必要になることがあります。処理の複雑さに応じて、4種類のテンプレート関数を使用できます。

  • make_url(path, [query_name, query_value]+) -- this function is the easiest way to construct a query URL. It uses a path, the web site and page you want to query, and query_name, query_value pairs from which the query is built. In general, the query_value must be URL-encoded. With this function it is always encoded and spaces are always replaced with '+' signs.

  • make_url_extended(...) -- this function is similar to make_url() but gives you more control over the URL components. The components of a URL are

    scheme:://authority/path?query string.

    See Uniform Resource Locator on Wikipedia for more detail.

    The function has two variants:

    make_url_extended(scheme, authority, path, [query_name, query_value]+)
    

    and

    make_url_extended(scheme, authority, path, query_string)
    
  • query_string([query_name, query_value, how_to_encode]+)-- returns a URL query string constructed from the query_name, query_value, how_to_encode triads. A query string is a series of items where each item looks like query_name=query_value where query_value is URL-encoded as instructed. The query items are separated by '&' (ampersand) characters.

  • encode_for_url(value, use_plus) -- use_plus``で指定された方法で、URLで使用できるように``value``をエンコードして返します。最初に、値はURLエンコードされます。次に、``use_plus0 の場合は、スペースが '+' (プラス記号) に置き換えられます。use_plus1 の場合は、スペースが %20 に置き換えられます。

例えば、カスタム列 Translators (#translators) があり、名前が Last name, First name になっているとします。URLを作成する際に、名前を First name Last name に変換する必要があるかもしれません。make_url 関数を使用すると、この変換が可能です。

program: make_url('https://en.wikipedia.org/w/index.php', 'search', swap_around_comma($item_value))

翻訳者の名前が Boy-Żeleński, Tadeusz であると仮定すると、上記のテンプレートは次のリンクを生成します:

https://en.wikipedia.org/w/index.php?search=Tadeusz+Boy-%C5%BBele%C5%84ski

なお、名前の順番が姓から名に変わり、スペースがプラス記号に置き換えられ、姓に含まれる英語以外の文字はURLエンコードされていることに注意してください。

追加の処理の複雑さに応じて、make_url_extendedquery_string 、および encode_for_url といった関数が役立つ場合があります。

calibre URLスキーム

calibreは、calibreライブラリを操作するための様々なURLをサポートしています。このセクションでは、テンプレートを使用してこれらのURLを構築する方法を説明します。利用可能なURLの詳細については、The calibre:// URL スキーム を参照してください。

  • 指定したライブラリに切り替えます。URLの構文は次のとおりです:

    calibre://switch-library/Library_Name
    

    Library_Name は、開きたいcalibreライブラリの名前に置き換える必要があります。ライブラリ名はウィンドウのタイトルバーに表示されます。これはファイルパスではなく、単純な名前です。タイトルバーに表示されているとおりに、大文字と小文字を含めて正確に入力してください。_ (アンダースコア)は現在のライブラリを表します。名前の中にスペースや特殊文字が含まれている場合は、次の例のように、to_hex 関数を使用して16進数エンコードする必要があります。

    program: strcat('calibre://switch-library/_hex_-', to_hex(current_library_name()))
    

    テンプレートは URL を生成します:

    calibre://switch-library/_hex_-4c6962726172792e746573745f736d616c6c
    

    You can replace the current_library_name() function with the actual name of the library, as in:

    program: strcat('calibre://switch-library/_hex_-', to_hex('Library.test_small'))
    
  • 本を表示するためのリンクです。これらのリンクをクリックすると、calibreライブラリ内の本が選択されます。このURLの構文は以下のとおりです:

    calibre://show-book/Library_Name/book_id
    

    book id は、本の calibre ID の数値で、テンプレートでは $id として使用できます。上記と同様に、ライブラリ名は 16 進数でエンコードする必要がある場合があります。以下に例を示します:

    program: strcat('calibre://show-book/_hex_-', to_hex(current_library_name()), '/', $id)
    

    次の URL が生成されます:

    calibre://show-book/_hex_-4c6962726172792e746573745f736d616c6c/1353
    
  • 本を検索します。これらのリンクは、指定されたcalibreライブラリ内の本を検索します。このURLの構文は以下のとおりです:

    calibre://search/Library_Name?q=query
    calibre://search/Library_Name?eq=hex_encoded_query
    

    ここで query は有効なcalibre検索式です。スペースや特殊文字を含む検索式はすべて16進数エンコードする必要があります。つまり、ほとんどすべての検索式が該当します。例えば、 'AA' で始まる階層タグを検索するためのcalibre検索式は tags:"=.AA" です。このテンプレートは、その検索式に対応する検索URLを生成します:

    program: strcat('calibre://search/_hex_-', to_hex(current_library_name()), '?eq=', to_hex('tags:"=.AA"'))
    

    結果の URL は次のようになります:

    calibre://search/_hex_-4c6962726172792e746573745f736d616c6c?eq=746167733a223d2e414122
    

    以下は、strcat 関数ではなく make_url_extended 関数を使用して構築された同じURLの例です:

    program: make_url_extended('calibre', '', 'search/_hex_-' & to_hex(current_library_name()),
                               'eq', to_hex('tags:"=.AA"'))
    
  • いずれかのライブラリにある本について、本の詳細ウィンドウを開きます。このURLの構文は以下のとおりです:

    calibre://book-details/Library_Name/book_id
    

    テンプレートの例は次のとおりです:

    program: strcat('calibre://book-details/_hex_-', to_hex(current_library_name()), '/', $id)
    

    これにより、次の URL が生成されます:

    calibre://book-details/_hex_-4c6962726172792e746573745f736d616c6c/1353
    
  • 著者やシリーズなどに関連付けられた注釈を開きます。URLの構文は以下のとおりです:

    calibre://book-details/Library_Name/Field_Name/id_Item_Id
    calibre://book-details/Library_Name/Field_Name/hex_Hex_Encoded_Item_Name
    

    Field_Name はフィールドの検索名です。フィールドがカスタム列の場合は、 # 文字をアンダースコア( _ )に置き換えてください。 Item_Id は、フィールド内の値の内部数値IDです。 Item_Id を返すテンプレート関数はないため、テンプレートでは通常、2番目の形式である Hex_Encoded_Item_Name を使用します。以下は、 #authtest フィールドにある Boy-Żeleński, Tadeusz という人物のメモを開くサンプルテンプレートです:

    program: strcat('calibre://show-note/_hex_-', to_hex(current_library_name()),
                    '/_authtest/hex_', to_hex('Boy-Żeleński, Tadeusz'))
    

    これにより、次の URL が生成されます:

    calibre://show-note/_hex_-4c6962726172792e746573745f736d616c6c/_authtest/hex_426f792dc5bb656c65c584736b692c205461646575737a
    

保存済みテンプレート

一般プログラム モード ` と :ref:`Python テンプレート モード ` は両方とも、ストアド関数の呼び出しと同様に、テンプレートの保存と別のテンプレートからの呼び出しをサポートしています。テンプレートを保存するには、[設定 -> 詳細設定 -> テンプレート機能] を使用します。詳細については、そのダイアログに表示されます。関数を呼び出すのと同じ方法でテンプレートを呼び出し、必要に応じて位置引数を渡します。引数には任意の式を指定できます。保存されたテンプレートの名前が ``foo` であると仮定して、テンプレートを呼び出す例:

  • foo() -- 引数を渡さずにテンプレートを呼び出します。

  • foo(a, b) は、2 つの変数 ab の値を渡すテンプレートを呼び出します。

  • foo(if field('series') then field('series_index') else 0 fi) -- 本に series があれば series_index を渡し、そうでなければ値 0 を渡します。

GPMでは、保存されたテンプレートの呼び出し時に渡された引数を、 arguments 関数を使用して取得します。この関数はローカル変数を宣言し、同時に初期化します。これらの変数は位置に基づいており、呼び出し時に同じ位置で指定された引数の値が代入されます。呼び出し時に対応する引数が指定されていない場合、 arguments 関数はその変数に指定されたデフォルト値を代入します。デフォルト値が指定されていない場合は、変数は空の文字列に設定されます。例えば、次の arguments 関数は、keyalternate という2つの変数を宣言します:

arguments(key, alternate='series')

例として、保存されたテンプレートの名前が今回も foo であると仮定します:

  • foo('#myseries') -- 引数 key には値 'myseries' が割り当てられ、引数 alternate にはデフォルト値 'series' が割り当てられます。

  • foo('series', '#genre') 変数 key には値 'series' が割り当てられ、変数 alternate には値 '#genre' が割り当てられます。

  • foo() -- 変数 key には空の文字列が割り当てられ、変数 alternate には値 'series' が割り当てられます。

PTMでは、引数は文字列のリストである arguments パラメータで渡されます。デフォルト値を指定する方法はありません。引数の数が想定どおりであることを確認するには、 arguments リストの長さをチェックする必要があります。

保存済みテンプレートをテストする簡単な方法は、 テンプレートテスタ ダイアログを使用することです。アクセスしやすくするには、環境設定 → 高度な設定 → キーボードショートカット → テンプレートテスタ でキーボードショートカットを指定します。 保存済みテンプレート ダイアログにショートカットを指定すると、テスタをすばやく切り替えたり、保存されたテンプレートのソースコードを編集したりするのに役立ちます。

テンプレートに追加情報を与える

開発者は、アプリケーション固有の本の書誌やプロセッサに要求されていることに関する情報など、追加情報をテンプレートプロセッサに渡すことを選択できます。テンプレートはこの情報にアクセスして、評価中に使用できます。

開発者: 追加情報の渡し方

追加情報は、変数名と値 のペアで構成されるPython辞書形式で提供されます。値は文字列のみ許されます。テンプレートはこの辞書にアクセスし、キーである変数名と同じ名前のテンプレートローカル変数を作成し、そこに値として対応する文字列を格納します。ユーザーは変数名を変更できないため、他のテンプレートローカル変数と名前が重複しないように、例えばアンダースコアを先頭に付けるなど、衝突しない名前を使用することが適切です。

この辞書は、名前付きパラメータ global_vars=your_dict を使用してテンプレートプロセッサ( formatter )に渡されます。メソッドの完全なシグネチャは次のとおりです:

def safe_format(self, fmt, kwargs, error_value, book,
                column_name=None, template_cache=None,
                strip_results=True, template_functions=None,
                global_vars={})

テンプレート作者: 追加情報のアクセス方法

テンプレート内で追加情報( globals 辞書)にアクセスするには、テンプレート関数を使用します:

globals(id[=expression] [, id[=expression]]*)

ここで、id は任意の有効な変数名です。この関数は、開発者から提供された追加情報に名前が含まれているかどうかを確認します。その場合、関数は提供された値をその名前のテンプレートローカル変数に割り当てます。名前が追加情報に含まれておらず、式が指定されている場合、式が評価され、結果がローカル変数に割り当てられます。値も式も指定されていない場合、関数は空の文字列 ('') をローカル変数に割り当てます。

テンプレートは、テンプレート関数を使用して globals 辞書に値を設定できます:

set_globals(id[=expression] [, id[=expression]]*)

この関数は、 globals 辞書にキーと値のペア id:value を設定します。ここで value はテンプレートのローカル変数 id の値です。もしそのローカル変数が存在しない場合は、valueexpression を評価した結果の値に設定されます。

モード間の違いに関する注意事項

3つのプログラムモード、 単関数モード (SFM), テンプレートプログラムモード (TPM), and 一般プログラムモード (GPM)は、それぞれ動作が異なります。 SFMは「シンプル」を目指しているため、多くのプログラミング言語情報を隠します。

相違点:

  • SFM では、列の値は常に「非表示」の最初の引数としてテンプレートに含まれる関数に渡されます。

  • SFMは、変数と文字列の違いをサポートしていません。すべての値は文字列です。

  • 次のSFMテンプレートは、シリーズ名か文字列 "no series" のいずれかを返します:

    {series:ifempty(no series)}
    

    TPM で同等のテンプレートは

    {series:'ifempty($, 'no series')'}
    

    GPM で同等のテンプレートは:

    program: ifempty(field('series'), 'no series')
    

    ifempty の最初の引数は、フィールド series の値です。 2 番目の引数は文字列 no series です。 SFMでは、最初の引数であるフィールドの値が自動的に渡されます (非表示の引数)。

  • booksize()current_library_name() などのテンプレート関数には引数を受け取らないものがいくつかあります。 「目に見えない引数」を使用するせいで、SFMではこれらの関数は使用できません。

  • 関数が別の関数を呼び出して引数を計算する入れ子関数は、SFMでは使用できません。たとえば、大文字のシリーズ値の最初の 5 文字を​​返すことを目的としたこのテンプレートは、SFMでは機能しません:

    {series:uppercase(substr(0,5))}
    
  • TPMGPM は、入れ子の関数をサポートします。 TPM の上記のテンプレートは次のようになります。

    {series:'uppercase(substr($, 0,5))'}
    

    GPM では次のようになります:

    program: uppercase(substr(field('series'), 0,5))
    
  • 上記のテンプレートプログラムモードのセクションで説明したように、TPM文字列リテラルで { および } 文字を使用すると、テンプレートプロセッサが混乱するため、エラーや予期しない結果が発生する可能性があります。それらを文字ではなくテンプレート境界として処理しようとします。すべてではありませんが {[[ に、そして }]] に置き換えることができる場合もあります。一般的に、プログラムに {} の文字が含まれている場合には 一般プログラムモード を使用すべきです。

ユーザ定義の Python テンプレート関数

テンプレートプロセッサに独自のPython関数を追加できます。これらの関数は、3つのテンプレートプログラミングモードすべてで使用可能です。関数を追加するには、環境設定  →  詳細設定  →  テンプレート関数 を選択してください。詳しい手順は、このダイアログに表示されています。なお、同様の目的で Pythonテンプレート を使用することもできます。ユーザー定義関数を呼び出す方がPythonテンプレートを呼び出すよりも高速であるため、関数またはテンプレートの処理内容の複雑さによっては、ユーザー定義関数の方が効率的になる場合があります。

異なるコンテキストでテンプレートを使用するときの特別な注意

GUI(他の列から作成された列 および テンプレート検索 )では:

  • GPMテンプレートは以前と同様に機能します。

  • Pythonテンプレートは、calibreデータベースにフルアクセスできます。

アイコンルールでは:

  • アイコンルールテンプレートには本のデータが含まれていないため、:ref:`ff_format_date_field:ref:`ff_list_count_field:ref:`ff_check_yes_no といったフィールドベースの関数は機能しません。

コンテンツサーバでは:

  • テンプレートは新しいAPIにはアクセスできますが、古いAPI(ライブラリデータベース)にはアクセスできません。

  • 以上の理由により、以下のフォーマッタ関数はGPMテンプレート(複合列、アイコンルールなど)では正常に動作することが保証されないため、コンテンツサーバーを使用する場合は使用を避けてください。

テンプレートの保存/送信に関する特記事項

Special processing is applied when a template is used in a Save to disk or Send to device template. The values of the fields are cleaned, replacing characters that are special to file systems with underscores, including slashes. This means that field text cannot be used to create folders. However, slashes are not changed in prefix or suffix strings, so slashes in these strings will cause folders to be created. Because of this, you can create variable-depth folder structure.

たとえば、フォルダの構造を series/series_index - title としたいが、シリーズが存在しない場合はタイトルを最上位のフォルダに配置したいと仮定します。これを行うためのテンプレートは次のとおりです:

{series:||/}{series_index:|| - }{title}

スラッシュとハイフンは、シリーズが空でない場合にのみ表示されます。

ルックアップ関数を使用すると、さらに高度な処理を実行できます。たとえば、本にシリーズがあるときにはフォルダ構造を series/series index - title.fmt にしたいと仮定します。そして本にシリーズがない場合は、フォルダ構造を genre/author_sort/title.fmt にしたいものとします。その本にジャンルがない場合は 'Unknown' を使用します。series の値に応じて、2つの完全に異なるパスが必要です。

これを達成するには:

  1. {series}/{series_index} - {title} を含む複合フィールドを作成します (ルックアップ名 #aa を指定します)。シリーズが空でなければ、このテンプレートは series/series_index - title を生成します。

  2. {#genre:ifempty(Unknown)}/{author_sort}/{title} を含む複合フィールドを作成します (ルックアップ名 #bb を指定します)。このテンプレートは genre/author_sort/title を生成し、空のジャンルは Unknown に置き換えられます。

  3. 保存テンプレートを {series:lookup(.,#aa,#bb)} に設定します。このテンプレートは、シリーズが空でない場合は複合フィールド #aa を、シリーズが空の場合は複合フィールド #bb を選択します。したがって、 series が空であるかどうかによって、完全に異なる2つの保存パスを提供することになります。

ヒント

  • テンプレートテスタを使用してテンプレートをテストします。テスタをライブラリ内の本のコンテキストメニューに追加するか、キーボードショートカットを指定します。

  • テンプレートは、他のテンプレートを使用できます。それをするには、使用したいテンプレートの作成した複合列を参照します。または、保存済みテンプレートを使用することもできます。

  • プラグボードでは、特殊なテンプレート {} を使用することで、フィールドを空(または空に相当するもの)に設定できます。このテンプレートは常に空の文字列として評価されます。

  • ゼロ値であっても数値を表示する上記の手法は、標準フィールド series_index で機能します。

テンプレート関数リファレンス