local progress = require 'progress' local table_insert = table.insert local table_sort = table.sort local math_type = math.type local table_concat = table.concat local string_char = string.char local type = type local os_clock = os.clock local w2l local metadata local remove_unuse_object local ttype local str local function get_len(tbl) local n = 0 for k in pairs(tbl) do if type(k) == 'number' and k > n then n = k end end return n end local function format_value(tp, value) if value == nil then return 'nil' end if tp == 0 then return ('%d'):format(value) elseif tp == 1 or tp == 2 then return ('%.4f'):format(value) elseif tp == 3 then value = w2l:editstring(value) if value:match '[\n\r]' then return ('[=[\r\n%s]=]'):format(value) else return ('%q'):format(value) end end return 'nil' end local function write(format, ...) str[#str+1] = format:format(...) end local function write_data(meta, data, lines) local len local key = meta.field if type(data) == 'table' then len = get_len(data) if len == 0 then return end end if key:match '[^%w%_]' then key = ('%q'):format(key) end if meta.displayname then lines[#lines+1] = {'-- %s', w2l:editstring(meta.displayname):gsub('^%s*(.-)%s*$', '%1')} end if not len then lines[#lines+1] = {'%s = %s', key, format_value(meta.type, data)} return end if len <= 1 then lines[#lines+1] = {'%s = %s', key, format_value(meta.type, data[1])} return end local values = {} local is_string for i = 1, len do if type(data[i]) == 'string' then is_string = true end if len >= 10 then values[i] = ('%d = %s'):format(i, format_value(meta.type, data[i])) else values[i] = format_value(meta.type, data[i]) end end if is_string or len >= 10 then lines[#lines+1] = {'%s = {\r\n%s,\r\n}', key, table_concat(values, ',\r\n')} return end lines[#lines+1] = {'%s = {%s}', key, table_concat(values, ', ')} end local function write_obj(id, obj) local metas = {} local datas = {} local haskey = {} if metadata[obj._code] then for key, meta in pairs(metadata[obj._code]) do local data = obj[key] if data then metas[#metas+1] = meta datas[meta] = data end haskey[key] = true end end if metadata[ttype] then for key, meta in pairs(metadata[ttype]) do if not haskey[key] then local data = obj[key] if data then metas[#metas+1] = meta datas[meta] = data end end end end table_sort(metas, function(meta1, meta2) return meta1.field < meta2.field end) local lines = {} for _, meta in ipairs(metas) do write_data(meta, datas[meta], lines) end if #lines == 0 and id == obj._parent then return end write('[%s]', id) if obj._parent then write('%s = %q', '_parent', obj._parent) end for i = 1, #lines do write(table.unpack(lines[i])) end write '' end local function write_table(slk) local list = {} for id in pairs(slk) do if not remove_unuse_object or obj._mark then list[#list+1] = id end end table_sort(list, function(a, b) local is_origin_a = a == slk[a]._parent local is_origin_b = b == slk[b]._parent if is_origin_a and not is_origin_b then return true end if not is_origin_a and is_origin_b then return false end return a < b end) local clock = os_clock() for i = 1, #list do local obj = slk[list[i]] write_obj(list[i], obj) if os_clock() - clock >= 0.1 then clock = os_clock() message(('正在转换%s: [%s] (%d/%d)'):format(ttype, obj._id, i, #list)) progress(i / #list) end end end return function (w2l_, type, slk) w2l = w2l_ metadata = w2l:metadata() remove_unuse_object = w2l.config.remove_unuse_object ttype = type str = {} write_table(slk, type) return table_concat(str, '\r\n') end