Mallspråket för calibre

calibre-mallspråket är ett calibre-specifikt språk som används i hela calibre för uppgifter som att specificera filsökvägar, formatera värden och beräkna värdet för användarspecificerade kolumner. Exempel:

  • Ange mappstruktur och filnamn när du sparar filer från calibre-biblioteket till disken eller e-bokläsenhet.

  • Definiera regler för att lägga till ikoner och färger till calibre-boklistan.

  • Definiera virtuella kolumner som innehåller data från andra kolumner.

  • Avancerad bibliotekssökning.

  • Avancerad metadata sök och ersätt.

Språket bygger på begreppet mall, som anger vilka bokmetadata som ska användas, vilka beräkningar som ska utföras på dem och hur resultatet ska formateras.

Grundläggande mallar

En grundläggande mall består av ett eller flera malluttryck. Ett malluttryck består av text och namn inom klammerparenteser ({}) som ersätts av motsvarande metadata från boken som bearbetas. Till exempel har standardmallen i calibre som används för att spara böcker till enheten fyra malluttryck:

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

För boken ”The Foundation” av ”Isaac Asimov” blir mallen:

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

Snedstreck är inte malluttryck eftersom de inte finns mellan {}. Sådan text lämnas där den visas. Till exempel, om mallen är:

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

sedan för ”Stiftelsen” producerar mallen:

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

Ett malluttryck kan komma åt alla metadata som finns tillgängliga i calibre, inklusive anpassade kolumner (kolumner du skapar själv), genom att använda en kolumns lookup name. För att hitta söknamnet för en kolumn (ibland kallad fält), håll muspekaren över kolumnrubriken i calibres boklista. Söknamn för anpassade kolumner börjar alltid med #. För kolumner av serietyp finns det ett ytterligare fält med namnet #lookup name_index som är serieindexet för den boken i serien. Om du till exempel har en anpassad seriekolumn med namnet #myseries kommer det också att finnas en kolumn med namnet #myseries_index. Standardseriekolumnens index heter series_index.

Utöver de vanliga kolumnbaserade fälten kan du också använda:

  • {formats} - En lista över format tillgängliga i calibre-biblioteket för en bok

  • {identifiers:select(isbn)} - Bokens ISBN

Om metadata för fältet för en given bok inte är definierad ersätts fältet i mallen med den tomma strängen (''). Tänk till exempel på följande mall:

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

Om Asimovs bok ”Second Foundation” finns i serien ”Foundation” så producerar mallen:

Asimov, Isaac/Foundation/Second Foundation 3

Om en serie inte har angetts för boken producerar mallen:

Asimov, Isaac/Second Foundation

Mallprocessorn tar automatiskt bort flera snedstreck och inledande eller efterföljande mellanslag.

Avancerad formatering

Förutom ersättning av metadata kan mallar villkorligt innehålla ytterligare text och styra hur ersatt data formateras.

Villkorligt inkludera text

Ibland vill man att text bara ska visas i utdata om ett fält inte är tomt. Ett vanligt fall är series och series_index där man antingen vill ha ingenting eller att de två värdena ska separeras med ett bindestreck. calibre hanterar detta fall med hjälp av en speciell syntax för template expression.

Till exempel, och med hjälp av ovanstående Foundation-exempel, anta att du vill att mallen ska producera Foundation - 3 - Second Foundation. Den här mallen producerar följande utmatning:

{series} - {series_index} - {title}

Om en bok däremot inte har någon serie kommer mallen att producera - - titeln, vilket förmodligen inte är vad du vill ha. Generellt sett vill folk att resultatet ska vara titeln utan onödiga bindestreck. Du kan åstadkomma detta med hjälp av följande mallsyntax:

{field:|prefix_text|suffix_text}

Detta template expression säger att om field har värdet XXXX så blir resultatet prefix_textXXXXXsuffix_text. Om field är tomt (har inget värde) blir resultatet en tom sträng (ingenting) eftersom prefixet och suffixet ignoreras. Prefixet och suffixet kan innehålla mellanslag.

Använd inte undermallar (`{ … }`) eller funktioner (se nedan) i prefixet eller suffixet.

Med hjälp av denna syntax kan vi lösa ovanstående icke-serier problem med mallen:

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

Bindestreck inkluderas endast om boken har ett serieindex, vilket den bara har om den har en serie. Om du fortsätter med Foundation-exemplet igen kommer mallen att producera Foundation - 1 - Second Foundation.

Anteckningar:

  • Du måste ta med kolonet efter söknamnet om du använder ett prefix eller suffix.

  • Du måste använda antingen inga eller båda |-tecknen. Att använda ett av dem, som i {field:| - }, är inte tillåtet.

  • Det är okej att inte ange någon text för vare sig prefixet eller suffixet, som i {series:|| - }. Mallen {title:||} är densamma som {title}.

Formatering

Anta att du vill att series_index ska formateras som tre siffror med inledande nollor. Detta gör tricket:

{series_index:0>3s} - Tre siffror med inledande nollor

För efterföljande nollor, använd:

{series_index:0<3s} - Tre siffror med efterföljande nollor

Om du använder serieindex med bråkvärden, t.ex. 1,1, kanske du vill att decimaltecken ska hamna i linje. Till exempel kanske du vill att indexen 1 och 2,5 ska visas som 01,00 och 02,50 så att de kommer att sortera korrekt på en enhet som gör lexikal sortering. För att göra detta, använd:

{series_index:0>5.2f} - Fem tecken som består av två siffror med inledande nollor, en decimalkomma, sedan 2 siffror efter decimalkomma.

Om du bara vill ha de två första bokstäverna i data, använd:

{author_sort:.2} - Endast de två första bokstäverna i författaren sorterar namn

Mycket av formateringen av calibre mallspråk kommer från Python. För mer information om syntaxen för dessa avancerade formateringsoperationer, se Python-dokumentationen.

Använda mallar för att definiera anpassade kolumner

Mallar kan användas för att visa information som inte finns i calibre-metadata, eller för att visa metadata på ett annat sätt än calibres normala format. Du kanske till exempel vill visa ISBN, ett fält som calibre inte visar. Du kan åstadkomma detta genom att skapa en anpassad kolumn med typen Kolumn byggd från andra kolumner (hädanefter kallad sammansatta kolumner) och tillhandahålla en mall för att generera den visade texten. Kolumnen visar resultatet av utvärderingen av mallen. För att till exempel visa ISBN, skapa kolumnen och ange {identifiers:select(isbn)} i mallrutan. För att visa en kolumn som innehåller värdena för två anpassade seriekolumner, separerade med ett kommatecken, använd {#series1:||,}{#series2}.

Sammansatta kolumner kan använda godtyckligt mallalternativ, även formatering.

Observera: Du kan inte redigera data som visas i en sammansatt kolumn. Redigera i stället källkolumnerna. Om du redigerar en sammansatt kolumn, till exempel genom att dubbelklicka på den, öppnar calibre mallen för redigering, inte underliggande data.

Mallar och pluggbrädor

Pluggbrädor används för att ändra metadata som skrivs till böcker vid åtgärderna ”Skicka till enhet” och ”Spara till disk”. Med en pluggbräda kan du ange en mall som genererar de data som ska skrivas till bokens metadata. Du kan använda pluggbrädor för att ändra följande fält: författare, author_sort, språk, utgivare, taggar, titel och title_sort. Den här funktionen är användbar för personer som vill använda andra metadata i böcker på enheter för att lösa sorterings- eller visningsproblem.

När du skapar en pluggbräda anger du vilket format och vilken enhet den ska användas för. Det finns en särskild enhet, save_to_disk, som används när format sparas (i stället för att skickas till en enhet). När du har valt format och enhet väljer du vilka metadatafält som ska ändras och anger mallar som tillhandahåller de nya värdena. Mallarna är anslutna till sina målfält, därav namnet pluggbrädor. Du kan naturligtvis använda sammansatta kolumner i dessa mallar.

Pluggbrädor är mycket flexibla och kan skrivas i enkelt funktionsläge, mallprogramläge, allmänt programläge eller Python-malläge.

När en pluggbräda kan gälla (innehållsserver, spara till disk, eller skicka till enhet), söker calibre de definierade pluggbrädor att välja den rätta för givet format och enhet. Till exempel för att hitta rätt pluggbräda för en EPUB-bok som skickas till en Android-enhet, söker calibre dessa pluggbrädor enligt följande sökordning:

  • en pluggbräda med en exakt matchning på format och enhet, till exempel EPUB och ANDROID

  • en pluggbräda med exakt matchande format och det speciella alternativet valfri enhet, t.ex. EPUB och valfri enhet

  • en pluggbräda med det speciella valet valfritt format och en exakt matchning på enheten, t.ex. valfritt format och ANDROID

  • en pluggbräda med valfritt format och valfri enhet

Fälten för taggar och författare behandlas särskilt, eftersom båda kan innehålla flera värden. En bok kan ha flera taggar och flera författare. När du anger att något av dessa fält ska ändras undersöks mallens resultat för att avgöra om det innehåller flera värden. För taggar delas resultatet vid varje kommatecken. Om mallen exempelvis ger värdet Thriller, Horror blir resultatet de två taggarna Thriller och Horror. Det går inte att använda ett kommatecken inuti en enskild tagg.

Samma sak gäller för författare, men då används ett annat avgränsningstecken: ett & (et-tecken) i stället för ett kommatecken. Om mallen exempelvis ger värdet Blogs, Joe&Posts, Susan får boken två författare: Blogs, Joe och Posts, Susan. Om mallen ger värdet Blogs, Joe;Posts, Susan får boken i stället en enda författare med ett ganska märkligt namn.

Pluggbrädor påverkar metadata som skrivs in i boken när den sparas till disk eller skrivs till enheten. Pluggbrädor påverkar inte metadata som används av spara till disk och skicka till enhet för att skapa filnamnen. I stället konstrueras filnamn med hjälp av mallar som anges i lämpliga inställningsfönster.

Använda funktioner i mallar – enkelt funktionsläge

Anta att du vill visa värdet i ett fält med versaler när fältet normalt skrivs med inledande versal i varje ord. Du kan göra detta med mallfunktioner. Om du till exempel vill visa titeln med versaler använder du funktionen uppercase, som i {title:uppercase()}. Om du vill visa den med inledande versal i varje ord använder du {title:titlecase()}.

Funktioner placeras i mallens formatdel, efter : och före det första | eller den avslutande } om inget prefix eller suffix används. Om du har både ett format och en funktionsreferens placeras funktionen efter ett andra :. Funktioner returnerar värdet i kolumnen som anges i mallen, ändrat på lämpligt sätt.

Syntaxen för att använda funktioner är en av:

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

Funktionsnamn måste alltid följas av inledande och avslutande parenteser. Vissa funktioner kräver extra värden (argument), som anges inom parenteserna. Argument avgränsas med kommatecken. Bokstavliga kommatecken (kommatecken som text, inte argumentavgränsare) måste föregås av ett omvänt snedstreck (\). Det sista (eller enda) argumentet får inte innehålla en avslutande parentes som text.

Funktioner utvärderas före formatspecifikationerna och prefixet/suffixet. Längre ned finns ett exempel där både ett format och en funktion används.

Viktigt: Om du har programmeringserfarenhet bör du observera att syntaxen i enkelt funktionsläge inte fungerar som du kanske förväntar dig. Strängar omges inte av citattecken och blanksteg har betydelse. Alla argument betraktas som konstanter; det finns inga uttryck.

Använd inte undermallar (`{ … }`) som funktionsargument. Använd i stället Mallprogramläge och Allmänt programläge.

Anmärkningar om att anropa funktioner i enkelt funktionsläge:

  • När funktioner används i enkelt funktionsläge ersätts den första parametern, value, automatiskt med innehållet i fältet som anges i mallen. När mallen {title:capitalize()} bearbetas skickas till exempel innehållet i fältet title som parametern value till funktionen capitalize.

  • I funktionsdokumentationen betyder beteckningen [something]* att something kan upprepas noll eller flera gånger. Beteckningen [something]+ betyder att something upprepas en eller flera gånger (det måste förekomma minst en gång).

  • Vissa funktioner använder reguljära uttryck. I mallspråket är matchning med reguljära uttryck skiftlägesokänslig.

