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

Source Code for Module pyxb.utils.templates

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