Browse files

Merge branch 'packaging' into develop

Conflicts:
	mint.py
  • Loading branch information...
2 parents 4460cf6 + 9dfd922 commit b64c05b96d5992ac1fac526e9318b01c1119426a @riffm committed Aug 1, 2011
Showing with 127 additions and 120 deletions.
  1. +1 −0 .gitignore
  2. +8 −0 AUTHORS
  3. +19 −0 LICENSE
  4. +22 −23 README.rst
  5. 0 { → ext}/mint.vim
  6. +28 −0 ext/pygments/README.rst
  7. +0 −49 pyg.py → ext/pygments/pygmint.py
  8. +8 −9 mint.py
  9. +7 −5 setup.py
  10. +34 −34 tests.py
View
1 .gitignore
@@ -6,3 +6,4 @@
build/
dist/
MANIFEST
+.coverage
View
8 AUTHORS
@@ -0,0 +1,8 @@
+Lead Developer:
+
+- Tim Perevezentsev <riffm2005@gmail.com>
+
+Contributor(s):
+
+- Alexander Solovyov <alexander@solovyov.net>
+- Eugene Van den Bulke <eugene.vandenbulke@gmail.com>
View
19 LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2011 see AUTHORS for more details.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
45 README.rst
@@ -40,7 +40,7 @@ about
**mint** - is small, fast and easy to use (x)html templates engine.
Implemented with python language.
-Why to use **mint**?:
+Why use **mint**?:
single python module
You can copy ``mint.py`` to your project package and use it.
@@ -50,35 +50,34 @@ minimalistic syntax
indent based syntax.
works fast
- **mint** uses ``ast`` python module from standard library
- (since python2.6, thank you Armin and co). So all templates compiles to optimized
- python byte code (during first call) which works fast.
+ **mint** uses ``ast`` python module from standard library
+ (since python2.6, thank you Armin and co). So all templates compiles to
+ optimized python byte code (during first call) which works fast.
smart
**mint** knows about (x)html tags and attributes,
- so you get smart escaping. (There is a plan to implement html
+ so you get smart escaping. (There is a plan to implement html
validation during rendering)
-not standing on your way
- **mint** does't hide exceptions like some other template engines, and shows line
- in your template file where exception was raised
+not standing in your way
+ **mint** does't hide exceptions like some other template engines, and
+ shows line in your template file where exception was raised
Template engine was inspired by haml (a template engine written in ruby),
but some concepts were redisigned for simplification and adoptation to python world.
-
.. _usage:
-----
usage
-----
-API is simple::
+Simple API::
>>> import mint
>>> loader = mint.Loader('./templates', cache=True)
>>> namespace = dict(a='a', b='b')
- >>> result = loder.get_template('index.mint').render(**namespace)
+ >>> result = loader.get_template('index.mint').render(**namespace)
``mint.Loader`` accepts names of directories and then search for template files
by name provided in ``get_template(name)`` call.
@@ -89,7 +88,7 @@ by name provided in ``get_template(name)`` call.
syntax
------
-**mint** syntax is based on indention, so you see document structure and
+**mint** syntax is based on indention, so you see the document structure and
update document fast. You can move blocks of code and do not search for
begining of parent tag and where it ends.
@@ -160,7 +159,7 @@ Note that **mint** knows about selfclosed html tags.
Why do not use python dictionary declaration syntax instead?
Something like ``{alt:"", src:"/img/my_picture.png"}``
-Because it is overloaded for html templating. "Chained-methods-call" like
+Because it is overloaded for html templating. "Chained-methods-call" like
syntax uses less chars to type.
**mint** alows to set/append value of tag attribute somewhere inside tag::
@@ -235,7 +234,7 @@ implements ``__html__`` method (this is something like convention). To insert
html inside templates you need to mark your python variables with
``mint.Markup`` inside your python code.
-In previous example if ``doc.body`` has html we need attribute ``body`` to return
+In previous example if ``doc.body`` has html we need attribute ``body`` to return
``mint.Markup(html_string)``. And that ``html_string`` will be inserted in template
without escaping. That is the preferred way to insert markup inside html template.
@@ -326,7 +325,7 @@ to get::
<!-- In this div we provide content, yours C.O. -->
<div id="content"></div>
-Sometimes you need to use special tokens in text, so if a line starts with
+Sometimes you need to use special tokens in text, so if a line starts with
token ``\`` line is not interpreted by **mint**::
@p.class(title) Here we have title
@@ -357,11 +356,11 @@ Remember rule #1: This records::
@div.id(1) @div.id(2) @div.id(3)
- @div.id(1)
+ @div.id(1)
@div.id(2) @div.id(3)
- @div.id(1)
- @div.id(2)
+ @div.id(1)
+ @div.id(2)
@div.id(3)
are the same.
@@ -421,8 +420,8 @@ slot implementation::
It is simple and powerful concept.
-Slots are python functions, so they see all global variables passed to template and have
-own scope. This is very handy, because sometimes people have problems with such things
+Slots are python functions, so they see all global variables passed to template and have
+own scope. This is very handy, because sometimes people have problems with such things
in other templates engines.
For example we need a block inside ``for`` loop::
@@ -492,7 +491,7 @@ example with ``for`` loop::
>>> loop_slot(item)
Markup(u'<p class="title">...</p><img alt="" src="..." />')
-But sometimes slots needs global variables, you must provide such variables
+But sometimes slots needs global variables, you must provide such variables
with kwargs in method ``slot(name, **globals)`` of ``Template`` object.
@@ -502,7 +501,7 @@ with kwargs in method ``slot(name, **globals)`` of ``Template`` object.
utils
-----
-**mint** provides global variable ``utils`` which contains useful constants and helper
+**mint** provides global variable ``utils`` which contains useful constants and helper
functions.
Doctype declarations
@@ -519,7 +518,7 @@ Example of usage::
Class ``mint.Markup`` is ``utils.markup`` (this is replacement for hack ``{{ var|safe }}``)
-``utils.loop`` is helper function to use with ``for`` statement. It takes iterable
+``utils.loop`` is helper function to use with ``for`` statement. It takes iterable
object and returns tuple of item and special object that consist of useful info for each
iteration::
View
0 mint.vim → ext/mint.vim
File renamed without changes.
View
28 ext/pygments/README.rst
@@ -0,0 +1,28 @@
+=====================
+Mint - Pygments lexer
+=====================
+
+Mint ships with a Pygments_ lexer available in **ext/pygments**.
+
+We haven't included it in the package to avoid requiring Pygments_.
+
+In order to use it you will have to make sure that **pygmint.py**
+is in your `sys.path`.
+
+Instantiate the MintLexer when calling highlight as you would with other
+schemes::
+
+ from pygmint import MintLexer
+ from pygments import highlight
+ from pygments.formatters import HtmlFormatter
+
+ code = """
+ {{ utils.doctype.html5 }}
+ @html
+ @head
+ @body
+ @div.class(content)"""
+
+ print highlight(code, MintLexer(), HtmlFormatter())
+
+.. _pygments: http://www.pygments.org
View
49 pyg.py → ext/pygments/pygmint.py
@@ -1,7 +1,5 @@
-from pygments import highlight
from pygments.lexer import RegexLexer, bygroups, using, include
from pygments.lexers import PythonLexer
-from pygments.formatters import HtmlFormatter
from pygments.token import *
class MintLexer(RegexLexer):
@@ -37,50 +35,3 @@ class MintLexer(RegexLexer):
(r'.+\)', using(PythonLexer), '#pop'),
],
}
-
-
-code = '''
-@html
- @head
- @title {{ title }}
- @body
-
- @ul
- #for img in images:
- @li @img.alt().src({{ img }})
-
- @table
- @tr.class(2 attr value ).id( 43)
- @td {{ item }}
- -- comment string
- @td -- comment
- text text {{ range(2) }}
- @.class(name)
- @+class(name)
- text text
-
- #def content(arg, arg1='value'):
- @p {{ arg }} text {{ arg1 }}
- @p
- {{ arg }} text {{ arg1 }}
- @div.id(1) @div.id(2) @div.id(3)
- \@div.id(1) @div.id(2) @div.id(3)
-
- #content(1)
-'''
-
-template = '''
-<html>
- <head>
- <style>
- %s
- </style>
- </head>
- <body>
- %s
- </body>
-</html>
-'''
-
-print template % (HtmlFormatter().get_style_defs('.highlight'),
- highlight(code, MintLexer(), HtmlFormatter()) )
View
17 mint.py
@@ -2,24 +2,23 @@
'''
mint - small, fast and simple template engine.
-Inspired by haml.
'''
-import weakref
-import logging
-import mmap
+import os
import re
import ast
-import htmlentitydefs
-import itertools
-import os
-import fnmatch
+import mmap
import time
+import fnmatch
+import logging
+import weakref
+import itertools
+import htmlentitydefs
from ast import Load, Store, Param
from StringIO import StringIO
+from functools import partial
from collections import deque
from xml.etree.ElementTree import TreeBuilder as _TreeBuilder, Element
-from functools import partial
############# LEXER
View
12 setup.py
@@ -1,13 +1,15 @@
-#!/usr/bin/env python
-
from distutils.core import setup
+version = '0.5'
+
setup(
name='mint',
- version='0.4',
+ version=version,
description='Simple indetion based template engine',
+ long_description=open('README.rst').read(),
+ py_modules=['mint'],
+ license='MIT',
author='Tim Perevezentsev',
author_email='riffm2005@gmail.com',
- py_modules=['mint'],
- url='http://github.com/riffm/mint',
+ url='http://github.com/riffm/mint'
)
View
68 tests.py
@@ -3,10 +3,10 @@
import os
import glob
import unittest
-import mint
import types
from StringIO import StringIO
+import mint
class TagsAndText(unittest.TestCase):
@@ -40,12 +40,12 @@ def test_nested_tags2(self):
'Nested tags more levels'
self.assertEqual(mint.Template('@tag\n'
' @tag2\n'
- ' @tag3').render(),
+ ' @tag3').render(),
'<tag><tag2><tag3></tag3></tag2></tag>')
def test_nested_tags3(self):
'Nested tags shortcuts'
- self.assertEqual(mint.Template('@tag @tag2 @tag3').render(),
+ self.assertEqual(mint.Template('@tag @tag2 @tag3').render(),
'<tag><tag2><tag3></tag3></tag2></tag>')
def test_nested_tags4(self):
@@ -58,12 +58,12 @@ def test_nested_tags4(self):
def test_text_content(self):
'Tag with text content'
self.assertEqual(mint.Template('@tag\n'
- ' text content').render(),
+ ' text content').render(),
'<tag>text content\n</tag>')
def test_text_content2(self):
'Tag with text content shortcut'
- self.assertEqual(mint.Template('@tag text content').render(),
+ self.assertEqual(mint.Template('@tag text content').render(),
'<tag>text content\n</tag>')
def test_text_content3(self):
@@ -163,19 +163,19 @@ def test_backspace_escaping(self):
def test_escaping(self):
'Text value escaping'
- self.assertEqual(mint.Template('text < > \' " &').render(),
+ self.assertEqual(mint.Template('text < > \' " &').render(),
'text &lt; &gt; &#39; &quot; &amp;\n')
def test_escaping2(self):
'Tag attr value escaping'
- self.assertEqual(mint.Template('@tag.attr(text < > \' " &)').render(),
+ self.assertEqual(mint.Template('@tag.attr(text < > \' " &)').render(),
'<tag attr="text &lt; &gt; &#39; &quot; &amp;"></tag>')
def test_escaping3(self):
'Markup object value'
self.assertEqual(mint.Template('@tag\n'
' text <tag attr="&" />\n'
- ' {{ value }}').render(value=mint.Markup('<tag attr="&amp;" />')),
+ ' {{ value }}').render(value=mint.Markup('<tag attr="&amp;" />')),
'<tag>text &lt;tag attr=&quot;&amp;&quot; /&gt;\n<tag attr="&amp;" />\n</tag>')
def test_escaping4(self):
@@ -206,12 +206,12 @@ class Tokenizer(unittest.TestCase):
def test_tokens(self):
'Empty string'
- self.assertEqual(list(mint.tokenizer(StringIO())),
+ self.assertEqual(list(mint.tokenizer(StringIO())),
[(mint.TOKEN_EOF, 'EOF', 1, 0)])
def test_tokens2(self):
'Simple tokens'
- self.assertEqual(list(mint.tokenizer(StringIO('@@.@+()[]:;.,-+{{}}'))),
+ self.assertEqual(list(mint.tokenizer(StringIO('@@.@+()[]:;.,-+{{}}'))),
[(mint.TOKEN_TAG_START, '@', 1, 1),
(mint.TOKEN_TAG_ATTR_SET, '@.', 1, 2),
(mint.TOKEN_TAG_ATTR_APPEND, '@+', 1, 4),
@@ -231,7 +231,7 @@ def test_tokens2(self):
def test_tokens3(self):
'Special tokens'
- self.assertEqual(list(mint.tokenizer(StringIO('#base: #if #elif #else:#def #for #'))),
+ self.assertEqual(list(mint.tokenizer(StringIO('#base: #if #elif #else:#def #for #'))),
[(mint.TOKEN_BASE_TEMPLATE, '#base: ', 1, 1),
(mint.TOKEN_STATEMENT_IF, '#if ', 1, 8),
(mint.TOKEN_STATEMENT_ELIF, '#elif ', 1, 12),
@@ -244,7 +244,7 @@ def test_tokens3(self):
def test_tokens4(self):
'Two tokens in a row'
- self.assertEqual(list(mint.tokenizer(StringIO('{{{{#if #if '))),
+ self.assertEqual(list(mint.tokenizer(StringIO('{{{{#if #if '))),
[(mint.TOKEN_EXPRESSION_START, '{{', 1, 1),
(mint.TOKEN_EXPRESSION_START, '{{', 1, 3),
(mint.TOKEN_STATEMENT_IF, '#if ', 1, 5),
@@ -254,7 +254,7 @@ def test_tokens4(self):
def test_tokens5(self):
'Special tokens (js)'
- self.assertEqual(list(mint.tokenizer(StringIO('#function #else if '))),
+ self.assertEqual(list(mint.tokenizer(StringIO('#function #else if '))),
[(mint.TOKEN_SLOT_DEF, '#function ', 1, 1),
(mint.TOKEN_STATEMENT_ELIF, '#else if ', 1, 11),
(mint.TOKEN_NEWLINE, '\n', 1, 20),
@@ -290,7 +290,7 @@ def test_indent3(self):
'Indent tokens'
self.assertEqual(list(mint.tokenizer(StringIO(' \n'
' \n'
- ' '))),
+ ' '))),
[(mint.TOKEN_INDENT, ' ', 1, 1),
(mint.TOKEN_NEWLINE, '\n', 1, 5),
(mint.TOKEN_INDENT, ' ', 2, 5),
@@ -303,7 +303,7 @@ def test_indent3(self):
def test_indent4(self):
'Mixed indent'
self.assertEqual(list(mint.tokenizer(StringIO(' \n'
- ' '))),
+ ' '))),
[(mint.TOKEN_INDENT, ' ', 1, 1),
(mint.TOKEN_NEWLINE, '\n', 1, 4),
(mint.TOKEN_INDENT, ' ', 2, 4),
@@ -316,7 +316,7 @@ def test_indent4(self):
def test_indent5(self):
'More mixed indent'
self.assertEqual(list(mint.tokenizer(StringIO(' \n'
- ' '))),
+ ' '))),
[(mint.TOKEN_INDENT, ' ', 1, 1),
(mint.TOKEN_NEWLINE, '\n', 1, 5),
(mint.TOKEN_UNINDENT, ' ', 1, 5),
@@ -329,7 +329,7 @@ def test_indent6(self):
self.assertEqual(list(mint.tokenizer(StringIO('\n'
' \n'
' \n'
- ' '))),
+ ' '))),
[(mint.TOKEN_NEWLINE, '\n', 1, 1),
(mint.TOKEN_INDENT, ' ', 2, 1),
(mint.TOKEN_NEWLINE, '\n', 2, 5),
@@ -345,7 +345,7 @@ def test_indent7(self):
self.assertEqual(list(mint.tokenizer(StringIO('\n'
' \n'
' \n'
- ' '))),
+ ' '))),
[(mint.TOKEN_NEWLINE, '\n', 1, 1),
(mint.TOKEN_INDENT, ' ', 2, 1),
(mint.TOKEN_NEWLINE, '\n', 2, 5),
@@ -409,12 +409,12 @@ def test_tag_node2(self):
tree = self.get_mint_tree('@tag.attr(value)')
self.assertEqual(tree,
mint.MintTemplate(body=[
- mint.TagNode('tag',
- attrs=[mint.TagAttrNode('attr',
- value=[mint.TextNode('value',
- lineno=1,
+ mint.TagNode('tag',
+ attrs=[mint.TagAttrNode('attr',
+ value=[mint.TextNode('value',
+ lineno=1,
col_offset=11)],
- lineno=1, col_offset=6)],
+ lineno=1, col_offset=6)],
lineno=1, col_offset=1)]))
def test_tag_node3(self):
@@ -423,10 +423,10 @@ def test_tag_node3(self):
' text value')
self.assertEqual(tree,
mint.MintTemplate(body=[
- mint.TagNode('tag',
- attrs=[mint.TagAttrNode('attr',
- value=[mint.TextNode('value',
- lineno=1,
+ mint.TagNode('tag',
+ attrs=[mint.TagAttrNode('attr',
+ value=[mint.TextNode('value',
+ lineno=1,
col_offset=11)],
lineno=1, col_offset=6)],
body=[mint.TextNode('text value\n', lineno=2, col_offset=5)],
@@ -459,7 +459,7 @@ def test_tag_node6(self):
self.assertEqual(tree,
mint.MintTemplate(body=[
mint.TagNode('tag', attrs=[],
- body=[mint.TagNode('tag2', attrs=[],
+ body=[mint.TagNode('tag2', attrs=[],
body=[mint.TextNode('text value\n',
lineno=1, col_offset=12)],
lineno=1, col_offset=6)],
@@ -470,12 +470,12 @@ def test_tag_attr(self):
tree = self.get_mint_tree('@tag.attr({{ expression }})')
self.assertEqual(tree,
mint.MintTemplate(body=[
- mint.TagNode('tag',
- attrs=[mint.TagAttrNode('attr',
- value=[mint.ExpressionNode('expression',
- lineno=1,
+ mint.TagNode('tag',
+ attrs=[mint.TagAttrNode('attr',
+ value=[mint.ExpressionNode('expression',
+ lineno=1,
col_offset=11)],
- lineno=1, col_offset=6)],
+ lineno=1, col_offset=6)],
lineno=1, col_offset=1)]))
def test_if_node(self):
@@ -506,7 +506,7 @@ def test_if_node3(self):
mint.IfStmtNode('#if statement',
body=[mint.TextNode('text value\n', lineno=2, col_offset=5)],
orelse=[mint.ElseStmtNode(body=[
- mint.TextNode('another text value\n',
+ mint.TextNode('another text value\n',
lineno=4, col_offset=5)],
lineno=3, col_offset=1)],
lineno=1, col_offset=1)]))

0 comments on commit b64c05b

Please sign in to comment.