http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/examples/rwbench/mako/index.html ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/examples/rwbench/mako/index.html b/ambari-common/src/main/python/jinja2/examples/rwbench/mako/index.html new file mode 100644 index 0000000..c4c6303 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/examples/rwbench/mako/index.html @@ -0,0 +1,31 @@ +<%! + from rwbench import dateformat +%> +<%inherit file="layout.html" /> +<%namespace file="helpers.html" import="input_field, textarea, form" /> +<%def name="page_title()">Index Page</%def> +% for article in articles: + <% if not article.published: continue %> +<div class="article"> + <h2><a href="${article.href|h}">${article.title|h}</a></h2> + <p class="meta">written by <a href="${article.user.href|h + }">${article.user.username|h}</a> on ${dateformat(article.pub_date)}</p> + <div class="text">${article.body}</div> +</div> +% endfor +<%call expr="form()"> + <dl> + <dt>Name</dt> + <dd>${input_field('name')}</dd> + <dt>E-Mail</dt> + <dd>${input_field('email')}</dd> + <dt>URL</dt> + <dd>${input_field('url')}</dd> + <dt>Comment</dt> + <dd>${textarea('comment')}</dd> + <dt>Captcha</dt> + <dd>${input_field('captcha')}</dd> + </dl> + ${input_field(type='submit', value='Submit')} + ${input_field(name='cancel', type='submit', value='Cancel')} +</%call>
http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/examples/rwbench/mako/layout.html ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/examples/rwbench/mako/layout.html b/ambari-common/src/main/python/jinja2/examples/rwbench/mako/layout.html new file mode 100644 index 0000000..a9c353e --- /dev/null +++ b/ambari-common/src/main/python/jinja2/examples/rwbench/mako/layout.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> + <title>${self.page_title()} | RealWorld Benchmark</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +</head> +<body> + <div class="contents"> + <div class="header"> + <h1>RealWorld Benchmark</h1> + <blockquote><p> + A less stupid benchmark for Mako and Jinja2 to get an impression how + code changes affect runtime performance. + </p></blockquote> + </div> + <ul class="navigation"> + % for href, caption in page_navigation: + <li><a href="${href|h}">${caption}</a></li> + % endfor + </ul> + <div class="body"> + ${self.body()} + </div> + <div class="footer"> + © Copyright 2008 by I don't know who. + </div> + </div> +</body> +</html> +<%def name="page_title()"></%def> http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/examples/rwbench/rwbench.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/examples/rwbench/rwbench.py b/ambari-common/src/main/python/jinja2/examples/rwbench/rwbench.py new file mode 100644 index 0000000..813dd56 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/examples/rwbench/rwbench.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +""" + RealWorldish Benchmark + ~~~~~~~~~~~~~~~~~~~~~~ + + A more real-world benchmark of Jinja2. Like the other benchmark in the + Jinja2 repository this has no real-world usefulnes (despite the name). + Just go away and ignore it. NOW! + + :copyright: (c) 2009 by the Jinja Team. + :license: BSD. +""" +import sys +from os.path import join, dirname, abspath +try: + from cProfile import Profile +except ImportError: + from profile import Profile +from pstats import Stats +ROOT = abspath(dirname(__file__)) + +from random import choice, randrange +from datetime import datetime +from timeit import Timer +from jinja2 import Environment, FileSystemLoader +from jinja2.utils import generate_lorem_ipsum +from mako.lookup import TemplateLookup +from genshi.template import TemplateLoader as GenshiTemplateLoader + + +def dateformat(x): + return x.strftime('%Y-%m-%d') + + +jinja_env = Environment(loader=FileSystemLoader(join(ROOT, 'jinja'))) +jinja_env.filters['dateformat'] = dateformat +mako_lookup = TemplateLookup(directories=[join(ROOT, 'mako')]) +genshi_loader = GenshiTemplateLoader([join(ROOT, 'genshi')]) + +class Article(object): + + def __init__(self, id): + self.id = id + self.href = '/article/%d' % self.id + self.title = generate_lorem_ipsum(1, False, 5, 10) + self.user = choice(users) + self.body = generate_lorem_ipsum() + self.pub_date = datetime.utcfromtimestamp(randrange(10 ** 9, 2 * 10 ** 9)) + self.published = True + + +class User(object): + + def __init__(self, username): + self.href = '/user/%s' % username + self.username = username + + +users = map(User, [u'John Doe', u'Jane Doe', u'Peter Somewhat']) +articles = map(Article, range(20)) +navigation = [ + ('index', 'Index'), + ('about', 'About'), + ('foo?bar=1', 'Foo with Bar'), + ('foo?bar=2&s=x', 'Foo with X'), + ('blah', 'Blub Blah'), + ('hehe', 'Haha'), +] * 5 + +context = dict(users=users, articles=articles, page_navigation=navigation) + + +jinja_template = jinja_env.get_template('index.html') +mako_template = mako_lookup.get_template('index.html') +genshi_template = genshi_loader.load('index.html') + + +def test_jinja(): + jinja_template.render(context) + +def test_mako(): + mako_template.render_unicode(**context) + + +from djangoext import django_loader, DjangoContext +def test_django(): + # not cached because django is not thread safe and does + # not cache by itself so it would be unfair to cache it here. + django_template = django_loader.get_template('index.html') + django_template.render(DjangoContext(context)) + + +def test_genshi(): + genshi_template.generate(**context).render('html', doctype='html') + + +if __name__ == '__main__': + sys.stdout.write('Realworldish Benchmark:\n') + for test in 'jinja', 'mako', 'django', 'genshi': + t = Timer(setup='from __main__ import test_%s as bench' % test, + stmt='bench()') + sys.stdout.write(' >> %-20s<running>' % test) + sys.stdout.flush() + sys.stdout.write('\r %-20s%.4f seconds\n' % (test, t.timeit(number=200) / 200)) + + if '-p' in sys.argv: + print 'Jinja profile' + p = Profile() + p.runcall(test_jinja) + stats = Stats(p) + stats.sort_stats('time', 'calls') + stats.print_stats() http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/Vim/htmljinja.vim ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/Vim/htmljinja.vim b/ambari-common/src/main/python/jinja2/ext/Vim/htmljinja.vim new file mode 100644 index 0000000..3f9cba4 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/Vim/htmljinja.vim @@ -0,0 +1,27 @@ +" Vim syntax file +" Language: Jinja HTML template +" Maintainer: Armin Ronacher <armin.ronac...@active-4.com> +" Last Change: 2007 Apr 8 + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +if !exists("main_syntax") + let main_syntax = 'html' +endif + +if version < 600 + so <sfile>:p:h/jinja.vim + so <sfile>:p:h/html.vim +else + runtime! syntax/jinja.vim + runtime! syntax/html.vim + unlet b:current_syntax +endif + +let b:current_syntax = "htmljinja" http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/Vim/jinja.vim ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/Vim/jinja.vim b/ambari-common/src/main/python/jinja2/ext/Vim/jinja.vim new file mode 100644 index 0000000..919954b --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/Vim/jinja.vim @@ -0,0 +1,113 @@ +" Vim syntax file +" Language: Jinja template +" Maintainer: Armin Ronacher <armin.ronac...@active-4.com> +" Last Change: 2008 May 9 +" Version: 1.1 +" +" Known Bugs: +" because of odd limitations dicts and the modulo operator +" appear wrong in the template. +" +" Changes: +" +" 2008 May 9: Added support for Jinja2 changes (new keyword rules) + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +syntax case match + +" Jinja template built-in tags and parameters (without filter, macro, is and raw, they +" have special threatment) +syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained and if else in not or recursive as import + +syn keyword jinjaStatement containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained is filter skipwhite nextgroup=jinjaFilter +syn keyword jinjaStatement containedin=jinjaTagBlock contained macro skipwhite nextgroup=jinjaFunction +syn keyword jinjaStatement containedin=jinjaTagBlock contained block skipwhite nextgroup=jinjaBlockName + +" Variable Names +syn match jinjaVariable containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/ +syn keyword jinjaSpecial containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained false true none False True None loop super caller varargs kwargs + +" Filters +syn match jinjaOperator "|" containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained nextgroup=jinjaFilter +syn match jinjaFilter contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/ +syn match jinjaFunction contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/ +syn match jinjaBlockName contained skipwhite /[a-zA-Z_][a-zA-Z0-9_]*/ + +" Jinja template constants +syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/"/ skip=/\\"/ end=/"/ +syn region jinjaString containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained start=/'/ skip=/\\'/ end=/'/ +syn match jinjaNumber containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[0-9]\+\(\.[0-9]\+\)\?/ + +" Operators +syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[+\-*\/<>=!,:]/ +syn match jinjaPunctuation containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /[()\[\]]/ +syn match jinjaOperator containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained /\./ nextgroup=jinjaAttribute +syn match jinjaAttribute contained /[a-zA-Z_][a-zA-Z0-9_]*/ + +" Jinja template tag and variable blocks +syn region jinjaNested matchgroup=jinjaOperator start="(" end=")" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaNested matchgroup=jinjaOperator start="\[" end="\]" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaNested matchgroup=jinjaOperator start="{" end="}" transparent display containedin=jinjaVarBlock,jinjaTagBlock,jinjaNested contained +syn region jinjaTagBlock matchgroup=jinjaTagDelim start=/{%-\?/ end=/-\?%}/ skipwhite containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment + +syn region jinjaVarBlock matchgroup=jinjaVarDelim start=/{{-\?/ end=/-\?}}/ containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaRaw,jinjaString,jinjaNested,jinjaComment + +" Jinja template 'raw' tag +syn region jinjaRaw matchgroup=jinjaRawDelim start="{%\s*raw\s*%}" end="{%\s*endraw\s*%}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString,jinjaComment + +" Jinja comments +syn region jinjaComment matchgroup=jinjaCommentDelim start="{#" end="#}" containedin=ALLBUT,jinjaTagBlock,jinjaVarBlock,jinjaString + +" Block start keywords. A bit tricker. We only highlight at the start of a +" tag block and only if the name is not followed by a comma or equals sign +" which usually means that we have to deal with an assignment. +syn match jinjaStatement containedin=jinjaTagBlock contained skipwhite /\({%-\?\s*\)\@<=\<[a-zA-Z_][a-zA-Z0-9_]*\>\(\s*[,=]\)\@!/ + +" and context modifiers +syn match jinjaStatement containedin=jinjaTagBlock contained /\<with\(out\)\?\s\+context\>/ skipwhite + + +" Define the default highlighting. +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_jinja_syn_inits") + if version < 508 + let did_jinja_syn_inits = 1 + command -nargs=+ HiLink hi link <args> + else + command -nargs=+ HiLink hi def link <args> + endif + + HiLink jinjaPunctuation jinjaOperator + HiLink jinjaAttribute jinjaVariable + HiLink jinjaFunction jinjaFilter + + HiLink jinjaTagDelim jinjaTagBlock + HiLink jinjaVarDelim jinjaVarBlock + HiLink jinjaCommentDelim jinjaComment + HiLink jinjaRawDelim jinja + + HiLink jinjaSpecial Special + HiLink jinjaOperator Normal + HiLink jinjaRaw Normal + HiLink jinjaTagBlock PreProc + HiLink jinjaVarBlock PreProc + HiLink jinjaStatement Statement + HiLink jinjaFilter Function + HiLink jinjaBlockName Function + HiLink jinjaVariable Identifier + HiLink jinjaString Constant + HiLink jinjaNumber Constant + HiLink jinjaComment Comment + + delcommand HiLink +endif + +let b:current_syntax = "jinja" http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/django2jinja/django2jinja.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/django2jinja/django2jinja.py b/ambari-common/src/main/python/jinja2/ext/django2jinja/django2jinja.py new file mode 100644 index 0000000..6d9e76c --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/django2jinja/django2jinja.py @@ -0,0 +1,768 @@ +# -*- coding: utf-8 -*- +""" + Django to Jinja + ~~~~~~~~~~~~~~~ + + Helper module that can convert django templates into Jinja2 templates. + + This file is not intended to be used as stand alone application but to + be used as library. To convert templates you basically create your own + writer, add extra conversion logic for your custom template tags, + configure your django environment and run the `convert_templates` + function. + + Here a simple example:: + + # configure django (or use settings.configure) + import os + os.environ['DJANGO_SETTINGS_MODULE'] = 'yourapplication.settings' + from yourapplication.foo.templatetags.bar import MyNode + + from django2jinja import Writer, convert_templates + + def write_my_node(writer, node): + writer.start_variable() + writer.write('myfunc(') + for idx, arg in enumerate(node.args): + if idx: + writer.write(', ') + writer.node(arg) + writer.write(')') + writer.end_variable() + + writer = Writer() + writer.node_handlers[MyNode] = write_my_node + convert_templates('/path/to/output/folder', writer=writer) + + Here is an example hos to automatically translate your django + variables to jinja2:: + + import re + # List of tuple (Match pattern, Replace pattern, Exclusion pattern) + + var_re = ((re.compile(r"(u|user)\.is_authenticated"), r"\1.is_authenticated()", None), + (re.compile(r"\.non_field_errors"), r".non_field_errors()", None), + (re.compile(r"\.label_tag"), r".label_tag()", None), + (re.compile(r"\.as_dl"), r".as_dl()", None), + (re.compile(r"\.as_table"), r".as_table()", None), + (re.compile(r"\.as_widget"), r".as_widget()", None), + (re.compile(r"\.as_hidden"), r".as_hidden()", None), + + (re.compile(r"\.get_([0-9_\w]+)_url"), r".get_\1_url()", None), + (re.compile(r"\.url"), r".url()", re.compile(r"(form|calendar).url")), + (re.compile(r"\.get_([0-9_\w]+)_display"), r".get_\1_display()", None), + (re.compile(r"loop\.counter"), r"loop.index", None), + (re.compile(r"loop\.revcounter"), r"loop.revindex", None), + (re.compile(r"request\.GET\.([0-9_\w]+)"), r"request.GET.get('\1', '')", None), + (re.compile(r"request\.get_host"), r"request.get_host()", None), + + (re.compile(r"\.all(?!_)"), r".all()", None), + (re.compile(r"\.all\.0"), r".all()[0]", None), + (re.compile(r"\.([0-9])($|\s+)"), r"[\1]\2", None), + (re.compile(r"\.items"), r".items()", None), + ) + writer = Writer(var_re=var_re) + + For details about the writing process have a look at the module code. + + :copyright: (c) 2009 by the Jinja Team. + :license: BSD. +""" +import re +import os +import sys +from jinja2.defaults import * +from django.conf import settings +from django.template import defaulttags as core_tags, loader, TextNode, \ + FilterExpression, libraries, Variable, loader_tags, TOKEN_TEXT, \ + TOKEN_VAR +from django.template.debug import DebugVariableNode as VariableNode +from django.templatetags import i18n as i18n_tags +from StringIO import StringIO + + +_node_handlers = {} +_resolved_filters = {} +_newline_re = re.compile(r'(?:\r\n|\r|\n)') + + +# Django stores an itertools object on the cycle node. Not only is this +# thread unsafe but also a problem for the converter which needs the raw +# string values passed to the constructor to create a jinja loop.cycle() +# call from it. +_old_cycle_init = core_tags.CycleNode.__init__ +def _fixed_cycle_init(self, cyclevars, variable_name=None): + self.raw_cycle_vars = map(Variable, cyclevars) + _old_cycle_init(self, cyclevars, variable_name) +core_tags.CycleNode.__init__ = _fixed_cycle_init + + +def node(cls): + def proxy(f): + _node_handlers[cls] = f + return f + return proxy + + +def convert_templates(output_dir, extensions=('.html', '.txt'), writer=None, + callback=None): + """Iterates over all templates in the template dirs configured and + translates them and writes the new templates into the output directory. + """ + if writer is None: + writer = Writer() + + def filter_templates(files): + for filename in files: + ifilename = filename.lower() + for extension in extensions: + if ifilename.endswith(extension): + yield filename + + def translate(f, loadname): + template = loader.get_template(loadname) + original = writer.stream + writer.stream = f + writer.body(template.nodelist) + writer.stream = original + + if callback is None: + def callback(template): + print template + + for directory in settings.TEMPLATE_DIRS: + for dirname, _, files in os.walk(directory): + dirname = dirname[len(directory) + 1:] + for filename in filter_templates(files): + source = os.path.normpath(os.path.join(dirname, filename)) + target = os.path.join(output_dir, dirname, filename) + basetarget = os.path.dirname(target) + if not os.path.exists(basetarget): + os.makedirs(basetarget) + callback(source) + f = file(target, 'w') + try: + translate(f, source) + finally: + f.close() + + +class Writer(object): + """The core writer class.""" + + def __init__(self, stream=None, error_stream=None, + block_start_string=BLOCK_START_STRING, + block_end_string=BLOCK_END_STRING, + variable_start_string=VARIABLE_START_STRING, + variable_end_string=VARIABLE_END_STRING, + comment_start_string=COMMENT_START_STRING, + comment_end_string=COMMENT_END_STRING, + initial_autoescape=True, + use_jinja_autoescape=False, + custom_node_handlers=None, + var_re=[], + env=None): + if stream is None: + stream = sys.stdout + if error_stream is None: + error_stream = sys.stderr + self.stream = stream + self.error_stream = error_stream + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.autoescape = initial_autoescape + self.spaceless = False + self.use_jinja_autoescape = use_jinja_autoescape + self.node_handlers = dict(_node_handlers, + **(custom_node_handlers or {})) + self._loop_depth = 0 + self._filters_warned = set() + self.var_re = var_re + self.env = env + + def enter_loop(self): + """Increments the loop depth so that write functions know if they + are in a loop. + """ + self._loop_depth += 1 + + def leave_loop(self): + """Reverse of enter_loop.""" + self._loop_depth -= 1 + + @property + def in_loop(self): + """True if we are in a loop.""" + return self._loop_depth > 0 + + def write(self, s): + """Writes stuff to the stream.""" + self.stream.write(s.encode(settings.FILE_CHARSET)) + + def print_expr(self, expr): + """Open a variable tag, write to the string to the stream and close.""" + self.start_variable() + self.write(expr) + self.end_variable() + + def _post_open(self): + if self.spaceless: + self.write('- ') + else: + self.write(' ') + + def _pre_close(self): + if self.spaceless: + self.write(' -') + else: + self.write(' ') + + def start_variable(self): + """Start a variable.""" + self.write(self.variable_start_string) + self._post_open() + + def end_variable(self, always_safe=False): + """End a variable.""" + if not always_safe and self.autoescape and \ + not self.use_jinja_autoescape: + self.write('|e') + self._pre_close() + self.write(self.variable_end_string) + + def start_block(self): + """Starts a block.""" + self.write(self.block_start_string) + self._post_open() + + def end_block(self): + """Ends a block.""" + self._pre_close() + self.write(self.block_end_string) + + def tag(self, name): + """Like `print_expr` just for blocks.""" + self.start_block() + self.write(name) + self.end_block() + + def variable(self, name): + """Prints a variable. This performs variable name transformation.""" + self.write(self.translate_variable_name(name)) + + def literal(self, value): + """Writes a value as literal.""" + value = repr(value) + if value[:2] in ('u"', "u'"): + value = value[1:] + self.write(value) + + def filters(self, filters, is_block=False): + """Dumps a list of filters.""" + want_pipe = not is_block + for filter, args in filters: + name = self.get_filter_name(filter) + if name is None: + self.warn('Could not find filter %s' % name) + continue + if name not in DEFAULT_FILTERS and \ + name not in self._filters_warned: + self._filters_warned.add(name) + self.warn('Filter %s probably doesn\'t exist in Jinja' % + name) + if not want_pipe: + want_pipe = True + else: + self.write('|') + self.write(name) + if args: + self.write('(') + for idx, (is_var, value) in enumerate(args): + if idx: + self.write(', ') + if is_var: + self.node(value) + else: + self.literal(value) + self.write(')') + + def get_location(self, origin, position): + """Returns the location for an origin and position tuple as name + and lineno. + """ + if hasattr(origin, 'source'): + source = origin.source + name = '<unknown source>' + else: + source = origin.loader(origin.loadname, origin.dirs)[0] + name = origin.loadname + lineno = len(_newline_re.findall(source[:position[0]])) + 1 + return name, lineno + + def warn(self, message, node=None): + """Prints a warning to the error stream.""" + if node is not None and hasattr(node, 'source'): + filename, lineno = self.get_location(*node.source) + message = '[%s:%d] %s' % (filename, lineno, message) + print >> self.error_stream, message + + def translate_variable_name(self, var): + """Performs variable name translation.""" + if self.in_loop and var == 'forloop' or var.startswith('forloop.'): + var = var[3:] + + for reg, rep, unless in self.var_re: + no_unless = unless and unless.search(var) or True + if reg.search(var) and no_unless: + var = reg.sub(rep, var) + break + return var + + def get_filter_name(self, filter): + """Returns the filter name for a filter function or `None` if there + is no such filter. + """ + if filter not in _resolved_filters: + for library in libraries.values(): + for key, value in library.filters.iteritems(): + _resolved_filters[value] = key + return _resolved_filters.get(filter, None) + + def node(self, node): + """Invokes the node handler for a node.""" + for cls, handler in self.node_handlers.iteritems(): + if type(node) is cls or type(node).__name__ == cls: + handler(self, node) + break + else: + self.warn('Untranslatable node %s.%s found' % ( + node.__module__, + node.__class__.__name__ + ), node) + + def body(self, nodes): + """Calls node() for every node in the iterable passed.""" + for node in nodes: + self.node(node) + + +@node(TextNode) +def text_node(writer, node): + writer.write(node.s) + + +@node(Variable) +def variable(writer, node): + if node.translate: + writer.warn('i18n system used, make sure to install translations', node) + writer.write('_(') + if node.literal is not None: + writer.literal(node.literal) + else: + writer.variable(node.var) + if node.translate: + writer.write(')') + + +@node(VariableNode) +def variable_node(writer, node): + writer.start_variable() + if node.filter_expression.var.var == 'block.super' \ + and not node.filter_expression.filters: + writer.write('super()') + else: + writer.node(node.filter_expression) + writer.end_variable() + + +@node(FilterExpression) +def filter_expression(writer, node): + writer.node(node.var) + writer.filters(node.filters) + + +@node(core_tags.CommentNode) +def comment_tag(writer, node): + pass + + +@node(core_tags.DebugNode) +def comment_tag(writer, node): + writer.warn('Debug tag detected. Make sure to add a global function ' + 'called debug to the namespace.', node=node) + writer.print_expr('debug()') + + +@node(core_tags.ForNode) +def for_loop(writer, node): + writer.start_block() + writer.write('for ') + for idx, var in enumerate(node.loopvars): + if idx: + writer.write(', ') + writer.variable(var) + writer.write(' in ') + if node.is_reversed: + writer.write('(') + writer.node(node.sequence) + if node.is_reversed: + writer.write(')|reverse') + writer.end_block() + writer.enter_loop() + writer.body(node.nodelist_loop) + writer.leave_loop() + writer.tag('endfor') + + +@node(core_tags.IfNode) +def if_condition(writer, node): + writer.start_block() + writer.write('if ') + join_with = 'and' + if node.link_type == core_tags.IfNode.LinkTypes.or_: + join_with = 'or' + + for idx, (ifnot, expr) in enumerate(node.bool_exprs): + if idx: + writer.write(' %s ' % join_with) + if ifnot: + writer.write('not ') + writer.node(expr) + writer.end_block() + writer.body(node.nodelist_true) + if node.nodelist_false: + writer.tag('else') + writer.body(node.nodelist_false) + writer.tag('endif') + + +@node(core_tags.IfEqualNode) +def if_equal(writer, node): + writer.start_block() + writer.write('if ') + writer.node(node.var1) + if node.negate: + writer.write(' != ') + else: + writer.write(' == ') + writer.node(node.var2) + writer.end_block() + writer.body(node.nodelist_true) + if node.nodelist_false: + writer.tag('else') + writer.body(node.nodelist_false) + writer.tag('endif') + + +@node(loader_tags.BlockNode) +def block(writer, node): + writer.tag('block ' + node.name.replace('-', '_').rstrip('_')) + node = node + while node.parent is not None: + node = node.parent + writer.body(node.nodelist) + writer.tag('endblock') + + +@node(loader_tags.ExtendsNode) +def extends(writer, node): + writer.start_block() + writer.write('extends ') + if node.parent_name_expr: + writer.node(node.parent_name_expr) + else: + writer.literal(node.parent_name) + writer.end_block() + writer.body(node.nodelist) + + +@node(loader_tags.ConstantIncludeNode) +@node(loader_tags.IncludeNode) +def include(writer, node): + writer.start_block() + writer.write('include ') + if hasattr(node, 'template'): + writer.literal(node.template.name) + else: + writer.node(node.template_name) + writer.end_block() + + +@node(core_tags.CycleNode) +def cycle(writer, node): + if not writer.in_loop: + writer.warn('Untranslatable free cycle (cycle outside loop)', node=node) + return + if node.variable_name is not None: + writer.start_block() + writer.write('set %s = ' % node.variable_name) + else: + writer.start_variable() + writer.write('loop.cycle(') + for idx, var in enumerate(node.raw_cycle_vars): + if idx: + writer.write(', ') + writer.node(var) + writer.write(')') + if node.variable_name is not None: + writer.end_block() + else: + writer.end_variable() + + +@node(core_tags.FilterNode) +def filter(writer, node): + writer.start_block() + writer.write('filter ') + writer.filters(node.filter_expr.filters, True) + writer.end_block() + writer.body(node.nodelist) + writer.tag('endfilter') + + +@node(core_tags.AutoEscapeControlNode) +def autoescape_control(writer, node): + original = writer.autoescape + writer.autoescape = node.setting + writer.body(node.nodelist) + writer.autoescape = original + + +@node(core_tags.SpacelessNode) +def spaceless(writer, node): + original = writer.spaceless + writer.spaceless = True + writer.warn('entering spaceless mode with different semantics', node) + # do the initial stripping + nodelist = list(node.nodelist) + if nodelist: + if isinstance(nodelist[0], TextNode): + nodelist[0] = TextNode(nodelist[0].s.lstrip()) + if isinstance(nodelist[-1], TextNode): + nodelist[-1] = TextNode(nodelist[-1].s.rstrip()) + writer.body(nodelist) + writer.spaceless = original + + +@node(core_tags.TemplateTagNode) +def template_tag(writer, node): + tag = { + 'openblock': writer.block_start_string, + 'closeblock': writer.block_end_string, + 'openvariable': writer.variable_start_string, + 'closevariable': writer.variable_end_string, + 'opencomment': writer.comment_start_string, + 'closecomment': writer.comment_end_string, + 'openbrace': '{', + 'closebrace': '}' + }.get(node.tagtype) + if tag: + writer.start_variable() + writer.literal(tag) + writer.end_variable() + + +@node(core_tags.URLNode) +def url_tag(writer, node): + writer.warn('url node used. make sure to provide a proper url() ' + 'function', node) + if node.asvar: + writer.start_block() + writer.write('set %s = ' % node.asvar) + else: + writer.start_variable() + autoescape = writer.autoescape + writer.write('url(') + writer.literal(node.view_name) + for arg in node.args: + writer.write(', ') + writer.node(arg) + for key, arg in node.kwargs.items(): + writer.write(', %s=' % key) + writer.node(arg) + writer.write(')') + if node.asvar: + writer.end_block() + else: + writer.end_variable() + + +@node(core_tags.WidthRatioNode) +def width_ratio(writer, node): + writer.warn('widthratio expanded into formula. You may want to provide ' + 'a helper function for this calculation', node) + writer.start_variable() + writer.write('(') + writer.node(node.val_expr) + writer.write(' / ') + writer.node(node.max_expr) + writer.write(' * ') + writer.write(str(int(node.max_width))) + writer.write(')|round|int') + writer.end_variable(always_safe=True) + + +@node(core_tags.WithNode) +def with_block(writer, node): + writer.warn('with block expanded into set statement. This could cause ' + 'variables following that block to be overriden.', node) + writer.start_block() + writer.write('set %s = ' % node.name) + writer.node(node.var) + writer.end_block() + writer.body(node.nodelist) + + +@node(core_tags.RegroupNode) +def regroup(writer, node): + if node.expression.var.literal: + writer.warn('literal in groupby filter used. Behavior in that ' + 'situation is undefined and translation is skipped.', node) + return + elif node.expression.filters: + writer.warn('filters in groupby filter used. Behavior in that ' + 'situation is undefined which is most likely a bug ' + 'in your code. Filters were ignored.', node) + writer.start_block() + writer.write('set %s = ' % node.var_name) + writer.node(node.target) + writer.write('|groupby(') + writer.literal(node.expression.var.var) + writer.write(')') + writer.end_block() + + +@node(core_tags.LoadNode) +def warn_load(writer, node): + writer.warn('load statement used which was ignored on conversion', node) + + +@node(i18n_tags.GetAvailableLanguagesNode) +def get_available_languages(writer, node): + writer.warn('make sure to provide a get_available_languages function', node) + writer.tag('set %s = get_available_languages()' % + writer.translate_variable_name(node.variable)) + + +@node(i18n_tags.GetCurrentLanguageNode) +def get_current_language(writer, node): + writer.warn('make sure to provide a get_current_language function', node) + writer.tag('set %s = get_current_language()' % + writer.translate_variable_name(node.variable)) + + +@node(i18n_tags.GetCurrentLanguageBidiNode) +def get_current_language_bidi(writer, node): + writer.warn('make sure to provide a get_current_language_bidi function', node) + writer.tag('set %s = get_current_language_bidi()' % + writer.translate_variable_name(node.variable)) + + +@node(i18n_tags.TranslateNode) +def simple_gettext(writer, node): + writer.warn('i18n system used, make sure to install translations', node) + writer.start_variable() + writer.write('_(') + writer.node(node.value) + writer.write(')') + writer.end_variable() + + +@node(i18n_tags.BlockTranslateNode) +def translate_block(writer, node): + first_var = [] + variables = set() + + def touch_var(name): + variables.add(name) + if not first_var: + first_var.append(name) + + def dump_token_list(tokens): + for token in tokens: + if token.token_type == TOKEN_TEXT: + writer.write(token.contents) + elif token.token_type == TOKEN_VAR: + writer.print_expr(token.contents) + touch_var(token.contents) + + writer.warn('i18n system used, make sure to install translations', node) + writer.start_block() + writer.write('trans') + idx = -1 + for idx, (key, var) in enumerate(node.extra_context.items()): + if idx: + writer.write(',') + writer.write(' %s=' % key) + touch_var(key) + writer.node(var.filter_expression) + + have_plural = False + plural_var = None + if node.plural and node.countervar and node.counter: + have_plural = True + plural_var = node.countervar + if plural_var not in variables: + if idx > -1: + writer.write(',') + touch_var(plural_var) + writer.write(' %s=' % plural_var) + writer.node(node.counter) + + writer.end_block() + dump_token_list(node.singular) + if node.plural and node.countervar and node.counter: + writer.start_block() + writer.write('pluralize') + if node.countervar != first_var[0]: + writer.write(' ' + node.countervar) + writer.end_block() + dump_token_list(node.plural) + writer.tag('endtrans') + +@node("SimpleNode") +def simple_tag(writer, node): + """Check if the simple tag exist as a filter in """ + name = node.tag_name + if writer.env and \ + name not in writer.env.filters and \ + name not in writer._filters_warned: + writer._filters_warned.add(name) + writer.warn('Filter %s probably doesn\'t exist in Jinja' % + name) + + if not node.vars_to_resolve: + # No argument, pass the request + writer.start_variable() + writer.write('request|') + writer.write(name) + writer.end_variable() + return + + first_var = node.vars_to_resolve[0] + args = node.vars_to_resolve[1:] + writer.start_variable() + + # Copied from Writer.filters() + writer.node(first_var) + + writer.write('|') + writer.write(name) + if args: + writer.write('(') + for idx, var in enumerate(args): + if idx: + writer.write(', ') + if var.var: + writer.node(var) + else: + writer.literal(var.literal) + writer.write(')') + writer.end_variable() + +# get rid of node now, it shouldn't be used normally +del node http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/django2jinja/example.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/django2jinja/example.py b/ambari-common/src/main/python/jinja2/ext/django2jinja/example.py new file mode 100644 index 0000000..2d4ab9a --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/django2jinja/example.py @@ -0,0 +1,7 @@ +from django.conf import settings +settings.configure(TEMPLATE_DIRS=['templates'], TEMPLATE_DEBUG=True) + +from django2jinja import convert_templates, Writer + +writer = Writer(use_jinja_autoescape=True) +convert_templates('converted', writer=writer) http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/index.html ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/index.html b/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/index.html new file mode 100644 index 0000000..d0fbe38 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/index.html @@ -0,0 +1,58 @@ +{% extends "layout.html" %} +{% load i18n %} +{% block title %}Foo{% endblock %} +{% block page-body %} + {{ block.super }} + Hello {{ name|cut:"d" }}! + + {% for item in seq reversed %} + {% if forloop.index|divisibleby:2 %} + <li class="{% cycle 'a' 'b' %}">{{ item }}</li> + {% endif %} + {% endfor %} + {% ifequal foo bar %} + haha + {% else %} + hmm + {% endifequal %} + {% filter upper %} + {% include "subtemplate.html" %} + {% include foo %} + {% endfilter %} + {% spaceless %} + Hello World + {{ foo }} + Hmm + {% endspaceless %} + {% templatetag opencomment %}...{% templatetag closecomment %} + {% url foo a, b, c=d %} + {% url foo a, b, c=d as hmm %} + + {% with object.value as value %} + <img src='bar.gif' height='10' width='{% widthratio value 200 100 %}'> + {% endwith %} + + <pre>{% debug %}</pre> + + {% blocktrans with book|title as book_t and author|title as author_t %} + This is {{ book_t }} by {{ author_t }} + {% endblocktrans %} + + {% blocktrans count list|length as counter %} + There is only one {{ name }} object. + {% plural %} + There are {{ counter }} {{ name }} objects. + {% endblocktrans %} + + {% blocktrans with name|escape as name count list|length as counter %} + There is only one {{ name }} object. + {% plural %} + There are {{ counter }} {{ name }} objects. + {% endblocktrans %} + + {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %} + + <p>{% trans "This is the title." %}</p> + + {% regroup people by gender as grouped %} +{% endblock %} http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/layout.html ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/layout.html b/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/layout.html new file mode 100644 index 0000000..3f21a12 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/layout.html @@ -0,0 +1,4 @@ +<title>{% block title %}{% endblock %}</title> +<div class="body"> + {% block page-body %}{% endblock %} +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/subtemplate.html ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/subtemplate.html b/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/subtemplate.html new file mode 100644 index 0000000..980a0d5 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/django2jinja/templates/subtemplate.html @@ -0,0 +1 @@ +Hello World! http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/djangojinja2.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/djangojinja2.py b/ambari-common/src/main/python/jinja2/ext/djangojinja2.py new file mode 100644 index 0000000..d24d164 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/djangojinja2.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +""" + djangojinja2 + ~~~~~~~~~~~~ + + Adds support for Jinja2 to Django. + + Configuration variables: + + ======================= ============================================= + Key Description + ======================= ============================================= + `JINJA2_TEMPLATE_DIRS` List of template folders + `JINJA2_EXTENSIONS` List of Jinja2 extensions to use + `JINJA2_CACHE_SIZE` The size of the Jinja2 template cache. + ======================= ============================================= + + :copyright: (c) 2009 by the Jinja Team. + :license: BSD. +""" +from itertools import chain +from django.conf import settings +from django.http import HttpResponse +from django.core.exceptions import ImproperlyConfigured +from django.template.context import get_standard_processors +from django.template import TemplateDoesNotExist +from jinja2 import Environment, FileSystemLoader, TemplateNotFound +from jinja2.defaults import DEFAULT_NAMESPACE + + +# the environment is unconfigured until the first template is loaded. +_jinja_env = None + + +def get_env(): + """Get the Jinja2 env and initialize it if necessary.""" + global _jinja_env + if _jinja_env is None: + _jinja_env = create_env() + return _jinja_env + + +def create_env(): + """Create a new Jinja2 environment.""" + searchpath = list(settings.JINJA2_TEMPLATE_DIRS) + return Environment(loader=FileSystemLoader(searchpath), + auto_reload=settings.TEMPLATE_DEBUG, + cache_size=getattr(settings, 'JINJA2_CACHE_SIZE', 50), + extensions=getattr(settings, 'JINJA2_EXTENSIONS', ())) + + +def get_template(template_name, globals=None): + """Load a template.""" + try: + return get_env().get_template(template_name, globals=globals) + except TemplateNotFound, e: + raise TemplateDoesNotExist(str(e)) + + +def select_template(templates, globals=None): + """Try to load one of the given templates.""" + env = get_env() + for template in templates: + try: + return env.get_template(template, globals=globals) + except TemplateNotFound: + continue + raise TemplateDoesNotExist(', '.join(templates)) + + +def render_to_string(template_name, context=None, request=None, + processors=None): + """Render a template into a string.""" + context = dict(context or {}) + if request is not None: + context['request'] = request + for processor in chain(get_standard_processors(), processors or ()): + context.update(processor(request)) + return get_template(template_name).render(context) + + +def render_to_response(template_name, context=None, request=None, + processors=None, mimetype=None): + """Render a template into a response object.""" + return HttpResponse(render_to_string(template_name, context, request, + processors), mimetype=mimetype) http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/inlinegettext.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/inlinegettext.py b/ambari-common/src/main/python/jinja2/ext/inlinegettext.py new file mode 100644 index 0000000..cf4ed5e --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/inlinegettext.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +""" + Inline Gettext + ~~~~~~~~~~~~~~ + + An example extension for Jinja2 that supports inline gettext calls. + Requires the i18n extension to be loaded. + + :copyright: (c) 2009 by the Jinja Team. + :license: BSD. +""" +import re +from jinja2.ext import Extension +from jinja2.lexer import Token, count_newlines +from jinja2.exceptions import TemplateSyntaxError + + +_outside_re = re.compile(r'\\?(gettext|_)\(') +_inside_re = re.compile(r'\\?[()]') + + +class InlineGettext(Extension): + """This extension implements support for inline gettext blocks:: + + <h1>_(Welcome)</h1> + <p>_(This is a paragraph)</p> + + Requires the i18n extension to be loaded and configured. + """ + + def filter_stream(self, stream): + paren_stack = 0 + + for token in stream: + if token.type is not 'data': + yield token + continue + + pos = 0 + lineno = token.lineno + + while 1: + if not paren_stack: + match = _outside_re.search(token.value, pos) + else: + match = _inside_re.search(token.value, pos) + if match is None: + break + new_pos = match.start() + if new_pos > pos: + preval = token.value[pos:new_pos] + yield Token(lineno, 'data', preval) + lineno += count_newlines(preval) + gtok = match.group() + if gtok[0] == '\\': + yield Token(lineno, 'data', gtok[1:]) + elif not paren_stack: + yield Token(lineno, 'block_begin', None) + yield Token(lineno, 'name', 'trans') + yield Token(lineno, 'block_end', None) + paren_stack = 1 + else: + if gtok == '(' or paren_stack > 1: + yield Token(lineno, 'data', gtok) + paren_stack += gtok == ')' and -1 or 1 + if not paren_stack: + yield Token(lineno, 'block_begin', None) + yield Token(lineno, 'name', 'endtrans') + yield Token(lineno, 'block_end', None) + pos = match.end() + + if pos < len(token.value): + yield Token(lineno, 'data', token.value[pos:]) + + if paren_stack: + raise TemplateSyntaxError('unclosed gettext expression', + token.lineno, stream.name, + stream.filename) http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/ext/jinja.el ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/ext/jinja.el b/ambari-common/src/main/python/jinja2/ext/jinja.el new file mode 100644 index 0000000..401ba29 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/ext/jinja.el @@ -0,0 +1,213 @@ +;;; jinja.el --- Jinja mode highlighting +;; +;; Author: Georg Brandl +;; Copyright: (c) 2009 by the Jinja Team +;; Last modified: 2008-05-22 23:04 by gbr +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Mostly ripped off django-mode by Lennart Borgman. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(defconst jinja-font-lock-keywords + (list +; (cons (rx "{% comment %}" (submatch (0+ anything)) +; "{% endcomment %}") (list 1 font-lock-comment-face)) + '("{# ?\\(.*?\\) ?#}" . (1 font-lock-comment-face)) + '("{%-?\\|-?%}\\|{{\\|}}" . font-lock-preprocessor-face) + '("{#\\|#}" . font-lock-comment-delimiter-face) + ;; first word in a block is a command + '("{%-?[ \t\n]*\\([a-zA-Z_]+\\)" . (1 font-lock-keyword-face)) + ;; variables + '("\\({{ ?\\)\\([^|]*?\\)\\(|.*?\\)? ?}}" . (1 font-lock-variable-name-face)) + ;; keywords and builtins + (cons (rx word-start + (or "in" "as" "recursive" "not" "and" "or" "if" "else" + "import" "with" "without" "context") + word-end) + font-lock-keyword-face) + (cons (rx word-start + (or "true" "false" "none" "loop" "self" "super") + word-end) + font-lock-builtin-face) + ;; tests + '("\\(is\\)[ \t]*\\(not\\)[ \t]*\\([a-zA-Z_]+\\)" + (1 font-lock-keyword-face) (2 font-lock-keyword-face) + (3 font-lock-function-name-face)) + ;; builtin filters + (cons (rx + "|" (* space) + (submatch + (or "abs" "batch" "capitalize" "capture" "center" "count" "default" + "dformat" "dictsort" "e" "escape" "filesizeformat" "first" + "float" "format" "getattribute" "getitem" "groupby" "indent" + "int" "join" "jsonencode" "last" "length" "lower" "markdown" + "pprint" "random" "replace" "reverse" "round" "rst" "slice" + "sort" "string" "striptags" "sum" "textile" "title" "trim" + "truncate" "upper" "urlencode" "urlize" "wordcount" "wordwrap" + "xmlattr"))) + (list 1 font-lock-builtin-face)) + ) + "Minimal highlighting expressions for Jinja mode") + +(define-derived-mode jinja-mode nil "Jinja" + "Simple Jinja mode for use with `mumamo-mode'. +This mode only provides syntax highlighting." + ;;(set (make-local-variable 'comment-start) "{#") + ;;(set (make-local-variable 'comment-end) "#}") + (setq font-lock-defaults '(jinja-font-lock-keywords))) + +;; mumamo stuff + +(when (require 'mumamo nil t) + + (defun mumamo-chunk-jinja3(pos min max) + "Find {# ... #}. Return range and `jinja-mode'. +See `mumamo-find-possible-chunk' for POS, MIN and MAX." + (mumamo-find-possible-chunk pos min max + 'mumamo-search-bw-exc-start-jinja3 + 'mumamo-search-bw-exc-end-jinja3 + 'mumamo-search-fw-exc-start-jinja3 + 'mumamo-search-fw-exc-end-jinja3)) + + (defun mumamo-chunk-jinja2(pos min max) + "Find {{ ... }}. Return range and `jinja-mode'. +See `mumamo-find-possible-chunk' for POS, MIN and MAX." + (mumamo-find-possible-chunk pos min max + 'mumamo-search-bw-exc-start-jinja2 + 'mumamo-search-bw-exc-end-jinja2 + 'mumamo-search-fw-exc-start-jinja2 + 'mumamo-search-fw-exc-end-jinja2)) + + (defun mumamo-chunk-jinja (pos min max) + "Find {% ... %}. Return range and `jinja-mode'. +See `mumamo-find-possible-chunk' for POS, MIN and MAX." + (mumamo-find-possible-chunk pos min max + 'mumamo-search-bw-exc-start-jinja + 'mumamo-search-bw-exc-end-jinja + 'mumamo-search-fw-exc-start-jinja + 'mumamo-search-fw-exc-end-jinja)) + + (defun mumamo-search-bw-exc-start-jinja (pos min) + "Helper for `mumamo-chunk-jinja'. +POS is where to start search and MIN is where to stop." + (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{%"))) + (and exc-start + (<= exc-start pos) + (cons exc-start 'jinja-mode)))) + + (defun mumamo-search-bw-exc-start-jinja2(pos min) + "Helper for `mumamo-chunk-jinja2'. +POS is where to start search and MIN is where to stop." + (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{{"))) + (and exc-start + (<= exc-start pos) + (cons exc-start 'jinja-mode)))) + + (defun mumamo-search-bw-exc-start-jinja3(pos min) + "Helper for `mumamo-chunk-jinja3'. +POS is where to start search and MIN is where to stop." + (let ((exc-start (mumamo-chunk-start-bw-str-inc pos min "{#"))) + (and exc-start + (<= exc-start pos) + (cons exc-start 'jinja-mode)))) + + (defun mumamo-search-bw-exc-end-jinja (pos min) + "Helper for `mumamo-chunk-jinja'. +POS is where to start search and MIN is where to stop." + (mumamo-chunk-end-bw-str-inc pos min "%}")) + + (defun mumamo-search-bw-exc-end-jinja2(pos min) + "Helper for `mumamo-chunk-jinja2'. +POS is where to start search and MIN is where to stop." + (mumamo-chunk-end-bw-str-inc pos min "}}")) + + (defun mumamo-search-bw-exc-end-jinja3(pos min) + "Helper for `mumamo-chunk-jinja3'. +POS is where to start search and MIN is where to stop." + (mumamo-chunk-end-bw-str-inc pos min "#}")) + + (defun mumamo-search-fw-exc-start-jinja (pos max) + "Helper for `mumamo-chunk-jinja'. +POS is where to start search and MAX is where to stop." + (mumamo-chunk-start-fw-str-inc pos max "{%")) + + (defun mumamo-search-fw-exc-start-jinja2(pos max) + "Helper for `mumamo-chunk-jinja2'. +POS is where to start search and MAX is where to stop." + (mumamo-chunk-start-fw-str-inc pos max "{{")) + + (defun mumamo-search-fw-exc-start-jinja3(pos max) + "Helper for `mumamo-chunk-jinja3'. +POS is where to start search and MAX is where to stop." + (mumamo-chunk-start-fw-str-inc pos max "{#")) + + (defun mumamo-search-fw-exc-end-jinja (pos max) + "Helper for `mumamo-chunk-jinja'. +POS is where to start search and MAX is where to stop." + (mumamo-chunk-end-fw-str-inc pos max "%}")) + + (defun mumamo-search-fw-exc-end-jinja2(pos max) + "Helper for `mumamo-chunk-jinja2'. +POS is where to start search and MAX is where to stop." + (mumamo-chunk-end-fw-str-inc pos max "}}")) + + (defun mumamo-search-fw-exc-end-jinja3(pos max) + "Helper for `mumamo-chunk-jinja3'. +POS is where to start search and MAX is where to stop." + (mumamo-chunk-end-fw-str-inc pos max "#}")) + +;;;###autoload + (define-mumamo-multi-major-mode jinja-html-mumamo + "Turn on multiple major modes for Jinja with main mode `html-mode'. +This also covers inlined style and javascript." + ("Jinja HTML Family" html-mode + (mumamo-chunk-jinja + mumamo-chunk-jinja2 + mumamo-chunk-jinja3 + mumamo-chunk-inlined-style + mumamo-chunk-inlined-script + mumamo-chunk-style= + mumamo-chunk-onjs= + ))) + +;;;###autoload + (define-mumamo-multi-major-mode jinja-nxhtml-mumamo + "Turn on multiple major modes for Jinja with main mode `nxhtml-mode'. +This also covers inlined style and javascript." + ("Jinja nXhtml Family" nxhtml-mode + (mumamo-chunk-jinja + mumamo-chunk-jinja2 + mumamo-chunk-jinja3 + mumamo-chunk-inlined-style + mumamo-chunk-inlined-script + mumamo-chunk-style= + mumamo-chunk-onjs= + ))) + ) + +(provide 'jinja) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; jinja.el ends here http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2-debug.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2-debug.py b/ambari-common/src/main/python/jinja2/jinja2-debug.py new file mode 100644 index 0000000..c9c482f --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2-debug.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + Jinja2 Debug Interface + ~~~~~~~~~~~~~~~~~~~~~~ + + Helper script for internal Jinja2 debugging. Requires Werkzeug. + + :copyright: Copyright 2010 by Armin Ronacher. + :license: BSD. +""" +import sys +import jinja2 +from werkzeug import script + +env = jinja2.Environment(extensions=['jinja2.ext.i18n', 'jinja2.ext.do', + 'jinja2.ext.loopcontrols']) + +def shell_init_func(): + def _compile(x): + print env.compile(x, raw=True) + result = { + 'e': env, + 'c': _compile, + 't': env.from_string, + 'p': env.parse + } + for key in jinja2.__all__: + result[key] = getattr(jinja2, key) + return result + + +def action_compile(): + print env.compile(sys.stdin.read(), raw=True) + +action_shell = script.make_shell(shell_init_func) + + +if __name__ == '__main__': + script.run() http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2/__init__.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2/__init__.py b/ambari-common/src/main/python/jinja2/jinja2/__init__.py new file mode 100644 index 0000000..f944e11 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2/__init__.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +""" + jinja2 + ~~~~~~ + + Jinja2 is a template engine written in pure Python. It provides a + Django inspired non-XML syntax but supports inline expressions and + an optional sandboxed environment. + + Nutshell + -------- + + Here a small example of a Jinja2 template:: + + {% extends 'base.html' %} + {% block title %}Memberlist{% endblock %} + {% block content %} + <ul> + {% for user in users %} + <li><a href="{{ user.url }}">{{ user.username }}</a></li> + {% endfor %} + </ul> + {% endblock %} + + + :copyright: (c) 2010 by the Jinja Team. + :license: BSD, see LICENSE for more details. +""" +__docformat__ = 'restructuredtext en' +try: + __version__ = __import__('pkg_resources') \ + .get_distribution('Jinja2').version +except: + __version__ = 'unknown' + +# high level interface +from jinja2.environment import Environment, Template + +# loaders +from jinja2.loaders import BaseLoader, FileSystemLoader, PackageLoader, \ + DictLoader, FunctionLoader, PrefixLoader, ChoiceLoader, \ + ModuleLoader + +# bytecode caches +from jinja2.bccache import BytecodeCache, FileSystemBytecodeCache, \ + MemcachedBytecodeCache + +# undefined types +from jinja2.runtime import Undefined, DebugUndefined, StrictUndefined + +# exceptions +from jinja2.exceptions import TemplateError, UndefinedError, \ + TemplateNotFound, TemplatesNotFound, TemplateSyntaxError, \ + TemplateAssertionError + +# decorators and public utilities +from jinja2.filters import environmentfilter, contextfilter, \ + evalcontextfilter +from jinja2.utils import Markup, escape, clear_caches, \ + environmentfunction, evalcontextfunction, contextfunction, \ + is_undefined + +__all__ = [ + 'Environment', 'Template', 'BaseLoader', 'FileSystemLoader', + 'PackageLoader', 'DictLoader', 'FunctionLoader', 'PrefixLoader', + 'ChoiceLoader', 'BytecodeCache', 'FileSystemBytecodeCache', + 'MemcachedBytecodeCache', 'Undefined', 'DebugUndefined', + 'StrictUndefined', 'TemplateError', 'UndefinedError', 'TemplateNotFound', + 'TemplatesNotFound', 'TemplateSyntaxError', 'TemplateAssertionError', + 'ModuleLoader', 'environmentfilter', 'contextfilter', 'Markup', 'escape', + 'environmentfunction', 'contextfunction', 'clear_caches', 'is_undefined', + 'evalcontextfilter', 'evalcontextfunction' +] http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2/_debugsupport.c ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2/_debugsupport.c b/ambari-common/src/main/python/jinja2/jinja2/_debugsupport.c new file mode 100644 index 0000000..e756d8e --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2/_debugsupport.c @@ -0,0 +1,78 @@ +/** + * jinja2._debugsupport + * ~~~~~~~~~~~~~~~~~~~~ + * + * C implementation of `tb_set_next`. + * + * :copyright: (c) 2010 by the Jinja Team. + * :license: BSD. + */ + +#include <Python.h> + + +static PyObject* +tb_set_next(PyObject *self, PyObject *args) +{ + PyTracebackObject *tb, *old; + PyObject *next; + + if (!PyArg_ParseTuple(args, "O!O:tb_set_next", &PyTraceBack_Type, &tb, &next)) + return NULL; + if (next == Py_None) + next = NULL; + else if (!PyTraceBack_Check(next)) { + PyErr_SetString(PyExc_TypeError, + "tb_set_next arg 2 must be traceback or None"); + return NULL; + } + else + Py_INCREF(next); + + old = tb->tb_next; + tb->tb_next = (PyTracebackObject*)next; + Py_XDECREF(old); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef module_methods[] = { + {"tb_set_next", (PyCFunction)tb_set_next, METH_VARARGS, + "Set the tb_next member of a traceback object."}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + + +#if PY_MAJOR_VERSION < 3 + +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ +#define PyMODINIT_FUNC void +#endif +PyMODINIT_FUNC +init_debugsupport(void) +{ + Py_InitModule3("jinja2._debugsupport", module_methods, ""); +} + +#else /* Python 3.x module initialization */ + +static struct PyModuleDef module_definition = { + PyModuleDef_HEAD_INIT, + "jinja2._debugsupport", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__debugsupport(void) +{ + return PyModule_Create(&module_definition); +} + +#endif http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/__init__.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/__init__.py b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/__init__.py new file mode 100644 index 0000000..ec7bd57 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/__init__.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- +""" + markupsafe + ~~~~~~~~~~ + + Implements a Markup string. + + :copyright: (c) 2010 by Armin Ronacher. + :license: BSD, see LICENSE for more details. +""" +import re +from itertools import imap + + +__all__ = ['Markup', 'soft_unicode', 'escape', 'escape_silent'] + + +_striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)') +_entity_re = re.compile(r'&([^;]+);') + + +class Markup(unicode): + r"""Marks a string as being safe for inclusion in HTML/XML output without + needing to be escaped. This implements the `__html__` interface a couple + of frameworks and web applications use. :class:`Markup` is a direct + subclass of `unicode` and provides all the methods of `unicode` just that + it escapes arguments passed and always returns `Markup`. + + The `escape` function returns markup objects so that double escaping can't + happen. + + The constructor of the :class:`Markup` class can be used for three + different things: When passed an unicode object it's assumed to be safe, + when passed an object with an HTML representation (has an `__html__` + method) that representation is used, otherwise the object passed is + converted into a unicode string and then assumed to be safe: + + >>> Markup("Hello <em>World</em>!") + Markup(u'Hello <em>World</em>!') + >>> class Foo(object): + ... def __html__(self): + ... return '<a href="#">foo</a>' + ... + >>> Markup(Foo()) + Markup(u'<a href="#">foo</a>') + + If you want object passed being always treated as unsafe you can use the + :meth:`escape` classmethod to create a :class:`Markup` object: + + >>> Markup.escape("Hello <em>World</em>!") + Markup(u'Hello <em>World</em>!') + + Operations on a markup string are markup aware which means that all + arguments are passed through the :func:`escape` function: + + >>> em = Markup("<em>%s</em>") + >>> em % "foo & bar" + Markup(u'<em>foo & bar</em>') + >>> strong = Markup("<strong>%(text)s</strong>") + >>> strong % {'text': '<blink>hacker here</blink>'} + Markup(u'<strong><blink>hacker here</blink></strong>') + >>> Markup("<em>Hello</em> ") + "<foo>" + Markup(u'<em>Hello</em> <foo>') + """ + __slots__ = () + + def __new__(cls, base=u'', encoding=None, errors='strict'): + if hasattr(base, '__html__'): + base = base.__html__() + if encoding is None: + return unicode.__new__(cls, base) + return unicode.__new__(cls, base, encoding, errors) + + def __html__(self): + return self + + def __add__(self, other): + if hasattr(other, '__html__') or isinstance(other, basestring): + return self.__class__(unicode(self) + unicode(escape(other))) + return NotImplemented + + def __radd__(self, other): + if hasattr(other, '__html__') or isinstance(other, basestring): + return self.__class__(unicode(escape(other)) + unicode(self)) + return NotImplemented + + def __mul__(self, num): + if isinstance(num, (int, long)): + return self.__class__(unicode.__mul__(self, num)) + return NotImplemented + __rmul__ = __mul__ + + def __mod__(self, arg): + if isinstance(arg, tuple): + arg = tuple(imap(_MarkupEscapeHelper, arg)) + else: + arg = _MarkupEscapeHelper(arg) + return self.__class__(unicode.__mod__(self, arg)) + + def __repr__(self): + return '%s(%s)' % ( + self.__class__.__name__, + unicode.__repr__(self) + ) + + def join(self, seq): + return self.__class__(unicode.join(self, imap(escape, seq))) + join.__doc__ = unicode.join.__doc__ + + def split(self, *args, **kwargs): + return map(self.__class__, unicode.split(self, *args, **kwargs)) + split.__doc__ = unicode.split.__doc__ + + def rsplit(self, *args, **kwargs): + return map(self.__class__, unicode.rsplit(self, *args, **kwargs)) + rsplit.__doc__ = unicode.rsplit.__doc__ + + def splitlines(self, *args, **kwargs): + return map(self.__class__, unicode.splitlines(self, *args, **kwargs)) + splitlines.__doc__ = unicode.splitlines.__doc__ + + def unescape(self): + r"""Unescape markup again into an unicode string. This also resolves + known HTML4 and XHTML entities: + + >>> Markup("Main » <em>About</em>").unescape() + u'Main \xbb <em>About</em>' + """ + from jinja2._markupsafe._constants import HTML_ENTITIES + def handle_match(m): + name = m.group(1) + if name in HTML_ENTITIES: + return unichr(HTML_ENTITIES[name]) + try: + if name[:2] in ('#x', '#X'): + return unichr(int(name[2:], 16)) + elif name.startswith('#'): + return unichr(int(name[1:])) + except ValueError: + pass + return u'' + return _entity_re.sub(handle_match, unicode(self)) + + def striptags(self): + r"""Unescape markup into an unicode string and strip all tags. This + also resolves known HTML4 and XHTML entities. Whitespace is + normalized to one: + + >>> Markup("Main » <em>About</em>").striptags() + u'Main \xbb About' + """ + stripped = u' '.join(_striptags_re.sub('', self).split()) + return Markup(stripped).unescape() + + @classmethod + def escape(cls, s): + """Escape the string. Works like :func:`escape` with the difference + that for subclasses of :class:`Markup` this function would return the + correct subclass. + """ + rv = escape(s) + if rv.__class__ is not cls: + return cls(rv) + return rv + + def make_wrapper(name): + orig = getattr(unicode, name) + def func(self, *args, **kwargs): + args = _escape_argspec(list(args), enumerate(args)) + _escape_argspec(kwargs, kwargs.iteritems()) + return self.__class__(orig(self, *args, **kwargs)) + func.__name__ = orig.__name__ + func.__doc__ = orig.__doc__ + return func + + for method in '__getitem__', 'capitalize', \ + 'title', 'lower', 'upper', 'replace', 'ljust', \ + 'rjust', 'lstrip', 'rstrip', 'center', 'strip', \ + 'translate', 'expandtabs', 'swapcase', 'zfill': + locals()[method] = make_wrapper(method) + + # new in python 2.5 + if hasattr(unicode, 'partition'): + partition = make_wrapper('partition'), + rpartition = make_wrapper('rpartition') + + # new in python 2.6 + if hasattr(unicode, 'format'): + format = make_wrapper('format') + + # not in python 3 + if hasattr(unicode, '__getslice__'): + __getslice__ = make_wrapper('__getslice__') + + del method, make_wrapper + + +def _escape_argspec(obj, iterable): + """Helper for various string-wrapped functions.""" + for key, value in iterable: + if hasattr(value, '__html__') or isinstance(value, basestring): + obj[key] = escape(value) + return obj + + +class _MarkupEscapeHelper(object): + """Helper for Markup.__mod__""" + + def __init__(self, obj): + self.obj = obj + + __getitem__ = lambda s, x: _MarkupEscapeHelper(s.obj[x]) + __str__ = lambda s: str(escape(s.obj)) + __unicode__ = lambda s: unicode(escape(s.obj)) + __repr__ = lambda s: str(escape(repr(s.obj))) + __int__ = lambda s: int(s.obj) + __float__ = lambda s: float(s.obj) + + +# we have to import it down here as the speedups and native +# modules imports the markup type which is define above. +try: + from jinja2._markupsafe._speedups import escape, escape_silent, soft_unicode +except ImportError: + from jinja2._markupsafe._native import escape, escape_silent, soft_unicode http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_bundle.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_bundle.py b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_bundle.py new file mode 100644 index 0000000..e694faf --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_bundle.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" + jinja2._markupsafe._bundle + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This script pulls in markupsafe from a source folder and + bundles it with Jinja2. It does not pull in the speedups + module though. + + :copyright: Copyright 2010 by the Jinja team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" +import sys +import os +import re + + +def rewrite_imports(lines): + for idx, line in enumerate(lines): + new_line = re.sub(r'(import|from)\s+markupsafe\b', + r'\1 jinja2._markupsafe', line) + if new_line != line: + lines[idx] = new_line + + +def main(): + if len(sys.argv) != 2: + print 'error: only argument is path to markupsafe' + sys.exit(1) + basedir = os.path.dirname(__file__) + markupdir = sys.argv[1] + for filename in os.listdir(markupdir): + if filename.endswith('.py'): + f = open(os.path.join(markupdir, filename)) + try: + lines = list(f) + finally: + f.close() + rewrite_imports(lines) + f = open(os.path.join(basedir, filename), 'w') + try: + for line in lines: + f.write(line) + finally: + f.close() + + +if __name__ == '__main__': + main() http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_constants.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_constants.py b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_constants.py new file mode 100644 index 0000000..919bf03 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_constants.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +""" + markupsafe._constants + ~~~~~~~~~~~~~~~~~~~~~ + + Highlevel implementation of the Markup string. + + :copyright: (c) 2010 by Armin Ronacher. + :license: BSD, see LICENSE for more details. +""" + + +HTML_ENTITIES = { + 'AElig': 198, + 'Aacute': 193, + 'Acirc': 194, + 'Agrave': 192, + 'Alpha': 913, + 'Aring': 197, + 'Atilde': 195, + 'Auml': 196, + 'Beta': 914, + 'Ccedil': 199, + 'Chi': 935, + 'Dagger': 8225, + 'Delta': 916, + 'ETH': 208, + 'Eacute': 201, + 'Ecirc': 202, + 'Egrave': 200, + 'Epsilon': 917, + 'Eta': 919, + 'Euml': 203, + 'Gamma': 915, + 'Iacute': 205, + 'Icirc': 206, + 'Igrave': 204, + 'Iota': 921, + 'Iuml': 207, + 'Kappa': 922, + 'Lambda': 923, + 'Mu': 924, + 'Ntilde': 209, + 'Nu': 925, + 'OElig': 338, + 'Oacute': 211, + 'Ocirc': 212, + 'Ograve': 210, + 'Omega': 937, + 'Omicron': 927, + 'Oslash': 216, + 'Otilde': 213, + 'Ouml': 214, + 'Phi': 934, + 'Pi': 928, + 'Prime': 8243, + 'Psi': 936, + 'Rho': 929, + 'Scaron': 352, + 'Sigma': 931, + 'THORN': 222, + 'Tau': 932, + 'Theta': 920, + 'Uacute': 218, + 'Ucirc': 219, + 'Ugrave': 217, + 'Upsilon': 933, + 'Uuml': 220, + 'Xi': 926, + 'Yacute': 221, + 'Yuml': 376, + 'Zeta': 918, + 'aacute': 225, + 'acirc': 226, + 'acute': 180, + 'aelig': 230, + 'agrave': 224, + 'alefsym': 8501, + 'alpha': 945, + 'amp': 38, + 'and': 8743, + 'ang': 8736, + 'apos': 39, + 'aring': 229, + 'asymp': 8776, + 'atilde': 227, + 'auml': 228, + 'bdquo': 8222, + 'beta': 946, + 'brvbar': 166, + 'bull': 8226, + 'cap': 8745, + 'ccedil': 231, + 'cedil': 184, + 'cent': 162, + 'chi': 967, + 'circ': 710, + 'clubs': 9827, + 'cong': 8773, + 'copy': 169, + 'crarr': 8629, + 'cup': 8746, + 'curren': 164, + 'dArr': 8659, + 'dagger': 8224, + 'darr': 8595, + 'deg': 176, + 'delta': 948, + 'diams': 9830, + 'divide': 247, + 'eacute': 233, + 'ecirc': 234, + 'egrave': 232, + 'empty': 8709, + 'emsp': 8195, + 'ensp': 8194, + 'epsilon': 949, + 'equiv': 8801, + 'eta': 951, + 'eth': 240, + 'euml': 235, + 'euro': 8364, + 'exist': 8707, + 'fnof': 402, + 'forall': 8704, + 'frac12': 189, + 'frac14': 188, + 'frac34': 190, + 'frasl': 8260, + 'gamma': 947, + 'ge': 8805, + 'gt': 62, + 'hArr': 8660, + 'harr': 8596, + 'hearts': 9829, + 'hellip': 8230, + 'iacute': 237, + 'icirc': 238, + 'iexcl': 161, + 'igrave': 236, + 'image': 8465, + 'infin': 8734, + 'int': 8747, + 'iota': 953, + 'iquest': 191, + 'isin': 8712, + 'iuml': 239, + 'kappa': 954, + 'lArr': 8656, + 'lambda': 955, + 'lang': 9001, + 'laquo': 171, + 'larr': 8592, + 'lceil': 8968, + 'ldquo': 8220, + 'le': 8804, + 'lfloor': 8970, + 'lowast': 8727, + 'loz': 9674, + 'lrm': 8206, + 'lsaquo': 8249, + 'lsquo': 8216, + 'lt': 60, + 'macr': 175, + 'mdash': 8212, + 'micro': 181, + 'middot': 183, + 'minus': 8722, + 'mu': 956, + 'nabla': 8711, + 'nbsp': 160, + 'ndash': 8211, + 'ne': 8800, + 'ni': 8715, + 'not': 172, + 'notin': 8713, + 'nsub': 8836, + 'ntilde': 241, + 'nu': 957, + 'oacute': 243, + 'ocirc': 244, + 'oelig': 339, + 'ograve': 242, + 'oline': 8254, + 'omega': 969, + 'omicron': 959, + 'oplus': 8853, + 'or': 8744, + 'ordf': 170, + 'ordm': 186, + 'oslash': 248, + 'otilde': 245, + 'otimes': 8855, + 'ouml': 246, + 'para': 182, + 'part': 8706, + 'permil': 8240, + 'perp': 8869, + 'phi': 966, + 'pi': 960, + 'piv': 982, + 'plusmn': 177, + 'pound': 163, + 'prime': 8242, + 'prod': 8719, + 'prop': 8733, + 'psi': 968, + 'quot': 34, + 'rArr': 8658, + 'radic': 8730, + 'rang': 9002, + 'raquo': 187, + 'rarr': 8594, + 'rceil': 8969, + 'rdquo': 8221, + 'real': 8476, + 'reg': 174, + 'rfloor': 8971, + 'rho': 961, + 'rlm': 8207, + 'rsaquo': 8250, + 'rsquo': 8217, + 'sbquo': 8218, + 'scaron': 353, + 'sdot': 8901, + 'sect': 167, + 'shy': 173, + 'sigma': 963, + 'sigmaf': 962, + 'sim': 8764, + 'spades': 9824, + 'sub': 8834, + 'sube': 8838, + 'sum': 8721, + 'sup': 8835, + 'sup1': 185, + 'sup2': 178, + 'sup3': 179, + 'supe': 8839, + 'szlig': 223, + 'tau': 964, + 'there4': 8756, + 'theta': 952, + 'thetasym': 977, + 'thinsp': 8201, + 'thorn': 254, + 'tilde': 732, + 'times': 215, + 'trade': 8482, + 'uArr': 8657, + 'uacute': 250, + 'uarr': 8593, + 'ucirc': 251, + 'ugrave': 249, + 'uml': 168, + 'upsih': 978, + 'upsilon': 965, + 'uuml': 252, + 'weierp': 8472, + 'xi': 958, + 'yacute': 253, + 'yen': 165, + 'yuml': 255, + 'zeta': 950, + 'zwj': 8205, + 'zwnj': 8204 +} http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_native.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_native.py b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_native.py new file mode 100644 index 0000000..7b95828 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/_native.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +""" + markupsafe._native + ~~~~~~~~~~~~~~~~~~ + + Native Python implementation the C module is not compiled. + + :copyright: (c) 2010 by Armin Ronacher. + :license: BSD, see LICENSE for more details. +""" +from jinja2._markupsafe import Markup + + +def escape(s): + """Convert the characters &, <, >, ' and " in string s to HTML-safe + sequences. Use this if you need to display text that might contain + such characters in HTML. Marks return value as markup string. + """ + if hasattr(s, '__html__'): + return s.__html__() + return Markup(unicode(s) + .replace('&', '&') + .replace('>', '>') + .replace('<', '<') + .replace("'", ''') + .replace('"', '"') + ) + + +def escape_silent(s): + """Like :func:`escape` but converts `None` into an empty + markup string. + """ + if s is None: + return Markup() + return escape(s) + + +def soft_unicode(s): + """Make a string unicode if it isn't already. That way a markup + string is not converted back to unicode. + """ + if not isinstance(s, unicode): + s = unicode(s) + return s http://git-wip-us.apache.org/repos/asf/ambari/blob/570de228/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/tests.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/tests.py b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/tests.py new file mode 100644 index 0000000..c1ce394 --- /dev/null +++ b/ambari-common/src/main/python/jinja2/jinja2/_markupsafe/tests.py @@ -0,0 +1,80 @@ +import gc +import unittest +from jinja2._markupsafe import Markup, escape, escape_silent + + +class MarkupTestCase(unittest.TestCase): + + def test_markup_operations(self): + # adding two strings should escape the unsafe one + unsafe = '<script type="application/x-some-script">alert("foo");</script>' + safe = Markup('<em>username</em>') + assert unsafe + safe == unicode(escape(unsafe)) + unicode(safe) + + # string interpolations are safe to use too + assert Markup('<em>%s</em>') % '<bad user>' == \ + '<em><bad user></em>' + assert Markup('<em>%(username)s</em>') % { + 'username': '<bad user>' + } == '<em><bad user></em>' + + # an escaped object is markup too + assert type(Markup('foo') + 'bar') is Markup + + # and it implements __html__ by returning itself + x = Markup("foo") + assert x.__html__() is x + + # it also knows how to treat __html__ objects + class Foo(object): + def __html__(self): + return '<em>awesome</em>' + def __unicode__(self): + return 'awesome' + assert Markup(Foo()) == '<em>awesome</em>' + assert Markup('<strong>%s</strong>') % Foo() == \ + '<strong><em>awesome</em></strong>' + + # escaping and unescaping + assert escape('"<>&\'') == '"<>&'' + assert Markup("<em>Foo & Bar</em>").striptags() == "Foo & Bar" + assert Markup("<test>").unescape() == "<test>" + + def test_all_set(self): + import jinja2._markupsafe as markup + for item in markup.__all__: + getattr(markup, item) + + def test_escape_silent(self): + assert escape_silent(None) == Markup() + assert escape(None) == Markup(None) + assert escape_silent('<foo>') == Markup(u'<foo>') + + +class MarkupLeakTestCase(unittest.TestCase): + + def test_markup_leaks(self): + counts = set() + for count in xrange(20): + for item in xrange(1000): + escape("foo") + escape("<foo>") + escape(u"foo") + escape(u"<foo>") + counts.add(len(gc.get_objects())) + assert len(counts) == 1, 'ouch, c extension seems to leak objects' + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(MarkupTestCase)) + + # this test only tests the c extension + if not hasattr(escape, 'func_code'): + suite.addTest(unittest.makeSuite(MarkupLeakTestCase)) + + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite')