Le langage de modèle calibre

Le langage de modèle de calibre est utilisé dans divers endroits. Il est utilisé pour contrôler la structure des dossiers et le nom des fichiers lors de la sauvegarde des fichiers de la bibliothèque calibre sur le disque ou sur votre périphérique de lecture. Il est également utilisé pour définir les colonnes «virtuelles» qui contiennent des données provenant d’autres colonnes et ainsi de suite.

Le langage de modèle de base est très simple, mais dispose de fonctionnalités avancées très puissantes. L’idée de base est que le modèle se compose de texte et de noms entre accolades qui sont ensuite remplacés par les métadonnées correspondantes de l’ouvrage en cours de traitement. Ainsi, par exemple, le modèle par défaut utilisé dans calibre pour l’enregistrement des livres sur un périphérique est:

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

Pour le livre « The Foundation » par Isaac Asimov cela donnera:

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

Les barres obliques sont du texte, qui est inclus dans le modèle où elles apparaissent. Par exemple, si votre modèle est:

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

Pour le livre « The Foundation » par Isaac Asimov cela donnera:

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

Vous pouvez utiliser tous les champs de métadonnées disponibles dans calibre dans un modèle, y compris les colonnes personnalisées que vous avez créées vous-même. Pour connaître le nom à indiquer dans le modèle pour une colonne, passez votre souris sur l’en-tête de la colonne. Le nom des champs personnalisés (colonnes ajoutées par vos soins) ont toujours un # comme premier caractère. Pour les champs personnalisés de type série, il y a toujours un champ supplémentaire nommé #seriesname_index qui devient l’indice de série pour cette série. Donc si vous avez un champ de série personnalisé nommé #MesSeries, il y aura aussi un champ appelé #MesSeries_index.

En plus des champs basés sur des colonnes, vous pouvez aussi utiliser:

{formats} - A list of formats available in the calibre library for a book
{identifiers:select(isbn)} - The ISBN of the book

Si un livre spécifique n’a pas un morceau particulier de métadonnée, le champ dans le modèle est automatiquement supprimé pour ce livre. Considérons, par exemple:

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

Si un livre a une série, le modèle produira:

Asimov, Isaac/Foundation/Second Foundation 3

et si un livre ne fait pas partie d’une série:

Asimov, Isaac/Second Foundation

(calibre supprime automatiquement les barres obliques multiples et les espaces suivant ou précédant).

Mise en forme avancée

Vous pouvez faire plus que juste une simple substitution avec les modèles. Vous pouvez également inclure conditionnellement du texte et contrôler la façon dont les données substituées sont formatées.

Premièrement, inclure du texte conditionnellement. Il y a des cas où vous pouvez vouloir avoir du texte qui apparaît dans la sortie uniquement si un champ n’est pas vide. Une situation commune est series et series_index, où vous voulez soit rien soit les deux valeurs séparées par un tiret. calibre prend en charge cette situation en utilisant une syntaxe spéciale de champ.

Par exemple, supposons que vous vouliez utiliser le modèle:

{series} - {series_index} - {title}

Si le livre n’a pas de série, la réponse sera - - titre. Beaucoup de personnes voudrait plutôt que le résultat soit simplement titre, sans les tirets.. Pour faire cela, utilisez la syntaxe étendue {field:|prefix_text|suffix_text}. Quand vous utilisez cette syntaxe, si le champ à la valeur SERIES alors le résultat sera prefix_textSERIESsuffix_text. Si le champ n’a pas de valeur, alors le résultat sera la chaîne vide (rien); le préfixe et le suffixe sont ignorés. Le préfixe et le suffixe peuvent contenir des blancs. N’utilisez pas des sous-modèles (`{ … }`) ou des fonctions (voir plus bas) comme préfixe ou suffixe.

En utilisant cette syntaxe, nous pouvons résoudre le problème des séries ci-dessus avec le modèle:

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

Les tirets seront inclus uniquement si le livre a un index de séries, qu’il aura uniquement s’il a une série.

Note : vous devez inclure le caractère « : » si vous voulez utiliser un préfixe ou un suffixe. Vous devez soit ne pas utiliser de caractères | ou les deux; en utiliser un, comme dans {field:| - }, n’est pas permis. Il n’est pas dérangeant de ne procurer aucun texte pour un côté ou pour l’autre, tel que dans {series:|| - }. Utiliser {title:||} est la même chose qu’utiliser {title}.

Deuxièmement : formater. Supposons que vous voulez vous assurer que series_index est toujours composé de trois chiffres avec des zéros devant. Ceci ferait l’affaire:

{series_index:0>3s} - Three digits with leading zeros

Si à la place des zéros devant vous voulez des espaces, utilisez:

{series_index:>3s} - Three digits with leading spaces

Pour des zéros qui suivent, utilisez:

{series_index:0<3s} - Three digits with trailing zeros

Si vous utilisez des indices de série avec des sous valeurs (Par ex., 1,1), vous pourriez vouloir vous assurer que les virgules décimales s’alignent. Par exemple, vous voudriez peut-être que 1 et 2,5 apparaissent sous la forme 01,00 et 02,50 afin qu’ils puissent être triés correctement. Pour ce faire, utilisez:

{series_index:0>5.2f} - Five characters, consisting of two digits with leading zeros, a decimal point, then 2 digits after the decimal point

Si vous ne voulez que les deux premières lettres de la donnée, utilisez:

{author_sort:.2} - Only the first two letter of the author sort name

Le langage de modèle de calibre vient de Python et pour plus de détails sur la syntaxe de ces opérations de mise en forme avancée, reportez-vous à la Documentation Python.

Fonctionnalités avancées

Utiliser les modèles dans les colonnes personnalisées

