├── .gitattributes
├── .gitignore
├── .gitmodules
├── ConfigConvertTool.py
├── LICENSE
├── README.md
├── client
├── cfg_array_example1.xml
├── cfg_array_example2.xml
├── cfg_array_example3.xml
├── cfg_object.xml
└── cfg_object1_cfg_object.xml
├── color_print.py
├── config_excel
├── A_array表示例--cfg_array.xlsx
└── A_object表示例--cfg_object.xlsx
├── decoder.py
├── lancher.bat
├── lancher.sh
├── server
├── cfg_array.erl
├── cfg_array.ex
├── cfg_array.json
├── cfg_array.lua
├── cfg_array_example1.erl
├── cfg_array_example1.ex
├── cfg_array_example1.hrl
├── cfg_array_example1.json
├── cfg_array_example1.lua
├── cfg_array_example2.erl
├── cfg_array_example2.ex
├── cfg_array_example2.hrl
├── cfg_array_example2.json
├── cfg_array_example2.lua
├── cfg_array_example3.erl
├── cfg_array_example3.ex
├── cfg_array_example3.json
├── cfg_array_example3.lua
├── cfg_object.erl
├── cfg_object.ex
├── cfg_object.json
├── cfg_object.lua
└── cfg_object1_cfg_object.ex
├── slpp
├── .gitignore
├── LICENSE
├── README.markdown
├── __init__.py
├── setup.py
├── slpp-c4d7f69af338f973c0ef21a9a06a145936367229.zip
├── slpp-c4d7f69af338f973c0ef21a9a06a145936367229
│ ├── .gitignore
│ ├── LICENSE
│ ├── README.markdown
│ ├── __init__.py
│ ├── setup.py
│ ├── slpp.py
│ └── tests.py
├── slpp.py
└── tests.py
├── writer.py
├── writer_elixir.py
├── writer_erlang_erl.py
├── writer_erlang_hrl.py
├── writer_json_array.py
├── writer_json_object.py
├── writer_lua.py
├── writer_python.py
└── writer_xml.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.zip binary
3 | *.tar.gz binary
4 | *.tar.bz2 binary
5 | *.xlsx binary
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # yongzhong office temp file
10 | $*
11 |
12 | # xlsx temp file
13 | ~*.xlsx
14 | .~*.xlsx
15 |
16 |
17 | # Distribution / packaging
18 | .Python
19 | env/
20 | build/
21 | develop-eggs/
22 | dist/
23 | downloads/
24 | eggs/
25 | .eggs/
26 | lib/
27 | lib64/
28 | parts/
29 | sdist/
30 | var/
31 | wheels/
32 | *.egg-info/
33 | .installed.cfg
34 | *.egg
35 |
36 | # PyInstaller
37 | # Usually these files are written by a python script from a template
38 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
39 | *.manifest
40 | *.spec
41 |
42 | # Installer logs
43 | pip-log.txt
44 | pip-delete-this-directory.txt
45 |
46 | # Unit test / coverage reports
47 | htmlcov/
48 | .tox/
49 | .coverage
50 | .coverage.*
51 | .cache
52 | nosetests.xml
53 | coverage.xml
54 | *.cover
55 | .hypothesis/
56 |
57 | # Translations
58 | *.mo
59 | *.pot
60 |
61 | # Django stuff:
62 | *.log
63 | local_settings.py
64 |
65 | # Flask stuff:
66 | instance/
67 | .webassets-cache
68 |
69 | # Scrapy stuff:
70 | .scrapy
71 |
72 | # Sphinx documentation
73 | docs/_build/
74 |
75 | # PyBuilder
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # pyenv
82 | .python-version
83 |
84 | # celery beat schedule file
85 | celerybeat-schedule
86 |
87 | # SageMath parsed files
88 | *.sage.py
89 |
90 | # dotenv
91 | .env
92 |
93 | # virtualenv
94 | .venv
95 | venv/
96 | ENV/
97 |
98 | # Spyder project settings
99 | .spyderproject
100 | .spyproject
101 |
102 | # Rope project settings
103 | .ropeproject
104 |
105 | # mkdocs documentation
106 | /site
107 |
108 | # mypy
109 | .mypy_cache/
110 |
111 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "slpp"]
2 | path = slpp
3 | url = https://github.com/changnet/slpp.git
4 |
--------------------------------------------------------------------------------
/ConfigConvertTool.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import time
6 | from writer import *
7 | from writer_erlang_erl import *
8 | from writer_erlang_hrl import *
9 | from writer_elixir import *
10 | from writer_lua import *
11 | from writer_xml import *
12 | from writer_json_object import *
13 | from writer_json_array import *
14 | from writer_python import *
15 | from optparse import OptionParser
16 |
17 | from decoder import ExcelDoc
18 |
19 | class Reader:
20 | # @input_path:excel文件所在目录
21 | # @srv_path :server输出目录
22 | # @clt_path :客户端输出目录
23 | # @timeout :只处理文档最后更改时间在N秒内的文档
24 | # @suffix :excel文件后缀
25 | def __init__(self,input_path,
26 | srv_path,clt_path,timeout,suffix,srv_writer,clt_writer):
27 | self.input_path = input_path
28 | self.srv_path = srv_path
29 | self.clt_path = clt_path
30 | self.timeout = timeout
31 | self.suffix = suffix
32 |
33 | self.srv_writer = None
34 | self.clt_writer = None
35 |
36 | if None != srv_writer :
37 | self.srv_writer = eval( srv_writer.capitalize() + "Writer" )
38 | if None != clt_writer :
39 | self.clt_writer = eval( clt_writer.capitalize() + "Writer" )
40 |
41 | def attention(self):
42 | print("*****************************开始导表*****************************\n")
43 |
44 | def can_read(self,file,abspath):
45 | if not os.path.isfile( abspath ): return False
46 | # ~开头的excel文件是临时文件,linux下wps临时文件以.~开头
47 | if file.startswith( "~" ) \
48 | or file.startswith( "." ) or file.startswith( "$" ): return False
49 | if "" != self.suffix and not file.endswith( self.suffix ): return False
50 |
51 | if self.timeout > 0:
52 | now = time.time()
53 | mtime = os.path.getmtime( abspath )
54 |
55 | if now - mtime > self.timeout: return False
56 |
57 | return True
58 |
59 | def read(self):
60 | if self.timeout > 0 :
61 | print("read %s files from %s modified \
62 | within %d seconds" % (self.suffix,self.input_path,self.timeout))
63 | else :
64 | print("read %s files from %s" % (self.suffix,self.input_path))
65 |
66 | if None != self.srv_path and not os.path.exists( self.srv_path ) :
67 | os.makedirs( self.srv_path )
68 | if None != self.clt_path and not os.path.exists( self.clt_path ) :
69 | os.makedirs( self.clt_path )
70 |
71 | now = time.time()
72 | file_list = os.listdir( options.input_path )
73 | for file in file_list:
74 | abspath = os.path.join( self.input_path,file )
75 | if self.can_read( file,abspath ) :
76 | self.read_one( file,abspath )
77 |
78 | print( "done,%d seconds elapsed" % ( time.time() - now ) )
79 |
80 | def read_one(self,file,abspath):
81 | doc = ExcelDoc( file,abspath )
82 | doc.decode( self.srv_path,
83 | self.clt_path,self.srv_writer,self.clt_writer )
84 |
85 | if __name__ == '__main__':
86 |
87 | parser = OptionParser()
88 |
89 | parser.add_option( "-i", "--input", dest="input_path",
90 | default="xls/",
91 | help="read all files from this path" )
92 | parser.add_option( "-s", "--srv", dest="srv_path",
93 | help="write all server file to this path" )
94 | parser.add_option( "-c", "--clt", dest="clt_path",
95 | help="write all client file to this path" )
96 | parser.add_option( "-t", "--timeout", dest="timeout",type="int",
97 | default="-1",
98 | help="only converte files modified within seconds" )
99 | parser.add_option( "-f", "--suffix", dest="suffix",
100 | default="",
101 | help="what type of file will be readed.empty mean all files" )
102 | parser.add_option( "-w","--swriter", dest="srv_writer",
103 | help="which server writer you wish to use:lua xml json" )
104 | parser.add_option( "-l","--cwriter", dest="clt_writer",
105 | help="which client writer you wish to use:lua xml json" )
106 |
107 | options, args = parser.parse_args()
108 |
109 | reader = Reader( options.input_path,options.srv_path,options.clt_path,
110 | options.timeout,options.suffix,options.srv_writer,options.clt_writer )
111 | reader.attention()
112 | reader.read()
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 AICells
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # py_exceltools
2 | python3 基于openpyxl的excel转换工具。支持xlsx文件转换为erlang,elixir,lua,json,xml,python等配置文件。
3 |
4 | 关于openpyxl库:https://pypi.python.org/pypi/openpyxl。
5 |
6 | ## python和openpyxl安装
7 | linux安装
8 | apt-get install python-pip
9 | pip install openpyxl
10 |
11 | win安装
12 |
13 | 安装python(同时安装pip并添加到Path)
14 | 安装openpyxl, 在安装python后在cmd中运行: pip install openpyxl
15 |
16 | # 使用
17 | lancher.bat(win)和lancher.sh(linux)为对应运行脚本。
18 | 当前配置了用于参考的参数来转换example.xlsx,
19 | 可在对应server、client输出文件夹查看生成配置效果。
20 |
21 | 参数:
22 | --input :需要转换的excel文件所在目录
23 | --srv : 服务端配置文件输出目录
24 | --clt : 客户端配置文件输出目录
25 | --timeout : 需要转换的excel文件最后更新时间距当前时间秒数。-1转换所有
26 | --suffix :excel文件后缀,通常为.xlsx
27 | --swriter : 服务端配置文件转换器,可以指定为: erlanghrl,erlangerl,elixir,lua,jsonarray,jsonobject,xml,python
28 | --cwriter : 客户端配置文件转换器,可以指定为: erlanghrl,erlangerl,elixir,lua,jsonarray,jsonobject,xml,python
29 |
30 | 注:对于client和server,如果未配置输出目录或转换器,则不会导出。
31 |
32 | # 数据类型
33 | 支持int(int64), number(float), string, tuple, list, dict, json、lua
34 | 其中tuple, list, dict 为 python原生数据结构 json 为json数据类型 Lua为 lua table
35 | # 数据格式示范(可以参考本工具自带的示例配置表)
36 | int 整数 1,2,1000 64位
37 | number 整数或者小数都OK
38 | string 字符串 excel表中配置时不需要额外加双引号
39 | tuple (元素, 元素, ...) 元素可以为 int number string tuple list dict
40 | list [元素, 元素, ...] 元素可以为 int number string tuple list dict
41 | dict [key:value, key:value, ...] key可以为 int number string tuple value可以为 int number string tuple list dict
42 | 特别注意该类型的使用 因为在一些语言中 对应dict类似的类型的key不支持 int 比如 jsonarray和xml,如果在转成jsonarray和xml时key不能配置为int和number
43 | json {key:value, key:value, ...}该类型为json的对象类型 Key为字符串, Value可以为任意Json数据类型即可以是对象,数字,基本数据类型。
44 | lua 该类型为lua的table类型
45 | 其中 list dict json 三种数据格式可以互相嵌套
46 | 转换时会将这些数据类型转换为其他语言支持的数据类型,另外注意点是一些其他语言的一些限制
47 | 比如 json不能用数字做为对象的Key(), xml的也不能用数字作为标签, 在配置的时候需要注意
48 | 而且导出xml和jsonjsonarray都是用的库,出错的时候不太好找到对应配置错误的数据,需要配置前
49 | 就额外注意,以免不必要的懵逼和浪费时间,策划不太明白的可以请教程序或者百度
50 |
51 | # 打包exe
52 | 部署时,可以将python打包成exe。建议使用pyinstaller。
53 | pyinstaller3.2.1尚不支持python3.6.1,建议使用python 3.5。
54 |
55 | pip install pyinstaller
56 | pyinstaller -F -c ConfigConvertTool.py
57 |
58 | excel文件名命名格式
59 | 为了表名的可视化和可理解性,文件命名支持 MMM-NNN.xlsx的方式。MMM可以是任意字符(一般为文件中文名,但是不用下划线结尾),
60 | 作为文件名的注释性描述。NNN只能是数字,字母和下划线(不能以下划线开头和数字开头),作为导出的配置以NNN做为表名前缀
61 | excel sheet命名格式
62 | 为了考虑策划会使用一个excel配置同一的功能的多个配置子表,且方便导出和查看,sheet命名为YYY-XXX或者 YYY+XXX,
63 | 或者YYY (里面不包含 "+"""-"), YYY可以为任意字符(一般为中文描述),XXX为导出配置的表名后缀,
64 | 当sheet命名为 YYY-XXX或者 YYY+XXX时 导出文件名为: NNN_XXX.lang(此种命名一般用于 一个excel配置多个需要导出的sheet页签)
65 | 当sheet命名为 YYY 时 导出文件名为: NNN.lang (此种命名用法仅仅用于一个excel只配置一个需要导出的sheet页签)
66 | lang为目标语言的后缀名
67 | 具体示例
68 | A_arrary表示例--cfg_array.xlsx 前缀Y可以用方便排序显示 更多具体参见配置excel示例
69 | * 在string中无法直接使用换行等特殊称号。请用\n等转义字符替代。
70 | * 由于xml并不存在数组等结构,不建议使用。
71 | * 工具会检测server和client标识。如果不存在,则不导出些表。方便策划做备注
72 |
--------------------------------------------------------------------------------
/client/cfg_array_example1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
-
6 |
- 1
7 | - 700
8 |
9 | -
10 |
- 2
11 | - 800
12 |
13 | -
14 |
- 3
15 | - 900
16 |
17 |
18 | 从小城镇
19 | 1001
20 | 88
21 | 黑切+蓝盾
22 | pos1
23 | 1
24 |
25 | -
26 |
27 |
-
28 |
- 1
29 | - 700
30 |
31 | -
32 |
- 2
33 | - 800
34 |
35 | -
36 |
- 3
37 | - 900
38 |
39 |
40 | 有钱就可以买
41 | 1001
42 | 88
43 | 黑切+蓝盾
44 | pos1
45 | 2
46 |
47 | -
48 |
49 |
-
50 |
- 1
51 | - 700
52 |
53 | -
54 |
- 2
55 | - 800
56 |
57 | -
58 |
- 3
59 | - 900
60 |
61 |
62 | 有钱就可以买
63 | 1001
64 | 89
65 | 黑切+蓝盾
66 | pos1
67 | 89
68 |
69 | -
70 |
71 |
-
72 |
- 1
73 | - 700
74 |
75 | -
76 |
- 2
77 | - 800
78 |
79 | -
80 |
- 3
81 | - 900
82 |
83 |
84 | 有钱就可以买
85 | 1001
86 | 88
87 | 黑切+蓝盾
88 | pos2
89 | 88.9
90 |
91 | -
92 |
93 |
-
94 |
- 1
95 | - 700
96 |
97 | -
98 |
- 2
99 | - 800
100 |
101 | -
102 |
- 3
103 | - 900
104 |
105 |
106 | 有钱就可以买
107 | 1001
108 | 89
109 | 黑切+蓝盾
110 | pos2
111 | 89
112 |
113 | -
114 |
115 |
-
116 |
- 1
117 | - 700
118 |
119 | -
120 |
- 2
121 | - 800
122 |
123 | -
124 |
- 3
125 | - 901
126 |
127 |
128 | 有钱就可以买
129 | 1002
130 | 88
131 | 黑切+蓝盾
132 | pos1
133 | 88
134 |
135 | -
136 |
137 |
-
138 |
- 1
139 | - 700
140 |
141 | -
142 |
- 2
143 | - 800
144 |
145 | -
146 |
- 3
147 | - 900
148 |
149 |
150 | 有钱就可以买
151 | 1002
152 | 89
153 | 黑切+蓝盾
154 | pos1
155 | 89
156 |
157 | -
158 |
159 |
-
160 |
- 1
161 | - 700
162 |
163 | -
164 |
- 2
165 | - 800
166 |
167 | -
168 |
- 3
169 | - 901
170 |
171 |
172 | 有钱就可以买
173 | 1002
174 | 90
175 | 黑切+蓝盾
176 | pos1
177 | 90
178 |
179 | -
180 |
181 |
-
182 |
- 1
183 | - 700
184 |
185 | -
186 |
- 2
187 | - 800
188 |
189 | -
190 |
- 3
191 | - 901
192 |
193 |
194 | 有钱就可以买
195 | 1002
196 | 88
197 | 黑切+蓝盾
198 | pos2
199 | 88
200 |
201 | -
202 |
203 |
-
204 |
- 1
205 | - 700
206 |
207 | -
208 |
- 2
209 | - 800
210 |
211 | -
212 |
- 3
213 | - 900
214 |
215 |
216 | 有钱就可以买
217 | 1002
218 | 89
219 | 黑切+蓝盾
220 | pos2
221 | 89
222 |
223 | -
224 |
225 |
-
226 |
- 1
227 | - 700
228 |
229 | -
230 |
- 2
231 | - 800
232 |
233 | -
234 |
- 3
235 | - 901
236 |
237 |
238 | 有钱就可以买
239 | 1002
240 | 90
241 | 黑切+蓝盾
242 | pos2
243 | 90
244 |
245 | -
246 |
247 |
-
248 |
- 1
249 | - 700
250 |
251 | -
252 |
- 2
253 | - 800
254 |
255 | -
256 |
- 3
257 | - 902
258 |
259 |
260 | 有钱就可以买
261 | 1003
262 | 85
263 | 黑切+蓝盾
264 | pos1
265 | 85
266 |
267 | -
268 |
269 |
-
270 |
- 1
271 | - 700
272 |
273 | -
274 |
- 2
275 | - 800
276 |
277 | -
278 |
- 3
279 | - 903
280 |
281 |
282 | 有钱就可以买
283 | 1004
284 | 80
285 | 黑切+蓝盾
286 | pos1
287 | 80
288 |
289 |
290 |
--------------------------------------------------------------------------------
/client/cfg_array_example2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
-
6 |
- 1
7 | - 700
8 |
9 | -
10 |
- 2
11 | - 800
12 |
13 | -
14 |
- 3
15 | - 900
16 |
17 | -
18 |
19 |
- 4
20 | - 100
21 |
22 |
23 |
24 |
25 | - 1
26 | - 2
27 | - 3
28 |
29 |
30 | 1
31 | 3
32 | 2
33 |
34 |
35 | - 来源1
36 | - 来源2
37 | - 来源4
38 |
39 | 1
40 |
41 | -
42 | 1
43 | 10001
44 | 1
45 |
46 | -
47 | 1
48 | 10001
49 | 1
50 |
51 |
52 | examp1001
53 |
54 | -
55 |
56 |
-
57 |
- 1
58 | - 700
59 |
60 | -
61 |
- 2
62 | - 800
63 |
64 | -
65 |
- 3
66 | - 901
67 |
68 | -
69 |
70 |
- 5
71 | - 100
72 |
73 |
74 |
75 |
76 | - 1
77 | - 2
78 | - 3
79 |
80 |
81 | 1
82 | 3
83 | 2
84 |
85 |
86 | - 来源1
87 | - 来源2
88 | - 来源4
89 |
90 | 2
91 |
92 | 1
93 | 10001
94 | 1
95 |
96 | examp1002
97 |
98 | -
99 |
100 |
-
101 |
- 1
102 | - 700
103 |
104 | -
105 |
- 2
106 | - 800
107 |
108 | -
109 |
- 3
110 | - 902
111 |
112 | -
113 |
114 |
- 6
115 | - 100
116 |
117 |
118 |
119 |
120 | - 1
121 | - 2
122 | - 3
123 |
124 |
125 | 1
126 | 3
127 | 2
128 |
129 |
130 | - 来源1
131 | - 来源2
132 | - 来源5
133 |
134 | 3
135 |
136 | - 1
137 | - 2
138 | - 3
139 | - 4
140 | - 5
141 | - 6
142 | - 7
143 | - 8
144 | - 9
145 | - 9
146 | - 9
147 | - 9
148 | - 9
149 | - 9
150 | - 9
151 | - 9
152 | - 9
153 | - 9
154 |
155 | examp1003
156 |
157 | -
158 |
159 |
-
160 |
- 1
161 | - 700
162 |
163 | -
164 |
- 2
165 | - 800
166 |
167 | -
168 |
- 3
169 | - 903
170 |
171 | -
172 |
173 |
- 7
174 | - 100
175 |
176 |
177 |
178 |
179 | - 1
180 | - 2
181 | - 3
182 |
183 |
184 | 1
185 | 3
186 | 2
187 |
188 |
189 | - 来源1
190 | - 来源2
191 | - 来源6
192 |
193 | 4
194 |
195 | - 测试数据
196 | - 测试数据2
197 | - 测试数据3
198 |
199 | examp1004
200 |
201 | -
202 |
203 |
-
204 |
- 1
205 | - 700
206 |
207 | -
208 |
- 2
209 | - 800
210 |
211 | -
212 |
- 3
213 | - 903
214 |
215 | -
216 |
217 |
- 7
218 | - 100
219 |
220 |
221 |
222 |
223 | - 1
224 | - 2
225 | - 3
226 |
227 |
228 | 1
229 | 3
230 | 2
231 |
232 |
233 | - 来源1
234 | - 来源2
235 | - 来源6
236 |
237 | 5
238 |
239 | - test
240 |
241 | examp1004
242 |
243 |
244 |
--------------------------------------------------------------------------------
/client/cfg_array_example3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 啦啦啦!!!
4 |
5 |
--------------------------------------------------------------------------------
/client/cfg_object.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1001
4 | 100.1
5 | 100
6 |
7 | -
8 |
- 1001
9 | - 20
10 |
11 | -
12 |
- 1002
13 | - 20
14 |
15 | -
16 |
- 1003
17 | - 30
18 |
19 |
20 |
21 | -
22 |
- 1001
23 | - 10
24 |
25 | -
26 |
- 1002
27 | - 20
28 |
29 |
30 |
31 |
32 | - 7003
33 | - 1
34 |
35 |
36 | - 3006
37 | - 99
38 |
39 |
40 | - 1001
41 | - 20
42 |
43 | 这就是一个测试
44 |
45 |
46 | -
47 |
- 1001
48 | - 20
49 |
50 | -
51 |
- 3006
52 | - 99
53 |
54 | -
55 |
- 7003
56 | - 1
57 |
58 | -
59 |
60 |
- 12356
61 | - 654321
62 |
63 |
64 |
65 |
66 | - 1
67 | - 2
68 | - 3
69 | - 4
70 | - 5
71 | - 6
72 | - 7
73 | - 8
74 | - 9
75 | - 9
76 | - 9
77 | - 9
78 | - 9
79 | - 9
80 | - 9
81 | - 9
82 | - 9
83 | - 9
84 |
85 | 前面字段为errorID,这里是错误描述,是的object配置的server,client字段名还支持数字作为key(但是转出格式为xml和jsonarray时就不支持了)
86 | 18:00:0
87 | 90
88 |
89 |
--------------------------------------------------------------------------------
/client/cfg_object1_cfg_object.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1001
4 | 100.1
5 | 100
6 |
7 | -
8 |
- 1001
9 | - 20
10 |
11 | -
12 |
- 1002
13 | - 20
14 |
15 | -
16 |
- 1003
17 | - 30
18 |
19 |
20 |
21 | -
22 |
- 1001
23 | - 10
24 |
25 | -
26 |
- 1002
27 | - 20
28 |
29 |
30 |
31 |
32 | - 7003
33 | - 1
34 |
35 |
36 | - 3006
37 | - 99
38 |
39 |
40 | - 1001
41 | - 20
42 |
43 | 这就是一个测试
44 |
45 |
46 | -
47 |
- 1001
48 | - 20
49 |
50 | -
51 |
- 3006
52 | - 99
53 |
54 | -
55 |
- 7003
56 | - 1
57 |
58 | -
59 |
60 |
- 12356
61 | - 654321
62 |
63 |
64 |
65 |
66 | - 1
67 | - 2
68 | - 3
69 | - 4
70 | - 5
71 | - 6
72 | - 7
73 | - 8
74 | - 9
75 | - 9
76 | - 9
77 | - 9
78 | - 9
79 | - 9
80 | - 9
81 | - 9
82 | - 9
83 | - 9
84 |
85 | 前面字段为errorID,这里是错误描述,是的object配置的server,client字段名还支持数字作为key(但是转出格式为xml和jsonarray时就不支持了)
86 | fgfdg
87 | 90
88 |
89 |
--------------------------------------------------------------------------------
/color_print.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erlyshare/ConfigConvertTool/3ac2b7fdd8b09cd98e75fac03f589e0cd5881741/color_print.py
--------------------------------------------------------------------------------
/config_excel/A_array表示例--cfg_array.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erlyshare/ConfigConvertTool/3ac2b7fdd8b09cd98e75fac03f589e0cd5881741/config_excel/A_array表示例--cfg_array.xlsx
--------------------------------------------------------------------------------
/config_excel/A_object表示例--cfg_object.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erlyshare/ConfigConvertTool/3ac2b7fdd8b09cd98e75fac03f589e0cd5881741/config_excel/A_object表示例--cfg_object.xlsx
--------------------------------------------------------------------------------
/decoder.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import re
6 | import sys
7 | import json
8 | import openpyxl
9 | import color_print
10 |
11 | from slpp.slpp import slpp as lua
12 |
13 | # array数组模式下,各个栏的分布
14 | # 1、2行是文档注释,不导出
15 | ACMT_ROW = 3 # comment row 注释
16 | ATPE_ROW = 4 # type row 类型
17 | ASRV_ROW = 5 # server row 服务器
18 | ACLT_ROW = 6 # client row 客户端
19 | AKEY_COL = 1 # key column key所在列
20 |
21 | # object(kv)模式下,各个栏的分布
22 | OCMT_COL = 1 # comment column 注释
23 | OTPE_COL = 2 # type column 类型
24 | OSRV_COL = 3 # server column 服务器
25 | OCLT_COL = 4 # client column 客户端
26 | OCTX_COL = 5 # content column 内容所在列
27 |
28 | # 1、2行是文档注释,不导出
29 | OFLG_ROW = 3 # flag row server client所在行
30 |
31 | SRV_FLAG = "server"
32 | CLT_FLAG = "client"
33 |
34 | SHEET_FLAG_ROW = 3 # 3列1行表示是array 还是object 或者是不用导出的表
35 | SHEET_FLAG_COL = 1 # 3列1行表示是array 还是object 或者是不用导出的表
36 |
37 | # 用于标识表的类型 不是这两种就不会导出数据
38 | ARRAY_FLAG = "array" # 标识表的是array类型的表
39 | OBJECT_FLAG = "object" # 标识表的是object类型的表
40 |
41 | KEY_FLAG = "$key_" # array表的 作为Key字段的前缀标识
42 | KEY_FLAG_LEN = 5 # array表的 作为Key字段的前缀标识长度 用于分割字符串
43 |
44 | # 支持的数据类型
45 | # "int":1,"number":2,"int64":3,"string":4, "tuple":5, "list":6, "dict":7 为python原生数据格式
46 | # "json":8,"lua":9 为json和lua的数据格式
47 | # excel配置的时候 对应类型字段 填入对应数据类型的有效数据格式的数据就OK
48 | TYPES = { "int":1,"number":2,"int64":3,"string":4, "tuple":5, "list":6, "dict":7, "json":8,"lua":9}
49 |
50 | try:
51 | basestring
52 | except NameError:
53 | basestring = str
54 |
55 | # python3中没有uincode了,int能表示int64
56 | try:
57 | long
58 | except NameError:
59 | long = int
60 |
61 | # python3中没有unicode了
62 | try:
63 | unicode
64 | except NameError:
65 | unicode = str
66 |
67 | # 类型转换器
68 | class ValueConverter(object):
69 | def __init__(self):
70 | pass
71 |
72 | # 在python中,字符串和unicode是不一样的。默认从excel读取的数据都是unicode。
73 | # str可以通过decode转换为unicode
74 | # ascii' codec can't encode characters
75 | # 这个函数在python3中没用
76 | def to_unicode_str( self,val ):
77 | if isinstance( val,str ) :
78 | return val
79 | elif isinstance( val,unicode ) :
80 | return val
81 | else :
82 | return str( val ).decode("utf8")
83 |
84 | def to_value(self,val_type,val):
85 | if "int" == val_type :
86 | return int( val )
87 | elif "int64" == val_type :
88 | return long( val )
89 | elif "number" == val_type :
90 | # 去除带小数时的小数点,100.0 ==>> 100
91 | # number就让它带小数点吧,不然强类型的配置无法正确识别出来
92 | # if long( val ) == float( val ) : return long( val )
93 | return float( val )
94 | elif "string" == val_type :
95 | return self.to_unicode_str( val )
96 | elif "json" == val_type :
97 | return json.loads( val )
98 | elif "lua" == val_type :
99 | return lua.decode( val )
100 | elif "tuple" == val_type :
101 | return tuple(eval(val))
102 | elif "list" == val_type :
103 | return list(eval(val))
104 | elif "dict" == val_type :
105 | return dict(eval(val))
106 | else :
107 | self.raise_error( "invalid type",value )
108 |
109 | class Sheet(object):
110 |
111 | def __init__(self,base_name,wb_sheet,srv_writer,clt_writer):
112 |
113 | self.types = [] # 记录各列字段的类型
114 |
115 | self.srv_writer = srv_writer
116 | self.clt_writer = clt_writer
117 |
118 | self.srv_fields = [] #服务端各列字段名
119 | self.clt_fields = [] #客户端各列字段名
120 | self.srv_comment = {} # 服务器字段注释
121 | self.clt_comment = {} # 客户端字段注释
122 |
123 | self.srv_keys = {} # 服务器key
124 | self.clt_keys = {} # 客户端key
125 |
126 |
127 | self.converter = ValueConverter()
128 |
129 | self.wb_sheet = wb_sheet
130 | self.base_name = base_name
131 |
132 | match_list = re.findall("[a-zA-Z0-9_]+$",base_name)
133 | if None == match_list or 1 != len(match_list):
134 | Exception( base_name,"not a legal file name" )
135 |
136 | self.base_file_name = match_list[0]
137 |
138 | # 记录出错时的行列,方便策划定位问题
139 | self.error_row = 0
140 | self.error_col = 0
141 |
142 | # 记录出错位置
143 | def mark_error_pos(self,row,col):
144 | if row > 0 : self.error_row = row
145 | if col > 0 : self.error_col = col
146 |
147 | # 发起一个解析错误
148 | def raise_error(self,what,val):
149 | excel_info = format("DOC:%s,SHEET:%s,ROW:%d,COLUMN:%d" % \
150 | (self.base_name,self.wb_sheet.title,self.error_row,self.error_col))
151 | raise Exception( what,val,excel_info )
152 |
153 | def to_value(self,val_type,val):
154 | try:
155 | return self.converter.to_value(val_type,val)
156 | except Exception :
157 | t, e = sys.exc_info()[:2]
158 | self.raise_error( "ConverError",e )
159 |
160 | # 解析一个表格
161 | def decode_sheet(self):
162 | wb_sheet = self.wb_sheet
163 |
164 | self.decode_type ()
165 | self.decode_field()
166 | self.decode_ctx ()
167 |
168 | color_print.printGreen( " covert successfully... sheet name -> %s \n" % wb_sheet.title )
169 | return True
170 |
171 | # 写入配置到文件
172 | def write_one_file(self,ctx,base_path,writer, keys_list, comment_text):
173 | # 有些配置可能只导出客户端或只导出服务器
174 | if not any(ctx) :
175 | return
176 |
177 | write_file_name = self.base_file_name
178 | if self.wb_sheet.title.find("+") >= 0 or self.wb_sheet.title.find("-") >= 0 :
179 | match_list = re.findall("[a-zA-Z0-9_]+$", self.wb_sheet.title)
180 | if 1 == len(match_list):
181 | write_file_name = write_file_name + '_' + match_list[0]
182 |
183 | wt = writer(self.base_name,self.wb_sheet.title, write_file_name, keys_list, comment_text)
184 | ctx = wt.context( ctx )
185 | suffix = wt.suffix()
186 | if None != ctx :
187 | path = base_path + write_file_name + suffix
188 |
189 | #必须为wb,不然无法写入utf-8
190 | file = open( path, 'wb' )
191 | file.write( ctx.encode( "utf-8" ) )
192 | file.close()
193 |
194 | # 分别写入到服务端、客户端的配置文件
195 | def write_files(self,srv_path,clt_path):
196 | if None != srv_path and None != self.srv_writer :
197 | self.write_one_file( self.srv_ctx,srv_path,self.srv_writer, self.srv_keys, self.srv_comment)
198 | if None != clt_path and None != self.clt_writer :
199 | self.write_one_file( self.clt_ctx,clt_path,self.clt_writer, self.clt_keys, self.clt_comment )
200 |
201 | # 导出数组类型配置,A1格子的内容有array标识
202 | class ArraySheet(Sheet):
203 |
204 | def __init__(self,base_name,wb_sheet,srv_writer,clt_writer):
205 | # 记录导出各行的内容
206 | self.srv_ctx = []
207 | self.clt_ctx = []
208 |
209 | super( ArraySheet, self ).__init__(
210 | base_name,wb_sheet,srv_writer,clt_writer )
211 |
212 | # 解析各列的类型(string、number...)
213 | def decode_type(self):
214 | # 第一列没数据,类型可以不填,默认为None,但是这里要占个位
215 | self.types.append( None )
216 |
217 | for col_idx in range( AKEY_COL + 1,self.wb_sheet.max_column + 1 ):
218 | self.mark_error_pos(ATPE_ROW,col_idx)
219 | value = self.wb_sheet.cell( row = ATPE_ROW, column = col_idx ).value
220 |
221 | # 单元格为空的时候,wb_sheet.cell(row=1, column=2).value == None
222 | # 类型那一行必须连续,空白表示后面的数据都不导出了
223 | if value == None :
224 | break
225 | if value not in TYPES :
226 | self.raise_error( "invalid type",value )
227 |
228 | self.types.append( value )
229 |
230 | # 解析客户端、服务器的字段名(server、client)那两行
231 | def decode_one_field(self,fields,row_index, keys):
232 | key_index = 1
233 | for col_index in range( AKEY_COL,len( self.types ) + 1 ):
234 | value = self.wb_sheet.cell(
235 | row = row_index, column = col_index ).value
236 | # 对于array类型的表 一条数据可以有多个值作为KEY 需要处理一下
237 | if None != value and value.find(KEY_FLAG) >= 0 :
238 | value = value[KEY_FLAG_LEN:]
239 | keys[value] = key_index
240 | key_index = key_index + 1
241 |
242 | # 对于不需要导出的field,可以为空。即value为None
243 | fields.append( value )
244 |
245 | # 解析注释那一行
246 | def decode_one_comment(self,fields,row_index, key_index):
247 | for col_index in range( AKEY_COL + 1,len( self.types ) + 1 ):
248 | value = self.wb_sheet.cell(
249 | row = row_index, column = col_index ).value
250 |
251 | key = self.wb_sheet.cell(
252 | row = key_index, column = col_index ).value
253 |
254 | if None == key :
255 | continue
256 |
257 | # 对于不需要导出的field,可以为空。即value为None
258 | if key.find(KEY_FLAG) >= 0 :
259 | key = key[KEY_FLAG_LEN:]
260 | fields[key] = value
261 | else :
262 | fields[key] = value
263 |
264 | # 导出客户端、服务端字段名(server、client)那一列
265 | def decode_field(self):
266 | self.decode_one_field( self.srv_fields,ASRV_ROW, self.srv_keys )
267 | self.decode_one_field( self.clt_fields,ACLT_ROW, self.clt_keys )
268 | # 导出服务器和客户端对用字段的注释, 导表的时候可能用到
269 | self.decode_one_comment( self.srv_comment, ACMT_ROW, ASRV_ROW)
270 | self.decode_one_comment( self.clt_comment, ACMT_ROW, ACLT_ROW)
271 |
272 | # 解析出一个格子的内容
273 | def decode_cell(self,row_idx,col_idx):
274 | value = self.wb_sheet.cell( row = row_idx, column = col_idx ).value
275 | if None == value:
276 | return None
277 |
278 | # 类型是从0下标开始,但是excel的第一列从1开始
279 | self.mark_error_pos( row_idx,col_idx )
280 | return self.to_value( self.types[col_idx - 1],value )
281 |
282 | # 解析出一行的内容
283 | def decode_row(self,row_idx):
284 | srv_row = {}
285 | clt_row = {}
286 |
287 | # 第一列没数据,从第二列开始解析
288 | for col_idx in range( AKEY_COL + 1,len( self.types ) + 1 ):
289 | value = self.decode_cell( row_idx,col_idx )
290 | if None == value : continue
291 |
292 | srv_key = self.srv_fields[col_idx - 1]
293 | clt_key = self.clt_fields[col_idx - 1]
294 |
295 |
296 | if srv_key :
297 | srv_row[srv_key] = value
298 | if clt_key :
299 | clt_row[clt_key] = value
300 | return srv_row,clt_row # 返回一个tuple
301 |
302 | # 解析导出的内容
303 | def decode_ctx(self):
304 | for row_idx in range( ACLT_ROW + 1,self.wb_sheet.max_row + 1 ):
305 | srv_row,clt_row = self.decode_row( row_idx )
306 |
307 | if row_idx > 57 :
308 | break
309 |
310 | # 不为空才追加
311 | if any( srv_row ) :
312 | self.srv_ctx.append( srv_row )
313 | if any( clt_row ) :
314 | self.clt_ctx.append( clt_row )
315 |
316 | # 导出object类型的结构,A1格子有object标识
317 | class ObjectSheet(Sheet):
318 |
319 | def __init__(self,base_name,wb_sheet,srv_writer,clt_writer):
320 | # 记录导出各行的内容
321 | self.srv_ctx = {}
322 | self.clt_ctx = {}
323 |
324 | super( ObjectSheet, self ).__init__(
325 | base_name,wb_sheet,srv_writer,clt_writer )
326 |
327 | # 解析各字段的类型
328 | def decode_type(self):
329 | for row_idx in range( OFLG_ROW + 1,self.wb_sheet.max_row + 1 ):
330 | self.mark_error_pos( row_idx,OTPE_COL)
331 | value = self.wb_sheet.cell( row = row_idx, column = OTPE_COL ).value
332 |
333 | # 类型必须连续,遇到空则认为后续数据不再导出
334 | if value == None :
335 | break
336 | if value not in TYPES :
337 | self.raise_error( "invalid type",value )
338 |
339 | self.types.append( value )
340 |
341 | # 导出客户端、服务端字段名(server、client)那一列
342 | def decode_one_field(self,fields,col_idx):
343 | for row_idx in range( OFLG_ROW + 1,len( self.types ) + OFLG_ROW + 1 ):
344 | value = self.wb_sheet.cell( row = row_idx, column = col_idx ).value
345 |
346 | # 对于不需要导出的field,可以为空。即value为None
347 | fields.append( value )
348 |
349 | # 解析注释那一行
350 | def decode_one_comment(self,fields,col_idx, key_index):
351 | for row_idx in range( OFLG_ROW + 1,len( self.types ) + OFLG_ROW + 1 ):
352 | value = self.wb_sheet.cell( row = row_idx, column = col_idx ).value
353 |
354 | key = self.wb_sheet.cell( row = row_idx, column = key_index ).value
355 |
356 | if None == value:
357 | continue
358 | # 导出存在值的fields的注释
359 | fields[key] = value
360 |
361 | # 导出客户端、服务端字段名(server、client)那一列
362 | def decode_field(self):
363 | self.decode_one_field( self.srv_fields,OSRV_COL )
364 | self.decode_one_field( self.clt_fields,OCLT_COL )
365 | # 导出服务器和客户端对用字段的注释, 导表的时候可能用到
366 | self.decode_one_comment( self.srv_comment, OCMT_COL, OSRV_COL)
367 | self.decode_one_comment( self.clt_comment, OCMT_COL, OCLT_COL )
368 |
369 | # 解析一个单元格内容
370 | def decode_cell(self,row_idx):
371 | value = self.wb_sheet.cell( row = row_idx, column = OCTX_COL ).value
372 | if None == value : return None
373 |
374 | # 在object的结构中,数据是从第二行开始的,所以types的下标偏移2
375 | self.mark_error_pos( row_idx,OCTX_COL )
376 | return self.to_value( self.types[row_idx - OFLG_ROW - 1],value )
377 |
378 | # 解析表格的所有内容
379 | def decode_ctx(self):
380 | for row_idx in range( OFLG_ROW + 1,len( self.types ) + OFLG_ROW + 1 ):
381 | value = self.decode_cell( row_idx )
382 |
383 | if row_idx > 54 :
384 | break
385 |
386 | if None == value :
387 | continue
388 |
389 | srv_key = self.srv_fields[row_idx - OFLG_ROW - 1]
390 | clt_key = self.clt_fields[row_idx - OFLG_ROW - 1]
391 |
392 | if srv_key : self.srv_ctx[srv_key] = value
393 | if clt_key : self.clt_ctx[clt_key] = value
394 |
395 | class ExcelDoc:
396 |
397 | def __init__(self, file,abspath):
398 | self.file = file
399 | self.abspath = abspath
400 |
401 | # 是否需要解析
402 | # 返回解析的对象类型
403 | def need_decode(self,wb_sheet):
404 | sheet_val = wb_sheet.cell(
405 | row = SHEET_FLAG_ROW, column = SHEET_FLAG_COL ).value
406 |
407 | sheeter = None
408 | srv_value = None
409 | clt_value = None
410 | if ARRAY_FLAG == sheet_val :
411 | if wb_sheet.max_row <= ACLT_ROW or wb_sheet.max_column <= AKEY_COL:
412 | return None
413 |
414 | sheeter = ArraySheet
415 | srv_value = wb_sheet.cell( row = ASRV_ROW, column = AKEY_COL ).value
416 | clt_value = wb_sheet.cell( row = ACLT_ROW, column = AKEY_COL ).value
417 | elif OBJECT_FLAG == sheet_val :
418 | sheeter = ObjectSheet
419 | srv_value = wb_sheet.cell( row = OFLG_ROW, column = OSRV_COL ).value
420 | clt_value = wb_sheet.cell( row = OFLG_ROW, column = OCLT_COL ).value
421 | else :
422 | return None
423 |
424 | # 没有这两个标识就不是配置表。可能是策划的一些备注说明
425 | if SRV_FLAG != srv_value or CLT_FLAG != clt_value :
426 | return None
427 | return sheeter
428 |
429 | def decode(self,srv_path,clt_path,srv_writer,clt_writer):
430 | color_print.printYellow( " start covert: %s \n" % self.file.ljust(44, "*") )
431 | base_name = os.path.splitext( self.file )[0]
432 | wb = openpyxl.load_workbook( self.abspath )
433 |
434 | for wb_sheet in wb.worksheets:
435 | Sheeter = self.need_decode( wb_sheet )
436 | if None == Sheeter :
437 | color_print.printPink( " covert skip........... sheet name -> %s\n" % wb_sheet.title )
438 | continue
439 |
440 | sheet = Sheeter( base_name,wb_sheet,srv_writer,clt_writer )
441 | if sheet.decode_sheet() :
442 | sheet.write_files( srv_path,clt_path )
--------------------------------------------------------------------------------
/lancher.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | :python ConfigConvertTool.py --input ./config_excel --srv server/ --clt client/ --timeout -1 --suffix .xlsx --swriter lua --cwriter lua
4 | :python ConfigConvertTool.py --input ./config_excel --srv server/ --clt client/ --timeout -1 --suffix .xlsx --swriter erlanghrl
5 | :python ConfigConvertTool.py --input ./config_excel --srv server/ --clt client/ --timeout -1 --suffix .xlsx --swriter erlangerl
6 | :python ConfigConvertTool.py --input ./config_excel --srv server/ --clt client/ --timeout -1 --suffix .xlsx --swriter elixir
7 | :python ConfigConvertTool.py --input ./config_excel --srv server/ --clt client/ --timeout -1 --suffix .xlsx --swriter jsonobject
8 | :python ConfigConvertTool.py --input ./config_excel --srv server/ --clt client/ --timeout -1 --suffix .xlsx --cwriter jsonarray
9 | python ConfigConvertTool.py --input ./config_excel --srv server/ --clt client/ --timeout -1 --suffix .xlsx --swriter elixir --cwriter xml
10 |
11 |
12 | pause
13 |
--------------------------------------------------------------------------------
/lancher.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | python reader.py --input ./ --srv server/ --clt client/ --timeout -1 --suffix .xlsx --swriter lua --cwriter json
4 | python reader.py --input ./ --srv server/ --clt client/ --timeout -1 --suffix .xlsx --cwriter xml
5 | python reader.py --input ./ --srv server/ --clt client/ --timeout -1 --suffix .xlsx --cwriter lua
6 |
7 |
--------------------------------------------------------------------------------
/server/cfg_array.erl:
--------------------------------------------------------------------------------
1 | %% Automatic generation from -->>
2 | %% excel file name : A_object表示例--cfg_array
3 | %% excel sheet name : +example3
4 |
5 | -module(cfg_array).
6 |
7 | -compile(export_all).
8 |
9 | %% 演示
10 | get('level') ->
11 | "啦啦啦!!!";
12 |
13 | get(_) ->
14 | undefined.
--------------------------------------------------------------------------------
/server/cfg_array.ex:
--------------------------------------------------------------------------------
1 | ## Automatic generation from -->>
2 | ## excel file name: A_object表示例--cfg_array
3 | ## excel sheet name: +example3
4 |
5 | defmodule Cfg_Array do
6 |
7 | ## 演示
8 | def get(:level) do
9 | "啦啦啦!!!"
10 | end
11 |
12 | def get(_) do
13 | :undefined
14 | end
15 |
16 | end
--------------------------------------------------------------------------------
/server/cfg_array.json:
--------------------------------------------------------------------------------
1 | {
2 | "level":"啦啦啦!!!"
3 | }
--------------------------------------------------------------------------------
/server/cfg_array.lua:
--------------------------------------------------------------------------------
1 | -- Automatic generation from -->>
2 | -- excel file name: A_object表示例--cfg_array
3 | -- excel sheet name: +example3
4 |
5 | local cfg_array =
6 | {
7 | -- 演示
8 | level = '啦啦啦!!!'
9 | }
10 | return cfg_array
--------------------------------------------------------------------------------
/server/cfg_array_example1.erl:
--------------------------------------------------------------------------------
1 | %% Automatic generation from -->>
2 | %% excel file name : A_array表示例--cfg_array
3 | %% excel sheet name : 示例1-example1
4 |
5 | -module(cfg_array_example1).
6 |
7 | -include("cfg_array_example1.hrl").
8 | -compile(export_all).
9 |
10 | get(1001, "pos1", 88, 1) ->
11 | #cfg_array_example1{
12 | 'id' = 1001
13 | ,'str' = "pos1"
14 | ,'level' = 88
15 | ,'sub_level' = 1
16 | ,'name' = "黑切+蓝盾"
17 | ,'attr' = [[1, 700], [2, 800], [3, 900]]
18 | ,'desc1' = "从小城镇"
19 | };
20 |
21 | get(1001, "pos1", 88, 2) ->
22 | #cfg_array_example1{
23 | 'id' = 1001
24 | ,'str' = "pos1"
25 | ,'level' = 88
26 | ,'sub_level' = 2
27 | ,'name' = "黑切+蓝盾"
28 | ,'attr' = [[1, 700], [2, 800], [3, 900]]
29 | ,'desc1' = "有钱就可以买"
30 | };
31 |
32 | get(1001, "pos1", 89, 89) ->
33 | #cfg_array_example1{
34 | 'id' = 1001
35 | ,'str' = "pos1"
36 | ,'level' = 89
37 | ,'sub_level' = 89
38 | ,'name' = "黑切+蓝盾"
39 | ,'attr' = [[1, 700], [2, 800], [3, 900]]
40 | ,'desc1' = "有钱就可以买"
41 | };
42 |
43 | get(1001, "pos2", 88, 88.9) ->
44 | #cfg_array_example1{
45 | 'id' = 1001
46 | ,'str' = "pos2"
47 | ,'level' = 88
48 | ,'sub_level' = 88.9
49 | ,'name' = "黑切+蓝盾"
50 | ,'attr' = [[1, 700], [2, 800], [3, 900]]
51 | ,'desc1' = "有钱就可以买"
52 | };
53 |
54 | get(1001, "pos2", 89, 89) ->
55 | #cfg_array_example1{
56 | 'id' = 1001
57 | ,'str' = "pos2"
58 | ,'level' = 89
59 | ,'sub_level' = 89
60 | ,'name' = "黑切+蓝盾"
61 | ,'attr' = [[1, 700], [2, 800], [3, 900]]
62 | ,'desc1' = "有钱就可以买"
63 | };
64 |
65 | get(1002, "pos1", 88, 88) ->
66 | #cfg_array_example1{
67 | 'id' = 1002
68 | ,'str' = "pos1"
69 | ,'level' = 88
70 | ,'sub_level' = 88
71 | ,'name' = "黑切+蓝盾"
72 | ,'attr' = [[1, 700], [2, 800], [3, 901]]
73 | ,'desc1' = "有钱就可以买"
74 | };
75 |
76 | get(1002, "pos1", 89, 89) ->
77 | #cfg_array_example1{
78 | 'id' = 1002
79 | ,'str' = "pos1"
80 | ,'level' = 89
81 | ,'sub_level' = 89
82 | ,'name' = "黑切+蓝盾"
83 | ,'attr' = [[1, 700], [2, 800], [3, 900]]
84 | ,'desc1' = "有钱就可以买"
85 | };
86 |
87 | get(1002, "pos1", 90, 90) ->
88 | #cfg_array_example1{
89 | 'id' = 1002
90 | ,'str' = "pos1"
91 | ,'level' = 90
92 | ,'sub_level' = 90
93 | ,'name' = "黑切+蓝盾"
94 | ,'attr' = [[1, 700], [2, 800], [3, 901]]
95 | ,'desc1' = "有钱就可以买"
96 | };
97 |
98 | get(1002, "pos2", 88, 88) ->
99 | #cfg_array_example1{
100 | 'id' = 1002
101 | ,'str' = "pos2"
102 | ,'level' = 88
103 | ,'sub_level' = 88
104 | ,'name' = "黑切+蓝盾"
105 | ,'attr' = [[1, 700], [2, 800], [3, 901]]
106 | ,'desc1' = "有钱就可以买"
107 | };
108 |
109 | get(1002, "pos2", 89, 89) ->
110 | #cfg_array_example1{
111 | 'id' = 1002
112 | ,'str' = "pos2"
113 | ,'level' = 89
114 | ,'sub_level' = 89
115 | ,'name' = "黑切+蓝盾"
116 | ,'attr' = [[1, 700], [2, 800], [3, 900]]
117 | ,'desc1' = "有钱就可以买"
118 | };
119 |
120 | get(1002, "pos2", 90, 90) ->
121 | #cfg_array_example1{
122 | 'id' = 1002
123 | ,'str' = "pos2"
124 | ,'level' = 90
125 | ,'sub_level' = 90
126 | ,'name' = "黑切+蓝盾"
127 | ,'attr' = [[1, 700], [2, 800], [3, 901]]
128 | ,'desc1' = "有钱就可以买"
129 | };
130 |
131 | get(1003, "pos1", 85, 85) ->
132 | #cfg_array_example1{
133 | 'id' = 1003
134 | ,'str' = "pos1"
135 | ,'level' = 85
136 | ,'sub_level' = 85
137 | ,'name' = "黑切+蓝盾"
138 | ,'attr' = [[1, 700], [2, 800], [3, 902]]
139 | ,'desc1' = "有钱就可以买"
140 | };
141 |
142 | get(1004, "pos1", 80, 80) ->
143 | #cfg_array_example1{
144 | 'id' = 1004
145 | ,'str' = "pos1"
146 | ,'level' = 80
147 | ,'sub_level' = 80
148 | ,'name' = "黑切+蓝盾"
149 | ,'attr' = [[1, 700], [2, 800], [3, 903]]
150 | ,'desc1' = "有钱就可以买"
151 | };
152 |
153 | get(_, _, _, _) ->
154 | undefined.
155 |
156 | get_all() ->
157 | [
158 | {1001, "pos1", 88, 1}
159 | ,{1001, "pos1", 88, 2}
160 | ,{1001, "pos1", 89, 89}
161 | ,{1001, "pos2", 88, 88.9}
162 | ,{1001, "pos2", 89, 89}
163 | ,{1002, "pos1", 88, 88}
164 | ,{1002, "pos1", 89, 89}
165 | ,{1002, "pos1", 90, 90}
166 | ,{1002, "pos2", 88, 88}
167 | ,{1002, "pos2", 89, 89}
168 | ,{1002, "pos2", 90, 90}
169 | ,{1003, "pos1", 85, 85}
170 | ,{1004, "pos1", 80, 80}
171 | ].
172 |
173 | get_list() ->
174 | get_all().
175 |
176 | get_list(1001) ->
177 | [
178 | {1001, "pos1", 88, 1}
179 | ,{1001, "pos1", 88, 2}
180 | ,{1001, "pos1", 89, 89}
181 | ,{1001, "pos2", 88, 88.9}
182 | ,{1001, "pos2", 89, 89}
183 | ];
184 |
185 | get_list(1002) ->
186 | [
187 | {1002, "pos1", 88, 88}
188 | ,{1002, "pos1", 89, 89}
189 | ,{1002, "pos1", 90, 90}
190 | ,{1002, "pos2", 88, 88}
191 | ,{1002, "pos2", 89, 89}
192 | ,{1002, "pos2", 90, 90}
193 | ];
194 |
195 | get_list(1003) ->
196 | [
197 | {1003, "pos1", 85, 85}
198 | ];
199 |
200 | get_list(1004) ->
201 | [
202 | {1004, "pos1", 80, 80}
203 | ];
204 |
205 | get_list(_) ->
206 | [].
207 |
208 | get_list(1001, "pos1") ->
209 | [
210 | {1001, "pos1", 88, 1}
211 | ,{1001, "pos1", 88, 2}
212 | ,{1001, "pos1", 89, 89}
213 | ];
214 |
215 | get_list(1001, "pos2") ->
216 | [
217 | {1001, "pos2", 88, 88.9}
218 | ,{1001, "pos2", 89, 89}
219 | ];
220 |
221 | get_list(1002, "pos1") ->
222 | [
223 | {1002, "pos1", 88, 88}
224 | ,{1002, "pos1", 89, 89}
225 | ,{1002, "pos1", 90, 90}
226 | ];
227 |
228 | get_list(1002, "pos2") ->
229 | [
230 | {1002, "pos2", 88, 88}
231 | ,{1002, "pos2", 89, 89}
232 | ,{1002, "pos2", 90, 90}
233 | ];
234 |
235 | get_list(1003, "pos1") ->
236 | [
237 | {1003, "pos1", 85, 85}
238 | ];
239 |
240 | get_list(1004, "pos1") ->
241 | [
242 | {1004, "pos1", 80, 80}
243 | ];
244 |
245 | get_list(_, _) ->
246 | [].
247 |
248 | get_list(1001, "pos1", 88) ->
249 | [
250 | {1001, "pos1", 88, 1}
251 | ,{1001, "pos1", 88, 2}
252 | ];
253 |
254 | get_list(1001, "pos1", 89) ->
255 | [
256 | {1001, "pos1", 89, 89}
257 | ];
258 |
259 | get_list(1001, "pos2", 88) ->
260 | [
261 | {1001, "pos2", 88, 88.9}
262 | ];
263 |
264 | get_list(1001, "pos2", 89) ->
265 | [
266 | {1001, "pos2", 89, 89}
267 | ];
268 |
269 | get_list(1002, "pos1", 88) ->
270 | [
271 | {1002, "pos1", 88, 88}
272 | ];
273 |
274 | get_list(1002, "pos1", 89) ->
275 | [
276 | {1002, "pos1", 89, 89}
277 | ];
278 |
279 | get_list(1002, "pos1", 90) ->
280 | [
281 | {1002, "pos1", 90, 90}
282 | ];
283 |
284 | get_list(1002, "pos2", 88) ->
285 | [
286 | {1002, "pos2", 88, 88}
287 | ];
288 |
289 | get_list(1002, "pos2", 89) ->
290 | [
291 | {1002, "pos2", 89, 89}
292 | ];
293 |
294 | get_list(1002, "pos2", 90) ->
295 | [
296 | {1002, "pos2", 90, 90}
297 | ];
298 |
299 | get_list(1003, "pos1", 85) ->
300 | [
301 | {1003, "pos1", 85, 85}
302 | ];
303 |
304 | get_list(1004, "pos1", 80) ->
305 | [
306 | {1004, "pos1", 80, 80}
307 | ];
308 |
309 | get_list(_, _, _) ->
310 | [].
311 |
312 |
--------------------------------------------------------------------------------
/server/cfg_array_example1.ex:
--------------------------------------------------------------------------------
1 | ## Automatic generation from -->>
2 | ## excel file name: A_array表示例--cfg_array
3 | ## excel sheet name: 示例1-example1
4 |
5 | defmodule Cfg_Array_Example1 do
6 |
7 | defstruct [
8 | :id, ## 唯一id
9 | :str, ## 佩戴位置
10 | :level, ## 等级
11 | :sub_level, ## 等级
12 | :name, ## 装备名字
13 | :attr, ## 装备增加属性
14 | :desc1 ## 装备来源描述
15 | ]
16 |
17 | def get(1001, "pos1", 88, 1) do
18 | %Cfg_Array_Example1{
19 | :id => 1001,
20 | :str => "pos1",
21 | :level => 88,
22 | :sub_level => 1,
23 | :name => "黑切+蓝盾",
24 | :attr => [[1, 700], [2, 800], [3, 900]],
25 | :desc1 => "从小城镇"
26 | }
27 | end
28 |
29 | def get(1001, "pos1", 88, 2) do
30 | %Cfg_Array_Example1{
31 | :id => 1001,
32 | :str => "pos1",
33 | :level => 88,
34 | :sub_level => 2,
35 | :name => "黑切+蓝盾",
36 | :attr => [[1, 700], [2, 800], [3, 900]],
37 | :desc1 => "有钱就可以买"
38 | }
39 | end
40 |
41 | def get(1001, "pos1", 89, 89) do
42 | %Cfg_Array_Example1{
43 | :id => 1001,
44 | :str => "pos1",
45 | :level => 89,
46 | :sub_level => 89,
47 | :name => "黑切+蓝盾",
48 | :attr => [[1, 700], [2, 800], [3, 900]],
49 | :desc1 => "有钱就可以买"
50 | }
51 | end
52 |
53 | def get(1001, "pos2", 88, 88.9) do
54 | %Cfg_Array_Example1{
55 | :id => 1001,
56 | :str => "pos2",
57 | :level => 88,
58 | :sub_level => 88.9,
59 | :name => "黑切+蓝盾",
60 | :attr => [[1, 700], [2, 800], [3, 900]],
61 | :desc1 => "有钱就可以买"
62 | }
63 | end
64 |
65 | def get(1001, "pos2", 89, 89) do
66 | %Cfg_Array_Example1{
67 | :id => 1001,
68 | :str => "pos2",
69 | :level => 89,
70 | :sub_level => 89,
71 | :name => "黑切+蓝盾",
72 | :attr => [[1, 700], [2, 800], [3, 900]],
73 | :desc1 => "有钱就可以买"
74 | }
75 | end
76 |
77 | def get(1002, "pos1", 88, 88) do
78 | %Cfg_Array_Example1{
79 | :id => 1002,
80 | :str => "pos1",
81 | :level => 88,
82 | :sub_level => 88,
83 | :name => "黑切+蓝盾",
84 | :attr => [[1, 700], [2, 800], [3, 901]],
85 | :desc1 => "有钱就可以买"
86 | }
87 | end
88 |
89 | def get(1002, "pos1", 89, 89) do
90 | %Cfg_Array_Example1{
91 | :id => 1002,
92 | :str => "pos1",
93 | :level => 89,
94 | :sub_level => 89,
95 | :name => "黑切+蓝盾",
96 | :attr => [[1, 700], [2, 800], [3, 900]],
97 | :desc1 => "有钱就可以买"
98 | }
99 | end
100 |
101 | def get(1002, "pos1", 90, 90) do
102 | %Cfg_Array_Example1{
103 | :id => 1002,
104 | :str => "pos1",
105 | :level => 90,
106 | :sub_level => 90,
107 | :name => "黑切+蓝盾",
108 | :attr => [[1, 700], [2, 800], [3, 901]],
109 | :desc1 => "有钱就可以买"
110 | }
111 | end
112 |
113 | def get(1002, "pos2", 88, 88) do
114 | %Cfg_Array_Example1{
115 | :id => 1002,
116 | :str => "pos2",
117 | :level => 88,
118 | :sub_level => 88,
119 | :name => "黑切+蓝盾",
120 | :attr => [[1, 700], [2, 800], [3, 901]],
121 | :desc1 => "有钱就可以买"
122 | }
123 | end
124 |
125 | def get(1002, "pos2", 89, 89) do
126 | %Cfg_Array_Example1{
127 | :id => 1002,
128 | :str => "pos2",
129 | :level => 89,
130 | :sub_level => 89,
131 | :name => "黑切+蓝盾",
132 | :attr => [[1, 700], [2, 800], [3, 900]],
133 | :desc1 => "有钱就可以买"
134 | }
135 | end
136 |
137 | def get(1002, "pos2", 90, 90) do
138 | %Cfg_Array_Example1{
139 | :id => 1002,
140 | :str => "pos2",
141 | :level => 90,
142 | :sub_level => 90,
143 | :name => "黑切+蓝盾",
144 | :attr => [[1, 700], [2, 800], [3, 901]],
145 | :desc1 => "有钱就可以买"
146 | }
147 | end
148 |
149 | def get(1003, "pos1", 85, 85) do
150 | %Cfg_Array_Example1{
151 | :id => 1003,
152 | :str => "pos1",
153 | :level => 85,
154 | :sub_level => 85,
155 | :name => "黑切+蓝盾",
156 | :attr => [[1, 700], [2, 800], [3, 902]],
157 | :desc1 => "有钱就可以买"
158 | }
159 | end
160 |
161 | def get(1004, "pos1", 80, 80) do
162 | %Cfg_Array_Example1{
163 | :id => 1004,
164 | :str => "pos1",
165 | :level => 80,
166 | :sub_level => 80,
167 | :name => "黑切+蓝盾",
168 | :attr => [[1, 700], [2, 800], [3, 903]],
169 | :desc1 => "有钱就可以买"
170 | }
171 | end
172 |
173 | def get(_, _, _, _) do
174 | :undefined
175 | end
176 |
177 | def get_all() do
178 | [
179 | {1001, "pos1", 88, 1},
180 | {1001, "pos1", 88, 2},
181 | {1001, "pos1", 89, 89},
182 | {1001, "pos2", 88, 88.9},
183 | {1001, "pos2", 89, 89},
184 | {1002, "pos1", 88, 88},
185 | {1002, "pos1", 89, 89},
186 | {1002, "pos1", 90, 90},
187 | {1002, "pos2", 88, 88},
188 | {1002, "pos2", 89, 89},
189 | {1002, "pos2", 90, 90},
190 | {1003, "pos1", 85, 85},
191 | {1004, "pos1", 80, 80}
192 | ]
193 | end
194 |
195 | def get_list() do
196 | get_all()
197 | end
198 |
199 | def get_list(1001) do
200 | [
201 | {1001, "pos1", 88, 1},
202 | {1001, "pos1", 88, 2},
203 | {1001, "pos1", 89, 89},
204 | {1001, "pos2", 88, 88.9},
205 | {1001, "pos2", 89, 89}
206 | ]
207 | end
208 |
209 | def get_list(1002) do
210 | [
211 | {1002, "pos1", 88, 88},
212 | {1002, "pos1", 89, 89},
213 | {1002, "pos1", 90, 90},
214 | {1002, "pos2", 88, 88},
215 | {1002, "pos2", 89, 89},
216 | {1002, "pos2", 90, 90}
217 | ]
218 | end
219 |
220 | def get_list(1003) do
221 | [
222 | {1003, "pos1", 85, 85}
223 | ]
224 | end
225 |
226 | def get_list(1004) do
227 | [
228 | {1004, "pos1", 80, 80}
229 | ]
230 | end
231 |
232 | def get_list(_) do
233 | []
234 | end
235 |
236 | def get_list(1001, "pos1") do
237 | [
238 | {1001, "pos1", 88, 1},
239 | {1001, "pos1", 88, 2},
240 | {1001, "pos1", 89, 89}
241 | ]
242 | end
243 |
244 | def get_list(1001, "pos2") do
245 | [
246 | {1001, "pos2", 88, 88.9},
247 | {1001, "pos2", 89, 89}
248 | ]
249 | end
250 |
251 | def get_list(1002, "pos1") do
252 | [
253 | {1002, "pos1", 88, 88},
254 | {1002, "pos1", 89, 89},
255 | {1002, "pos1", 90, 90}
256 | ]
257 | end
258 |
259 | def get_list(1002, "pos2") do
260 | [
261 | {1002, "pos2", 88, 88},
262 | {1002, "pos2", 89, 89},
263 | {1002, "pos2", 90, 90}
264 | ]
265 | end
266 |
267 | def get_list(1003, "pos1") do
268 | [
269 | {1003, "pos1", 85, 85}
270 | ]
271 | end
272 |
273 | def get_list(1004, "pos1") do
274 | [
275 | {1004, "pos1", 80, 80}
276 | ]
277 | end
278 |
279 | def get_list(_, _) do
280 | []
281 | end
282 |
283 | def get_list(1001, "pos1", 88) do
284 | [
285 | {1001, "pos1", 88, 1},
286 | {1001, "pos1", 88, 2}
287 | ]
288 | end
289 |
290 | def get_list(1001, "pos1", 89) do
291 | [
292 | {1001, "pos1", 89, 89}
293 | ]
294 | end
295 |
296 | def get_list(1001, "pos2", 88) do
297 | [
298 | {1001, "pos2", 88, 88.9}
299 | ]
300 | end
301 |
302 | def get_list(1001, "pos2", 89) do
303 | [
304 | {1001, "pos2", 89, 89}
305 | ]
306 | end
307 |
308 | def get_list(1002, "pos1", 88) do
309 | [
310 | {1002, "pos1", 88, 88}
311 | ]
312 | end
313 |
314 | def get_list(1002, "pos1", 89) do
315 | [
316 | {1002, "pos1", 89, 89}
317 | ]
318 | end
319 |
320 | def get_list(1002, "pos1", 90) do
321 | [
322 | {1002, "pos1", 90, 90}
323 | ]
324 | end
325 |
326 | def get_list(1002, "pos2", 88) do
327 | [
328 | {1002, "pos2", 88, 88}
329 | ]
330 | end
331 |
332 | def get_list(1002, "pos2", 89) do
333 | [
334 | {1002, "pos2", 89, 89}
335 | ]
336 | end
337 |
338 | def get_list(1002, "pos2", 90) do
339 | [
340 | {1002, "pos2", 90, 90}
341 | ]
342 | end
343 |
344 | def get_list(1003, "pos1", 85) do
345 | [
346 | {1003, "pos1", 85, 85}
347 | ]
348 | end
349 |
350 | def get_list(1004, "pos1", 80) do
351 | [
352 | {1004, "pos1", 80, 80}
353 | ]
354 | end
355 |
356 | def get_list(_, _, _) do
357 | []
358 | end
359 |
360 | end
--------------------------------------------------------------------------------
/server/cfg_array_example1.hrl:
--------------------------------------------------------------------------------
1 | %% Automatic generation from -->>
2 | %% excel file name : A_array表示例--cfg_array
3 | %% excel sheet name : 示例1-example1
4 |
5 | -record(cfg_array_example1, {
6 | 'id' %% 唯一id
7 | ,'str' %% 佩戴位置
8 | ,'level' %% 等级
9 | ,'sub_level' %% 等级
10 | ,'name' %% 装备名字
11 | ,'attr' %% 装备增加属性
12 | ,'desc1' %% 装备来源描述
13 | }).
--------------------------------------------------------------------------------
/server/cfg_array_example1.json:
--------------------------------------------------------------------------------
1 | {
2 | "1001":{
3 | "pos1":{
4 | "88":{
5 | "1":{
6 | "id":1001,
7 | "str":"pos1",
8 | "level":88,
9 | "sub_level":1,
10 | "name":"黑切+蓝盾",
11 | "desc1":"从小城镇",
12 | "attr":[
13 | [
14 | 1,
15 | 700
16 | ],
17 | [
18 | 2,
19 | 800
20 | ],
21 | [
22 | 3,
23 | 900
24 | ]
25 | ]
26 | },
27 | "2":{
28 | "id":1001,
29 | "str":"pos1",
30 | "level":88,
31 | "sub_level":2,
32 | "name":"黑切+蓝盾",
33 | "desc1":"有钱就可以买",
34 | "attr":[
35 | [
36 | 1,
37 | 700
38 | ],
39 | [
40 | 2,
41 | 800
42 | ],
43 | [
44 | 3,
45 | 900
46 | ]
47 | ]
48 | }
49 | },
50 | "89":{
51 | "89":{
52 | "id":1001,
53 | "str":"pos1",
54 | "level":89,
55 | "sub_level":89,
56 | "name":"黑切+蓝盾",
57 | "desc1":"有钱就可以买",
58 | "attr":[
59 | [
60 | 1,
61 | 700
62 | ],
63 | [
64 | 2,
65 | 800
66 | ],
67 | [
68 | 3,
69 | 900
70 | ]
71 | ]
72 | }
73 | }
74 | },
75 | "pos2":{
76 | "88":{
77 | "88.9":{
78 | "id":1001,
79 | "str":"pos2",
80 | "level":88,
81 | "sub_level":88.9,
82 | "name":"黑切+蓝盾",
83 | "desc1":"有钱就可以买",
84 | "attr":[
85 | [
86 | 1,
87 | 700
88 | ],
89 | [
90 | 2,
91 | 800
92 | ],
93 | [
94 | 3,
95 | 900
96 | ]
97 | ]
98 | }
99 | },
100 | "89":{
101 | "89":{
102 | "id":1001,
103 | "str":"pos2",
104 | "level":89,
105 | "sub_level":89,
106 | "name":"黑切+蓝盾",
107 | "desc1":"有钱就可以买",
108 | "attr":[
109 | [
110 | 1,
111 | 700
112 | ],
113 | [
114 | 2,
115 | 800
116 | ],
117 | [
118 | 3,
119 | 900
120 | ]
121 | ]
122 | }
123 | }
124 | }
125 | },
126 | "1002":{
127 | "pos1":{
128 | "88":{
129 | "88":{
130 | "id":1002,
131 | "str":"pos1",
132 | "level":88,
133 | "sub_level":88,
134 | "name":"黑切+蓝盾",
135 | "desc1":"有钱就可以买",
136 | "attr":[
137 | [
138 | 1,
139 | 700
140 | ],
141 | [
142 | 2,
143 | 800
144 | ],
145 | [
146 | 3,
147 | 901
148 | ]
149 | ]
150 | }
151 | },
152 | "89":{
153 | "89":{
154 | "id":1002,
155 | "str":"pos1",
156 | "level":89,
157 | "sub_level":89,
158 | "name":"黑切+蓝盾",
159 | "desc1":"有钱就可以买",
160 | "attr":[
161 | [
162 | 1,
163 | 700
164 | ],
165 | [
166 | 2,
167 | 800
168 | ],
169 | [
170 | 3,
171 | 900
172 | ]
173 | ]
174 | }
175 | },
176 | "90":{
177 | "90":{
178 | "id":1002,
179 | "str":"pos1",
180 | "level":90,
181 | "sub_level":90,
182 | "name":"黑切+蓝盾",
183 | "desc1":"有钱就可以买",
184 | "attr":[
185 | [
186 | 1,
187 | 700
188 | ],
189 | [
190 | 2,
191 | 800
192 | ],
193 | [
194 | 3,
195 | 901
196 | ]
197 | ]
198 | }
199 | }
200 | },
201 | "pos2":{
202 | "88":{
203 | "88":{
204 | "id":1002,
205 | "str":"pos2",
206 | "level":88,
207 | "sub_level":88,
208 | "name":"黑切+蓝盾",
209 | "desc1":"有钱就可以买",
210 | "attr":[
211 | [
212 | 1,
213 | 700
214 | ],
215 | [
216 | 2,
217 | 800
218 | ],
219 | [
220 | 3,
221 | 901
222 | ]
223 | ]
224 | }
225 | },
226 | "89":{
227 | "89":{
228 | "id":1002,
229 | "str":"pos2",
230 | "level":89,
231 | "sub_level":89,
232 | "name":"黑切+蓝盾",
233 | "desc1":"有钱就可以买",
234 | "attr":[
235 | [
236 | 1,
237 | 700
238 | ],
239 | [
240 | 2,
241 | 800
242 | ],
243 | [
244 | 3,
245 | 900
246 | ]
247 | ]
248 | }
249 | },
250 | "90":{
251 | "90":{
252 | "id":1002,
253 | "str":"pos2",
254 | "level":90,
255 | "sub_level":90,
256 | "name":"黑切+蓝盾",
257 | "desc1":"有钱就可以买",
258 | "attr":[
259 | [
260 | 1,
261 | 700
262 | ],
263 | [
264 | 2,
265 | 800
266 | ],
267 | [
268 | 3,
269 | 901
270 | ]
271 | ]
272 | }
273 | }
274 | }
275 | },
276 | "1003":{
277 | "pos1":{
278 | "85":{
279 | "85":{
280 | "id":1003,
281 | "str":"pos1",
282 | "level":85,
283 | "sub_level":85,
284 | "name":"黑切+蓝盾",
285 | "desc1":"有钱就可以买",
286 | "attr":[
287 | [
288 | 1,
289 | 700
290 | ],
291 | [
292 | 2,
293 | 800
294 | ],
295 | [
296 | 3,
297 | 902
298 | ]
299 | ]
300 | }
301 | }
302 | }
303 | },
304 | "1004":{
305 | "pos1":{
306 | "80":{
307 | "80":{
308 | "id":1004,
309 | "str":"pos1",
310 | "level":80,
311 | "sub_level":80,
312 | "name":"黑切+蓝盾",
313 | "desc1":"有钱就可以买",
314 | "attr":[
315 | [
316 | 1,
317 | 700
318 | ],
319 | [
320 | 2,
321 | 800
322 | ],
323 | [
324 | 3,
325 | 903
326 | ]
327 | ]
328 | }
329 | }
330 | }
331 | }
332 | }
--------------------------------------------------------------------------------
/server/cfg_array_example1.lua:
--------------------------------------------------------------------------------
1 | -- Automatic generation from -->>
2 | -- excel file name: A_array表示例--cfg_array
3 | -- excel sheet name: 示例1-example1
4 |
5 | local cfg_array_example1 =
6 | --: id ## 唯一id
7 | --: str ## 佩戴位置
8 | --: level ## 等级
9 | --: sub_level ## 等级
10 | --: name ## 装备名字
11 | --: attr ## 装备增加属性
12 | --: desc1 ## 装备来源描述
13 |
14 | {
15 | [1001] =
16 | {
17 | pos1 =
18 | {
19 | [88] =
20 | {
21 | [1] =
22 | {
23 | id = 1001,
24 | str = 'pos1',
25 | level = 88,
26 | sub_level = 1,
27 | name = '黑切+蓝盾',
28 | desc1 = '从小城镇',
29 | attr =
30 | {
31 | [1] =
32 | {
33 | [1] = 1,
34 | [2] = 700
35 | },
36 | [2] =
37 | {
38 | [1] = 2,
39 | [2] = 800
40 | },
41 | [3] =
42 | {
43 | [1] = 3,
44 | [2] = 900
45 | }
46 | }
47 | },
48 | [2] =
49 | {
50 | id = 1001,
51 | str = 'pos1',
52 | level = 88,
53 | sub_level = 2,
54 | name = '黑切+蓝盾',
55 | desc1 = '有钱就可以买',
56 | attr =
57 | {
58 | [1] =
59 | {
60 | [1] = 1,
61 | [2] = 700
62 | },
63 | [2] =
64 | {
65 | [1] = 2,
66 | [2] = 800
67 | },
68 | [3] =
69 | {
70 | [1] = 3,
71 | [2] = 900
72 | }
73 | }
74 | }
75 | },
76 | [89] =
77 | {
78 | [89] =
79 | {
80 | id = 1001,
81 | str = 'pos1',
82 | level = 89,
83 | sub_level = 89,
84 | name = '黑切+蓝盾',
85 | desc1 = '有钱就可以买',
86 | attr =
87 | {
88 | [1] =
89 | {
90 | [1] = 1,
91 | [2] = 700
92 | },
93 | [2] =
94 | {
95 | [1] = 2,
96 | [2] = 800
97 | },
98 | [3] =
99 | {
100 | [1] = 3,
101 | [2] = 900
102 | }
103 | }
104 | }
105 | }
106 | },
107 | pos2 =
108 | {
109 | [88] =
110 | {
111 | [88.9] =
112 | {
113 | id = 1001,
114 | str = 'pos2',
115 | level = 88,
116 | sub_level = 88.9,
117 | name = '黑切+蓝盾',
118 | desc1 = '有钱就可以买',
119 | attr =
120 | {
121 | [1] =
122 | {
123 | [1] = 1,
124 | [2] = 700
125 | },
126 | [2] =
127 | {
128 | [1] = 2,
129 | [2] = 800
130 | },
131 | [3] =
132 | {
133 | [1] = 3,
134 | [2] = 900
135 | }
136 | }
137 | }
138 | },
139 | [89] =
140 | {
141 | [89] =
142 | {
143 | id = 1001,
144 | str = 'pos2',
145 | level = 89,
146 | sub_level = 89,
147 | name = '黑切+蓝盾',
148 | desc1 = '有钱就可以买',
149 | attr =
150 | {
151 | [1] =
152 | {
153 | [1] = 1,
154 | [2] = 700
155 | },
156 | [2] =
157 | {
158 | [1] = 2,
159 | [2] = 800
160 | },
161 | [3] =
162 | {
163 | [1] = 3,
164 | [2] = 900
165 | }
166 | }
167 | }
168 | }
169 | }
170 | },
171 | [1002] =
172 | {
173 | pos1 =
174 | {
175 | [88] =
176 | {
177 | [88] =
178 | {
179 | id = 1002,
180 | str = 'pos1',
181 | level = 88,
182 | sub_level = 88,
183 | name = '黑切+蓝盾',
184 | desc1 = '有钱就可以买',
185 | attr =
186 | {
187 | [1] =
188 | {
189 | [1] = 1,
190 | [2] = 700
191 | },
192 | [2] =
193 | {
194 | [1] = 2,
195 | [2] = 800
196 | },
197 | [3] =
198 | {
199 | [1] = 3,
200 | [2] = 901
201 | }
202 | }
203 | }
204 | },
205 | [89] =
206 | {
207 | [89] =
208 | {
209 | id = 1002,
210 | str = 'pos1',
211 | level = 89,
212 | sub_level = 89,
213 | name = '黑切+蓝盾',
214 | desc1 = '有钱就可以买',
215 | attr =
216 | {
217 | [1] =
218 | {
219 | [1] = 1,
220 | [2] = 700
221 | },
222 | [2] =
223 | {
224 | [1] = 2,
225 | [2] = 800
226 | },
227 | [3] =
228 | {
229 | [1] = 3,
230 | [2] = 900
231 | }
232 | }
233 | }
234 | },
235 | [90] =
236 | {
237 | [90] =
238 | {
239 | id = 1002,
240 | str = 'pos1',
241 | level = 90,
242 | sub_level = 90,
243 | name = '黑切+蓝盾',
244 | desc1 = '有钱就可以买',
245 | attr =
246 | {
247 | [1] =
248 | {
249 | [1] = 1,
250 | [2] = 700
251 | },
252 | [2] =
253 | {
254 | [1] = 2,
255 | [2] = 800
256 | },
257 | [3] =
258 | {
259 | [1] = 3,
260 | [2] = 901
261 | }
262 | }
263 | }
264 | }
265 | },
266 | pos2 =
267 | {
268 | [88] =
269 | {
270 | [88] =
271 | {
272 | id = 1002,
273 | str = 'pos2',
274 | level = 88,
275 | sub_level = 88,
276 | name = '黑切+蓝盾',
277 | desc1 = '有钱就可以买',
278 | attr =
279 | {
280 | [1] =
281 | {
282 | [1] = 1,
283 | [2] = 700
284 | },
285 | [2] =
286 | {
287 | [1] = 2,
288 | [2] = 800
289 | },
290 | [3] =
291 | {
292 | [1] = 3,
293 | [2] = 901
294 | }
295 | }
296 | }
297 | },
298 | [89] =
299 | {
300 | [89] =
301 | {
302 | id = 1002,
303 | str = 'pos2',
304 | level = 89,
305 | sub_level = 89,
306 | name = '黑切+蓝盾',
307 | desc1 = '有钱就可以买',
308 | attr =
309 | {
310 | [1] =
311 | {
312 | [1] = 1,
313 | [2] = 700
314 | },
315 | [2] =
316 | {
317 | [1] = 2,
318 | [2] = 800
319 | },
320 | [3] =
321 | {
322 | [1] = 3,
323 | [2] = 900
324 | }
325 | }
326 | }
327 | },
328 | [90] =
329 | {
330 | [90] =
331 | {
332 | id = 1002,
333 | str = 'pos2',
334 | level = 90,
335 | sub_level = 90,
336 | name = '黑切+蓝盾',
337 | desc1 = '有钱就可以买',
338 | attr =
339 | {
340 | [1] =
341 | {
342 | [1] = 1,
343 | [2] = 700
344 | },
345 | [2] =
346 | {
347 | [1] = 2,
348 | [2] = 800
349 | },
350 | [3] =
351 | {
352 | [1] = 3,
353 | [2] = 901
354 | }
355 | }
356 | }
357 | }
358 | }
359 | },
360 | [1003] =
361 | {
362 | pos1 =
363 | {
364 | [85] =
365 | {
366 | [85] =
367 | {
368 | id = 1003,
369 | str = 'pos1',
370 | level = 85,
371 | sub_level = 85,
372 | name = '黑切+蓝盾',
373 | desc1 = '有钱就可以买',
374 | attr =
375 | {
376 | [1] =
377 | {
378 | [1] = 1,
379 | [2] = 700
380 | },
381 | [2] =
382 | {
383 | [1] = 2,
384 | [2] = 800
385 | },
386 | [3] =
387 | {
388 | [1] = 3,
389 | [2] = 902
390 | }
391 | }
392 | }
393 | }
394 | }
395 | },
396 | [1004] =
397 | {
398 | pos1 =
399 | {
400 | [80] =
401 | {
402 | [80] =
403 | {
404 | id = 1004,
405 | str = 'pos1',
406 | level = 80,
407 | sub_level = 80,
408 | name = '黑切+蓝盾',
409 | desc1 = '有钱就可以买',
410 | attr =
411 | {
412 | [1] =
413 | {
414 | [1] = 1,
415 | [2] = 700
416 | },
417 | [2] =
418 | {
419 | [1] = 2,
420 | [2] = 800
421 | },
422 | [3] =
423 | {
424 | [1] = 3,
425 | [2] = 903
426 | }
427 | }
428 | }
429 | }
430 | }
431 | }
432 | }
433 | return cfg_array_example1
--------------------------------------------------------------------------------
/server/cfg_array_example2.erl:
--------------------------------------------------------------------------------
1 | %% Automatic generation from -->>
2 | %% excel file name : A_array表示例--cfg_array
3 | %% excel sheet name : 示例2+example2
4 |
5 | -module(cfg_array_example2).
6 |
7 | -include("cfg_array_example2.hrl").
8 | -compile(export_all).
9 |
10 | get(1) ->
11 | #cfg_array_example2{
12 | 'id' = 1
13 | ,'name' = "examp1001"
14 | ,'material' = [#{'res' => 1, 'id' => 10001, 'count' => 1}, #{'res' => 1, 'id' => 10001, 'count' => 1}]
15 | ,'attr' = [[1, 700], [2, 800], [3, 900], #{'add' => [4, 100]}]
16 | ,'award1' = {1, 2, 3}
17 | ,'award2' = #{'id' => 1, 'type' => 2, 'num' => 3}
18 | };
19 |
20 | get(2) ->
21 | #cfg_array_example2{
22 | 'id' = 2
23 | ,'name' = "examp1002"
24 | ,'material' = #{'res' => 1, 'id' => 10001, 'count' => 1}
25 | ,'attr' = [[1, 700], [2, 800], [3, 901], #{'add' => [5, 100]}]
26 | ,'award1' = {1, 2, 3}
27 | ,'award2' = #{'id' => 1, 'type' => 2, 'num' => 3}
28 | };
29 |
30 | get(3) ->
31 | #cfg_array_example2{
32 | 'id' = 3
33 | ,'name' = "examp1003"
34 | ,'material' = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
35 | ,'attr' = [[1, 700], [2, 800], [3, 902], #{'add' => [6, 100]}]
36 | ,'award1' = {1, 2, 3}
37 | ,'award2' = #{'id' => 1, 'type' => 2, 'num' => 3}
38 | };
39 |
40 | get(4) ->
41 | #cfg_array_example2{
42 | 'id' = 4
43 | ,'name' = "examp1004"
44 | ,'material' = ["测试数据", "测试数据2", "测试数据3"]
45 | ,'attr' = [[1, 700], [2, 800], [3, 903], #{'add' => [7, 100]}]
46 | ,'award1' = {1, 2, 3}
47 | ,'award2' = #{'id' => 1, 'type' => 2, 'num' => 3}
48 | };
49 |
50 | get(5) ->
51 | #cfg_array_example2{
52 | 'id' = 5
53 | ,'name' = "examp1004"
54 | ,'material' = ["test"]
55 | ,'attr' = [[1, 700], [2, 800], [3, 903], #{'add' => [7, 100]}]
56 | ,'award1' = {1, 2, 3}
57 | ,'award2' = #{'id' => 1, 'type' => 2, 'num' => 3}
58 | };
59 |
60 | get(_) ->
61 | undefined.
62 |
63 | get_all() ->
64 | [
65 | {1}
66 | ,{2}
67 | ,{3}
68 | ,{4}
69 | ,{5}
70 | ].
71 |
72 | get_list() ->
73 | get_all().
74 |
75 |
--------------------------------------------------------------------------------
/server/cfg_array_example2.ex:
--------------------------------------------------------------------------------
1 | ## Automatic generation from -->>
2 | ## excel file name: A_array表示例--cfg_array
3 | ## excel sheet name: 示例2+example2
4 |
5 | defmodule Cfg_Array_Example2 do
6 |
7 | defstruct [
8 | :id, ## 英雄id
9 | :name, ## 英雄名字
10 | :material, ## 合成消耗
11 | :attr, ## 属性
12 | :award1, ## 奖励1
13 | :award2 ## 奖励2
14 | ]
15 |
16 | def get(1) do
17 | %Cfg_Array_Example2{
18 | :id => 1,
19 | :name => "examp1001",
20 | :material => [%{:res => 1, :id => 10001, :count => 1}, %{:res => 1, :id => 10001, :count => 1}],
21 | :attr => [[1, 700], [2, 800], [3, 900], %{:add => [4, 100]}],
22 | :award1 => {1, 2, 3},
23 | :award2 => %{:id => 1, :type => 2, :num => 3}
24 | }
25 | end
26 |
27 | def get(2) do
28 | %Cfg_Array_Example2{
29 | :id => 2,
30 | :name => "examp1002",
31 | :material => %{:res => 1, :id => 10001, :count => 1},
32 | :attr => [[1, 700], [2, 800], [3, 901], %{:add => [5, 100]}],
33 | :award1 => {1, 2, 3},
34 | :award2 => %{:id => 1, :type => 2, :num => 3}
35 | }
36 | end
37 |
38 | def get(3) do
39 | %Cfg_Array_Example2{
40 | :id => 3,
41 | :name => "examp1003",
42 | :material => [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
43 | :attr => [[1, 700], [2, 800], [3, 902], %{:add => [6, 100]}],
44 | :award1 => {1, 2, 3},
45 | :award2 => %{:id => 1, :type => 2, :num => 3}
46 | }
47 | end
48 |
49 | def get(4) do
50 | %Cfg_Array_Example2{
51 | :id => 4,
52 | :name => "examp1004",
53 | :material => ["测试数据", "测试数据2", "测试数据3"],
54 | :attr => [[1, 700], [2, 800], [3, 903], %{:add => [7, 100]}],
55 | :award1 => {1, 2, 3},
56 | :award2 => %{:id => 1, :type => 2, :num => 3}
57 | }
58 | end
59 |
60 | def get(5) do
61 | %Cfg_Array_Example2{
62 | :id => 5,
63 | :name => "examp1004",
64 | :material => ["test"],
65 | :attr => [[1, 700], [2, 800], [3, 903], %{:add => [7, 100]}],
66 | :award1 => {1, 2, 3},
67 | :award2 => %{:id => 1, :type => 2, :num => 3}
68 | }
69 | end
70 |
71 | def get(_) do
72 | :undefined
73 | end
74 |
75 | def get_all() do
76 | [
77 | {1},
78 | {2},
79 | {3},
80 | {4},
81 | {5}
82 | ]
83 | end
84 |
85 | def get_list() do
86 | get_all()
87 | end
88 |
89 | end
--------------------------------------------------------------------------------
/server/cfg_array_example2.hrl:
--------------------------------------------------------------------------------
1 | %% Automatic generation from -->>
2 | %% excel file name : A_array表示例--cfg_array
3 | %% excel sheet name : 示例2+example2
4 |
5 | -record(cfg_array_example2, {
6 | 'id' %% 英雄id
7 | ,'name' %% 英雄名字
8 | ,'material' %% 合成消耗
9 | ,'attr' %% 属性
10 | ,'award1' %% 奖励1
11 | ,'award2' %% 奖励2
12 | }).
--------------------------------------------------------------------------------
/server/cfg_array_example2.json:
--------------------------------------------------------------------------------
1 | {
2 | "1":{
3 | "id":1,
4 | "name":"examp1001",
5 | "material":[
6 | {
7 | "res":1,
8 | "id":10001,
9 | "count":1
10 | },
11 | {
12 | "res":1,
13 | "id":10001,
14 | "count":1
15 | }
16 | ],
17 | "attr":[
18 | [
19 | 1,
20 | 700
21 | ],
22 | [
23 | 2,
24 | 800
25 | ],
26 | [
27 | 3,
28 | 900
29 | ],
30 | {
31 | "add":[
32 | 4,
33 | 100
34 | ]
35 | }
36 | ],
37 | "award1":[
38 | 1,
39 | 2,
40 | 3
41 | ],
42 | "award2":{
43 | "id":1,
44 | "type":2,
45 | "num":3
46 | }
47 | },
48 | "2":{
49 | "id":2,
50 | "name":"examp1002",
51 | "material":{
52 | "res":1,
53 | "id":10001,
54 | "count":1
55 | },
56 | "attr":[
57 | [
58 | 1,
59 | 700
60 | ],
61 | [
62 | 2,
63 | 800
64 | ],
65 | [
66 | 3,
67 | 901
68 | ],
69 | {
70 | "add":[
71 | 5,
72 | 100
73 | ]
74 | }
75 | ],
76 | "award1":[
77 | 1,
78 | 2,
79 | 3
80 | ],
81 | "award2":{
82 | "id":1,
83 | "type":2,
84 | "num":3
85 | }
86 | },
87 | "3":{
88 | "id":3,
89 | "name":"examp1003",
90 | "material":[
91 | 1,
92 | 2,
93 | 3,
94 | 4,
95 | 5,
96 | 6,
97 | 7,
98 | 8,
99 | 9,
100 | 9,
101 | 9,
102 | 9,
103 | 9,
104 | 9,
105 | 9,
106 | 9,
107 | 9,
108 | 9
109 | ],
110 | "attr":[
111 | [
112 | 1,
113 | 700
114 | ],
115 | [
116 | 2,
117 | 800
118 | ],
119 | [
120 | 3,
121 | 902
122 | ],
123 | {
124 | "add":[
125 | 6,
126 | 100
127 | ]
128 | }
129 | ],
130 | "award1":[
131 | 1,
132 | 2,
133 | 3
134 | ],
135 | "award2":{
136 | "id":1,
137 | "type":2,
138 | "num":3
139 | }
140 | },
141 | "4":{
142 | "id":4,
143 | "name":"examp1004",
144 | "material":[
145 | "测试数据",
146 | "测试数据2",
147 | "测试数据3"
148 | ],
149 | "attr":[
150 | [
151 | 1,
152 | 700
153 | ],
154 | [
155 | 2,
156 | 800
157 | ],
158 | [
159 | 3,
160 | 903
161 | ],
162 | {
163 | "add":[
164 | 7,
165 | 100
166 | ]
167 | }
168 | ],
169 | "award1":[
170 | 1,
171 | 2,
172 | 3
173 | ],
174 | "award2":{
175 | "id":1,
176 | "type":2,
177 | "num":3
178 | }
179 | },
180 | "5":{
181 | "id":5,
182 | "name":"examp1004",
183 | "material":[
184 | "test"
185 | ],
186 | "attr":[
187 | [
188 | 1,
189 | 700
190 | ],
191 | [
192 | 2,
193 | 800
194 | ],
195 | [
196 | 3,
197 | 903
198 | ],
199 | {
200 | "add":[
201 | 7,
202 | 100
203 | ]
204 | }
205 | ],
206 | "award1":[
207 | 1,
208 | 2,
209 | 3
210 | ],
211 | "award2":{
212 | "id":1,
213 | "type":2,
214 | "num":3
215 | }
216 | }
217 | }
--------------------------------------------------------------------------------
/server/cfg_array_example2.lua:
--------------------------------------------------------------------------------
1 | -- Automatic generation from -->>
2 | -- excel file name: A_array表示例--cfg_array
3 | -- excel sheet name: 示例2+example2
4 |
5 | local cfg_array_example2 =
6 | --: id ## 英雄id
7 | --: name ## 英雄名字
8 | --: material ## 合成消耗
9 | --: attr ## 属性
10 | --: award1 ## 奖励1
11 | --: award2 ## 奖励2
12 |
13 | {
14 | [1] =
15 | {
16 | id = 1,
17 | name = 'examp1001',
18 | material =
19 | {
20 | [1] =
21 | {
22 | res = 1,
23 | id = 10001,
24 | count = 1
25 | },
26 | [2] =
27 | {
28 | res = 1,
29 | id = 10001,
30 | count = 1
31 | }
32 | },
33 | attr =
34 | {
35 | [1] =
36 | {
37 | [1] = 1,
38 | [2] = 700
39 | },
40 | [2] =
41 | {
42 | [1] = 2,
43 | [2] = 800
44 | },
45 | [3] =
46 | {
47 | [1] = 3,
48 | [2] = 900
49 | },
50 | [4] =
51 | {
52 | add =
53 | {
54 | [1] = 4,
55 | [2] = 100
56 | }
57 | }
58 | },
59 | award1 =
60 | {
61 | [1] = 1,
62 | [2] = 2,
63 | [3] = 3
64 | },
65 | award2 =
66 | {
67 | id = 1,
68 | type = 2,
69 | num = 3
70 | }
71 | },
72 | [2] =
73 | {
74 | id = 2,
75 | name = 'examp1002',
76 | material =
77 | {
78 | res = 1,
79 | id = 10001,
80 | count = 1
81 | },
82 | attr =
83 | {
84 | [1] =
85 | {
86 | [1] = 1,
87 | [2] = 700
88 | },
89 | [2] =
90 | {
91 | [1] = 2,
92 | [2] = 800
93 | },
94 | [3] =
95 | {
96 | [1] = 3,
97 | [2] = 901
98 | },
99 | [4] =
100 | {
101 | add =
102 | {
103 | [1] = 5,
104 | [2] = 100
105 | }
106 | }
107 | },
108 | award1 =
109 | {
110 | [1] = 1,
111 | [2] = 2,
112 | [3] = 3
113 | },
114 | award2 =
115 | {
116 | id = 1,
117 | type = 2,
118 | num = 3
119 | }
120 | },
121 | [3] =
122 | {
123 | id = 3,
124 | name = 'examp1003',
125 | material =
126 | {
127 | [1] = 1,
128 | [2] = 2,
129 | [3] = 3,
130 | [4] = 4,
131 | [5] = 5,
132 | [6] = 6,
133 | [7] = 7,
134 | [8] = 8,
135 | [9] = 9,
136 | [10] = 9,
137 | [11] = 9,
138 | [12] = 9,
139 | [13] = 9,
140 | [14] = 9,
141 | [15] = 9,
142 | [16] = 9,
143 | [17] = 9,
144 | [18] = 9
145 | },
146 | attr =
147 | {
148 | [1] =
149 | {
150 | [1] = 1,
151 | [2] = 700
152 | },
153 | [2] =
154 | {
155 | [1] = 2,
156 | [2] = 800
157 | },
158 | [3] =
159 | {
160 | [1] = 3,
161 | [2] = 902
162 | },
163 | [4] =
164 | {
165 | add =
166 | {
167 | [1] = 6,
168 | [2] = 100
169 | }
170 | }
171 | },
172 | award1 =
173 | {
174 | [1] = 1,
175 | [2] = 2,
176 | [3] = 3
177 | },
178 | award2 =
179 | {
180 | id = 1,
181 | type = 2,
182 | num = 3
183 | }
184 | },
185 | [4] =
186 | {
187 | id = 4,
188 | name = 'examp1004',
189 | material =
190 | {
191 | [1] = '测试数据',
192 | [2] = '测试数据2',
193 | [3] = '测试数据3'
194 | },
195 | attr =
196 | {
197 | [1] =
198 | {
199 | [1] = 1,
200 | [2] = 700
201 | },
202 | [2] =
203 | {
204 | [1] = 2,
205 | [2] = 800
206 | },
207 | [3] =
208 | {
209 | [1] = 3,
210 | [2] = 903
211 | },
212 | [4] =
213 | {
214 | add =
215 | {
216 | [1] = 7,
217 | [2] = 100
218 | }
219 | }
220 | },
221 | award1 =
222 | {
223 | [1] = 1,
224 | [2] = 2,
225 | [3] = 3
226 | },
227 | award2 =
228 | {
229 | id = 1,
230 | type = 2,
231 | num = 3
232 | }
233 | },
234 | [5] =
235 | {
236 | id = 5,
237 | name = 'examp1004',
238 | material =
239 | {
240 | [1] = 'test'
241 | },
242 | attr =
243 | {
244 | [1] =
245 | {
246 | [1] = 1,
247 | [2] = 700
248 | },
249 | [2] =
250 | {
251 | [1] = 2,
252 | [2] = 800
253 | },
254 | [3] =
255 | {
256 | [1] = 3,
257 | [2] = 903
258 | },
259 | [4] =
260 | {
261 | add =
262 | {
263 | [1] = 7,
264 | [2] = 100
265 | }
266 | }
267 | },
268 | award1 =
269 | {
270 | [1] = 1,
271 | [2] = 2,
272 | [3] = 3
273 | },
274 | award2 =
275 | {
276 | id = 1,
277 | type = 2,
278 | num = 3
279 | }
280 | }
281 | }
282 | return cfg_array_example2
--------------------------------------------------------------------------------
/server/cfg_array_example3.erl:
--------------------------------------------------------------------------------
1 | %% Automatic generation from -->>
2 | %% excel file name : A_array表示例--cfg_array
3 | %% excel sheet name : +example3
4 |
5 | -module(cfg_array_example3).
6 |
7 | -compile(export_all).
8 |
9 | %% 演示
10 | get('level') ->
11 | "啦啦啦!!!";
12 |
13 | get(_) ->
14 | undefined.
--------------------------------------------------------------------------------
/server/cfg_array_example3.ex:
--------------------------------------------------------------------------------
1 | ## Automatic generation from -->>
2 | ## excel file name: A_array表示例--cfg_array
3 | ## excel sheet name: +example3
4 |
5 | defmodule Cfg_Array_Example3 do
6 |
7 | ## 演示
8 | def get(:level) do
9 | "啦啦啦!!!"
10 | end
11 |
12 | def get(_) do
13 | :undefined
14 | end
15 |
16 | end
--------------------------------------------------------------------------------
/server/cfg_array_example3.json:
--------------------------------------------------------------------------------
1 | {
2 | "level":"啦啦啦!!!"
3 | }
--------------------------------------------------------------------------------
/server/cfg_array_example3.lua:
--------------------------------------------------------------------------------
1 | -- Automatic generation from -->>
2 | -- excel file name: A_array表示例--cfg_array
3 | -- excel sheet name: +example3
4 |
5 | local cfg_array_example3 =
6 | {
7 | -- 演示
8 | level = '啦啦啦!!!'
9 | }
10 | return cfg_array_example3
--------------------------------------------------------------------------------
/server/cfg_object.erl:
--------------------------------------------------------------------------------
1 | %% Automatic generation from -->>
2 | %% excel file name : A_object表示例--cfg_object
3 | %% excel sheet name : 武器(这个sheet就不会附加到导出名后部分)
4 |
5 | -module(cfg_object).
6 |
7 | -compile(export_all).
8 |
9 | %% 开放等级
10 | get('open_level') ->
11 | 90;
12 |
13 | %% 额外添加属性值1
14 | get('add_value1') ->
15 | 100.1;
16 |
17 | %% 额外添加属性值2
18 | get('add_value2') ->
19 | 100;
20 |
21 | %% 活动id
22 | get('act_id') ->
23 | 1001;
24 |
25 | %% 开始时间
26 | get('open') ->
27 | "18:00:0";
28 |
29 | %% 错误信息
30 | get(10000) ->
31 | "前面字段为errorID,这里是错误描述,是的object配置的server,client字段名还支持数字作为key(但是转出格式为xml和jsonarray时就不支持了)";
32 |
33 | %% 奖励1
34 | get('award1') ->
35 | [[1001, 20], {1002, 20}, [1003, 30]];
36 |
37 | %% 奖励2
38 | get('award2') ->
39 | {{1001, 10}, [1002, 20]};
40 |
41 | %% 奖励3(这条转成xml是就会报错)
42 | get('award3') ->
43 | #{1 => #{'res' => 1001, 'id' => 10001, 'count' => 1}, 2 => #{'res' => [1002, 1], 'id' => 10001, 'count' => 1}};
44 |
45 | %% 奖励4
46 | get('award4') ->
47 | #{'rr' => [1001, 20], 'ff' => [3006, 99], 'aa' => [7003, 1], 'test' => "这就是一个测试"};
48 |
49 | %% 奖励5
50 | get('award5') ->
51 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9];
52 |
53 | %% 奖励
54 | get('award6') ->
55 | [[1001, 20], [3006, 99], [7003, 1], #{'jsonobject' => [12356, 654321]}];
56 |
57 | get(_) ->
58 | undefined.
--------------------------------------------------------------------------------
/server/cfg_object.ex:
--------------------------------------------------------------------------------
1 | ## Automatic generation from -->>
2 | ## excel file name: A_object表示例--cfg_object
3 | ## excel sheet name: 武器(这个sheet就不会附加到导出名后部分)
4 |
5 | defmodule Cfg_Object do
6 |
7 | ## 开放等级
8 | def get(:open_level) do
9 | 90
10 | end
11 |
12 | ## 额外添加属性值1
13 | def get(:add_value1) do
14 | 100.1
15 | end
16 |
17 | ## 额外添加属性值2
18 | def get(:add_value2) do
19 | 100
20 | end
21 |
22 | ## 活动id
23 | def get(:act_id) do
24 | 1001
25 | end
26 |
27 | ## 开始时间
28 | def get(:open) do
29 | "18:00:0"
30 | end
31 |
32 | ## 错误信息
33 | def get(10000) do
34 | "前面字段为errorID,这里是错误描述,是的object配置的server,client字段名还支持数字作为key(但是转出格式为xml和jsonarray时就不支持了)"
35 | end
36 |
37 | ## 奖励1
38 | def get(:award1) do
39 | [[1001, 20], {1002, 20}, [1003, 30]]
40 | end
41 |
42 | ## 奖励2
43 | def get(:award2) do
44 | {{1001, 10}, [1002, 20]}
45 | end
46 |
47 | ## 奖励3(这条转成xml是就会报错,因为KEY为数字)
48 | def get(:award3) do
49 | %{1 => %{:res => 1001, :id => 10001, :count => 1}, 2 => %{:res => [1002, 1], :id => 10001, :count => 1}}
50 | end
51 |
52 | ## 奖励4
53 | def get(:award4) do
54 | %{:rr => [1001, 20], :ff => [3006, 99], :aa => [7003, 1], :test => "这就是一个测试"}
55 | end
56 |
57 | ## 奖励5
58 | def get(:award5) do
59 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
60 | end
61 |
62 | ## 奖励
63 | def get(:award6) do
64 | [[1001, 20], [3006, 99], [7003, 1], %{:jsonobject => [12356, 654321]}]
65 | end
66 |
67 | def get(_) do
68 | :undefined
69 | end
70 |
71 | end
--------------------------------------------------------------------------------
/server/cfg_object.json:
--------------------------------------------------------------------------------
1 | {
2 | "open_level":90,
3 | "add_value1":100.1,
4 | "add_value2":100,
5 | "act_id":1001,
6 | "open":"18:00:0",
7 | "10000":"前面字段为errorID,这里是错误描述,是的object配置的server,client字段名还支持数字作为key(但是转出格式为xml和jsonarray时就不支持了)",
8 | "award1":[
9 | [
10 | 1001,
11 | 20
12 | ],
13 | [
14 | 1002,
15 | 20
16 | ],
17 | [
18 | 1003,
19 | 30
20 | ]
21 | ],
22 | "award2":[
23 | [
24 | 1001,
25 | 10
26 | ],
27 | [
28 | 1002,
29 | 20
30 | ]
31 | ],
32 | "award3":{
33 | "1":{
34 | "res":1001,
35 | "id":10001,
36 | "count":1
37 | },
38 | "2":{
39 | "id":10001,
40 | "count":1,
41 | "res":[
42 | 1002,
43 | 1
44 | ]
45 | }
46 | },
47 | "award4":{
48 | "test":"这就是一个测试",
49 | "rr":[
50 | 1001,
51 | 20
52 | ],
53 | "ff":[
54 | 3006,
55 | 99
56 | ],
57 | "aa":[
58 | 7003,
59 | 1
60 | ]
61 | },
62 | "award5":[
63 | 1,
64 | 2,
65 | 3,
66 | 4,
67 | 5,
68 | 6,
69 | 7,
70 | 8,
71 | 9,
72 | 9,
73 | 9,
74 | 9,
75 | 9,
76 | 9,
77 | 9,
78 | 9,
79 | 9,
80 | 9
81 | ],
82 | "award6":[
83 | [
84 | 1001,
85 | 20
86 | ],
87 | [
88 | 3006,
89 | 99
90 | ],
91 | [
92 | 7003,
93 | 1
94 | ],
95 | {
96 | "jsonobject":[
97 | 12356,
98 | 654321
99 | ]
100 | }
101 | ]
102 | }
--------------------------------------------------------------------------------
/server/cfg_object.lua:
--------------------------------------------------------------------------------
1 | -- Automatic generation from -->>
2 | -- excel file name: A_object表示例--cfg_object
3 | -- excel sheet name: 武器(这个sheet就不会附加到导出名后部分)
4 |
5 | local cfg_object =
6 | {
7 | -- 开放等级
8 | open_level =90,
9 |
10 | -- 额外添加属性值1
11 | add_value1 =100.1,
12 |
13 | -- 额外添加属性值2
14 | add_value2 =100,
15 |
16 | -- 活动id
17 | act_id =1001,
18 |
19 | -- 开始时间
20 | open ='18:00:0',
21 |
22 | -- 错误信息
23 | [10000] ='前面字段为errorID,这里是错误描述,是的object配置的server,client字段名还支持数字作为key(但是转出格式为xml和jsonarray时就不支持了)',
24 |
25 | -- 奖励1
26 | award1 =
27 | {
28 | [1] =
29 | {
30 | [1] = 1001,
31 | [2] = 20
32 | },
33 | [2] =
34 | {
35 | [1] = 1002,
36 | [2] = 20
37 | },
38 | [3] =
39 | {
40 | [1] = 1003,
41 | [2] = 30
42 | }
43 | },
44 |
45 | -- 奖励2
46 | award2 =
47 | {
48 | [1] =
49 | {
50 | [1] = 1001,
51 | [2] = 10
52 | },
53 | [2] =
54 | {
55 | [1] = 1002,
56 | [2] = 20
57 | }
58 | },
59 |
60 | -- 奖励3(这条转成xml是就会报错)
61 | award3 =
62 | {
63 | [1] =
64 | {
65 | res = 1001,
66 | id = 10001,
67 | count = 1
68 | },
69 | [2] =
70 | {
71 | id = 10001,
72 | count = 1,
73 | res =
74 | {
75 | [1] = 1002,
76 | [2] = 1
77 | }
78 | }
79 | },
80 |
81 | -- 奖励4
82 | award4 =
83 | {
84 | test = '这就是一个测试',
85 | rr =
86 | {
87 | [1] = 1001,
88 | [2] = 20
89 | },
90 | ff =
91 | {
92 | [1] = 3006,
93 | [2] = 99
94 | },
95 | aa =
96 | {
97 | [1] = 7003,
98 | [2] = 1
99 | }
100 | },
101 |
102 | -- 奖励5
103 | award5 =
104 | {
105 | [1] = 1,
106 | [2] = 2,
107 | [3] = 3,
108 | [4] = 4,
109 | [5] = 5,
110 | [6] = 6,
111 | [7] = 7,
112 | [8] = 8,
113 | [9] = 9,
114 | [10] = 9,
115 | [11] = 9,
116 | [12] = 9,
117 | [13] = 9,
118 | [14] = 9,
119 | [15] = 9,
120 | [16] = 9,
121 | [17] = 9,
122 | [18] = 9
123 | },
124 |
125 | -- 奖励
126 | award6 =
127 | {
128 | [1] =
129 | {
130 | [1] = 1001,
131 | [2] = 20
132 | },
133 | [2] =
134 | {
135 | [1] = 3006,
136 | [2] = 99
137 | },
138 | [3] =
139 | {
140 | [1] = 7003,
141 | [2] = 1
142 | },
143 | [4] =
144 | {
145 | jsonobject =
146 | {
147 | [1] = 12356,
148 | [2] = 654321
149 | }
150 | }
151 | }
152 | }
153 | return cfg_object
--------------------------------------------------------------------------------
/server/cfg_object1_cfg_object.ex:
--------------------------------------------------------------------------------
1 | ## Automatic generation from -->>
2 | ## excel file name: A_object表示例--cfg_object1
3 | ## excel sheet name: A_object表示例--cfg_object
4 |
5 | defmodule Cfg_Object1_Cfg_Object do
6 |
7 | ## 开放等级
8 | def get(:open_level) do
9 | 90
10 | end
11 |
12 | ## 额外添加属性值1
13 | def get(:add_value1) do
14 | 100.1
15 | end
16 |
17 | ## 额外添加属性值2
18 | def get(:add_value2) do
19 | 100
20 | end
21 |
22 | ## 活动id
23 | def get(:act_id) do
24 | 1001
25 | end
26 |
27 | ## 开始时间
28 | def get(:open) do
29 | "fgfdg"
30 | end
31 |
32 | ## 错误信息
33 | def get(10000) do
34 | "前面字段为errorID,这里是错误描述,是的object配置的server,client字段名还支持数字作为key(但是转出格式为xml和jsonarray时就不支持了)"
35 | end
36 |
37 | ## 奖励1
38 | def get(:award1) do
39 | [[1001, 20], {1002, 20}, [1003, 30]]
40 | end
41 |
42 | ## 奖励2
43 | def get(:award2) do
44 | {{1001, 10}, [1002, 20]}
45 | end
46 |
47 | ## 奖励3(这条转成xml是就会报错,因为KEY为数字)
48 | def get(:award3) do
49 | %{1 => %{:res => 1001, :id => 10001, :count => 1}, 2 => %{:res => [1002, 1], :id => 10001, :count => 1}}
50 | end
51 |
52 | ## 奖励4
53 | def get(:award4) do
54 | %{:rr => [1001, 20], :ff => [3006, 99], :aa => [7003, 1], :test => "这就是一个测试"}
55 | end
56 |
57 | ## 奖励5
58 | def get(:award5) do
59 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
60 | end
61 |
62 | ## 奖励
63 | def get(:award6) do
64 | [[1001, 20], [3006, 99], [7003, 1], %{:jsonobject => [12356, 654321]}]
65 | end
66 |
67 | def get(_) do
68 | :undefined
69 | end
70 |
71 | end
--------------------------------------------------------------------------------
/slpp/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *~
3 |
4 |
5 |
--------------------------------------------------------------------------------
/slpp/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010, 2011, 2012 SirAnthony
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/slpp/README.markdown:
--------------------------------------------------------------------------------
1 | #### SLPP
2 | SLPP is a simple lua-python data structures parser.
3 |
4 | Lua data check:
5 |
6 | ```lua
7 | data = '{ array = { 65, 23, 5 }, dict = { string = "value", array = { 3, 6, 4}, mixed = { 43, 54.3, false, string = "value", 9 } } }'
8 | > data = assert(loadstring('return ' .. data))()
9 | > for i,j in pairs(data['dict']) do print(i,j) end
10 | mixed table: 0x2014290
11 | string value
12 | array table: 0x2014200
13 | ```
14 |
15 | Parse lua data:
16 |
17 | ```python
18 | >>> from slpp import slpp as lua
19 | >>> data = lua.decode('{ array = { 65, 23, 5 }, dict = { string = "value", array = { 3, 6, 4}, mixed = { 43, 54.3, false, string = "value", 9 } } }')
20 | >>> print data
21 | {'array': [65, 23, 5], 'dict': {'mixed': {0: 43, 1: 54.33, 2: False, 4: 9, 'string': 'value'}, 'array': [3, 6, 4], 'string': 'value'}}
22 | ```
23 |
24 | Dump python object:
25 |
26 | ```python
27 | >>> lua.encode(data)
28 | '{array = {65,23,5},dict = {mixed = {43,54.33,false,9,string = "value"},array = {3,6,4},string = "value"}}'
29 | ```
30 |
31 | Dump test:
32 |
33 | ```lua
34 | > data = assert(loadstring('return ' .. '{array = {65,23,5,},dict = {mixed = {43,54.33,false,9,string = "value",},array = {3,6,4,},string = "value",},}'))()
35 | > print(data['dict'])
36 | table: 0x1b64ea0
37 | > for i,j in pairs(data['dict']) do print(i,j) end
38 | mixed table: 0x880afe0
39 | array table: 0x880af60
40 | string value
41 | ```
42 |
--------------------------------------------------------------------------------
/slpp/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erlyshare/ConfigConvertTool/3ac2b7fdd8b09cd98e75fac03f589e0cd5881741/slpp/__init__.py
--------------------------------------------------------------------------------
/slpp/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from distutils.core import setup
3 |
4 | setup(
5 | name='SLPP',
6 | description='SLPP is a simple lua-python data structures parser',
7 | version='1.0',
8 | author='SirAnthony',
9 | url='https://github.com/SirAnthony/slpp',
10 | license='https://github.com/SirAnthony/slpp/blob/master/LICENSE',
11 | keywords=['lua'],
12 | py_modules=['slpp'],
13 | )
14 |
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erlyshare/ConfigConvertTool/3ac2b7fdd8b09cd98e75fac03f589e0cd5881741/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229.zip
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *~
3 |
4 |
5 |
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010, 2011, 2012 SirAnthony
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/README.markdown:
--------------------------------------------------------------------------------
1 | #### SLPP
2 | SLPP is a simple lua-python data structures parser.
3 |
4 | Lua data check:
5 |
6 | ```lua
7 | data = '{ array = { 65, 23, 5 }, dict = { string = "value", array = { 3, 6, 4}, mixed = { 43, 54.3, false, string = "value", 9 } } }'
8 | > data = assert(loadstring('return ' .. data))()
9 | > for i,j in pairs(data['dict']) do print(i,j) end
10 | mixed table: 0x2014290
11 | string value
12 | array table: 0x2014200
13 | ```
14 |
15 | Parse lua data:
16 |
17 | ```python
18 | >>> from slpp import slpp as lua
19 | >>> data = lua.decode('{ array = { 65, 23, 5 }, dict = { string = "value", array = { 3, 6, 4}, mixed = { 43, 54.3, false, string = "value", 9 } } }')
20 | >>> print data
21 | {'array': [65, 23, 5], 'dict': {'mixed': {0: 43, 1: 54.33, 2: False, 4: 9, 'string': 'value'}, 'array': [3, 6, 4], 'string': 'value'}}
22 | ```
23 |
24 | Dump python object:
25 |
26 | ```python
27 | >>> lua.encode(data)
28 | '{array = {65,23,5},dict = {mixed = {43,54.33,false,9,string = "value"},array = {3,6,4},string = "value"}}'
29 | ```
30 |
31 | Dump test:
32 |
33 | ```lua
34 | > data = assert(loadstring('return ' .. '{array = {65,23,5,},dict = {mixed = {43,54.33,false,9,string = "value",},array = {3,6,4,},string = "value",},}'))()
35 | > print(data['dict'])
36 | table: 0x1b64ea0
37 | > for i,j in pairs(data['dict']) do print(i,j) end
38 | mixed table: 0x880afe0
39 | array table: 0x880af60
40 | string value
41 | ```
42 |
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erlyshare/ConfigConvertTool/3ac2b7fdd8b09cd98e75fac03f589e0cd5881741/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/__init__.py
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from distutils.core import setup
3 |
4 | setup(
5 | name='SLPP',
6 | description='SLPP is a simple lua-python data structures parser',
7 | version='1.0',
8 | author='SirAnthony',
9 | url='https://github.com/SirAnthony/slpp',
10 | license='https://github.com/SirAnthony/slpp/blob/master/LICENSE',
11 | keywords=['lua'],
12 | py_modules=['slpp'],
13 | )
14 |
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/slpp.py:
--------------------------------------------------------------------------------
1 | import re
2 | import sys
3 |
4 | ERRORS = {
5 | 'unexp_end_string': u'Unexpected end of string while parsing Lua string.',
6 | 'unexp_end_table': u'Unexpected end of table while parsing Lua string.',
7 | 'mfnumber_minus': u'Malformed number (no digits after initial minus).',
8 | 'mfnumber_dec_point': u'Malformed number (no digits after decimal point).',
9 | 'mfnumber_sci': u'Malformed number (bad scientific format).',
10 | }
11 | # Python 3 renamed the unicode type to str,
12 | # the old str type has been replaced by bytes
13 | try:
14 | basestring
15 | except NameError:
16 | basestring = str
17 |
18 | try:
19 | unicode
20 | except NameError:
21 | unicode = str
22 |
23 | class ParseError(Exception):
24 | pass
25 |
26 |
27 | class SLPP(object):
28 |
29 | def __init__(self):
30 | self.text = ''
31 | self.ch = ''
32 | self.at = 0
33 | self.len = 0
34 | self.depth = 0
35 | self.space = re.compile('\s', re.M)
36 | self.alnum = re.compile('\w', re.M)
37 | self.newline = '\n'
38 | self.tab = '\t'
39 |
40 | def decode(self, text):
41 | if not text or not isinstance(text, basestring):
42 | return
43 | #FIXME: only short comments removed
44 | reg = re.compile('--.*$', re.M)
45 | text = reg.sub('', text, 0)
46 | self.text = text
47 | self.at, self.ch, self.depth = 0, '', 0
48 | self.len = len(text)
49 | self.next_chr()
50 | result = self.value()
51 | return result
52 |
53 | def encode(self, obj):
54 | self.depth = 0
55 | return self.__encode(obj)
56 |
57 | def __encode(self, obj):
58 | s = ''
59 | tab = self.tab
60 | newline = self.newline
61 | tp = type(obj)
62 | if isinstance(obj, str):
63 | s += '"%s"' % obj.replace(r'"', r'\"')
64 | if isinstance(obj, unicode):
65 | s += '"%s"' % obj.encode('utf-8').replace(r'"', r'\"')
66 | elif tp in [int, float, long, complex]:
67 | s += str(obj)
68 | elif tp is bool:
69 | s += str(obj).lower()
70 | elif obj is None:
71 | s += 'nil'
72 | elif tp in [list, tuple, dict]:
73 | self.depth += 1
74 | if len(obj) == 0 or ( tp is not dict and len(filter(
75 | lambda x: type(x) in (int, float, long) \
76 | or (isinstance(x, basestring) and len(x) < 10), obj
77 | )) == len(obj) ):
78 | newline = tab = ''
79 | dp = tab * self.depth
80 | s += "%s{%s" % (tab * (self.depth - 2), newline)
81 | if tp is dict:
82 | contents = []
83 | for k, v in obj.iteritems():
84 | if type(k) is int:
85 | contents.append(self.__encode(v))
86 | else:
87 | contents.append(dp + '%s = %s' % (k, self.__encode(v)))
88 | s += (',%s' % newline).join(contents)
89 |
90 | else:
91 | s += (',%s' % newline).join(
92 | [dp + self.__encode(el) for el in obj])
93 | self.depth -= 1
94 | s += "%s%s}" % (newline, tab * self.depth)
95 | return s
96 |
97 | def white(self):
98 | while self.ch:
99 | if self.space.match(self.ch):
100 | self.next_chr()
101 | else:
102 | break
103 |
104 | def next_chr(self):
105 | if self.at >= self.len:
106 | self.ch = None
107 | return None
108 | self.ch = self.text[self.at]
109 | self.at += 1
110 | return True
111 |
112 | def value(self):
113 | self.white()
114 | if not self.ch:
115 | return
116 | if self.ch == '{':
117 | return self.object()
118 | if self.ch == "[":
119 | self.next_chr()
120 | if self.ch in ['"', "'", '[']:
121 | return self.string(self.ch)
122 | if self.ch.isdigit() or self.ch == '-':
123 | return self.number()
124 | return self.word()
125 |
126 | def string(self, end=None):
127 | s = ''
128 | start = self.ch
129 | if end == '[':
130 | end = ']'
131 | if start in ['"', "'", '[']:
132 | while self.next_chr():
133 | if self.ch == end:
134 | self.next_chr()
135 | if start != "[" or self.ch == ']':
136 | return s
137 | if self.ch == '\\' and start == end:
138 | self.next_chr()
139 | if self.ch != end:
140 | s += '\\'
141 | s += self.ch
142 | raise Exception(ERRORS['unexp_end_string'])
143 |
144 | def object(self):
145 | o = {}
146 | k = None
147 | idx = 0
148 | numeric_keys = False
149 | self.depth += 1
150 | self.next_chr()
151 | self.white()
152 | if self.ch and self.ch == '}':
153 | self.depth -= 1
154 | self.next_chr()
155 | return o #Exit here
156 | else:
157 | while self.ch:
158 | self.white()
159 | if self.ch == '{':
160 | o[idx] = self.object()
161 | idx += 1
162 | continue
163 | elif self.ch == '}':
164 | self.depth -= 1
165 | self.next_chr()
166 | if k is not None:
167 | o[idx] = k
168 | if not numeric_keys and len([ key for key in o if isinstance(key, (str, unicode, float, bool, tuple))]) == 0:
169 | ar = []
170 | for key in o:
171 | ar.insert(key, o[key])
172 | o = ar
173 | return o #or here
174 | else:
175 | if self.ch == ',':
176 | self.next_chr()
177 | continue
178 | else:
179 | k = self.value()
180 | if self.ch == ']':
181 | numeric_keys = True
182 | self.next_chr()
183 | self.white()
184 | ch = self.ch
185 | if ch in ('=', ','):
186 | self.next_chr()
187 | self.white()
188 | if ch == '=':
189 | o[k] = self.value()
190 | else:
191 | o[idx] = k
192 | idx += 1
193 | k = None
194 | raise Exception(ERRORS['unexp_end_table']) #Bad exit here
195 |
196 | words = {'true': True, 'false': False, 'nil': None}
197 | def word(self):
198 | s = ''
199 | if self.ch != '\n':
200 | s = self.ch
201 | self.next_chr()
202 | while self.ch is not None and self.alnum.match(self.ch) and s not in self.words:
203 | s += self.ch
204 | self.next_chr()
205 | return self.words.get(s, s)
206 |
207 | def number(self):
208 | def next_digit(err):
209 | n = self.ch
210 | self.next_chr()
211 | if not self.ch or not self.ch.isdigit():
212 | raise ParseError(err)
213 | return n
214 | n = ''
215 | try:
216 | if self.ch == '-':
217 | n += next_digit(ERRORS['mfnumber_minus'])
218 | n += self.digit()
219 | if n == '0' and self.ch in ['x', 'X']:
220 | n += self.ch
221 | self.next_chr()
222 | n += self.hex()
223 | else:
224 | if self.ch and self.ch == '.':
225 | n += next_digit(ERRORS['mfnumber_dec_point'])
226 | n += self.digit()
227 | if self.ch and self.ch in ['e', 'E']:
228 | n += self.ch
229 | self.next_chr()
230 | if not self.ch or self.ch not in ('+', '-'):
231 | raise ParseError(ERRORS['mfnumber_sci'])
232 | n += next_digit(ERRORS['mfnumber_sci'])
233 | n += self.digit()
234 | except ParseError:
235 | t, e = sys.exc_info()[:2]
236 | print(e)
237 | return 0
238 | try:
239 | return int(n, 0)
240 | except:
241 | pass
242 | return float(n)
243 |
244 | def digit(self):
245 | n = ''
246 | while self.ch and self.ch.isdigit():
247 | n += self.ch
248 | self.next_chr()
249 | return n
250 |
251 | def hex(self):
252 | n = ''
253 | while self.ch and \
254 | (self.ch in 'ABCDEFabcdef' or self.ch.isdigit()):
255 | n += self.ch
256 | self.next_chr()
257 | return n
258 |
259 |
260 | slpp = SLPP()
261 |
262 | __all__ = ['slpp']
263 |
--------------------------------------------------------------------------------
/slpp/slpp-c4d7f69af338f973c0ef21a9a06a145936367229/tests.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | from slpp import slpp as lua
5 |
6 | """
7 | Tests for slpp
8 | """
9 |
10 |
11 | def is_iterator(obj):
12 | """
13 | >>> assert is_iterator(list()) is True
14 | >>> assert is_iterator(int) is False
15 | """
16 | if isinstance(obj, (list, tuple)):
17 | return True
18 | try:
19 | iter(obj)
20 | return True
21 | except TypeError:
22 | return False
23 |
24 |
25 | def differ(value, origin):
26 | """
27 | Same:
28 | >>> differ(1, 1)
29 | >>> differ([2, 3], [2, 3])
30 | >>> differ({'1': 3, '4': '6'}, {'4': '6', '1': 3})
31 | >>> differ('4', '4')
32 |
33 | Different:
34 | >>> differ(1, 2)
35 | Traceback (most recent call last):
36 | ...
37 | AssertionError: 1 not match original: 2.
38 | >>> differ([2, 3], [3, 2])
39 | Traceback (most recent call last):
40 | ...
41 | AssertionError: 2 not match original: 3.
42 | >>> differ({'6': 4, '3': '1'}, {'4': '6', '1': 3})
43 | Traceback (most recent call last):
44 | ...
45 | AssertionError: {'3': '1', '6': 4} not match original: {'1': 3, '4': '6'};
46 | Key: 1, item: 3
47 | >>> differ('4', 'no')
48 | Traceback (most recent call last):
49 | ...
50 | AssertionError: 4 not match original: no.
51 | """
52 |
53 | if type(value) is not type(origin):
54 | raise AssertionError('Types does not match: {0}, {1}'.format(type(value), type(origin)))
55 |
56 | if isinstance(origin, dict):
57 | for key, item in origin.items():
58 | try:
59 | differ(value[key], item)
60 | except KeyError:
61 | raise AssertionError('''{0} not match original: {1};
62 | Key: {2}, item: {3}'''.format(value, origin, key, item))
63 | return
64 |
65 | if isinstance(origin, basestring):
66 | assert value == origin, '{0} not match original: {1}.'.format(value, origin)
67 | return
68 |
69 | if is_iterator(origin):
70 | for i in range(0, len(origin)):
71 | try:
72 | differ(value[i], origin[i])
73 | except IndexError:
74 | raise AssertionError(
75 | '{0} not match original: {1}. Item {2} not found'.format(
76 | response, origin, origin[i]))
77 | except Exception, e:
78 | raise e
79 | return
80 |
81 | assert value == origin, '{0} not match original: {1}.'.format(value, origin)
82 |
83 |
84 |
85 |
86 | def number_test():
87 | """
88 | Integer and float:
89 | >>> assert lua.decode('3') == 3
90 | >>> assert lua.decode('4.1') == 4.1
91 |
92 | Negative float:
93 | >>> assert lua.decode('-0.45') == -0.45
94 |
95 | Scientific:
96 | >>> assert lua.decode('3e-7') == 3e-7
97 | >>> assert lua.decode('-3.23e+17') == -3.23e+17
98 |
99 | Hex:
100 | >>> assert lua.decode('0x3a') == 0x3a
101 |
102 | #4
103 | >>> differ(lua.decode('''{ \
104 | ID = 0x74fa4cae, \
105 | Version = 0x07c2, \
106 | Manufacturer = 0x21544948 \
107 | }'''), { \
108 | 'ID': 0x74fa4cae, \
109 | 'Version': 0x07c2, \
110 | 'Manufacturer': 0x21544948 \
111 | })
112 | """
113 | pass
114 |
115 |
116 | def test_bool():
117 | """
118 | >>> assert lua.decode('false') == False
119 | >>> assert lua.decode('true') == True
120 |
121 | >>> assert lua.encode(False) == 'false'
122 | >>> assert lua.encode(True) == 'true'
123 | """
124 | pass
125 |
126 |
127 | def test_nil():
128 | """
129 | >>> assert lua.decode('nil') == None
130 | >>> assert lua.encode(None) == 'nil'
131 | """
132 | pass
133 |
134 |
135 | def table_test():
136 | """
137 | Bracketed string key:
138 | >>> assert lua.decode('{[10] = 1}') == {10: 1}
139 |
140 | Void table:
141 | >>> assert lua.decode('{nil}') == []
142 |
143 | Values-only table:
144 | >>> assert lua.decode('{"10"}') == ["10"]
145 |
146 | Last zero
147 | >>> assert lua.decode('{0, 1, 0}') == [0,1,0]
148 | """
149 | pass
150 |
151 | def string_test():
152 | r"""
153 | Escape test:
154 | >>> assert lua.decode(r"'test\'s string'") == "test's string"
155 |
156 | Add escaping on encode:
157 | >>> assert lua.encode({'a': 'func("call()");'}) == '{\n\ta = "func(\\"call()\\");"\n}'
158 | """
159 | pass
160 |
161 | def basic_test():
162 | """
163 | No data loss:
164 |
165 | >>> data = '{ array = { 65, 23, 5 }, dict = { string = "value", array = { 3, 6, 4}, mixed = { 43, 54.3, false, string = "value", 9 } } }'
166 | >>> d = lua.decode(data)
167 | >>> differ(d, lua.decode(lua.encode(d)))
168 | """
169 | pass
170 |
171 |
172 | def unicode_test():
173 | ur"""
174 | >>> assert lua.encode(u'Привет') == '"\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82"'
175 | >>> assert lua.encode({'s': u'Привет'}) == '{\n\ts = "Привет"\n}'
176 | """
177 | pass
178 |
179 |
180 | if __name__ == '__main__':
181 | import doctest
182 | doctest.testmod()
183 |
--------------------------------------------------------------------------------
/slpp/slpp.py:
--------------------------------------------------------------------------------
1 | import re
2 | import sys
3 |
4 | ERRORS = {
5 | 'unexp_end_string': u'Unexpected end of string while parsing Lua string.',
6 | 'unexp_end_table': u'Unexpected end of table while parsing Lua string.',
7 | 'mfnumber_minus': u'Malformed number (no digits after initial minus).',
8 | 'mfnumber_dec_point': u'Malformed number (no digits after decimal point).',
9 | 'mfnumber_sci': u'Malformed number (bad scientific format).',
10 | }
11 | # Python 3 renamed the unicode type to str,
12 | # the old str type has been replaced by bytes
13 | try:
14 | basestring
15 | except NameError:
16 | basestring = str
17 |
18 | try:
19 | unicode
20 | except NameError:
21 | unicode = str
22 |
23 | class ParseError(Exception):
24 | pass
25 |
26 |
27 | class SLPP(object):
28 |
29 | def __init__(self):
30 | self.text = ''
31 | self.ch = ''
32 | self.at = 0
33 | self.len = 0
34 | self.depth = 0
35 | self.space = re.compile('\s', re.M)
36 | self.alnum = re.compile('\w', re.M)
37 | self.newline = '\n'
38 | self.tab = '\t'
39 |
40 | def decode(self, text):
41 | if not text or not isinstance(text, basestring):
42 | return
43 | #FIXME: only short comments removed
44 | reg = re.compile('--.*$', re.M)
45 | text = reg.sub('', text, 0)
46 | self.text = text
47 | self.at, self.ch, self.depth = 0, '', 0
48 | self.len = len(text)
49 | self.next_chr()
50 | result = self.value()
51 | return result
52 |
53 | def encode(self, obj):
54 | self.depth = 0
55 | return self.__encode(obj)
56 |
57 | def __encode(self, obj):
58 | s = ''
59 | tab = self.tab
60 | newline = self.newline
61 | tp = type(obj)
62 | if isinstance(obj, str):
63 | s += '"%s"' % obj.replace(r'"', r'\"')
64 | if isinstance(obj, unicode):
65 | s += '"%s"' % obj.encode('utf-8').replace(r'"', r'\"')
66 | elif tp in [int, float, long, complex]:
67 | s += str(obj)
68 | elif tp is bool:
69 | s += str(obj).lower()
70 | elif obj is None:
71 | s += 'nil'
72 | elif tp in [list, tuple, dict]:
73 | self.depth += 1
74 | if len(obj) == 0 or ( tp is not dict and len(filter(
75 | lambda x: type(x) in (int, float, long) \
76 | or (isinstance(x, basestring) and len(x) < 10), obj
77 | )) == len(obj) ):
78 | newline = tab = ''
79 | dp = tab * self.depth
80 | s += "%s{%s" % (tab * (self.depth - 2), newline)
81 | if tp is dict:
82 | contents = []
83 | for k, v in obj.iteritems():
84 | if type(k) is int:
85 | contents.append(self.__encode(v))
86 | else:
87 | contents.append(dp + '%s = %s' % (k, self.__encode(v)))
88 | s += (',%s' % newline).join(contents)
89 |
90 | else:
91 | s += (',%s' % newline).join(
92 | [dp + self.__encode(el) for el in obj])
93 | self.depth -= 1
94 | s += "%s%s}" % (newline, tab * self.depth)
95 | return s
96 |
97 | def white(self):
98 | while self.ch:
99 | if self.space.match(self.ch):
100 | self.next_chr()
101 | else:
102 | break
103 |
104 | def next_chr(self):
105 | if self.at >= self.len:
106 | self.ch = None
107 | return None
108 | self.ch = self.text[self.at]
109 | self.at += 1
110 | return True
111 |
112 | def value(self):
113 | self.white()
114 | if not self.ch:
115 | return
116 | if self.ch == '{':
117 | return self.object()
118 | if self.ch == "[":
119 | self.next_chr()
120 | if self.ch in ['"', "'", '[']:
121 | return self.string(self.ch)
122 | if self.ch.isdigit() or self.ch == '-':
123 | return self.number()
124 | return self.word()
125 |
126 | def string(self, end=None):
127 | s = ''
128 | start = self.ch
129 | if end == '[':
130 | end = ']'
131 | if start in ['"', "'", '[']:
132 | while self.next_chr():
133 | if self.ch == end:
134 | self.next_chr()
135 | if start != "[" or self.ch == ']':
136 | return s
137 | if self.ch == '\\' and start == end:
138 | self.next_chr()
139 | if self.ch != end:
140 | s += '\\'
141 | s += self.ch
142 | raise Exception(ERRORS['unexp_end_string'])
143 |
144 | def object(self):
145 | o = {}
146 | k = None
147 | idx = 0
148 | numeric_keys = False
149 | self.depth += 1
150 | self.next_chr()
151 | self.white()
152 | if self.ch and self.ch == '}':
153 | self.depth -= 1
154 | self.next_chr()
155 | return o #Exit here
156 | else:
157 | while self.ch:
158 | self.white()
159 | if self.ch == '{':
160 | o[idx] = self.object()
161 | idx += 1
162 | continue
163 | elif self.ch == '}':
164 | self.depth -= 1
165 | self.next_chr()
166 | if k is not None:
167 | o[idx] = k
168 | if not numeric_keys and len([ key for key in o if isinstance(key, (str, unicode, float, bool, tuple))]) == 0:
169 | ar = []
170 | for key in o:
171 | ar.insert(key, o[key])
172 | o = ar
173 | return o #or here
174 | else:
175 | if self.ch == ',':
176 | self.next_chr()
177 | continue
178 | else:
179 | k = self.value()
180 | if self.ch == ']':
181 | numeric_keys = True
182 | self.next_chr()
183 | self.white()
184 | ch = self.ch
185 | if ch in ('=', ','):
186 | self.next_chr()
187 | self.white()
188 | if ch == '=':
189 | o[k] = self.value()
190 | else:
191 | o[idx] = k
192 | idx += 1
193 | k = None
194 | raise Exception(ERRORS['unexp_end_table']) #Bad exit here
195 |
196 | words = {'true': True, 'false': False, 'nil': None}
197 | def word(self):
198 | s = ''
199 | if self.ch != '\n':
200 | s = self.ch
201 | self.next_chr()
202 | while self.ch is not None and self.alnum.match(self.ch) and s not in self.words:
203 | s += self.ch
204 | self.next_chr()
205 | return self.words.get(s, s)
206 |
207 | def number(self):
208 | def next_digit(err):
209 | n = self.ch
210 | self.next_chr()
211 | if not self.ch or not self.ch.isdigit():
212 | raise ParseError(err)
213 | return n
214 | n = ''
215 | try:
216 | if self.ch == '-':
217 | n += next_digit(ERRORS['mfnumber_minus'])
218 | n += self.digit()
219 | if n == '0' and self.ch in ['x', 'X']:
220 | n += self.ch
221 | self.next_chr()
222 | n += self.hex()
223 | else:
224 | if self.ch and self.ch == '.':
225 | n += next_digit(ERRORS['mfnumber_dec_point'])
226 | n += self.digit()
227 | if self.ch and self.ch in ['e', 'E']:
228 | n += self.ch
229 | self.next_chr()
230 | if not self.ch or self.ch not in ('+', '-'):
231 | raise ParseError(ERRORS['mfnumber_sci'])
232 | n += next_digit(ERRORS['mfnumber_sci'])
233 | n += self.digit()
234 | except ParseError:
235 | t, e = sys.exc_info()[:2]
236 | print(e)
237 | return 0
238 | try:
239 | return int(n, 0)
240 | except:
241 | pass
242 | return float(n)
243 |
244 | def digit(self):
245 | n = ''
246 | while self.ch and self.ch.isdigit():
247 | n += self.ch
248 | self.next_chr()
249 | return n
250 |
251 | def hex(self):
252 | n = ''
253 | while self.ch and \
254 | (self.ch in 'ABCDEFabcdef' or self.ch.isdigit()):
255 | n += self.ch
256 | self.next_chr()
257 | return n
258 |
259 |
260 | slpp = SLPP()
261 |
262 | __all__ = ['slpp']
263 |
--------------------------------------------------------------------------------
/slpp/tests.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | from slpp import slpp as lua
5 |
6 | """
7 | Tests for slpp
8 | """
9 |
10 |
11 | def is_iterator(obj):
12 | """
13 | >>> assert is_iterator(list()) is True
14 | >>> assert is_iterator(int) is False
15 | """
16 | if isinstance(obj, (list, tuple)):
17 | return True
18 | try:
19 | iter(obj)
20 | return True
21 | except TypeError:
22 | return False
23 |
24 |
25 | def differ(value, origin):
26 | """
27 | Same:
28 | >>> differ(1, 1)
29 | >>> differ([2, 3], [2, 3])
30 | >>> differ({'1': 3, '4': '6'}, {'4': '6', '1': 3})
31 | >>> differ('4', '4')
32 |
33 | Different:
34 | >>> differ(1, 2)
35 | Traceback (most recent call last):
36 | ...
37 | AssertionError: 1 not match original: 2.
38 | >>> differ([2, 3], [3, 2])
39 | Traceback (most recent call last):
40 | ...
41 | AssertionError: 2 not match original: 3.
42 | >>> differ({'6': 4, '3': '1'}, {'4': '6', '1': 3})
43 | Traceback (most recent call last):
44 | ...
45 | AssertionError: {'3': '1', '6': 4} not match original: {'1': 3, '4': '6'};
46 | Key: 1, item: 3
47 | >>> differ('4', 'no')
48 | Traceback (most recent call last):
49 | ...
50 | AssertionError: 4 not match original: no.
51 | """
52 |
53 | if type(value) is not type(origin):
54 | raise AssertionError('Types does not match: {0}, {1}'.format(type(value), type(origin)))
55 |
56 | if isinstance(origin, dict):
57 | for key, item in origin.items():
58 | try:
59 | differ(value[key], item)
60 | except KeyError:
61 | raise AssertionError('''{0} not match original: {1};
62 | Key: {2}, item: {3}'''.format(value, origin, key, item))
63 | return
64 |
65 | if isinstance(origin, basestring):
66 | assert value == origin, '{0} not match original: {1}.'.format(value, origin)
67 | return
68 |
69 | if is_iterator(origin):
70 | for i in range(0, len(origin)):
71 | try:
72 | differ(value[i], origin[i])
73 | except IndexError:
74 | raise AssertionError(
75 | '{0} not match original: {1}. Item {2} not found'.format(
76 | response, origin, origin[i]))
77 | except Exception, e:
78 | raise e
79 | return
80 |
81 | assert value == origin, '{0} not match original: {1}.'.format(value, origin)
82 |
83 |
84 |
85 |
86 | def number_test():
87 | """
88 | Integer and float:
89 | >>> assert lua.decode('3') == 3
90 | >>> assert lua.decode('4.1') == 4.1
91 |
92 | Negative float:
93 | >>> assert lua.decode('-0.45') == -0.45
94 |
95 | Scientific:
96 | >>> assert lua.decode('3e-7') == 3e-7
97 | >>> assert lua.decode('-3.23e+17') == -3.23e+17
98 |
99 | Hex:
100 | >>> assert lua.decode('0x3a') == 0x3a
101 |
102 | #4
103 | >>> differ(lua.decode('''{ \
104 | ID = 0x74fa4cae, \
105 | Version = 0x07c2, \
106 | Manufacturer = 0x21544948 \
107 | }'''), { \
108 | 'ID': 0x74fa4cae, \
109 | 'Version': 0x07c2, \
110 | 'Manufacturer': 0x21544948 \
111 | })
112 | """
113 | pass
114 |
115 |
116 | def test_bool():
117 | """
118 | >>> assert lua.decode('false') == False
119 | >>> assert lua.decode('true') == True
120 |
121 | >>> assert lua.encode(False) == 'false'
122 | >>> assert lua.encode(True) == 'true'
123 | """
124 | pass
125 |
126 |
127 | def test_nil():
128 | """
129 | >>> assert lua.decode('nil') == None
130 | >>> assert lua.encode(None) == 'nil'
131 | """
132 | pass
133 |
134 |
135 | def table_test():
136 | """
137 | Bracketed string key:
138 | >>> assert lua.decode('{[10] = 1}') == {10: 1}
139 |
140 | Void table:
141 | >>> assert lua.decode('{nil}') == []
142 |
143 | Values-only table:
144 | >>> assert lua.decode('{"10"}') == ["10"]
145 |
146 | Last zero
147 | >>> assert lua.decode('{0, 1, 0}') == [0,1,0]
148 | """
149 | pass
150 |
151 | def string_test():
152 | r"""
153 | Escape test:
154 | >>> assert lua.decode(r"'test\'s string'") == "test's string"
155 |
156 | Add escaping on encode:
157 | >>> assert lua.encode({'a': 'func("call()");'}) == '{\n\ta = "func(\\"call()\\");"\n}'
158 | """
159 | pass
160 |
161 | def basic_test():
162 | """
163 | No data loss:
164 |
165 | >>> data = '{ array = { 65, 23, 5 }, dict = { string = "value", array = { 3, 6, 4}, mixed = { 43, 54.3, false, string = "value", 9 } } }'
166 | >>> d = lua.decode(data)
167 | >>> differ(d, lua.decode(lua.encode(d)))
168 | """
169 | pass
170 |
171 |
172 | def unicode_test():
173 | ur"""
174 | >>> assert lua.encode(u'Привет') == '"\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82"'
175 | >>> assert lua.encode({'s': u'Привет'}) == '{\n\ts = "Привет"\n}'
176 | """
177 | pass
178 |
179 |
180 | if __name__ == '__main__':
181 | import doctest
182 | doctest.testmod()
183 |
--------------------------------------------------------------------------------
/writer.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | import json
7 | from xml.dom.minidom import Document
8 |
9 | try:
10 | basestring
11 | except NameError:
12 | basestring = str
13 |
14 | try:
15 | long
16 | except NameError:
17 | long = int
18 |
19 | # python3中没有unicode了
20 | try:
21 | unicode
22 | except NameError:
23 | unicode = str
24 |
25 | # 加上不确定的层级缩进,60比较合适
26 | BASE_LENGTH = 60
27 | BASE_INDENT = " "
28 | INDENT_LIST = {}
29 |
30 | class Writer(object):
31 | def __init__(self,doc_name,sheet_name, base_name, keys_list, comment_text):
32 | # 文件名包含中文则需要转unicode
33 | #self.doc_name = unicode(doc_name, "utf-8")
34 | self.doc_name = doc_name
35 | self.sheet_name = sheet_name
36 | self.base_name = base_name
37 | self.keys_list = keys_list
38 | self.comment_text = comment_text
39 |
40 | # 文件后缀
41 | def suffix(self):
42 | pass
43 | # 文件内容
44 | def context(self,ctx):
45 | pass
46 | # 注释开始
47 | def comment_start(self):
48 | pass
49 | # 注释结束
50 | def comment_end(self):
51 | pass
52 | # 文件注释(千万不要加时间,影响svn)
53 | def comment(self):
54 | comment = []
55 | return "".join( comment )
56 |
57 |
--------------------------------------------------------------------------------
/writer_elixir.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | from writer import *
7 |
8 | try:
9 | basestring
10 | except NameError:
11 | basestring = str
12 |
13 | try:
14 | long
15 | except NameError:
16 | long = int
17 |
18 | # python3中没有unicode了
19 | try:
20 | unicode
21 | except NameError:
22 | unicode = str
23 |
24 | # 加上不确定的层级缩进,60比较合适
25 | BASE_LENGTH = 60
26 | BASE_INDENT = " "
27 | INDENT_LIST = {}
28 |
29 | class ElixirWriter(Writer):
30 | # 文件后缀
31 | def suffix(self):
32 | return ".ex"
33 |
34 | def comment(self):
35 | comment = [
36 | '## Automatic generation from -->>'
37 | '\n## excel file name: ' + self.doc_name +
38 | '\n## excel sheet name: ' + self.sheet_name,
39 | '\ndefmodule ' + self.base_name.title() + ' do\n\n'
40 | ]
41 |
42 | return "\n".join( comment )
43 |
44 | # 获取缩进字符串
45 | def indent_ctx( self,indent ):
46 | if indent <= 0: return ""
47 |
48 | if indent not in INDENT_LIST:
49 | INDENT_LIST[indent] = ""
50 | else:
51 | ctx = BASE_INDENT*indent
52 | INDENT_LIST[indent] = ctx
53 |
54 | return INDENT_LIST[indent]
55 |
56 | def dict_to_text(self, value, indent) :
57 | dict_text_list = []
58 | for k in ( value ) :
59 | k_indent,lk = self.to_target_lang( k,indent )
60 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
61 |
62 | comment = self.comment_text[k]
63 |
64 | val_type = type( lk )
65 | if str == val_type :
66 | if lk.replace(".", "").isdigit() :
67 | lk.replace("\"", "")
68 | else :
69 | lk = ':' + lk.replace("\"", "")
70 |
71 | key = "".join( [" def get(",lk,") do\n"] )
72 |
73 | val = "".join( [" ## ", comment, "\n", key, " ", lv, "\n end\n\n"] )
74 |
75 | dict_text_list.append( val )
76 |
77 | dict_str = "".join( dict_text_list )
78 | dict_str = dict_str + " def get(_) do\n :undefined\n end\n\nend"
79 | return False, dict_str
80 |
81 | def list_to_text(self, value, indent):
82 | list_text_list = []
83 | # 先定义 struct
84 | struct_text_list = []
85 | struct_len = len(self.comment_text)
86 | tem_count = 0
87 | for k in self.comment_text :
88 | tem_count += 1
89 | comment = self.comment_text[k]
90 | k_indent,lk = self.to_target_lang( k,indent )
91 | val_type = type( lk )
92 | if str == val_type :
93 | if lk.replace(".", "").isdigit() :
94 | lk.replace("\"", "")
95 | else :
96 | lk = ':' + lk.replace("\"", "")
97 |
98 | if tem_count != struct_len :
99 | lk = lk + ','
100 | else :
101 | lk = lk
102 |
103 | if None == comment :
104 | comment = ""
105 | val = "".join( [lk.ljust(20, " "), "\t## ", comment, "\n"] )
106 |
107 | struct_text_list.append( val )
108 |
109 | struct_str = " ".join( struct_text_list )
110 | end_str = " defstruct [\n " + struct_str + " ]\n\n"
111 |
112 | list_text_list.append(end_str)
113 |
114 | all_key_list = []
115 | # 生成 get() 函数
116 | for i, onedict in enumerate( value ) :
117 | # 生成对应的 key
118 | key_list = []
119 | for k in ( onedict ) :
120 | if None != self.keys_list.get(k, None) :
121 | is_indent,lv = self.to_target_lang( onedict[k],indent + 1 )
122 | key_list.append(lv)
123 | all_key_list.append(key_list)
124 |
125 | tem = ", ".join( key_list )
126 |
127 | key = "".join( [" def get(",tem,") do\n %", self.base_name.title(), "{\n "] )
128 |
129 | # 生成对应的value
130 | value_list = []
131 | onedict_len = len(onedict)
132 | tem_count = 0
133 | for k in ( onedict ) :
134 | tem_count += 1
135 | k_indent,lk = self.to_target_lang( k,indent )
136 | is_indent,lv = self.to_target_lang( onedict[k],indent + 1 )
137 |
138 | val_type = type( lk )
139 | if str == val_type :
140 | if lk.replace(".", "").isdigit() :
141 | lk.replace("\"", "")
142 | else :
143 | lk = ':' + lk.replace("\"", "")
144 |
145 | if tem_count != onedict_len :
146 | oneval = "".join( [lk, " => ", lv , ",\n"] )
147 | value_list.append( oneval )
148 | else :
149 | oneval = "".join( [lk, " => ", lv , "\n"] )
150 | value_list.append( oneval )
151 |
152 | value_list_str = " ".join(value_list)
153 | end_str = "".join( [key, value_list_str, " }\n end\n\n"] )
154 |
155 | list_text_list.append( end_str )
156 |
157 | underline_list = []
158 | for i in self.keys_list :
159 | underline_list.append('_')
160 |
161 | end_str = ", ".join(underline_list)
162 | no_match_str = " def get(" + end_str + ") do\n :undefined\n end\n\n"
163 |
164 | list_text_list.append(no_match_str)
165 |
166 | # 生成 get_all() 函数
167 | get_all_fun = []
168 | allkey_len = len(all_key_list)
169 | tem_count = 0
170 | for i, ival in enumerate(all_key_list) :
171 | tem_count += 1
172 | if tem_count != allkey_len :
173 | oneval = '{' + ", ".join(ival) + '},\n'
174 | get_all_fun.append(oneval)
175 | else :
176 | oneval = '{' + ", ".join(ival) + '}\n'
177 | get_all_fun.append(oneval)
178 |
179 | value_list_str = " ".join(get_all_fun)
180 | start_str = ' def get_all() do\n [\n '
181 | end_str = "".join( [start_str, value_list_str, " ]\n end\n\n"] )
182 |
183 | list_text_list.append( end_str )
184 |
185 | # 生成 get_list() 函数
186 | get_list_fun = []
187 | keys_len = len(self.keys_list)
188 | for key in self.keys_list :
189 | keyindex = self.keys_list[key]
190 | if keyindex == 1 :
191 | list_text_list.append( ' def get_list() do\n get_all()\n end\n\n')
192 | elif keyindex <= keys_len :
193 | get_tem_dict = {}
194 | underline_list = []
195 | for i, ival in enumerate(all_key_list) :
196 | key_tem_list = []
197 | j = 0
198 | underline_list = []
199 | while j < keyindex - 1 :
200 | key_tem_list.append(ival[j])
201 | underline_list.append('_')
202 | j += 1
203 |
204 | keystr = '(' + ", ".join(key_tem_list) + ')'
205 | if None != get_tem_dict.get(keystr, None) :
206 | oldlist = get_tem_dict[keystr]
207 | oldlist.append(ival)
208 | get_tem_dict[keystr] = oldlist
209 | else :
210 | get_tem_dict[keystr] = [ival]
211 |
212 | for onekey in get_tem_dict :
213 | value_tem_list = []
214 | valuelist = get_tem_dict[onekey]
215 |
216 | value_len = len(valuelist)
217 | tem_count = 0
218 | for l, lval in enumerate(valuelist) :
219 | tem_count += 1
220 | if tem_count != value_len :
221 | oneval = '{' + ", ".join(lval) + '},\n'
222 | value_tem_list.append(oneval)
223 | else :
224 | oneval = '{' + ", ".join(lval) + '}\n'
225 | value_tem_list.append(oneval)
226 | start_str = ' def get_list' + onekey + ' do\n [\n '
227 | end_str = "".join( [start_str, " ".join(value_tem_list), " ]\n end\n\n"] )
228 | get_list_fun.append(end_str)
229 | no_match_str = "".join(' def get_list(' + ", ".join(underline_list) + ') do\n []\n end\n\n')
230 | get_list_fun.append(no_match_str)
231 |
232 |
233 | value_list_str = "".join(get_list_fun) + 'end'
234 | list_text_list.append( value_list_str )
235 | dict_str = "".join( list_text_list )
236 |
237 | return False, dict_str
238 |
239 | # 转换为文本数据 之前解析出来的excel数据存放方式存在LIST(array格式)和DICT(object格式)两种类型
240 | def to_text(self,value,indent):
241 | val_type = type( value )
242 | if dict == val_type :
243 | return self.dict_to_text(value, indent)
244 | else :
245 | return self.list_to_text(value, indent)
246 |
247 | # python的dict转换为elixir的map类型
248 | def dict_to_elixir(self,value,indent):
249 | dict_ctx_list = []
250 |
251 | for k in ( value ) :
252 | k_indent,lk = self.to_target_lang( k,indent )
253 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
254 |
255 | val_type = type( lk )
256 | if str == val_type :
257 | if lk.replace(".", "").isdigit() :
258 | lk.replace("\"", "")
259 | else :
260 | lk = ':' + lk.replace("\"", "")
261 |
262 | key = "".join( [lk," => "] )
263 | val = "".join( [key, lv] )
264 | dict_ctx_list.append(val)
265 |
266 | dict_str = ", ".join( dict_ctx_list )
267 | return False,"".join( ["%{",dict_str,"}"] )
268 |
269 | # python的list转换为elixir的list类型
270 | def list_to_elixir(self,value,indent):
271 | list_ctx_list = []
272 | for v in value :
273 | is_indent,lv = self.to_target_lang( v,indent + 1 )
274 | list_ctx_list.append( lv )
275 |
276 |
277 | list_str = ", ".join( list_ctx_list )
278 | return False,"".join( ["[",list_str,"]"] )
279 |
280 | # python的tuple转换为elixir的tuple类型
281 | def tuple_to_elixir(self,value,indent):
282 | tuple_ctx_list = []
283 |
284 | for v in value :
285 | is_indent,lv = self.to_target_lang( v,indent + 1 )
286 | tuple_ctx_list.append( lv )
287 |
288 | # 返回 {a,b,c}这种不换行的格式
289 | list_str = ", ".join( tuple_ctx_list )
290 | return False,"".join( ["{",list_str,"}"] )
291 |
292 |
293 | # 变量转换到目标语言字符串
294 | def to_target_lang(self,value,indent):
295 | val_type = type( value )
296 | if int == val_type :
297 | return False,str( value )
298 | elif long == val_type :
299 | return False,str( value )
300 | elif float == val_type :
301 | # 1001.0 -->> 001 去除多余小数点
302 | if int( value ) == value :
303 | return False,str( int(value) )
304 | return False,str( value )
305 | elif str == val_type or unicode == val_type:
306 | return False, "".join(["\"",value,"\""])
307 | elif tuple == val_type :
308 | return self.tuple_to_elixir(value,indent)
309 | elif dict == val_type :
310 | return self.dict_to_elixir(value,indent)
311 | elif list == val_type :
312 | return self.list_to_elixir(value,indent)
313 | else :
314 | raise Exception( "invalid type",val_type )
315 |
316 | #文件内容
317 | def context(self,ctx):
318 | is_indent,str_ctx = self.to_text( ctx,0 )
319 | return "".join( [self.comment(),"",str_ctx] )
320 |
--------------------------------------------------------------------------------
/writer_erlang_erl.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | from writer import *
7 |
8 | try:
9 | basestring
10 | except NameError:
11 | basestring = str
12 |
13 | try:
14 | long
15 | except NameError:
16 | long = int
17 |
18 | # python3中没有unicode了
19 | try:
20 | unicode
21 | except NameError:
22 | unicode = str
23 |
24 | # 加上不确定的层级缩进,60比较合适
25 | BASE_LENGTH = 60
26 | BASE_INDENT = " "
27 | INDENT_LIST = {}
28 |
29 | class ErlangerlWriter(Writer):
30 | # 文件后缀
31 | def suffix(self):
32 | return ".erl"
33 |
34 | def comment(self):
35 | comment = [
36 | '%% Automatic generation from -->>'
37 | '\n%% excel file name : ' + self.doc_name +
38 | '\n%% excel sheet name : ' + self.sheet_name,
39 | '\n-module(' + self.base_name + ').',
40 | '\n'
41 | ]
42 |
43 | return "\n".join( comment )
44 |
45 | # 获取缩进字符串
46 | def indent_ctx( self,indent ):
47 | if indent <= 0: return ""
48 |
49 | if indent not in INDENT_LIST:
50 | INDENT_LIST[indent] = ""
51 | else:
52 | ctx = BASE_INDENT*indent
53 | INDENT_LIST[indent] = ctx
54 |
55 | return INDENT_LIST[indent]
56 |
57 | def dict_to_text(self, value, indent) :
58 | dict_text_list = []
59 | dict_text_list.append("-compile(export_all).\n\n")
60 | for k in ( value ) :
61 | k_indent,lk = self.to_target_lang( k,indent )
62 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
63 |
64 | comment = self.comment_text[k]
65 |
66 | val_type = type( lk )
67 | if str == val_type :
68 | lk = lk.replace("\"", "\'")
69 |
70 | key = "".join( ["get(",lk,") ->\n"] )
71 |
72 | val = "".join( ["%% ", comment, "\n", key, " ", lv, ";\n\n"] )
73 |
74 | dict_text_list.append( val )
75 |
76 | dict_str = "".join( dict_text_list )
77 | dict_str = dict_str + "get(_) ->\n undefined."
78 | return False, dict_str
79 |
80 | def list_to_text(self, value, indent):
81 | list_text_list = []
82 | val = "-include(\"" + self.base_name + ".hrl\").\n" + "-compile(export_all).\n\n"
83 | list_text_list.append(val)
84 | all_key_list = []
85 | # 生成 get() 函数
86 | for i, onedict in enumerate( value ) :
87 | # 生成对应的 key
88 | key_list = []
89 | for k in ( onedict ) :
90 | if None != self.keys_list.get(k, None) :
91 | is_indent,lv = self.to_target_lang( onedict[k],indent + 1 )
92 | key_list.append(lv)
93 | all_key_list.append(key_list)
94 |
95 | tem = ", ".join( key_list )
96 |
97 | key = "".join( ["get(",tem,") ->\n #", self.base_name, "{\n "] )
98 |
99 | # 生成对应的value
100 | value_list = []
101 | for k in ( onedict ) :
102 | k_indent,lk = self.to_target_lang( k,indent )
103 | is_indent,lv = self.to_target_lang( onedict[k],indent + 1 )
104 |
105 | val_type = type( lk )
106 | if str == val_type :
107 | lk = lk.replace("\"", "\'")
108 |
109 | oneval = "".join( [lk, " = ", lv , "\n"] )
110 |
111 | value_list.append( oneval )
112 |
113 | value_list_str = " ,".join(value_list)
114 | end_str = "".join( [key, value_list_str, " };\n\n"] )
115 |
116 | list_text_list.append( end_str )
117 |
118 | underline_list = []
119 | for i in self.keys_list :
120 | underline_list.append('_')
121 |
122 | end_str = ", ".join(underline_list)
123 | no_match_str = "get(" + end_str + ") ->\n undefined.\n\n"
124 |
125 | list_text_list.append(no_match_str)
126 |
127 | # 生成 get_all() 函数
128 | get_all_fun = []
129 | for i, ival in enumerate(all_key_list) :
130 | oneval = '{' + ", ".join(ival) + '}\n'
131 | get_all_fun.append(oneval)
132 | value_list_str = " ,".join(get_all_fun)
133 | start_str = 'get_all() ->\n [\n '
134 | end_str = "".join( [start_str, value_list_str, " ].\n\n"] )
135 |
136 | list_text_list.append( end_str )
137 |
138 | # 生成 get_list() 函数
139 | get_list_fun = []
140 | keys_len = len(self.keys_list)
141 | for key in self.keys_list :
142 | keyindex = self.keys_list[key]
143 | if keyindex == 1 :
144 | list_text_list.append( 'get_list() ->\n get_all().\n\n')
145 | elif keyindex <= keys_len :
146 | get_tem_dict = {}
147 | underline_list = []
148 | for i, ival in enumerate(all_key_list) :
149 | key_tem_list = []
150 | j = 0
151 | underline_list = []
152 | while j < keyindex - 1 :
153 | key_tem_list.append(ival[j])
154 | underline_list.append('_')
155 | j += 1
156 |
157 | keystr = '(' + ", ".join(key_tem_list) + ')'
158 | if None != get_tem_dict.get(keystr, None) :
159 | oldlist = get_tem_dict[keystr]
160 | oldlist.append(ival)
161 | get_tem_dict[keystr] = oldlist
162 | else :
163 | get_tem_dict[keystr] = [ival]
164 |
165 | for onekey in get_tem_dict :
166 | value_tem_list = []
167 | valuelist = get_tem_dict[onekey]
168 | for l, lval in enumerate(valuelist) :
169 | oneval = '{' + ", ".join(lval) + '}\n'
170 | value_tem_list.append(oneval)
171 | start = 'get_list' + onekey + ' ->\n [\n '
172 | val = "".join( [start, " ,".join(value_tem_list), " ];\n\n"] )
173 | get_list_fun.append(val)
174 | no_match_str = "".join('get_list(' + ", ".join(underline_list) + ') ->\n [].\n\n')
175 | get_list_fun.append(no_match_str)
176 |
177 |
178 | value_list = "".join(get_list_fun)
179 | list_text_list.append( value_list )
180 | dict_str = "".join( list_text_list )
181 |
182 | return False, dict_str
183 |
184 | # 转换为文本数据 之前解析出来的excel数据存放方式存在LIST(array格式)和DICT(object格式)两种类型
185 | def to_text(self,value,indent):
186 | val_type = type( value )
187 | if dict == val_type :
188 | return self.dict_to_text(value, indent)
189 | else :
190 | return self.list_to_text(value, indent)
191 |
192 | # python的dict转换为erlang的map类型
193 | def dict_to_erlang(self,value,indent):
194 | dict_ctx_list = []
195 |
196 | for k in ( value ) :
197 | k_indent,lk = self.to_target_lang( k,indent )
198 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
199 |
200 | val_type = type( lk )
201 | if str == val_type :
202 | lk = lk.replace("\"", "\'")
203 | key = "".join( [lk," => "] )
204 | val = "".join( [key, lv] )
205 | dict_ctx_list.append(val)
206 |
207 | dict_str = ", ".join( dict_ctx_list )
208 | return False,"".join( ["#{",dict_str,"}"] )
209 |
210 | # python的list转换为erlang的list类型
211 | def list_to_erlang(self,value,indent):
212 | list_ctx_list = []
213 | for v in value :
214 | is_indent,lv = self.to_target_lang( v,indent + 1 )
215 | list_ctx_list.append( lv )
216 |
217 | list_str = ", ".join( list_ctx_list )
218 | return False,"".join( ["[",list_str,"]"] )
219 |
220 | # python的tuple转换为erlang的tuple类型
221 | def tuple_to_erlang(self,value,indent):
222 | tuple_ctx_list = []
223 |
224 | for v in value :
225 | is_indent,lv = self.to_target_lang( v,indent + 1 )
226 | tuple_ctx_list.append( lv )
227 |
228 | # 返回 {a,b,c}这种不换行的格式
229 | list_str = ", ".join( tuple_ctx_list )
230 | return False,"".join( ["{",list_str,"}"] )
231 |
232 |
233 | # 变量转换到目标语言的字符串
234 | def to_target_lang(self,value,indent):
235 | val_type = type( value )
236 | if int == val_type :
237 | return False,str( value )
238 | elif long == val_type :
239 | return False,str( value )
240 | elif float == val_type :
241 | # 1001.0 -->> 001 去除多余小数点
242 | if int( value ) == value :
243 | return False,str( int(value) )
244 | return False,str( value )
245 | elif str == val_type or unicode == val_type:
246 | return False, "".join(["\"",value,"\""])
247 | elif tuple == val_type :
248 | return self.tuple_to_erlang(value,indent)
249 | elif dict == val_type :
250 | return self.dict_to_erlang(value,indent)
251 | elif list == val_type :
252 | return self.list_to_erlang(value,indent)
253 | else :
254 | raise Exception( "invalid type",val_type )
255 |
256 | #文件内容
257 | def context(self,ctx):
258 | is_indent,str_ctx = self.to_text( ctx,0 )
259 | return "".join( [self.comment(),"",str_ctx] )
260 |
--------------------------------------------------------------------------------
/writer_erlang_hrl.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | from writer import *
7 |
8 | try:
9 | basestring
10 | except NameError:
11 | basestring = str
12 |
13 | try:
14 | long
15 | except NameError:
16 | long = int
17 |
18 | # python3中没有unicode了
19 | try:
20 | unicode
21 | except NameError:
22 | unicode = str
23 |
24 | # 加上不确定的层级缩进,60比较合适
25 | BASE_LENGTH = 60
26 | BASE_INDENT = " "
27 | INDENT_LIST = {}
28 |
29 | class ErlanghrlWriter(Writer):
30 | # 文件后缀
31 | def suffix(self):
32 | return ".hrl"
33 |
34 | def comment(self):
35 | comment = [
36 | '%% Automatic generation from -->>'
37 | '\n%% excel file name : ' + self.doc_name +
38 | '\n%% excel sheet name : ' + self.sheet_name,
39 | '\n-record(' + self.base_name + ', {\n '
40 | ]
41 |
42 | return "\n".join( comment )
43 |
44 | # 获取缩进字符串
45 | def indent_ctx( self,indent ) :
46 | if indent <= 0: return ""
47 |
48 | if indent not in INDENT_LIST :
49 | INDENT_LIST[indent] = ""
50 | else :
51 | ctx = BASE_INDENT*indent
52 | INDENT_LIST[indent] = ctx
53 |
54 | return INDENT_LIST[indent]
55 |
56 | def list_to_text(self, value, indent):
57 | list_text_list = []
58 | for k in self.comment_text :
59 | comment = self.comment_text[k]
60 | k_indent,lk = self.to_target_lang( k,indent )
61 | val_type = type( lk )
62 | if str == val_type :
63 | lk = lk.replace("\"", "\'")
64 | if None == comment :
65 | comment = ""
66 | val = "".join( [lk.ljust(20, " "), "\t%% ", comment, "\n"] )
67 |
68 | list_text_list.append( val )
69 |
70 | list_str = " ,".join( list_text_list )
71 | list_str = list_str + " })."
72 | return False, list_str
73 |
74 | # 转换为文本数据 之前解析出来的excel数据存放方式存在LIST(array格式)和DICT(object格式)两种类型
75 | def to_text(self,value,indent):
76 | val_type = type( value )
77 | if list == val_type :
78 | return self.list_to_text(value, indent)
79 | else :
80 | return False, None
81 |
82 | # python的dict转换为erlang的map类型
83 | def dict_to_erlang(self,value,indent):
84 | dict_ctx_list = []
85 |
86 | for k in ( value ) :
87 | k_indent,lk = self.to_target_lang( k,indent )
88 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
89 |
90 | val_type = type( lk )
91 | if str == val_type :
92 | lk = lk.replace("\"", "\'")
93 | key = "".join( [lk," => "] )
94 | val = "".join( [key, lv] )
95 | dict_ctx_list.append(val)
96 |
97 | dict_str = ",".join( dict_ctx_list )
98 | return False,"".join( ["#{",dict_str,"}"] )
99 |
100 | # python的list转换为erlang的list类型
101 | def list_to_erlang(self,value,indent):
102 | list_ctx_list = []
103 | for v in value :
104 | is_indent,lv = self.to_target_lang( v,indent + 1 )
105 | list_ctx_list.append( lv )
106 |
107 |
108 | list_str = ",".join( list_ctx_list )
109 | return False,"".join( ["[",list_str,"]"] )
110 |
111 | # python的tuple转换为erlang的tuple类型
112 | def tuple_to_erlang(self,value,indent):
113 | tuple_ctx_list = []
114 |
115 | for v in value :
116 | is_indent,lv = self.to_target_lang( v,indent + 1 )
117 | tuple_ctx_list.append( lv )
118 |
119 | # 返回 {a,b,c}这种不换行的格式
120 | list_str = ",".join( tuple_ctx_list )
121 | return False,"".join( ["{",list_str,"}"] )
122 |
123 | # 变量转换到目标语言的字符串
124 | def to_target_lang(self,value,indent):
125 | val_type = type( value )
126 | if int == val_type :
127 | return False,str( value )
128 | elif long == val_type :
129 | return False,str( value )
130 | elif float == val_type :
131 | # 1001.0 -->> 001 去除多余小数点
132 | if int( value ) == value :
133 | return False,str( int(value) )
134 | return False,str( value )
135 | elif str == val_type or unicode == val_type:
136 | return False, "".join(["\"",value,"\""])
137 | elif tuple == val_type :
138 | return self.tuple_to_erlang(value,indent)
139 | elif dict == val_type :
140 | return self.dict_to_erlang(value,indent)
141 | elif list == val_type :
142 | return self.list_to_erlang(value,indent)
143 | else :
144 | raise Exception( "invalid type",val_type )
145 |
146 | #文件内容
147 | def context(self,ctx):
148 | is_indent,str_ctx = self.to_text( ctx,0 )
149 | if None != str_ctx :
150 | return "".join( [self.comment(),"",str_ctx] )
151 | else :
152 | return None
153 |
--------------------------------------------------------------------------------
/writer_json_array.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | import json
7 | from writer import *
8 |
9 | try:
10 | basestring
11 | except NameError:
12 | basestring = str
13 |
14 | try:
15 | long
16 | except NameError:
17 | long = int
18 |
19 | # python3中没有unicode了
20 | try:
21 | unicode
22 | except NameError:
23 | unicode = str
24 |
25 | # 加上不确定的层级缩进,60比较合适
26 | BASE_LENGTH = 60
27 | BASE_INDENT = " "
28 | INDENT_LIST = {}
29 |
30 | class JsonarrayWriter(Writer):
31 | # 文件后缀
32 | def suffix(self):
33 | return ".json"
34 |
35 | # 文件内容(字符串)
36 | def context(self,ctx):
37 | return json.dumps(ctx,ensure_ascii=False,\
38 | indent=4,sort_keys=True,separators=(',', ':') )
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/writer_json_object.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | from writer import *
7 |
8 | try:
9 | basestring
10 | except NameError:
11 | basestring = str
12 |
13 | try:
14 | long
15 | except NameError:
16 | long = int
17 |
18 | # python3中没有unicode了
19 | try:
20 | unicode
21 | except NameError:
22 | unicode = str
23 |
24 | # 加上不确定的层级缩进,60比较合适
25 | BASE_LENGTH = 60
26 | BASE_INDENT = " "
27 | INDENT_LIST = {}
28 |
29 | class JsonobjectWriter(Writer):
30 | # 文件后缀
31 | def suffix(self):
32 | return ".json"
33 |
34 | def comment(self):
35 | comment = []
36 | return "\n".join( comment )
37 |
38 | # 获取缩进字符串
39 | def indent_ctx( self,indent ):
40 | if indent <= 0: return ""
41 |
42 | if indent not in INDENT_LIST:
43 | ctx = BASE_INDENT*indent
44 | INDENT_LIST[indent] = ctx
45 |
46 | return INDENT_LIST[indent]
47 |
48 | def dict_to_text(self, value, indent) :
49 | dict_ctx_list = []
50 | is_indent,lv = self.to_target_lang( value, indent)
51 | dict_ctx_list.append(lv)
52 |
53 | dict_str = "".join( dict_ctx_list )
54 |
55 | return False,"".join( [dict_str] )
56 |
57 | def list_to_dit(self, cur_key_index, total_key_cnt, onedict, storge_dict) :
58 | for k in ( onedict ) :
59 | key_index = self.keys_list.get(k, None)
60 | if None != key_index and key_index == cur_key_index :
61 | lv = onedict[k]
62 | if cur_key_index == total_key_cnt :
63 | storge_dict[lv] = onedict
64 | else :
65 | if None != storge_dict.get(lv, None) :
66 | olddict = storge_dict[lv]
67 | new_storge_dict = olddict
68 | self.list_to_dit(cur_key_index + 1, total_key_cnt, onedict, new_storge_dict)
69 | else :
70 | storge_dict[lv] ={}
71 | new_storge_dict = storge_dict[lv]
72 | self.list_to_dit(cur_key_index + 1, total_key_cnt, onedict, new_storge_dict)
73 |
74 | def list_to_text(self, value, indent):
75 | list_text_list = []
76 |
77 | ## 处理多个key的情况
78 | key_value_list = {}
79 | key_cnt = len(self.keys_list)
80 | for i, onedict in enumerate( value ) :
81 | self.list_to_dit(1, key_cnt, onedict, key_value_list)
82 |
83 | is_indent,lv = self.to_target_lang( key_value_list, 0 )
84 | list_str = "".join( lv )
85 | list_text_list.append(list_str)
86 | return False,"".join( list_text_list )
87 |
88 | # 转换为文本数据 之前解析出来的excel数据存放方式存在LIST(array格式)和DICT(object格式)两种类型
89 | def to_text(self,value,indent):
90 | val_type = type( value )
91 | if dict == val_type :
92 | return self.dict_to_text(value, indent)
93 | else :
94 | return self.list_to_text(value, indent)
95 |
96 | # dict转换为json类型
97 | def dict_to_json(self,value,indent):
98 | dict_ctx_list = []
99 | #if indent % 2 != 0 :
100 | # indent += 1
101 | cur_indent = self.indent_ctx(indent)
102 | next_indent = self.indent_ctx(indent + 1)
103 |
104 | dict_len = len(value)
105 | tem_count = 0
106 | for k in ( value ) :
107 | lvalue = value[k]
108 | lvalue_type = type(lvalue)
109 | if tuple != lvalue_type and dict != lvalue_type and list != lvalue_type :
110 | tem_count += 1
111 | k_indent,lk = self.to_target_lang( k,indent )
112 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
113 |
114 | if lk.replace(".", "").isdigit() :
115 | key = "".join( ["\"",lk,"\"", ':'] )
116 | else :
117 | key = lk.replace("\'", "\"") + ':'
118 |
119 | if tem_count != dict_len :
120 | val = "".join( [ next_indent, key + lv + ',\n' ] )
121 | else :
122 | val = "".join( [ next_indent, key + lv ])
123 | dict_ctx_list.append( val )
124 |
125 | for k in ( value ) :
126 | lvalue = value[k]
127 | lvalue_type = type(lvalue)
128 | if tuple == lvalue_type or dict == lvalue_type or list == lvalue_type :
129 | tem_count += 1
130 | k_indent,lk = self.to_target_lang( k,indent )
131 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
132 | if lk.replace(".", "").isdigit() :
133 | key = "".join( ["\"",lk,"\"", ':'] )
134 | else :
135 | key = lk.replace("\'", "\"") + ':'
136 |
137 |
138 | if tem_count != dict_len :
139 | val = "".join( [ next_indent, key + lv + ',\n' ] )
140 | else :
141 | val = "".join( [ next_indent, key + lv ])
142 | dict_ctx_list.append( val )
143 |
144 | dict_str = "".join(dict_ctx_list)
145 | return True,"".join(["{\n" , dict_str, "\n",cur_indent,"}"] )
146 |
147 | # list转换为json类型
148 | def list_to_json(self,value,indent):
149 | list_ctx_list = []
150 | #if indent % 2 != 0 :
151 | # indent += 1
152 | cur_indent = self.indent_ctx(indent)
153 | next_indent = self.indent_ctx(indent + 1)
154 |
155 | index_cnt = 1
156 | list_len = len(value)
157 | tem_count = 0
158 | for v in value :
159 | tem_count += 1
160 | is_indent,lv = self.to_target_lang( v,indent + 1 )
161 | if tem_count != list_len :
162 | val = "".join( [ next_indent, lv + ',\n' ] )
163 | else :
164 | val = "".join( [ next_indent, lv])
165 | list_ctx_list.append( val )
166 | index_cnt += 1
167 |
168 | list_str = "".join(list_ctx_list)
169 | return True,"".join(["[\n" , list_str, "\n",cur_indent,"]"] )
170 |
171 | # 变量转换到目标语言的字符串
172 | def to_target_lang(self,value,indent):
173 | val_type = type( value )
174 | if int == val_type :
175 | return False,str( value )
176 | elif long == val_type :
177 | return False,str( value )
178 | elif float == val_type :
179 | # 1001.0 -->> 001 去除多余小数点
180 | if int( value ) == value :
181 | return False,str( int(value) )
182 | return False, str( value )
183 | elif str == val_type or unicode == val_type:
184 | # 字符串要用单引号,因为Lua里单引号级别比双引号高
185 | return False,"".join(["\"",value,"\""])
186 | elif tuple == val_type :
187 | value1 = list(value)
188 | return self.list_to_json(value1,indent)
189 | elif dict == val_type :
190 | return self.dict_to_json(value,indent)
191 | elif list == val_type :
192 | return self.list_to_json(value,indent)
193 | else :
194 | raise Exception( "invalid type",val_type )
195 |
196 | #文件内容
197 | def context(self,ctx):
198 | is_indent,str_ctx = self.to_text( ctx, 0 )
199 | return "".join( [self.comment(), str_ctx] )
200 |
201 |
202 |
--------------------------------------------------------------------------------
/writer_lua.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | from writer import *
7 |
8 | try:
9 | basestring
10 | except NameError:
11 | basestring = str
12 |
13 | try:
14 | long
15 | except NameError:
16 | long = int
17 |
18 | # python3中没有unicode了
19 | try:
20 | unicode
21 | except NameError:
22 | unicode = str
23 |
24 | # 加上不确定的层级缩进,60比较合适
25 | BASE_LENGTH = 60
26 | BASE_INDENT = " "
27 | INDENT_LIST = {}
28 |
29 | class LuaWriter(Writer):
30 | # 文件后缀
31 | def suffix(self):
32 | return ".lua"
33 |
34 | def comment(self):
35 | comment = [
36 | '-- Automatic generation from -->>'
37 | '\n-- excel file name: ' + self.doc_name +
38 | '\n-- excel sheet name: ' + self.sheet_name,
39 | '\nlocal ' + self.base_name + ' =\n'
40 | ]
41 | return "\n".join( comment )
42 |
43 | # 获取缩进字符串
44 | def indent_ctx( self,indent ):
45 | if indent <= 0: return ""
46 |
47 | if indent not in INDENT_LIST:
48 | ctx = BASE_INDENT*indent
49 | INDENT_LIST[indent] = ctx
50 |
51 | return INDENT_LIST[indent]
52 |
53 | def dict_to_text(self, value, indent) :
54 | dict_ctx_list = []
55 |
56 | cur_indent = self.indent_ctx(indent)
57 | next_indent = self.indent_ctx(indent + 1)
58 |
59 | tem_count = 0
60 | total_len = len(value)
61 | for k in ( value ) :
62 | tem_count += 1
63 | k_indent,lk = self.to_target_lang( k,indent )
64 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
65 |
66 | comment = self.comment_text[k]
67 | val = '-- ' + comment + '\n'
68 | dict_ctx_list.append(val)
69 |
70 | val_type = type( lk )
71 | if str == val_type :
72 | if lk.replace(".", "").isdigit() :
73 | key = "".join( ["[",lk,"]"] )
74 | else :
75 | key = lk.replace("\'", "")
76 | if tem_count != total_len :
77 | val = "".join( [cur_indent, key," =", lv, ",\n\n", cur_indent] )
78 | else :
79 | val = "".join( [cur_indent, key," = ",lv] )
80 |
81 | dict_ctx_list.append( val )
82 | dict_str = "".join( dict_ctx_list )
83 |
84 | return False,"".join( ["{\n", cur_indent, dict_str, "\n}"] )
85 |
86 | def list_to_dit(self, cur_key_index, total_key_cnt, onedict, storge_dict) :
87 | for k in ( onedict ) :
88 | key_index = self.keys_list.get(k, None)
89 | if None != key_index and key_index == cur_key_index :
90 | lv = onedict[k]
91 | if cur_key_index == total_key_cnt :
92 | storge_dict[lv] = onedict
93 | else :
94 | if None != storge_dict.get(lv, None) :
95 | olddict = storge_dict[lv]
96 | new_storge_dict = olddict
97 | self.list_to_dit(cur_key_index + 1, total_key_cnt, onedict, new_storge_dict)
98 | else :
99 | storge_dict[lv] ={}
100 | new_storge_dict = storge_dict[lv]
101 | self.list_to_dit(cur_key_index + 1, total_key_cnt, onedict, new_storge_dict)
102 |
103 | def list_to_text(self, value, indent):
104 | list_text_list = []
105 |
106 | # 先把各个字段的注释放在前面
107 | comment_text_list = []
108 | for k in self.comment_text :
109 | comment = self.comment_text[k]
110 | k_indent,lk = self.to_target_lang( k,indent )
111 |
112 | lk = lk.replace("\'", "")
113 |
114 | if None == comment :
115 | comment = ""
116 | val = "".join( [ '--: ', lk.ljust(20, " "), "\t## ", comment, "\n"] )
117 |
118 | comment_text_list.append( val )
119 |
120 | comment_str = "".join( comment_text_list )
121 |
122 | list_text_list.append(comment_str)
123 |
124 | ## 处理多个key的情况
125 | key_value_list = {}
126 | key_cnt = len(self.keys_list)
127 | for i, onedict in enumerate( value ) :
128 | self.list_to_dit(1, key_cnt, onedict, key_value_list)
129 |
130 | is_indent,lv = self.to_target_lang( key_value_list, 0 )
131 | list_str = "".join( lv )
132 | list_text_list.append(list_str)
133 | return False,"".join( list_text_list )
134 |
135 | # 转换为文本数据 之前解析出来的excel数据存放方式存在LIST(array格式)和DICT(object格式)两种类型
136 | def to_text(self,value,indent):
137 | val_type = type( value )
138 | if dict == val_type :
139 | return self.dict_to_text(value, indent)
140 | else :
141 | return self.list_to_text(value, indent)
142 |
143 | # dict转换为lua类型
144 | def dict_to_lua(self,value,indent):
145 | dict_ctx_list = []
146 | if indent % 2 != 0 :
147 | indent += 1
148 | cur_indent = self.indent_ctx(indent)
149 | next_indent = self.indent_ctx(indent + 1)
150 |
151 | dict_len = len(value)
152 | tem_count = 0
153 | for k in ( value ) :
154 | lvalue = value[k]
155 | lvalue_type = type(lvalue)
156 | if tuple != lvalue_type and dict != lvalue_type and list != lvalue_type :
157 | tem_count += 1
158 | k_indent,lk = self.to_target_lang( k,indent )
159 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
160 |
161 | if lk.replace(".", "").isdigit() :
162 | key = "".join( ["[",lk,"]"] )
163 | else :
164 | key = lk.replace("\'", "")
165 |
166 | if tem_count != dict_len :
167 | val = "".join( [ next_indent, key + " = " + lv + ',\n' ] )
168 | else :
169 | val = "".join( [ next_indent, key + " = " + lv ])
170 | dict_ctx_list.append( val )
171 |
172 | for k in ( value ) :
173 | lvalue = value[k]
174 | lvalue_type = type(lvalue)
175 | if tuple == lvalue_type or dict == lvalue_type or list == lvalue_type :
176 | tem_count += 1
177 | k_indent,lk = self.to_target_lang( k,indent )
178 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
179 |
180 | if lk.replace(".", "").isdigit() :
181 | key = "".join( ["[",lk,"]"] )
182 | else :
183 | key = lk.replace("\'", "")
184 |
185 | if tem_count != dict_len :
186 | val = "".join( [ next_indent, key + " = " + lv + ',\n' ] )
187 | else :
188 | val = "".join( [ next_indent, key + " = " + lv ])
189 | dict_ctx_list.append( val )
190 |
191 | dict_str = "".join(dict_ctx_list)
192 | return True,"".join(['\n', cur_indent,"{\n" , dict_str, "\n",cur_indent,"}"] )
193 |
194 | # list转换为lua类型
195 | def list_to_lua(self,value,indent):
196 | list_ctx_list = []
197 | if indent % 2 != 0 :
198 | indent += 1
199 | cur_indent = self.indent_ctx(indent)
200 | next_indent = self.indent_ctx(indent + 1)
201 |
202 | index_cnt = 1
203 | list_len = len(value)
204 | tem_count = 0
205 | for v in value :
206 | tem_count += 1
207 | is_indent,lv = self.to_target_lang( v,indent + 1 )
208 | if tem_count != list_len :
209 | val = "".join( [ next_indent, "[" + str(index_cnt) + "] = " + lv + ',\n' ] )
210 | else :
211 | val = "".join( [ next_indent, "[" + str(index_cnt) + "] = " + lv ])
212 | list_ctx_list.append( val )
213 | index_cnt += 1
214 |
215 | list_str = "".join(list_ctx_list)
216 | return True,"".join(['\n', cur_indent,"{\n" , list_str, "\n",cur_indent,"}"] )
217 |
218 | # tuple转换为lua类型
219 | def tuple_to_lua(self,value1,indent):
220 | value = list(value1)
221 | list_ctx_list = []
222 | if indent % 2 != 0 :
223 | indent += 1
224 | cur_indent = self.indent_ctx(indent)
225 | next_indent = self.indent_ctx(indent + 1)
226 |
227 | index_cnt = 1
228 | list_len = len(value)
229 | tem_count = 0
230 | for v in value :
231 | tem_count += 1
232 | is_indent,lv = self.to_target_lang( v,indent + 1 )
233 | if tem_count != list_len :
234 | val = "".join( [ next_indent, "[" + str(index_cnt) + "] = " + lv + ',\n' ] )
235 | else :
236 | val = "".join( [ next_indent, "[" + str(index_cnt) + "] = " + lv ])
237 | list_ctx_list.append( val )
238 | index_cnt += 1
239 |
240 | list_str = "".join(list_ctx_list)
241 | return True,"".join(['\n', cur_indent,"{\n" , list_str, "\n",cur_indent,"}"] )
242 |
243 |
244 | # 变量转换到目标语言的字符串
245 | def to_target_lang(self,value,indent):
246 | val_type = type( value )
247 | if int == val_type :
248 | return False,str( value )
249 | elif long == val_type :
250 | return False,str( value )
251 | elif float == val_type :
252 | # 1001.0 -->> 001 去除多余小数点
253 | if int( value ) == value :
254 | return False,str( int(value) )
255 | return False,str( value )
256 | elif str == val_type or unicode == val_type:
257 | # 字符串要用单引号,因为Lua里单引号级别比双引号高
258 | return False,"".join(["'",value,"'"])
259 | elif tuple == val_type :
260 | return self.tuple_to_lua(value,indent)
261 | elif dict == val_type :
262 | return self.dict_to_lua(value,indent)
263 | elif list == val_type :
264 | return self.list_to_lua(value,indent)
265 | else :
266 | raise Exception( "invalid type",val_type )
267 |
268 | #文件内容
269 | def context(self,ctx):
270 | is_indent,str_ctx = self.to_text( ctx,1 )
271 | return "".join( [self.comment(), str_ctx, "\nreturn ", self.base_name] )
272 |
273 |
274 |
--------------------------------------------------------------------------------
/writer_python.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | from writer import *
7 |
8 | try:
9 | basestring
10 | except NameError:
11 | basestring = str
12 |
13 | try:
14 | long
15 | except NameError:
16 | long = int
17 |
18 | # python3中没有unicode了
19 | try:
20 | unicode
21 | except NameError:
22 | unicode = str
23 |
24 | # 加上不确定的层级缩进,60比较合适
25 | BASE_LENGTH = 60
26 | BASE_INDENT = " "
27 | INDENT_LIST = {}
28 |
29 | class PythonWriter(Writer):
30 | # 文件后缀
31 | def suffix(self):
32 | return ".py"
33 |
34 | # 文件注释(千万不要加时间,影响svn)
35 | def comment(self):
36 | comment = [
37 | '## Automatic generation from -->>'
38 | '\n## excel file name: ' + self.doc_name +
39 | '\n## excel sheet name: ' + self.sheet_name,
40 | '\ndefmodule ' + self.base_name.title() + ' do\n\n'
41 | ]
42 |
43 | return "\n".join( comment )
44 |
45 | # 获取缩进字符串
46 | def indent_ctx( self,indent ):
47 | if indent <= 0: return ""
48 |
49 | if indent not in INDENT_LIST:
50 | INDENT_LIST[indent] = ""
51 | else:
52 | ctx = BASE_INDENT*indent
53 | INDENT_LIST[indent] = ctx
54 |
55 | return INDENT_LIST[indent]
56 |
57 | def dict_to_text(self, value, indent) :
58 |
59 |
60 | dict_text_list = []
61 | for k in ( value ) :
62 | k_indent,lk = self.to_target_lang( k,indent )
63 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
64 |
65 | comment = self.comment_text[k]
66 |
67 | val_type = type( lk )
68 | if str == val_type :
69 | lk = ':' + lk.replace("\"", "")
70 |
71 | key = "".join( [" def get(",lk,") do\n"] )
72 |
73 | val = "".join( [" ## ", comment, "\n", key, " ", lv, "\n end\n\n"] )
74 |
75 | dict_text_list.append( val )
76 |
77 | dict_str = "".join( dict_text_list )
78 | dict_str = dict_str + " def get(_) do\n :undefined\n end\n\nend"
79 | return False, dict_str
80 |
81 | def list_to_text(self, value, indent):
82 | list_text_list = []
83 | # 先定义 struct
84 | struct_text_list = []
85 | struct_len = len(self.comment_text)
86 | tem_count = 0
87 | for k in self.comment_text :
88 | tem_count += 1
89 | comment = self.comment_text[k]
90 | k_indent,lk = self.to_target_lang( k,indent )
91 | val_type = type( lk )
92 | if str == val_type :
93 | if tem_count != struct_len :
94 | lk = ':' + lk.replace("\"", "") + ','
95 | else :
96 | lk = ':' + lk.replace("\"", "")
97 |
98 | if None == comment :
99 | comment = ""
100 | val = "".join( [lk.ljust(20, " "), "\t## ", comment, "\n"] )
101 |
102 | struct_text_list.append( val )
103 |
104 | struct_str = " ".join( struct_text_list )
105 | end_str = " defstruct [\n " + struct_str + " ]\n\n"
106 |
107 | list_text_list.append(end_str)
108 |
109 | all_key_list = []
110 | # 生成 get() 函数
111 | for i, onedict in enumerate( value ) :
112 | # 生成对应的 key
113 | key_list = []
114 | for k in ( onedict ) :
115 | if None != self.keys_list.get(k, None) :
116 | is_indent,lv = self.to_target_lang( onedict[k],indent + 1 )
117 | key_list.append(lv)
118 | all_key_list.append(key_list)
119 |
120 | tem = ", ".join( key_list )
121 |
122 | key = "".join( [" def get(",tem,") do\n %", self.base_name.title(), "{\n "] )
123 |
124 | # 生成对应的value
125 | value_list = []
126 | onedict_len = len(onedict)
127 | tem_count = 0
128 | for k in ( onedict ) :
129 | tem_count += 1
130 | k_indent,lk = self.to_target_lang( k,indent )
131 | is_indent,lv = self.to_target_lang( onedict[k],indent + 1 )
132 |
133 | val_type = type( lk )
134 | if str == val_type :
135 | lk = ':' + lk.replace("\"", "")
136 |
137 | if tem_count != onedict_len :
138 | oneval = "".join( [lk, " => ", lv , ",\n"] )
139 | value_list.append( oneval )
140 | else :
141 | oneval = "".join( [lk, " => ", lv , "\n"] )
142 | value_list.append( oneval )
143 |
144 | value_list_str = " ".join(value_list)
145 | end_str = "".join( [key, value_list_str, " }\n end\n\n"] )
146 |
147 | list_text_list.append( end_str )
148 |
149 | underline_list = []
150 | for i in self.keys_list :
151 | underline_list.append('_')
152 |
153 | end_str = ", ".join(underline_list)
154 | no_match_str = " def get(" + end_str + ") do\n :undefined\n end\n\n"
155 |
156 | list_text_list.append(no_match_str)
157 |
158 | # 生成 get_all() 函数
159 | get_all_fun = []
160 | allkey_len = len(all_key_list)
161 | tem_count = 0
162 | for i, ival in enumerate(all_key_list) :
163 | tem_count += 1
164 | if tem_count != allkey_len :
165 | oneval = '{' + ", ".join(ival) + '},\n'
166 | get_all_fun.append(oneval)
167 | else :
168 | oneval = '{' + ", ".join(ival) + '}\n'
169 | get_all_fun.append(oneval)
170 |
171 | value_list_str = " ".join(get_all_fun)
172 | start_str = ' def get_all() do\n [\n '
173 | end_str = "".join( [start_str, value_list_str, " ]\n end\n\n"] )
174 |
175 | list_text_list.append( end_str )
176 |
177 | # 生成 get_list() 函数
178 | get_list_fun = []
179 | keys_len = len(self.keys_list)
180 | for key in self.keys_list :
181 | keyindex = self.keys_list[key]
182 | if keyindex == 1 :
183 | list_text_list.append( ' def get_list() do\n get_all()\n end\n\n')
184 | elif keyindex <= keys_len :
185 | get_tem_dict = {}
186 | underline_list = []
187 | for i, ival in enumerate(all_key_list) :
188 | key_tem_list = []
189 | j = 0
190 | underline_list = []
191 | while j < keyindex - 1 :
192 | key_tem_list.append(ival[j])
193 | underline_list.append('_')
194 | j += 1
195 |
196 | keystr = '(' + ", ".join(key_tem_list) + ')'
197 | if None != get_tem_dict.get(keystr, None) :
198 | oldlist = get_tem_dict[keystr]
199 | oldlist.append(ival)
200 | get_tem_dict[keystr] = oldlist
201 | else :
202 | get_tem_dict[keystr] = [ival]
203 |
204 | for onekey in get_tem_dict :
205 | value_tem_list = []
206 | valuelist = get_tem_dict[onekey]
207 |
208 | value_len = len(valuelist)
209 | tem_count = 0
210 | for l, lval in enumerate(valuelist) :
211 | tem_count += 1
212 | if tem_count != value_len :
213 | oneval = '{' + ", ".join(lval) + '},\n'
214 | value_tem_list.append(oneval)
215 | else :
216 | oneval = '{' + ", ".join(lval) + '}\n'
217 | value_tem_list.append(oneval)
218 | start_str = ' def get_list' + onekey + ' do\n [\n '
219 | end_str = "".join( [start_str, " ".join(value_tem_list), " ]\n end\n\n"] )
220 | get_list_fun.append(end_str)
221 | no_match_str = "".join(' def get_list(' + ", ".join(underline_list) + ') do\n []\n end\n\n')
222 | get_list_fun.append(no_match_str)
223 |
224 |
225 | value_list_str = "".join(get_list_fun) + 'end'
226 | list_text_list.append( value_list_str )
227 | dict_str = "".join( list_text_list )
228 |
229 | return False, dict_str
230 |
231 | # 转换为erlang 文本数据 之前解析出来的excel数据存放方式存在LIST(array格式)和DICT(object格式)两种类型
232 | def to_text(self,value,indent):
233 | val_type = type( value )
234 | if dict == val_type :
235 | return self.dict_to_text(value, indent)
236 | else :
237 | return self.list_to_text(value, indent)
238 |
239 | # python的dict转换为elixir的map类型
240 | def dict_to_elixir(self,value,indent):
241 | dict_ctx_list = []
242 |
243 | for k in ( value ) :
244 | k_indent,lk = self.to_target_lang( k,indent )
245 | is_indent,lv = self.to_target_lang( value[k],indent + 1 )
246 |
247 | val_type = type( lk )
248 | if str == val_type :
249 | lk = lk.replace("\"", "\'")
250 | key = "".join( [lk," => "] )
251 | val = "".join( [key, lv] )
252 | dict_ctx_list.append(val)
253 |
254 | dict_str = ", ".join( dict_ctx_list )
255 | return False,"".join( ["%{",dict_str,"}"] )
256 |
257 | # python的list转换为elixir的list类型
258 | def list_to_elixir(self,value,indent):
259 | list_ctx_list = []
260 | for v in value :
261 | is_indent,lv = self.to_target_lang( v,indent + 1 )
262 | list_ctx_list.append( lv )
263 |
264 |
265 | list_str = ", ".join( list_ctx_list )
266 | return False,"".join( ["[",list_str,"]"] )
267 |
268 | # python的tuple转换为elixir的tuple类型
269 | def tuple_to_elixir(self,value,indent):
270 | tuple_ctx_list = []
271 |
272 | for v in value :
273 | is_indent,lv = self.to_target_lang( v,indent + 1 )
274 | tuple_ctx_list.append( lv )
275 |
276 | # 返回 {a,b,c}这种不换行的格式
277 | list_str = ", ".join( tuple_ctx_list )
278 | return False,"".join( ["{",list_str,"}"] )
279 |
280 |
281 | # 变量转换到目标语言字符串
282 | def to_target_lang(self,value,indent):
283 | val_type = type( value )
284 | if int == val_type :
285 | return False,str( value )
286 | elif long == val_type :
287 | return False,str( value )
288 | elif float == val_type :
289 | # 1001.0 -->> 001 去除多余小数点
290 | if int( value ) == value :
291 | return False,str( int(value) )
292 | return False,str( value )
293 | elif str == val_type or unicode == val_type:
294 | return False, "".join(["\"",value,"\""])
295 | elif tuple == val_type :
296 | return self.tuple_to_elixir(value,indent)
297 | elif dict == val_type :
298 | return self.dict_to_elixir(value,indent)
299 | elif list == val_type :
300 | return self.list_to_elixir(value,indent)
301 | else :
302 | raise Exception( "invalid type",val_type )
303 |
304 | #文件内容
305 | def context(self,ctx):
306 | is_indent,str_ctx = self.to_text( ctx,0 )
307 | return "".join( [self.comment(),"",str_ctx] )
308 |
--------------------------------------------------------------------------------
/writer_xml.py:
--------------------------------------------------------------------------------
1 | #! python
2 | # -*- coding:utf-8 -*-
3 |
4 | import os
5 | import sys
6 | from xml.dom.minidom import Document
7 | from writer import *
8 |
9 | try:
10 | basestring
11 | except NameError:
12 | basestring = str
13 |
14 | try:
15 | long
16 | except NameError:
17 | long = int
18 |
19 | # python3中没有unicode了
20 | try:
21 | unicode
22 | except NameError:
23 | unicode = str
24 |
25 | # 加上不确定的层级缩进,60比较合适
26 | BASE_LENGTH = 60
27 | BASE_INDENT = " "
28 | INDENT_LIST = {}
29 |
30 | class JsonWriter(Writer):
31 | # 文件后缀
32 | def suffix(self):
33 | return ".json"
34 |
35 | # 文件内容(字符串)
36 | def context(self,ctx):
37 | return json.dumps(ctx,ensure_ascii=False,\
38 | indent=4,sort_keys=True,separators=(',', ':') )
39 |
40 |
41 | class XmlWriter(Writer):
42 | # 文件后缀
43 | def suffix(self):
44 | return ".xml"
45 | # 注释开始
46 | def comment_start(self):
47 | return ""
51 |
52 | #创建根元素
53 | def root_element(self):
54 | root = self.doc.createElement( self.base_name )
55 | return root
56 |
57 | # dict类型转换为xml
58 | def dict_to_xml(self,root,value):
59 | # 需要对key排序,不然每次导出的xml字段是乱的,对版本管理不友好
60 | for k in sorted( value ) :
61 | v = value[k]
62 | sub_root = self.doc.createElement( k )
63 |
64 | self.to_xml( sub_root,v )
65 | root.appendChild( sub_root )
66 |
67 | # list类型转换为xml
68 | def list_to_xml(self,root,value):
69 | for k,v in enumerate( value ) :
70 | # xml中并不支持array,用item来命名,外加一个index属性
71 | sub_root = self.doc.createElement( "item" )
72 | sub_root.setAttribute( "index",str( k ) )
73 |
74 | self.to_xml( sub_root,v )
75 | root.appendChild( sub_root )
76 | # tuple类型转换为xml
77 | def tuple_to_xml(self,root,value):
78 | valueList = list(value)
79 | for k,v in enumerate( valueList ) :
80 | # xml中并不支持array,用item来命名,外加一个index属性
81 | sub_root = self.doc.createElement( "item" )
82 | sub_root.setAttribute( "index",str( k ) )
83 |
84 | self.to_xml( sub_root,v )
85 | root.appendChild( sub_root )
86 |
87 | # 转换为xml节点
88 | def to_xml(self,root,value):
89 | sub_node = None
90 | val_type_str = None
91 | val_type = type( value )
92 | if int == val_type :
93 | # python3中没有Long类型,int64也用int表示
94 | val_type_str = "int64"
95 | sub_node = self.doc.createTextNode( str( value ) )
96 | elif long == val_type :
97 | val_type_str = "int64"
98 | sub_node = self.doc.createTextNode( str( value ) )
99 | elif float == val_type :
100 | val_type_str = "number"
101 | # 去除带小数时的小数点,100.0 ==>> 100
102 | if long( value ) == float( value ) :
103 | sub_node = self.doc.createTextNode( str( long( value ) ) )
104 | else:
105 | sub_node = self.doc.createTextNode( str( value ) )
106 | elif str == val_type or unicode == val_type :
107 | val_type_str = "string"
108 | sub_node = self.doc.createTextNode( value )
109 | elif tuple == val_type :
110 | self.tuple_to_xml( root,value )
111 | elif dict == val_type :
112 | self.dict_to_xml( root,value )
113 | elif list == val_type :
114 | self.list_to_xml( root,value )
115 | else :
116 | raise Exception( "invalid type",val_type )
117 |
118 | # 类型为dict或者list的,没有这个type属性
119 | if val_type_str : root.setAttribute( "type",val_type_str )
120 | if sub_node : root.appendChild( sub_node )
121 |
122 | # 文件内容
123 | def context(self,ctx):
124 | #创建DOM文档对象
125 | self.doc = Document()
126 | root = self.root_element()
127 |
128 | self.to_xml( root,ctx )
129 | self.doc.appendChild( root )
130 |
131 | return self.comment() + self.doc.toprettyxml( indent=" " )
132 |
133 |
134 |
--------------------------------------------------------------------------------