Template engine for file paths. Expand variables like ``$title`` and apply functions like ``%upper{}``.
Project description
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.