Thread: Old FAQ posts
View Single Post
Old 06-23-2015, 10:31 AM   #67
chaley
CC Android & calibre dev
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 8,632
Karma: 2655474
Join Date: Jan 2010
Location: France
Device: Many android devices
What can I use in a CC file name template?

CC file name templates are similar to calibre templates. You can use some column names, a prefix, and a suffix, and printf-style format specifications. An if-then-else construct is available to support conditional text; this construct is not supported by calibre. It does not support template functions.
  • The CC Template Language
    1. Basic syntax
      • The columns allowed are:
        • {title}, {title_sort} (title is the real title. No articles are moved)
        • {authors}, {first_author}, {author_sort}, {first_author_sort}
        • {series}, {series_index}
        • {id} (the calibre database identifier, which is a number)
        • text-type custom columns {#col_lookup_name}
      • Prefixes and suffixes are specified as in calibre:
        Code:
        {column:| prefix | suffix}
        Both the prefix and suffix part can be empty, as in:
        Code:
        {series:| - |}
      • Format specifications can be supplied as in calibre, but using printf format syntax instead of Python syntax. The usual use is to format a series index but it can be used for other purposes. Because series_index can be either an integer or a floating point number, you can supply two format specifiers: one for each. See the example below.

        Use this syntax to add a format specification:
        Code:
        {columnName:format|prefix|suffix)
        The prefix and suffix are optional, but if one is supplied then they both must be supplied. The format is also optional.

        A format specifier is a string beginning with a % character and ending with a format type character. Examples:
        • %d -- format as an integer
        • %04d -- format as an integer four digits long and zero-filled
        • %06.2f -- format as a floating point number 6 characters wide, zero-filled, with 3 digits to the left of the decimal point and 2 digits to the right of the decimal point.
        • %.10s -- format as a string to be at most 10 characters long.
        See printf format cheat sheet for more examples.

        As a special case, series_index can have two format specifiers, one to use if the index is an integer and the other to use if the index is a floating point number. The second format specifier is separated from the first by a slash. See the third example below for more details.
      • The following are examples of complete templates. The first has one segment (segments are separated by slashes):
        Code:
        {title} - {authors} ({id})
        The next has two segments:
        Code:
        {series}/{title} - {authors} ({id})
        This third example formats series index with leading zeros. Integer values are formatted with 3 digits. Floating point values are formatted to be 6 characters long: three digits to the left of the decimal point, the decimal point itself, and 2 digits to the right. In both cases the result is zero-filled.
        Code:
        {series} {series_index:%03d/%06.2f| [|]}/{title} - {authors} ({id})
    2. Conditional text (if-then-else) is specified as follows:
      Code:
      :if: some template :then: another template :else: another template :::
      CC will evaluate the template between the :if: and the :then:. If that evaluation results in a non-empty value then the :then: template is evaluated and the entire if-then-else is replaced with that result. If the evaluation of the :if: template results in an empty value then the :else: template is evaluated and the entire if-then-else is replaced with that value.

      Some notes:
      • The :else: part is optional: it is legal to have
        Code:
        :if: template :then: template 2 :::
      • In the then and else templates, the special value :tv: will be replaced with the value of the :if: template. (Yes, this doesn't have much use in the :else: part because it will always be empty.)
      • Spaces after the :if:, around :then: and :else:, and before ::: are removed.
      • You cannot nest an if-then-else inside another if-then-else. In other words, the following will not work because the second :if: is inside the first :else: part.
        Code:
        :if: {something} :then: bla :else: :if: {something else} :then: mumble ::: :::
      Some examples of if-then-else:
      • :if:{series}:then: :tv:/ :else:{first_author}/:::
        If the series is not empty then create a directory named by the series, otherwise create a directory named by the first author.
      • :if: {#genre} :then: {#genre:|Genre |} :else: {series:|Series ||} ::: {title}
        If the genre is not empty then prefix the title with Genre the-genre otherwise prefix the title with Series the-series if the series exists,
    3. CC's template processor "cleans" the result of the template as follows:
      • If a character is not in the following list then it is changed to undescore: letters, numbers, underscore, minus "-", ampersand "&", left square bracket "[", right square bracket "]", left parenthesis "(", right parenthesis ")", period ".", comma "," , slash "/", single quote "'", and equals "="
      • Multiple spaces are changed to a single space
      • Leading and trailing spaces in a segment (something between slashes) are removed
      • Leading and trailing periods in a segment are removed
      For example, if the two-segment example template above is used to generate a name for a book without a series, the result will be something like
      Code:
      bookTitle - bookAuthors (123)
      If the book has a series the result will be something like
      Code:
      bookSeries/bookTitle - bookAuthors (123)
  • Advanced Techniques
    It might be that you want to change the template based on some combination of metadata values. There are two ways to do this.
    1. Create a Yes/No column that is set to Yes for any book that would match the expression you want to use in the if test, otherwise set to empty. In this case the if test would be
      Code:
       :if: {#yesno_col} :then: {series_index:%04d} :else: {series_index:%04.2f}:::
    2. Use the order CC evaluates if/then within templates to insert information from calibre columns into the template.

      CC evaluates the if/then/else parts, substitutes the results back into the template, then evaluates the template with the substitutions. This permits you to specify arbitrary template parts inside the if statement that are used when finally evaluating the template. Consequence: you can put templates or template components in calibre columns then use these in CC. For example, the following would use a CC template stored in a text column in calibre:
      Code:
      :if:{#sometextcolumn}:then: :tv: :else:{the default template}:::
      If #sometextcolumn contains
      Code:
      :if: {series}:then:{series:|_|}:else:{first_author} :::/{series_index:%04d/%07.2f|[|] - }{title} -  {first_author}
      then that is the template that would be used.

      You can do the same thing with template components. For example, assume that #sif is a text column containing the format specifier to use for the series index for the book. The following template segment would use that format if it exists, otherwise %04d/%07.2f
      Code:
      {series} {series_index::if: {#sif} :then: :tv: :else: %04d/%07.2f:::}
      To finish the example, if #sif contains %03d/%06.2f then after processing the :if:, the template would be
      Code:
      {series} {series_index:%03d/%06.2f}
      If #sif is empty then after processing the :if:, the template would be
      Code:
      {series} {series_index:%04d/%07.2f}
      In the end you could use a different series index format for every series.


      Note that there is a bug in V4.0.5 causing % characters to be replaced before they are substituted into the template. Production release candidate V4.1.0, released to the beta group this morning, fixes this problem.

Last edited by chaley; 07-18-2015 at 06:02 AM.
chaley is offline