annotate mercurial/templater.py @ 40626:87a872555e90

revlog: detect incomplete revlog reads _readsegment() is supposed to return N bytes of revlog revision data starting at a file offset. Surprisingly, its behavior before this patch never verified that it actually read and returned N bytes! Instead, it would perform the read(), then return whatever data was available. And even more surprisingly, nothing in the call chain appears to have been validating that it received all the data it was expecting. This behavior could lead to partial or incomplete revision chunks being operated on. This could result in e.g. cached deltas being applied against incomplete base revisions. The delta application process would happily perform this operation. Only hash verification would detect the corruption and save us. This commit changes the behavior of raw revlog reading to validate that we actually read() the number of bytes that were requested. We will raise a more specific error faster, rather than possibly have it go undetected or manifest later in the call stack, at delta application or hash verification. Differential Revision: https://phab.mercurial-scm.org/D5266
author Gregory Szorc <gregory.szorc@gmail.com>
date Tue, 13 Nov 2018 12:30:59 -0800
parents ff8b2886c492
children 4591c9791a82
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
1 # templater.py - template expansion for output
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
2 #
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8223
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9842
diff changeset
6 # GNU General Public License version 2 or any later version.
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
7
37014
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
8 """Slightly complicated template engine for commands and hgweb
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
9
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
10 This module provides low-level interface to the template engine. See the
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
11 formatter and cmdutil modules if you are looking for high-level functions
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
12 such as ``cmdutil.rendertemplate(ctx, tmpl)``.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
13
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
14 Internal Data Types
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
15 -------------------
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
16
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
17 Template keywords and functions take a dictionary of current symbols and
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
18 resources (a "mapping") and return result. Inputs and outputs must be one
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
19 of the following data types:
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
20
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
21 bytes
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
22 a byte string, which is generally a human-readable text in local encoding.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
23
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
24 generator
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
25 a lazily-evaluated byte string, which is a possibly nested generator of
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
26 values of any printable types, and will be folded by ``stringify()``
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
27 or ``flatten()``.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
28
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
29 None
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
30 sometimes represents an empty value, which can be stringified to ''.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
31
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
32 True, False, int, float
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
33 can be stringified as such.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
34
38226
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
35 wrappedbytes, wrappedvalue
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
36 a wrapper for the above printable types.
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38225
diff changeset
37
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
38 date
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38283
diff changeset
39 represents a (unixtime, offset) tuple.
37014
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
40
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
41 hybrid
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
42 represents a list/dict of printable values, which can also be converted
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
43 to mappings by % operator.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
44
38283
0e0d03d09ecd templater: rename mappable to hybriditem as it is the primary use case
Yuya Nishihara <yuya@tcha.org>
parents: 38226
diff changeset
45 hybriditem
37014
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
46 represents a scalar printable value, also supports % operator.
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37398
diff changeset
47
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37398
diff changeset
48 mappinggenerator, mappinglist
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37398
diff changeset
49 represents mappings (i.e. a list of dicts), which may have default
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37398
diff changeset
50 output format.
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37399
diff changeset
51
40475
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
52 mappingdict
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
53 represents a single mapping (i.e. a dict), which may have default output
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
54 format.
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
55
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37399
diff changeset
56 mappedgenerator
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37399
diff changeset
57 a lazily-evaluated list of byte strings, which is e.g. a result of %
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37399
diff changeset
58 operation.
37014
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
59 """
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
60
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
61 from __future__ import absolute_import, print_function
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
62
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
63 import abc
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
64 import os
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
65
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
66 from .i18n import _
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
67 from . import (
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
68 config,
31520
6f150bb19317 templater: make pad() compute actual width
Yuya Nishihara <yuya@tcha.org>
parents: 31519
diff changeset
69 encoding,
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
70 error,
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
71 parser,
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
72 pycompat,
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
73 templatefilters,
36922
521f6c7e1756 templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
74 templatefuncs,
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
75 templateutil,
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
76 util,
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
77 )
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37075
diff changeset
78 from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37075
diff changeset
79 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37075
diff changeset
80 )
36443
8dbd97aef915 templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents: 36245
diff changeset
81
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
82 # template parsing
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
83
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
84 elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
85 # token-type: binding-strength, primary, prefix, infix, suffix
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
86 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
87 ".": (18, None, None, (".", 18), None),
34329
6367318327f0 templater: adjust binding strength of '%' and '|' operators (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 34328
diff changeset
88 "%": (15, None, None, ("%", 15), None),
31884
0926ca37a990 templater: adjust binding strengths to make room for key-value operator
Yuya Nishihara <yuya@tcha.org>
parents: 31883
diff changeset
89 "|": (15, None, None, ("|", 15), None),
0926ca37a990 templater: adjust binding strengths to make room for key-value operator
Yuya Nishihara <yuya@tcha.org>
parents: 31883
diff changeset
90 "*": (5, None, None, ("*", 5), None),
0926ca37a990 templater: adjust binding strengths to make room for key-value operator
Yuya Nishihara <yuya@tcha.org>
parents: 31883
diff changeset
91 "/": (5, None, None, ("/", 5), None),
0926ca37a990 templater: adjust binding strengths to make room for key-value operator
Yuya Nishihara <yuya@tcha.org>
parents: 31883
diff changeset
92 "+": (4, None, None, ("+", 4), None),
0926ca37a990 templater: adjust binding strengths to make room for key-value operator
Yuya Nishihara <yuya@tcha.org>
parents: 31883
diff changeset
93 "-": (4, None, ("negate", 19), ("-", 4), None),
31885
d18b624c1c06 templater: add parsing rule for key-value pair
Yuya Nishihara <yuya@tcha.org>
parents: 31884
diff changeset
94 "=": (3, None, None, ("keyvalue", 3), None),
31883
25be03a33f50 templater: sort token table by binding strength
Yuya Nishihara <yuya@tcha.org>
parents: 31880
diff changeset
95 ",": (2, None, None, ("list", 2), None),
25be03a33f50 templater: sort token table by binding strength
Yuya Nishihara <yuya@tcha.org>
parents: 31880
diff changeset
96 ")": (0, None, None, None, None),
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
97 "integer": (0, "integer", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
98 "symbol": (0, "symbol", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
99 "string": (0, "string", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
100 "template": (0, "template", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
101 "end": (0, None, None, None, None),
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
102 }
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
103
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
104 def tokenize(program, start, end, term=None):
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
105 """Parse a template expression into a stream of tokens, which must end
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
106 with term if specified"""
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
107 pos = start
32154
52e222eef646 py3: use pycompat.bytestr instead of bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32037
diff changeset
108 program = pycompat.bytestr(program)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
109 while pos < end:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
110 c = program[pos]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
111 if c.isspace(): # skip inter-token whitespace
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
112 pass
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
113 elif c in "(=,).%|+-*/": # handle simple operators
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
114 yield (c, None, pos)
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
115 elif c in '"\'': # handle quoted templates
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
116 s = pos + 1
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
117 data, pos = _parsetemplate(program, s, end, c)
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
118 yield ('template', data, s)
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
119 pos -= 1
25784
33e613687dab templater: remove processing of "string" literals from tokenizer
Yuya Nishihara <yuya@tcha.org>
parents: 25783
diff changeset
120 elif c == 'r' and program[pos:pos + 2] in ("r'", 'r"'):
33e613687dab templater: remove processing of "string" literals from tokenizer
Yuya Nishihara <yuya@tcha.org>
parents: 25783
diff changeset
121 # handle quoted strings
33e613687dab templater: remove processing of "string" literals from tokenizer
Yuya Nishihara <yuya@tcha.org>
parents: 25783
diff changeset
122 c = program[pos + 1]
33e613687dab templater: remove processing of "string" literals from tokenizer
Yuya Nishihara <yuya@tcha.org>
parents: 25783
diff changeset
123 s = pos = pos + 2
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
124 while pos < end: # find closing quote
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
125 d = program[pos]
25638
6047b60cdd09 templater: fix handling of \-escapes in raw string literals
Yuya Nishihara <yuya@tcha.org>
parents: 25637
diff changeset
126 if d == '\\': # skip over escaped characters
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
127 pos += 2
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
128 continue
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
129 if d == c:
25785
f976b7dc5e7b templater: unify "string" and "rawstring"
Yuya Nishihara <yuya@tcha.org>
parents: 25784
diff changeset
130 yield ('string', program[s:pos], s)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
131 break
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
132 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
133 else:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
134 raise error.ParseError(_("unterminated string"), s)
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
135 elif c.isdigit():
25002
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
136 s = pos
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
137 while pos < end:
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
138 d = program[pos]
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
139 if not d.isdigit():
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
140 break
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
141 pos += 1
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
142 yield ('integer', program[s:pos], s)
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
143 pos -= 1
36546
14bbb54a9c5b py3: fix type of string literals in templater.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents: 36545
diff changeset
144 elif (c == '\\' and program[pos:pos + 2] in (br"\'", br'\"')
14bbb54a9c5b py3: fix type of string literals in templater.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents: 36545
diff changeset
145 or c == 'r' and program[pos:pos + 3] in (br"r\'", br'r\"')):
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
146 # handle escaped quoted strings for compatibility with 2.9.2-3.4,
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
147 # where some of nested templates were preprocessed as strings and
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
148 # then compiled. therefore, \"...\" was allowed. (issue4733)
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
149 #
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
150 # processing flow of _evalifliteral() at 5ab28a2e9962:
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
151 # outer template string -> stringify() -> compiletemplate()
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
152 # ------------------------ ------------ ------------------
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
153 # {f("\\\\ {g(\"\\\"\")}"} \\ {g("\"")} [r'\\', {g("\"")}]
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
154 # ~~~~~~~~
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
155 # escaped quoted string
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
156 if c == 'r':
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
157 pos += 1
25785
f976b7dc5e7b templater: unify "string" and "rawstring"
Yuya Nishihara <yuya@tcha.org>
parents: 25784
diff changeset
158 token = 'string'
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
159 else:
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
160 token = 'template'
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
161 quote = program[pos:pos + 2]
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
162 s = pos = pos + 2
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
163 while pos < end: # find closing escaped quote
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
164 if program.startswith('\\\\\\', pos, end):
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
165 pos += 4 # skip over double escaped characters
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
166 continue
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
167 if program.startswith(quote, pos, end):
26215
72aad184f061 templater: create string unescape helper (issue4798)
Matt Mackall <mpm@selenic.com>
parents: 26197
diff changeset
168 # interpret as if it were a part of an outer string
26231
87c9c562c37a parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents: 26215
diff changeset
169 data = parser.unescapestr(program[s:pos])
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
170 if token == 'template':
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
171 data = _parsetemplate(data, 0, len(data))[0]
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
172 yield (token, data, s)
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
173 pos += 1
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
174 break
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
175 pos += 1
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
176 else:
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
177 raise error.ParseError(_("unterminated string"), s)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
178 elif c.isalnum() or c in '_':
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
179 s = pos
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
180 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
181 while pos < end: # find end of symbol
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
182 d = program[pos]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
183 if not (d.isalnum() or d == "_"):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
184 break
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
185 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
186 sym = program[s:pos]
18893
74ea61318ea8 templater: back out 0615b22da148, it breaks schemes ({1})
Brendan Cully <brendan@kublai.com>
parents: 18889
diff changeset
187 yield ('symbol', sym, s)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
188 pos -= 1
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
189 elif c == term:
36691
1b179d151578 templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents: 36670
diff changeset
190 yield ('end', None, pos)
25782
babd2c93bd99 templater: check existence of closing brace of template string
Yuya Nishihara <yuya@tcha.org>
parents: 25781
diff changeset
191 return
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
192 else:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
193 raise error.ParseError(_("syntax error"), pos)
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
194 pos += 1
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
195 if term:
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
196 raise error.ParseError(_("unterminated template expansion"), start)
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
197 yield ('end', None, pos)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
198
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
199 def _parsetemplate(tmpl, start, stop, quote=''):
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
200 r"""
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
201 >>> _parsetemplate(b'foo{bar}"baz', 0, 12)
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
202 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
203 >>> _parsetemplate(b'foo{bar}"baz', 0, 12, quote=b'"')
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
204 ([('string', 'foo'), ('symbol', 'bar')], 9)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
205 >>> _parsetemplate(b'foo"{bar}', 0, 9, quote=b'"')
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
206 ([('string', 'foo')], 4)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
207 >>> _parsetemplate(br'foo\"bar"baz', 0, 12, quote=b'"')
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
208 ([('string', 'foo"'), ('string', 'bar')], 9)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
209 >>> _parsetemplate(br'foo\\"bar', 0, 10, quote=b'"')
25785
f976b7dc5e7b templater: unify "string" and "rawstring"
Yuya Nishihara <yuya@tcha.org>
parents: 25784
diff changeset
210 ([('string', 'foo\\')], 6)
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
211 """
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
212 parsed = []
36244
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
213 for typ, val, pos in _scantemplate(tmpl, start, stop, quote):
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
214 if typ == 'string':
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
215 parsed.append((typ, val))
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
216 elif typ == 'template':
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
217 parsed.append(val)
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
218 elif typ == 'end':
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
219 return parsed, pos
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
220 else:
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
221 raise error.ProgrammingError('unexpected type: %s' % typ)
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
222 raise error.ProgrammingError('unterminated scanning of template')
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
223
36509
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
224 def scantemplate(tmpl, raw=False):
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
225 r"""Scan (type, start, end) positions of outermost elements in template
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
226
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
227 If raw=True, a backslash is not taken as an escape character just like
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
228 r'' string in Python. Note that this is different from r'' literal in
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
229 template in that no template fragment can appear in r'', e.g. r'{foo}'
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
230 is a literal '{foo}', but ('{foo}', raw=True) is a template expression
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
231 'foo'.
36245
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
232
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
233 >>> list(scantemplate(b'foo{bar}"baz'))
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
234 [('string', 0, 3), ('template', 3, 8), ('string', 8, 12)]
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
235 >>> list(scantemplate(b'outer{"inner"}outer'))
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
236 [('string', 0, 5), ('template', 5, 14), ('string', 14, 19)]
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
237 >>> list(scantemplate(b'foo\\{escaped}'))
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
238 [('string', 0, 5), ('string', 5, 13)]
36509
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
239 >>> list(scantemplate(b'foo\\{escaped}', raw=True))
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
240 [('string', 0, 4), ('template', 4, 13)]
36245
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
241 """
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
242 last = None
36509
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
243 for typ, val, pos in _scantemplate(tmpl, 0, len(tmpl), raw=raw):
36245
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
244 if last:
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
245 yield last + (pos,)
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
246 if typ == 'end':
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
247 return
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
248 else:
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
249 last = (typ, pos)
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
250 raise error.ProgrammingError('unterminated scanning of template')
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36244
diff changeset
251
36509
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
252 def _scantemplate(tmpl, start, stop, quote='', raw=False):
36244
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
253 """Parse template string into chunks of strings and template expressions"""
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
254 sepchars = '{' + quote
36509
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36500
diff changeset
255 unescape = [parser.unescapestr, pycompat.identity][raw]
25781
82c918509ef5 templater: extract function that parses template string
Yuya Nishihara <yuya@tcha.org>
parents: 25780
diff changeset
256 pos = start
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25599
diff changeset
257 p = parser.parser(elements)
36669
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
258 try:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
259 while pos < stop:
38085
e887381e2976 py3: bytestr() bytes to get bytechar while iterating on it
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37501
diff changeset
260 n = min((tmpl.find(c, pos, stop)
e887381e2976 py3: bytestr() bytes to get bytechar while iterating on it
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37501
diff changeset
261 for c in pycompat.bytestr(sepchars)),
36669
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
262 key=lambda n: (n < 0, n))
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
263 if n < 0:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
264 yield ('string', unescape(tmpl[pos:stop]), pos)
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
265 pos = stop
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
266 break
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
267 c = tmpl[n:n + 1]
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
268 bs = 0 # count leading backslashes
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
269 if not raw:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
270 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
271 if bs % 2 == 1:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
272 # escaped (e.g. '\{', '\\\{', but not '\\{')
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
273 yield ('string', unescape(tmpl[pos:n - 1]) + c, pos)
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
274 pos = n + 1
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
275 continue
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
276 if n > pos:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
277 yield ('string', unescape(tmpl[pos:n]), pos)
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
278 if c == quote:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
279 yield ('end', None, n + 1)
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
280 return
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
281
36669
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
282 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop, '}'))
36691
1b179d151578 templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents: 36670
diff changeset
283 if not tmpl.startswith('}', pos):
36669
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
284 raise error.ParseError(_("invalid token"), pos)
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
285 yield ('template', parseres, n)
36691
1b179d151578 templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents: 36670
diff changeset
286 pos += 1
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
287
36669
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
288 if quote:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
289 raise error.ParseError(_("unterminated string"), start)
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
290 except error.ParseError as inst:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
291 if len(inst.args) > 1: # has location
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
292 loc = inst.args[1]
36670
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
293 # Offset the caret location by the number of newlines before the
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
294 # location of the error, since we will replace one-char newlines
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
295 # with the two-char literal r'\n'.
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
296 offset = tmpl[:loc].count('\n')
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
297 tmpl = tmpl.replace('\n', br'\n')
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
298 # We want the caret to point to the place in the template that
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
299 # failed to parse, but in a hint we get a open paren at the
36691
1b179d151578 templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents: 36670
diff changeset
300 # start. Therefore, we print "loc + 1" spaces (instead of "loc")
36670
44048f1bcee5 templater: provide hint for multi-line templates with parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 36669
diff changeset
301 # to line up the caret with the location of the error.
36691
1b179d151578 templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents: 36670
diff changeset
302 inst.hint = (tmpl + '\n'
1b179d151578 templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents: 36670
diff changeset
303 + ' ' * (loc + 1 + offset) + '^ ' + _('here'))
36669
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36648
diff changeset
304 raise
36244
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
305 yield ('end', None, pos)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
306
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
307 def _unnesttemplatelist(tree):
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
308 """Expand list of templates to node tuple
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
309
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
310 >>> def f(tree):
34137
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
311 ... print(pycompat.sysstr(prettyformat(_unnesttemplatelist(tree))))
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
312 >>> f((b'template', []))
34073
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34071
diff changeset
313 (string '')
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
314 >>> f((b'template', [(b'string', b'foo')]))
34073
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34071
diff changeset
315 (string 'foo')
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
316 >>> f((b'template', [(b'string', b'foo'), (b'symbol', b'rev')]))
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
317 (template
34073
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34071
diff changeset
318 (string 'foo')
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34071
diff changeset
319 (symbol 'rev'))
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
320 >>> f((b'template', [(b'symbol', b'rev')])) # template(rev) -> str
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
321 (template
34073
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34071
diff changeset
322 (symbol 'rev'))
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
323 >>> f((b'template', [(b'template', [(b'string', b'foo')])]))
34073
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34071
diff changeset
324 (string 'foo')
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
325 """
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
326 if not isinstance(tree, tuple):
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
327 return tree
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
328 op = tree[0]
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
329 if op != 'template':
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
330 return (op,) + tuple(_unnesttemplatelist(x) for x in tree[1:])
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
331
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
332 assert len(tree) == 2
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
333 xs = tuple(_unnesttemplatelist(x) for x in tree[1])
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
334 if not xs:
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
335 return ('string', '') # empty template ""
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
336 elif len(xs) == 1 and xs[0][0] == 'string':
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
337 return xs[0] # fast path for string with no template fragment "x"
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
338 else:
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
339 return (op,) + xs
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
340
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
341 def parse(tmpl):
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
342 """Parse template string into tree"""
25781
82c918509ef5 templater: extract function that parses template string
Yuya Nishihara <yuya@tcha.org>
parents: 25780
diff changeset
343 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
344 assert pos == len(tmpl), 'unquoted template should be consumed'
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
345 return _unnesttemplatelist(('template', parsed))
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
346
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
347 def _parseexpr(expr):
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
348 """Parse a template expression into tree
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
349
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
350 >>> _parseexpr(b'"foo"')
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
351 ('string', 'foo')
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
352 >>> _parseexpr(b'foo(bar)')
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
353 ('func', ('symbol', 'foo'), ('symbol', 'bar'))
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
354 >>> _parseexpr(b'foo(')
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
355 Traceback (most recent call last):
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
356 ...
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
357 ParseError: ('not a prefix: end', 4)
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
358 >>> _parseexpr(b'"foo" "bar"')
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
359 Traceback (most recent call last):
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
360 ...
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
361 ParseError: ('invalid token', 7)
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
362 """
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
363 p = parser.parser(elements)
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
364 tree, pos = p.parse(tokenize(expr, 0, len(expr)))
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
365 if pos != len(expr):
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
366 raise error.ParseError(_('invalid token'), pos)
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
367 return _unnesttemplatelist(tree)
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
368
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
369 def prettyformat(tree):
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
370 return parser.prettyformat(tree, ('integer', 'string', 'symbol'))
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
371
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
372 def compileexp(exp, context, curmethods):
28956
eea98190ed73 templater: inline compiletemplate() function into engine
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
373 """Compile parsed template tree to (func, data) pair"""
35744
8685192a8733 templater: fix crash by empty group expression
Yuya Nishihara <yuya@tcha.org>
parents: 35680
diff changeset
374 if not exp:
8685192a8733 templater: fix crash by empty group expression
Yuya Nishihara <yuya@tcha.org>
parents: 35680
diff changeset
375 raise error.ParseError(_("missing argument"))
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
376 t = exp[0]
40618
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
377 return curmethods[t](exp, context)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
378
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
379 # template evaluation
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
380
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
381 def getsymbol(exp):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
382 if exp[0] == 'symbol':
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
383 return exp[1]
21822
028a48105191 templater: add symbol to error
Ryan McElroy <rmcelroy@fb.com>
parents: 21821
diff changeset
384 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
385
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
386 def getlist(x):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
387 if not x:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
388 return []
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
389 if x[0] == 'list':
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
390 return getlist(x[1]) + [x[2]]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
391 return [x]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
392
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
393 def gettemplate(exp, context):
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
394 """Compile given template tree or load named template from map file;
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
395 returns (func, data) pair"""
28546
1987ed32efca templater: relax type of mapped template
Yuya Nishihara <yuya@tcha.org>
parents: 28545
diff changeset
396 if exp[0] in ('template', 'string'):
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
397 return compileexp(exp, context, methods)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
398 if exp[0] == 'symbol':
25599
695b93a79d17 templater: comment that gettemplate() has different name resolution order
Yuya Nishihara <yuya@tcha.org>
parents: 25598
diff changeset
399 # unlike runsymbol(), here 'symbol' is always taken as template name
695b93a79d17 templater: comment that gettemplate() has different name resolution order
Yuya Nishihara <yuya@tcha.org>
parents: 25598
diff changeset
400 # even if it exists in mapping. this allows us to override mapping
695b93a79d17 templater: comment that gettemplate() has different name resolution order
Yuya Nishihara <yuya@tcha.org>
parents: 25598
diff changeset
401 # by web templates, e.g. 'changelogtag' is redefined in map file.
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
402 return context._load(exp[1])
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
403 raise error.ParseError(_("expected template specifier"))
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
404
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
405 def _runrecursivesymbol(context, mapping, key):
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
406 raise error.Abort(_("recursive reference '%s' in template") % key)
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
407
25596
c1975809a6b5 templater: take any string literals as template, but not for rawstring (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25595
diff changeset
408 def buildtemplate(exp, context):
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
409 ctmpl = [compileexp(e, context, methods) for e in exp[1:]]
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
410 return (templateutil.runtemplate, ctmpl)
25595
a7dd6692e5cb templater: move runtemplate function out of buildmap/runmap pair
Yuya Nishihara <yuya@tcha.org>
parents: 25580
diff changeset
411
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
412 def buildfilter(exp, context):
26104
0f1bc7faa50d templater: inline getfilter() to buildfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 25985
diff changeset
413 n = getsymbol(exp[2])
0f1bc7faa50d templater: inline getfilter() to buildfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 25985
diff changeset
414 if n in context._filters:
0f1bc7faa50d templater: inline getfilter() to buildfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 25985
diff changeset
415 filt = context._filters[n]
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
416 arg = compileexp(exp[1], context, methods)
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
417 return (templateutil.runfilter, (arg, filt))
36912
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36712
diff changeset
418 if n in context._funcs:
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36712
diff changeset
419 f = context._funcs[n]
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
420 args = _buildfuncargs(exp[1], context, methods, n, f._argspec)
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
421 return (f, args)
26104
0f1bc7faa50d templater: inline getfilter() to buildfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 25985
diff changeset
422 raise error.ParseError(_("unknown function '%s'") % n)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
423
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
424 def buildmap(exp, context):
34325
86d050abd5c1 templater: do not destructure operands in buildmap()
Yuya Nishihara <yuya@tcha.org>
parents: 34324
diff changeset
425 darg = compileexp(exp[1], context, methods)
86d050abd5c1 templater: do not destructure operands in buildmap()
Yuya Nishihara <yuya@tcha.org>
parents: 34324
diff changeset
426 targ = gettemplate(exp[2], context)
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
427 return (templateutil.runmap, (darg, targ))
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
428
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
429 def buildmember(exp, context):
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
430 darg = compileexp(exp[1], context, methods)
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
431 memb = getsymbol(exp[2])
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
432 return (templateutil.runmember, (darg, memb))
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
433
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
434 def buildnegate(exp, context):
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
435 arg = compileexp(exp[1], context, exprmethods)
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
436 return (templateutil.runnegate, arg)
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
437
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
438 def buildarithmetic(exp, context, func):
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
439 left = compileexp(exp[1], context, exprmethods)
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
440 right = compileexp(exp[2], context, exprmethods)
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
441 return (templateutil.runarithmetic, (func, left, right))
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
442
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
443 def buildfunc(exp, context):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
444 n = getsymbol(exp[1])
36912
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36712
diff changeset
445 if n in context._funcs:
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36712
diff changeset
446 f = context._funcs[n]
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
447 args = _buildfuncargs(exp[2], context, exprmethods, n, f._argspec)
14925
ab545a15d807 templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents: 14168
diff changeset
448 return (f, args)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
449 if n in context._filters:
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
450 args = _buildfuncargs(exp[2], context, exprmethods, n, argspec=None)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
451 if len(args) != 1:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
452 raise error.ParseError(_("filter %s expects one argument") % n)
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
453 f = context._filters[n]
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
454 return (templateutil.runfilter, (args[0], f))
20857
6eb55310fcbc templater: raise error for unknown func
Sean Farley <sean.michael.farley@gmail.com>
parents: 20663
diff changeset
455 raise error.ParseError(_("unknown function '%s'") % n)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
456
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
457 def _buildfuncargs(exp, context, curmethods, funcname, argspec):
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
458 """Compile parsed tree of function arguments into list or dict of
31921
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
459 (func, data) pairs
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
460
36987
4b744c7b35ce templater: fix invalid reference of runsymbol in doctest
Yuya Nishihara <yuya@tcha.org>
parents: 36983
diff changeset
461 >>> context = engine(lambda t: (templateutil.runsymbol, t))
31921
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
462 >>> def fargs(expr, argspec):
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
463 ... x = _parseexpr(expr)
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
464 ... n = getsymbol(x[1])
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
465 ... return _buildfuncargs(x[2], context, exprmethods, n, argspec)
34139
be00af4a1ac5 doctest: coerce dict.keys() to list
Yuya Nishihara <yuya@tcha.org>
parents: 34137
diff changeset
466 >>> list(fargs(b'a(l=1, k=2)', b'k l m').keys())
31922
0f41f1e3c75c parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31921
diff changeset
467 ['l', 'k']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34073
diff changeset
468 >>> args = fargs(b'a(opts=1, k=2)', b'**opts')
34139
be00af4a1ac5 doctest: coerce dict.keys() to list
Yuya Nishihara <yuya@tcha.org>
parents: 34137
diff changeset
469 >>> list(args.keys()), list(args[b'opts'].keys())
31922
0f41f1e3c75c parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31921
diff changeset
470 (['opts'], ['opts', 'k'])
31921
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
471 """
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
472 def compiledict(xs):
31922
0f41f1e3c75c parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31921
diff changeset
473 return util.sortdict((k, compileexp(x, context, curmethods))
0f41f1e3c75c parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31921
diff changeset
474 for k, x in xs.iteritems())
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
475 def compilelist(xs):
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
476 return [compileexp(x, context, curmethods) for x in xs]
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
477
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
478 if not argspec:
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
479 # filter or function with no argspec: return list of positional args
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
480 return compilelist(getlist(exp))
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
481
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
482 # function with argspec: return dict of named args
31921
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
483 _poskeys, varkey, _keys, optkey = argspec = parser.splitargspec(argspec)
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
484 treeargs = parser.buildargsdict(getlist(exp), funcname, argspec,
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
485 keyvaluenode='keyvalue', keynode='symbol')
31922
0f41f1e3c75c parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31921
diff changeset
486 compargs = util.sortdict()
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
487 if varkey:
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
488 compargs[varkey] = compilelist(treeargs.pop(varkey))
31921
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
489 if optkey:
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
490 compargs[optkey] = compiledict(treeargs.pop(optkey))
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
491 compargs.update(compiledict(treeargs))
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
492 return compargs
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
493
31885
d18b624c1c06 templater: add parsing rule for key-value pair
Yuya Nishihara <yuya@tcha.org>
parents: 31884
diff changeset
494 def buildkeyvaluepair(exp, content):
d18b624c1c06 templater: add parsing rule for key-value pair
Yuya Nishihara <yuya@tcha.org>
parents: 31884
diff changeset
495 raise error.ParseError(_("can't use a key-value pair in this context"))
d18b624c1c06 templater: add parsing rule for key-value pair
Yuya Nishihara <yuya@tcha.org>
parents: 31884
diff changeset
496
40618
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
497 def buildlist(exp, context):
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
498 raise error.ParseError(_("can't use a list in this context"),
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
499 hint=_('check place of comma and parens'))
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
500
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
501 # methods to interpret function arguments or inner expressions (e.g. {_(x)})
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
502 exprmethods = {
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
503 "integer": lambda e, c: (templateutil.runinteger, e[1]),
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
504 "string": lambda e, c: (templateutil.runstring, e[1]),
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
505 "symbol": lambda e, c: (templateutil.runsymbol, e[1]),
25596
c1975809a6b5 templater: take any string literals as template, but not for rawstring (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25595
diff changeset
506 "template": buildtemplate,
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
507 "group": lambda e, c: compileexp(e[1], c, exprmethods),
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
508 ".": buildmember,
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
509 "|": buildfilter,
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
510 "%": buildmap,
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
511 "func": buildfunc,
31885
d18b624c1c06 templater: add parsing rule for key-value pair
Yuya Nishihara <yuya@tcha.org>
parents: 31884
diff changeset
512 "keyvalue": buildkeyvaluepair,
40618
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40475
diff changeset
513 "list": buildlist,
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
514 "+": lambda e, c: buildarithmetic(e, c, lambda a, b: a + b),
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
515 "-": lambda e, c: buildarithmetic(e, c, lambda a, b: a - b),
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
516 "negate": buildnegate,
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
517 "*": lambda e, c: buildarithmetic(e, c, lambda a, b: a * b),
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
518 "/": lambda e, c: buildarithmetic(e, c, lambda a, b: a // b),
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
519 }
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
520
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
521 # methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
522 methods = exprmethods.copy()
25002
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
523 methods["integer"] = exprmethods["symbol"] # '{1}' as variable
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
524
28912
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
525 class _aliasrules(parser.basealiasrules):
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
526 """Parsing and expansion rule set of template aliases"""
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
527 _section = _('template alias')
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
528 _parse = staticmethod(_parseexpr)
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
529
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
530 @staticmethod
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
531 def _trygetfunc(tree):
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
532 """Return (name, args) if tree is func(...) or ...|filter; otherwise
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
533 None"""
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
534 if tree[0] == 'func' and tree[1][0] == 'symbol':
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
535 return tree[1][1], getlist(tree[2])
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
536 if tree[0] == '|' and tree[2][0] == 'symbol':
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
537 return tree[2][1], [tree[1]]
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
538
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
539 def expandaliases(tree, aliases):
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
540 """Return new tree of aliases are expanded"""
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
541 aliasmap = _aliasrules.buildmap(aliases)
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
542 return _aliasrules.expand(aliasmap, tree)
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
543
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
544 # template engine
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
545
24988
e8ff0b09acac templater: rename parsestring() to unquotestring() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 24987
diff changeset
546 def unquotestring(s):
28630
bf35644b9f3a templater: relax unquotestring() to fall back to bare string
Yuya Nishihara <yuya@tcha.org>
parents: 28628
diff changeset
547 '''unwrap quotes if any; otherwise returns unmodified string'''
28687
29c249dfb4ef templater: do not strip non-quote characters from template config
Yuya Nishihara <yuya@tcha.org>
parents: 28630
diff changeset
548 if len(s) < 2 or s[0] not in "'\"" or s[0] != s[-1]:
28630
bf35644b9f3a templater: relax unquotestring() to fall back to bare string
Yuya Nishihara <yuya@tcha.org>
parents: 28628
diff changeset
549 return s
25696
c1cac25ad1a6 templater: remove workaround for escaped quoted string in quoted template
Yuya Nishihara <yuya@tcha.org>
parents: 25695
diff changeset
550 return s[1:-1]
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
551
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
552 class resourcemapper(object):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
553 """Mapper of internal template resources"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
554
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
555 __metaclass__ = abc.ABCMeta
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
556
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
557 @abc.abstractmethod
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38440
diff changeset
558 def availablekeys(self, mapping):
37075
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
559 """Return a set of available resource keys based on the given mapping"""
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
560
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
561 @abc.abstractmethod
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
562 def knownkeys(self):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
563 """Return a set of supported resource keys"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
564
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
565 @abc.abstractmethod
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38440
diff changeset
566 def lookup(self, mapping, key):
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
567 """Return a resource for the key if available; otherwise None"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
568
37102
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
569 @abc.abstractmethod
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
570 def populatemap(self, context, origmapping, newmapping):
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
571 """Return a dict of additional mapping items which should be paired
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
572 with the given new mapping"""
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
573
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
574 class nullresourcemapper(resourcemapper):
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38440
diff changeset
575 def availablekeys(self, mapping):
37075
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
576 return set()
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
577
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
578 def knownkeys(self):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
579 return set()
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
580
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38440
diff changeset
581 def lookup(self, mapping, key):
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
582 return None
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
583
37102
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
584 def populatemap(self, context, origmapping, newmapping):
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
585 return {}
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
586
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
587 class engine(object):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
588 '''template expansion engine.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
589
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
590 template expansion works like this. a map file contains key=value
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
591 pairs. if value is quoted, it is treated as string. otherwise, it
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
592 is treated as name of template file.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
593
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
594 templater is asked to expand a key in map. it looks up key, and
4334
66a3fe30f9fc minor typo fix in templater's docstring
TK Soh <teekaysoh@yahoo.com>
parents: 3904
diff changeset
595 looks for strings like this: {foo}. it expands {foo} by looking up
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
596 foo in map, and substituting it. expansion is recursive: it stops
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
597 when there is no more {foo} to replace.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
598
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
599 expansion also allows formatting and filtering.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
600
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
601 format uses key to expand each item in list. syntax is
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
602 {key%format}.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
603
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
604 filter uses function to transform value. syntax is
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
605 {key|filter1|filter2|...}.'''
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
606
38354
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
607 def __init__(self, loader, filters=None, defaults=None, resources=None):
10848
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
608 self._loader = loader
26330
ec4f3755d997 templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26234
diff changeset
609 if filters is None:
ec4f3755d997 templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26234
diff changeset
610 filters = {}
10848
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
611 self._filters = filters
36922
521f6c7e1756 templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
612 self._funcs = templatefuncs.funcs # make this a parameter if needed
26331
2c6a741bf05e templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26330
diff changeset
613 if defaults is None:
2c6a741bf05e templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26330
diff changeset
614 defaults = {}
35468
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35467
diff changeset
615 if resources is None:
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
616 resources = nullresourcemapper()
10848
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
617 self._defaults = defaults
35468
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35467
diff changeset
618 self._resources = resources
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
619 self._cache = {} # key: (func, data)
37398
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
620 self._tmplcache = {} # literal template: (func, data)
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
621
37074
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
622 def overlaymap(self, origmapping, newmapping):
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
623 """Create combined mapping from the original mapping and partial
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
624 mapping to override the original"""
37075
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
625 # do not copy symbols which overrides the defaults depending on
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
626 # new resources, so the defaults will be re-evaluated (issue5612)
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
627 knownres = self._resources.knownkeys()
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38440
diff changeset
628 newres = self._resources.availablekeys(newmapping)
37075
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
629 mapping = {k: v for k, v in origmapping.iteritems()
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
630 if (k in knownres # not a symbol per self.symbol()
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
631 or newres.isdisjoint(self._defaultrequires(k)))}
37074
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
632 mapping.update(newmapping)
37102
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
633 mapping.update(
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
634 self._resources.populatemap(self, origmapping, newmapping))
37074
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
635 return mapping
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
636
37075
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
637 def _defaultrequires(self, key):
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
638 """Resource keys required by the specified default symbol function"""
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
639 v = self._defaults.get(key)
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
640 if v is None or not callable(v):
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
641 return ()
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
642 return getattr(v, '_requires', ())
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37074
diff changeset
643
35467
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
644 def symbol(self, mapping, key):
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
645 """Resolve symbol to value or function; None if nothing found"""
35470
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35468
diff changeset
646 v = None
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37070
diff changeset
647 if key not in self._resources.knownkeys():
35470
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35468
diff changeset
648 v = mapping.get(key)
35467
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
649 if v is None:
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
650 v = self._defaults.get(key)
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
651 return v
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
652
37501
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
653 def availableresourcekeys(self, mapping):
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
654 """Return a set of available resource keys based on the given mapping"""
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38440
diff changeset
655 return self._resources.availablekeys(mapping)
37501
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
656
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
657 def knownresourcekeys(self):
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
658 """Return a set of supported resource keys"""
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
659 return self._resources.knownkeys()
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
660
35467
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
661 def resource(self, mapping, key):
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
662 """Return internal data (e.g. cache) used for keyword/function
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
663 evaluation"""
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38440
diff changeset
664 v = self._resources.lookup(mapping, key)
35468
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35467
diff changeset
665 if v is None:
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
666 raise templateutil.ResourceUnavailable(
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
667 _('template resource not available: %s') % key)
35468
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35467
diff changeset
668 return v
35467
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35414
diff changeset
669
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
670 def _load(self, t):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
671 '''load, parse, and cache a template'''
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
672 if t not in self._cache:
38354
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
673 x = self._loader(t)
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
674 # put poison to cut recursion while compiling 't'
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
675 self._cache[t] = (_runrecursivesymbol, t)
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
676 try:
28956
eea98190ed73 templater: inline compiletemplate() function into engine
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
677 self._cache[t] = compileexp(x, self, methods)
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
678 except: # re-raises
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
679 del self._cache[t]
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
680 raise
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
681 return self._cache[t]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
682
37398
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
683 def _parse(self, tmpl):
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
684 """Parse and cache a literal template"""
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
685 if tmpl not in self._tmplcache:
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
686 x = parse(tmpl)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
687 self._tmplcache[tmpl] = compileexp(x, self, methods)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
688 return self._tmplcache[tmpl]
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
689
37067
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
690 def preload(self, t):
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
691 """Load, parse, and cache the specified template if available"""
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
692 try:
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
693 self._load(t)
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
694 return True
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
695 except templateutil.TemplateNotFound:
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
696 return False
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
697
10853
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
698 def process(self, t, mapping):
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
699 '''Perform expansion. t is name of map element to expand.
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
700 mapping contains added elements for use during expansion. Is a
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
701 generator.'''
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
702 func, data = self._load(t)
37398
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
703 return self._expand(func, data, mapping)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
704
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
705 def expand(self, tmpl, mapping):
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
706 """Perform expansion over a literal template
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
707
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
708 No user aliases will be expanded since this is supposed to be called
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
709 with an internal template string.
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
710 """
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
711 func, data = self._parse(tmpl)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
712 return self._expand(func, data, mapping)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
713
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37272
diff changeset
714 def _expand(self, func, data, mapping):
37102
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
715 # populate additional items only if they don't exist in the given
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
716 # mapping. this is slightly different from overlaymap() because the
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
717 # initial 'revcache' may contain pre-computed items.
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
718 extramapping = self._resources.populatemap(self, {}, mapping)
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
719 if extramapping:
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
720 extramapping.update(mapping)
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
721 mapping = extramapping
37272
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37159
diff changeset
722 return templateutil.flatten(self, mapping, func(self, mapping, data))
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
723
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
724 def stylelist():
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
725 paths = templatepaths()
20312
268a5ab5c27b templater: selecting a style with no templates does not crash (issue4140)
Simon Heimberg <simohe@besonet.ch>
parents: 20067
diff changeset
726 if not paths:
268a5ab5c27b templater: selecting a style with no templates does not crash (issue4140)
Simon Heimberg <simohe@besonet.ch>
parents: 20067
diff changeset
727 return _('no templates found, try `hg debuginstall` for more info')
27637
b502138f5faa cleanup: remove superfluous space after space after equals (python)
timeless <timeless@mozdev.org>
parents: 27293
diff changeset
728 dirlist = os.listdir(paths[0])
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
729 stylelist = []
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
730 for file in dirlist:
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
731 split = file.split(".")
28403
d2e154dddb6e templater: ignore orig/rej files
timeless <timeless@mozdev.org>
parents: 28384
diff changeset
732 if split[-1] in ('orig', 'rej'):
d2e154dddb6e templater: ignore orig/rej files
timeless <timeless@mozdev.org>
parents: 28384
diff changeset
733 continue
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
734 if split[0] == "map-cmdline":
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
735 stylelist.append(split[1])
19127
d982edcfe7f0 templater: fix output instability from gsoc patches
Augie Fackler <raf@durin42.com>
parents: 19125
diff changeset
736 return ", ".join(sorted(stylelist))
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
737
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
738 def _readmapfile(mapfile):
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
739 """Load template elements from the given map file"""
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
740 if not os.path.exists(mapfile):
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
741 raise error.Abort(_("style '%s' not found") % mapfile,
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
742 hint=_("available styles: %s") % stylelist())
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
743
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
744 base = os.path.dirname(mapfile)
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
745 conf = config.config(includepaths=templatepaths())
34714
f4aeb952ab77 templater: load template fragments from [templates] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34712
diff changeset
746 conf.read(mapfile, remap={'': 'templates'})
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
747
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
748 cache = {}
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
749 tmap = {}
34715
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34714
diff changeset
750 aliases = []
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
751
34714
f4aeb952ab77 templater: load template fragments from [templates] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34712
diff changeset
752 val = conf.get('templates', '__base__')
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
753 if val and val[0] not in "'\"":
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
754 # treat as a pointer to a base class for this style
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
755 path = util.normpath(os.path.join(base, val))
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
756
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
757 # fallback check in template paths
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
758 if not os.path.exists(path):
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
759 for p in templatepaths():
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
760 p2 = util.normpath(os.path.join(p, val))
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
761 if os.path.isfile(p2):
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
762 path = p2
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
763 break
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
764 p3 = util.normpath(os.path.join(p2, "map"))
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
765 if os.path.isfile(p3):
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
766 path = p3
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
767 break
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
768
34715
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34714
diff changeset
769 cache, tmap, aliases = _readmapfile(path)
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
770
34714
f4aeb952ab77 templater: load template fragments from [templates] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34712
diff changeset
771 for key, val in conf['templates'].items():
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
772 if not val:
34714
f4aeb952ab77 templater: load template fragments from [templates] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34712
diff changeset
773 raise error.ParseError(_('missing value'),
f4aeb952ab77 templater: load template fragments from [templates] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34712
diff changeset
774 conf.source('templates', key))
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
775 if val[0] in "'\"":
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
776 if val[0] != val[-1]:
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
777 raise error.ParseError(_('unmatched quotes'),
34714
f4aeb952ab77 templater: load template fragments from [templates] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34712
diff changeset
778 conf.source('templates', key))
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
779 cache[key] = unquotestring(val)
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
780 elif key != '__base__':
38353
48289eafb37d templater: drop extension point of engine classes (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
781 tmap[key] = os.path.join(base, val)
34715
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34714
diff changeset
782 aliases.extend(conf['templatealias'].items())
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34714
diff changeset
783 return cache, tmap, aliases
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
784
38438
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
785 class loader(object):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
786 """Load template fragments optionally from a map file"""
35481
964510dcdc2a templater: rewrite docstring of templater.__init__()
Yuya Nishihara <yuya@tcha.org>
parents: 35470
diff changeset
787
38438
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
788 def __init__(self, cache, aliases):
26334
0a5a774f5956 templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26333
diff changeset
789 if cache is None:
0a5a774f5956 templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26333
diff changeset
790 cache = {}
1975
6e1a8ea5d717 Duplicate cache when creating templater.
Shun-ichi Goto <shunichi.goto@gmail.com>
parents: 1964
diff changeset
791 self.cache = cache.copy()
38351
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
792 self._map = {}
38354
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
793 self._aliasmap = _aliasrules.buildmap(aliases)
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
794
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
795 def __contains__(self, key):
38351
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
796 return key in self.cache or key in self._map
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
797
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
798 def load(self, t):
38354
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
799 """Get parsed tree for the given template name. Use a local cache."""
16686
67964cda8701 cleanup: "not x in y" -> "x not in y"
Brodie Rao <brodie@sf.io>
parents: 14944
diff changeset
800 if t not in self.cache:
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
801 try:
38353
48289eafb37d templater: drop extension point of engine classes (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
802 self.cache[t] = util.readfile(self._map[t])
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
803 except KeyError as inst:
36913
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
804 raise templateutil.TemplateNotFound(
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36912
diff changeset
805 _('"%s" not in template map') % inst.args[0])
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
806 except IOError as inst:
36500
43e108027b0d py3: move between bytes and unicode when re-raising IOError
Yuya Nishihara <yuya@tcha.org>
parents: 36445
diff changeset
807 reason = (_('template file %s: %s')
38353
48289eafb37d templater: drop extension point of engine classes (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38352
diff changeset
808 % (self._map[t],
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37075
diff changeset
809 stringutil.forcebytestr(inst.args[1])))
36500
43e108027b0d py3: move between bytes and unicode when re-raising IOError
Yuya Nishihara <yuya@tcha.org>
parents: 36445
diff changeset
810 raise IOError(inst.args[0], encoding.strfromlocal(reason))
38354
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
811 return self._parse(self.cache[t])
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
812
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
813 def _parse(self, tmpl):
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
814 x = parse(tmpl)
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
815 if self._aliasmap:
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
816 x = _aliasrules.expand(self._aliasmap, x)
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38353
diff changeset
817 return x
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
818
38355
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
819 def _findsymbolsused(self, tree, syms):
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
820 if not tree:
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
821 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
822 op = tree[0]
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
823 if op == 'symbol':
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
824 s = tree[1]
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
825 if s in syms[0]:
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
826 return # avoid recursion: s -> cache[s] -> s
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
827 syms[0].add(s)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
828 if s in self.cache or s in self._map:
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
829 # s may be a reference for named template
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
830 self._findsymbolsused(self.load(s), syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
831 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
832 if op in {'integer', 'string'}:
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
833 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
834 # '{arg|func}' == '{func(arg)}'
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
835 if op == '|':
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
836 syms[1].add(getsymbol(tree[2]))
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
837 self._findsymbolsused(tree[1], syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
838 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
839 if op == 'func':
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
840 syms[1].add(getsymbol(tree[1]))
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
841 self._findsymbolsused(tree[2], syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
842 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
843 for x in tree[1:]:
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
844 self._findsymbolsused(x, syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
845
38438
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
846 def symbolsused(self, t):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
847 """Look up (keywords, filters/functions) referenced from the name
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
848 template 't'
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
849
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
850 This may load additional templates from the map file.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
851 """
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
852 syms = (set(), set())
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
853 self._findsymbolsused(self.load(t), syms)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
854 return syms
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
855
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
856 class templater(object):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
857
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
858 def __init__(self, filters=None, defaults=None, resources=None,
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
859 cache=None, aliases=(), minchunk=1024, maxchunk=65536):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
860 """Create template engine optionally with preloaded template fragments
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
861
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
862 - ``filters``: a dict of functions to transform a value into another.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
863 - ``defaults``: a dict of symbol values/functions; may be overridden
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
864 by a ``mapping`` dict.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
865 - ``resources``: a resourcemapper object to look up internal data
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
866 (e.g. cache), inaccessible from user template.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
867 - ``cache``: a dict of preloaded template fragments.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
868 - ``aliases``: a list of alias (name, replacement) pairs.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
869
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
870 self.cache may be updated later to register additional template
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
871 fragments.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
872 """
38440
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
873 allfilters = templatefilters.filters.copy()
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
874 if filters:
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
875 allfilters.update(filters)
38438
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
876 self._loader = loader(cache, aliases)
38440
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
877 self._proc = engine(self._loader.load, allfilters, defaults, resources)
38438
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
878 self._minchunk, self._maxchunk = minchunk, maxchunk
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
879
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
880 @classmethod
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
881 def frommapfile(cls, mapfile, filters=None, defaults=None, resources=None,
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
882 cache=None, minchunk=1024, maxchunk=65536):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
883 """Create templater from the specified map file"""
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
884 t = cls(filters, defaults, resources, cache, [], minchunk, maxchunk)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
885 cache, tmap, aliases = _readmapfile(mapfile)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
886 t._loader.cache.update(cache)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
887 t._loader._map = tmap
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
888 t._loader._aliasmap = _aliasrules.buildmap(aliases)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
889 return t
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
890
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
891 def __contains__(self, key):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
892 return key in self._loader
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
893
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
894 @property
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
895 def cache(self):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
896 return self._loader.cache
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
897
38440
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
898 # for highlight extension to insert one-time 'colorize' filter
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
899 @property
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
900 def _filters(self):
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
901 return self._proc._filters
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
902
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
903 @property
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
904 def defaults(self):
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
905 return self._proc._defaults
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38439
diff changeset
906
38438
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
907 def load(self, t):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
908 """Get parsed tree for the given template name. Use a local cache."""
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
909 return self._loader.load(t)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
910
38355
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
911 def symbolsuseddefault(self):
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
912 """Look up (keywords, filters/functions) referenced from the default
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
913 unnamed template
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
914
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
915 This may load additional templates from the map file.
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
916 """
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
917 return self.symbolsused('')
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
918
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
919 def symbolsused(self, t):
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
920 """Look up (keywords, filters/functions) referenced from the name
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
921 template 't'
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
922
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
923 This may load additional templates from the map file.
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
924 """
38438
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38355
diff changeset
925 return self._loader.symbolsused(t)
38355
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38354
diff changeset
926
36988
317382151ac3 templater: rename .render(mapping) to .renderdefault(mapping) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36987
diff changeset
927 def renderdefault(self, mapping):
32873
2ecce24dfcd3 templater: add simple interface for unnamed template (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32684
diff changeset
928 """Render the default unnamed template and return result as string"""
36989
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36988
diff changeset
929 return self.render('', mapping)
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36988
diff changeset
930
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36988
diff changeset
931 def render(self, t, mapping):
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36988
diff changeset
932 """Render the specified named template and return result as string"""
37159
b56b79185aad templater: do not use stringify() to concatenate flattened template output
Yuya Nishihara <yuya@tcha.org>
parents: 37157
diff changeset
933 return b''.join(self.generate(t, mapping))
32873
2ecce24dfcd3 templater: add simple interface for unnamed template (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32684
diff changeset
934
37019
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37014
diff changeset
935 def generate(self, t, mapping):
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37014
diff changeset
936 """Return a generator that renders the specified named template and
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37014
diff changeset
937 yields chunks"""
38439
256581484c7f templater: resurrect cache of engine instance
Yuya Nishihara <yuya@tcha.org>
parents: 38438
diff changeset
938 stream = self._proc.process(t, mapping)
38351
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
939 if self._minchunk:
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
940 stream = util.increasingchunks(stream, min=self._minchunk,
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
941 max=self._maxchunk)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
942 return stream
7434
cf7741aa1e96 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7396
diff changeset
943
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
944 def templatepaths():
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
945 '''return locations used for template files.'''
22636
d844e220792a templater: don't search randomly for templates - trust util.datapath
Mads Kiilerich <madski@unity3d.com>
parents: 22635
diff changeset
946 pathsrel = ['templates']
22635
660861a6fad4 templater: inline global 'path' list in templatepaths
Mads Kiilerich <madski@unity3d.com>
parents: 22634
diff changeset
947 paths = [os.path.normpath(os.path.join(util.datapath, f))
660861a6fad4 templater: inline global 'path' list in templatepaths
Mads Kiilerich <madski@unity3d.com>
parents: 22634
diff changeset
948 for f in pathsrel]
660861a6fad4 templater: inline global 'path' list in templatepaths
Mads Kiilerich <madski@unity3d.com>
parents: 22634
diff changeset
949 return [p for p in paths if os.path.isdir(p)]
2189
e3eba577a0ae move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2001
diff changeset
950
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
951 def templatepath(name):
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
952 '''return location of template file. returns None if not found.'''
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
953 for p in templatepaths():
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
954 f = os.path.join(p, name)
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
955 if os.path.exists(f):
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
956 return f
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
957 return None
2189
e3eba577a0ae move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2001
diff changeset
958
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
959 def stylemap(styles, paths=None):
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
960 """Return path to mapfile for a given style.
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
961
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
962 Searches mapfile in the following locations:
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
963 1. templatepath/style/map
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
964 2. templatepath/map-style
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
965 3. templatepath/map
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
966 """
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
967
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
968 if paths is None:
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
969 paths = templatepaths()
36550
7f6be7121b28 py3: replace type 'str' by 'bytes' in templater.py
Yuya Nishihara <yuya@tcha.org>
parents: 36546
diff changeset
970 elif isinstance(paths, bytes):
8223
02145b700fe4 templater: fix little problem from stylemap() changes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8218
diff changeset
971 paths = [paths]
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
972
36550
7f6be7121b28 py3: replace type 'str' by 'bytes' in templater.py
Yuya Nishihara <yuya@tcha.org>
parents: 36546
diff changeset
973 if isinstance(styles, bytes):
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
974 styles = [styles]
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
975
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
976 for style in styles:
24296
b73a22d1d9bf hgweb: prevent loading style map from directories other than specified paths
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
977 # only plain name is allowed to honor template paths
b73a22d1d9bf hgweb: prevent loading style map from directories other than specified paths
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
978 if (not style
36648
6585ac350fd9 py3: make os.curdir a bytes
Yuya Nishihara <yuya@tcha.org>
parents: 36647
diff changeset
979 or style in (pycompat.oscurdir, pycompat.ospardir)
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
980 or pycompat.ossep in style
30625
bcf4a975f93d py3: replace os.altsep with pycompat.altsep
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30615
diff changeset
981 or pycompat.osaltsep and pycompat.osaltsep in style):
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
982 continue
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
983 locations = [os.path.join(style, 'map'), 'map-' + style]
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
984 locations.append('map')
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
985
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
986 for path in paths:
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
987 for location in locations:
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
988 mapfile = os.path.join(path, location)
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
989 if os.path.isfile(mapfile):
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
990 return style, mapfile
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
991
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
992 raise RuntimeError("No hgweb templates found in %r" % paths)