yat.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # @brief YAT: YAml Template text processor
00004 # @date $Date: 2008-02-09 20:04:27 $
00005 # @author Norkai Ando <n-ando@aist.go.jp>
00006 #
00007 # Copyright (C) 2008 Noriaki Ando, All rights reserved.
00008 #
00009 # $Id: yat.py 775 2008-07-28 16:14:45Z n-ando $
00010 #
00011 
00012 #
00013 # Usage:
00014 #------------------------------------------------------------
00015 # import yaml
00016 # import yat
00017 #
00018 # dict   = yaml.load(open(filename, "r").read())
00019 # t      = yat.Template(template, "\[", "\]")
00020 # result = t.generate(dict)
00021 #------------------------------------------------------------
00022 #
00023 # 1. Simple directive:
00024 #    [dictionary_key]
00025 #
00026 #    Nested dictionaries can be expressed by dotted expression.
00027 #
00028 # example:
00029 # dict = {"a": "This is a",
00030 #         "b": {"1": "This is b.1",
00031 #               "2": "This is b.2"}
00032 #        }
00033 #
00034 # template:
00035 # [a]
00036 #
00037 # [b.1]
00038 #
00039 # [b.2]
00040 #
00041 # result:
00042 # This is a
00043 # This is b.1
00044 # This is b.2
00045 #
00046 #
00047 # 2. "for" directive:
00048 #    [for key in list] statement [endfor]
00049 #
00050 #    Iterative evaluation for listed values is performed by "for" statement.
00051 #    In iteration at each evaluation, the value of the list is assigned to
00052 #    "key". The "key" also can be the nested dictionary directive.
00053 #
00054 # example:
00055 # dict = {"list": [0, 1, 2],
00056 #         "listed_dict": [
00057 #           {"name": "x", "value": "1.0"},
00058 #           {"name": "y", "value": "0.2"},
00059 #           {"name": "z", "value": "0.1"}]}
00060 #
00061 # template:
00062 # [for lst in list]
00063 # [lst],  
00064 # [endfor]
00065 # [for lst in listed_dict]
00066 # [lst.name]: [lst.value]
00067 # 
00068 # [endfor]
00069 #
00070 # result:
00071 # 1, 2, 3,
00072 # x: 1.0
00073 # y: 0.2
00074 # x: 0.1
00075 #
00076 #
00077 # 3. "if-index" directive:
00078 #    [for key in val]
00079 #    [if-index key is first|even|odd|last|NUMBER] statement1
00080 #    [elif-index key is first|even|odd|last|NUMBER] statement2
00081 #    [endif][endfor]
00082 #
00083 #    "if-index" is used to specify the index of the "for" iteration.
00084 #    The "key" string which is defined in the "for" statement is used as index.
00085 #    A number or predefined directives such as "first", "even", "odd" and
00086 #    "last" can be used to specify the index.
00087 #
00088 # example:
00089 # dict = {"list": [0,1,2,3,4,5,6,7,8,9,10]}
00090 #
00091 # template:
00092 # [for key in list]
00093 # [if-index key is 3] [key] is hoge!!
00094 # [elif-index key is 6] [key] is foo!!
00095 # [elif-index key is 9] [key] is bar!!
00096 # [elif-index key is first] [key] is first
00097 # [elif-index key is last] Omoro-------!!!!
00098 # [elif-index key is odd] [key] is odd number
00099 # [elif-index key is even] [key] is even number
00100 # [endif]
00101 # [endfor]
00102 #
00103 # result:
00104 #  0 is first
00105 #  1 is odd number
00106 #  2 is even number
00107 #  3 is hoge!!
00108 #  4 is even number
00109 #  5 is odd number
00110 #  6 is foo!!
00111 #  7 is odd number
00112 #  8 is even number
00113 #  9 is bar!!
00114 #  Omoro-------!!!!
00115 #
00116 #
00117 # 4. "if" directive: [if key is value] text1 [else] text2 [endif]
00118 #    If "key" is "value", "text1" appears, otherwise "text2" appears.
00119 #
00120 # example:
00121 # dict = {"key1": "a", "key2": "b"}
00122 #
00123 # template:
00124 # [if key1 is a]
00125 # The key1 is "a".
00126 # [else]
00127 # This key1 is not "a".
00128 # [endif]
00129 #
00130 # result:
00131 # The key1 is "a".
00132 #
00133 #
00134 # 5. "if-any" directive: [if-any key1] text1 [else] text2 [endif]
00135 #    If the "key1" exists in the dictionary, "text1" appears, otherwise
00136 #    "text2" appears.
00137 #
00138 # example:
00139 # dict = {"key1": "a", "key2": "b"}
00140 #
00141 # template:
00142 # [if-any key1]
00143 # key1 exists.
00144 # [endif][if-any key3]
00145 # key3 exists.
00146 # [else]
00147 # key3 does not exists.
00148 # [endif]
00149 #
00150 # result:
00151 # key1 exists.
00152 # key3 does not exists.
00153 #
00154 #
00155 # 6. bracket and comment:
00156 #    [[] is left bracket if begin mark is "["
00157 #    [# comment ] is comment if begin/end marks are "[" and "]"
00158 #
00159 # example:
00160 # dict = {}
00161 #
00162 # template:
00163 # [[]bracket]
00164 # [# comment]
00165 #
00166 # result:
00167 # [bracket]
00168 #
00169 import string
00170 import re
00171 from types import StringType, IntType, FloatType, DictType, ListType, ClassType
00172 import sys
00173 
00174 class Template:
00175     """
00176     usage:
00177       tempalte_text = read template text from file
00178       dictionary    = create dictionaly by using yaml
00179       t = Template(tempalte_text)
00180       generated_text = t.generate(dictionary)
00181 
00182     """
00183     
00184     def __init__(self, template, begin_mark="\[", end_mark="\]"):
00185         self.__procs = [self.__proc_text,
00186                         self.__proc_cmd,
00187                         self.__proc_bracket]
00188         self.template = template
00189 
00190         # regular expression to devide text into DIRECTIVE, BRACKET and COMMENT
00191         #
00192         # default:
00193         # START_MARK: "["
00194         # END_MARK  : "]"
00195         # -> START_MARK and END_MARK can be given in ctor
00196         #
00197         # ITEM: (?:"(?:[^\\"]|\\.)*"|[-\w.]+)
00198         # \[(ITEM(?: +ITEM)*)\]|(\[\[\])|\[#[^\]]*\]
00199         # ~~~~~~~~(1)~~~~~~ ~~(2)~~~ ~~~(3)~~~~~
00200         # (1) COMMAND  : '[' ITEM (whitespace ITEM)* ']
00201         #     ITEM     : STRING | NAME
00202         #     STRING   : '"' (not-slash-or-dquote | '\' anychar)* '"'
00203         #     NAME     : (alphanum | '_' | '-' | '.')+
00204         # (2) BEGIN_MARK_ESCAPE : '[[]'
00205         # (3) COMMENT  : '[#' not-rbracket
00206         #        
00207         # re_item      = r'(?:"(?:[^\\"]|\\.)*"|[-\w.]+)'
00208         # re_command   = r'\[(%s(?: +%s)*)\]' % (re_item, re_item)
00209         # re_beginmark = r'\[\[\]'
00210         # re_comment   = r'\[#[^\]]*\]'
00211         # re_parse     = re.compile(r'%s|(%s)|%s' 
00212         #                     % (re_command, re_beginmark, re_comment))
00213         # re_args      = re.compile(r'"(?:[^\\"]|\\.)*"|[-\w.]+')
00214         #
00215         #
00216         re_item      = r'(?:"(?:[^\\"]|\\.)*"|[-\w.:]+)'
00217         re_command   = r'%s(%s(?: +%s)*)%s' % \
00218             (begin_mark, re_item, re_item, end_mark)
00219         re_bracket   = r'%s%s%s' % \
00220             (begin_mark, begin_mark, end_mark)
00221         re_comment   = r'%s#[^%s]*%s' % \
00222             (begin_mark, end_mark, end_mark)
00223         self.begin_mark = begin_mark.replace("\\","")
00224         self.re_parse = re.compile(r'%s|(%s)|%s' % \
00225                                        (re_command, re_bracket, re_comment))
00226         self.re_args  = re.compile(r'"(?:[^\\"]|\\.)*"|[-\w.:]+')
00227         self.re_number = re.compile(r'[0-9]+')
00228 
00229         # tokenize input text
00230         self.token = self.re_parse.split(self.template)
00231         self.token_len  = len(self.token)
00232         
00233         # initialize variables
00234         self.script = program
00235         self.indent = 4
00236         self.script_level  = 2
00237         self.level = 0
00238         self.index = 0
00239         self.cmd_cxt = []
00240 
00241         # parse token
00242         self.__parse_template(self.token)
00243 
00244         return
00245 
00246     def generate(self, dict):
00247         # eval generated script
00248         exec(self.script)
00249         # script includes Generator class
00250         gen = Generator(self.token, dict)
00251         # execute generated script
00252         return gen.generate()
00253 
00254     def get_script(self):
00255         return self.script
00256 
00257     def __push_level(self):
00258         self.level += 1
00259 
00260     def __pop_level(self):
00261         self.level -= 1
00262 
00263     def __write_cmd(self, cmd):
00264         tmp_cmd  = self.__indent()
00265         tmp_cmd += "self.set_index(%s)\n" % (self.index)
00266         self.script += tmp_cmd
00267         self.__write_cmd_noindex(cmd)
00268 
00269     def __write_cmd_noindex(self, cmd):
00270         tmp_cmd  = self.__indent()
00271         tmp_cmd += cmd + "\n"
00272         self.script += tmp_cmd
00273 
00274     def __parse_template(self, dict):
00275         try:
00276             # split into (TEXT DIRECTIVE BRACKET)* TEXT
00277             self.__parse()
00278         except YATException, e:
00279             self.__print_error(e)
00280             sys.exit(-1)
00281 
00282     def __indent(self):
00283         indent = " " * ((self.script_level + self.level) * self.indent)
00284         return indent
00285 
00286     def __parse(self):
00287         while self.index < self.token_len:
00288             self.__procs[self.index % 3]()
00289             self.index += 1
00290 
00291     def __proc_text(self):
00292         if self.token[self.index] == None:
00293             return
00294         cmd_text = "self.write_token(%s)" % (self.index)
00295         self.__write_cmd(cmd_text)
00296         return True
00297  
00298     def __proc_bracket(self):
00299         if self.token[self.index] == None:
00300             return
00301         cmd_text = "self.write(\"" + self.begin_mark + "\")"
00302         self.__write_cmd(cmd_text)
00303         return True
00304             
00305     def __proc_cmd(self):
00306         cmd = self.token[self.index]
00307         try:
00308             args = self.re_args.findall(cmd)
00309         except:
00310             return
00311         self.del_nl_after_cmd()
00312         argc = len(args)
00313         if argc == 0:
00314             raise InvalidDirective(self.lineno(), "_an empty directive_ ")
00315 
00316         # simple directive
00317         if argc == 1:
00318             if   args[0] == "endfor":
00319                 self.__endfor_cmd(args)
00320                 return
00321             elif args[0] == "else":
00322                 self.__else_cmd(args)
00323                 return
00324             elif args[0] == "last":
00325                 self.__last_cmd(args)
00326                 return
00327             elif args[0] == "endif":
00328                 self.__endif_cmd(args)
00329                 return
00330             else:
00331                 self.__cmd(args)
00332                 return
00333         elif argc == 2:
00334             if args[0] == "if-any":
00335                 self.__if_any_cmd(args)
00336                 return
00337         elif argc == 4: # [for key in value]
00338             if args[0] == "for" and args[2] == "in":
00339                 self.__for_cmd(args)
00340                 return True
00341             elif args[0] == "if" and args[2] == "is":
00342                 self.__if_cmd(args)
00343             elif args[0] == "elif" and args[2] == "is":
00344                 self.__elif_cmd(args)
00345             elif args[0] == "if-index" and args[2] == "is":
00346                 self.__if_index_cmd(args)
00347             elif args[0] == "elif-index" and args[2] == "is":
00348                 self.__elif_index_cmd(args)
00349             else:
00350                 raise InvalidDirective(self.lineno(), cmd)
00351         else:
00352             raise InvalidDirective(self.lineno(), cmd)
00353         return True
00354 
00355     def __cmd(self, args):
00356         cmd_text = "self.write_dict(\"%s\")" % (args[0])
00357         self.__write_cmd(cmd_text)
00358 
00359     #------------------------------------------------------------
00360     # [for] commands
00361     # - for
00362     # - last
00363     # - endfor
00364     #------------------------------------------------------------
00365     def __for_cmd(self, args):
00366         """
00367         The following [for] directive
00368           [for tmp_key in directive]
00369         is converted into the following python command.
00370           for i in len(directive):
00371               self.dicts.append({tmp_key: ditective[i])
00372         and, endfor directive terminate as the following,
00373               self.dicts.pop()
00374         """
00375         key = args[1]
00376         directive = args[3]
00377         # (key)     : variable string of index variable for [for] block
00378         # (key)_list: list value of specified directive
00379         # (key)_len : length of the list
00380         cmd_text = "%s_list = self.get_list(\"%s\")" % (key, directive)
00381         self.__write_cmd(cmd_text)
00382         cmd_text = "%s_len = len(%s_list)" % (key, key)
00383         self.__write_cmd(cmd_text)
00384         cmd_text = "for %s_index in range(len(%s_list)):" % (key, key)
00385         self.__write_cmd(cmd_text)
00386         self.__push_level()
00387         cmd_text = "self.push_dict({\"%s\": %s_list[%s_index]})" \
00388             % (key, key, key)
00389         self.__write_cmd(cmd_text)
00390         self.cmd_cxt.append("for")
00391 
00392     def __endfor_cmd(self, args):
00393         try:
00394             cxt = self.cmd_cxt.pop()
00395             if cxt != "for":
00396                 raise UnmatchedBlock(self.lineno(), "endfor")
00397             self.__write_cmd("self.pop_dict()")
00398             self.__pop_level()
00399         except:
00400             print args, self.lineno()
00401             raise UnmatchedBlock(self.lineno(), "endfor")
00402         return
00403 
00404     # end of [for] commands
00405     #------------------------------------------------------------
00406 
00407     #------------------------------------------------------------
00408     # [if] commands
00409     # - if
00410     # - if-index
00411     # - if-any
00412     #------------------------------------------------------------
00413     def __if_cmd(self, args):
00414         """
00415         The following [if] directive
00416           [if directive is string]
00417         is converted into the following python command.
00418           if self.__get_string() == "string":
00419         """
00420         directive = args[1]
00421         string = args[3]
00422         cmd_text = "if self.get_text(\"%s\") == \"%s\":" % \
00423             (directive, string)
00424         self.__write_cmd(cmd_text)
00425         self.__push_level()
00426         self.cmd_cxt.append("if")
00427         return
00428 
00429     def __elif_cmd(self, args):
00430         if self.cmd_cxt[-1] != "if":
00431             raise UnmatchedBlock(self.lineno(), "elif")
00432         directive = args[1]
00433         string = args[3]
00434         cmd_text = "elif self.get_text(\"%s\") == \"%s\":" % \
00435             (directive, string)
00436         self.__pop_level()
00437         self.__write_cmd_noindex(cmd_text)
00438         self.__push_level()
00439         return
00440 
00441     # [if-index] commands
00442     def __if_index_cmd(self, args):
00443         # [if-index KEY is [first|even|odd|last|NUMBER]]
00444         #  ~~~0~~~  ~1~  2 ~~~~~~~~~~~~~~3~~~~~~~~~~~~
00445         cmdlist = {"first": "if %s_index == 0:",
00446                    "even" : "if (%s_index %% 2) == 0:",
00447                    "odd"  : "if (%s_index %% 2) != 0:",
00448                    "last" : "if %s_index == %s_len - 1:"}
00449         key = args[1]
00450         cmd = args[3]
00451         if len(self.re_number.findall(cmd)) == 1:
00452             cmd_text = "if %s_index == %s:" % (key, cmd)
00453         elif cmdlist.has_key(cmd):
00454             if cmd == "last":
00455                 cmd_text = cmdlist[cmd] % (key,key)
00456             else:
00457                 cmd_text = cmdlist[cmd] % (key)
00458         else:
00459             raise InvalidDirective(self.lineno(), ''.join(args))
00460         self.__write_cmd(cmd_text)
00461         self.__push_level()
00462         self.cmd_cxt.append("if-index")
00463 
00464     def __elif_index_cmd(self, args):
00465         if self.cmd_cxt[-1] != "if-index":
00466             raise UnmatchedBlock(self.lineno(), "elif-index")
00467         # [elif-index KEY is [first|even|odd|last|NUMBER]]
00468         #  ~~~0~~~  ~1~  2 ~~~~~~~~~~~~~~3~~~~~~~~~~~~
00469         cmdlist = {"first": "elif %s_index == 0:",
00470                    "even" : "elif (%s_index %% 2) == 0:",
00471                    "odd"  : "elif (%s_index %% 2) != 0:",
00472                    "last" : "elif %s_index == %s_len - 1:"}
00473         key = args[1]
00474         cmd = args[3]
00475         if len(self.re_number.findall(cmd)) == 1:
00476             cmd_text = "elif %s_index == %s:" % (key, cmd)
00477         elif cmdlist.has_key(cmd):
00478             if cmd == "last":
00479                 cmd_text = cmdlist[cmd] % (key,key)
00480             else:
00481                 cmd_text = cmdlist[cmd] % (key)
00482         else:
00483             raise InvalidDirective(self.lineno(), ' '.join(args))
00484         self.__pop_level()
00485         self.__write_cmd_noindex(cmd_text)
00486         self.__push_level()
00487 
00488     # [if-any] command
00489     def __if_any_cmd(self, args):
00490         directive = args[1]
00491         cmd_text = "if self.has_key(\"%s\"):" % (directive)
00492         self.__write_cmd(cmd_text)
00493         self.__push_level()
00494         self.cmd_cxt.append("if-any")
00495         return
00496 
00497     def __elif_any_cmd(self, args):
00498         if self.cmd_cxt[-1] != "if-any":
00499             raise UnmatchedBlock(self.lineno(), "elif-any")
00500         directive = args[1]
00501         cmd_text = "if self.has_key(\"%s\"):" % (directive)
00502         self.__pop_level()
00503         self.__write_cmd_noindex(cmd_text)
00504         self.__push_level()
00505         return
00506 
00507     # [else], [endif] commands
00508     def __else_cmd(self, args):
00509         if self.cmd_cxt[-1] != "if" and self.cmd_cxt[-1] != "if-index" \
00510                 and self.cmd_cxt[-1] != "if-any":
00511             raise UnmatchedBlock(self.lineno(), "else")
00512         self.__pop_level()
00513         self.__write_cmd_noindex("else:")
00514         self.__push_level()
00515         return
00516 
00517     def __endif_cmd(self, args):
00518         if self.cmd_cxt[-1] != "if" and self.cmd_cxt[-1] != "if-index" \
00519                 and self.cmd_cxt[-1] != "if-any":
00520             raise UnmatchedBlock(self.lineno(), "endif")
00521         self.cmd_cxt.pop()
00522         self.__pop_level()
00523         return
00524     # end of [if] commands
00525     #------------------------------------------------------------
00526 
00527     def __print_error(self, e):
00528         print "Parse Error: line", e.lineno, "in input data"
00529         print "  " + ''.join(nesteditem(e.value))
00530         lines = self.template.split("\n")
00531         length = len(lines)
00532         print "------------------------------------------------------------"
00533         for i in range(1,10):
00534             l = e.lineno - 6 + i
00535             if l > 0 and l < length:
00536                 print lines[l]
00537                 if i == 5:
00538                     uline = '~'*len(lines[l])
00539                     print uline
00540         print "------------------------------------------------------------"
00541     
00542     def del_nl_after_cmd(self):
00543         # next text index after command
00544         next = self.index + 2
00545         if next > self.token_len: return
00546         if self.token[next] == None: return
00547         text = self.token[next]
00548         tlen = len(text)
00549         if tlen > 0 and text[0] == '\n':
00550             self.token[next] = text[1:]
00551             return
00552         elif tlen > 0 and text[0] == '\r':
00553             self.token[next] = text[1:]
00554             return
00555         elif tlen > 1 and text[0:2] == '\r\n':
00556             self.token[next] = text[2:]
00557 
00558     def lineno(self):
00559         l = 1
00560         for i in range(self.index):
00561             if isinstance(self.token[i], StringType):
00562                 l += self.token[i].count('\n')
00563         for i in range(1, self.index, 3):
00564             l += 1
00565         return l
00566 
00567 
00568 #------------------------------------------------------------
00569 # Generator and GeneratorBase classes
00570 #------------------------------------------------------------
00571 program = """
00572 class Generator(GeneratorBase):
00573     def __init__(self, token, dict):
00574         GeneratorBase.__init__(self, token, dict)
00575     def generate(self):
00576         try:
00577             self.process()
00578         except YATException, e:
00579             self.print_error(e)
00580             sys.exit(-1)
00581         return self.text
00582 
00583     def process(self):
00584 """
00585 
00586 class GeneratorBase:
00587     def __init__(self, token, dict):
00588         self.token = token
00589         self.dicts = [dict]
00590         self.index = 0
00591         self.text = ""
00592 
00593     def print_error(self, e):
00594         print "\nTemplate Generation Error: line", e.lineno, "in input data"
00595         print "  " + ''.join(nesteditem(e.value))
00596         temp = ""
00597         for i, s in enumerate(self.token):
00598             if s != None:
00599                 if i % 3 == 1:
00600                     temp += "[" + s + "]\n"
00601                 else:
00602                     temp += s
00603         lines = temp.split("\n")
00604         length = len(lines)
00605         print "------------------------------------------------------------"
00606         for i in range(1,10):
00607             l = e.lineno - 6 + i
00608             if l > 0 and l < length:
00609                 print lines[l]
00610                 if i == 5:
00611                     uline = '~'*len(lines[l])
00612                     print uline
00613         print "------------------------------------------------------------"
00614         
00615     def set_index(self, index):
00616         self.index = index
00617 
00618     def push_dict(self, dict):
00619         self.dicts.append(dict)
00620 
00621     def pop_dict(self):
00622         if len(self.dicts) < 2:
00623             raise UnmatchedBlock(self.lineno(), "")
00624         self.dicts.pop()
00625 
00626     def write(self, text):
00627         self.text += text
00628 
00629     def write_dict(self, keytext):
00630         self.write(self.get_text(keytext))
00631 
00632     def write_token(self, index):
00633         self.write(self.token[index])
00634 
00635     def lineno(self):
00636         cnt = 1
00637         for i in range(0, self.index, 3):
00638             if self.token[i] != None:
00639                 cnt += self.token[i].count('\n')
00640         # count deleted '\n' after commands
00641         for i in range(1, self.index, 3):
00642             if self.token[i] != None:
00643                 cnt += 1
00644         return cnt
00645                                 
00646     def get_text(self, keytext):
00647         val = self.get_value(keytext)
00648         if isinstance(val, StringType):
00649             return val
00650         if isinstance(val, IntType) or isinstance(val, FloatType):
00651             return str(val)
00652         raise UnexpectedData(self.lineno(), "\"" + keytext + \
00653                                  "\" should have string, int or float value.")
00654 
00655     def get_list(self, keytext):
00656         val = self.get_value(keytext)
00657         if not isinstance(val, ListType):
00658             raise UnexpectedData(self.lineno(),
00659                                  "\"" + keytext + "\" should have list value.")
00660         return val
00661 
00662     def has_key(self, keytext):
00663         try:
00664             self.get_value(keytext)
00665             return True
00666         except NotFound, e:
00667             return False
00668 
00669     def get_value(self, keytext):
00670         keys = keytext.split('.')
00671         for i in range(len(self.dicts) - 1, -1, -1):
00672             dict_value = self.get_dict_value(keys, self.dicts[i])
00673             if dict_value != None:
00674                 return dict_value
00675         raise NotFound(self.lineno(), keytext) 
00676 
00677     def get_dict_value(self, keys, dict):
00678         length = len(keys)
00679         d = dict
00680         for i in range(length):
00681             if isinstance(d, DictType) and d.has_key(keys[i]):
00682                 d = d[keys[i]]
00683             else:
00684                 return None
00685         return d
00686 
00687 
00688 #------------------------------------------------------------
00689 # Exceptions                                
00690 #------------------------------------------------------------
00691 class YATException(Exception):
00692     pass
00693 
00694 class UnknownError(YATException):
00695     def __init__(self, lineno):
00696         self.lineno = lineno
00697         self.value = "Unknown error."
00698 
00699 class UnmatchedBlock(YATException):
00700     def __init__(self, lineno, msg):
00701         self.lineno = lineno
00702         self.value = "Unmatched block error: " + msg
00703 
00704 class UnexpectedData(YATException):
00705     def __init__(self, lineno, msg):
00706         self.lineno = lineno
00707         self.value = msg
00708 
00709 class NotFinalElement(YATException):
00710     def __init__(self, dictkey, dictvalue):
00711         self.value = "Specified key is not final element: ",\
00712             dictkey, "=>", dictvalue
00713 
00714 class InvalidDirective(YATException):
00715     def __init__(self, lineno, directive):
00716         self.lineno = lineno
00717         self.value = "Invalid directive: \"[" + directive + "]\""
00718 
00719 class UnmatchedData(YATException):
00720     def __init__(self, lineno, description):
00721         self.lineno = lineno
00722         self.value = "Unmatched data and input: ", description
00723 
00724 class NotFound(YATException):
00725     def __init__(self, lineno, description):
00726         self.lineno = lineno
00727         self.value = "Value not found for: \"" + description + "\""
00728 
00729 #------------------------------------------------------------
00730 # other functions
00731 #------------------------------------------------------------
00732 def nesteditem(aList):
00733     for anItem in aList:
00734         if type(anItem)==list:
00735             for subitem in nesteditem(anItem):
00736                 yield subitem
00737         else:
00738             yield anItem
00739 
00740 
00741 
00742 if __name__ == "__main__":
00743     dict = []
00744     template = []
00745     #------------------------------------------------------------
00746     # Example 0
00747     #------------------------------------------------------------
00748     dict.append({"a": "This is a",
00749                  "b": {"1": "This is b.1",
00750                        "2": "This is b.2"}
00751                  })
00752     template.append("""[a]
00753 
00754 [b.1]
00755 
00756 [b.2]""")
00757 
00758     #------------------------------------------------------------
00759     # Example 1
00760     #------------------------------------------------------------
00761     dict.append({"list": [0, 1, 2],
00762                  "listed_dict": [
00763                 {"name": "x", "value": "1.0"},
00764                 {"name": "y", "value": "0.2"},
00765                 {"name": "z", "value": "0.1"}]})
00766     template.append("""[for lst in list]
00767 [lst],  
00768 [endfor]
00769 [for lst in listed_dict]
00770 [lst.name]: [lst.value]
00771 
00772 [endfor]""")
00773 
00774     #------------------------------------------------------------
00775     # Example 2
00776     #------------------------------------------------------------
00777     dict.append({"list": [0,1,2,3,4,5,6,7,8,9,10]})
00778     template.append("""[for key in list]
00779 [if-index key is 3] [key] is hoge!!
00780 [elif-index key is 6] [key] is foo!!
00781 [elif-index key is 9] [key] is bar!!
00782 [elif-index key is first] [key] is first
00783 [elif-index key is last] Omoro-------!!!!
00784 [elif-index key is odd] [key] is odd number
00785 [elif-index key is even] [key] is even number
00786 [endif]
00787 [endfor]""")
00788 
00789     #------------------------------------------------------------
00790     # Example 3
00791     #------------------------------------------------------------
00792     dict.append({"key1": "a", "key2": "b"})
00793     template.append("""[if key1 is a]
00794 The key1 is "a".
00795 [else]
00796 This key1 is not "a".
00797 [endif]""")
00798 
00799     #------------------------------------------------------------
00800     # Example 4
00801     #------------------------------------------------------------
00802     dict.append({"key1": "a", "key2": "b"})
00803     template.append("""[if-any key1]
00804 key1 exists.
00805 [endif][if-any key3]
00806 key3 exists.
00807 [else]
00808 key3 does not exists.
00809 [endif]""")
00810 
00811     dict.append({})
00812     template.append("""
00813 [[]bracket]
00814 [# comment]
00815 """)
00816 
00817     import yaml
00818     if len(dict) == len(template):
00819         for i in range(len(dict)-1,len(dict)):
00820             t = Template(template[i])
00821             print "-" * 60
00822             print "Example:", i
00823             print "-" * 60
00824             print "Template:\n"
00825             print template[i]
00826             print "-" * 60
00827             print "Dictionary:\n"
00828             print yaml.dump(dict[i], default_flow_style=False)
00829             print "-" * 60
00830             print "Generated Script:\n"
00831             print t.get_script()
00832             print "-" * 60
00833             print "Generated Text:\n"
00834             print t.generate(dict[i])
00835             print ""


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Sat Jun 8 2019 18:49:07