webmcp
annotate framework/bin/langtool.lua @ 33:fc98e5c6bfab
add missing debug_table
trace.debug_table prints a table into the log.
trace.debug_table prints a table into the log.
author | Daniel Poelzleithner <poelzi@poelzi.org> |
---|---|
date | Tue Oct 05 05:19:47 2010 +0200 (2010-10-05) |
parents | 5e32ef998acf |
children | 3d43a5cf17c1 |
rev | line source |
---|---|
jbe/bsw@0 | 1 #!/usr/bin/env lua |
jbe/bsw@0 | 2 |
jbe/bsw@0 | 3 if not pcall( |
jbe/bsw@0 | 4 function() |
jbe/bsw@0 | 5 require "extos" |
jbe/bsw@0 | 6 end |
jbe/bsw@0 | 7 ) then |
jbe/bsw@0 | 8 io.stderr:write('Could not load library "extos".\n') |
jbe/bsw@0 | 9 io.stderr:write('Hint: Set LUA_CPATH="/path_to_extos_library/?.so;;"\n') |
jbe/bsw@0 | 10 end |
jbe/bsw@0 | 11 |
jbe/bsw@0 | 12 |
jbe/bsw@0 | 13 local args = {...} |
jbe/bsw@0 | 14 |
jbe/bsw@0 | 15 if #args == 0 then |
jbe/bsw@0 | 16 print() |
jbe/bsw@0 | 17 print("This program creates translation files by traversing source directories.") |
jbe/bsw@0 | 18 print() |
jbe/bsw@0 | 19 print("Two formats are supported: lua files and po files.") |
jbe/bsw@0 | 20 print("At runtime a lua file is needed.") |
jbe/bsw@0 | 21 print("For use with po-file editors you may want to create po files first though.") |
jbe/bsw@0 | 22 print() |
jbe/bsw@0 | 23 print("Create or update a lua file: langtool.lua dir1/ dir2/ ... <basename>.lua") |
jbe/bsw@0 | 24 print("Create or update a po file: langtool.lua dir1/ dir2/ ... <basename>.po") |
jbe/bsw@0 | 25 print("Convert po file to lua file: langtool.lua <basename>.po <basename>.lua") |
jbe/bsw@0 | 26 print("Convert lua file to po file: langtool.lua <basename>.lua <basename>.po") |
jbe/bsw@0 | 27 print() |
jbe/bsw@0 | 28 end |
jbe/bsw@0 | 29 |
jbe/bsw@0 | 30 local in_filename, in_filetype, out_filename, out_filetype |
jbe/bsw@0 | 31 local directories = {} |
jbe/bsw@0 | 32 |
jbe/bsw@0 | 33 for arg_num, arg in ipairs(args) do |
jbe/bsw@0 | 34 local function arg_error(msg) |
jbe/bsw@0 | 35 error("Illegal command line argument #" .. arg_num .. ": " .. msg) |
jbe/bsw@0 | 36 end |
jbe/bsw@0 | 37 local po = string.match(arg, "^po:(.*)$") or string.match(arg, "^(.*%.po)$") |
jbe/bsw@0 | 38 local lua = string.match(arg, "^lua:(.*)$") or string.match(arg, "^(.*%.lua)$") |
jbe/bsw@0 | 39 local filetype |
jbe/bsw@0 | 40 if po and not lua then filetype = "po" |
jbe/bsw@0 | 41 filetype = "po" |
jbe/bsw@0 | 42 elseif lua and not po then filetype = "lua" |
jbe/bsw@0 | 43 filetype = "lua" |
jbe/bsw@0 | 44 else |
jbe/bsw@0 | 45 filetype = "path" |
jbe/bsw@0 | 46 end |
jbe/bsw@0 | 47 if filetype == "path" then |
jbe/bsw@0 | 48 table.insert(directories, arg) |
jbe/bsw@0 | 49 elseif filetype == "po" or filetype == "lua" then |
jbe/bsw@0 | 50 if not out_filename then |
jbe/bsw@0 | 51 out_filename = arg |
jbe/bsw@0 | 52 out_filetype = filetype |
jbe/bsw@0 | 53 elseif not in_filename then |
jbe/bsw@0 | 54 in_filename = out_filename |
jbe/bsw@0 | 55 in_filetype = out_filetype |
jbe/bsw@0 | 56 out_filename = arg |
jbe/bsw@0 | 57 out_filetype = filetype |
jbe/bsw@0 | 58 else |
jbe/bsw@0 | 59 arg_error("Only two language files (one input and one output file) can be specified.") |
jbe/bsw@0 | 60 end |
jbe/bsw@0 | 61 else |
jbe/bsw@0 | 62 -- should not happen, as default type is "path" |
jbe/bsw@0 | 63 arg_error("Type not recognized") |
jbe/bsw@0 | 64 end |
jbe/bsw@0 | 65 end |
jbe/bsw@0 | 66 |
jbe/bsw@0 | 67 if #directories > 0 and not os.listdir then |
jbe/bsw@0 | 68 io.stderr:write('Fatal: Cannot traverse directories without "extos" library -> Abort\n') |
jbe/bsw@0 | 69 os.exit(1) |
jbe/bsw@0 | 70 end |
jbe/bsw@0 | 71 |
jbe/bsw@0 | 72 if out_filename and not in_filename then |
jbe/bsw@0 | 73 local file = io.open(out_filename, "r") |
jbe/bsw@0 | 74 if file then |
jbe/bsw@0 | 75 in_filename = out_filename |
jbe/bsw@0 | 76 in_filetype = out_filetype |
jbe/bsw@0 | 77 file:close() |
jbe/bsw@0 | 78 end |
jbe/bsw@0 | 79 end |
jbe/bsw@0 | 80 |
jbe/bsw@0 | 81 local translations = { } |
jbe/bsw@0 | 82 |
jbe/bsw@0 | 83 local function traverse(path) |
jbe/bsw@0 | 84 local filenames = os.listdir(path) |
jbe/bsw@0 | 85 if not filenames then return false end |
jbe/bsw@0 | 86 for num, filename in ipairs(filenames) do |
jbe/bsw@0 | 87 if not string.find(filename, "^%.") then |
jbe/bsw@0 | 88 if string.find(filename, "%.lua$") then |
jbe/bsw@0 | 89 for line in io.lines(path .. "/" .. filename) do |
jbe/bsw@0 | 90 -- TODO: exact parsing of comments and escape characters |
jbe/bsw@0 | 91 for key in string.gmatch(line, "_%(?'([^'\]+)'") do |
jbe/bsw@0 | 92 if |
jbe/bsw@0 | 93 key ~= "([^" and |
jbe/bsw@0 | 94 (not string.find(key, "^%s*%.%.[^%.]")) and |
jbe/bsw@0 | 95 (not string.find(key, "^%s*,[^,]")) |
jbe/bsw@0 | 96 then |
jbe/bsw@4 | 97 local key = key:gsub("\\n", "\n") |
jbe/bsw@0 | 98 translations[key] = false |
jbe/bsw@0 | 99 end |
jbe/bsw@0 | 100 end |
jbe/bsw@0 | 101 for key in string.gmatch(line, '_%(?"([^"\]+)"') do |
jbe/bsw@0 | 102 if |
jbe/bsw@0 | 103 key ~= "([^" and |
jbe/bsw@0 | 104 (not string.find(key, "^%s*%.%.[^%.]")) and |
jbe/bsw@0 | 105 (not string.find(key, "^%s*,[^,]")) |
jbe/bsw@0 | 106 then |
jbe/bsw@4 | 107 local key = key:gsub("\\n", "\n") |
jbe/bsw@0 | 108 translations[key] = false |
jbe/bsw@0 | 109 end |
jbe/bsw@0 | 110 end |
jbe/bsw@0 | 111 end |
jbe/bsw@0 | 112 end |
jbe/bsw@0 | 113 traverse(path .. "/" .. filename) |
jbe/bsw@0 | 114 end |
jbe/bsw@0 | 115 end |
jbe/bsw@0 | 116 return true |
jbe/bsw@0 | 117 end |
jbe/bsw@0 | 118 for num, directory in ipairs(directories) do |
jbe/bsw@0 | 119 io.stderr:write('Parsing files in directory "', directory, '".\n') |
jbe/bsw@0 | 120 if not traverse(directory) then |
jbe/bsw@0 | 121 error('Could not read directory "' .. directory .. '".') |
jbe/bsw@0 | 122 end |
jbe/bsw@0 | 123 end |
jbe/bsw@0 | 124 |
jbe/bsw@0 | 125 local function update_translation(key, value) |
jbe/bsw@0 | 126 if #directories > 0 then |
jbe/bsw@0 | 127 if translations[key] ~= nil then translations[key] = value end |
jbe/bsw@0 | 128 else |
jbe/bsw@0 | 129 translations[key] = value |
jbe/bsw@0 | 130 end |
jbe/bsw@0 | 131 end |
jbe/bsw@0 | 132 |
jbe/bsw@0 | 133 if in_filetype == "po" then |
jbe/bsw@0 | 134 io.stderr:write('Reading translations from po file "', in_filename, '".\n') |
jbe/bsw@0 | 135 local next_line = io.lines(in_filename) |
jbe/bsw@0 | 136 for line in next_line do |
jbe/bsw@0 | 137 if not line then break end |
jbe/bsw@0 | 138 local key = string.match(line, '^msgid%s*"(.*)"%s*$') |
jbe/bsw@0 | 139 if key then |
jbe/bsw@0 | 140 local line = next_line() |
jbe/bsw@0 | 141 local value = string.match(line, '^msgstr%s*"(.*)"%s*$') |
jbe/bsw@0 | 142 if not value then |
jbe/bsw@0 | 143 error("Expected msgstr line in po file.") |
jbe/bsw@0 | 144 end |
jbe/bsw@0 | 145 if translations[key] then |
jbe/bsw@0 | 146 error("Duplicate key '" .. key .. "' in po file.") |
jbe/bsw@0 | 147 end |
jbe/bsw@0 | 148 if value == "" then value = false end |
jbe/bsw@0 | 149 update_translation(key, value) |
jbe/bsw@0 | 150 end |
jbe/bsw@0 | 151 end |
jbe/bsw@0 | 152 elseif in_filetype == "lua" then |
jbe/bsw@0 | 153 io.stderr:write('Reading translations from lua file "', in_filename, '".\n') |
jbe/bsw@0 | 154 local func = assert(loadfile(in_filename)) |
jbe/bsw@0 | 155 setfenv(func, {}) |
jbe/bsw@0 | 156 local updates = func() |
jbe/bsw@0 | 157 for key, value in pairs(updates) do |
jbe/bsw@0 | 158 update_translation(key, value) |
jbe/bsw@0 | 159 end |
jbe/bsw@0 | 160 end |
jbe/bsw@0 | 161 |
jbe/bsw@0 | 162 local translation_keys = {} |
jbe/bsw@0 | 163 for key in pairs(translations) do |
jbe/bsw@0 | 164 table.insert(translation_keys, key) |
jbe/bsw@0 | 165 end |
jbe/bsw@0 | 166 table.sort(translation_keys) |
jbe/bsw@0 | 167 |
jbe/bsw@0 | 168 if out_filetype == "po" then |
jbe/bsw@0 | 169 io.stderr:write('Writing translations to po file "', out_filename, '".\n') |
jbe/bsw@0 | 170 local file = assert(io.open(out_filename, "w")) |
jbe/bsw@0 | 171 for num, key in ipairs(translation_keys) do |
jbe/bsw@0 | 172 local value = translations[key] |
jbe/bsw@0 | 173 file:write('msgid "', key, '"\nmsgstr "', value or "", '"\n\n') |
jbe/bsw@0 | 174 end |
jbe/bsw@0 | 175 io.close(file) |
jbe/bsw@0 | 176 elseif out_filetype == "lua" then |
jbe/bsw@0 | 177 io.stderr:write('Writing translations to lua file "', out_filename, '".\n') |
jbe/bsw@0 | 178 local file = assert(io.open(out_filename, "w")) |
jbe/bsw@0 | 179 file:write("#!/usr/bin/env lua\n", "return {\n") |
jbe/bsw@0 | 180 for num, key in ipairs(translation_keys) do |
jbe/bsw@0 | 181 local value = translations[key] |
jbe/bsw@0 | 182 if value then |
jbe/bsw@4 | 183 file:write((string.format("[%q] = %q;\n", key, value):gsub("\\\n", "\\n"))) -- double () important to hide second result of gsub |
jbe/bsw@0 | 184 else |
jbe/bsw@4 | 185 file:write((string.format("[%q] = false;\n", key):gsub("\\\n", "\\n"))) -- double () important to hide second result of gsub |
jbe/bsw@0 | 186 end |
jbe/bsw@0 | 187 end |
jbe/bsw@0 | 188 file:write("}\n") |
jbe/bsw@0 | 189 io.close(file) |
jbe/bsw@0 | 190 end |