Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pystache_custom
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
pystache_custom
Commits
11b156c2
Commit
11b156c2
authored
Feb 07, 2011
by
Pieter van de Bruggen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Beginning a rework of the parser.
parent
c19e58c8
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
50 additions
and
124 deletions
+50
-124
pystache/template.py
+50
-124
No files found.
pystache/template.py
View file @
11b156c2
import
re
import
re
import
cgi
import
collections
import
os
import
copy
modifiers
=
{}
def
modifier
(
symbol
):
"""Decorator for associating a function with a Mustache tag modifier.
@modifier('P')
def render_tongue(self, tag_name=None, context=None):
return ":P
%
s"
%
tag_name
{{P yo }} => :P yo
"""
def
set_modifier
(
func
):
modifiers
[
symbol
]
=
func
return
func
return
set_modifier
class
Template
(
object
):
class
Template
(
object
):
tag_re
=
None
tag_re
=
None
otag
,
ctag
=
'{{'
,
'}}'
otag
=
'{{'
def
__init__
(
self
,
template
=
None
,
context
=
{},
**
kwargs
):
ctag
=
'}}'
def
__init__
(
self
,
template
=
None
,
context
=
None
,
**
kwargs
):
from
view
import
View
from
view
import
View
self
.
template
=
template
self
.
template
=
template
...
@@ -39,116 +16,65 @@ class Template(object):
...
@@ -39,116 +16,65 @@ class Template(object):
self
.
_compile_regexps
()
self
.
_compile_regexps
()
def
_compile_regexps
(
self
):
def
_compile_regexps
(
self
):
tags
=
{
tags
=
{
'otag'
:
re
.
escape
(
self
.
otag
),
'ctag'
:
re
.
escape
(
self
.
ctag
)}
'otag'
:
re
.
escape
(
self
.
otag
),
tag
=
r"""
'ctag'
:
re
.
escape
(
self
.
ctag
)
(?P<content>[\s\S]*?)
}
(?P<whitespace>[\ \t]*)
%(otag)
s \s*
(?:
(?P<change>=) \s* (?P<delims>.+?) \s* = |
(?P<raw>{) \s* (?P<raw_name>.+?) \s* } |
(?P<tag>\W?) \s* (?P<name>[\s\S]+?)
)
\s*
%(ctag)
s
"""
self
.
tag_re
=
re
.
compile
(
tag
%
tags
,
re
.
M
|
re
.
X
)
section
=
r"
%(otag)
s[\#|^]([^\}]*)
%(ctag)
s\s*(.+?\s*)
%(otag)
s/\1
%(ctag)
s"
def
_parse
(
self
,
template
,
section
=
None
,
index
=
0
):
self
.
section_re
=
re
.
compile
(
section
%
tags
,
re
.
M
|
re
.
S
)
"""Parse a template into a syntax tree."""
tag
=
r"
%(otag)
s(#|=|&|!|>|\{)?(.+?)\1?
%(ctag)
s+"
buffer
=
[]
self
.
tag_re
=
re
.
compile
(
tag
%
tags
)
pos
=
index
def
_render_sections
(
self
,
template
,
view
):
while
True
:
while
True
:
match
=
self
.
section_re
.
search
(
template
)
match
=
self
.
tag_re
.
search
(
template
,
pos
)
if
match
is
None
:
break
section
,
section_name
,
inner
=
match
.
group
(
0
,
1
,
2
)
section_name
=
section_name
.
strip
()
it
=
self
.
view
.
get
(
section_name
,
None
)
replacer
=
''
# Callable
if
it
and
isinstance
(
it
,
collections
.
Callable
):
replacer
=
it
(
inner
)
# Dictionary
elif
it
and
hasattr
(
it
,
'keys'
)
and
hasattr
(
it
,
'__getitem__'
):
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
# Lists
elif
it
and
hasattr
(
it
,
'__iter__'
):
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_list
(
inner
,
it
)
# Other objects
elif
it
and
isinstance
(
it
,
object
):
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
# Falsey and Negated or Truthy and Not Negated
elif
(
not
it
and
section
[
2
]
==
'^'
)
or
(
it
and
section
[
2
]
!=
'^'
):
replacer
=
inner
template
=
template
.
replace
(
section
,
replacer
)
return
template
def
_render_tags
(
self
,
template
):
while
True
:
match
=
self
.
tag_re
.
search
(
template
)
if
match
is
None
:
if
match
is
None
:
break
break
tag
,
tag_type
,
tag_name
=
match
.
group
(
0
,
1
,
2
)
# Normalize the captures dictionary.
tag_name
=
tag_name
.
strip
()
captures
=
match
.
groupdict
()
func
=
modifiers
[
tag_type
]
if
captures
[
'change'
]
is
not
None
:
replacement
=
func
(
self
,
tag_name
)
captures
.
update
(
tag
=
'='
,
name
=
captures
[
'delims'
])
template
=
template
.
replace
(
tag
,
replacement
)
elif
captures
[
'raw'
]
is
not
None
:
captures
.
update
(
tag
=
'{'
,
name
=
captures
[
'raw_name'
])
return
template
# Save the literal text content.
def
_render_dictionary
(
self
,
template
,
context
):
buffer
.
append
(
captures
[
'content'
])
self
.
view
.
context_list
.
insert
(
0
,
context
)
pos
=
match
.
end
()
template
=
Template
(
template
,
self
.
view
)
out
=
template
.
render
()
# Save the whitespace following the text content.
self
.
view
.
context_list
.
pop
(
0
)
# TODO: Standalone tags should consume this.
return
out
buffer
.
append
(
captures
[
'whitespace'
])
def
_render_list
(
self
,
template
,
listing
):
# TODO: Process the remaining tag types.
insides
=
[]
if
captures
[
'tag'
]
is
'!'
:
for
item
in
listing
:
pass
insides
.
append
(
self
.
_render_dictionary
(
template
,
item
))
# Save the rest of the template.
return
''
.
join
(
insides
)
buffer
.
append
(
template
[
pos
:])
@modifier
(
None
)
return
buffer
def
_render_tag
(
self
,
tag_name
):
raw
=
self
.
view
.
get
(
tag_name
,
''
)
def
_generate
(
self
,
parsed
,
view
):
"""Convert a parse tree into a fully evaluated template."""
# For methods with no return value
if
not
raw
and
raw
is
not
0
:
return
''
return
cgi
.
escape
(
unicode
(
raw
))
@modifier
(
'!'
)
def
_render_comment
(
self
,
tag_name
):
return
''
@modifier
(
'>'
)
def
_render_partial
(
self
,
template_name
):
from
pystache
import
Loader
markup
=
Loader
()
.
load_template
(
template_name
,
self
.
view
.
template_path
,
encoding
=
self
.
view
.
template_encoding
)
template
=
Template
(
markup
,
self
.
view
)
return
template
.
render
()
@modifier
(
'='
)
def
_change_delimiter
(
self
,
tag_name
):
"""Changes the Mustache delimiter."""
self
.
otag
,
self
.
ctag
=
tag_name
.
split
(
' '
)
self
.
_compile_regexps
()
return
''
@modifier
(
'{'
)
# TODO: Handle non-trivial cases.
@modifier
(
'&'
)
return
''
.
join
(
parsed
)
def
render_unescaped
(
self
,
tag_name
):
"""Render a tag without escaping it."""
return
unicode
(
self
.
view
.
get
(
tag_name
,
''
))
def
render
(
self
,
encoding
=
None
):
def
render
(
self
,
encoding
=
None
):
template
=
self
.
_render_sections
(
self
.
template
,
self
.
view
)
parsed
=
self
.
_parse
(
self
.
template
)
result
=
self
.
_
render_tags
(
template
)
result
=
self
.
_
generate
(
parsed
,
self
.
view
)
if
encoding
is
not
None
:
if
encoding
is
not
None
:
result
=
result
.
encode
(
encoding
)
result
=
result
.
encode
(
encoding
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment