annotate mercurial/templater.py @ 48813:2bb75c65fa6c stable

ci: use the `v1.0` flavor of the docker images in the CI This new versioning will help us to maintain backward compatibility in the docker image. This will be useful to deal with mismatch between default/stable in version and the re-run CI on older changesets in the future. Once this changeset land on stable, we will have to merge it in default. Then we can start make backward incompatible changes in a new image version. Differential Revision: https://phab.mercurial-scm.org/D12388
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 18 Mar 2022 18:09:46 +0100
parents 2b76255a4f74
children 6000f5b25c9b
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 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Rapha?l Gom?s <rgomes@octobus.net>
parents: 46492
diff changeset
3 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
1909
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
37017
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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: 36992
diff changeset
9
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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: 36992
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: 36992
diff changeset
12 such as ``cmdutil.rendertemplate(ctx, tmpl)``.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
13
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
14 Internal Data Types
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
15 -------------------
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
16
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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: 36992
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: 36992
diff changeset
19 of the following data types:
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
20
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
21 bytes
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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: 36992
diff changeset
23
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
24 generator
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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: 36992
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: 36992
diff changeset
27 or ``flatten()``.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
28
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
29 None
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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: 36992
diff changeset
31
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
32 True, False, int, float
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
33 can be stringified as such.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
34
38238
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38237
diff changeset
35 wrappedbytes, wrappedvalue
7824783a6d5e templater: add wrapped types for pure non-list/dict values
Yuya Nishihara <yuya@tcha.org>
parents: 38237
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: 38237
diff changeset
37
38297
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38295
diff changeset
38 date
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 38295
diff changeset
39 represents a (unixtime, offset) tuple.
37017
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
40
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
41 hybrid
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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: 36992
diff changeset
43 to mappings by % operator.
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
44
38295
0e0d03d09ecd templater: rename mappable to hybriditem as it is the primary use case
Yuya Nishihara <yuya@tcha.org>
parents: 38238
diff changeset
45 hybriditem
37017
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
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
44597
fc1fa3a07af6 templater: introduce wrapper for smartset (API)
Yuya Nishihara <yuya@tcha.org>
parents: 43715
diff changeset
48 revslist
fc1fa3a07af6 templater: introduce wrapper for smartset (API)
Yuya Nishihara <yuya@tcha.org>
parents: 43715
diff changeset
49 represents a list of revision numbers.
fc1fa3a07af6 templater: introduce wrapper for smartset (API)
Yuya Nishihara <yuya@tcha.org>
parents: 43715
diff changeset
50
37399
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37398
diff changeset
51 mappinggenerator, mappinglist
0b64416224d9 templater: add class representing a nested mappings
Yuya Nishihara <yuya@tcha.org>
parents: 37398
diff changeset
52 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
53 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
54
40525
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39598
diff changeset
55 mappingdict
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39598
diff changeset
56 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: 39598
diff changeset
57 format.
8fa26f3baf30 templater: add wrapper for a single template mapping
Yuya Nishihara <yuya@tcha.org>
parents: 39598
diff changeset
58
40952
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40662
diff changeset
59 mappingnone
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40662
diff changeset
60 represents None of Optional[mappable], which will be mapped to an empty
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40662
diff changeset
61 string by % operation.
4591c9791a82 templatefuncs: specialize "no match" value of search() to allow % operation
Yuya Nishihara <yuya@tcha.org>
parents: 40662
diff changeset
62
37499
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37399
diff changeset
63 mappedgenerator
75c13343cf38 templater: wrap result of '%' operation so it never looks like a thunk
Yuya Nishihara <yuya@tcha.org>
parents: 37399
diff changeset
64 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
65 operation.
37017
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
66 """
a5311d7f4af8 templater: add brief doc about internal data types
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
67
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
68 from __future__ import absolute_import, print_function
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
69
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
70 import abc
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
71 import os
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
72
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
73 from .i18n import _
47852
2b76255a4f74 template: FileNotFoundError is actually a built in exception
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47831
diff changeset
74 from .pycompat import (
2b76255a4f74 template: FileNotFoundError is actually a built in exception
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47831
diff changeset
75 FileNotFoundError,
2b76255a4f74 template: FileNotFoundError is actually a built in exception
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47831
diff changeset
76 getattr,
2b76255a4f74 template: FileNotFoundError is actually a built in exception
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47831
diff changeset
77 )
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
78 from . import (
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
79 config,
31526
6f150bb19317 templater: make pad() compute actual width
Yuya Nishihara <yuya@tcha.org>
parents: 31525
diff changeset
80 encoding,
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
81 error,
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
82 parser,
30620
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30342
diff changeset
83 pycompat,
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
84 templatefilters,
36928
521f6c7e1756 templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
85 templatefuncs,
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
86 templateutil,
25985
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
87 util,
7eb357b5f774 templater: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
88 )
43715
5be909dbe385 util: remove datapath and swith users over to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43522
diff changeset
89 from .utils import (
5be909dbe385 util: remove datapath and swith users over to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43522
diff changeset
90 resourceutil,
5be909dbe385 util: remove datapath and swith users over to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43522
diff changeset
91 stringutil,
5be909dbe385 util: remove datapath and swith users over to resourceutil
Martin von Zweigbergk <martinvonz@google.com>
parents: 43522
diff changeset
92 )
36473
8dbd97aef915 templater: move specialized exception types to top
Yuya Nishihara <yuya@tcha.org>
parents: 36278
diff changeset
93
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
94 # template parsing
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
95
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
96 elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
97 # token-type: binding-strength, primary, prefix, infix, suffix
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
98 b"(": (20, None, (b"group", 1, b")"), (b"func", 1, b")"), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
99 b".": (18, None, None, (b".", 18), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
100 b"%": (15, None, None, (b"%", 15), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
101 b"|": (15, None, None, (b"|", 15), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
102 b"*": (5, None, None, (b"*", 5), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
103 b"/": (5, None, None, (b"/", 5), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
104 b"+": (4, None, None, (b"+", 4), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
105 b"-": (4, None, (b"negate", 19), (b"-", 4), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
106 b"=": (3, None, None, (b"keyvalue", 3), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
107 b",": (2, None, None, (b"list", 2), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
108 b")": (0, None, None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
109 b"integer": (0, b"integer", None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
110 b"symbol": (0, b"symbol", None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
111 b"string": (0, b"string", None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
112 b"template": (0, b"template", None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
113 b"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
114 }
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
115
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
116
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
117 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
118 """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
119 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
120 pos = start
32203
52e222eef646 py3: use pycompat.bytestr instead of bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32037
diff changeset
121 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
122 while pos < end:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
123 c = program[pos]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
124 if c.isspace(): # skip inter-token whitespace
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
125 pass
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
126 elif c in b"(=,).%|+-*/": # 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
127 yield (c, None, pos)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
128 elif c in b'"\'': # handle quoted templates
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
129 s = pos + 1
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
130 data, pos = _parsetemplate(program, s, end, c)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
131 yield (b'template', data, s)
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
132 pos -= 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
133 elif c == b'r' and program[pos : pos + 2] in (b"r'", b'r"'):
25784
33e613687dab templater: remove processing of "string" literals from tokenizer
Yuya Nishihara <yuya@tcha.org>
parents: 25783
diff changeset
134 # handle quoted strings
33e613687dab templater: remove processing of "string" literals from tokenizer
Yuya Nishihara <yuya@tcha.org>
parents: 25783
diff changeset
135 c = program[pos + 1]
33e613687dab templater: remove processing of "string" literals from tokenizer
Yuya Nishihara <yuya@tcha.org>
parents: 25783
diff changeset
136 s = pos = pos + 2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
137 while pos < end: # find closing quote
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
138 d = program[pos]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
139 if d == b'\\': # 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
140 pos += 2
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
141 continue
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
142 if d == c:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
143 yield (b'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
144 break
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
145 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
146 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
147 raise error.ParseError(_(b"unterminated string"), s)
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
148 elif c.isdigit():
25002
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
149 s = pos
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
150 while pos < end:
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
151 d = program[pos]
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
152 if not d.isdigit():
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
153 break
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
154 pos += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
155 yield (b'integer', program[s:pos], s)
25002
829faf8ab605 templater: tokenize decimal integer literal (issue4638) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25001
diff changeset
156 pos -= 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
157 elif (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
158 c == b'\\'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
159 and program[pos : pos + 2] in (br"\'", br'\"')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
160 or c == b'r'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
161 and program[pos : pos + 3] in (br"r\'", br'r\"')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
162 ):
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
163 # 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
164 # 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
165 # 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
166 #
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
167 # 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
168 # 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
169 # ------------------------ ------------ ------------------
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
170 # {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
171 # ~~~~~~~~
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
172 # escaped quoted string
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
173 if c == b'r':
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
174 pos += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
175 token = b'string'
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
176 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
177 token = b'template'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
178 quote = program[pos : pos + 2]
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
179 s = pos = pos + 2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
180 while pos < end: # find closing escaped quote
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
181 if program.startswith(b'\\\\\\', pos, end):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
182 pos += 4 # skip over double escaped characters
25676
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
183 continue
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
184 if program.startswith(quote, pos, end):
26215
72aad184f061 templater: create string unescape helper (issue4798)
Matt Mackall <mpm@selenic.com>
parents: 26197
diff changeset
185 # 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
186 data = parser.unescapestr(program[s:pos])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
187 if token == b'template':
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
188 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
189 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
190 pos += 1
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
191 break
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
192 pos += 1
ec9c258e666d templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
Yuya Nishihara <yuya@tcha.org>
parents: 25638
diff changeset
193 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
194 raise error.ParseError(_(b"unterminated string"), s)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
195 elif c.isalnum() or c in b'_':
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
196 s = pos
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
197 pos += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
198 while pos < end: # find end of symbol
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
199 d = program[pos]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
200 if not (d.isalnum() or d == b"_"):
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
201 break
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
202 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
203 sym = program[s:pos]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
204 yield (b'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
205 pos -= 1
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
206 elif c == term:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
207 yield (b'end', None, pos)
25782
babd2c93bd99 templater: check existence of closing brace of template string
Yuya Nishihara <yuya@tcha.org>
parents: 25781
diff changeset
208 return
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
209 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
210 raise error.ParseError(_(b"syntax error"), pos)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
211 pos += 1
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
212 if term:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
213 raise error.ParseError(_(b"unterminated template expansion"), start)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
214 yield (b'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
215
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
216
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
217 def _parsetemplate(tmpl, start, stop, quote=b''):
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
218 r"""
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
219 >>> _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
220 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
221 >>> _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
222 ([('string', 'foo'), ('symbol', 'bar')], 9)
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
223 >>> _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
224 ([('string', 'foo')], 4)
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
225 >>> _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
226 ([('string', 'foo"'), ('string', 'bar')], 9)
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
227 >>> _parsetemplate(br'foo\\"bar', 0, 10, quote=b'"')
25785
f976b7dc5e7b templater: unify "string" and "rawstring"
Yuya Nishihara <yuya@tcha.org>
parents: 25784
diff changeset
228 ([('string', 'foo\\')], 6)
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
229 """
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
230 parsed = []
36277
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
231 for typ, val, pos in _scantemplate(tmpl, start, stop, quote):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
232 if typ == b'string':
36277
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
233 parsed.append((typ, val))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
234 elif typ == b'template':
36277
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
235 parsed.append(val)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
236 elif typ == b'end':
36277
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
237 return parsed, pos
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
238 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
239 raise error.ProgrammingError(b'unexpected type: %s' % typ)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
240 raise error.ProgrammingError(b'unterminated scanning of template')
36277
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
241
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
242
36539
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36530
diff changeset
243 def scantemplate(tmpl, raw=False):
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36530
diff changeset
244 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: 36530
diff changeset
245
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36530
diff changeset
246 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: 36530
diff changeset
247 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: 36530
diff changeset
248 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: 36530
diff changeset
249 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: 36530
diff changeset
250 'foo'.
36278
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
251
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
252 >>> list(scantemplate(b'foo{bar}"baz'))
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
253 [('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: 36277
diff changeset
254 >>> list(scantemplate(b'outer{"inner"}outer'))
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
255 [('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: 36277
diff changeset
256 >>> list(scantemplate(b'foo\\{escaped}'))
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
257 [('string', 0, 5), ('string', 5, 13)]
36539
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36530
diff changeset
258 >>> 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: 36530
diff changeset
259 [('string', 0, 4), ('template', 4, 13)]
36278
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
260 """
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
261 last = None
36539
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36530
diff changeset
262 for typ, val, pos in _scantemplate(tmpl, 0, len(tmpl), raw=raw):
36278
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
263 if last:
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
264 yield last + (pos,)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
265 if typ == b'end':
36278
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
266 return
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
267 else:
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
268 last = (typ, pos)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
269 raise error.ProgrammingError(b'unterminated scanning of template')
36278
c6ce479f7a28 templater: add function to help substituting patterns in template string
Yuya Nishihara <yuya@tcha.org>
parents: 36277
diff changeset
270
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
271
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
272 def _scantemplate(tmpl, start, stop, quote=b'', raw=False):
36277
18bdfad8506e templater: extract function scanning template string
Yuya Nishihara <yuya@tcha.org>
parents: 35744
diff changeset
273 """Parse template string into chunks of strings and template expressions"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
274 sepchars = b'{' + quote
36539
638c012a87ef templater: add option to parse template string just like raw string literal
Yuya Nishihara <yuya@tcha.org>
parents: 36530
diff changeset
275 unescape = [parser.unescapestr, pycompat.identity][raw]
25781
82c918509ef5 templater: extract function that parses template string
Yuya Nishihara <yuya@tcha.org>
parents: 25780
diff changeset
276 pos = start
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25599
diff changeset
277 p = parser.parser(elements)
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
278 try:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
279 while pos < stop:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
280 n = min(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
281 (tmpl.find(c, pos, stop) for c in pycompat.bytestr(sepchars)),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
282 key=lambda n: (n < 0, n),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
283 )
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
284 if n < 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
285 yield (b'string', unescape(tmpl[pos:stop]), pos)
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
286 pos = stop
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
287 break
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
288 c = tmpl[n : n + 1]
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
289 bs = 0 # count leading backslashes
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
290 if not raw:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
291 bs = (n - pos) - len(tmpl[pos:n].rstrip(b'\\'))
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
292 if bs % 2 == 1:
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
293 # escaped (e.g. '\{', '\\\{', but not '\\{')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
294 yield (b'string', unescape(tmpl[pos : n - 1]) + c, pos)
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
295 pos = n + 1
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
296 continue
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
297 if n > pos:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
298 yield (b'string', unescape(tmpl[pos:n]), pos)
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
299 if c == quote:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
300 yield (b'end', None, n + 1)
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
301 return
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
302
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
303 parseres, pos = p.parse(tokenize(tmpl, n + 1, stop, b'}'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
304 if not tmpl.startswith(b'}', pos):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
305 raise error.ParseError(_(b"invalid token"), pos)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
306 yield (b'template', parseres, n)
36716
1b179d151578 templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents: 36699
diff changeset
307 pos += 1
25783
1f6878c87c25 templater: introduce one-pass parsing of nested template strings
Yuya Nishihara <yuya@tcha.org>
parents: 25782
diff changeset
308
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
309 if quote:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
310 raise error.ParseError(_(b"unterminated string"), start)
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
311 except error.ParseError as inst:
43098
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
312 _addparseerrorhint(inst, tmpl)
36698
80d7fb6c2dec templater: add hint to template parse errors to help locate issues
Ryan McElroy <rmcelroy@fb.com>
parents: 36677
diff changeset
313 raise
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
314 yield (b'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
315
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
316
43098
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
317 def _addparseerrorhint(inst, tmpl):
45799
0fc8b066928a errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 45462
diff changeset
318 if inst.location is None:
0fc8b066928a errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 45462
diff changeset
319 return
0fc8b066928a errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 45462
diff changeset
320 loc = inst.location
43098
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
321 # Offset the caret location by the number of newlines before the
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
322 # location of the error, since we will replace one-char newlines
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
323 # with the two-char literal r'\n'.
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
324 offset = tmpl[:loc].count(b'\n')
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
325 tmpl = tmpl.replace(b'\n', br'\n')
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
326 # We want the caret to point to the place in the template that
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
327 # failed to parse, but in a hint we get a open paren at the
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
328 # start. Therefore, we print "loc + 1" spaces (instead of "loc")
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
329 # to line up the caret with the location of the error.
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
330 inst.hint = tmpl + b'\n' + b' ' * (loc + 1 + offset) + b'^ ' + _(b'here')
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
331
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
332
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
333 def _unnesttemplatelist(tree):
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
334 """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
335
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
336 >>> def f(tree):
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
337 ... print(pycompat.sysstr(prettyformat(_unnesttemplatelist(tree))))
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
338 >>> f((b'template', []))
34090
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
339 (string '')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
340 >>> f((b'template', [(b'string', b'foo')]))
34090
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
341 (string 'foo')
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
342 >>> 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
343 (template
34090
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
344 (string 'foo')
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
345 (symbol 'rev'))
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
346 >>> 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
347 (template
34090
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
348 (symbol 'rev'))
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
349 >>> f((b'template', [(b'template', [(b'string', b'foo')])]))
34090
7bbc4e113e5f parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents: 34088
diff changeset
350 (string 'foo')
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
351 """
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
352 if not isinstance(tree, tuple):
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
353 return tree
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
354 op = tree[0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
355 if op != b'template':
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
356 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
357
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
358 assert len(tree) == 2
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
359 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
360 if not xs:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
361 return (b'string', b'') # empty template ""
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
362 elif len(xs) == 1 and xs[0][0] == b'string':
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
363 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
364 else:
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
365 return (op,) + xs
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
366
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
367
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
368 def parse(tmpl):
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
369 """Parse template string into tree"""
25781
82c918509ef5 templater: extract function that parses template string
Yuya Nishihara <yuya@tcha.org>
parents: 25780
diff changeset
370 parsed, pos = _parsetemplate(tmpl, 0, len(tmpl))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
371 assert pos == len(tmpl), b'unquoted template should be consumed'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
372 return _unnesttemplatelist((b'template', parsed))
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
373
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
374
43098
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
375 def parseexpr(expr):
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
376 """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
377
43098
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
378 >>> parseexpr(b'"foo"')
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
379 ('string', 'foo')
43098
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
380 >>> 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
381 ('func', ('symbol', 'foo'), ('symbol', 'bar'))
45901
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
382 >>> from . import error
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
383 >>> from . import pycompat
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
384 >>> try:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
385 ... parseexpr(b'foo(')
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
386 ... except error.ParseError as e:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
387 ... pycompat.sysstr(e.message)
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
388 ... e.location
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
389 'not a prefix: end'
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
390 4
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
391 >>> try:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
392 ... parseexpr(b'"foo" "bar"')
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
393 ... except error.ParseError as e:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
394 ... pycompat.sysstr(e.message)
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
395 ... e.location
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
396 'invalid token'
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45799
diff changeset
397 7
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
398 """
43098
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
399 try:
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
400 return _parseexpr(expr)
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
401 except error.ParseError as inst:
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
402 _addparseerrorhint(inst, expr)
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
403 raise
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
404
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
405
9691fc764bdc templater: add public parseexpr() function to parse "-Tjson(...)"
Yuya Nishihara <yuya@tcha.org>
parents: 43089
diff changeset
406 def _parseexpr(expr):
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
407 p = parser.parser(elements)
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
408 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
409 if pos != len(expr):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
410 raise error.ParseError(_(b'invalid token'), pos)
28911
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
411 return _unnesttemplatelist(tree)
35da19348143 templater: add function to parse whole string as template expression
Yuya Nishihara <yuya@tcha.org>
parents: 28837
diff changeset
412
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
413
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
414 def prettyformat(tree):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
415 return parser.prettyformat(tree, (b'integer', b'string', b'symbol'))
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
416
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
417
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
418 def compileexp(exp, context, curmethods):
28956
eea98190ed73 templater: inline compiletemplate() function into engine
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
419 """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
420 if not exp:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
421 raise error.ParseError(_(b"missing argument"))
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
422 t = exp[0]
40662
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40525
diff changeset
423 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
424
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
425
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
426 # template evaluation
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
427
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
428
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
429 def getsymbol(exp):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
430 if exp[0] == b'symbol':
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
431 return exp[1]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
432 raise error.ParseError(_(b"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
433
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
434
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
435 def getlist(x):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
436 if not x:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
437 return []
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
438 if x[0] == b'list':
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
439 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
440 return [x]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
441
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
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 gettemplate(exp, context):
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
444 """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
445 returns (func, data) pair"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
446 if exp[0] in (b'template', b'string'):
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
447 return compileexp(exp, context, methods)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
448 if exp[0] == b'symbol':
25599
695b93a79d17 templater: comment that gettemplate() has different name resolution order
Yuya Nishihara <yuya@tcha.org>
parents: 25598
diff changeset
449 # 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
450 # 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
451 # 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
452 return context._load(exp[1])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
453 raise error.ParseError(_(b"expected template specifier"))
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
454
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
455
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
456 def _runrecursivesymbol(context, mapping, key):
46121
c000eff2c635 errors: raise InputError on recursive template definition
Martin von Zweigbergk <martinvonz@google.com>
parents: 45957
diff changeset
457 raise error.InputError(_(b"recursive reference '%s' in template") % key)
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
458
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
459
25596
c1975809a6b5 templater: take any string literals as template, but not for rawstring (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25595
diff changeset
460 def buildtemplate(exp, context):
28547
73d01cba5810 templater: expand list of parsed templates to template node
Yuya Nishihara <yuya@tcha.org>
parents: 28546
diff changeset
461 ctmpl = [compileexp(e, context, methods) for e in exp[1:]]
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
462 return (templateutil.runtemplate, ctmpl)
25595
a7dd6692e5cb templater: move runtemplate function out of buildmap/runmap pair
Yuya Nishihara <yuya@tcha.org>
parents: 25580
diff changeset
463
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
464
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
465 def buildfilter(exp, context):
26104
0f1bc7faa50d templater: inline getfilter() to buildfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 25985
diff changeset
466 n = getsymbol(exp[2])
0f1bc7faa50d templater: inline getfilter() to buildfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 25985
diff changeset
467 if n in context._filters:
0f1bc7faa50d templater: inline getfilter() to buildfilter()
Yuya Nishihara <yuya@tcha.org>
parents: 25985
diff changeset
468 filt = context._filters[n]
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
469 arg = compileexp(exp[1], context, methods)
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
470 return (templateutil.runfilter, (arg, filt))
36918
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36735
diff changeset
471 if n in context._funcs:
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36735
diff changeset
472 f = context._funcs[n]
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
473 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
474 return (f, args)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
475 raise error.ParseError(_(b"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
476
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
477
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
478 def buildmap(exp, context):
34332
86d050abd5c1 templater: do not destructure operands in buildmap()
Yuya Nishihara <yuya@tcha.org>
parents: 34331
diff changeset
479 darg = compileexp(exp[1], context, methods)
86d050abd5c1 templater: do not destructure operands in buildmap()
Yuya Nishihara <yuya@tcha.org>
parents: 34331
diff changeset
480 targ = gettemplate(exp[2], context)
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
481 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
482
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
483
34535
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
484 def buildmember(exp, context):
78590585c0db templater: add dot operator to easily access a sub item
Yuya Nishihara <yuya@tcha.org>
parents: 34534
diff changeset
485 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
486 memb = getsymbol(exp[2])
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
487 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
488
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
489
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
490 def buildnegate(exp, context):
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
491 arg = compileexp(exp[1], context, exprmethods)
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
492 return (templateutil.runnegate, arg)
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
493
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
494
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
495 def buildarithmetic(exp, context, func):
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
496 left = compileexp(exp[1], context, exprmethods)
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
497 right = compileexp(exp[2], context, exprmethods)
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
498 return (templateutil.runarithmetic, (func, left, right))
30115
8e42dfde93d1 templater: provide arithmetic operations on integers
Simon Farnsworth <simonfar@fb.com>
parents: 30083
diff changeset
499
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
500
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
501 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
502 n = getsymbol(exp[1])
36918
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36735
diff changeset
503 if n in context._funcs:
543afbdc8e59 templater: move function table to the "context" object
Yuya Nishihara <yuya@tcha.org>
parents: 36735
diff changeset
504 f = context._funcs[n]
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
505 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
506 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
507 if n in context._filters:
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
508 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
509 if len(args) != 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
510 raise error.ParseError(_(b"filter %s expects one argument") % n)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
511 f = context._filters[n]
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
512 return (templateutil.runfilter, (args[0], f))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
513 raise error.ParseError(_(b"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
514
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
515
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
516 def _buildfuncargs(exp, context, curmethods, funcname, argspec):
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
517 """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
518 (func, data) pairs
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
519
36990
4b744c7b35ce templater: fix invalid reference of runsymbol in doctest
Yuya Nishihara <yuya@tcha.org>
parents: 36986
diff changeset
520 >>> 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
521 >>> def fargs(expr, argspec):
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
522 ... x = _parseexpr(expr)
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
523 ... n = getsymbol(x[1])
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
524 ... return _buildfuncargs(x[2], context, exprmethods, n, argspec)
34154
be00af4a1ac5 doctest: coerce dict.keys() to list
Yuya Nishihara <yuya@tcha.org>
parents: 34152
diff changeset
525 >>> 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
526 ['l', 'k']
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34090
diff changeset
527 >>> args = fargs(b'a(opts=1, k=2)', b'**opts')
34154
be00af4a1ac5 doctest: coerce dict.keys() to list
Yuya Nishihara <yuya@tcha.org>
parents: 34152
diff changeset
528 >>> 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
529 (['opts'], ['opts', 'k'])
31921
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
530 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
531
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
532 def compiledict(xs):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
533 return util.sortdict(
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43098
diff changeset
534 (k, compileexp(x, context, curmethods))
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43098
diff changeset
535 for k, x in pycompat.iteritems(xs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
536 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
537
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
538 def compilelist(xs):
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
539 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
540
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
541 if not argspec:
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
542 # 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
543 return compilelist(getlist(exp))
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
544
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
545 # 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
546 _poskeys, varkey, _keys, optkey = argspec = parser.splitargspec(argspec)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
547 treeargs = parser.buildargsdict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
548 getlist(exp),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
549 funcname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
550 argspec,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
551 keyvaluenode=b'keyvalue',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
552 keynode=b'symbol',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
553 )
31922
0f41f1e3c75c parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31921
diff changeset
554 compargs = util.sortdict()
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
555 if varkey:
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
556 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
557 if optkey:
2156934b7917 parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents: 31887
diff changeset
558 compargs[optkey] = compiledict(treeargs.pop(optkey))
31886
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
559 compargs.update(compiledict(treeargs))
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
560 return compargs
bdda942f4b9c templater: add support for keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 31885
diff changeset
561
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
562
31885
d18b624c1c06 templater: add parsing rule for key-value pair
Yuya Nishihara <yuya@tcha.org>
parents: 31884
diff changeset
563 def buildkeyvaluepair(exp, content):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
564 raise error.ParseError(_(b"can't use a key-value pair in this context"))
31885
d18b624c1c06 templater: add parsing rule for key-value pair
Yuya Nishihara <yuya@tcha.org>
parents: 31884
diff changeset
565
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
566
40662
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40525
diff changeset
567 def buildlist(exp, context):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
568 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
569 _(b"can't use a list in this context"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
570 hint=_(b'check place of comma and parens'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
571 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
572
40662
ff8b2886c492 templater: check invalid use of list expression properly (issue5920)
Yuya Nishihara <yuya@tcha.org>
parents: 40525
diff changeset
573
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
574 # 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
575 exprmethods = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
576 b"integer": lambda e, c: (templateutil.runinteger, e[1]),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
577 b"string": lambda e, c: (templateutil.runstring, e[1]),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
578 b"symbol": lambda e, c: (templateutil.runsymbol, e[1]),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
579 b"template": buildtemplate,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
580 b"group": lambda e, c: compileexp(e[1], c, exprmethods),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
581 b".": buildmember,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
582 b"|": buildfilter,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
583 b"%": buildmap,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
584 b"func": buildfunc,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
585 b"keyvalue": buildkeyvaluepair,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
586 b"list": buildlist,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
587 b"+": lambda e, c: buildarithmetic(e, c, lambda a, b: a + b),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
588 b"-": lambda e, c: buildarithmetic(e, c, lambda a, b: a - b),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
589 b"negate": buildnegate,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
590 b"*": lambda e, c: buildarithmetic(e, c, lambda a, b: a * b),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
591 b"/": lambda e, c: buildarithmetic(e, c, lambda a, b: a // b),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
592 }
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
593
25001
9668c1a433b3 templater: switch methods table on compileexp() of func args and inner expr
Yuya Nishihara <yuya@tcha.org>
parents: 24988
diff changeset
594 # 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
595 methods = exprmethods.copy()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
596 methods[b"integer"] = exprmethods[b"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
597
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
598
28912
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
599 class _aliasrules(parser.basealiasrules):
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
600 """Parsing and expansion rule set of template aliases"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
601
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
602 _section = _(b'template alias')
28912
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
603 _parse = staticmethod(_parseexpr)
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
604
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
605 @staticmethod
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
606 def _trygetfunc(tree):
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
607 """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
608 None"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
609 if tree[0] == b'func' and tree[1][0] == b'symbol':
28912
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
610 return tree[1][1], getlist(tree[2])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
611 if tree[0] == b'|' and tree[2][0] == b'symbol':
28912
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
612 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
613
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
614
28912
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
615 def expandaliases(tree, aliases):
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
616 """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
617 aliasmap = _aliasrules.buildmap(aliases)
867d6ba2353d templater: add parsing and expansion rules to process "templatealias" section
Yuya Nishihara <yuya@tcha.org>
parents: 28911
diff changeset
618 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
619
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
620
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
621 # template engine
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
622
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
623
24988
e8ff0b09acac templater: rename parsestring() to unquotestring() (API)
Yuya Nishihara <yuya@tcha.org>
parents: 24987
diff changeset
624 def unquotestring(s):
28630
bf35644b9f3a templater: relax unquotestring() to fall back to bare string
Yuya Nishihara <yuya@tcha.org>
parents: 28628
diff changeset
625 '''unwrap quotes if any; otherwise returns unmodified string'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
626 if len(s) < 2 or s[0] not in b"'\"" 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
627 return s
25696
c1cac25ad1a6 templater: remove workaround for escaped quoted string in quoted template
Yuya Nishihara <yuya@tcha.org>
parents: 25695
diff changeset
628 return s[1:-1]
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
629
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
630
43522
70d42e2ad9b4 pytype: don't warn us about ignored-on-py3 metaclasses
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
631 class resourcemapper(object): # pytype: disable=ignored-metaclass
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
632 """Mapper of internal template resources"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
633
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
634 __metaclass__ = abc.ABCMeta
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
635
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
636 @abc.abstractmethod
39598
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38445
diff changeset
637 def availablekeys(self, mapping):
37078
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
638 """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: 37077
diff changeset
639
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
640 @abc.abstractmethod
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
641 def knownkeys(self):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
642 """Return a set of supported resource keys"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
643
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
644 @abc.abstractmethod
39598
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38445
diff changeset
645 def lookup(self, mapping, key):
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
646 """Return a resource for the key if available; otherwise None"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
647
37105
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
648 @abc.abstractmethod
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
649 def populatemap(self, context, origmapping, newmapping):
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
650 """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: 37087
diff changeset
651 with the given new mapping"""
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
652
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
653
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
654 class nullresourcemapper(resourcemapper):
39598
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38445
diff changeset
655 def availablekeys(self, mapping):
37078
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
656 return set()
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
657
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
658 def knownkeys(self):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
659 return set()
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
660
39598
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38445
diff changeset
661 def lookup(self, mapping, key):
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
662 return None
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
663
37105
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
664 def populatemap(self, context, origmapping, newmapping):
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
665 return {}
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
666
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
667
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
668 class engine(object):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
669 """template expansion engine.
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
670
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
671 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
672 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
673 is treated as name of template file.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
674
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
675 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
676 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
677 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
678 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
679
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
680 expansion also allows formatting and filtering.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
681
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
682 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
683 {key%format}.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
684
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
685 filter uses function to transform value. syntax is
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
686 {key|filter1|filter2|...}."""
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
687
38360
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
688 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
689 self._loader = loader
26330
ec4f3755d997 templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26234
diff changeset
690 if filters is None:
ec4f3755d997 templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26234
diff changeset
691 filters = {}
10848
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
692 self._filters = filters
36928
521f6c7e1756 templater: split template functions to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36927
diff changeset
693 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
694 if defaults is None:
2c6a741bf05e templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26330
diff changeset
695 defaults = {}
35472
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35471
diff changeset
696 if resources is None:
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
697 resources = nullresourcemapper()
10848
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
698 self._defaults = defaults
35472
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35471
diff changeset
699 self._resources = resources
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
700 self._cache = {} # key: (func, data)
37398
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
701 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
702
37077
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37076
diff changeset
703 def overlaymap(self, origmapping, newmapping):
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37076
diff changeset
704 """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: 37076
diff changeset
705 mapping to override the original"""
37078
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
706 # 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: 37077
diff changeset
707 # 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: 37077
diff changeset
708 knownres = self._resources.knownkeys()
39598
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38445
diff changeset
709 newres = self._resources.availablekeys(newmapping)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
710 mapping = {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
711 k: v
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43098
diff changeset
712 for k, v in pycompat.iteritems(origmapping)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
713 if (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
714 k in knownres # not a symbol per self.symbol()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
715 or newres.isdisjoint(self._defaultrequires(k))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
716 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
717 }
37077
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37076
diff changeset
718 mapping.update(newmapping)
37105
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
719 mapping.update(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
720 self._resources.populatemap(self, origmapping, newmapping)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
721 )
37077
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37076
diff changeset
722 return mapping
2891079fb0c0 templater: factor out function to create mapping dict for nested evaluation
Yuya Nishihara <yuya@tcha.org>
parents: 37076
diff changeset
723
37078
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
724 def _defaultrequires(self, key):
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
725 """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: 37077
diff changeset
726 v = self._defaults.get(key)
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
727 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: 37077
diff changeset
728 return ()
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
729 return getattr(v, '_requires', ())
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37077
diff changeset
730
35471
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
731 def symbol(self, mapping, key):
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
732 """Resolve symbol to value or function; None if nothing found"""
35474
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
733 v = None
37076
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
734 if key not in self._resources.knownkeys():
35474
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35472
diff changeset
735 v = mapping.get(key)
35471
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
736 if v is None:
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
737 v = self._defaults.get(key)
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
738 return v
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
739
37501
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
740 def availableresourcekeys(self, mapping):
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
741 """Return a set of available resource keys based on the given mapping"""
39598
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38445
diff changeset
742 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
743
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
744 def knownresourcekeys(self):
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
745 """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
746 return self._resources.knownkeys()
0f4de9c27973 templater: add public interface returning a set of resource keys
Yuya Nishihara <yuya@tcha.org>
parents: 37499
diff changeset
747
35471
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
748 def resource(self, mapping, key):
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
749 """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: 35421
diff changeset
750 evaluation"""
39598
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38445
diff changeset
751 v = self._resources.lookup(mapping, key)
35472
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35471
diff changeset
752 if v is None:
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
753 raise templateutil.ResourceUnavailable(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
754 _(b'template resource not available: %s') % key
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
755 )
35472
32c278eb876f templater: keep default resources per template engine (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35471
diff changeset
756 return v
35471
d6cfa722b044 templater: look up mapping table through template engine
Yuya Nishihara <yuya@tcha.org>
parents: 35421
diff changeset
757
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
758 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
759 '''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
760 if t not in self._cache:
38360
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
761 x = self._loader(t)
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
762 # 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
763 self._cache[t] = (_runrecursivesymbol, t)
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
764 try:
28956
eea98190ed73 templater: inline compiletemplate() function into engine
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
765 self._cache[t] = compileexp(x, self, methods)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
766 except: # re-raises
27940
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
767 del self._cache[t]
cfe7da66f555 templater: abort if infinite recursion detected while compiling
Yuya Nishihara <yuya@tcha.org>
parents: 27939
diff changeset
768 raise
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
769 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
770
37398
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
771 def _parse(self, tmpl):
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
772 """Parse and cache a literal template"""
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
773 if tmpl not in self._tmplcache:
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
774 x = parse(tmpl)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
775 self._tmplcache[tmpl] = compileexp(x, self, methods)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
776 return self._tmplcache[tmpl]
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
777
37070
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
778 def preload(self, t):
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
779 """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: 37022
diff changeset
780 try:
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
781 self._load(t)
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
782 return True
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
783 except templateutil.TemplateNotFound:
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
784 return False
04aafcec00b9 templater: add context.preload(t) to test if the specified template exists
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
785
10853
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
786 def process(self, t, mapping):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
787 """Perform expansion. t is name of map element to expand.
10853
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
788 mapping contains added elements for use during expansion. Is a
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
789 generator."""
28545
1d461ee26e1b templater: lift parsed and compiled templates to generic data types
Yuya Nishihara <yuya@tcha.org>
parents: 28462
diff changeset
790 func, data = self._load(t)
37398
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
791 return self._expand(func, data, mapping)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
792
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
793 def expand(self, tmpl, mapping):
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
794 """Perform expansion over a literal template
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
795
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
796 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: 37274
diff changeset
797 with an internal template string.
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
798 """
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
799 func, data = self._parse(tmpl)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
800 return self._expand(func, data, mapping)
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
801
3235afdfcf1c templater: add function that expands internal literal templates
Yuya Nishihara <yuya@tcha.org>
parents: 37274
diff changeset
802 def _expand(self, func, data, mapping):
37105
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
803 # 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: 37087
diff changeset
804 # 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: 37087
diff changeset
805 # initial 'revcache' may contain pre-computed items.
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
806 extramapping = self._resources.populatemap(self, {}, mapping)
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
807 if extramapping:
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
808 extramapping.update(mapping)
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37087
diff changeset
809 mapping = extramapping
37274
7d3bc1d4e871 templater: pass (context, mapping) down to unwraphybrid()
Yuya Nishihara <yuya@tcha.org>
parents: 37161
diff changeset
810 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
811
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
812
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
813 def stylelist():
45235
91aa9bba3dc9 templater: make templatepaths() return a single path, or None
Martin von Zweigbergk <martinvonz@google.com>
parents: 45234
diff changeset
814 path = templatedir()
91aa9bba3dc9 templater: make templatepaths() return a single path, or None
Martin von Zweigbergk <martinvonz@google.com>
parents: 45234
diff changeset
815 if not path:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
816 return _(b'no templates found, try `hg debuginstall` for more info')
45235
91aa9bba3dc9 templater: make templatepaths() return a single path, or None
Martin von Zweigbergk <martinvonz@google.com>
parents: 45234
diff changeset
817 dirlist = os.listdir(path)
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
818 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
819 for file in dirlist:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
820 split = file.split(b".")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
821 if split[-1] in (b'orig', b'rej'):
28403
d2e154dddb6e templater: ignore orig/rej files
timeless <timeless@mozdev.org>
parents: 28384
diff changeset
822 continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
823 if split[0] == b"map-cmdline":
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
824 stylelist.append(split[1])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
825 return b", ".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
826
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
827
45329
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
828 def _open_mapfile(mapfile):
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
829 if os.path.exists(mapfile):
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
830 return util.posixfile(mapfile, b'rb')
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
831 raise error.Abort(
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
832 _(b"style '%s' not found") % mapfile,
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
833 hint=_(b"available styles: %s") % stylelist(),
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
834 )
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
835
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
836
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
837 def _readmapfile(fp, mapfile):
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
838 """Load template elements from the given map file"""
47825
981cef5188c3 templater: swap `\` with `/` in more location
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47824
diff changeset
839 if pycompat.iswindows:
981cef5188c3 templater: swap `\` with `/` in more location
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47824
diff changeset
840 # quick hack to make sure we can process '/' in the code dealing with
981cef5188c3 templater: swap `\` with `/` in more location
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47824
diff changeset
841 # ressource. Ideally we would make sure we use `/` instead of `ossep`
981cef5188c3 templater: swap `\` with `/` in more location
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47824
diff changeset
842 # in the templater code, but that seems a bigger and less certain
981cef5188c3 templater: swap `\` with `/` in more location
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47824
diff changeset
843 # change that we better left for the default branch.
981cef5188c3 templater: swap `\` with `/` in more location
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47824
diff changeset
844 name_paths = mapfile.split(pycompat.ossep)
981cef5188c3 templater: swap `\` with `/` in more location
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47824
diff changeset
845 mapfile = b'/'.join(name_paths)
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
846 base = os.path.dirname(mapfile)
45246
4ccd5ec565c2 templater: do search for include of unqualified builtin outside of config code
Martin von Zweigbergk <martinvonz@google.com>
parents: 45245
diff changeset
847 conf = config.config()
45245
8ec3062b7047 templater: switch to lower-level config.parse() in _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45236
diff changeset
848
45281
668af67bfd18 config: remove now-unused `abs` argument from `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents: 45247
diff changeset
849 def include(rel, remap, sections):
45333
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
850 subresource = None
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
851 if base:
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
852 abs = os.path.normpath(os.path.join(base, rel))
45246
4ccd5ec565c2 templater: do search for include of unqualified builtin outside of config code
Martin von Zweigbergk <martinvonz@google.com>
parents: 45245
diff changeset
853 if os.path.isfile(abs):
45333
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
854 subresource = util.posixfile(abs, b'rb')
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
855 if not subresource:
45334
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
856 if pycompat.ossep not in rel:
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
857 abs = rel
47831
f3b1df44b716 template: handle missing resource in `_readmapfile`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47825
diff changeset
858 try:
f3b1df44b716 template: handle missing resource in `_readmapfile`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47825
diff changeset
859 subresource = resourceutil.open_resource(
f3b1df44b716 template: handle missing resource in `_readmapfile`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47825
diff changeset
860 b'mercurial.templates', rel
f3b1df44b716 template: handle missing resource in `_readmapfile`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47825
diff changeset
861 )
47852
2b76255a4f74 template: FileNotFoundError is actually a built in exception
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47831
diff changeset
862 except FileNotFoundError:
47831
f3b1df44b716 template: handle missing resource in `_readmapfile`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47825
diff changeset
863 subresource = None
45334
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
864 else:
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
865 dir = templatedir()
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
866 if dir:
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
867 abs = os.path.normpath(os.path.join(dir, rel))
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
868 if os.path.isfile(abs):
fef64d7a4a84 templater: try to read %include in mapfiles from resources
Martin von Zweigbergk <martinvonz@google.com>
parents: 45333
diff changeset
869 subresource = util.posixfile(abs, b'rb')
45333
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
870 if subresource:
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
871 data = subresource.read()
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
872 conf.parse(
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
873 abs,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
874 data,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
875 sections=sections,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
876 remap=remap,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
877 include=include,
45333
d9a502a0a9ca templater: unroll loop over mapfile directories
Martin von Zweigbergk <martinvonz@google.com>
parents: 45332
diff changeset
878 )
45245
8ec3062b7047 templater: switch to lower-level config.parse() in _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45236
diff changeset
879
45329
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
880 data = fp.read()
45245
8ec3062b7047 templater: switch to lower-level config.parse() in _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45236
diff changeset
881 conf.parse(mapfile, data, remap={b'': b'templates'}, include=include)
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
882
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
883 cache = {}
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
884 tmap = {}
34715
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34714
diff changeset
885 aliases = []
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
886
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
887 val = conf.get(b'templates', b'__base__')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
888 if val and val[0] not in b"'\"":
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
889 # treat as a pointer to a base class for this style
45285
28840ef52f71 templater: don't normalize path separators to '/' when interacting with OS
Martin von Zweigbergk <martinvonz@google.com>
parents: 45283
diff changeset
890 path = os.path.normpath(os.path.join(base, val))
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
891
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
892 # 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
893 if not os.path.exists(path):
45247
d5ccc059fbcd templater: handle None returned from templatedir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45246
diff changeset
894 dir = templatedir()
d5ccc059fbcd templater: handle None returned from templatedir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45246
diff changeset
895 if dir is not None:
45285
28840ef52f71 templater: don't normalize path separators to '/' when interacting with OS
Martin von Zweigbergk <martinvonz@google.com>
parents: 45283
diff changeset
896 p2 = os.path.normpath(os.path.join(dir, val))
45247
d5ccc059fbcd templater: handle None returned from templatedir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45246
diff changeset
897 if os.path.isfile(p2):
d5ccc059fbcd templater: handle None returned from templatedir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45246
diff changeset
898 path = p2
d5ccc059fbcd templater: handle None returned from templatedir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45246
diff changeset
899 else:
45285
28840ef52f71 templater: don't normalize path separators to '/' when interacting with OS
Martin von Zweigbergk <martinvonz@google.com>
parents: 45283
diff changeset
900 p3 = os.path.normpath(os.path.join(p2, b"map"))
45247
d5ccc059fbcd templater: handle None returned from templatedir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45246
diff changeset
901 if os.path.isfile(p3):
d5ccc059fbcd templater: handle None returned from templatedir()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45246
diff changeset
902 path = p3
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
903
45329
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
904 fp = _open_mapfile(path)
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
905 cache, tmap, aliases = _readmapfile(fp, path)
34712
56f085334611 templater: simplify merge of __base__ dicts by reading it first
Yuya Nishihara <yuya@tcha.org>
parents: 34693
diff changeset
906
46492
5272542196cc config: use the right API to access template access
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46121
diff changeset
907 for key, val in conf.items(b'templates'):
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
908 if not val:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
909 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
910 _(b'missing value'), conf.source(b'templates', key)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
911 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
912 if val[0] in b"'\"":
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
913 if val[0] != val[-1]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
914 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
915 _(b'unmatched quotes'), conf.source(b'templates', key)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
916 )
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
917 cache[key] = unquotestring(val)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
918 elif key != b'__base__':
38359
48289eafb37d templater: drop extension point of engine classes (API)
Yuya Nishihara <yuya@tcha.org>
parents: 38358
diff changeset
919 tmap[key] = os.path.join(base, val)
46492
5272542196cc config: use the right API to access template access
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46121
diff changeset
920 aliases.extend(conf.items(b'templatealias'))
34715
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34714
diff changeset
921 return cache, tmap, aliases
28953
7f6b8ec691e3 templater: extract function that loads template map file
Yuya Nishihara <yuya@tcha.org>
parents: 28952
diff changeset
922
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
923
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
924 class loader(object):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
925 """Load template fragments optionally from a map file"""
35485
964510dcdc2a templater: rewrite docstring of templater.__init__()
Yuya Nishihara <yuya@tcha.org>
parents: 35474
diff changeset
926
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
927 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
928 if cache is None:
0a5a774f5956 templater: remove a mutable default argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26333
diff changeset
929 cache = {}
1975
6e1a8ea5d717 Duplicate cache when creating templater.
Shun-ichi Goto <shunichi.goto@gmail.com>
parents: 1964
diff changeset
930 self.cache = cache.copy()
38357
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38297
diff changeset
931 self._map = {}
38360
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
932 self._aliasmap = _aliasrules.buildmap(aliases)
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
933
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
934 def __contains__(self, key):
38357
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38297
diff changeset
935 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
936
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
937 def load(self, t):
38360
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
938 """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
939 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
940 try:
45343
c3376a724e32 templater: teach template loader to use open_template() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 45342
diff changeset
941 mapfile, fp = open_template(self._map[t])
c3376a724e32 templater: teach template loader to use open_template() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 45342
diff changeset
942 self.cache[t] = fp.read()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
943 except KeyError as inst:
36919
da2977e674a3 templater: extract template evaluation utility to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36918
diff changeset
944 raise templateutil.TemplateNotFound(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
945 _(b'"%s" not in template map') % inst.args[0]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
946 )
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
947 except IOError as inst:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
948 reason = _(b'template file %s: %s') % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
949 self._map[t],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
950 stringutil.forcebytestr(inst.args[1]),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
951 )
36530
43e108027b0d py3: move between bytes and unicode when re-raising IOError
Yuya Nishihara <yuya@tcha.org>
parents: 36475
diff changeset
952 raise IOError(inst.args[0], encoding.strfromlocal(reason))
38360
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
953 return self._parse(self.cache[t])
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
954
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
955 def _parse(self, tmpl):
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
956 x = parse(tmpl)
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
957 if self._aliasmap:
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
958 x = _aliasrules.expand(self._aliasmap, x)
e637dc0b3b1f templater: parse template string to tree by templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38359
diff changeset
959 return x
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
960
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
961 def _findsymbolsused(self, tree, syms):
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
962 if not tree:
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
963 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
964 op = tree[0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
965 if op == b'symbol':
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
966 s = tree[1]
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
967 if s in syms[0]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
968 return # avoid recursion: s -> cache[s] -> s
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
969 syms[0].add(s)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
970 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: 38360
diff changeset
971 # 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: 38360
diff changeset
972 self._findsymbolsused(self.load(s), syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
973 return
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
974 if op in {b'integer', b'string'}:
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
975 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
976 # '{arg|func}' == '{func(arg)}'
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
977 if op == b'|':
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
978 syms[1].add(getsymbol(tree[2]))
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
979 self._findsymbolsused(tree[1], syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
980 return
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
981 if op == b'func':
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
982 syms[1].add(getsymbol(tree[1]))
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
983 self._findsymbolsused(tree[2], syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
984 return
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
985 for x in tree[1:]:
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
986 self._findsymbolsused(x, syms)
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
987
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
988 def symbolsused(self, t):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
989 """Look up (keywords, filters/functions) referenced from the name
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
990 template 't'
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
991
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
992 This may load additional templates from the map file.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
993 """
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
994 syms = (set(), set())
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
995 self._findsymbolsused(self.load(t), syms)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
996 return syms
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
997
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
998
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
999 class templater(object):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1000 def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1001 self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1002 filters=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1003 defaults=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1004 resources=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1005 cache=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1006 aliases=(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1007 minchunk=1024,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1008 maxchunk=65536,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1009 ):
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1010 """Create template engine optionally with preloaded template fragments
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1011
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1012 - ``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: 38361
diff changeset
1013 - ``defaults``: a dict of symbol values/functions; may be overridden
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1014 by a ``mapping`` dict.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1015 - ``resources``: a resourcemapper object to look up internal data
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1016 (e.g. cache), inaccessible from user template.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1017 - ``cache``: a dict of preloaded template fragments.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1018 - ``aliases``: a list of alias (name, replacement) pairs.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1019
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1020 self.cache may be updated later to register additional template
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1021 fragments.
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1022 """
38445
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1023 allfilters = templatefilters.filters.copy()
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1024 if filters:
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1025 allfilters.update(filters)
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1026 self._loader = loader(cache, aliases)
38445
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1027 self._proc = engine(self._loader.load, allfilters, defaults, resources)
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1028 self._minchunk, self._maxchunk = minchunk, maxchunk
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1029
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1030 @classmethod
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1031 def frommapfile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1032 cls,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1033 mapfile,
45331
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45330
diff changeset
1034 fp=None,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1035 filters=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1036 defaults=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1037 resources=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1038 cache=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1039 minchunk=1024,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1040 maxchunk=65536,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1041 ):
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1042 """Create templater from the specified map file"""
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1043 t = cls(filters, defaults, resources, cache, [], minchunk, maxchunk)
45331
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45330
diff changeset
1044 if not fp:
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45330
diff changeset
1045 fp = _open_mapfile(mapfile)
45329
dc10bcd5c08d templater: start passing resource to read from into _readmapfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45328
diff changeset
1046 cache, tmap, aliases = _readmapfile(fp, mapfile)
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1047 t._loader.cache.update(cache)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1048 t._loader._map = tmap
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1049 t._loader._aliasmap = _aliasrules.buildmap(aliases)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1050 return t
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1051
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1052 def __contains__(self, key):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1053 return key in self._loader
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1054
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1055 @property
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1056 def cache(self):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1057 return self._loader.cache
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1058
38445
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1059 # for highlight extension to insert one-time 'colorize' filter
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1060 @property
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1061 def _filters(self):
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1062 return self._proc._filters
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1063
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1064 @property
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1065 def defaults(self):
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1066 return self._proc._defaults
3813c6b7337c templater: remove redundant member variables from templater class
Yuya Nishihara <yuya@tcha.org>
parents: 38444
diff changeset
1067
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1068 def load(self, t):
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1069 """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: 38361
diff changeset
1070 return self._loader.load(t)
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1071
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1072 def symbolsuseddefault(self):
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1073 """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: 38360
diff changeset
1074 unnamed template
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1075
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1076 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: 38360
diff changeset
1077 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1078 return self.symbolsused(b'')
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1079
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1080 def symbolsused(self, t):
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1081 """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: 38360
diff changeset
1082 template 't'
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1083
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1084 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: 38360
diff changeset
1085 """
38443
f79237942dec templater: extract template loader to separate class
Yuya Nishihara <yuya@tcha.org>
parents: 38361
diff changeset
1086 return self._loader.symbolsused(t)
38361
d4fae9a0ab1f templater: add function to look up symbols used in template
Yuya Nishihara <yuya@tcha.org>
parents: 38360
diff changeset
1087
36991
317382151ac3 templater: rename .render(mapping) to .renderdefault(mapping) (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36990
diff changeset
1088 def renderdefault(self, mapping):
32891
2ecce24dfcd3 templater: add simple interface for unnamed template (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32704
diff changeset
1089 """Render the default unnamed template and return result as string"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1090 return self.render(b'', mapping)
36992
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36991
diff changeset
1091
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36991
diff changeset
1092 def render(self, t, mapping):
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36991
diff changeset
1093 """Render the specified named template and return result as string"""
37161
b56b79185aad templater: do not use stringify() to concatenate flattened template output
Yuya Nishihara <yuya@tcha.org>
parents: 37159
diff changeset
1094 return b''.join(self.generate(t, mapping))
32891
2ecce24dfcd3 templater: add simple interface for unnamed template (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32704
diff changeset
1095
37022
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37017
diff changeset
1096 def generate(self, t, mapping):
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37017
diff changeset
1097 """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: 37017
diff changeset
1098 yields chunks"""
38444
256581484c7f templater: resurrect cache of engine instance
Yuya Nishihara <yuya@tcha.org>
parents: 38443
diff changeset
1099 stream = self._proc.process(t, mapping)
38357
de089e3eb328 templater: mark most attributes as private
Yuya Nishihara <yuya@tcha.org>
parents: 38297
diff changeset
1100 if self._minchunk:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1101 stream = util.increasingchunks(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1102 stream, min=self._minchunk, max=self._maxchunk
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1103 )
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
1104 return stream
7434
cf7741aa1e96 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7396
diff changeset
1105
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1106
45235
91aa9bba3dc9 templater: make templatepaths() return a single path, or None
Martin von Zweigbergk <martinvonz@google.com>
parents: 45234
diff changeset
1107 def templatedir():
91aa9bba3dc9 templater: make templatepaths() return a single path, or None
Martin von Zweigbergk <martinvonz@google.com>
parents: 45234
diff changeset
1108 '''return the directory used for template files, or None.'''
45234
e2ec36167151 templater: simplify templatepaths() to avoid iterating a singleton list
Martin von Zweigbergk <martinvonz@google.com>
parents: 44597
diff changeset
1109 path = os.path.normpath(os.path.join(resourceutil.datapath, b'templates'))
45235
91aa9bba3dc9 templater: make templatepaths() return a single path, or None
Martin von Zweigbergk <martinvonz@google.com>
parents: 45234
diff changeset
1110 return path if os.path.isdir(path) else None
2189
e3eba577a0ae move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2001
diff changeset
1111
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40952
diff changeset
1112
45337
1b983985edd9 hgweb: open mapfile using templater.open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45334
diff changeset
1113 def open_template(name, templatepath=None):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
1114 """returns a file-like object for the given template, and its full path
45332
3b27ed8e324e templater: make open_template() read from resources if in frozen binary
Martin von Zweigbergk <martinvonz@google.com>
parents: 45331
diff changeset
1115
3b27ed8e324e templater: make open_template() read from resources if in frozen binary
Martin von Zweigbergk <martinvonz@google.com>
parents: 45331
diff changeset
1116 If the name is a relative path and we're in a frozen binary, the template
3b27ed8e324e templater: make open_template() read from resources if in frozen binary
Martin von Zweigbergk <martinvonz@google.com>
parents: 45331
diff changeset
1117 will be read from the mercurial.templates package instead. The returned path
3b27ed8e324e templater: make open_template() read from resources if in frozen binary
Martin von Zweigbergk <martinvonz@google.com>
parents: 45331
diff changeset
1118 will then be the relative path.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45901
diff changeset
1119 """
45342
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1120 # Does the name point directly to a map file?
45343
c3376a724e32 templater: teach template loader to use open_template() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 45342
diff changeset
1121 if os.path.isfile(name) or os.path.isabs(name):
45342
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1122 return name, open(name, mode='rb')
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1123
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1124 # Does the name point to a template in the provided templatepath, or
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1125 # in mercurial/templates/ if no path was provided?
45337
1b983985edd9 hgweb: open mapfile using templater.open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45334
diff changeset
1126 if templatepath is None:
1b983985edd9 hgweb: open mapfile using templater.open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45334
diff changeset
1127 templatepath = templatedir()
45342
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1128 if templatepath is not None:
45330
65a812ed9e9f templater: replace templatepath() with function that also opens the file
Martin von Zweigbergk <martinvonz@google.com>
parents: 45329
diff changeset
1129 f = os.path.join(templatepath, name)
45341
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1130 return f, open(f, mode='rb')
45342
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1131
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1132 # Otherwise try to read it using the resources API
47824
7ab7f73a7f0a templater: swap `\` with `/` to allow the resource logic to kicks in
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
1133 if pycompat.iswindows:
7ab7f73a7f0a templater: swap `\` with `/` to allow the resource logic to kicks in
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
1134 # quick hack to make sure we can process '/' in the code dealing with
7ab7f73a7f0a templater: swap `\` with `/` to allow the resource logic to kicks in
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
1135 # ressource. Ideally we would make sure we use `/` instead of `ossep`
7ab7f73a7f0a templater: swap `\` with `/` to allow the resource logic to kicks in
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
1136 # in the templater code, but that seems a bigger and less certain
7ab7f73a7f0a templater: swap `\` with `/` to allow the resource logic to kicks in
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
1137 # change that we better left for the default branch.
7ab7f73a7f0a templater: swap `\` with `/` to allow the resource logic to kicks in
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
1138 name_paths = name.split(pycompat.ossep)
7ab7f73a7f0a templater: swap `\` with `/` to allow the resource logic to kicks in
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
1139 name = b'/'.join(name_paths)
45462
e53a3d0ef416 templater: fix reading of templates in frozen binaries with py3 < 3.7
Martin von Zweigbergk <martinvonz@google.com>
parents: 45343
diff changeset
1140 name_parts = name.split(b'/')
e53a3d0ef416 templater: fix reading of templates in frozen binaries with py3 < 3.7
Martin von Zweigbergk <martinvonz@google.com>
parents: 45343
diff changeset
1141 package_name = b'.'.join([b'mercurial', b'templates'] + name_parts[:-1])
45342
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1142 return (
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1143 name,
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1144 resourceutil.open_resource(package_name, name_parts[-1]),
735756ecda8c templater: restructure open_template() a little to prepare for relative paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 45341
diff changeset
1145 )
45341
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1146
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1147
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1148 def try_open_template(name, templatepath=None):
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1149 try:
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1150 return open_template(name, templatepath)
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1151 except (EnvironmentError, ImportError):
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45340
diff changeset
1152 return None, None