Funktionerna dokumenteras i Mallfunktionsreferens. Dokumentationen anger vilka argument funktionerna kräver och vad de gör. Här visas till exempel dokumentationen för funktionen ifempty.

  • ifempty(value, text_if_empty) – om value inte är tomt returneras value, annars returneras text_if_empty.

Du ser att funktionen kräver två argument, value och text_if_empty. Eftersom vi använder enkelt funktionsläge utelämnar vi dock argumentet value och skickar endast text_if_empty. Exempelvis visar följande mall:

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

visar bokens taggar, om den har några. Om den inte har några taggar visas No tags on this book.

Följande funktioner kan användas i enkelt funktionsläge eftersom deras första parameter är value.

  • capitalize(value) – returnerar value med den första bokstaven i stor bokstav och resten i liten bokstav.

  • ceiling(value) – returnerar det minsta heltalet större än eller lika med value.

  • cmp(value, y, lt, eq, gt) – jämför value och y efter att båda har konverterats till tal.

  • contains(value, pattern, text_if_match, text_if_not_match) – kontrollerar om värdet matchas av det reguljära uttrycket pattern.

  • date_arithmetic(value, calc_spec, fmt) – beräknar ett nytt datum från value med calc_spec.

  • encode_for_url(value, use_plus) – returnerar value kodat för användning i en URL enligt use_plus. Värdet URL-kodas först. Om use_plus är 0 ersätts mellanslag med '+' (plus)-tecken. Om det är 1 ersätts mellanslag med %20.

  • floor(value) – returnerar det största heltalet mindre än eller lika med value.

  • format_date(value, format_string) – formatera value, som måste vara en datumsträng, med format_string, vilket returnerar en sträng.

  • format_duration(value, template, [largest_unit]) – formaterar värdet, ett antal sekunder, till en sträng som visar veckor, dagar, timmar, minuter och sekunder. Om värdet är ett flyttal avrundas det till närmaste heltal.

  • format_number(value, template) – tolkar value som ett tal och formaterar det talet med hjälp av en Python-formateringsmall som {0:5.2f} eller {0:,d} eller ${0:5,.2f}.

  • fractional_part(value) – returnerar den del av värdet som kommer efter decimaltecknet.

  • human_readable(value) – förväntar sig att value är ett tal och returnerar en sträng som representerar det talet i KB, MB, GB, etc.

  • ifempty(value, text_if_empty) – om value inte är tomt returneras value, annars returneras text_if_empty.

  • language_strings(value, localize) – returnerar språknamnen för språkkoderna (se här för namn och koder) som skickats i value.

  • list_contains(value, separator, [ pattern, found_val, ]* not_found_val) – tolka value som en lista med objekt separerade med separator, och kontrollera pattern mot varje objekt i listan.

  • list_count(value, separator) – tolkar värdet som en lista med objekt separerade med separator och returnerar antalet objekt i listan.

  • list_count_matching(value, pattern, separator) – tolkar value som en lista med objekt separerade med separator, och returnerar antalet objekt i listan som matchar det reguljära uttrycket pattern.

  • list_item(value, index, separator) – tolka value som en lista med objekt separerade med separator, vilket returnerar det ’index’te objektet.

  • list_sort(value, direction, separator) – returnerar value sorterat med en skiftlägesokänslig lexikal sortering.

  • lookup(value, [ pattern, key, ]* else_key) – mönstren kontrolleras mot value i ordning.

  • lowercase(value) – returnerar value med gemener.

  • mod(value, y) – returnerar floor för resten av value / y.

  • rating_to_stars(value, use_half_stars) – returnerar value som en sträng med stjärntecken ().

  • re(value, pattern, replacement) – returnerar value efter att det reguljära uttrycket har tillämpats.

  • re_group(value, pattern [, template_for_group]*) – returnerar en sträng skapad genom att tillämpa det reguljära uttrycket patternvalue och ersätta varje matchande instans

  • round(value) – returnerar närmaste heltal till value.

  • select(value, key) – tolkar value som en kommaseparerad lista med objekt där varje objekt har formen id:id_value (calibre identifier-formatet).

  • shorten(value, left_chars, middle_text, right_chars) – returnerar en förkortad version av value

  • str_in_list(value, separator, [ string, found_val, ]+ not_found_val) – tolka value som en lista med objekt separerade med separator och jämför sedan string med varje värde i listan.

  • subitems(value, start_index, end_index) – denna funktion bryter isär listor med taggliknande hierarkiska objekt som genrer.

  • sublist(value, start_index, end_index, separator) – tolka value som en lista med objekt separerade med separator, vilket returnerar en ny lista gjord av objekten från start_index till end_index.

  • substr(value, start, end) – returnerar tecknen från start till end i value.

  • swap_around_articles(value, separator) – returnerar value med artiklar flyttade till slutet, separerade med semikolon.

  • swap_around_comma(value) – givet ett value av formen B, A, returnerar A B.

  • switch(value, [patternN, valueN,]+ else_value) – för varje patternN, valueN-par, kontrolleras om value matchar det reguljära uttrycket patternN

  • test(value, text_if_not_empty, text_if_empty) – returnerar text_if_not_empty om värdet inte är tomt, annars text_if_empty.

  • titlecase(value) – returnerar value i titelkapitalisering.

  • transliterate(value) – returnerar en sträng i ett latinskt alfabet som bildas genom att approximera ljudet av orden i value.

  • uppercase(value) – returnerar value med versaler.

Använda funktioner och formatering i samma mall

Anta att du har en anpassad heltalskolumn #myint som du vill visa med inledande nollor, exempelvis 003. Ett sätt är att använda formatet 0>3s. Som standard visas dock ett tal (heltal eller flyttal) som den tomma strängen om det är lika med noll, så nollvärden ger den tomma strängen och inte 000. Om du vill visa värdet 000 använder du både formatsträngen och funktionen ifempty för att ändra tillbaka det tomma värdet till noll. Mallen blir:

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

Observera att du även kan använda prefix och suffix. Om du vill att talet ska visas som [003] eller [000] använder du mallen:

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

Allmänt programläge

Allmänt programläge (GPM) ersätter malluttryck med ett program skrivet i mallspråket. Språkets syntax definieras av följande grammatik:

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

