webmcp
annotate framework/bin/langtool.lua @ 2:72860d232f32
Version 1.0.2
Fixed bug with explicit garbage collection (requests > 256kB caused an error)
Views prefixed with an underscore can't be called externally
ui.paginate now displays the last page, if the selected page number is too high.
Fixed bug with explicit garbage collection (requests > 256kB caused an error)
Views prefixed with an underscore can't be called externally
ui.paginate now displays the last page, if the selected page number is too high.
author | jbe/bsw |
---|---|
date | Thu Dec 10 12:00:00 2009 +0100 (2009-12-10) |
parents | 9fdfb27f8e67 |
children | 5e32ef998acf |
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@0 | 97 translations[key] = false |
jbe/bsw@0 | 98 end |
jbe/bsw@0 | 99 end |
jbe/bsw@0 | 100 for key in string.gmatch(line, '_%(?"([^"\]+)"') do |
jbe/bsw@0 | 101 if |
jbe/bsw@0 | 102 key ~= "([^" and |
jbe/bsw@0 | 103 (not string.find(key, "^%s*%.%.[^%.]")) and |
jbe/bsw@0 | 104 (not string.find(key, "^%s*,[^,]")) |
jbe/bsw@0 | 105 then |
jbe/bsw@0 | 106 translations[key] = false |
jbe/bsw@0 | 107 end |
jbe/bsw@0 | 108 end |
jbe/bsw@0 | 109 end |
jbe/bsw@0 | 110 end |
jbe/bsw@0 | 111 traverse(path .. "/" .. filename) |
jbe/bsw@0 | 112 end |
jbe/bsw@0 | 113 end |
jbe/bsw@0 | 114 return true |
jbe/bsw@0 | 115 end |
jbe/bsw@0 | 116 for num, directory in ipairs(directories) do |
jbe/bsw@0 | 117 io.stderr:write('Parsing files in directory "', directory, '".\n') |
jbe/bsw@0 | 118 if not traverse(directory) then |
jbe/bsw@0 | 119 error('Could not read directory "' .. directory .. '".') |
jbe/bsw@0 | 120 end |
jbe/bsw@0 | 121 end |
jbe/bsw@0 | 122 |
jbe/bsw@0 | 123 local function update_translation(key, value) |
jbe/bsw@0 | 124 if #directories > 0 then |
jbe/bsw@0 | 125 if translations[key] ~= nil then translations[key] = value end |
jbe/bsw@0 | 126 else |
jbe/bsw@0 | 127 translations[key] = value |
jbe/bsw@0 | 128 end |
jbe/bsw@0 | 129 end |
jbe/bsw@0 | 130 |
jbe/bsw@0 | 131 if in_filetype == "po" then |
jbe/bsw@0 | 132 io.stderr:write('Reading translations from po file "', in_filename, '".\n') |
jbe/bsw@0 | 133 local next_line = io.lines(in_filename) |
jbe/bsw@0 | 134 for line in next_line do |
jbe/bsw@0 | 135 if not line then break end |
jbe/bsw@0 | 136 local key = string.match(line, '^msgid%s*"(.*)"%s*$') |
jbe/bsw@0 | 137 if key then |
jbe/bsw@0 | 138 local line = next_line() |
jbe/bsw@0 | 139 local value = string.match(line, '^msgstr%s*"(.*)"%s*$') |
jbe/bsw@0 | 140 if not value then |
jbe/bsw@0 | 141 error("Expected msgstr line in po file.") |
jbe/bsw@0 | 142 end |
jbe/bsw@0 | 143 if translations[key] then |
jbe/bsw@0 | 144 error("Duplicate key '" .. key .. "' in po file.") |
jbe/bsw@0 | 145 end |
jbe/bsw@0 | 146 if value == "" then value = false end |
jbe/bsw@0 | 147 update_translation(key, value) |
jbe/bsw@0 | 148 end |
jbe/bsw@0 | 149 end |
jbe/bsw@0 | 150 elseif in_filetype == "lua" then |
jbe/bsw@0 | 151 io.stderr:write('Reading translations from lua file "', in_filename, '".\n') |
jbe/bsw@0 | 152 local func = assert(loadfile(in_filename)) |
jbe/bsw@0 | 153 setfenv(func, {}) |
jbe/bsw@0 | 154 local updates = func() |
jbe/bsw@0 | 155 for key, value in pairs(updates) do |
jbe/bsw@0 | 156 update_translation(key, value) |
jbe/bsw@0 | 157 end |
jbe/bsw@0 | 158 end |
jbe/bsw@0 | 159 |
jbe/bsw@0 | 160 local translation_keys = {} |
jbe/bsw@0 | 161 for key in pairs(translations) do |
jbe/bsw@0 | 162 table.insert(translation_keys, key) |
jbe/bsw@0 | 163 end |
jbe/bsw@0 | 164 table.sort(translation_keys) |
jbe/bsw@0 | 165 |
jbe/bsw@0 | 166 if out_filetype == "po" then |
jbe/bsw@0 | 167 io.stderr:write('Writing translations to po file "', out_filename, '".\n') |
jbe/bsw@0 | 168 local file = assert(io.open(out_filename, "w")) |
jbe/bsw@0 | 169 for num, key in ipairs(translation_keys) do |
jbe/bsw@0 | 170 local value = translations[key] |
jbe/bsw@0 | 171 file:write('msgid "', key, '"\nmsgstr "', value or "", '"\n\n') |
jbe/bsw@0 | 172 end |
jbe/bsw@0 | 173 io.close(file) |
jbe/bsw@0 | 174 elseif out_filetype == "lua" then |
jbe/bsw@0 | 175 io.stderr:write('Writing translations to lua file "', out_filename, '".\n') |
jbe/bsw@0 | 176 local file = assert(io.open(out_filename, "w")) |
jbe/bsw@0 | 177 file:write("#!/usr/bin/env lua\n", "return {\n") |
jbe/bsw@0 | 178 for num, key in ipairs(translation_keys) do |
jbe/bsw@0 | 179 local value = translations[key] |
jbe/bsw@0 | 180 if value then |
jbe/bsw@0 | 181 file:write(string.format("[%q] = %q;\n", key, value)) |
jbe/bsw@0 | 182 else |
jbe/bsw@0 | 183 file:write(string.format("[%q] = false;\n", key)) |
jbe/bsw@0 | 184 end |
jbe/bsw@0 | 185 end |
jbe/bsw@0 | 186 file:write("}\n") |
jbe/bsw@0 | 187 io.close(file) |
jbe/bsw@0 | 188 end |