De calibre sjabloontaal¶
De calibre sjabloontaal is een calibre-eigen taal gebruikt doorheen calibre voor taken zoals specificeren van bestandspaden, opmaken van waarden en berekenen van de waarde voor gebruiker-gespecificeerde kolommen. Voorbeelden:
Specificeer de mappenstructuur en bestandsnamen bij opslaan van bestanden van de calibre bibliotheek naar de schijf of e-boekreader.
Definieer regels voor toevoegen van iconen en kleuren aan calibre’s boekenlijst.
Definieer virtuele kolommen die data bevatten van andere kolommen.
Geavanceerd bibliotheek zoeken.
Geavanceerd metadata zoeken en vervangen.
De taal is gebouwd rond het concept van een sjabloon die specificeert welke metadata te gebruiken, berekeningen op die metadata en hoe het opgemaakt moet worden.
Basis sjablonen¶
Een basissjabloon bestaat uit één of meer template expressions
. Een template expression
bestaat uit tekst en namen tussen accolades ({}
) die wordt vervangen door de overeenkomende metadata van het boek in verwerking. Bv. de standaard sjabloon in calibre gebruikt voor boeken naar toestel opslaan heeft vier template expressions
:
{author_sort}/{title}/{title} - {authors}
Voor het boek “The Foundation” door “Isaac Asimov” wordt dit:
Asimov, Isaac/The Foundation/The Foundation - Isaac Asimov
De schuine strepen zijn geen template expressions
omdat ze tussen {}
staan. Zulke tekst blijft waar ie is. Bv., als de sjabloon is:
{author_sort} Some Important Text {title}/{title} - {authors}
dan voor “The Foundation” produceert de sjabloon:
Asimov, Isaac Some Important Text The Foundation/The Foundation - Isaac Asimov
Een template expression
heeft toegang tot alle metadata in calibre, inbegrepen aangepaste kolommen (kolommen die u zelf creëerde), door de kolom z’n lookup name
te gebruiken. Om een kolom z’n lookup name te vinden (soms velden genaamd), zweef met uw muis over de kolom header in calibre’s boekenlijst. Lookup names voor aangepaste kolommen beginnen altijd met #
. Voor reeks type kolommen is er een bijkomend veld genaamd #lookup name_index
wat de serie index is voor dat boek in de serie. Bv., als u een aangepaste serie hebt genaamd #myseries
dan zal er ook een kolom zijn genaamd #myseries_index
. De standaard serie kolom index heet series_index
.
Naast de kolom gebaseerde velden, kunt u gebruik maken van:
{formats}
- Een lijst van formaten beschikbaar in de calibre bibliotheek voor een boek
{identifiers:select(isbn)}
- De ISBN van het boek
Als de metadata voor het veld voor een bepaald boek niet gedefinieerd is wordt het veld in de sjabloon vervangen door de lege string (''
). Bv. overweeg volgende sjabloon:
{author_sort}/{series}/{title} {series_index}
Als Asimov’s boek “Second Foundation” in de serie “Foundation” is dan geeft de sjabloon:
Asimov, Isaac/Foundation/Second Foundation 3
Als er voor een boek geen serie is ingevoerd geeft de sjabloon:
Asimov, Isaac/Second Foundation
De sjabloonverwerker verwijdert automatisch meerdere schuine strepen en voorloop en volg spaties.
Geavanceerde opmaak¶
Bovenop metadatasubstitutie kunnen sjablonen voorwaardelijk extra tekst opnemen en de opmaak van gesubstitueerde gegevens controleren.
Voorwaardelijk tekst opnemen
Soms wilt u dat tekst enkel in de uitvoer verschijnt als een veld niet leeg is. Een veel voorkomend geval is series
en series_index
waar u ofwel niets wil of de twee waarden gescheiden door een streepje. calibre doet dit via een speciale template expression
syntaxis.
Bv. met het Foundation voorbeeld van boven, veronderstel dat u wilt dat de sjabloon Foundation - 3 - Second Foundation geeft. Deze sjabloon geeft die uitvoer:
{series} - {series_index} - {title}
Alhoewel, als een boek geen deel van een serie is, geeft de sjabloon - - de titel, wat waarschijnlijk niet is wat u wilt. Gewoonlijk willen de mensen als resultaat de titel zonder extra streepjes. Dit kan met de volgende sjabloon syntaxis:
{field:|prefix_text|suffix_text}
Deze template expression
zegt dat als field
de waarde XXXX heeft, het resultaat prefix_textXXXXXsuffix_text zal zijn. Als field
leeg is (heeft geen waarde) dan zal het resultaat de lege string zijn (niets) omdat voor- en achtervoegsel genegeerd worden. Het voor- en achtervoegsel kunnen lege plekken hebben.
Gebruik geen subsjablonen (`{ … }`) of functies (zie onder) in het voor- of achtervoegsel.
Met deze syntaxis kunnen we het geen-serie probleem boven oplossen met de sjabloon:
{series}{series_index:| - | - }{title}
De streepjes komen er enkel bij als het boek een serie index heeft, die het enkel heeft als het deel van een serie is. Verder weer met het Foundation voorbeeld, de sjabloon geeft Foundation - 1 - Second Foundation.
Aantekeningen:
U moet een dubbel punt zetten na de
lookup name
als u een voor- of achtervoegsel gebruikt.U moet ofwel beide ofwel geen
|
karakters gebruiken. Eén gebruiken, zoals in{field:| - }
, is niet toegelaten.Het is oké om geen tekst te voorzien voor voor- of achtervoegsel, zoals in
{series:|| - }
. De sjabloon{title:||}
is hetzelfde als{title}
.
Opmaak
Veronderstel dat u series_index
opgemaakt wilt als drie cijfers met voorloopnullen. Dit doet de truc:
{series_index:0>3s}
- Drie cijfers met voorloopnullen
Voor volgnullen, gebruik:
{series_index:0<3s}
- Drie cijfers met volgnullen
Als u reeksindexen gebruikt met fractionele waarden, bv. 1,1, hebt u de komma’s misschien graag uitgelijnd. Bv. u hebt misschien graag dat indexen 1 en 2,5 eruit zien als 01,00 en 02,50 zodat ze correct sorteren op een toestel dat lexicaal sorteert. Om dit te doen, gebruik:
{series_index:0>5.2f}
- Vijf karakters bestaande uit twee cijfers met voorloopnullen, een komma en twee cijfers na de komma.
Als u enkel de twee eerste letters van de data wil, gebruik:
{author_sort:.2}
- Enkel de eerste twee letters van de auteursorteernaam
Veel van de calibre sjabloontaalvormgeving komt van Python. Voor meer details over de syntaxis van deze geavanceerde vormgevingsoperaties zie de Python documentatie.
Sjablonen gebruiken om aangepaste kolommen te definiëren¶
Sjablonen kunnen gebruikt worden om informatie weer te geven niet in calibre’s metadata of metadata afwijkend van calibre’s gewone formaat. Bv. u wilt misschien het ISBN
tonen, een veld dat calibre niet weergeeft. Dit kan door een aangepaste kolom te creëren van het type Kolom gemaakt van andere kolommen (hierna samengestelde kolommen) en een sjabloon te voorzien om de weer te geven tekst te genereren. De kolom geeft het resultaat weer van het evalueren van de sjabloon. Bv. om het ISBN weer te geven, creëer de kolom en voer {identifiers:select(isbn)}
in in het sjabloon vak. Om een kolom weer te geven met de waardes van twee series aangepaste kolommen, gescheiden door een komma, gebruik {#series1:||,}{#series2}
.
Samengestelde kolommen kunnen elke sjabloonoptie gebruiken, inclusief opmaak.
Nota: U kan data getoond in een samengestelde kolom niet bewerken. U moet de bronkolommen bewerken. Als u een samengestelde kolom bewerkt, bv. door erop dubbel te klikken, zal calibre de bewerksjabloon openen, niet de onderliggende data.
Templates and plugboards¶
Plugboards are used for changing the metadata written into books during send-to-device and save-to-disk operations. A plugboard permits you to specify a template to provide the data to write into the book’s metadata. You can use plugboards to modify the following fields: authors, author_sort, language, publisher, tags, title, title_sort. This feature helps people who want to use different metadata in books on devices to solve sorting or display issues.
When you create a plugboard, you specify the format and device for which the plugboard is to be used. A special device is provided, save_to_disk
, that is used when saving formats (as opposed to sending them to a device). Once you have chosen the format and device, you choose the metadata fields to change, providing templates to supply the new values. These templates are connected to their destination fields, hence the name plugboards. You can of course use composite columns in these templates.
Plugboards are quite flexible and can be written in Single Function Mode, Template Program Mode, General Program Mode, or Python Template mode.
When a plugboard might apply (Content server, save to disk, or send to device), calibre searches the defined plugboards to choose the correct one for the given format and device. For example, to find the appropriate plugboard for an EPUB book being sent to an ANDROID device, calibre searches the plugboards using the following search order:
een adapter met een exacte overeenkomst op formaat en toestel, bv.
EPUB
enANDROID
a plugboard with an exact match on format and the special
any device
choice, e.g.,EPUB
andany device
een adapter met de speciale
any format
keuze en een exacte overeenkomst op toestel, bv.any format
enANDROID
a plugboard with
any format
andany device
De labels en auteurs velden hebben een speciale behandeling omdat beide velden meer dan één item kunnen vasthouden. Een boek kan vele labels en meerdere auteurs hebben. Als u opgeeft dat één van deze twee velden gewijzigd gaat worden, wordt de template resultaat onderzocht om te zien of meer dan één item is. Voor labels wordt het resultaat gescheiden waar Calibre een komma vindt. Bijvoorbeeld, als de template de waarde `` Thriller, Horror`` produceert, dan zal het resultaat twee labels zijn, Thriller
en Horror
. Er is geen manier om een komma in het midden van een tag te zetten.
The same thing happens for authors, but using a different character for the cut, a & (ampersand) instead of a comma. For example, if the template produces the value Blogs, Joe&Posts, Susan
, then the book will end up with two authors, Blogs, Joe
and Posts, Susan
. If the template produces the value Blogs, Joe;Posts, Susan
, then the book will have one author with a rather strange name.
Plugboards affect the metadata written into the book when it is saved to disk or written to the device. Plugboards do not affect the metadata used by save to disk
and send to device
to create the file names. Instead, file names are constructed using the templates entered on the appropriate preferences window.
Functies gebruiken in sjablonen - Eén Functie Modus¶
Veronderstel dat u de waarde van een veld in hoofdletters wil tonen wanneer dat veld normaal elk woord met beginhoofdletter toont. Dit kan met sjabloonfuncties. Bv., om de titel in hoofdletters te tonen, gebruik de uppercase
functie, zoals in {title:uppercase()}
. Om met beginhoofdletters te tonen, gebruik {title:titlecase()}
.
Functies gaan in het formaat deel van de sjabloon, na de :
en voor de eerste |
of de sluit }
als geen voor- of achtervoegsel is gebruikt. Als u zowel een formaat als een functie referentie hebt, komt de functie na een tweede :
. Functies geven de waarde terug van de kolom gespecificeerd in de sjabloon, gepast gewijzigd.
De syntaxis voor gebruik van functies is een van:
{lookup_name:function(arguments)}
{lookup_name:format:function(arguments)}
{lookup_name:function(arguments)|prefix|suffix}
{lookup_name:format:function(arguments)|prefix|suffix}
Functienamen moeten altijd gevolgd worden door open/sluithaakjes. Sommige functies hebben extra waarden (argumenten) nodig en deze staan tussen de haakjes. Argumenten worden gescheiden door komma’s. Letterlijke komma’s (als tekst, niet als argumenten scheiders) moeten vooraf gegaan worden door een achteroverhellend streepje (\
). Het laatste (of enige) argument kan geen tekstueel sluithaakje bevatten.
Functies worden geëvalueerd voor formaat specificaties en het voor-/achtervoegsel. Kijk verder beneden voor een voorbeeld van gebruik van zowel een formaat als een functie.
Belangrijk: Als u programmeerervaring hebt, hou er a.u.b. rekening mee dat de syntaxis in Eén Functie Modus niet is wat u verwacht. Strings hebben geen aanhalingstekens en spaties zijn belangrijk. Alle argumenten worden gezien als contanten; er zijn geen expressies.
Gebruik geen subsjablonen (`{ … }`) als functie argumenten. In plaats daarvan, gebruik Sjabloon Programma Modus en Algemene Programma Modus.
Sommige functies vereisen reguliere expressies. In de sjabloontaal zijn reguliere expressie overeenkomsten niet hoofdlettergevoelig.
In de functie documentatie onder betekent de notatie [something]*
dat something
nul of meer keren herhaald kan worden. De notatie [something]+
betekent dat something
één of meer keren herhaald wordt (moet minstens één keer bestaan).
De functies bedoeld voor gebruik in Eén Functie Modus zijn:
capitalize()
– geeft de waarde terug met de eerste letter als hoofdletter en de rest klein.contains(pattern, text if match, text if not match)
– controleert of de waarde overeen komt met het reguliere expressiepattern
. Geefttext if match
terug als het pattern overeenkomt met de waarde, anderstext if no match
.count(separator)
– interpreteert de waarde als een lijst van termen gescheiden doorseparator
en geeft het aantal items in de lijst terug. Meeste lijsten gebruiken een komma als scheiding maarauthors
gebruikt een ampersand (&). Bv.:{tags:count(,)}
,{authors:count(&)}
. Aliassen:count()
,list_count()
format_number(template)
– interpreteert de waarde als een getal en formateert dat getal met een Python formateersjabloon zoals{0:5.2f}
of{0:,d}
of${0:5,.2f}
. De formateersjabloon moet beginnen met{0:
en eindigen met}
zoals in de voorbeelden boven. Uitzondering: u kan de voorloop “{0:” en volg “}” weglaten als de formateersjabloon enkel een formaat bevat. Bekijk de sjabloontaal en de Python documentatie voor meer voorbeelden. Geeft de lege string terug als formateren mislukt.human_readable()
– verwacht een cijfer als waarde en geeft een string terug die dat cijfer voorstelt in KB, MB, GB, enz.ifempty(text if empty)
– als de waarde niet leeg is, geef dan de waarde van het veld terug, anders tekst als leeg.in_list(separator, [ pattern, found_val, ]* not_found_val)
– interpreteert de waarde als een itemlijst gescheiden doorseparator
, hetpattern
controlerend tegen elk item in de lijst. Als hetpattern
overeen komt met een item komtfound_val
terug, andersnot_found_val
. Het paarpattern
enfound_value
kan zo vaak als gewenst herhaald worden, toelatend verschillende waarden terug te geven, afhankelijk van item’s waarde. De patterns worden op volgorde gecontroleerd en de eerste overeenkomst wordt terug gegeven.language_strings(localize)
– geef de taalnamen terug voor de taalcodes ingegeven als de waarde. Bv.:{languages:language_strings()}
. Alslocalize
nul is, geef de string in het Engels terug. Alslocalize
niet nul is, geef de string terug in de taal van de huidige locale.Lang_codes
is een komma gescheiden lijst.list_item(index, separator)
– begrijp de waarde als een lijst met items gescheiden doorseparator
, terug gevend het ‘index’th item. Het eerste item is nummer nul. Het laatste item heeft index-1
zoals inlist_item(-1,separator)
. Als het item niet op de lijst staat, wordt een lege string terug gegeven.lookup([ pattern, key, ]* else_key)
– De patronen worden gecontroleerd tegen de waarde op volgorde. Als een patroon overeenkomt, wordt de waarde van het veld benoemd doorkey
teruggegeven. Als geen patroon overeenkomt, wordt de waarde van het veld benoemd doorelse_key
teruggegeven. Kijk bijswitch
(onder).lowercase()
– geeft de waarde van het veld terug in kleine letters.rating_to_stars(use_half_stars)
– Geeft de waardering terug als een string ster (★
) karakters. De waarde moet een cijfer zijn tussen 0 en 5. Stel use_half_stars in op 1 als u halve ster karakters wilt voor fractionele getallen beschikbaar met aangepaste waarderingskolommen.re(pattern, replacement)
– geef de waarde terug na toepassen reguliere expressie. Alle exemplaren vanpattern
in de waarde worden vervangen doorreplacement
. De sjabloontaal gebruikt hoofdletterongevoelige Python reguliere expressies.select(key)
– interpreteer de waarde als een komma gescheiden lijst met items waar elk item de vormid:value
heeft (het calibreidentifier
formaat). De functie vindt het eerste paar met het id gelijk aan de sleutel en geeft de overeenkomende waarde terug. Als geen id overeenkomt, geeft de functie de lege string terug.shorten(left chars, middle text, right chars)
– Geeft een verkorte versie van de waarde terug, bestaande uitleft chars
karakters van het begin van de waarde, gevolgd doormiddle text
, gevolgd doorright chars
karakters van het einde van de waarde.Left chars
enright chars
moeten niet-negatieve integers zijn. Bv.: veronderstel u wilt de titel tonen met een lengte van maximaal 15 karakters. Een sjabloon die dat doet is{title:shorten(9,-,5)}
. Voor een boek met de titel Ancient English Laws in the Times of Ivanhoe zal het resultaat Ancient E-nhoe zijn: de eerste 9 karakters van de titel, een-
, dan de laatste 5 karakters. Als de lengte van de waarde minder is danleft chars
+right chars
+ de lengte vanmiddle text
wordt de waarde onveranderd teruggegeven. Bv. de titel The Dome wordt niet veranderd.str_in_list(separator, [ string, found_val, ]+ not_found_val)
– interpreteer de waarde als een lijst met items gescheiden doorseparator
vergelijk danstring
met elke waarde in de lijst. Destring
is geen reguliere expressie. Alsstring
gelijk is aan een item (hoofdlettergebruik negerend) geef dan de bijhorendefound_val
terug. Bevatstring
separators
, wordt het ook als een lijst behandeld en elke subwaarde gecontroleerd. Destring
enfound_value
paren kunnen naar believen herhaald worden, teruggave van verschillende waardes toelatend afhankelijk van de string waarde. Komt geen enkele string overeen, wordtnot_found_value
teruggegeven. Strings worden in volgorde gecontroleerd. De eerste overeenkomst wordt teruggegeven.subitems(start_index, end_index)
– Deze functie wordt gebruikt om lijsten van label-like hiërarchische items zoals genres op te delen. Het interpreteert de waarde als een komma gescheiden lijst label-like items, waar elk item een punt gescheiden lijst is. Geeft een nieuwe lijst terug van elk de componenten vanstart_index
totend_index
af te trekken en vervolgens de resultaten terug te combineren. Dubbels worden verwijderd. Het eerste sub-item in een punt gescheiden lijst heeft een index van nul. Als een index negatief is, dan telt het vanaf het einde van de lijst. Als speciaal geval wordt een end_index van nul verondersteld de lengte van de lijst te zijn.Voorbeelden:
Een #genre kolom veronderstellend met A.B.C:
{#genre:subitems(0,1)}
geeft “A” terug{#genre:subitems(0,2)}
geeft “A.B” terug{#genre:subitems(1,0)}
geeft “B.C” terug
Een #genre kolom veronderstellend met “A.B.C, D.E”:
{#genre:subitems(0,1)}
geeft “A, D” terug{#genre:subitems(0,2)}
geeft “A.B, D.E” terug
sublist(start_index, end_index, separator)
– interpreteert de waarde als een itemlijst gescheiden doorseparator
, geeft een nieuwe lijst terug, gemaakt van de items vanstart_index
totend_index
. Het eerstet item is nummer zero. Als een index negatief is, dan telt hij van het einde van de lijst. Als een speciaal geval: een end_index van nul is wordt verondersteld de lengte van de lijst te zijn.Voorbeelden veronderstellen dat de labelkolom (die komma gescheiden is) “A, B ,C” bevat:
{tags:sublist(0,1,\,)}
geeft “A” terug{tags:sublist(-1,0,\,)}
geeft “C” terug{tags:sublist(0,-1,\,)}
geeft “A, B” terug
swap_around_articles(separator)
– geeft de waarde terug met artikelen naar het einde verplaatst. De waarde kan een lijst zijn, in welk geval elk item van de lijst verwerkt is. Als de waarde een lijst is dan moet u deseparator
voorzien. Als geenseparator
voorzien is, wordt de waarde behandeld als één enkele waarde, niet een lijst. De artikelen zijn diegenen gebruikt door calibre om detitle_sort
te genereren.swap_around_comma()
– gegeven een waarde in de vormB, A
, wordtA B
. Dit is heel nuttig voor het omzetten van namen in AN, VN formaat naar VN AN. Als er geen komma is, wordt de waarde onveranderd teruggegeven.switch([pattern, value,]+ else_value)
– voor iederpattern, value
paar, controleert of het waarde overeen komt met de reguliere expressiepattern
en indien zo geeft de geassocieerde``value`` terug. Als geenpattern
overeenkomt, wordtelse_value
teruggegeven. U kan zoveelpattern, value
paren hebben als u wilt. De eerste overeenkomst wordt teruggegeven.test(text if not empty, text if empty)
– geeftext if not empty
terug als de waarde niet leeg is, geef anderstext if empty
terug.titlecase()
– geeft de waarde van het veld terug in elk woord met hoofdletter.transliterate()
– Geeft een string in een Latijns alfabet terug, gevormd door benaderen van de klank van de woorden in het bron veld. Bij voorbeeld, wanneer het bron veldФёдор Миха́йлович Достоевский
is, geeft deze functieFiodor Mikhailovich Dostoievskii
terug.uppercase()
– geeft de waarde van het veld terug in hoofdletter.
Functies en opmaak gebruiken in dezelfde sjabloon
Veronderstel, u hebt een aangepaste kolom met gehele getallen #myint
die u wilt weergeven met voorloopnullen, zoals in 003
. Een manier om dit te doen is met het formaat 003
. Hoewel, standaard, als een getal (geheel of decimaal) gelijk is aan nul wordt de waarde getoond als de lege string dus nul waardes geven de lege string, niet 000
. Als u 000
waardes wilt zien, gebruikt u zowel de formaat string als de ifempty
functie om de lege waarde terug op nul te zetten. De sjabloon wordt:
{#myint:0>3s:ifempty(0)}
Merk op dat u zowel het voor- als het achtervoegsel kan gebruiken. Als u wil dat het getal verschijnt als [003]
of [000]
, gebruik dan de sjabloon:
{#myint:0>3s:ifempty(0)|[|]}
Algemene Programma Modus¶
Algemene Programma Modus (APM) vervangt sjabloonexpressies door een programma geschreven in de sjabloontaal. De syntaxis van de taal is gedefinieerd door de volgende grammatica:
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' |
'==#' | '!=#' | '>=#' | '>#' | '<=#' | '<#'
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 |
'(' 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 ] ] ')'
list_expr ::= top_expression
break_expr ::= 'break'
continue_expr ::= 'continue'
separator_expr ::= top_expression
start_expr ::= top_expression
stop_expr ::= top_expression
step_expr ::= top_expression
limit_expr ::= top_expression
Aantekeningen:
een
top_expression
heeft altijd een waarde. De waarde van eenexpression_list
is de waarde van de laatstetop_expression
in de lijst. Bv. de waarde van de expressielijst1;2;'foobar';3
is3
.In een logische context is elke niet-lege waarde
True
In een logische context is de lege waarde
False
Strings en getallen kunnen door elkaar gebruikt worden. Bv.
10
en'10'
zijn identiek.Commentaar zijn regels die beginnen met ‘#’. Commentaar verder in de regel wordt niet ondersteund.
Operator voorrang
De operator voorrang (volgorde van evalueren) van hoogste (eerst geëvalueerd) naar laagste (laatst geëvalueerd) is:
Functie aanroep, constanten, uitdrukkingen tussen haakjes, instructie-expressies, opdracht-expressies, veldreferenties.
Unary plus (
+
) en min (-
). Deze operatoren evalueren van rechts naar links.Deze en alle andere rekenkundige operatoren geven integers terug als het resultaat van de expressie een fractioneel deel gelijk aan nul is. Bv. als een expressie
3.0
terug geeft, wordt dit veranderd in3
.Vermenigvuldigen (
*
) en delen (/
). Deze operatoren zijn associatief en evalueren van links naar rechts. Gebruik haakjes als u de volgorde van evaluatie wilt veranderen.Optellen (
+
) en aftrekken (-
). Deze operatoren zijn associatief en evalueren van links naar rechts.Numerieke en string vergelijkingen. Deze operatoren geven
'1'
terug als de vergelijking door gaat, anders de lege string (''
). Vergelijkingen zijn niet associatief:a < b < c
is een syntaxis fout.String concatenation (
&
). The&
operator returns a string formed by concatenating the left-hand and right-hand expressions. Example:'aaa' & 'bbb'
returns'aaabbb'
. The operator is associative and evaluates left to right.Unary logisch niet (
!
). Deze operator geeft'1'
terug als de expressie Vals is (evalueert naar de lege string), anders''
.Logisch en (
&&
). Deze operator geeft ‘1’ terug als zowel de linker- als de rechter-kant expressies Waar zijn, of de lege string''
als een van beide Vals is. Het is associatief, evalueert van links naar rechts en doet aan kort-sluiten.Logische of (
||
). Deze operator geeft'1'
terug als ofwel de linker- ofwel de rechterkant expressie Waar is, of''
als beide Vals zijn. Hij is associatief, evalueert van links naar rechts en doet aan kort-sluiten. Het is een inclusieve of, geeft'1'
terug als zowel de linker- en rechterkant expressies Waar zijn.
Veldreferenties
Een field_reference
evalueert naar de waarde van het metadata veld genoemd bij lookup name dat volgt op $
or $$
. Gebruik van $
is equivalent aan gebruik van de field()
functie. Gebruik van $$
is equivalent aan gebruik van de raw_field
functie. Bv.:
* $authors ==> field('authors')
* $#genre ==> field('#genre')
* $$pubdate ==> raw_field('pubdate')
* $$#my_int ==> raw_field('#my_int')
If expressies
If
expressies evalueren eerst de condition
. Als de condition
Waar is (een niet-lege waarde) wordt de expression_list
in de then
clausule geëvalueerd. Als ze Onwaar is wordt, indien aanwezig, de expression_list
in de elif
of else
clausule geëvalueerd. De elif
en else
delen zijn optioneel. De woorden if
, then
, elif
, else
, en fi
zijn gereserveerd; U kan ze niet gebruiken als identificator namen. U kan nieuwe regels en spaties zetten overal waar het zin heeft. De condition
is een top_expression
geen expression_list
; puntkomma’s zijn niet toegelaten. De expression_lists
zijn puntkomma gescheiden reeksen met top_expressions
. Een if
expressie geeft het resultaat terug van de laatste top_expression
in de geëvalueerde expression_list
, of de lege string als geen expressie lijst werd geëvalueerd.
Voorbeelden:
* 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)
Genest if
voorbeeld:
program:
if field('series') then
if check_yes_no(field('#mybool'), '', '', '1') then
'yes'
else
'no'
fi
else
'no series'
fi
Zoals boven gezegd, een if
geeft een waarde. Dat betekent dat al de volgenden equivalent zijn:
* 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
Als laatste voorbeeld, dit programma geeft de waarde van de series
kolom terug als het boek van een serie is, anders de waarde van de title
kolom:
program: field(if field('series') then 'series' else 'title' fi)
For expressies
The for
expression iterates over a list of values, processing them one at a time. The list_expression
must evaluate either to a metadata field lookup name
e.g., tags
or #genre
, or to a list of values. The range() function (see below) generates a list of numbers. If the result is a valid lookup name
then the field’s value is fetched and the separator specified for that field type is used. If the result isn’t a valid lookup name then it is assumed to be a list of values. The list is assumed to be separated by commas unless the optional keyword separator
is supplied, in which case the list values must be separated by the result of evaluating the separator_expr
. A separator cannot be used if the list is generated by range()
. Each value in the list is assigned to the specified variable then the expression_list
is evaluated. You can use break
to jump out of the loop, and continue
to jump to the beginning of the loop for the next iteration.
Voorbeeld: Deze sjabloon verwijdert de eerste hiërarchische naam voor elke waarde in Genre (#genre
), een lijst opbouwend met de nieuwe namen:
program:
new_tags = '';
for i in '#genre':
j = re(i, '^.*?\.(.*)$', '\1');
new_tags = list_union(new_tags, j, ',')
rof;
new_tags
Als het originele Genre History.Military, Science Fiction.Alternate History, ReadMe is dan geeft de sjabloon Military, Alternate History, ReadMe terug. U kan deze sjabloon gebruiken in calibre’s Metadata bewerken in bulk → Zoeken & vervangen met Zoeken naar ingesteld op template
om het eerste niveau van de hiërarchie te verwijderen en de resulterende waarde aan Genre toe te wijzen.
Merk op: de laatste regel in de sjabloon, new_tags
, is niet strikt nodig in dit geval omdat for
de waarde van de laatste top_expression terug geeft in de expressie lijst. De waarde van een opdracht is de waarde van zijn expressie, dus de waarde van het for
bericht is wat was toegewezen aan new_tags
.
Function definition
If you have code in a template that repeats then you can put that code into a local function. The def
keyword starts the definition. It is followed by the function name, the argument list, then the code in the function. The function definition ends with the fed
keyword.
Arguments are positional. When a function is called the supplied arguments are matched left to right against the defined parameters, with the value of the argument assigned to the parameter. It is an error to provide more arguments than defined parameters. Parameters can have default values, such as a = 25
. If an argument is not supplied for that parameter then the default value is used, otherwise the parameter is set to the empty string.
The return
statement can be used in a local function.
A function must be defined before it can be used.
Example: This template computes an approximate duration in years, months, and days from a number of days. The function to_plural()
formats the computed values. Note that the example also uses the &
operator:
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')
Relationele operatoren
Relationele operatoren geven '1'
terug als de vergelijking waar is, anders de lege string (‘’).
Er zijn twee soorten relationele operatoren: string vergelijkingen en numerieke vergelijkingen.
String vergelijkingen doen hoofdletterongevoelige string vergelijking in lexicale volgorde. De ondersteunde vergelijkingsoperatoren zijn ==
, !=
, <
, <=
, >
, >=
, in
, en inlist
. Voor de in
operator wordt het resultaat van de linkse expressie geïnterpreteerd als een reguliere expressie patroon. De in
operator is Waar als de waarde van de linkse reguliere expressie overeenkomt met de waarde van de rechtse reguliere expressie. De inlist
operator is Waar als de linkse reguliere expressie overeenkomt met eender welk item in de rechtse lijst waar de items in de lijst gescheiden zijn door komma’s. De overeenkomsten zijn hoofdletterongevoelige.
De numerieke vergelijkingsoperatoren zijn ==#
, !=#
, <#
, <=#
, >#
, >=#
. De links en rechts expressies moeten evalueren naar numerieke waarden met twee uitzonderingen: zowel de string waarde “None” (niet gedefinieerd veld) en de lege string evalueren naar de waarde nul.
Voorbeelden:
program: field('series') == 'foo'
geett'1'
terug als het boek z’n serie ‘foo’ is, anders''
.
program: 'f.o' in field('series')
geeft'1'
terug als het boek z’n serie overeenkomt met de reguliere expressief.o
(bv., foo, Off Onyx, enz.), anders''
.
program: 'science' inlist field('#genre')
returns'1'
if any of the book’s genres match the regular expressionscience
, e.g., Science, History of Science, Science Fiction etc., otherwise''
.
program: '^science$' inlist field('#genre')
geeft'1'
terug als één van de boeken z’n genres exact overeenkomt met de reguliere expressie^science$
, bv., Science. De genres History of Science en Science Fiction komen niet overeen. Bij geen overeenkomst wordt''
teruggegeven.
program: if field('series') != 'foo' then 'bar' else 'mumble' fi
geeft'bar'
terug als het boek z’n serie nietfoo
is. Anders geeft het'mumble'
terug.
program: if field('series') == 'foo' || field('series') == '1632' then 'yes' else 'no' fi
geeft'yes'
terug als de serie ofwel``’foo’`` is ofwel'1632'
, anders'no'
.
program: if '^(foo|1632)$' in field('series') then 'yes' else 'no' fi
geeft'yes'
terug als de serie ofwel'foo'
is ofwel'1632'
, anders'no'
.
program: if 11 > 2 then 'yes' else 'no' fi
geeft'no'
omdat de>
operator een lexicale vergelijking doet.
program: if 11 ># 2 then 'yes' else 'no' fi
geeft'yes'
terug omdat de>#
operator een numerieke vergelijking doet.
Extra beschikbare functies
Volgende functies zijn beschikbaar bovenop die beschreven in Eén Functie Modus.
In APM hebben de functies beschreven in Eén Functie Modus allemaal een extra eerste parameter nodig die de waarde specificeert waarop te werken. Alle parameters zijn expression_lists (zie de grammatica boven).
add(x [, y]*)
– geeft de som van z’n argumenten terug. Gooit een uitzondering als een argument geen getal is. In de meeste gevallen kan u de+
operator gebruiken i.p.v. deze functie.and(value [, value]*)
– geeft de string “1” terug als geen enkele waarde leeg is, anders de lege string. U kan zoveel waardes hebben als u wil. In de meeste gevallen kan u de&&
operator gebruiken i.p.v. deze functie. Een reden omand
niet te vervangen door&&
is als short-circuiting de resultaten kan veranderen door bijwerkingen. Bv.and(a='',b=5)
zal altijd beide opdrachten doen terwijl de&&
operator de tweede niet zal doen.assign(id, val)
– wijstval
toe aanid
, geeft danval
terug.id
moet een identificator zijn, geen expressie. Meestal kan u de=
operator gebruiken i.p.v. deze functie.approximate_formats()
– geeft een komma gescheiden lijst terug met formaten geassocieerd met het boek. Er is garantie dat de lijst correct is maar waarschijnlijk wel. Deze en andere nul-parameter functies kunnen aangeroepen worden in Sjabloon Programma Modus (zie onder) met de sjabloon{:'approximate_formats()'}
. Merk op dat de resulterende formaatnamen altijd in hoofdletters zijn, zoals in EPUB. Deapproximate_formats()
functie is beduidend sneller dan deformats_...
functies besproken onder.author_links(val_separator, pair_separator)
– geeft een string terug met een lijst van auteurs en deze auteurs’ hun link waarde in de vorm:author1 val_separator author1_link pair_separator author2 val_separator author2_link etc.
Een auteur wordt gescheiden van z’n link waarde door de
val_separator
string zonder extra spaties.author:linkvalue
paren worden gescheiden door hetpair_separator
string argument zonder extra spaties. Het is aan u om separator strings te kiezen die niet in de auteursnaam of -links voorkomen. Een auteur wordt inbegrepen zelfs als de auteur link leeg is.author_sorts(val_separator)
– geeft een string terug die een lijst van auteur sorteer waarden bevat voor de auteurs van het boek. De sortering is diegene in de auteur’s metadata (anders dan de auteur_sort in boeken). De teruggegeven lijst heeft de vorm auteurauthor sort 1
val_separator
author sort 2
enz. De author_sort waarden in de lijst zijn in dezelfde volgorde als de auteurs van het boek. Indien u spaties wilt rondval_separator
zet deze in deval_separator
stringbook_count(query, use_vl)
– returns the count of books found by searching forquery
. Ifuse_vl
is0
(zero) then virtual libraries are ignored. This function and its companionbook_values()
are particularly useful in template searches, supporting searches that combine information from many books such as looking for series with only one book. It cannot be used in composite columns unless the tweakallow_template_database_functions_in_composites
is set to True. It can be used only in the GUI.For example this template search uses this function and its companion to find all series with only one book:
Define a stored template (using Preferences → Advanced → Template functions) named
series_only_one_book
(the name is arbitrary). The template is:program: vals = globals(vals=''); if !vals then all_series = book_values('series', 'series:true', ',', 0); for series in all_series: if book_count('series:="' & series & '"', 0) == 1 then vals = list_join(',', vals, ',', series, ',') fi rof; set_globals(vals) fi; str_in_list(vals, ',', $series, 1, '')
The first time the template runs (the first book checked) it stores the results of the database lookups in a
global
template variable namedvals
. These results are used to check subsequent books without redoing the lookups.Use the stored template in a template search:
template:"program: series_only_one_book()#@#:n:1"
Using a stored template instead of putting the template into the search eliminates problems caused by the requirement to escape quotes in search expressions.
book_values(column, query, sep, use_vl)
– returns a list of the unique values contained in the columncolumn
(a lookup name), separated bysep
, in the books found by searching forquery
. Ifuse_vl
is0
(zero) then virtual libraries are ignored. This function and its companionbook_count()
are particularly useful in template searches, supporting searches that combine information from many books such as looking for series with only one book. It cannot be used in composite columns unless the tweakallow_template_database_functions_in_composites
is set to True. It can be used only in the GUI.booksize()
– geeft de waarde van het calibre ‘grootte’ veld terug. Geeft ‘’ terug als er geen formaten zijn.check_yes_no(field_name, is_undefined, is_false, is_true)
– controleert of de waarde van het ja/nee veld genoemd door de opzoeknaamfield_name
is een van de waardes gespecificeerd door de parameters,'yes'
teruggevend als een overeenkomst werd gevonden anders de lege string. Stel de parameteris_undefined
,is_false
, ofis_true
in op 1 (het cijfer) om die voorwaarde te controleren, anders op 0. Bv.:check_yes_no("#bool", 1, 0, 1)
returns'Yes'
if the yes/no field#bool
is either True or undefined (neither True nor False).Meer dan een van
is_undefined
,is_false
, ofis_true
kan op 1 gezet worden.ceiling(x)
– geeft de kleinste integer terug groter dan of gelijk aanx
. Gooit een uitzondering alsx
geen getal is.character(character_name)
– geeft het karakter terug genoemd door character_name. Bv.:character('newline')
geeft een nieuwe regel karakter ('\n'
). De ondersteunde karakternamen zijnnewline
,return
,tab
enbackslash
.cmp(x, y, lt, eq, gt)
– vergelijktx
eny
na converteren van beiden naar getallen. Geetflt
ifx <# y
,eq
ifx ==# y
terug, andersgt
. Deze functie kan gewoonlijk vervangen worden door een van de numerieke vergelijkingsoperatoren (==#
,<#
,>#
, enz).connected_device_name(storage_location_key)
– als een toestel verbonden is, geef het toestel’s naam terug, anders de lege string. Elke opslaglocatie op een toestel heeft zijn eigen toestelnaam. Destorage_location_key
locatienamen zijn'main'
,'carda'
en'cardb'
. Deze functie werkt enkel in de GUI.connected_device_uuid(storage_location_key)
– als een toestel verbonden is, geef het toestel’s uuid (unique id) terug, anders de lege string. Elke opslaglocatie op een toestel heeft een ander uuid. Destorage_location_key
locatienamen zijn'main'
,'carda'
en'cardb'
. Deze functie werkt enkel in de GUI.current_library_name()
– geeft de laatste naam op het pad naar de huidige calibre bibliotheel terug.current_library_path()
– geeft het volledige pad naar de huidige calibre bibliotheek terug.current_virtual_library_name()
– geeft de naam van de huidige virtuele bibliotheek als er een is, anders de lege string. Bibliotheeknaam hoofdlettergebruik wordt behouden. Bv.:program: current_virtual_library_name()
. Deze functie werkt enkel in de GUI.date_arithmetic(date, calc_spec, fmt)
– Bereken een nieuwe datum vandate
metcalc_spec
. Geef de nieuwe datum terug geformatteerd volgens optioneelfmt
: indien niet voorzien zal het resultaat in ISO formaat zijn. De calc_spec is een string gevormd door aaneengeregen paren vanvW
(valueWhat
) waarv
een mogelijk-negatief getal is en W een van de volgende letters:s
: voegv
seconden toe aandate
m
: voegv
minuten toe aandate
h
: voegv
uren toe aandate
d
: voegv
dagen toe aandate
w
: voegv
weken toe aandate
y
: voegv
jaren toe aandate
, waar een jaar is 365 dagen.
Voorbeeld:
'1s3d-1m'
voegt 1 seconde, 3 dagen toe en trekt 1 minuut af vandate
.days_between(date1, date2)
– geeft het aantal dagen tussendate1
endate2
terug. Het aantal is positief alsdate1
groter is dandate2
, anders negatief. Als ofweldate1
ofweldate2
geen datum is, wordt de lege string terug gegeven.divide(x, y)
– returnsx / y
. Gooit een uitzondering als ofwelx
ofwely
geen getallen zijn. Deze functie kan gewoonlijk vervangen worden door de/
operator.eval(string)
– evalueert de string als een programma, de lokale variabelen doorgevend. Dit laat toe complexe resultaten te bouwen van lokale variabelen met de sjabloonprocessor. In Template Program Mode, omdat de { en } karakters geïnterpreteerd worden voor de sjabloon wordt geëvalueerd, moet u [[ gebruiken voor het { karakter en ]] voor het}
karakter. Ze worden automatisch omgezet. Merk ook op dat voor- en achtervoegsel (de |prefix|suffix syntaxis) niet gebruikt kunnen worden in het argument bij deze functie bij gebruik van Template Program Mode.extra_file_size(file_name)
– returns the size in bytes of the extra filefile_name
in the book’sdata/
folder if it exists, otherwise-1
. See also the functionshas_extra_files()
,extra_file_names()
andextra_file_modtime()
. This function can be used only in the GUI.extra_file_modtime(file_name, format_string)
– returns the modification time of the extra filefile_name
in the book’sdata/
folder if it exists, otherwise-1
. The modtime is formatted according toformat_string
(seeformat_date()
for details). Ifformat_string
is the empty string, returns the modtime as the floating point number of seconds since the epoch. See also the functionshas_extra_files()
,extra_file_names()
andextra_file_size()
. The epoch is OS dependent. This function can be used only in the GUI.extra_file_names(sep [, pattern])
returns asep
-separated list of extra files in the book’sdata/
folder. If the optional parameterpattern
, a regular expression, is supplied then the list is filtered to files that matchpattern
. The pattern match is case insensitive. See also the functionshas_extra_files()
,extra_file_modtime()
andextra_file_size()
. This function can be used only in the GUI.field(lookup_name)
– geeft de waarde terug van het metadata veld met opzoeknaamlookup_name
.field_exists(field_name)
– controleert of een veld (kolom) met de lookup naamfield_name
bestaat, geeft'1'
indien ja en de lege string indien niet.finish_formatting(val, fmt, prefix, suffix)
– pas het formaat, voor- en achtervoegsel toe op een waarde op dezelfde manier als in een sjabloon zoals{series_index:05.2f| - |- }
. Deze functie is voorzien om conversie te vergemakkelijken van ingewikkelde één-functie- of sjabloon-programma-modus sjablonen naar GPM Sjablonen. Bv. het volgende programma geeft dezelfde output als bovenstaande sjabloon:program: finish_formatting(field("series_index"), "05.2f", " - ", " - ")
Nog een voorbeeld: voor de sjabloon
{series:re(([^\s])[^\s]+(\s|$),\1)}{series_index:0>2s| - | - }{title}
gebruik:program: strcat( re(field('series'), '([^\s])[^\s]+(\s|$)', '\1'), finish_formatting(field('series_index'), '0>2s', ' - ', ' - '), field('title') )
first_matching_cmp(val, [ cmp, result, ]* else_result)
– vergelijktval < cmp
in volgorde, het geassocieerde resultaat teruggevend voor de eerste vergelijking die klopt. Geeft else_result terug als geen vergelijking klopt. Bv:i = 10; first_matching_cmp(i,5,"small",10,"middle",15,"large","giant")
geeft
"large"
terug. Hetzelfde voorbeeld met een eerste warde van 16 geeft"giant"
terug.first_non_empty(value [, value]*)
– geeft de eerstevalue
terug welke niet leeg is. Als alle waardes leeg zijn, wordt de lege string terug gegeven. U kan zo veel waardes opgeven als u wilt.floor(x)
– geeft de grootste integer terug kleiner dan of gelijk aanx
. Gooit een uitzondering alsx
geen getal is.format_date(val, format_string)
– maak de waarde op, die een datumstring moet zijn, met behulp van format_string, geef een string terug. De opmaakcodes zijn:d :
de dag als getal zonder voorloopnul (1 to 31)dd :
de dag als getal met voorloopnul (01 to 31)ddd :
de afgekorte gelokaliseerde dag naam (bv. “Maa” tot “Zon”).dddd :
de voluit gelokaliseerde dag naam (bv. “Maandag” tot “Zondag”).M :
de maand als getal zonder voorloopnul (1 to 12)MM :
de maand als getal met voorloopnul (01 to 12)MMM :
de afgekorte gelokaliseerde maandnaam (bv. “jan” tot “dec”).MMMM :
de voluit gelokaliseerde maandnaam (bv. “januari” tot “december”).yy :
het jaar als tweecijferig getal (00 tot 99).yyyy :
het jaar als viercijferig getal.h :
de uren zonder voorloopnul (0 tot 11 of 0 tot 23, afhankelijk van am/pm)hh :
de uren met voorloopnul (00 tot 11 of 00 tot 23, afhankelijk van am/pm)m :
de minuten zonder voorloopnul (0 tot 59)mm :
de minuten met voorloopnul (00 tot 59)s :
de seconden zonder voorloopnul (0 tot 59)ss :
de seconden met voorloopnul (00 tot 59)ap :
gebruik een 12-uur klok i.p.v. een 24-uur klok, met ‘ap’ vervangen door de gelokaliseerde string voor am of pm.AP :
gebruik een 12-uur klok i.p.v. een 24-uur klok, met ‘AP’ vervangen door de gelokaliseerde string voor AM of PM.iso :
de datum met tijd en tijdzone. Moet als enige formaat aanwezig zijn.to_number :
converteer de datum & tijd in een floating point getal (een tijdstempel)from_number :
converteer een floating point getal (een tijdstempel) in eeniso
opgemaakte datum. Als u een ander datumformaat wilt, voeg de gewenste opmaakstring toe nafrom_number
en een dubbel punt (:
). Bv:from_number:MMM dd yyyy
U kan onverwachte resultaten krijgen bij opmaken van een datum met gelokaliseerde maandnamen. Dit kan gebeuren als u de datumopmaak tweaks veranderde om
MMMM
te bevatten. In dit geval, i.p.v. defield()
functie te gebruiken zoals in:format_date(field('pubdate'), 'yyyy')
gebruik de
raw_field()
functie zoals in:format_date(raw_field('pubdate'), 'yyyy')
format_date_field(field_name, format_string)
– format the value in the fieldfield_name
, which must be the lookup name of date field, either standard or custom. Seeformat_date()
for the formatting codes. This function is much faster than format_date and should be used when you are formatting the value in a field (column). It can’t be used for computed dates or dates in string variables. Examples:format_date_field('pubdate', 'yyyy.MM.dd') format_date_field('#date_read', 'MMM dd, yyyy')
formats_modtimes(date_format_string)
– geeft een komma-gescheiden lijst van door streepjes gescheiden items terug die de wijzigingsdata van de formaten van een boek weergeven. Dedate_format_string
parameter geeft aan hoe de datum geformatteerd moet worden. Zie deformat_date()
functie voor details. U kunt deselect
functie gebruiken om de wijzigingsdatum van een specifiek formaat op te vragen. Let op dat formaatnamen altijd in hoofdletters zijn, zoals EPUB.formats_paths()
– geeft een komma gescheiden lijst van streepjes gescheidenFMT:PATH
items terug met het volledige pad naar de formaten van een boek. U kunt de select functie gebruiken om het pad naar een specifiek formaat te krijgen. Let op dat formaatnamen altijd in hoofdletters zijn, zoals EPUB.formats_sizes()
– geeft een komma gescheiden lijst van streepjes gescheidenFMT:PATH
items met de grootte van de formaten van een boek in bytes. U kunt de select functie gebruiken om de grootte van een specifiek formaat te krijgen. Let op dat formaatnamen altijd in hoofdletters zijn, zoals EPUB.fractional_part(x)
– geeft de waarde na het decimale punt. Bv.fractional_part(3.14)
geeft0.14
terug. Gooit een uitzondering alsx
geen getal is.get_link(field_name, field_value)
– fetch the link for fieldfield_name
with valuefield_value
. If there is no attached link, return the empty string. Examples:
The following returns the link attached to the tag
Fiction
:get_link('tags', 'Fiction')This template makes a list of the links for all the tags associated with a book in the form
value:link, ...
:program: ans = ''; for t in $tags: l = get_link('tags', t); if l then ans = list_join(', ', ans, ',', t & ':' & get_link('tags', t), ',') fi rof; ans
get_note(field_name, field_value, plain_text)
– fetch the note for field ‘field_name’ with value ‘field_value’. If plain_text is empty, return the note’s HTML including images. If plain_text is 1 (or ‘1’), return the note’s plain text. If the note doesn’t exist, return the empty string in both cases. Example:
Return the HTML of the note attached to the tag Fiction:
program: get_note('tags', 'Fiction', '')Return the plain text of the note attached to the author Isaac Asimov:
program: get_note('authors', 'Isaac Asimov', 1)
has_cover()
– geeft'Yes'
terug als het boek een omslag heeft, anders de lege string.has_extra_files([pattern])
– returns the count of extra files, otherwise ‘’ (the empty string). If the optional parameterpattern
(a regular expression) is supplied then the list is filtered to files that matchpattern
before the files are counted. The pattern match is case insensitive. See also the functionsextra_file_names()
,extra_file_size()
andextra_file_modtime()
. This function can be used only in the GUI.identifier_in_list(val, id_name [, found_val, not_found_val])
– treatval
as a list of identifiers separated by commas. An identifier has the formatid_name:value
. Theid_name
parameter is the id_name text to search for, eitherid_name
orid_name:regexp
. The first case matches if there is any identifier matching that id_name. The second case matches if id_name matches an identifier and the regexp matches the identifier’s value. Iffound_val
andnot_found_val
are provided then if there is a match then returnfound_val
, otherwise returnnot_found_val
. Iffound_val
andnot_found_val
are not provided then if there is a match then return theidentifier:value
pair, otherwise the empty string (''
).is_dark_mode()
– returns'1'
if calibre is running in dark mode,''
(the empty string) otherwise. This function can be used in advanced color and icon rules to choose different colors/icons according to the mode. Example:if is_dark_mode() then 'dark.png' else 'light.png' fi
is_marked()
– controleer of het boek gemarkeerd is in calibre. Indien ja, geef de waarde van de markering terug, ofwel'true'
(kleine letters) of een kommagescheiden lijst van benoemde markeringen. Geeft''
(de lege string) terug als het boek niet gemarkeerd is. Deze functie werkt enkel in de GUI.language_codes(lang_strings)
– geef de taalcodes terug voor de taalnamen doorgegeven in lang_strings. De strings moeten in de taal van de huidige locale zijn.Lang_strings
is een kommagescheiden lijst.list_contains(value, separator, [ pattern, found_val, ]* not_found_val)
– (Alias vanin_list
) Interpreteert de waarde als een lijst met items gescheiden doorseparator
, evalueert hetpattern
tegen elke waarde in de lijst. Als hetpattern
overeen komt met een waarde komtfound_val
terug, andersnot_found_val
. Depattern
enfound_value
kunnen zo vaak als gewenst herhaald worden, toelatend verschillende waarden terug te geven, afhankelijk van de zoekopdracht. De patterns worden op volgorde gecontroleerd. De eerste overeenkomst wordt terug gegeven. Aliassen:in_list()
,list_contains()
list_count(value, separator)
– interpreteertvalue
als een lijst met items gescheiden doorseparator
, geeft het aantal items in de lijst terug. Aliassen:count()
,list_count()
list_count_matching(list, pattern, separator)
– interpreteertlijst
als een lijst met items gescheiden doorseparator
, geeft het aantal items in de lijst terug die overeenkomen met de reguliere expressiepattern
. Aliassen:list_count_matching()
,count_matching()
list_difference(list1, list2, separator)
– geeft een lijst terug gemaakt door uitlist1
alle item te verwijderen gevonden inlist2
waarbij niet hoofdlettergevoelig wordt vergeleken. De items inlist1
enlist2
zijn gescheiden door separator, net zoals de items in de teruggegeven lijst.list_equals(list1, sep1, list2, sep2, yes_val, no_val)
– geefyes_val
terug alslist1
en list2 dezelfde items bevatten, andersno_val
. De items worden bepaald door iedere lijst te splitsen met het juiste scheidingsteken (sep1
orsep2
). De volgorde van items in de lijst is niet relevant. De vergelijking is hoofdletterongevoelig.list_intersection(list1, list2, separator)
– geeft een lijst terug gemaakt door uitlist1
alle item te verwijderen niet gevonden inlist2
waarbij niet hoofdlettergevoelig wordt vergeleken. De items inlist1
enlist2
zijn gescheiden door separator, net zoals de items in de teruggegeven lijst.list_join(with_separator, list1, separator1 [, list2, separator2]*)
– return a list made by joining the items in the source lists (list1
etc) usingwith_separator
between the items in the result list. Items in each sourcelist[123...]
are separated by the associatedseparator[123...]
. A list can contain zero values. It can be a field likepublisher
that is single-valued, effectively a one-item list. Duplicates are removed using a case-insensitive comparison. Items are returned in the order they appear in the source lists. If items on lists differ only in letter case then the last is used. All separators can be more than one character.Voorbeeld:
program: list_join('#@#', $authors, '&', $tags, ',')
You can use
list_join
on the results of previous calls tolist_join
as follows:program: a = list_join('#@#', $authors, '&', $tags, ','); b = list_join('#@#', a, '#@#', $#genre, ',', $#people, '&', 'some value', ',')
You can use expressions to generate a list. For example, assume you want items for
authors
and#genre
, but with the genre changed to the word “Genre: “ followed by the first letter of the genre, i.e. the genre “Fiction” becomes “Genre: F”. The following will do that:program: list_join('#@#', $authors, '&', list_re($#genre, ',', '^(.).*$', 'Genre: \1'), ',')
list_re(src_list, separator, include_re, opt_replace)
– maak een lijst door eerstsrc_list
te scheiden in items met hetseparator
karakter. Voor elk item in de lijst, controleer of het overeenkot metinclude_re
. Indien ja, voeg het toe aan de terug te geven lijst. Alsopt_replace
niet de lege string is, pas de vervanging dan toe vóór het item aan de teruggegeven lijst toe te voegen.list_re_group(src_list, separator, include_re, search_re [, template_for_group]*)
– zoals list-re behalve vervanging is niet optioneel. Het gebruiktre_group(item, search_re, template ...)
bij het vervangen.list_remove_duplicates(list, separator)
– geef een lijst terug gemaakt door uitlist
alle duplicaten te verwijderen. Als items enkel verschillen in hoofdlettergebruik wordt het laatste teruggegeven. De items inlijst
zijn gescheiden doorseparator
, net zoals de items in de teruggegeven lijst.list_sort(list, direction, separator)
– geeftlist
terug gesorteerd met een hoofdletter ongevoelige lexicale sortering. Alsdirection
nul is, wordtlist
oplopend gesorteerd, anders aflopend. De lijstitems worden gescheiden doorseparator
, zowel als de items in de teruggegeven lijst.list_split(list_val, sep, id_prefix)
– splitstlist_val
in aparte waardes metsep
, wijst dan de waardes toe an lokale variabelen genaamdid_prefix_N
waar N de positie is van de waarde in de lijst. Het eerste item heeft positie 0 (zero). De functie geeft het laatste element in de lijst.Voorbeeld:
list_split('one:two:foo', ':', 'var')
is gelijkwaardig aan:
var_0 = 'one'; var_1 = 'two'; var_2 = 'foo
list_union(list1, list2, separator)
– geeft een lijst terug gemaakt door het samenvoegen van de items inlist1
enlist2
, waarbij dubbels worden verwijderd (hoofdletterongevoelig). Als items verschillen in hoofdletter-gebruik, zal de versie vanlist1
gebruikt worden. De items inlist1
enlist2
worden gescheiden doorseparator
, zo ook de items in de teruggegeven lijst. Aliassen:merge_lists()
,list_union()
mod(x, y)
– geeft devloer
van rest vanx / y
terug. Gooit een uitzondering als ofwelx
ofwely
geen getal is.multiply(x [, y]*)
– geeft het product van z’n argumenten terug. Gooit een uitzondering als eender welk argument geen getal is. Deze functie kan gewoonlijk vervangen worden door de*
operator.not(value)
– geeft de string “1” terug als de waarde leeg is, anders de lege string. Deze functie kan gewoonlijk vervangen worden door de unary niet (!
) operator.ondevice()
– geeft de string'Yes'
terug alsondevice
is ingesteld, anders de lege string.or(value [, value]*)
– returns the string'1'
if any value is not empty, otherwise returns the empty string. You can have as many values as you want. This function can usually be replaced by the||
operator. A reason it cannot be replaced is if short-circuiting will change the results because of side effects.print(a [, b]*)
– prints the arguments to standard output. Unless you start calibre from the command line (calibre-debug -g
), the output will go into a black hole. Theprint
function always returns its first argument.
range(start, stop, step, limit)
– returns a list of numbers generated by looping over the range specified by the parameters start, stop, and step, with a maximum length of limit. The first value produced is ‘start’. Subsequent valuesnext_v = current_v + step
. The loop continues whilenext_v < stop
assumingstep
is positive, otherwise whilenext_v > stop
. An empty list is produced ifstart
fails the test:start >= stop
ifstep
is positive. Thelimit
sets the maximum length of the list and has a default of 1000. The parametersstart
,step
, andlimit
are optional. Callingrange()
with one argument specifiesstop
. Two arguments specifystart
andstop
. Three arguments specifystart
,stop
, andstep
. Four arguments specifystart
,stop
,step
andlimit
. Examples:range(5) -> '0, 1, 2, 3, 4' range(0, 5) -> '0, 1, 2, 3, 4' range(-1, 5) -> '-1, 0, 1, 2, 3, 4' range(1, 5) -> '1, 2, 3, 4' range(1, 5, 2) -> '1, 3' range(1, 5, 2, 5) -> '1, 3' range(1, 5, 2, 1) -> error(limit exceeded)
raw_field(lookup_name [, optional_default])
– geeft het metadata veld terug genoemd doorlookup_name
zonder toepassen van opmaak. Het evalueert en geeft het optionele tweede argumentoptional_default
terug als de waarde va het veld niet gedefinieerd (None
).raw_list(lookup_name, separator)
– geeft de metadatalijst terug benoemd doorlookup_name
zonder toepassen van formatering of sortering, met items gescheiden door separator.re_group(value, pattern [, template_for_group]*)
– return a string made by applying the regular expression pattern tovalue
and replacing each matched instance with the value returned by the corresponding template. In Template Program Mode, like for thetemplate
and theeval
functions, you use[[
for{
and]]
for}
.Het volgende voorbeeld zoekt naar een reeks met meer dan één woord zet het eerste woord in hoofdletters:
program: re_group(field('series'), "(\S* )(.*)", "{$:uppercase()}", "{$}")'}
round(x)
– geeft de dichtbijgelegen integer vanx
terug. Gooit een uitzondering alsx
geen getal is.series_sort()
– geeft de reekssorteerwaarde terug.strcat(a [, b]*)
– kan een willekeurig aantal parameters verwerken. Geeft een string terug bestaande uit de samengevoegde parametersstrcat_max(max, string1 [, prefix2, string2]*)
– Geeft een string terug gevormd door samenvoegen van de argumenten. De teruggegeven waarde wordt aanstring1` toegewezen. Paren van ``prefix, string
worden aan het einde van die waarde toegevoegd, zolang de daaruit volgende string niet langer danmax
is. Prefixen kunnen leeg zijn. Geeftstring1` terug, zelfs als ``string1` langer is dan ``max
. U kunt zoveelprefix, string
paren opgeven als u wil.strcmp(x, y, lt, eq, gt)
– doet een hoofdletterongevoelige lexicale vergelijking vanx
eny
. Geeftlt
terug alsx < y
,eq
alsx == y
, andersgt
. Deze functie kan dikwijls vervangen worden door een van de lexicale vergelijkingsoperatoren (==
,>
,<
, etc.)strcmpcase(x, y, lt, eq, gt)
– does a case-sensitive lexical comparison ofx
andy
. Returnslt
ifx < y
,eq
ifx == y
, otherwisegt
.Note: This is NOT the default behavior used by calibre, for example, in the lexical comparison operators (
==
,>
,<
, etc.). This function could cause unexpected results, preferably usestrcmp()
whenever possible.strlen(value)
– Geeft de lengte van de stringvalue
terug.substr(str, start, end)
– geeft destart
’th tot deend
’th karakters vanstr
terug. Het eerste teken instr
is het 0-de karakter. Alsend
negatief is betekent dit ‘tot zoveel karakters vanaf rechts’. Alsend
nul is betekent dit het laatste karakter. Bijvoorbeeld: substr(‘12345’, 1, 0) geeft ‘2345’, en substr(‘12345’, 1, -1) geeft ‘234’.subtract(x, y)
– geeftx - y
terug. Gooit een uitzondering als ofwelx
ofwely
geen getallen zijn. Deze functie kan gewoonlijk vervangen worden door de-
operator.switch_if([test_expression, value_expression,]+ else_expression)
– for eachtest_expression, value_expression
pair, checks iftest_expression
is True (non-empty) and if so returns the result ofvalue_expression
. If notest_expression
is True then the result ofelse_expression` is returned. You can have as many ``test_expression, value_expression
pairs as you want.today()
– geeft een datum+tijd string voor vandaag (nu) terug. Deze waarde is gemaakt voor gebruik in format_date of days_between maar kan aangepast worden als elke andere string. De datum is in ISO datum/tijd formaat.template(x)
– evalueertx
als een sjabloon. De evaluatie wordt in z’n eigen context gedaan, variabelen worden dus niet gedeeld door de caller en de sjabloon evaluatie.to_hex(val)
– returns the stringval
encoded in hex. This is useful when constructing calibre URLs.urls_from_identifiers(identifiers, sort_results)
– given a comma-separated list ofidentifiers
, where an identifier is a colon-separated pair of values (id_name:id_value
), returns a comma-separated list of HTML URLs generated from the identifiers. The list not sorted if sort_results is0
(character or number), otherwise it is sorted alphabetically by the identifier name. The URLs are generated in the same way as the built-in identifiers column when shown in Book details.
Meer complexe programma’s in sjabloonexpressies - Sjabloon Programma Modus¶
Sjabloon Programma Modus (SPM) is een mengeling van Algemene Programma Modus en Eén Functie Modus. TPM verschilt van Eén Functie Modus in dat het toelaat sjabloon expressies te schrijven die verwijzen naar andere metadata velden, geneste functies gebruikt, variabelen wijzigt, en rekenkunde doet. Het verschilt van Algemene Programma Modus in dat de sjabloon gevat wordt tussen {
en }
karakters en niet begint met het woord program:
. Het programma deel van de sjabloon is een Algemene Programma Modus expressie lijst.
Example: assume you want a template to show the series for a book if it has one, otherwise show the value of a custom field #genre. You cannot do this in the Single Function Mode because you cannot make reference to another metadata field within a template expression. In TPM you can, as the following expression demonstrates:
{#series:'ifempty($, field('#genre'))'}
Het voorbeeld toont meerdere dingen:
TPM is used if the expression begins with
:'
and ends with'}
. Anything else is assumed to be in Single Function Mode.de variabele
$
staat voor het veld benoemd in de sjabloon: de expressie werkt op,#series
in dit geval.functies moeten al hun argumenten krijgen. Er is geen standaard waarde. Bv. de standaard ingebouwde functies moeten een extra initiële parameter krijgen die het bronveld aangeeft.
spaties worden genegeerd en kunnen eender waar in de expressie gebruikt worden
constante strings zijn omringd door overeenkomende aanhalingstekens, ofwel
'
ofwel"
.
Alle functies opgelijst onder Eén Functie Modus en Algemene Programma Modus kunnen gebruikt worden in TPM.
In TPM, met {
en }
karakters in string literals kan leiden tot fouten of onverwachte resultaten omdat ze de sjabloonprocessor in verwarring brengen. Het probeert ze te behandelen als sjabloon expressie grenzen, niet karakters. In sommige maar niet alle gevallen kan u een {
vervangen door [[
en een }
door ]]. In het algemeen, als uw programma {
en }
karakters bevat, moet u Algemene Programma Modus gebruiken.
As with General Program Mode, for functions documented under Single Function Mode you must supply the value the function is to act upon as the first parameter in addition to the documented parameters. In TPM you can use $
to access the value specified by the lookup name
for the template expression.
Python Template Mode¶
Python Template Mode (PTM) lets you write templates using native python and the calibre API. The database API will be of most use; further discussion is beyond the scope of this manual. PTM templates are faster and can do more complicated operations but you must know how to write code in python using the calibre API.
A PTM template begins with:
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'
You can add the above text to your template using the context menu, usually accessed with a right click. The comments are not significant and can be removed. You must use python indenting.
The context object supports str(context)
that returns a string of the context’s contents, and context.attributes
that returns a list of the attribute names in the context.
The context.funcs
attribute allows calling Built-in and User template functions, and Stored GPM/Python templates, so that you can execute them directly in your code. The functions are retrieved using their names. If the name conflicts with a Python keyword, add an underscore to the end of the name. Examples:
context.funcs.list_re_group()
context.funcs.assert_()
Here is an example of a PTM template that produces a list of all the authors for a series. The list is stored in a Column built from other columns, behaves like tags. It shows in Book details and has the on separate lines checked (in Preferences → Look & feel → Book details). That option requires the list to be comma-separated. To satisfy that requirement the template converts commas in author names to semicolons then builds a comma-separated list of authors. The authors are then sorted, which is why the template uses 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))
The output in Book details looks like this:
Opgeslagen sjablonen¶
Both General Program Mode and Python Template Mode support saving templates and calling those templates from another template, much like calling stored functions. You save templates using Preferences → Advanced → Template functions. More information is provided in that dialog. You call a template the same way you call a function, passing positional arguments if desired. An argument can be any expression. Examples of calling a template, assuming the stored template is named foo
:
foo()
– roep de sjabloon aan zonder argumenten door te geven.foo(a, b)
roep de sjabloon aan met doorgeven van de waardes van de twee variabelena
enb
.foo(if field('series') then field('series_index') else 0 fi)
– als het boek eenseries
heeft, passeer deseries_index
, anders de waarde0
.
In GPM you retrieve the arguments passed in the call to the stored template using the arguments
function. It both declares and initializes local variables, effectively parameters. The variables are positional; they get the value of the parameter given in the call in the same position. If the corresponding parameter is not provided in the call then arguments
assigns that variable the provided default value. If there is no default value then the variable is set to the empty string. For example, the following arguments
function declares 2 variables, key
, alternate
:
arguments(key, alternate='series')
Voorbeelden, er weer vanuit gaand dat de opgeslagen sjabloon foo
heet:
foo('#myseries')
– argumentkey
krijgt de waarde'myseries'
toegewezen en het argumentalternate
krijgt de standaard waarde'series'
toegewezen.foo('series', '#genre')
de variabelekey
krijgt de waarde'series'
toegewezen en de variabelealternate
de waarde'#genre'
.foo()
– de variabelekey
krijgt de lege string toegewezen en de variabelealternate
de waarde'series'
.
In PTM the arguments are passed in the arguments
parameter, which is a list of strings. There isn’t any way to specify default values. You must check the length of the arguments
list to be sure that the number of arguments is what you expect.
An easy way to test stored templates is using the Template tester
dialog. For ease of access give it a keyboard shortcut in Preferences → Advanced → Keyboard shortcuts → Template tester. Giving the Stored templates
dialog a shortcut will help switching more rapidly between the tester and editing the stored template’s source code.
Bijkomende informatie voor sjablonen voorzien¶
A developer can choose to pass additional information to the template processor, such as application-specific book metadata or information about what the processor is being asked to do. A template can access this information and use it during the evaluation.
Ontwikkelaar: hoe bijkomende informatie doorgeven
The additional information is a Python dictionary containing pairs variable_name: variable_value
where the values must be strings. The template can access the dictionary, creating template local variables named variable_name
containing the value variable_value
. The user cannot change the name so it is best to use names that won’t collide with other template local variables, for example by prefixing the name with an underscore.
This dictionary is passed to the template processor (the formatter
) using the named parameter global_vars=your_dict
. The full method signature is:
def safe_format(self, fmt, kwargs, error_value, book,
column_name=None, template_cache=None,
strip_results=True, template_functions=None,
global_vars={})
Sjabloon schrijver: hoe toegang krijgen tot de bijkomende informatie
You access the additional information (the globals
dictionary) in a template using the template function:
globals(id[=expression] [, id[=expression]]*)
where id
is any legal variable name. This function checks whether the additional information provided by the developer contains the name. If it does then the function assigns the provided value to a template local variable with that name. If the name is not in the additional information and if an expression
is provided, the expression
is evaluated and the result is assigned to the local variable. If neither a value nor an expression is provided, the function assigns the empty string (''
) to the local variable.
A template can set a value in the globals
dictionary using the template function:
set_globals(id[=expression] [, id[=expression]]*)
This function sets the globals
dictionary key:value pair id:value
where value
is the value of the template local variable id
. If that local variable doesn’t exist then value
is set to the result of evaluating expression
.
Notes on the difference between modes¶
The three program modes, Single Function Mode (SFM), Template Program Mode (TPM), and General Program Mode (GPM), work differently. SFM is intended to be ‘simple’ so it hides a lot of programming language bits.
Verschillen:
In SFM the value of the column is always passed as an ‘invisible’ first argument to a function included in the template.
SFM doesn’t support the difference between variables and strings; all values are strings.
The following SFM template returns either the series name or the string “no series”:
{series:ifempty(no series)}
De soortgelijke sjabloon in SPM is:
{series:'ifempty($, 'no series')'}
De soortgelijke sjabloon in APM is:
program: ifempty(field('series'), 'no series')
The first argument to
ifempty
is the value of the fieldseries
. The second argument is the stringno series
. In SFM the first argument, the value of the field, is automatically passed (the invisible argument).Several template functions, for example
booksize()
andcurrent_library_name()
, take no arguments. Because of the ‘invisible argument’ you cannot use these functions in SFM.Nested functions, where a function calls another function to compute an argument, cannot be used in SFM. For example this template, intended to return the first 5 characters of the series value uppercased, won’t work in SFM:
{series:uppercase(substr(0,5))}
TPM and GPM support nested functions. The above template in TPM would be:
{series:'uppercase(substr($, 0,5))'}
In GPM it would be:
program: uppercase(substr(field('series'), 0,5))
As noted in the above Template Program Mode section, using
{
and}
characters in TPM string literals can lead to errors or unexpected results because they confuse the template processor. It tries to treat them as template boundaries, not characters. In some but not all cases you can replace a{
with[[
and a}
with ]]. Generally, if your program contains{
and}
characters then you should use General Program Mode.
User-defined Python template functions¶
You can add your own Python functions to the template processor. Such functions can be used in any of the three template programming modes. The functions are added by going to Preferences → Advanced → Template functions. Instructions are shown in that dialog.
Extra opmerkingen voor opslaan/versturen van sjablonen¶
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.
For example, assume we want the folder structure series/series_index - title, with the caveat that if series does not exist, then the title should be in the top folder. The template to do this is:
{series:||/}{series_index:|| - }{title}
The slash and the hyphen appear only if series is not empty.
The lookup function lets us do even fancier processing. For example, assume that if a book has a series, then we want the folder structure series/series index - title.fmt. If the book does not have a series then we want the folder structure genre/author_sort/title.fmt. If the book has no genre then we want to use ‘Unknown’. We want two completely different paths, depending on the value of series.
Om dit te bereiken:
Create a composite field (give it lookup name #aa) containing
{series}/{series_index} - {title}
. If the series is not empty, then this template will produce series/series_index - title.Create a composite field (give it lookup name #bb) containing
{#genre:ifempty(Unknown)}/{author_sort}/{title}
. This template produces genre/author_sort/title, where an empty genre is replaced with Unknown.Set the save template to
{series:lookup(.,#aa,#bb)}
. This template chooses composite field#aa
if series is not empty and composite field#bb
if series is empty. We therefore have two completely different save paths, depending on whether or not series is empty.
Tips¶
Use the Template Tester to test templates. Add the tester to the context menu for books in the library and/or give it a keyboard shortcut.
Templates can use other templates by referencing composite columns built with the desired template. Alternatively, you can use Stored Templates.
In a plugboard, you can set a field to empty (or whatever is equivalent to empty) by using the special template
{}
. This template will always evaluate to an empty string.The technique described above to show numbers even if they have a zero value works with the standard field series_index.
Functie referentie¶
- Reference for all built-in template language functions
- Arithmetic
- Boolean
- Date functions
- Formatting values
- Get values from metadata
- annotation_count()
- approximate_formats()
- author_links(waarde_afscheider, paar_afscheider)
- author_sorts(waarde_afscheider)
- booksize()
- connected_device_name(storage_location)
- connected_device_uuid(storage_location)
- current_library_name()
- current_library_path()
- current_virtual_library_name()
- field(lookup_name)
- formats_modtimes(date_format)
- formats_paths()
- formats_sizes()
- has_cover()
- is_marked()
- language_codes(language_strings)
- language_strings(lang_codes, vertaling)
- ondevice()
- raw_field(lookup_name [, optional_default])
- raw_list(lookup_name, separator)
- series_sort()
- user_categories()
- virtual_libraries()
- If-then-else
- Iterating over values
- List lookup
- List manipulation
- count(val, separator)
- list_count_matching(list, pattern, separator)
- list_difference(list1, list2, separator)
- list_equals(list1, sep1, list2, sep2, yes_val, no_val)
- list_intersection(lijst1, lijst2, scheiding)
- list_join(with_separator, list1, separator1 [, list2, separator2]*)
- list_re(bron_lijst, scheidingsteken, bevat_re, opt_vervang)
- list_re_group(src_list, separator, include_re, search_re [, group_template]+)
- list_remove_duplicates(list, separator)
- list_sort(lijst, richting, scheiding)
- list_split(list_val, sep, id_prefix)
- list_union(list1, list2, separator)
- range(start, stop, step, limit)
- subitems(val, start_index, end_index)
- sublist(val, start_index, end_index, separator)
- Other
- Recursion
- Relational
- String case changes
- String manipulation
- character(character_name)
- re(val, pattern, replacement)
- re_group(val, pattern [, template_for_group]*)
- shorten(val, left chars, middle text, right chars)
- strcat(a [, b]*)
- strcat_max(max, string1 [, prefix2, string2]*)
- strlen(a)
- substr(str, begin, eind)
- swap_around_articles(val, separator)
- swap_around_comma(waarde)
- to_hex(val)
- transliterate(a)
- Template database functions
- book_count(query, use_vl)
- book_values(column, query, sep, use_vl)
- extra_file_modtime(file_name, format_string)
- extra_file_names(sep [, pattern])
- extra_file_size(file_name)
- get_link(field_name, field_value)
- get_note(field_name, field_value, plain_text)
- has_extra_files([pattern])
- has_note(field_name, field_value)
- other
- API of the Metadata objects