Il y a parfois des cas où vous souhaiteriez afficher des métadonnées que calibre n’affiche normalement pas ou afficher les données d’une manière différente de ce que calibre fait normalement. Par exemple, vous pouvez désirer afficher l’ISBN, un champ que calibre n’affiche pas. Pour cela, vous pouvez utiliser une colonne personnalisée de type “colonne construite à partir d’autres colonnes” (ci-après dénommées colonnes composites) et y entrer un modèle. Résultat : calibre affiche une colonne indiquant le résultat de l’interprétation de ce modèle. Pour afficher l’ISBN, créer la colonne et entrez {identifiers:select(isbn)} dans le champ modèle. Pour afficher une colonne contenant les valeurs de deux colonnes personnalisées série séparées par une virgule, utilisez {#series1:||,}{#series2}.

Les colonnes composites peuvent utiliser n’importe quelle option des modèles, y compris le formatage.

Vous ne pouvez pas modifier les données contenues dans une colonne composite. Si vous éditez une colonne composite en faisant un double clic sur n’importe quel élément, vous ouvrez le modèle pour l’édition, pas les données sous-jacentes. Modifier ainsi le modèle à partir de l’interface graphique est un moyen rapide de tester et de modifier les colonnes composites.

Utiliser les fonctions dans les modèles - mode fonction-seule

Supposons que vous voulez afficher la valeur d’un champ en majuscules, lorsque ce champ est normalement en casse Titre. Vous pouvez faire cela (et bien d’autres choses) en utilisant les fonctions disponibles pour les modèles. Par exemple, pour afficher le titre en majuscules, utilisez {title:uppercase()}. Pour l’afficher en casse titre, utilisez {title:titlecase()}.

Les références de fonction apparaissent dans la partie de format, allant après le : et avant le premier | ou le } fermant. Si vous avez à la fois un format et une fonction, la fonction vient après un autre :. Les fonctions doivent toujours se terminer avec ().Certaines fonctions prennent des valeurs supplémentaires (arguments), et ceux-ci vont à l’intérieur du ().

Les fonctions sont toujours appliquées avant les spécifications de format. Voir plus bas la démonstration de l’ordre d’application, dans un exemple utilisant à la fois un format et une fonction.

La syntaxe pour l’utilisation des fonctions est {field:function(arguments)}, ou {field:function(arguments)|prefix|suffix}. Les arguments sont séparés par des virgules. Les virgules se trouvant à l’intérieur d’arguments doivent être précédées d’une barre oblique inverse ( \ ).Le dernier argument (ou le seul) ne peut pas contenir une parenthèse fermante ( ) ). Les fonctions renvoient la valeur du champ utilisé dans le modèle, convenablement modifiées.

Important: Si vous avez de l’expérience en programmation, la syntaxe de ce mode (fonction seule) n’est pas ce que vous pourriez attendre. Les chaînes ne sont pas entre guillemets. Les espaces sont importants. Les arguments doivent être des constantes, il n’y a pas de sous-évaluation. Ne pas utiliser les sous-modèles (`{…}`) comme des arguments de la fonction. A la place, utilisez le mode programme de modèle et le mode programme général.

De nombreuses fonctions utilisent des expressions régulières. Dans tous les cas, la correspondance d’expression régulière est insensible à la casse.

Les fonctions disponibles sont listées ci-dessous. La documentation exhaustive des fonctions est disponible dans la section Classification de fonction:

  • lowercase() – renvoie la valeur du champ en minuscule.

  • uppercase() – renvoie la valeur du champ en majuscule.

  • titlecase() – renvoie la valeur du champ en casse titre.

  • capitalize() – renvoie la valeur avec la première lettre en majuscule et le reste en minuscule.

  • contains(pattern, text if match, text if not match) – vérifie si le champ contient des correspondances pour l’expression régulière pattern. Renvoie texte si correspondance si des correspondances sont trouvées, sinon texte si pas de correspondance

  • count(separator) – interprète la valeur comme une liste d’articles séparés par separator, retourne le nombre d’articles dans la liste. Beaucoup de listes utilisent une virgule comme séparateur, mais les auteurs utilisent l’esperluette. Exemples: {tags:count(,)}, {authors:count(&)}

  • format_number(template) – interprète le champ comme un nombre et formate ce nombre en utilisant un modèle de formatage Python comme « {0:5.2f} » ou « {0:,d} » ou « ${0:5,.2f} ». La partie field_name du modèle doit être un 0 (zéro) (le « {0: » dans les exemples ci-dessus). Vous pouvez cesser la conduite « {0: »et ce qui suit »} » si le modèle contient seulement un format. Regardez le langage des modèles et la documentation Python pour plus d’exemples. Retourne une chaîne vide si le formatage échoue.

  • human_readable() – s’attend que la valeur soit un nombre et renvoie une chaîne représentant ce nombre en KB, MB, GB, etc.

  • ifempty(text) – si le champ n’est pas vide, renvoie la valeur du champ. Autrement renvoie text.

  • in_list(separator, pattern, found_val, ..., not_found_val) – interprète le champ comme une liste d’éléments séparés par separator, comparant la pattern avec chaque valeur de la liste. Si la pattern correspond à une valeur, retourne found_val, sinon, retourne not_found_val. pattern et found_value peuvent être répétés autant de fois que désiré, permettant de renvoyer différentes valeurs dépendantes de la recherche. Les modèles sont traitées dans l’ordre. La première correspondance est renvoyée.

  • language_codes(lang_strings) – retourne les codes de langue pour les chaines passées dans lang_strings. Les chaines doivent être dans la langue actuelle de localisation. Lang_strings est une liste séparée par des virgules.

  • language_strings(lang_codes, localize) – retourne les chaines des codes de langue passées dans lang_codes. Si localize`est égal à zéro, retourne les chaines en anglais. Si localisation est différente de zéro, retourne les chaines dans la langue utilisée actuellement. `Lang_codes est une liste séparée par des virgules.

  • list_item(index, separator) – interprète la valeur comme une liste d’articles séparés par separator, retourne l’article index. Le premier article est le nombre zéro. Le dernier article peut être retourné en utilisant list_item(-1,separator). Si l’article n’est pas dans liste, alors une valeur vide est renvoyée. Le séparateur a la même signification que dans la fonction count.

  • lookup(pattern, field, pattern, field, ..., else_field) – lcomme switch, sauf que les arguments sont des noms de champs (métadonnées), et pas du texte. La valeur du champ approprié sera récupérée et utilisée. Notez que vu que les colonnes composées sont des champs, vous pouvez utiliser cette fonction dans un champ composé pour utiliser la valeur d’autres champs composés. C’est extrêmement utile dans la construction des chemins d’enregistrement variables (plus à ce propos ultérieurement).

  • re(pattern, replacement) – renvoie le champ après avoir appliquer l’expression régulière. Toutes les instances de pattern seront remplacées par replacement. Comme tout dans calibre, celles-ci sont des expressions régulières Python-compatibles.

  • select(key) – interprète la valeur comme une liste d’articles séparés par des virgules, ceux-ci étant de la forme « id:valeur ». Trouve la paire avec l’id égale à la clé, et retourne la valeur correspondante. Cette fonction est particulièrement utile pour extraire une valeur telle qu’un isbn à partir d’un ensemble d’identifiants pour un livre.

  • shorten(left chars, middle text, right chars) – Retourne une version raccourcie du champ, constituée par les left chars caractères du début du champ, suivis par middle text et enfin par right chars de la fin de la chaîne. left chars et right chars doivent être des entiers. Par exemple, supposons que le titre du livre est Ancient English Laws in the Times of Ivanhoe, et que vous voulez que ce titre rentre dans un espace maximal de 15 charactéres. Si vous utilisez {title:shorten(9,-,5)}, le resultat sera Ancient E-nhoe. Si la longueur du champ est inférieure à left chars + right chars + la longueur de middle text, alors le champ ne sera pas modifié. Par exemple, le titre The Dome ne serait pas modifié.

  • ``str_in_list(separator, string, found_val, …, not_found_val) – interprète le champ comme une liste d’éléments séparés par separator, comparant string avec chaque valeur de la liste. Si string correspond à une valeur (ignorant la casse) cela retourne found_val, sinon, cela retourne not_found_val. Si la chaîne contient des séparateurs, alors elle est également traitée comme une liste et chaque valeur est vérifiée. string et found_value peuvent être répétés autant de fois que désiré, permettant de renvoyer différentes valeurs dépendantes de la recherche. Les chaînes sont traitées dans l’ordre. La première correspondance est renvoyée.

  • subitems(start_index, end_index) – Cette fonction est utilisée pour séparer des listes d’éléments analogues de type hiérarchique comme les genres. Elle interprète le champ comme une liste d’éléments séparés par des virgules d’éléments analogues, où chaque élément est une liste séparée par des points. Retourne une nouvelle liste composée en recherchant d’abord tous les éléments analogues séparés par des points, puis pour chacun de ces éléments en extrayant les composantes entre start_index et end_index avant de les recombiner. Le premier élément dans une liste séparée par des points a un index de 0. Si un index est négatif, alors il part de la fin de la liste. Comme cas spécial, un fin_index de zéro est considéré comme étant la longueur de la liste. Exemples

    Assuming a #genre column containing "A.B.C":
        {#genre:subitems(0,1)} returns "A"
        {#genre:subitems(0,2)} returns "A.B"
        {#genre:subitems(1,0)} returns "B.C"
    Assuming a #genre column containing "A.B.C, D.E":
        {#genre:subitems(0,1)} returns "A, D"
        {#genre:subitems(0,2)} returns "A.B, D.E"
    
  • ``sublist(start_index, end_index, separator) – interprète le champ comme une liste d’éléments séparés par separator, retournant une nouvelle liste composée des éléments compris entre start_index et end_index. Le premier élément est le numéro 0. Si un index est négatif, alors il part de la fin de la liste. Comme cas spécial, un end_index de zéro est considéré comme étant la longueur de la liste. Des exemples supposant que la colonne des étiquettes (qui sont séparées par des virgules) contient « A, B, C »

    {tags:sublist(0,1,\,)} returns "A"
    {tags:sublist(-1,0,\,)} returns "C"
    {tags:sublist(0,-1,\,)} returns "A, B"
    
  • swap_around_comma() – donne un champ avec une valeur au format « B, A », renvoie « A B ». Ceci est très utile pour la conversion des noms du format NF, Pr vers Pr NF. Si il n’y a pas de virgule, la fonction renvoie val non modifiée

  • switch(pattern, value, pattern, value, …, else_valeur) – pour chaque paire pattern, value, vérifie si le champ à des correspondances pour l’expression régulière pattern et si oui renvoie cette valeur. Si aucun pattern ne correspond, alors else_value est renvoyé. Vous pouvez avoir autant de paires pattern, value que vous voulez.

  • test(text if not empty, text if empty) – renvoie text if not empty si le champ n’est pas vide, sinon renvoie text if empty.

  • transliterate() - Restitue une chaîne en alphabet latin représentant approximativement le son des mots de la chaîne source. Par exemple, si le champ source est Фёдор Миха́йлович Достоевский` la fonction renverra Fiodor Mikhailovich Dostoievskii.”

Maintenant, qu’en est-il de l’utilisation des fonctions et du formatage dans le même champ. Supposons que vous avez une colonne personnalisée appelée #myint que vous voulez avoir avec des 0 devant, tel que 003. Pour ce faire, vous devez utiliser un format de 0>3s. Cependant, par défaut, si un nombre (entier ou flottant) est égal à zéro alors le champ retourne une valeur vide, et les valeurs nulles ne produisent rien, pas 000. Si vous voulez vraiment voir la valeur 000, alors vous utilisez à la fois un format de chaîne et la fonction ifempty pour traiter la valeur vide et la transformer en zéro. La référence de champ serait:

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

Notez que vous pouvez également utiliser préfixe et suffixe, si vous voulez que le nombre apparaisse comme [003] ou [000], utilisez alors le champ:

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

Utiliser les fonctions dans les modèles - mode modèle de programme

Le langage du mode modèle de programme diffère du mode fonction seule en ce qu’il permet d’écrire des expressions de modèles qui font référence à d’autres champs de métadonnées, champs, de modifier les valeurs et faire de l’arithmétique. Il s’agit d’un langage de programmation assez complet.

Vous pouvez utiliser les fonctions documentées ci-dessus dans le mode de programmation de modèle. Voir ci-dessous pour plus de détails.

Commençons par un exemple : supposons que vous voulez que votre modèle vous donne la série d’un livre s’il en a une, et sinon vous donne la valeur du champ personnalisé #genre. Vous ne pouvez pas le faire dans la langue de base, parce que vous ne pouvez pas faire référence à un autre champ de métadonnées dans l’expression d’un modèle. En mode programmation, vous pouvez. L’expression suivante fonctionne:

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

L’exemple montre plusieurs choses :

  • le mode modèle de programmation est utilisé si l’expression commence par :' et se termine par '. Tout le reste est considéré comme étant fonction-seule.
  • la variable $ représente le champ sur lequel porte l’expression opère, #series dans ce cas.
  • les fonctions doivent être donnés avec tous leurs arguments. Il n’y a pas de valeur par défaut. Par exemple, les fonctions intégrées standard doivent avoir un paramètre initial supplémentaire indiquant le champ source, ce qui est une différence importante avec le mode fonction-seule.
  • les espaces sont ignorés et peuvent être utlisés n’importe où dans l’expression.
  • les chaînes constantes sont entre guillemets, soit ' ou ".

Le langage est similaire aux langages fonctionnels en ce qu’il est construit presque entièrement à partir de fonctions. Une déclaration est une fonction. Une expression est une fonction. Constantes et identificateurs peuvent être considérés comme des fonctions renvoyant la valeur indiquée par la constante ou stockés dans l’identificateur.

La syntaxe du langage est représentée par la grammaire suivante:

constant   ::= " string " | ' string ' | number
identifier ::= sequence of letters or ``_`` characters
function   ::= identifier ( statement [ , statement ]* )
expression ::= identifier | constant | function | assignment
assignment ::= identifier '=' expression
statement  ::= expression [ ; expression ]*
program    ::= statement

Les commentaires sont des lignes avec le caractère “#” au début de la ligne.

Une expression a toujours une valeur, soit la valeur d’une constante, soit la valeur contenue dans un identifiant, ou la valeur retournée par une fonction. La valeur d’une déclaration est la valeur de la dernière expression d’une phrase de déclarations. De même, la valeur d’un programme (déclaration):

1; 2; 'foobar'; 3

est 3.

Un autre exemple d’un programme complexe, même s’il est un peu ridicule, pourrait aider à clarifier les choses:

{series_index:'
    substr(
        strcat($, '->',
            cmp(divide($, 2), 1,
                assign(c, 1); substr('lt123', c, 0),
                'eq', 'gt')),
        0, 6)
   '| prefix | suffix}

Ce programme fait ce qui suit :

  • précise que le champ qui doit être traité est series_index. Cela définit la valeur de la variable $.
  • appelle la fonction substr, qui comprend 3 paramètres (str, start, end). Elle renvoie une chaîne qui est formée par l’extraction des caractères du début à la fin de la chaîne, base zéro (le premier caractère est un caractére zéro). Dans ce cas, la chaîne sera calculée par la fonction strcat, le début est 0, et la fin est 6. Dans ce cas, elle retournera les 6 premiers caractères de la chaîne renvoyée par strcat, qui doit être évaluée avant que substr puisse renvoyer.
  • appelle la fonction strcat (concaténation de chaîne). Strcat accepte 1 ou plus d’arguments, et renvoie une chaîne formée par la concaténation de toutes les valeurs. Dans ce cas il y a trois arguments. Le premier paramètre est la valeur dans $, qui ici est la valeur de series_index. Le deuxième paramètre est la chaîne constante '->'. Le troisième paramètre est la valeur retournée par la fonction cmp, qui doit être complètement évaluée avant que strcat puisse renvoyer.
  • La fonction cmp comprend 5 arguments (x, y, lt, eq, gt). Elle compare x et y et renvoie le troisième argument lt si x < y, le quatrième argument eq si x == y, et le cinquième argument gt si x > y. Comme avec toutes les fonctions, tous les paramètres peuvent être des déclarations. Dans ce cas le premier paramètre (la valeur pour x) est le résultat de la division de series_index par 2. Le deuxième paramètre y est la constante 1. Le troisième paramètre t est une déclaration (plus à ce sujet plus tard). Le quatrième paramètre eq est la chaîne constante 'eq'. Le cinquième paramètre est la chaîne constante 'gt'.
  • The third parameter (the one for lt) is a statement, or a sequence of expressions. Remember that a statement (a sequence of semicolon-separated expressions) is also an expression, returning the value of the last expression in the list. In this case, the program first assigns the value 1 to a local variable c, then returns a substring made by extracting the c’th character to the end. Since c always contains the constant 1, the substring will return the second through end’th characters, or 't123'.
  • Une fois la déclaration donnant la valeur du troisième paramètre est exécutée, cmp peut renvoyer une valeur. A ce moment, strcat peut renvoyer une valeur, puis substr peut renvoyer une valeur. Ensuite, le programme se termine.

Pour différentes valeurs de series_index, le programme renvoie :

  • series_index == indéfini, résultat = préfixe ->t123 suffixe
  • series_index == 0.5, resultat = prefix 0.50-> suffix
  • series_index == 1, résultat = préfixe 1->t12 suffixe
  • series_index == 2, résultat = préfixe 2->eq suffixe
  • series_index == 3, résultat = préfixe 3->gt suffixe

Toutes les fonctions listées sous le mode fonction-seule peuvent être utilisées dans le mode programmation. Pour faire cela, vous devez fournir la valeur sur laquelle la fonction agit comme premier paramètre, en complément des paramètres documentés ci-dessus. Par exemple, en mode programmation les paramètres de la fonction test sont test(x, text_if_not_empty, text_if_empty). Le paramètre x, qui est la valeur à tester, sera presque toujours une variable ou un appel de fonction, souvent field().

Les fonctions suivantes sont disponibles en complément de celles décrites dans le mode fonction-seule. Rappelez-vous de l’exemple ci-dessus que les fonctions du mode fonction-seule requièrent un premier paramètre additionnel spécifiant le champ sur lequel opérer.Avec l’exception du paramètre id d’assign, tous les paramètres peuvent être des déclarations (séquences d’expressions). Notez que la documentation définitive pour les fonctions est disponible dans la section Classification de fonction:

  • and(valeur, valeur, …) – renvoie la chaîne « 1 » si toutes les valeurs ne sont pas vides, sinon renvoie la chaine vide. Cette fonction fonctionne très bien avec test ou first_non_empty. Vous pouvez avoir autant de valeurs que vous voulez.

  • add(x, y) – renvoie x + y. Renvoie une exception si x ou y ne sont pas des nombres.

  • assign(id, val) – assigne val à id, puis renvoie val. id doit être un identifiant, pas une expression

  • approximate_formats() – retourne une liste de formats, séparées par des virgules, qui, à un certain moment, on été associés avec le livre. Il n’y a aucune garantie que cette liste est correcte, bien qu’elle le soit probablement. Cette fonction peut-être appelée en mode de modèle de programme en utilisant le modèle « {:”approximate_formats()”} ». Notez que ces noms de formats sont toujours en majuscule, comme dans EPUB.

  • author_links(val_separator, pair_separator) – retourne une chaîne contenant une liste d’auteurs et les valeurs de ce lien d’auteur dans la forme auteur1 val_separator author1link pair_separator auteur2 val_separator author2link etc. Un auteur est séparé de la valeur de son lien par la chaîne val_separator sans espaces ajoutés. Les paires author:linkvalue sont séparées par la chaîne d’argument pair_separator sans espaces ajoutés. Il vous incombe de choisir des chaines de séparateur qui n’apparaissent pas dans des noms ou des liens d’auteur. Un auteur est inclus même si le lien d’auteur est vide.

  • author_sorts(val_separator) – renvoie une chaîne contenant une liste des valeurs de tri de l’auteur pour les auteurs du livre. Le tri est celui des métadonnées auteur (différente de l’author_sort dans les livres). La liste renvoyée a ltri auteur 1 val_separator tri auteur 2 etc. Les valeurs de tri auteur dans cette liste sont dans le même ordre que les auteurs du livre. Si vous voulez les espaces autour du val_separator incluez les alors dans la chaîne separator

  • booksize() – renvoie la valeur du champ “size” de calibre. Renvoie “” s’il n’y a pas de formats.

  • cmp(x, y, lt, eq, gt) – compare x et y après les avoir converti tous les deux en nombres. Renvoie lt si x < y. Renvoie eq si x == y. Sinon renvoie gt.

  • current_library_name() – retourne le dernier nom du chemin de la bibliothèque calibre actuelle. Cette fonction peut-être appelée en mode de modèle de programme en utilisant le modèle {:'current_library_name()'}.

  • current_library_path() – retourne le chemin de la bibliothèque calibre actuelle. Cette fonction peut-être appelée en mode de modèle de programme en utilisant le modèle {:'current_library_path()'}.

  • days_between(date1, date2) – renvoie le nombre de jours entre date1 et date2. Le nombre est positif si date1 est plus grand que date2, sinon négatif. Si date1 ou date2 ne sont pas des dates, la fonction renvoie une chaîne vide.

  • divide(x, y) – renvoie x / y. Renvoie une exception si x ou y ne sont pas des nombres.

  • eval(string) – évalue la chaîne, en analysant les variables locales (celles ``assign``ées à). Cela permet en utilisant le traitement du modèle de construire des résultats complexes à partir de variables locales. Parce que les caractères { et } sont spéciaux, vous devez utiliser [[ pour le caractère { et ]] pour le caractère } ; ils sont convertis automatiquement. Notez également que les préfixes et les suffixes (la syntaxe |prefix|suffix) ne peuvent pas être utilisés dans les arguments de cette fonction lorsque le mode modèle de programmation est utilisé.

  • field(name) – renvoie le champ de métadonnée nommé par name.

  • first_matching_cmp(val, cmp1, result1, cmp2, r2, ..., else_result) – compare val < cmpN dans la séquence, retourne resultN pour la première comparaison qui réussit. Retourne else_return si aucune comparaison ne réussit. Exemple:

    first_matching_cmp(10,5,"small",10,"middle",15,"large","giant")
    

    renvoie « large ». Le même exemple avec une première valeur à 16 renvoie « géant ».

  • first_non_empty(valeur, valeur, …) – retourne la première valeur non vide. Si toutes les valeurs sont vides, la valeur vide est retournée. Vous pouvez avoir autant de valeurs que vous voulez.

  • format_date(val, format_string) – formate la valeur, qui doit être un champ date, en utilisant format_string, retournant une chaîne. Les codes de formatage sont:

    d    : the day as number without a leading zero (1 to 31)
    dd   : the day as number with a leading zero (01 to 31)
    ddd  : the abbreviated localized day name (e.g. "Mon" to "Sun").
    dddd : the long localized day name (e.g. "Monday" to "Sunday").
    M    : the month as number without a leading zero (1 to 12).
    MM   : the month as number with a leading zero (01 to 12)
    MMM  : the abbreviated localized month name (e.g. "Jan" to "Dec").
    MMMM : the long localized month name (e.g. "January" to "December").
    yy   : the year as two digit number (00 to 99).
    yyyy : the year as four digit number.
    h    : the hours without a leading 0 (0 to 11 or 0 to 23, depending on am/pm)
    hh   : the hours with a leading 0 (00 to 11 or 00 to 23, depending on am/pm)
    m    : the minutes without a leading 0 (0 to 59)
    mm   : the minutes with a leading 0 (00 to 59)
    s    : the seconds without a leading 0 (0 to 59)
    ss   : the seconds with a leading 0 (00 to 59)
    ap   : use a 12-hour clock instead of a 24-hour clock, with 'ap' replaced by the localized string for am or pm.
    AP   : use a 12-hour clock instead of a 24-hour clock, with 'AP' replaced by the localized string for AM or PM.
    iso  : the date with time and timezone. Must be the only format present.
    

    Vous pourriez obtenir des résultats inattendus si la date que vous formatez contient des noms de mois localisés, ce qui peut arriver si vous changez les ajustements de format pour contenir MMMM. Dans ce cas, à la place d’utiliser quelque chose comme {pubdate:format_date(yyyy)}, écrivez le modèle en utilisant le mode programmation de modèle comme dans {:'format_date(raw_field('pubdate'),'yyyy')'}.

  • finish_formatting(val, fmt, prefix, suffix) – applique le format, le préfixe, et le suffixe à une valeur de la même manière que cela ce fait dans un modèle comme {series_index:05.2f| - |- }. Cette fonction est fournie pour facilité la conversion d’une single-function complexe - ou des modèles template-program-mode en mode général de programmation (voir ci-dessous) pour profiter de l’avantage de la compilation de modèle GPM. Par exemple, le programme suivant produit la même sortie que le modèle ci-dessus:

    program: finish_formatting(field("series_index"), "05.2f", " - ", " - ")
    

    Un autre exemple: pour le modèle {series:re(([^\s])[^\s]+(\s|$),\1)}{series_index:0>2s| - | - }{title} utilisez:

    program:
        strcat(
            re(field('series'), '([^\s])[^\s]+(\s|$)', '\1'),
            finish_formatting(field('series_index'), '0>2s', ' - ', ' - '),
            field('title')
        )
    
  • formats_modtimes(format_string) – retourne une liste séparée par des virgules d’éléments séparés par deux-points représentant les dates de modification pour les formats d’un livre. Le paramètre format_string indique comment la date doit être formatée. Voir la fonction format_date() pour plus de détails. Vous pouvez utiliser la fonction select pour obtenir le moment de modification pour un format spécifique. Veuillez noter que les noms de format sont toujours en majuscules, comme dans EPUB.

  • formats_paths() – retourne une liste séparées par des virgules d’éléments séparés par deux points représentant le chemin absolu vers les formats d’un livre. Vous pouvez utiliser cette fonction pour obtenir le chemin d’un format spécifique. Notez que ces noms de formats sont toujours en majuscule, comme dans EPUB.

  • formats_sizes() – renvoie une liste séparée par des virgules correspondant à des articles représentant les tailles en octets des formats du livre. Vous pouvez utiliser la fonction select pour obtenir la taille d’un format spécifique. Notez que ces noms de formats sont toujours en majuscule, comme dans EPUB.

  • has_cover() – renvoie Yes si le livre a une couverture, sinon renvoie une chaine vide

  • not(value) – renvoie la chaîne « 1 » si la valeur est vide, sinon renvoie la chaîne vide. Cette fonction fonctionne très bien avec test ou first_non_empty.

  • list_difference(list1, list2, separator) – restitue une liste en supprimant de list1 tout élément trouvé dans list2 ``en utilisant une comparaison insensible à la casse. Les éléments dans ``list1 et list2 sont séparés par le séparateur, comme le sont les éléments dans la liste restituée.

  • list_equals(list1, sep1, list2, sep2, yes_val, no_val) –retourne yes_val si list1 et list2 contiennent les mêmes éléments, sinon renvoie no_val. Les éléments sont déterminés en éclatant chaque liste à l’aide du séparateur approprié (sep1 ou sep2). L’ordre des éléments dans la liste n’est pas pris en compte. La comparaison est insensible à la casse.

  • list_intersection(list1, list2, separator) – restitue une liste en supprimant de list1 tout élément non trouvé dans list2 ``en utilisant une comparaison insensible à la casse. Les éléments dans ``list1 et list2 sont séparés par le séparateur, comme le sont les éléments dans la liste restituée.

  • list_re(src_list, separator, include_re, opt_replace) – Construit une liste en séparant d’abord src_list en éléments utilisant le caractère de séparation. Pour chaque élément dans la liste, vérifie s’il correspond à include_re. Si c’est le cas, alors il l’ajoute à la liste à renvoyer. Si opt_replace n’est pas une chaîne vide, alors effectue le remplacement avant d’ajouter l’élément à la liste renvoyée.

  • list_re_group(src_list, separator, include_re, search_re, template_for_group_1, for_group_2, ...) – Comme list_re excepté que les remplacements ne sont pas optionnels. Il utilise re_group(item, search_re, template …) quand il effectue les remplacements.

  • ``list_sort(list, direction, separator) – retourne une liste triée en utilisant un tri insensible à la casse. Si direction est zéro, la liste est triée de manière ascendante, sinon descendante. Les éléments sont séparés par le séparateur, comme ceux de la liste retournée.

  • list_union(list1, list2, separator) – restitue une liste créée de la fusion des éléments dans list1 et list2, supprimant les doublons en utilisant une comparaison insensible à la casse. Si la casse des éléments diffère, celle de list1 est utilisée. Les éléments dans list1 et list2 sont séparés par le séparateur, comme ceux de la liste restituée.

  • multiply(x, y) – renvoie x * y. Renvoie une exception si x ou y ne sont pas des nombres.

  • ondevice() – renvoie la chaîne « Yes » si ondevice est paramétré, sinon renvoie la chaîne vide

  • or(value, value, …) – renvoie la chaîne « 1 » si n’importe quelle valeur n’est pas vide, sinon renvoie la chaine vide. Cette fonction fonctionne très bien avec test ou first_non_empty. Vous pouvez avoir autant de valeurs que vous voulez.

  • print(a, b, …) – affiche les arguments dans la console standard. Sauf si vous avez démarré calibre à partir de la ligne de commande (calibre-debug -g), la sortie ira dans un trou noir.

  • raw_field(name) – renvoie le champ de métadonnée nommé par name sans appliquer aucun formatage.

  • raw_field(name, separator) – renvoie la liste de métadonnées nommée par name sans appliquer aucun formatage ou triage et avec les éléments séparés par separator.

  • re_group(val, pattern, template_for_group_1, for_group_2, ...) – renvoie une chaîne faite en appliquant le modèle d’expression régulière à la valeur et en remplaçant chaque instance assortie par la chaîne calculée en remplaçant chaque groupe assorti par la valeur retournée par le modèle correspondant. La valeur assortie originale pour le groupe est disponible comme $. En mode programmation de modèle, comme pour le modèle et les fonctions eval, vous utiliserez [[ pour { et ]] pour }. L’exemple suivant en mode programmation de modèle recherche des séries avec plus d’un mot et des majuscules dans le premier mot:

    {series:'re_group($, "(\S* )(.*)", "[[$:uppercase()]]", "[[$]]")'}
    
  • series_sort() – renvoie la valeur de tri des séries.

  • strcat(a, b, …) – peut avoir n’importe quel nombre d’arguments. Renvoie une chaine constituée par la concaténation de tous les arguments.

  • strcat_max(max, string1, prefix1, string2, …) – Retourne la chaîne formée par la concaténation des arguments. La valeur retournée est initialisée à string1. Les paires “Prefix,string” sont ajoutées à la fin de la valeur tant que la taille de la chaîne de sortie est plus petite que “max”. String1 est retournée même si string1 est plus grande que max. Vous pouvez passer autant de paires de “prefix,string” que vous le souhaitez.

  • strcmp(x, y, lt, eq, gt) – effectue une comparaison insensible à la casse des chaines x et y. Renvoie lt si x < y. Renvoie eq si x == y. Sinon renvoie gt.

  • strlen(a) – Retourne la longueur de la chaîne de caractères passée en argument.

  • substr(str, start, end) – renvoie les caractères de début jusqu’à fin de str. Le premier caractère dans str est le caractère zéro. Si end est négatif, cela indique que beaucoup de caractères sont comptés à partir de la droite. Si end est zéro, cela indique le dernier caractère. Par exemple, substr('12345', 1, 0) renvoie '2345', et substr('12345', 1, -1) renvoie '234'.

  • subtract(x, y) – renvoie x - y. Renvoie une exception si x ou y ne sont pas des nombres.

  • today() – renvoie une chaine date pour aujourd’hui. Cette valeur est conçue pour être utiliser avec format_date ou days_between, mais peut être manipulée comme toute autre chaine. La date est au format ISO.

  • template(x) – évalue x comme un modèle. L’évaluation est effectuée dans son propre contexte, cela veut dire que les variables ne sont pas partagées entre l’appelant et l’évaluation du modèle. Comme les caractères { et } sont spéciaux, vous devez utiliser [[ pour le caractère { et ]] pour le caractère } ; ils sont convertis automatiquement. Par exemple, template('[[title_sort]]') évaluera le modèle {title_sort} et retournera sa valeur. Notez également que les préfixes et les suffixes (la syntaxe |prefix|suffix) ne peuvent pas être utilisés dans les arguments de cette fonction lorsque le mode modèle de programme est utilisé.

Classification de fonction

En utilisant le mode général de programmation

Pour les modèles de programme plus complexes, il est parfois plus facile d’éviter la syntaxe des modèles (avec tous ces caractères { et }), et utiliser à la place un programme plus classique. Vous pouvez le faire avec calibre en commençant par le modèle par program:. Dans ce cas, aucun traitement de modèle n’est fait. La variable spéciale $ n’est pas implémentée. C’est à votre programme de produire des résultats corrects.

Un avantage du mode program: est que les accolades ne sont plus considérées comme des caractères spéciaux. Par exemple, il n’est pas nécessaire d’utiliser des [[ et des ]] quand vous utilisez la fonction template(). Un autre avantage est que ces modèles sont compilés avec Python et peuvent tourner beaucoup plus vite que les modèles crées dans les deux autres modes. L’amélioration de la vitesse dépend de la complexité des modèles, plus le modèle est plus compliqué, plus l’amélioration est sensible. La compilation est activé ou désactivé à l’aide de l’ajustement compile_gpm_templates (Compiler les modèles du Mode Général de Programme en Python). La raison principale pour suspendre la compilation est si un modèle compilé ne fonctionne pas. Dans ce cas, merci de remplir un rapport d’erreur.

L’exemple suivant est un mode program: d’implémentation d’une recette sur le forum MobileRead : « Mettre les séries dans le titre, en utilisant soit les initiales soit une forme raccourcie. Retirer les articles principaux du nom de la série (n’importe lequel). » Par exemple, pour le livre The Two Towers dans la série Seigneur des Anneaux, la recette donne LotR [02] The Two Towers. En utilisant le modèle standard, la recette requiert trois colonnes personnalisées et un tableau de connexion, comme expliqué ci-après :

La solution requiert la création de trois colonnes composites. La première colonne est utilisée pour retirer les articles principaux. La seconde est utilisée pour calculer la forme “raccourcie”. La troisième est pour calculer la forme “initiales”. Une fois que vous avez ces colonnes, le tableau de connexion sélectionne entre elles. Vous pouvez masquer n’importe laquelle ou toutes les colonnes dans la vue bibliothèque:

First column:
Name: #stripped_series.
Template: {series:re(^(A|The|An)\s+,)||}

Second column (the shortened form):
Name: #shortened.
Template: {#stripped_series:shorten(4,-,4)}

Third column (the initials form):
Name: #initials.
Template: {#stripped_series:re(([^\s])[^\s]+(\s|$),\1)}

Plugboard expression:
Template:{#stripped_series:lookup(.\s,#initials,.,#shortened,series)}{series_index:0>2.0f| [|] }{title}
Destination field: title

This set of fields and plugboard produces:
Series: The Lord of the Rings
Series index: 2
Title: The Two Towers
Output: LotR [02] The Two Towers

Series: Dahak
Series index: 1
Title: Mutineers Moon
Output: Dahak [01] Mutineers Moon

Series: Berserkers
Series Index: 4
Title: Berserker Throne
Output: Bers-kers [04] Berserker Throne

Series: Meg Langslow Mysteries
Series Index: 3
Title: Revenge of the Wrought-Iron Flamingos
Output: MLM [03] Revenge of the Wrought-Iron Flamingos

Le programme qui suit produit le même résultat que la recette originale, en utilisant seulement une colonne personnalisée pour conserver le résultat d’un programme qui calcule la valeur spéciale titre:

Custom column:
Name: #special_title
Template: (the following with all leading spaces removed)
    program:
    #       compute the equivalent of the composite fields and store them in local variables
        stripped = re(field('series'), '^(A|The|An)\s+', '');
        shortened = shorten(stripped, 4, '-' ,4);
        initials = re(stripped, '[^\w]*(\w?)[^\s]+(\s|$)', '\1');

    #       Format the series index. Ends up as empty if there is no series index.
    #       Note that leading and trailing spaces will be removed by the formatter,
    #       so we cannot add them here. We will do that in the strcat below.
    #       Also note that because we are in 'program' mode, we can freely use
    #       curly brackets in strings, something we cannot do in template mode.
        s_index = template('{series_index:0>2.0f}');

    #       print(stripped, shortened, initials, s_index);

    #       Now concatenate all the bits together. The switch picks between
    #       initials and shortened, depending on whether there is a space
    #       in stripped. We then add the brackets around s_index if it is
    #       not empty. Finally, add the title. As this is the last function in
    #       the program, its value will be returned.
        strcat(
            switch( stripped,
                    '.\s', initials,
                    '.', shortened,
                    field('series')),
            test(s_index, strcat(' [', s_index, '] '), ''),
            field('title'));

Plugboard expression:
Template:{#special_title}
Destination field: title

Il serait possible de faire ce qu’il y a ci-dessus sans colonnes personnalisées en mettant le programme dans la case modèle du tableau de connexion. Cependant, pour faire cela,tous les commentaires doivent être supprimés car la case de texte du tableau de connexion ne supporte pas l’édition multi-lignes. C’est discutable si le gain de ne pas avoir la colonne personnalisée vaille la vaste augmentation en difficulté provoquée par le fait que le programme soit une ligne géante.

Modèles de fonctions définies par l’utilisateur

Vous pouvez ajouter vos propres fonctions au traitement des modèles. Ces fonctions s’écrivent en Python, et peuvent être utilisées dans n’importe lequel des trois modes de programmation de modèle. Les fonctions sont ajoutées en allant dans Préférences->Avancé->Modèles de fonctions. Les instructions sont affichées dans cette boite de dialogue.

Notes spéciales pour la sauvergarde/l’envoi des modèles

Un traitement spécial est appliqué quand un modèle est utilisé dans un modèle Enregistrer sur le disque ou Envoyer au périphérique. Les valeurs des champs sont nettoyées, les caractères qui sont propres aux systèmes de fichiers sont remplacées par des traits de soulignement, y compris les barres obliques. Cela signifie que le texte d’un champ ne peut pas être utilisé pour créer des dossiers. Toutefois, les barres obliques ne sont pas modifiés dans des chaînes préfixe ou suffixe. Vous pouvez donc insérer des barres obliques qui et provoquer ainsi la création de dossiers. Ainsi, vous pouvez créer une structure de dossier avec des profondeurs variables.

Par exemple, supposons que nous voulons que la structure des dossiers soit series/series_index - titre, en prévoyant que si la série n’existe pas, alors le titre devrait être dans le dossier racine (le premier dossier, pas le sous-dossier). Le modèle pour faire cela est :

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

La barre oblique et le trait d’union apparaissent uniquement si la série n’est pas vide.

La fonction de recherche nous permet de faire le traitement encore plus poussé. Par exemple, supposons que si un livre est dans une série, alors nous voulons que la structure soit la suivante : series/series index - title.fmt.. Si le livre n’est pas dans une série, alors nous voulons que la structure des dossiers soit genre/author_sort/title.fmt. Si le livre n’a pas de genre, nous voulons utiliser “Inconnu”. Nous voulons deux chemins de répertoire totalement différents en fonction de la valeur de la série.

Pour accomplir cela, nous :
  1. Créons une colonne composite (appelons-la #AA) contenant {series}/{series_index} - {title}. Si la série n’est pas vide, alors ce modèle produit series/series_index - title.
  2. Créons une champ composite (appelons-le #BB) contenant {#genre:ifempty(Unknown)}/{author_sort}/{title}. Ce modèle produit genre/author_sort/title, où un genre vide est remplacé par Inconnu.
  3. Paramétrez le modèle de sauvegarde à {series:lookup(.,#AA,#BB)}. Ce modèle choisit le champ composite #AA si série n’est pas vide, et le champ composite #BB si série est vide. Nous avons dès lors deux chemins de sauvegarde complètement différents, dépendant du fait que series soit vide ou pas.

Modèles et tableaux de connexions

Les tableaux de connexions sont utilisés pour modifier les métadonnées écrites dans les livres pendant l’envoi à une liseuse et les opérations de sauvegarde sur le disque. Le tableau de connexion vous permet de spécifier pour un modèle de lecteur précis quelles données à insérer dans les métadonnées du livre. Vous pouvez utiliser les tableaux de connexions pour modifier les champs suivants : authors, author_sort, language, publisher, tags, title, title_sort. Cette fonctionnalité aide ceux qui veulent utiliser les différentes métadonnées des livres pour contrôler le tri ou l’affichage des livres sur leurs périphériques.

Lorsque vous créez un tableau de connexion, vous spécifiez le format et le périphérique pour lequel le tableau de connexion doit être utilisé. Un périphérique spécial est procuré, save_to_disk qui est utilisé lors de la sauvegarde de formats (en opposition à les envoyer vers le périphérique). Une fois que vous avez choisi le format et le périphérique, vous choisissez les champs de métadonnées à modifier, indiquez le modèle à appliquer pour fournir les nouvelles valeurs. Ces modèles sont reliés à leurs champs de destination, d’où le nom de tableau de connexions. Vous pouvez, bien sûr, utiliser des colonnes composites dans ces modèles.

Quand un tableau de connexion doit s’appliquer (Serveur de contenu, sauvegarde sur disque ou envoyer au périphérique), calibre recherche les tableau de connexions définis et celui qui est correct pour le format donné et le périphérique. Par exemple, pour trouver le tableau de connexion approprié pour un livre EPUB envoyé à un périphérique ANDROID, calibre recherche dans les tableaux de connexion dans l’ordre de recherche suivant :

  • un tableau de connexion avec une correspondance exacte sur le format et le périphérique, par ex., EPUB et ANDROID
  • un tableau de connexion avec une correspondance exacte sur le format et le choix spécial n'importe quel périphérique, par ex., EPUB et n'importe quel périphérique
  • un tableau de connexion avec le choix spécial n'importe quel format et une correspondance exacte sur le périphérique, par ex., n'importe quel format et ANDROID
  • un tableau de conversion avec n'importe quel format et n'importe quel périphérique

Les étiquettes et les champs auteur ont un traitement spécial, parce que ces deux champs peuvent contenir plusieurs données. Un livre peut avoir plusieurs étiquettes et plusieurs auteurs. Lorsque vous spécifiez que l’un de ces deux champs doit être modifié, le résultat du modèle est examiné pour voir s’il y a plus d’un élément dedans. Pour les étiquettes, le résultat est découpé partout où calibre trouve une virgule. Par exemple, si le modèle produit les valeurs Thriller, Horreur, alors ke résultat sera deux étiquettes, Thriller et Horreur. Il n’est pas possible de mettre une virgule au milieu d’une étiquette.

La même chose se produit pour les auteurs, mais en utilisant un caractère différent comme séparateur, le & (esperluette) au lieu d’une virgule. Par exemple, si le modèle produit la valeur Blogs, Joe&Posts, Susan, alors le livre finira avec deux auteurs Blogs, Joe et Posts, Susan. Si le modèle produit la valeur Blogs, Joe;Posts, Susan, alors ce livre aura un auteur avec un nom assez étrange.

Les tableaux de connexions affectent les métadonnées écrites dans le livre quand il est sauvegardé sur le disque ou copié sur le périphérique. Les tableaux de connexions n’affecte pas les métadonnées utilisées par Enregistrer sur le disque et Envoyer au périphérique. A la place, les noms de fichiers sont construits en utilisant les modèles entrés dans la fenêtre de préférence appropriée.

Astuces utiles

Vous devriez trouver les astuces suivantes utiles.

  • Créez une colonne composite pour tester vos modèles. Une fois la colonne en place, vous pouvez modifier son modèle en double cliquant simplement dessus.Masquez cette colonne lorsque vous ne testez pas.
  • Les modèles peuvent utiliser d’autres modèles se référençant à des colonnes composites.
  • Dans un tableau de connexions, vous pouvez paramétrer un champ à vide (ou quelque soit sont équivalent à vide) en utilisant le modèle spécial {}. Ce modèle sera toujours évalué à une chaîne vide.
  • La technique indiquée ci-dessus pour montrer les nombre même s’ils ont une valeur zéro fonctionne avec le champ standard series_index.