Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- import contextlib
- import pyjade
- from pyjade.runtime import is_mapping, iteration
- def process_param(key, value, terse=False):
- if terse:
- if (key == value) or (value is True):
- return key
- if isinstance(value, basestring):
- value = value.decode('utf8')
- return '''%s="%s"''' % (key, value)
- TYPE_CODE = {
- 'if': lambda v: bool(v),
- 'unless': lambda v: not bool(v),
- 'elsif': lambda v: bool(v),
- 'else': lambda v: True}
- @contextlib.contextmanager
- def local_context_manager(compiler, local_context):
- old_local_context = compiler.local_context
- new_local_context = dict(compiler.local_context)
- new_local_context.update(local_context)
- compiler.local_context = new_local_context
- yield
- compiler.local_context = old_local_context
- class HTMLCompiler(pyjade.compiler.Compiler):
- global_context = dict()
- local_context = dict()
- mixins = dict()
- useRuntime = True
- def _do_eval(self, value):
- if isinstance(value, basestring):
- value = value.encode('utf-8')
- try:
- value = eval(value, self.global_context, self.local_context)
- except:
- return ''
- return value
- def compile(self):
- self.buf = [self.compile_top()]
- self.lastBufferedIdx = -1
- self.local_context = dict()
- self.global_context = dict()
- self.mixins = dict()
- self.visit(self.node)
- return unicode(u''.join(self.buf))
- def _get_value(self, attr):
- value = attr['val']
- if attr['static']:
- return attr['val']
- if isinstance(value, basestring):
- return self._do_eval(value)
- else:
- return attr['name']
- def _make_mixin(self, mixin):
- arg_names = [arg.strip() for arg in mixin.args.split(",")]
- def _mixin(self, args, block=None):
- if args:
- arg_values = self._do_eval(args)
- else:
- arg_values = []
- if '__iter__' not in dir(arg_values):
- arg_values = [arg_values]
- local_context = dict(zip(arg_names, arg_values))
- if block: local_context['block'] = block
- with local_context_manager(self, local_context):
- self.visitBlock(mixin.block)
- return _mixin
- def visitCodeBlock(self,block,mixing=None):
- if 'block' in self.local_context:
- self.visitBlock(self.local_context['block'])
- else:
- self.visitBlock(block)
- def interpolate(self,text):
- return self._interpolate(text, lambda x: str(self._do_eval(x)))
- def visitInclude(self, node):
- raise pyjade.exceptions.CurrentlyNotSupported()
- def visitExtends(self, node):
- raise pyjade.exceptions.CurrentlyNotSupported()
- def visitMixin(self, mixin):
- if mixin.name in self.mixins:
- self.mixins[mixin.name](self, mixin.args, mixin.block)
- else:
- self.mixins[mixin.name] = self._make_mixin(mixin)
- def visitAssignment(self, assignment):
- self.global_context[assignment.name] = eval(assignment.val)
- def visitConditional(self, conditional):
- if not conditional.sentence:
- value = False
- else:
- value = self._do_eval(conditional.sentence)
- if TYPE_CODE[conditional.type](value):
- self.visit(conditional.block)
- elif conditional.next:
- for item in conditional.next:
- self.visitConditional(item)
- def visitCode(self, code):
- if code.buffer:
- val = code.val.lstrip()
- val = self._do_eval(val)
- if code.escape:
- val = str(val).replace('&', '&').replace('<', '<').replace('>', '>')
- self.buf.append(val)
- if code.block:
- self.visit(code.block)
- if not code.buffer and not code.block:
- exec code.val.lstrip() in self.global_context, self.local_context
- def visitEach(self, each):
- obj = iteration(self._do_eval(each.obj), len(each.keys))
- for item in obj:
- local_context = dict()
- if len(each.keys) > 1:
- for (key, value) in zip(each.keys, item):
- local_context[key] = value
- else:
- local_context[each.keys[0]] = item
- with local_context_manager(self, local_context):
- self.visit(each.block)
- def attributes(self, attrs):
- return " ".join(['''%s="%s"''' % (k,v) for (k,v) in attrs.items()])
- def visitDynamicAttributes(self, attrs):
- classes = []
- params = []
- for attr in attrs:
- if attr['name'] == 'class':
- value = self._get_value(attr)
- if isinstance(value, list):
- classes.extend(value)
- else:
- classes.append(value)
- else:
- value = self._get_value(attr)
- if value not in (None,False):
- params.append((attr['name'], value))
- if classes:
- classes = [unicode(c) for c in classes]
- params.append(('class', " ".join(classes)))
- if params:
- self.buf.append(" "+" ".join([process_param(k, v, self.terse) for (k,v) in params]))
- def process_jade(src):
- parser = pyjade.parser.Parser(src)
- block = parser.parse()
- compiler = HTMLCompiler(block, pretty=True)
- return compiler.compile()
Advertisement
Add Comment
Please, Sign In to add comment