Skip to main content

Template engine for file paths. Expand variables like ``$title`` and apply functions like ``%upper{}``.

Project description

This package on the Python Package Index Tests Documentation Status

TMEP

TMEP (Template Macro Expansion for Paths) is a small template engine that has been specially developed for file paths.

The engine can replace or expand symbols (or variables) like $title and apply functions (or macros) like %upper{} in path templates.

The code originates from the Beets project and was “extracted” from the code base together with the tests.

Installation

From PyPI

pip install tmep

Usage

>>> import tmep
>>> template = "%upper{$prename $lastname}"
>>> values = {"prename": "Franz", "lastname": "Schubert"}
>>> result = tmep.parse(template, values)
>>> print(result)
FRANZ SCHUBERT

This module implements a string formatter based on the standard PEP 292 string.Template class extended with function calls. Variables, as with string.Template, are indicated with $ and functions are delimited with %.

This module assumes that everything is Unicode: the template and the substitution values. Bytestrings are not supported. Also, the templates always behave like the safe_substitute method in the standard library: unknown symbols are left intact.

This is sort of like a tiny, horrible degeneration of a real templating engine like Jinja2 or Mustache.

TMEP provides public Python functions and a small command line tool that outputs documentation in various formats that can be used by projects based on TMEP.

Introduction

tmep-doc --introduction-rst

Template Symbols (or Variables)

In path templates, symbols or varialbes such as $title (any name with the prefix $) are replaced by the corresponding value.

Because $ is used to delineate a field reference, you can use $$ to emit a dollars sign. As with Python template strings, ${title} is equivalent to $title; you can use this if you need to separate a field name from the text that follows it.

Template Functions (or Macros)

Path templates also support function calls, which can be used to transform text and perform logical manipulations. The syntax for function calls is like this: %func{arg,arg}. For example, the upper function makes its argument upper-case, so %upper{lorem ipsum} will be replaced with LOREM IPSUM. You can, of course, nest function calls and place variable references in function arguments, so %upper{$title} becomes the upper-case version of the title.

Syntax Details

The characters $, %, {, }, and , are “special” in the path template syntax. This means that, for example, if you want a % character to appear in your paths, you’ll need to be careful that you don’t accidentally write a function call. To escape any of these characters (except {, and , outside a function argument), prefix it with a $. For example, $$ becomes $; $% becomes %, etc. The only exceptions are:

  • ${, which is ambiguous with the variable reference syntax (like ${title}). To insert a { alone, it’s always sufficient to just type {.

  • commas are used as argument separators in function calls. Inside of a function’s argument, use $, to get a literal , character. Outside of any function argument, escaping is not necessary: , by itself will produce , in the output.

If a value or function is undefined, the syntax is simply left unreplaced. For example, if you write $foo in a path template, this will yield $foo in the resulting paths because “foo” is not a valid field name. The same is true of syntax errors like unclosed {} pairs; if you ever see template syntax constructs leaking into your paths, check your template for errors.

If an error occurs in the Python code that implements a function, the function call will be expanded to a string that describes the exception so you can debug your template. For example, the second parameter to %left must be an integer; if you write %left{foo,bar}, this will be expanded to something like <ValueError: invalid literal for int()>.

Functions

reStructuredText format (tmep-doc --functions-rst):

alpha

%alpha{text}: This function first ASCIIfies the given text, then all non alphabet characters are replaced with whitespaces.

Example: %alpha{a1b23c}a b c

alphanum

%alphanum{text}: This function first ASCIIfies the given text, then all non alpanumeric characters are replaced with whitespaces.

Example: %alphanum{après-évêque1}apres eveque1

asciify

%asciify{text}: Translate non-ASCII characters to their ASCII equivalents. For example, “café” becomes “cafe”. Uses the mapping provided by the unidecode module.

Example: %asciify{äÄöÖüÜ}aeAeoeOeueUe

delchars

%delchars{text,chars}: Delete every single character of “chars“ in “text”.

Example: %delchars{Schubert, ue}Schbrt

deldupchars

%deldupchars{text,chars}: Search for duplicate characters and replace with only one occurrance of this characters.

Example: %deldupchars{a---b___c...d}a-b_c.d; %deldupchars{a ---b___c, -}a-b___c

first

%first{text} or %first{text,count,skip} or %first{text,count,skip,sep,join}: Returns the first item, separated by ;. You can use %first{text,count,skip}, where count is the number of items (default 1) and skip is number to skip (default 0). You can also use %first{text,count,skip,sep,join} where sep is the separator, like ; or / and join is the text to concatenate the items.

Example: %first{Alice / Bob / Eve,2,0, / , & }Alice & Bob

if

%if{condition,trueval} or %if{condition,trueval,falseval}: If condition is nonempty (or nonzero, if it’s a number), then returns the second argument. Otherwise, returns the third argument if specified (or nothing if falseval is left off).

Example: x%if{false,foo}x

ifdef

%ifdef{field}, %ifdef{field,trueval} or %ifdef{field,trueval,falseval}: If field exists, then return trueval or field (default). Otherwise, returns falseval. The field should be entered without $.

Example: %ifdef{compilation,Compilation}

ifdefempty

%ifdefempty{field,text} or %ifdefempty{field,text,falsetext}: If field exists and is empty, then return truetext. Otherwise, returns falsetext. The field should be entered without $.

Example: %ifdefempty{compilation,Album,Compilation}

ifdefnotempty

%ifdefnotempty{field,text} or %ifdefnotempty{field,text,falsetext}: If field is not empty, then return truetext. Otherwise, returns falsetext. The field should be entered without $.

Example: %ifdefnotempty{compilation,Compilation,Album}

initial

%initial{text}: Get the first character of a text in lowercase. The text is converted to ASCII. All non word characters are erased.

Example: %initial{Schubert}s

left

%left{text,n}: Return the first “n” characters of “text”.

Example: %left{Schubert, 3}Sch

lower

%lower{text}: Convert “text” to lowercase.

Example: %lower{SCHUBERT}schubert

nowhitespace

%nowhitespace{text,replace}: Replace all whitespace characters with replace. By default: a dash (-)

Example: %nowhitespace{a b}a-b; %nowhitespace{a b, _}a_b

num

%num{number,count}: Pad decimal number with leading zeros.

Example: %num{7,3}007

replchars

%replchars{text,chars,replace}: Replace the characters “chars” in “text” with “replace”.

Example: %replchars{Schubert,-,ue}Sch-b-rt

right

%right{text,n}: Return the last “n” characters of “text”.

Example: %right{Schubert,3}ert

sanitize

%sanitize{text}: Delete characters that are not allowed in most file systems.

Example: %sanitize{x:*?<>|/~&x}xx

shorten

%shorten{text} or %shorten{text,max_size}: Shorten “text” on word boundarys.

Example: %shorten{Lorem ipsum dolor sit, 10}Lorem

time

%time{date_time,format,curformat}: Return the date and time in any format accepted by strftime. For example, to get the year, use %time{$added,%Y}.

Example: %time{30 Nov 2024,%Y,%d %b %Y}2024

title

%title{text}: Convert “text” to Title Case.

Example: %title{franz schubert}Franz Schubert

upper

%upper{text}: Convert “text” to UPPERCASE.

Example: %upper{foo}FOO

alpha
  ``%alpha{text}``:  This function first ASCIIfies the given text, then all
  non alphabet characters are replaced with whitespaces.

  **Example:** ``%alpha{a1b23c}`` → ``a b c``

alphanum
  ``%alphanum{text}``:  This function first ASCIIfies the given text, then all
  non alpanumeric characters are replaced with whitespaces.

  **Example:** ``%alphanum{après-évêque1}`` → ``apres eveque1``

asciify
  ``%asciify{text}``:  Translate non-ASCII characters to their ASCII
  equivalents. For example, “café” becomes “cafe”. Uses the mapping provided
  by the unidecode module.

  **Example:** ``%asciify{äÄöÖüÜ}`` → ``aeAeoeOeueUe``

delchars
  ``%delchars{text,chars}``:  Delete every single character of “chars“ in
  “text”.

  **Example:** ``%delchars{Schubert, ue}`` → ``Schbrt``

deldupchars
  ``%deldupchars{text,chars}``:  Search for duplicate characters and replace
  with only one occurrance of this characters.

  **Example:** ``%deldupchars{a---b___c...d}`` → ``a-b_c.d``; ``%deldupchars{a
  ---b___c, -}`` → ``a-b___c``

first
  ``%first{text}`` or ``%first{text,count,skip}`` or
  ``%first{text,count,skip,sep,join}``:  Returns the first item, separated by
  ``;``. You can use ``%first{text,count,skip}``, where count is the number of
  items (default 1) and skip is number to skip (default 0). You can also use
  ``%first{text,count,skip,sep,join}`` where ``sep`` is the separator, like
  ``;`` or ``/`` and join is the text to concatenate the items.

  **Example:** ``%first{Alice / Bob / Eve,2,0, / , & }`` → ``Alice & Bob``

if
  ``%if{condition,trueval}`` or ``%if{condition,trueval,falseval}``:  If
  condition is nonempty (or nonzero, if it’s a number), then returns the
  second argument. Otherwise, returns the third argument if specified (or
  nothing if ``falseval`` is left off).

  **Example:** ``x%if{false,foo}`` → ``x``

ifdef
  ``%ifdef{field}``, ``%ifdef{field,trueval}`` or
  ``%ifdef{field,trueval,falseval}``:  If field exists, then return
  ``trueval`` or field (default). Otherwise, returns ``falseval``. The field
  should be entered without ``$``.

  **Example:** ``%ifdef{compilation,Compilation}``

ifdefempty
  ``%ifdefempty{field,text}`` or ``%ifdefempty{field,text,falsetext}``:  If
  field exists and is empty, then return ``truetext``. Otherwise, returns
  ``falsetext``. The field should be entered without ``$``.

  **Example:** ``%ifdefempty{compilation,Album,Compilation}``

ifdefnotempty
  ``%ifdefnotempty{field,text}`` or ``%ifdefnotempty{field,text,falsetext}``:
  If field is not empty, then return ``truetext``. Otherwise, returns
  ``falsetext``. The field should be entered without ``$``.

  **Example:** ``%ifdefnotempty{compilation,Compilation,Album}``

initial
  ``%initial{text}``:  Get the first character of a text in lowercase. The
  text is converted to ASCII. All non word characters are erased.

  **Example:** ``%initial{Schubert}`` → ``s``

left
  ``%left{text,n}``:  Return the first “n” characters of “text”.

  **Example:** ``%left{Schubert, 3}`` → ``Sch``

lower
  ``%lower{text}``:  Convert “text” to lowercase.

  **Example:** ``%lower{SCHUBERT}`` → ``schubert``

nowhitespace
  ``%nowhitespace{text,replace}``:  Replace all whitespace characters with
  ``replace``. By default: a dash (``-``)

  **Example:** ``%nowhitespace{a b}`` → ``a-b``; ``%nowhitespace{a b, _}`` →
  ``a_b``

num
  ``%num{number,count}``:  Pad decimal number with leading zeros.

  **Example:** ``%num{7,3}`` → ``007``

replchars
  ``%replchars{text,chars,replace}``:  Replace the characters “chars” in
  “text” with “replace”.

  **Example:** ``%replchars{Schubert,-,ue}`` → ``Sch-b-rt``

right
  ``%right{text,n}``:  Return the last “n” characters of “text”.

  **Example:** ``%right{Schubert,3}`` → ``ert``

sanitize
  ``%sanitize{text}``:  Delete characters that are not allowed in most file
  systems.

  **Example:** ``%sanitize{x:*?<>|/~&x}`` → ``xx``

shorten
  ``%shorten{text}`` or ``%shorten{text,max_size}``:  Shorten “text” on word
  boundarys.

  **Example:** ``%shorten{Lorem ipsum dolor sit, 10}`` → ``Lorem``

time
  ``%time{date_time,format,curformat}``:  Return the date and time in any
  format accepted by ``strftime``. For example, to get the year, use
  ``%time{$added,%Y}``.

  **Example:** ``%time{30 Nov 2024,%Y,%d %b %Y}`` → ``2024``

title
  ``%title{text}``:  Convert “text” to Title Case.

  **Example:** ``%title{franz schubert}`` → ``Franz Schubert``

upper
  ``%upper{text}``:  Convert “text” to UPPERCASE.

  **Example:** ``%upper{foo}`` → ``FOO``

Plain text format (tmep-doc --functions-txt):

alpha
    -----

    ``%alpha{text}``
        This function first ASCIIfies the given text, then all non alphabet
        characters are replaced with whitespaces.
        ``%alpha{a1b23c}`` → ``a b c``

    alphanum
    --------

    ``%alphanum{text}``
        This function first ASCIIfies the given text, then all non alpanumeric
        characters are replaced with whitespaces.
        ``%alphanum{après-évêque1}`` → ``apres eveque1``

    asciify
    -------

    ``%asciify{text}``
        Translate non-ASCII characters to their ASCII equivalents. For
        example, “café” becomes “cafe”. Uses the mapping provided by the
        unidecode module.
        ``%asciify{äÄöÖüÜ}`` → ``aeAeoeOeueUe``

    delchars
    --------

    ``%delchars{text,chars}``
        Delete every single character of “chars“ in “text”.
        ``%delchars{Schubert, ue}`` → ``Schbrt``

    deldupchars
    -----------

    ``%deldupchars{text,chars}``
        Search for duplicate characters and replace with only one occurrance
        of this characters.
        ``%deldupchars{a---b___c...d}`` → ``a-b_c.d``; ``%deldupchars{a---
        b___c, -}`` → ``a-b___c``

    first
    -----

    ``%first{text}`` or ``%first{text,count,skip}`` or
    ``%first{text,count,skip,sep,join}``
        Returns the first item, separated by ``;``. You can use
        ``%first{text,count,skip}``, where count is the number of items
        (default 1) and skip is number to skip (default 0). You can also use
        ``%first{text,count,skip,sep,join}`` where ``sep`` is the separator,
        like ``;`` or ``/`` and join is the text to concatenate the items.
        ``%first{Alice / Bob / Eve,2,0, / , & }`` → ``Alice & Bob``

    if
    --

    ``%if{condition,trueval}`` or ``%if{condition,trueval,falseval}``
        If condition is nonempty (or nonzero, if it’s a number), then returns
        the second argument. Otherwise, returns the third argument if
        specified (or nothing if ``falseval`` is left off).
        ``x%if{false,foo}`` → ``x``

    ifdef
    -----

    ``%ifdef{field}``, ``%ifdef{field,trueval}`` or
    ``%ifdef{field,trueval,falseval}``
        If field exists, then return ``trueval`` or field (default).
        Otherwise, returns ``falseval``. The field should be entered without
        ``$``.
        ``%ifdef{compilation,Compilation}``

    ifdefempty
    ----------

    ``%ifdefempty{field,text}`` or ``%ifdefempty{field,text,falsetext}``
        If field exists and is empty, then return ``truetext``. Otherwise,
        returns ``falsetext``. The field should be entered without ``$``.
        ``%ifdefempty{compilation,Album,Compilation}``

    ifdefnotempty
    -------------

    ``%ifdefnotempty{field,text}`` or ``%ifdefnotempty{field,text,falsetext}``
        If field is not empty, then return ``truetext``. Otherwise, returns
        ``falsetext``. The field should be entered without ``$``.
        ``%ifdefnotempty{compilation,Compilation,Album}``

    initial
    -------

    ``%initial{text}``
        Get the first character of a text in lowercase. The text is converted
        to ASCII. All non word characters are erased.
        ``%initial{Schubert}`` → ``s``

    left
    ----

    ``%left{text,n}``
        Return the first “n” characters of “text”.
        ``%left{Schubert, 3}`` → ``Sch``

    lower
    -----

    ``%lower{text}``
        Convert “text” to lowercase.
        ``%lower{SCHUBERT}`` → ``schubert``

    nowhitespace
    ------------

    ``%nowhitespace{text,replace}``
        Replace all whitespace characters with ``replace``. By default: a dash
        (``-``)
        ``%nowhitespace{a b}`` → ``a-b``; ``%nowhitespace{a b, _}`` → ``a_b``

    num
    ---

    ``%num{number,count}``
        Pad decimal number with leading zeros.
        ``%num{7,3}`` → ``007``

    replchars
    ---------

    ``%replchars{text,chars,replace}``
        Replace the characters “chars” in “text” with “replace”.
        ``%replchars{Schubert,-,ue}`` → ``Sch-b-rt``

    right
    -----

    ``%right{text,n}``
        Return the last “n” characters of “text”.
        ``%right{Schubert,3}`` → ``ert``

    sanitize
    --------

    ``%sanitize{text}``
        Delete characters that are not allowed in most file systems.
        ``%sanitize{x:*?<>|/~&x}`` → ``xx``

    shorten
    -------

    ``%shorten{text}`` or ``%shorten{text,max_size}``
        Shorten “text” on word boundarys.
        ``%shorten{Lorem ipsum dolor sit, 10}`` → ``Lorem``

    time
    ----

    ``%time{date_time,format,curformat}``
        Return the date and time in any format accepted by ``strftime``. For
        example, to get the year, use ``%time{$added,%Y}``.
        ``%time{30 Nov 2024,%Y,%d %b %Y}`` → ``2024``

    title
    -----

    ``%title{text}``
        Convert “text” to Title Case.
        ``%title{franz schubert}`` → ``Franz Schubert``

    upper
    -----

    ``%upper{text}``
        Convert “text” to UPPERCASE.
        ``%upper{foo}`` → ``FOO``

Development

Test

poetry run tox

Publish a new version

git tag 1.1.1
git push --tags
poetry build
poetry publish

Package documentation

The package documentation is hosted on readthedocs.

Generate the package documentation:

python setup.py build_sphinx

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tmep-3.0.0.tar.gz (23.0 kB view details)

Uploaded Source

Built Distribution

tmep-3.0.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file tmep-3.0.0.tar.gz.

File metadata

  • Download URL: tmep-3.0.0.tar.gz
  • Upload date:
  • Size: 23.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.0 Linux/6.2.0-1019-azure

File hashes

Hashes for tmep-3.0.0.tar.gz
Algorithm Hash digest
SHA256 0c970c857d9bc35590215d3065ff3b29a0d36ca0e1ba9522a2ee0ab8a7b2854f
MD5 796613cf680825704b3595aee337b9a8
BLAKE2b-256 357ab8a6a8ded97727a13fb26be93a129fc081b8d452217a8249630c802be7c5

See more details on using hashes here.

File details

Details for the file tmep-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: tmep-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.0 Linux/6.2.0-1019-azure

File hashes

Hashes for tmep-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4084f49612cbfdc3e688c67c5c4dd8f7cbb467db852d4c248806eb096b56b600
MD5 986bb11cde96017c8bddb71c7aebc5b7
BLAKE2b-256 c154e0491e6ceaba31fd53127bfae71d9a228b15d0811130444f59dc55ed08b1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page