mako源码解读(2)——文档解析

本文深入探讨Mako模板引擎的工作原理,重点关注其文档解析阶段。通过编译模板文本为可执行的Python代码,Mako实现了动态内容的生成。解析过程中,Mako将文本分解为节点,为后续生成Python代码做准备。测试案例展示了模板中包含的各种元素如何被Mako处理,主要涉及self.template、self.tag和self.control_line等方法的应用。
摘要由CSDN通过智能技术生成

mako的生成模板首先需要把文本编译成可执行的Python代码,然后再从外部添加变量,进行执行,输出文本

编译过程也要分为两部分,先是根据文档结构进行解析,然后根据解析好的节点生成Python代码(好像编译原理中的中间代码生成啊,后悔上课不认真听那门课T^T)

这边文章我们先看解析成节点

老规矩,先上测试案例

def test_integration(self):
    template = """<%namespace name="foo" file="somefile.html"/>
# inherit from foobar.html
<%inherit file="foobar.html"/>

<%component name="header">
 <div>header</div>
</%component>
<%component name="footer">
<div> footer</div>
</%component>

<table>
% for j in data():
<tr>
    % for x in j:
        <td>Hello ${x| h}</td>
    % endfor
</tr>
% endfor
</table>
"""
    nodes = Lexer(template).parse()
    #print nodes
    assert repr(nodes) == r"""TemplateNode({}, [NamespaceTag('namespace', {'name': '"foo"', 'file': '"somefile.html"'}, (1, 1), []), Text('\n', (1, 46)), Comment('inherit from foobar.html', (2, 1)), InheritTag('inherit', {'file': '"foobar.html"'}, (3, 1), []), Text('\n\n', (3, 31)), ComponentTag('component', {'name': '"header"'}, (5, 1), ["Text('\\n     <div>header</div>\\n', (5, 27))"]), Text('\n', (7, 14)), ComponentTag('component', {'name': '"footer"'}, (8, 1), ["Text('\\n    <div> footer</div>\\n', (8, 27))"]), Text('\n\n<table>\n', (10, 14)), ControlLine('for', 'for j in data():', False, (13, 1)), Text('    <tr>\n', (14, 1)), ControlLine('for', 'for x in j:', False, (15, 1)), Text('            <td>Hello ', (16, 1)), Expression('x', ['h'], (16, 23)), Text('</td>\n', (16, 30)), ControlLine('for', 'endfor', True, (17, 1)), Text('    </tr>\n', (18, 1)), ControlLine('for', 'endfor', True, (19, 1)), Text('</table>\n', (20, 1))])"""

注意!,这里的节点并不是指html的节点,指的是mako当中的标签,如<%block>,<%def>这种,mako是文本模板引擎,而不是html模板引擎

上面测试代码的template是一段混合着mako各种元素的文本,让我们看看mako是如何对这段文本进行操作的

上面的测试代码用到了两个方法


class Lexer(object):
    def __init__(self, text):
        self.text = text
        self.template = parsetree.TemplateNode()
        self.matched_lineno = 1
        self.matched_charpos = 0
        self.lineno = 1
        self.match_position = 0
        self.tag = []
        self.control_line = []
 
    def parse(self):
        length = len(self.text)
        while (True):
            if self.match_position > length: 
                break
   
            if self.match_end():
                break
            if self.match_expression():
                continue
            if self.match_control_line():
                continue
            if self.match_tag_start(): 
                continue
            if self.match_tag_end():
                continue
            if self.match_python_block():
                continue
            if self.match_text(): 
                continue
            
            if (self.current.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值