Anteckningar:

  • ett top_expression har alltid ett värde. Värdet för en expression_list är värdet för den sista top_expression i listan. Värdet för uttryckslistan 1;2;'foobar';3 är till exempel 3.

  • I ett logiskt sammanhang är alla värden som inte är tomma True

  • I ett logiskt sammanhang är det tomma värdet False

  • Strängar och tal kan användas omväxlande. Till exempel är 10 och '10' samma sak.

  • Kommentarer är rader som börjar med tecknet ’#’, eventuellt föregånget av blanksteg eller tabbar.

Operatorprioritet

Operatorernas prioritet (utvärderingsordning), från högst (utvärderas först) till lägst (utvärderas sist), är:

  • Funktionsanrop, konstanter, parentesuttryck, satsuttryck, tilldelningsuttryck, fältreferenser.

  • Unärt plus (+) och minus (-). Dessa operatorer utvärderas från höger till vänster.

    Dessa och alla andra aritmetiska operatorer returnerar heltal om uttryckets bråkdel är noll. Om ett uttryck till exempel returnerar 3.0 ändras det till 3.

  • Multiplikation (*) och division (/). Dessa operatorer är associativa och utvärderas från vänster till höger. Använd parenteser om du vill ändra utvärderingsordningen.

  • Addition (+) och subtraktion (-). Dessa operatorer är associativa och utvärderas från vänster till höger.

  • Jämförelser av tal och strängar. Dessa operatorer returnerar '1' om jämförelsen lyckas, annars den tomma strängen (''). Jämförelser är inte associativa: a < b < c är ett syntaxfel.

  • Strängsammanslagning (&). Operatorn & returnerar en sträng som bildas genom att slå samman uttrycken till vänster och höger. Exempel: 'aaa' & 'bbb' returnerar 'aaabbb'. Operatorn är associativ och utvärderas från vänster till höger.

  • Unärt logiskt icke (!). Operatorn returnerar '1' om uttrycket är False (utvärderas till den tomma strängen), annars ''.

  • Logiskt och (&&). Denna operator returnerar ’1’ om både uttrycket till vänster och uttrycket till höger är True, eller den tomma strängen '' om något av dem är False. Den är associativ, utvärderas från vänster till höger och använder kortslutningsutvärdering.

  • Logiskt eller (||). Denna operator returnerar '1' om antingen uttrycket till vänster eller uttrycket till höger är True, eller '' om båda är False. Den är associativ, utvärderas från vänster till höger och använder kortslutningsutvärdering. Det är ett inklusivt eller som returnerar '1' om både uttrycket till vänster och uttrycket till höger är True.

Fältreferenser

En field_reference utvärderas till värdet i metadatafältet vars söknamn följer efter $ eller $$. Att använda $ motsvarar att använda funktionen field. Att använda $$ motsvarar att använda funktionen raw_field. Exempel:

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

if-uttryck

If-uttryck utvärderar först condition. Om condition är True (ett värde som inte är tomt) utvärderas expression_list i then-satsen. Om det är False utvärderas, om de finns, expression_list i elif- eller else-satsen. Delarna elif och else är valfria. Orden if, then, elif, else och fi är reserverade; du kan inte använda dem som identifierarnamn. Du kan lägga in radbrytningar och blanksteg där det är lämpligt. condition är ett top_expression, inte en expression_list; semikolon är inte tillåtna. expression_lists är sekvenser av top_expressions avgränsade med semikolon. Ett if-uttryck returnerar resultatet av det sista top_expression i den expression_list som utvärderades, eller den tomma strängen om ingen uttryckslista utvärderades.

Exempel:

* 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)

Exempel på nästlade if-uttryck:

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

Som nämnts ovan ger ett if-uttryck ett värde. Det innebär att alla följande är likvärdiga:

* 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

Det här programmet returnerar till exempel värdet i kolumnen series om boken ingår i en serie, annars värdet i kolumnen title:

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

for-uttryck

Uttrycket for itererar över en lista med värden och bearbetar dem ett i taget. list_expression måste utvärderas antingen till ett söknamn för ett metadatafält, till exempel tags eller #genre, eller till en lista med värden. range genererar en lista med tal. Om resultatet är ett giltigt söknamn hämtas fältets värde och avgränsaren som anges för fälttypen används. Om resultatet inte är ett giltigt söknamn antas det vara en lista med värden. Listan antas vara kommaavgränsad om inte det valfria nyckelordet separator anges; i så fall måste listvärdena avgränsas med resultatet av utvärderingen av separator_expr. En avgränsare kan inte användas om listan genereras av range(). Varje värde i listan tilldelas den angivna variabeln och därefter utvärderas expression_list. Du kan använda break för att lämna loopen och continue för att gå till början av loopen inför nästa iteration.

Exempel: Den här mallen tar bort det första hierarkiska namnet från varje värde i Genre (#genre) och skapar en lista med de nya namnen:

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

Om ursprungligt Genre är History.Military, Science Fiction.Alternate History, ReadMe returnerar mallen Military, Alternate History, ReadMe. Du kan använda mallen i calibres Redigera metadata i grupp  →  Sök och ersätt med Sök efter inställt på template för att ta bort hierarkins första nivå och tilldela resultatet till Genre.

Observera: den sista raden i mallen, new_tags, är egentligen inte nödvändig i det här fallet, eftersom for returnerar värdet för den sista top_expression i uttryckslistan. Värdet av en tilldelning är värdet av dess uttryck, så värdet för for-satsen är det som tilldelades new_tags.

with-uttryck

Uttrycket with:

  1. byter den aktuella boken till boken med det calibre-bok-ID (ett heltal) som fås genom att utvärdera top_expression.

  2. kör expression_list.

  3. återställer sedan den aktuella boken till den ursprungliga.

Uttrycket with returnerar resultatet av det sista top_expression i den expression_list som utvärderades, eller den tomma strängen om ingen uttryckslista utvärderades.

Den här mallen returnerar till exempel en lista med titlarna på alla böcker som är markerade i det grafiska gränssnittet:

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

return-sats

Returnera värdet för expression. Om satsen körs i en funktion returneras uttryckets värde till anroparen. Om den körs i det yttersta sammanhanget (mallen) anges mallens värde till uttryckets värde och mallen avslutas.

Funktionsdefinition

Om du har upprepad kod i en mall kan du placera koden i en lokal funktion. Nyckelordet def inleder definitionen. Därefter följer funktionsnamnet, argumentlistan och sedan funktionens kod. Funktionsdefinitionen avslutas med nyckelordet fed.

Argument är positionsberoende. När en funktion anropas matchas de angivna argumenten från vänster till höger mot de definierade parametrarna, och argumentets värde tilldelas parametern. Det är ett fel att ange fler argument än det finns definierade parametrar. Parametrar kan ha standardvärden, till exempel a = 25. Om inget argument anges för parametern används standardvärdet. Om det inte finns något standardvärde sätts parametern till den tomma strängen.

Satsen return kan användas i en lokal funktion.

En funktion måste definieras innan den kan användas.

Exempel: Den här mallen beräknar en ungefärlig tidslängd i år, månader och dagar från ett antal dagar. Funktionen to_plural() formaterar de beräknade värdena. Observera att exemplet även använder operatorn &:

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')

Relationsoperatorer

Relationsoperatorer returnerar '1' om jämförelsen är sann, annars den tomma strängen ('').

Det finns två typer av relationsoperatorer: strängjämförelser och numeriska jämförelser.

Strängjämförelser gör skiftlägesokänsliga jämförelser enligt lexikografisk ordning. De strängjämförelseoperatorer som stöds är ==, !=, <, <=, >, >=, in, inlist och inlist_field. För operatorerna in, inlist och inlist_field tolkas resultatet av uttrycket till vänster som ett mönster för reguljära uttryck. De är sanna om det reguljära uttrycket till vänster matchar värdet i uttrycket till höger. De reguljära uttrycken är skiftlägesokänsliga.

Operatorn inlist är sann om det reguljära uttrycket till vänster matchar något av objekten i listan till höger, där objekten är kommaavgränsade. Operatorn inlist_field är sann om det reguljära uttrycket till vänster matchar något av objekten i fältet (kolumnen) vars namn anges av uttrycket till höger, med den avgränsare som är definierad för fältet. Observera att inlist_field kräver att uttrycket till höger utvärderas till ett fältnamn, medan inlist kräver att uttrycket till höger utvärderas till en sträng med en kommaavgränsad lista. På grund av denna skillnad är inlist_field avsevärt snabbare än inlist, eftersom inga strängkonverteringar eller listkonstruktioner görs.

De numeriska jämförelseoperatorerna är ==#, !=#, <#, <=#, ># och >=#. Uttrycken till vänster och höger måste utvärderas till numeriska värden med två undantag: både strängvärdet ”None” (odefinierat fält) och den tomma strängen utvärderas till värdet noll.

Exempel:

  • program: field('series') == 'foo' returnerar '1' om bokens serie är foo, annars ''.

  • program: 'f.o' in field('series') returnerar '1' om bokens serie matchar det reguljära uttrycket f.o (till exempel foo, Off Onyx och så vidare), annars ''.

  • program: 'science' inlist $#genre returnerar '1' om något av värdena som hämtas från bokens genrer matchar det reguljära uttrycket science, till exempel Science, History of Science eller Science Fiction, annars ''.

  • program: '^science$' inlist $#genre returnerar '1' om någon av bokens genrer exakt matchar det reguljära uttrycket ^science$, till exempel Science, annars ''. Genrerna History of Science och Science Fiction matchar inte.

  • program: 'asimov' inlist $authors returnerar '1' om någon författare matchar det reguljära uttrycket asimov, till exempel Asimov, Isaac eller Isaac Asimov, annars ''.

  • program: 'asimov' inlist_field 'authors' returnerar '1' om någon författare matchar det reguljära uttrycket asimov, till exempel Asimov, Isaac eller Isaac Asimov, annars ''.

  • program: 'asimov$' inlist_field 'authors' returnerar '1' om någon författare matchar det reguljära uttrycket asimov$, till exempel Isaac Asimov, annars ''. Det matchar inte Asimov, Isaac på grund av ankaret $ i det reguljära uttrycket.

  • program: if field('series') != 'foo' then 'bar' else 'mumble' fi returnerar 'bar' om bokens serie inte är foo. Annars returneras 'mumble'.

  • program: if field('series') == 'foo' || field('series') == '1632' then 'yes' else 'no' fi returnerar 'yes' om serien är antingen foo eller 1632, annars 'no'.

  • program: if '^(foo|1632)$' in field('series') then 'yes' else 'no' fi returnerar 'yes' om serien är antingen foo eller 1632, annars 'no'.

  • program: if 11 > 2 then 'yes' else 'no' fi returnerar 'no' eftersom operatorn > gör en lexikografisk jämförelse.

  • program: if 11 ># 2 then 'yes' else 'no' fi returnerar 'yes' eftersom operatorn ># gör en numerisk jämförelse.

Funktioner i allmänt programläge

En lista över funktionerna som är inbyggda i mallspråket finns i Mallfunktionsreferens.

Anteckningar:

  • Till skillnad från enkelt funktionsläge måste du i allmänt programläge ange den första parametern value.

  • Alla parametrar är expression_lists (se grammatiken ovan).

Mer komplexa program i malluttryck – mallprogramläge

Mallprogramläge (TPM) är en blandning av Allmänt programläge och Enkelt funktionsläge. TPM skiljer sig från enkelt funktionsläge genom att det tillåter malluttryck som refererar till andra metadatafält, använder nästlade funktioner, ändrar variabler och utför aritmetik. Det skiljer sig från Allmänt programläge genom att mallen omges av tecknen { och } och inte börjar med ordet program:. Programdelen av mallen är en uttryckslista i allmänt programläge.

Exempel: anta att du vill att en mall ska visa en boks serie om den har en, annars värdet i det anpassade fältet #genre. Detta går inte i enkelt funktionsläge eftersom du inte kan referera till ett annat metadatafält inifrån ett malluttryck. I TPM går det, vilket följande uttryck visar:

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

Exemplet visar flera saker:

  • TPM används om uttrycket börjar med :' och slutar med '}. Allt annat antas vara i enkelt funktionsläge.

    Om mallen innehåller ett prefix och ett suffix slutar uttrycket med '|, där | avgränsar prefixet. Exempel:

    {series:'ifempty($, $#genre)'|prefix | suffix}
    
  • Funktioner måste få alla sina argument. De inbyggda standardfunktionerna måste till exempel få den inledande parametern value.

  • Variabeln $ kan användas som argumentet value och står för värdet i fältet som anges i mallen, i det här fallet series.

  • blanksteg ignoreras och kan användas var som helst i uttrycket.

  • konstanta strängar omges av matchande citattecken, antingen ' eller ".

I TPM kan tecknen { och } i strängliteraler orsaka fel eller oväntade resultat, eftersom de förvirrar mallprocessorn. Den försöker tolka dem som gränser för malluttryck, inte som tecken. I vissa, men inte alla, fall kan du ersätta { med [[ och } med ]]. Råd: om programmet innehåller tecknen { och } bör du använda Allmänt programläge.

Python-malläge

Python-malläge (PTM) låter dig skriva mallar med vanlig Python och calibre-API:et. Databas-API:et är sannolikt mest användbart; en utförligare genomgång ligger utanför den här manualens omfattning. PTM-mallar är snabbare och kan utföra mer komplicerade åtgärder, men du måste kunna skriva Python-kod som använder calibre-API:et.

En PTM-mall börjar med:

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'

Du kan lägga till texten ovan i mallen med snabbmenyn, som vanligtvis öppnas med ett högerklick. Kommentarerna saknar betydelse och kan tas bort. Du måste använda indrag enligt Python-syntax.

Kontextobjektet stöder str(context), som returnerar en sträng med kontextens innehåll, och context.attributes, som returnerar en lista med namnen på kontextens attribut.

Attributet context.funcs gör det möjligt att anropa inbyggda och användardefinierade mallfunktioner samt lagrade GPM-/Python-mallar, så att du kan köra dem direkt i koden. Funktionerna hämtas med sina namn. Om namnet krockar med ett Python-nyckelord lägger du till ett understreck i slutet av namnet. Exempel:

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

Följande är ett exempel på en PTM-mall som skapar en lista över alla författare i en serie. Listan lagras i en Kolumn byggd från andra kolumner, fungerar som taggar. Den visas i Bokdetaljer och alternativet på separata rader är markerat (under Inställningar  →  Utseende och känsla  →  Bokdetaljer). Det alternativet kräver att listan är kommaavgränsad. För att uppfylla kravet omvandlar mallen kommatecken i författarnamn till semikolon och bygger sedan en kommaavgränsad lista över författare. Författarna sorteras därefter, vilket är anledningen till att mallen använder 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))

Utmatningen i Bokdetaljer ser ut så här:

Dialogruta för konvertering av e-bok

Mallar och URL:er

Du kan använda mallar för att skapa URL:er. Två fall beskrivs här:

  • Sök-URL:er för anpassade kolumner i Bokdetaljer

  • calibres URL-schema

Sök-URL:er för anpassade kolumner i Bokdetaljer

När du skapar en anpassad kolumn kan du med hjälp av en mall ange en URL som ska användas i Bokdetaljer. Om du till exempel har en anpassad kolumn för Översättare kan du ange en URL som leder till en webbplats om översättare. Sök-URL:er i Bokdetaljer kan anges för kolumntyperna Text, Uppräkning, Serie och Kolumn byggd från annan kolumn.

När du klickar på ett objekt som har en sökmall i Bokdetaljer utvärderas mallen. Den får bokens vanliga metadata och dessutom tre extra fält:

  • item_value: värdet för det klickade objektet.

  • item_value_quoted: värdet för det klickade objektet, URL-kodat. Specialtecken kodas så att de är giltiga i URL:er och blanksteg ersätts med '+' (plustecken).

  • item_value_no_plus: värdet för det klickade objektet, URL-kodat. Specialtecken kodas så att de är giltiga i URL:er och blanksteg ersätts med %20, inte med plustecken.

Det finns flera sätt att skapa URL:en. I följande exempel används Wikipedia.

Det enklaste är en grundläggande mall:

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

I vissa fall kanske du vill göra mer bearbetning. Det finns fyra mallfunktioner som du kan använda beroende på hur komplex bearbetningen är.

  • make_url(path, [query_name, query_value]+) – den här funktionen är det enklaste sättet att konstruera en fråge-URL. Den använder en path, webbplatsen och sidan du vill fråga, och query_name, query_value-paren som frågan är byggd från. Generellt sett måste query_value vara URL-kodad. Med den här funktionen är den alltid kodad och mellanslag ersätts alltid med '+'-tecken.

  • make_url_extended(...) – den här funktionen liknar make_url() men ger dig mer kontroll över URL-komponenterna. Komponenterna i en URL är

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

    Se Uniform Resource Locator på Wikipedia för mer information.

    Funktionen har två varianter:

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

    och

    make_url_extended(scheme, authority, path, query_string)
    
  • query_string([query_name, query_value, how_to_encode]+)– returnerar en URL-förfrågesträng konstruerad från triaderna query_name, query_value, how_to_encode. En förfrågesträng är en serie poster där varje post ser ut som query_name=query_value där query_value är URL-kodat enligt instruktionerna. Frågeobjekten är separerade med '&' (et-tecken).

  • encode_for_url(value, use_plus) – returnerar value kodat för användning i en URL enligt use_plus. Värdet URL-kodas först. Om use_plus är 0 ersätts mellanslag med '+' (plus)-tecken. Om det är 1 ersätts mellanslag med %20.

