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.

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 expressie pattern. Geeft text if match terug als het pattern overeenkomt met de waarde, anders text if no match.

  • count(separator) – interpreteert de waarde als een lijst van termen gescheiden door separator en geeft het aantal items in de lijst terug. Meeste lijsten gebruiken een komma als scheiding maar authors 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 door separator, het pattern controlerend tegen elk item in de lijst. Als het pattern overeen komt met een item komt found_val terug, anders not_found_val. Het paar pattern en found_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()}. Als localize nul is, geef de string in het Engels terug. Als localize 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 door separator, terug gevend het ‘index’th item. Het eerste item is nummer nul. Het laatste item heeft index -1 zoals in list_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 door key teruggegeven. Als geen patroon overeenkomt, wordt de waarde van het veld benoemd door else_key teruggegeven. Kijk bij switch (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 van pattern in de waarde worden vervangen door replacement. De sjabloontaal gebruikt hoofdletterongevoelige Python reguliere expressies.

  • select(key) – interpreteer de waarde als een komma gescheiden lijst met items waar elk item de vorm id:value heeft (het calibre identifier 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 uit left chars karakters van het begin van de waarde, gevolgd door middle text, gevolgd door right chars karakters van het einde van de waarde. Left chars en right 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 dan left chars + right chars + de lengte van middle 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 door separator vergelijk dan string met elke waarde in de lijst. De string is geen reguliere expressie. Als string gelijk is aan een item (hoofdlettergebruik negerend) geef dan de bijhorende found_val terug. Bevat string separators, wordt het ook als een lijst behandeld en elke subwaarde gecontroleerd. De string en found_value paren kunnen naar believen herhaald worden, teruggave van verschillende waardes toelatend afhankelijk van de string waarde. Komt geen enkele string overeen, wordt not_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 van start_index tot end_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 door separator, geeft een nieuwe lijst terug, gemaakt van de items van start_index tot end_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 de separator voorzien. Als geen separator voorzien is, wordt de waarde behandeld als één enkele waarde, niet een lijst. De artikelen zijn diegenen gebruikt door calibre om de title_sort te genereren.

  • swap_around_comma() – gegeven een waarde in de vorm B, A, wordt A 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 ieder pattern, value paar, controleert of het waarde overeen komt met de reguliere expressie pattern en indien zo geeft de geassocieerde``value`` terug. Als geen pattern overeenkomt, wordt else_value teruggegeven. U kan zoveel pattern, value paren hebben als u wilt. De eerste overeenkomst wordt teruggegeven.

  • test(text if not empty, text if empty) – geef text if not empty terug als de waarde niet leeg is, geef anders text 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 functie Fiodor 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 ]* | compare_exp
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 een expression_list is de waarde van de laatste top_expression in de lijst. Bv. de waarde van de expressielijst 1;2;'foobar';3 is 3.

  • 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 in 3.

  • 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 expressie f.o (bv., foo, Off Onyx, enz.), anders ''.

  • program: 'science' inlist field('#genre') geeft '1' terug als één van de boeken z’n genres overeenkomen met de reguliere expressie science, bv., Science, History of Science, Science Fiction etc.), anders ''.

  • 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 niet foo 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 om and 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) – wijst val toe aan id, geeft dan val 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. De approximate_formats() functie is beduidend sneller dan de formats_... 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 het pair_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 auteur author 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 rond val_separator zet deze in de val_separator string

  • book_count(query, use_vl) – returns the count of books found by searching for query. If use_vl is 0 (zero) then virtual libraries are ignored. This function and its companion book_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 tweak allow_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:

    1. 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 named vals. These results are used to check subsequent books without redoing the lookups.

    1. 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 column column (a lookup name), separated by sep, in the books found by searching for query. If use_vl is 0 (zero) then virtual libraries are ignored. This function and its companion book_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 tweak allow_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 opzoeknaam field_name is een van de waardes gespecificeerd door de parameters, 'yes' teruggevend als een overeenkomst werd gevonden anders de lege string. Stel de parameter is_undefined, is_false, of is_true in op 1 (het cijfer) om die voorwaarde te controleren, anders op 0. Bv.:

    check_yes_no("#bool", 1, 0, 1) geeft 'yes' terug als het yes/no veld #bool ofwel Waar is ofwel ongedefinieerd (noch Waar noch Vals).

    Meer dan een van is_undefined, is_false, of is_true kan op 1 gezet worden.

  • ceiling(x) – geeft de kleinste integer terug groter dan of gelijk aan x. Gooit een uitzondering als x 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 zijn newline, return, tab en backslash.

  • cmp(x, y, lt, eq, gt) – vergelijkt x en y na converteren van beiden naar getallen. Geetf lt if x <# y, eq if x ==# y terug, anders gt. 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. De storage_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. De storage_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 van date met calc_spec. Geef de nieuwe datum terug geformatteerd volgens optioneel fmt: indien niet voorzien zal het resultaat in ISO formaat zijn. De calc_spec is een string gevormd door aaneengeregen paren van vW (valueWhat) waar v een mogelijk-negatief getal is en W een van de volgende letters:

    • s: voeg v seconden toe aan date

    • m: voeg v minuten toe aan date

    • h: voeg v uren toe aan date

    • d: voeg v dagen toe aan date

    • w: voeg v weken toe aan date

    • y: voeg v jaren toe aan date, waar een jaar is 365 dagen.

    Voorbeeld: '1s3d-1m' voegt 1 seconde, 3 dagen toe en trekt 1 minuut af van date.

  • days_between(date1, date2) – geeft het aantal dagen tussen date1 en date2 terug. Het aantal is positief als date1 groter is dan date2, anders negatief. Als ofwel date1 ofwel date2 geen datum is, wordt de lege string terug gegeven.

  • divide(x, y) – returns x / y. Gooit een uitzondering als ofwel x ofwel y 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.

  • field(lookup_name) – geeft de waarde terug van het metadata veld met opzoeknaam lookup_name.

  • field_exists(field_name) – controleert of een veld (kolom) met de lookup naam field_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) – vergelijkt val < 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 eerste value 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 aan x. Gooit een uitzondering als x 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 een iso opgemaakte datum. Als u een ander datumformaat wilt, voeg de gewenste opmaakstring toe na from_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. de field() functie te gebruiken zoals in:

    format_date(field('pubdate'), 'yyyy')
    

    gebruik de raw_field() functie zoals in:

    format_date(raw_field('pubdate'), '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. De date_format_string parameter geeft aan hoe de datum geformatteerd moet worden. Zie de format_date() functie voor details. U kunt de select 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 gescheiden FMT: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 gescheiden FMT: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) geeft 0.14 terug. Gooit een uitzondering als x geen getal is.

  • has_cover() – geeft 'Yes' terug als het boek een omslag heeft, anders de lege string.

  • 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 van in_list) Interpreteert de waarde als een lijst met items gescheiden door separator, evalueert het pattern tegen elke waarde in de lijst. Als het pattern overeen komt met een waarde komt found_val terug, anders not_found_val. De pattern en found_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) – interpreteert value als een lijst met items gescheiden door separator, geeft het aantal items in de lijst terug. Aliassen: count(), list_count()

  • list_count_matching(list, pattern, separator) – interpreteert lijst als een lijst met items gescheiden door separator, geeft het aantal items in de lijst terug die overeenkomen met de reguliere expressie pattern. Aliassen: list_count_matching(), count_matching()

  • list_difference(list1, list2, separator) – geeft een lijst terug gemaakt door uit list1 alle item te verwijderen gevonden in list2 waarbij niet hoofdlettergevoelig wordt vergeleken. De items in list1 en list2 zijn gescheiden door separator, net zoals de items in de teruggegeven lijst.

  • list_equals(list1, sep1, list2, sep2, yes_val, no_val) – geef yes_val terug als list1 en list2 dezelfde items bevatten, anders no_val. De items worden bepaald door iedere lijst te splitsen met het juiste scheidingsteken (sep1 or sep2). 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 uit list1 alle item te verwijderen niet gevonden in list2 waarbij niet hoofdlettergevoelig wordt vergeleken. De items in list1 en list2 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) using with_separator between the items in the result list. Items in each source list[123...] are separated by the associated separator[123...]. A list can contain zero values. It can be a field like publisher 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 to list_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 eerst src_list te scheiden in items met het separator karakter. Voor elk item in de lijst, controleer of het overeenkot met include_re. Indien ja, voeg het toe aan de terug te geven lijst. Als opt_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 gebruikt re_group(item, search_re, template ...) bij het vervangen.

  • list_remove_duplicates(list, separator) – geef een lijst terug gemaakt door uit list alle duplicaten te verwijderen. Als items enkel verschillen in hoofdlettergebruik wordt het laatste teruggegeven. De items in lijst zijn gescheiden door separator, net zoals de items in de teruggegeven lijst.

  • list_sort(list, direction, separator) – geeft list terug gesorteerd met een hoofdletter ongevoelige lexicale sortering. Als direction nul is, wordt list oplopend gesorteerd, anders aflopend. De lijstitems worden gescheiden door separator, zowel als de items in de teruggegeven lijst.

  • list_split(list_val, sep, id_prefix) – splitst list_val in aparte waardes met sep, wijst dan de waardes toe an lokale variabelen genaamd id_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 in list1 en list2, waarbij dubbels worden verwijderd (hoofdletterongevoelig). Als items verschillen in hoofdletter-gebruik, zal de versie van list1 gebruikt worden. De items in list1 en list2 worden gescheiden door separator, zo ook de items in de teruggegeven lijst. Aliassen: merge_lists(), list_union()

  • mod(x, y) – geeft de vloer van rest van x / y terug. Gooit een uitzondering als ofwel x ofwel y 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 als ondevice 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. The print 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 values next_v = current_v + step. The loop continues while next_v < stop assuming step is positive, otherwise while next_v > stop. An empty list is produced if start fails the test: start >= stop if step is positive. The limit sets the maximum length of the list and has a default of 1000. The parameters start, step, and limit are optional. Calling range() with one argument specifies stop. Two arguments specify start and stop. Three arguments specify start, stop, and step. Four arguments specify start, stop, step and limit. 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 door lookup_name zonder toepassen van opmaak. Het evalueert en geeft het optionele tweede argument optional_default terug als de waarde va het veld niet gedefinieerd (None).

  • raw_list(lookup_name, separator) – geeft de metadatalijst terug benoemd door lookup_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 to value and replacing each matched instance with the the value returned by the corresponding template. In Template Program Mode, like for the template and the eval 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 van x terug. Gooit een uitzondering als x 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 parameters

  • strcat_max(max, string1 [, prefix2, string2]*) – Geeft een string terug gevormd door samenvoegen van de argumenten. De teruggegeven waarde wordt aan string1` toegewezen. Paren van ``prefix, string worden aan het einde van die waarde toegevoegd, zolang de daaruit volgende string niet langer dan max is. Prefixen kunnen leeg zijn. Geeft string1` terug, zelfs als ``string1` langer is dan ``max. U kunt zoveel prefix, string paren opgeven als u wil.

  • strcmp(x, y, lt, eq, gt) – doet een hoofdletterongevoelige lexicale vergelijking van x en y. Geeft lt terug als x < y, eq als x == y, anders gt. 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 of x and y. Returns lt if x < y, eq if x == y, otherwise gt.

    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 use strcmp() whenever possible.

  • strlen(value) – Geeft de lengte van de string value terug.

  • substr(str, start, end) – geeft de start’th tot de end’th karakters van str terug. Het eerste teken in str is het 0-de karakter. Als end negatief is betekent dit ‘tot zoveel karakters vanaf rechts’. Als end nul is betekent dit het laatste karakter. Bijvoorbeeld: substr(‘12345’, 1, 0) geeft ‘2345’, en substr(‘12345’, 1, -1) geeft ‘234’.

  • subtract(x, y) – geeft x - y terug. Gooit een uitzondering als ofwel x ofwel y geen getallen zijn. Deze functie kan gewoonlijk vervangen worden door de - operator.

  • 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) – evalueert x 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 string val encoded in hex. This is useful when constructing calibre URLs.

  • urls_from_identifiers(identifiers, sort_results) – given a comma-separated list of identifiers, 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 is 0 (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:

  • SPM wordt gebruikt als de expressie begint met :' en eindigt met '. Al de rest wordt verondersteld aanwezig te zijn in Eén Functie Modus.

  • 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.

Opgeslagen algemene programma modus sjablonen

General Program Mode supports 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 variabelen a en b.

  • foo(if field('series') then field('series_index') else 0 fi) – als het boek een series heeft, passeer de series_index, anders de waarde 0.

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') – argument key krijgt de waarde 'myseries' toegewezen en het argument alternate krijgt de standaard waarde 'series' toegewezen.

  • foo('series', '#genre') de variabele key krijgt de waarde 'series' toegewezen en de variabele alternate de waarde '#genre'.

  • foo() – de variabele key krijgt de lege string toegewezen en de variabele alternate de waarde 'series'.

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 dict, 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.

Deze dict wordt doorgegeven aan de sjabloonverwerker (de formatter) met de benoemde parameter global_vars=your_dict. De volledige methodehandtekening 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

U hebt toegang tot de bijkomende informatie (de globals dict) in een sjabloon met de sjabloon functie:

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 dict using the template function:

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

This function sets the globals dict 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 field series. The second argument is the string no series. In SFM the first argument, the value of the field, is automatically passed (the invisible argument).

  • Several template functions, for example booksize() and current_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:

  1. 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.

  2. 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.

  3. 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.

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.

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 en ANDROID

  • a plugboard with an exact match on format and the special any device choice, e.g., EPUB and any device

  • een adapter met de speciale any format keuze en een exacte overeenkomst op toestel, bv. any format en ANDROID

  • a plugboard with any format and any 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.

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