Skip to main content

A simple annotation-based language to generate code from templates

Project description

templang

A simple annotation-based language to generate code from templates

Templates

Templates are just source files with annotations. For example:

# BEGIN
from typing import Literal

Rank = Literal[
  # LOOP RANK
  'RANK',
  # END
]

CLEARANCE_LEVEL = int # DELETE (just to make mypy happy)
# LOOP RANK CLEARANCE_LEVEL
class RANK:
  clearance_level: CLEARANCE_LEVEL

# END
# END

Template Parsing

from templang import parse
with open('ranks.py') as f:
  source = f.read()

code = parse(source, translations={
  'RANK': ['Captain', 'Lieutenant', 'Sergeant'],
  'CLEARANCE_LEVEL': ['1', '2', '3']
})

print(code)

# from typing import Literal
# 
# Rank = Literal[
#   'Captain',
#   'Lieutenant',
#   'Sergeant',
# ]
# 
# class Captain:
#   clearance_level: 1
# 
# class Lieutenant:
#   clearance_level: 2
# 
# class Sergeant:
#   clearance_level: 3

Rules

Now, that's most of what you need to now. But, to be precise, here are the rules:

  • # BEGIN and # END delimit a template

  • Lines starting with # UNCOMMENT are stripped to whatever proceeds the annotation

  • Lines ending with # DELETE are removed

  • translations: Mapping[str, str | Sequence[str]] is the dictionary of translations:

    • If value = translations[key] is a string, all instances of key are replaced by value
    • If value = translations[key] is a sequence of strings, key will be allowed in a # LOOP declaration
    • The order of translations is not guaranteed. So, keys substrings of other keys will probably yield inentended results
  • # LOOP VAR1 ... VARN and # END delimit a loop:

    • translations[VARi] must be a sequence of strings
    • LEN = len(translations[VAR1]) == ... == len(translations[VARN])
    • The template inside the loop is substituted with translations[VARi][j] for each j in range(LEN)
    • Nested loops are allowed
    • If nested loops involve a same variable VAR multiple times, then translations[VAR] must be a nested sequence of strings (matching the loop depth)
      • E.g:

        # BEGIN
        from typing import Union, Literal
        
        Marriage = Union[
        # LOOP NAMES
          tuple [
          # LOOP NAMES
            Literal['NAMES'],
          # END
          ],
        # END
        ]
        # END
        
        
        parse(open(__file__).read(), {
          'NAMES': [['John', 'Jane'], ['Stuart', 'Alice']]
        })
        
        # from typing import Union, Literal
        #
        # Marriage = Union[
        #   tuple [
        #     Literal['John'],
        #     Literal['Jane'],
        #   ],
        #   tuple [
        #     Literal['Stuart'],
        #     Literal['Alice'],
        #   ],
        # ]
        
  • Oh, and actually, # can be replaced by any custom string (e.g. //)

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

templang-0.1.1.tar.gz (3.4 kB view hashes)

Uploaded Source

Built Distribution

templang-0.1.1-py3-none-any.whl (3.8 kB view hashes)

Uploaded Python 3

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