Anta till exempel att du har en anpassad kolumn Översättare (#translators) där namnen har formen Efternamn, Förnamn. Du kan behöva omvandla namnet till Förnamn Efternamn när URL:en skapas. Du kan använda funktionen make_url för detta:

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

Om vi antar att översättarens namn är Boy-Żeleński, Tadeusz skapar mallen ovan länken:

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

Observera att personens förnamn nu står först, att blanksteget har blivit ett plustecken och att de icke-engelska tecknen i efternamnet är URL-kodade.

Funktionerna make_url_extended, query_string och encode_for_url kan vara användbara beroende på hur komplicerad den ytterligare bearbetningen är.

calibres URL-schema

calibre stöder flera olika URL:er för att navigera i dina calibre-bibliotek. Det här avsnittet visar hur mallar används för att skapa några av URL:erna. Information om tillgängliga URL:er finns i calibre:// URL-schema.

  • Byt till ett visst bibliotek. URL:ens syntax är:

    calibre://switch-library/Library_Name
    

    Library_Name måste ersättas med namnet på det calibre-bibliotek du vill öppna. Biblioteksnamnet visas i fönstrets namnlist. Det är ett enkelt namn, inte sökvägen till biblioteket. Du måste skriva det exakt som det visas i namnlisten, inklusive skiftläge. Tecknet _ (understreck) står för det aktuella biblioteket. Om namnet innehåller blanksteg eller specialtecken måste det hexkodas med funktionen to_hex, som i följande exempel:

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

    Mallen genererar URL:en:

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

    Du kan ersätta funktionen current_library_name() med bibliotekets faktiska namn, som i:

    program: strcat('calibre://switch-library/_hex_-', to_hex('Library.test_small'))
    
  • Länkar för att visa böcker. Dessa länkar markerar en bok i calibre-biblioteket. URL:ens syntax är:

    calibre://show-book/Library_Name/book_id
    

    book id är bokens numeriska calibre-ID och är tillgängligt för mallar som $id. Som ovan kan biblioteksnamnet behöva hexkodas. Här är ett exempel:

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

    Det ger URL:en:

    calibre://show-book/_hex_-4c6962726172792e746573745f736d616c6c/1353
    
  • Söka efter böcker. Dessa länkar söker efter böcker i det angivna calibre-biblioteket. URL:ens syntax är:

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

    där query är ett giltigt calibre-sökuttryck. Du måste hexkoda alla frågor som innehåller blanksteg eller specialtecken, vilket i praktiken innebär de flesta. Calibre-sökuttrycket för att söka efter en hierarkisk tagg som börjar med ’AA’ är till exempel tags:"=.AA". Den här mallen skapar en sök-URL för uttrycket:

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

    Den resulterande URL:en är:

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

    Här är ett exempel på samma URL skapad med funktionen :ref:ff_make_url_extended i stället för strcat:

    program: make_url_extended('calibre', '', 'search/_hex_-' & to_hex(current_library_name()),
                               'eq', to_hex('tags:"=.AA"'))
    
  • Öppna ett bokdetaljfönster för en bok i ett bibliotek. URL:ens syntax är:

    calibre://book-details/Library_Name/book_id
    

    En exempelmall är:

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

    vilket ger URL:en:

    calibre://book-details/_hex_-4c6962726172792e746573745f736d616c6c/1353
    
  • Öppna anteckningarna som är kopplade till en författare, serie och så vidare. URL:ens syntax är:

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

    Field_Name är fältets söknamn. Om fältet är en anpassad kolumn ersätter du tecknet # med ett understreck (_). Item_Id är det interna numeriska ID:t för värdet i fältet. Det finns ingen mallfunktion som returnerar Item_Id, så mallar använder normalt den andra formen, Hex_Encoded_Item_Name. Här är en exempelmall som öppnar anteckningen för personen Boy-Żeleński, Tadeusz i fältet #authtest:

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

    vilket ger URL:en:

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

Lagrade mallar

Både Allmänt programläge och Python-malläge stöder att mallar sparas och anropas från en annan mall, ungefär som lagrade funktioner. Du sparar mallar via Inställningar  →  Avancerat  →  Mallfunktioner. Mer information finns i dialogrutan. Du anropar en mall på samma sätt som en funktion och kan ange positionsargument. Ett argument kan vara vilket uttryck som helst. Exempel på hur en mall anropas, om den lagrade mallen heter foo:

  • foo() – anropa mallen utan argument.

  • foo(a, b) – anropa mallen och skicka värdena för de två variablerna a och b.

  • foo(if field('series') then field('series_index') else 0 fi) – om boken har en series skickas series_index, annars skickas värdet 0.

I GPM hämtar du argumenten som skickades i anropet till den lagrade mallen med funktionen arguments. Den både deklarerar och initierar lokala variabler, det vill säga parametrar. Variablerna är positionsberoende; de får värdet för parametern som anges på motsvarande position i anropet. Om motsvarande parameter inte anges i anropet tilldelar arguments variabeln det angivna standardvärdet. Om det inte finns något standardvärde sätts variabeln till den tomma strängen. Följande arguments-funktion deklarerar till exempel två variabler, key och alternate:

arguments(key, alternate='series')

Exempel, fortfarande med antagandet att den lagrade mallen heter foo:

  • foo('#myseries') – argumentet key tilldelas värdet 'myseries' och argumentet alternate tilldelas standardvärdet 'series'.

  • foo('series', '#genre') – variabeln key tilldelas värdet 'series' och variabeln alternate värdet '#genre'.

  • foo() – variabeln key tilldelas den tomma strängen och variabeln alternate tilldelas värdet 'series'.

I PTM skickas argumenten i parametern arguments, som är en lista med strängar. Det går inte att ange standardvärden. Du måste kontrollera längden på listan arguments för att säkerställa att antalet argument är det förväntade.

Ett enkelt sätt att testa lagrade mallar är dialogrutan Malltestaren. För att komma åt den snabbt ger du den ett kortkommando under Inställningar  →  Avancerat  →  Kortkommandon  →  Malltestaren. Om du även ger dialogrutan Lagrade mallar ett kortkommando kan du snabbare växla mellan testaren och redigeringen av den lagrade mallens källkod.

Tillhandahålla ytterligare information till mallar

En utvecklare kan välja att skicka ytterligare information till mallprocessorn, till exempel programspecifika bokmetadata eller information om vad processorn ska göra. En mall kan komma åt informationen och använda den under utvärderingen.

Utvecklare: så skickar du ytterligare information

Den ytterligare informationen är en Python-ordlista med paren variable_name: variable_value, där värdena måste vara strängar. Mallen kan komma åt ordlistan och skapa lokala mallvariabler med namnet variable_name och värdet variable_value. Användaren kan inte ändra namnet, så det är bäst att använda namn som inte krockar med andra lokala mallvariabler, till exempel genom att inleda namnet med ett understreck.

Denna ordlista skickas till mallprocessorn (formatter) med den namngivna parametern global_vars=your_dict. Den fullständiga metodsignaturen är:

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

Mallförfattare: så kommer du åt den ytterligare informationen

Du kommer åt den ytterligare informationen (ordlistan globals) i en mall med mallfunktionen:

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

där id är ett giltigt variabelnamn. Funktionen kontrollerar om den ytterligare informationen som utvecklaren tillhandahöll innehåller namnet. Om den gör det tilldelas det angivna värdet till en lokal mallvariabel med det namnet. Om namnet inte finns i den ytterligare informationen och ett expression anges, utvärderas expression och resultatet tilldelas den lokala variabeln. Om varken ett värde eller ett uttryck anges tilldelar funktionen den tomma strängen ('') till den lokala variabeln.

En mall kan ange ett värde i ordlistan globals med mallfunktionen:

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

Funktionen anger nyckel/värde-paret id:value i ordlistan globals, där value är värdet för den lokala mallvariabeln id. Om den lokala variabeln inte finns sätts value till resultatet av att utvärdera expression.

Anmärkningar om skillnaderna mellan lägena

De tre programlägena, Enkelt funktionsläge (SFM), Mallprogramläge (TPM) och Allmänt programläge (GPM), fungerar på olika sätt. SFM är avsett att vara ’enkelt’ och döljer därför många delar av programmeringsspråket.

Skillnader:

  • I SFM skickas kolumnens värde alltid som ett ’osynligt’ första argument till en funktion som ingår i mallen.

  • SFM skiljer inte mellan variabler och strängar; alla värden är strängar.

  • Följande SFM-mall returnerar antingen serienamnet eller strängen ”no series”:

    {series:ifempty(no series)}
    

    Motsvarande mall i TPM är:

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

    Motsvarande mall i GPM är:

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

    Det första argumentet till ifempty är värdet i fältet series. Det andra argumentet är strängen no series. I SFM skickas det första argumentet, fältets värde, automatiskt (det osynliga argumentet).

  • Flera mallfunktioner, till exempel booksize() och current_library_name(), tar inga argument. På grund av det ’osynliga argumentet’ kan du inte använda dessa funktioner i SFM.

  • Nästlade funktioner, där en funktion anropar en annan funktion för att beräkna ett argument, kan inte användas i SFM. Följande mall, som är avsedd att returnera de första fem tecknen i serievärdet med versaler, fungerar till exempel inte i SFM:

    {series:uppercase(substr(0,5))}
    
  • TPM och GPM stöder nästlade funktioner. Mallen ovan skulle i TPM vara:

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

    I GPM skulle det vara:

    program: uppercase(substr(field('series'), 0,5))
    
  • Som anges i avsnittet Mallprogramläge ovan kan tecknen { och } i TPM-strängliteraler orsaka fel eller oväntade resultat, eftersom de förvirrar mallprocessorn. Den försöker tolka dem som mallgränser, inte som tecken. I vissa, men inte alla, fall kan du ersätta { med [[ och } med ]]. Om programmet innehåller tecknen { och } bör du i allmänhet använda Allmänt programläge.

Användardefinierade Python-mallfunktioner

Du kan lägga till egna Python-funktioner i mallprocessorn. Sådana funktioner kan användas i alla tre mallprogramlägen. Funktionerna läggs till via Inställningar  →  Avancerat  →  Mallfunktioner. Instruktioner visas i dialogrutan. Observera att du kan använda Python-mallar för ett liknande ändamål. Eftersom anrop av användardefinierade funktioner är snabbare än anrop av en Python-mall kan användardefinierade funktioner vara effektivare, beroende på hur komplicerad funktionen eller mallen är.

Särskilda anmärkningar om att använda mallar i olika sammanhang

I det grafiska gränssnittet (Kolumner skapade från andra kolumner och Mallsökningar):

  • GPM-mallar fungerar som tidigare.

  • Python-mallar har fullständig åtkomst till calibre-databasen.

I ikonregler:

I Innehållsservern:

Särskilda anvisningar för att spara/skicka mallar

Särskild bearbetning används när en mall används som mall för Spara till disk eller Skicka till enhet. Fältvärdena rensas genom att tecken som är speciella för filsystem, inklusive snedstreck, ersätts med understreck. Det innebär att fälttext inte kan användas för att skapa mappar. Snedstreck ändras däremot inte i prefix- eller suffixsträngar, så snedstreck i dessa strängar skapar mappar. Därför kan du skapa en mappstruktur med varierande djup.

Antag till exempel att vi vill ha mappstrukturen series/series_index - title, med förbehållet att om serien inte finns, så bör titeln vara i översta mappen. Mallen för att göra detta är:

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

Snedstrecket och bindestrecket visas bara om serien inte är tom.

Funktionen lookup gör det möjligt att utföra ännu mer avancerad bearbetning. Anta till exempel att vi vill använda mappstrukturen series/series index - title.fmt om boken ingår i en serie. Om den inte ingår i en serie vill vi använda mappstrukturen genre/author_sort/title.fmt. Om boken saknar genre vill vi använda ’Unknown’. Vi vill alltså ha två helt olika sökvägar beroende på värdet för series.

För att åstadkomma det här, vi:

  1. Skapa ett sammansatt fält (ge det söknamnet #aa) som innehåller {series}/{series_index} - {title}. Om series inte är tomt skapar mallen series/series_index - title.

  2. Skapa ett sammansatt fält (ge det söknamnet #bb) som innehåller {#genre:ifempty(Unknown)}/{author_sort}/{title}. Mallen skapar genre/author_sort/title, där en tom genre ersätts med Unknown.

  3. Ange sparmallen som {series:lookup(.,#aa,#bb)}. Mallen väljer det sammansatta fältet #aa om series inte är tomt och det sammansatta fältet #bb om series är tomt. Vi får därför två helt olika sökvägar beroende på om series är tomt eller inte.

Tips

  • Använd Malltestaren för att testa mallar. Lägg till testaren i snabbmenyn för böcker i biblioteket och/eller ge den ett kortkommando.

  • Mallar kan använda andra mallar genom att referera till sammansatta kolumner som bygger på den önskade mallen. Du kan också använda Lagrade mallar.

  • I en pluggbräda kan du ställa in ett fält till tomt (eller vad som motsvarar tomt) genom att använda den särskilda mallen {}. Den här mallen kommer alltid att utvärderas till en tom sträng.

  • Den teknik som beskrivs ovan för att visa siffror även om de har ett nollvärde fungerar med standardfältet series_index.

Mallfunktionsreferens