t=Template('''These characters get replaced: _variable, _function
This line is then formatted: {0} ZIP _variable , _function
And this one is iterated: {0} ZIP _iter , _function''')
t.fill(_variable=2,_function="lambda i:i*10",_iter=range(2))
t
What happened? When calling t.fill, _variable was replaced with 2 everywhere it appeared in the template, similarly with _function. This includes after the custom function ZIP, where they appear as arguments.
After this substitution, ZIP formatted the text preceding it ({0}) with the result of _function(_variable), i.e, format("{0}",(lambda i:i*10)(2)).
In the next line, ZIP repeatedly formatted the text preceding it ({0}) with the result of _function(_iter), i.e, '\n'.join([format("{0}",(lambda i:i*10)(j)) for j in range(2)]).
Before we go into more detail on these functions, let's examine the template object:
t.__dict__
The temp attribute stores the un-formatted text handed to Template. The plate attribute stores the formatted lines as a list of strings. The object also stores any kwargs as attrs. Finally, text() attribute concatenates the formatted text into a string separated by newlines, and is used as the __repr__.
Let's see how ZIP works:
ZIP('{0}',range(10),lambda i:i)
When embedded in the Template, ZIP treats the text proceeding it as an iterable or a single-substitution, and any text after the , as a list of functions. These functions take the iterable as an argument, and format the text preceding ZIP with their evaluation on the iterable. They do not need to be lambdas - any callable will do. This makes embedding ZIP into other text documents a useful way to modularize the formatting of text, and automate code blocks in other languages which lack Python flexibility.
Other helper functions enabling this process are as follows:
replace('''result={0}; ZIP _myvar,lambda i:i*10''',_myvar=2)
txt=txt2lst('''var=_myvar
result={0}; ZIP _myvar,lambda i:i*10
''')
txt
for i,l in enumerate(txt):
txt[i]=replace(l,_myvar=2)
getEvals(txt,funcs=['ZIP'])
These are then packaged into the Template class, which we give another arbitrary example of here:
t=Template('''Filling out _stuff
which {0}{1} is ZIP 1, lambda t:'iterates ' , _arbitrarily
{0} ZIP range(3), lambda t: "much"
easier
since we can embed any keyword, iterable, and function anywhere.
''',_stuff='stuff',_arbitrarily="lambda t: 'arbitrarily'")
t
t.fill('we can append, _too',_too='too!',append=True)
t
Finally, a Template will attempt to auto-load a file if the input is a filename, e.g Template('template.txt') will load the file template.txt if it exists in the current directory, and use that as the string to format.