| Home | Trees | Indices | Help |
|
|---|
|
|
1 # Copyright 2009, Peter A. Bigot
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); you may
4 # not use this file except in compliance with the License. You may obtain a
5 # copy of the License at:
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 # License for the specific language governing permissions and limitations
13 # under the License.
14
15 """Functions that aid with generating text from templates and maps."""
16
17 import re
18
19 # POSIX shell variable syntax:
20 # Expansions with unset var
21 # ${var}=
22 # ${var+WORD}=
23 # ${var:+WORD}=
24 # ${var-WORD}=WORD
25 # ${var:-WORD}=WORD
26 # Expansions with empty var
27 # ${var}=
28 # ${var+WORD}=WORD
29 # ${var:+WORD}=
30 # ${var-WORD}=
31 # ${var:-WORD}=WORD
32 # Expansions with var=SET
33 # ${var}=SET
34 # ${var+WORD}=WORD
35 # ${var:+WORD}=WORD
36 # ${var-WORD}=SET
37 # ${var:-WORD}=SET
38
39 # This expression replaces markers in template text with the value
40 # obtained by looking up the marker in a dictionary.
41 # %{id} = value
42 _substIdPattern = re.compile("%{(?P<id>\w+)}")
43
44 # This expression performs conditional substitution: if the expression
45 # provided evaluates to true in a given context, then one value is
46 # substituted, otherwise the alternative value is substituted.
47 # %{?<cond>??<true>?:<false>?}
48 # %{?1 == 2??true?:false?}
49 _substConditionalPattern = re.compile("%{\?(?P<expr>.+?)\?\?(?P<true>.*?)(\?:(?P<false>.*?))?\?}", re.MULTILINE + re.DOTALL)
50
51 # This expression tests whether an identifier is defined to a non-None
52 # value in the context; if so, it replaces the marker with template
53 # text. In that replacement text, the value ?@ is replaced by the
54 # test expression. Contrast POSIX shell ${ID+subst}${ID-subst}
55 # Note: NOT by the value of the test expression. If no replacement
56 # text is given, the replacement '%{?@}' is used, which replaces it
57 # with the value of the test expression.
58 # %{?<id>?+<yessubst>?-?<nosubst>}}
59 # %{?maybe_text?+?@ is defined to be %{?@}?}
60 _substIfDefinedPattern = re.compile("%{\?(?P<id>\w+)(\?\+(?P<repl>.*?))?(\?\-(?P<ndrepl>.*?))?\?}", re.MULTILINE + re.DOTALL)
61
62 # The pattern which, if present in the body of a IfDefined block, is
63 # replaced by the test expression.
64 _substDefinedBodyPattern = re.compile("\?@")
65
67 global _substDefinedBodyPattern
68 id = match_object.group('id')
69 repl = match_object.group('repl')
70 ndrepl = match_object.group('ndrepl')
71 value = dictionary.get(id, None)
72 if value is not None:
73 if repl:
74 return _substDefinedBodyPattern.sub(id, repl)
75 if ndrepl:
76 return ''
77 return _substDefinedBodyPattern.sub(id, '%{?@}')
78 else:
79 if ndrepl:
80 return _substDefinedBodyPattern.sub(id, ndrepl)
81 return ''
82
84 global _substDefinedBodyPattern
85 expr = match_object.group('expr')
86 true = match_object.group('true')
87 false = match_object.group('false')
88 value = None
89 try:
90 value = eval(expr, dictionary)
91 except Exception, e:
92 return '%%{EXCEPTION: %s}' % (e,)
93 if value:
94 return _substDefinedBodyPattern.sub(expr, true)
95 if false is not None:
96 return _substDefinedBodyPattern.sub(expr, false)
97 return ''
98
100 global _substIfDefinedPattern
101 global _substConditionalPattern
102 global _substIdPattern
103 global _substDefinedBodyPattern
104 rv = text
105 rv = _substIfDefinedPattern.sub(lambda _x: _bodyIfDefinedPattern(_x, dictionary), rv)
106 rv = _substConditionalPattern.sub(lambda _x: _bodyConditionalPattern(_x, dictionary), rv)
107 rv = _substIdPattern.sub(
108 lambda _x,_map=dictionary:
109 _map.get(_x.group('id'), '%%{MISSING:%s}' % (_x.group('id'),))
110 , rv)
111 return rv
112
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Sep 9 14:08:54 2011 | http://epydoc.sourceforge.net |