123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- require_relative 'common'
- options = get_options(__FILE__)
- config_path = options['config_path']
- ini_path = options['generate_ini_path']
- text_path = options['generate_text_path']
- code_path = options['generate_code_path']
- language = options['source_text_language']
- is_generate_field_info = options['generate_field_info']
- recreate_dir ini_path
- recreate_dir text_path
- recreate_dir code_path
- require 'csv'
- # 各类型定义
- TypeInfo = Struct.new(:data_type, :data_type_extra, :ref_info, :default_value, :struct_info)
- FieldInfo = Struct.new(:column_id, :identifier, :comment, :type_info)
- Table = Struct.new(:csv, :fields, :name2id, :id_field, :raw_name)
- Ini = Struct.new(:io, :tables)
- inis = {}
- # 读取配置表子目录,以形成配置数据目录
- Dir["#{config_path}/*"].each do |path|
- ini_name = File::basename(path)
- ini = (inis[ini_name] ||= Ini.new(File.open("#{ini_path}/#{ini_name}.ini", 'wb'), {}))
- next unless File::directory?(path)
- # 每个配置表子目录将成为一个 ini 文件
- # 内含全部子 .csv 表格的导入数据
- Dir["#{path}/*.csv"].each do |file|
- table_name = File::basename(file, '.csv')
- table = (ini.tables[convert_case(table_name)] = Table.new(csv = CSV.open(file), [], {}, nil, table_name))
- identifiers = csv.readline
- comments = csv.readline
- type_infos = csv.readline
- field_id = nil
- field_id_name = nil
- # 处理表头列
- identifiers.each_with_index do |identifier, index|
- next if identifier.nil? || identifier.empty?
- type_info = TypeInfo.new(nil, nil, nil, nil, nil)
- type_infos[index].gsub(/\s+/, '').scan(/[(:|,|@|=)][a-zA-Z_]+/).each do |info|
- type_info.data_type = info[1..info.size] if info.start_with?(':')
- type_info.data_type_extra = info[1..info.size] if info.start_with?(',')
- type_info.ref_info = convert_case(info[1..info.size]) if info.start_with?('@')
- type_info.default_value = info[1..info.size] if info.start_with?('=')
- type_info.struct_info = info[1..info.size] if info.start_with?('!')
- end
- field = FieldInfo.new(index, identifier, comments[index], type_info)
- # 处理特殊类型的字段
- case type_info.data_type
- when 'id'
- field_id = field
- next
- when 'id_name'
- field_id_name = field
- next
- end
- # 参与导入的条目
- table.fields << field
- end
- # 验证 Id 列
- table.id_field = field_id
- # 处理条目形成引用表
- while !csv.eof?
- line = csv.readline
- next if field_id_name.nil?
- id = line[field_id.column_id]
- next if id.nil? || id.empty?
- table.name2id[line[field_id_name.column_id]] = id.upcase
- end
- # 回滚 csv 状态至表头读取后
- csv.rewind
- 3.times { csv.readline }
- end
- end
- # 所有表格缓存
- tables = inis.values.collect{|ini| ini.tables}.inject(:merge)
- # 导入实际数据条目
- inis.each_pair do |ini_name, ini_data|
- register_table = {}
- enum_table = {}
- buffer = StringIO.new
- # 逐目录生成 ini
- ini_data.tables.each_pair do |table_name, table|
- register = (register_table[table_name] = [])
- texts = {}
- count = 0
- # 逐行扫描
- while !table.csv.eof?
- line = table.csv.readline
- id = line[table.id_field.column_id]
- next if id.nil? || id.empty?
- id = id.upcase
- buffer.puts "[#{id}]"
- table.fields.each do |field|
- value = line[field.column_id]
- next if value.nil? || value.empty?
- # 引用名替换处理
- if field.type_info.ref_info
- ref_table = tables[field.type_info.ref_info]
- value = value.split(',').collect do |ref_name|
- ref_name.strip!
- ref_table.name2id[ref_name] || ref_name.upcase
- end.join(',')
- # 数据类型处理
- else
- case field.type_info.data_type
- # 文本内容
- when 'text'
- index = 0
- value = value.split(',').collect do |text|
- key = "#{id}"
- key = "#{key}:#{index}" if index > 0
- global_key = "C:#{table_name}:#{field.identifier}:#{key}"
- texts[global_key] = text
- index += 1
- key
- end.join(',')
- # 枚举内容
- when 'enum'
- case field.type_info.data_type_extra
- # 自动型枚举
- when 'auto'
- enum_key = "#{table_name}#{field.identifier}"
- value.split(',').each do |v|
- enums = (enum_table[enum_key] ||= {})
- enums[v] = enums.size
- end
- end
- end
- end
- buffer.puts "#{field.identifier}=#{value}"
- count += 1
- end
- buffer.puts
- register << id
- end
- # 导出语言表
- if !texts.empty?
- csf = CSV.open("#{text_path}/#{table.raw_name}.csv", 'wb')
- csf << ['', language]
- texts.keys.sort.each do |k|
- csf << [k, texts[k]]
- end
- end
- end
- # 导出 ini
- File.open("#{ini_path}/#{ini_name}.ini", 'wb') do |ini|
- # 导出注册表
- if !register_table.empty?
- ini.puts '[REGISTER]'
- register_table.each_pair do |table_name, register|
- ini.puts "#{table_name}=#{register.join(',')}"
- end
- ini.puts
- end
- # 导出枚举
- if !enum_table.empty?
- ini.puts '[ENUM]'
- enum_table.keys.sort.each do |enum_name|
- ini.puts "#{enum_name}=#{enum_table[enum_name].keys.join(',')}"
- end
- ini.puts
- end
- # 导出所有条目
- ini.puts buffer.string
- end
- end
|