Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.
/ tagged Public archive

JavaScript-style tagged templates for Python 3

License

Notifications You must be signed in to change notification settings

jviide/tagged

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tagged CircleCI PyPI

A Python version of JavaScript's tagged templates, mixed with Python 3's f-strings.

For a more involved example how this package can be used in practice, see htm.py that implements JSX-like syntax in plain Python.

Installation

$ pip3 install tagged

Usage

This package defines tag, a decorator for creating new tags. Let's define a simple one:

from tagged import tag

@tag
def t(strings, values):
    return strings, values

Now t can be called with a template string that can contain any Python 3 expression between { and }. The "static" parts of the string are listed in strings and the evaluated expressions are listed in values.

strings, values = t("1 + {2} equals {1 + 2}")
# strings == ('1 + ', ' equals ', '')
# values == (2, 3)

Because the expressions are evaluated in the current context they can refer to local variables:

a = [1, 2, 3]
strings, values = t("the sum of {a} is {sum(a)}")
# strings == ('the sum of ', ' is ', '')
# values == ([1, 2, 3], 6)

Double curly brackets are interpreted as a single textual curly bracket:

strings, values = t("Inline a set between {{ and }} like this: {({1, 2, 3})}")
# strings == ('Inline a set between { and } like this: ', '')
# values == ({1, 2, 3},)

rexample

Let's define a custom tag rex that allows composing regular expressions from strings and other regular expressions.

import re
from tagged import tag


@tag
def rex(strings, values):
    pattern = strings[0]
    for value, string in zip(values, strings[1:]):
        if isinstance(value, re.Pattern):
            value = value.pattern
        elif isinstance(value, str):
            value = re.escape(value)
        else:
            raise TypeError("expected re.Pattern or str")
        pattern += "(?:" + value + ")" + string
    return re.compile(pattern)
    

greeting = re.compile("Hello|Hi|Greetings")
name = "Python 3.7"

rex("{greeting}, {name}!")
# re.compile('(?:Hello|Hi|Greetings), (?:Python\\ 3\\.7)!')

Development

Running Tests

$ python3 -m unittest discover -s tests

License

This library is licensed under the MIT license. See ./LICENSE.

About

JavaScript-style tagged templates for Python 3

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages