Package pyxb :: Package utils :: Module templates
[hide private]
[frames] | no frames]

Source Code for Module pyxb.utils.templates

  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   
66 -def _bodyIfDefinedPattern (match_object, dictionary):
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
83 -def _bodyConditionalPattern (match_object, dictionary):
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
99 -def replaceInText (text, **dictionary):
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