annotate mercurial/templater.py @ 51689:39e2b2d062c1

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