webmcp
diff framework/bin/langtool.lua @ 0:9fdfb27f8e67
Version 1.0.0
author | jbe/bsw |
---|---|
date | Sun Oct 25 12:00:00 2009 +0100 (2009-10-25) |
parents | |
children | 5e32ef998acf |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/framework/bin/langtool.lua Sun Oct 25 12:00:00 2009 +0100 1.3 @@ -0,0 +1,188 @@ 1.4 +#!/usr/bin/env lua 1.5 + 1.6 +if not pcall( 1.7 + function() 1.8 + require "extos" 1.9 + end 1.10 +) then 1.11 + io.stderr:write('Could not load library "extos".\n') 1.12 + io.stderr:write('Hint: Set LUA_CPATH="/path_to_extos_library/?.so;;"\n') 1.13 +end 1.14 + 1.15 + 1.16 +local args = {...} 1.17 + 1.18 +if #args == 0 then 1.19 + print() 1.20 + print("This program creates translation files by traversing source directories.") 1.21 + print() 1.22 + print("Two formats are supported: lua files and po files.") 1.23 + print("At runtime a lua file is needed.") 1.24 + print("For use with po-file editors you may want to create po files first though.") 1.25 + print() 1.26 + print("Create or update a lua file: langtool.lua dir1/ dir2/ ... <basename>.lua") 1.27 + print("Create or update a po file: langtool.lua dir1/ dir2/ ... <basename>.po") 1.28 + print("Convert po file to lua file: langtool.lua <basename>.po <basename>.lua") 1.29 + print("Convert lua file to po file: langtool.lua <basename>.lua <basename>.po") 1.30 + print() 1.31 +end 1.32 + 1.33 +local in_filename, in_filetype, out_filename, out_filetype 1.34 +local directories = {} 1.35 + 1.36 +for arg_num, arg in ipairs(args) do 1.37 + local function arg_error(msg) 1.38 + error("Illegal command line argument #" .. arg_num .. ": " .. msg) 1.39 + end 1.40 + local po = string.match(arg, "^po:(.*)$") or string.match(arg, "^(.*%.po)$") 1.41 + local lua = string.match(arg, "^lua:(.*)$") or string.match(arg, "^(.*%.lua)$") 1.42 + local filetype 1.43 + if po and not lua then filetype = "po" 1.44 + filetype = "po" 1.45 + elseif lua and not po then filetype = "lua" 1.46 + filetype = "lua" 1.47 + else 1.48 + filetype = "path" 1.49 + end 1.50 + if filetype == "path" then 1.51 + table.insert(directories, arg) 1.52 + elseif filetype == "po" or filetype == "lua" then 1.53 + if not out_filename then 1.54 + out_filename = arg 1.55 + out_filetype = filetype 1.56 + elseif not in_filename then 1.57 + in_filename = out_filename 1.58 + in_filetype = out_filetype 1.59 + out_filename = arg 1.60 + out_filetype = filetype 1.61 + else 1.62 + arg_error("Only two language files (one input and one output file) can be specified.") 1.63 + end 1.64 + else 1.65 + -- should not happen, as default type is "path" 1.66 + arg_error("Type not recognized") 1.67 + end 1.68 +end 1.69 + 1.70 +if #directories > 0 and not os.listdir then 1.71 + io.stderr:write('Fatal: Cannot traverse directories without "extos" library -> Abort\n') 1.72 + os.exit(1) 1.73 +end 1.74 + 1.75 +if out_filename and not in_filename then 1.76 + local file = io.open(out_filename, "r") 1.77 + if file then 1.78 + in_filename = out_filename 1.79 + in_filetype = out_filetype 1.80 + file:close() 1.81 + end 1.82 +end 1.83 + 1.84 +local translations = { } 1.85 + 1.86 +local function traverse(path) 1.87 + local filenames = os.listdir(path) 1.88 + if not filenames then return false end 1.89 + for num, filename in ipairs(filenames) do 1.90 + if not string.find(filename, "^%.") then 1.91 + if string.find(filename, "%.lua$") then 1.92 + for line in io.lines(path .. "/" .. filename) do 1.93 + -- TODO: exact parsing of comments and escape characters 1.94 + for key in string.gmatch(line, "_%(?'([^'\]+)'") do 1.95 + if 1.96 + key ~= "([^" and 1.97 + (not string.find(key, "^%s*%.%.[^%.]")) and 1.98 + (not string.find(key, "^%s*,[^,]")) 1.99 + then 1.100 + translations[key] = false 1.101 + end 1.102 + end 1.103 + for key in string.gmatch(line, '_%(?"([^"\]+)"') do 1.104 + if 1.105 + key ~= "([^" and 1.106 + (not string.find(key, "^%s*%.%.[^%.]")) and 1.107 + (not string.find(key, "^%s*,[^,]")) 1.108 + then 1.109 + translations[key] = false 1.110 + end 1.111 + end 1.112 + end 1.113 + end 1.114 + traverse(path .. "/" .. filename) 1.115 + end 1.116 + end 1.117 + return true 1.118 +end 1.119 +for num, directory in ipairs(directories) do 1.120 + io.stderr:write('Parsing files in directory "', directory, '".\n') 1.121 + if not traverse(directory) then 1.122 + error('Could not read directory "' .. directory .. '".') 1.123 + end 1.124 +end 1.125 + 1.126 +local function update_translation(key, value) 1.127 + if #directories > 0 then 1.128 + if translations[key] ~= nil then translations[key] = value end 1.129 + else 1.130 + translations[key] = value 1.131 + end 1.132 +end 1.133 + 1.134 +if in_filetype == "po" then 1.135 + io.stderr:write('Reading translations from po file "', in_filename, '".\n') 1.136 + local next_line = io.lines(in_filename) 1.137 + for line in next_line do 1.138 + if not line then break end 1.139 + local key = string.match(line, '^msgid%s*"(.*)"%s*$') 1.140 + if key then 1.141 + local line = next_line() 1.142 + local value = string.match(line, '^msgstr%s*"(.*)"%s*$') 1.143 + if not value then 1.144 + error("Expected msgstr line in po file.") 1.145 + end 1.146 + if translations[key] then 1.147 + error("Duplicate key '" .. key .. "' in po file.") 1.148 + end 1.149 + if value == "" then value = false end 1.150 + update_translation(key, value) 1.151 + end 1.152 + end 1.153 +elseif in_filetype == "lua" then 1.154 + io.stderr:write('Reading translations from lua file "', in_filename, '".\n') 1.155 + local func = assert(loadfile(in_filename)) 1.156 + setfenv(func, {}) 1.157 + local updates = func() 1.158 + for key, value in pairs(updates) do 1.159 + update_translation(key, value) 1.160 + end 1.161 +end 1.162 + 1.163 +local translation_keys = {} 1.164 +for key in pairs(translations) do 1.165 + table.insert(translation_keys, key) 1.166 +end 1.167 +table.sort(translation_keys) 1.168 + 1.169 +if out_filetype == "po" then 1.170 + io.stderr:write('Writing translations to po file "', out_filename, '".\n') 1.171 + local file = assert(io.open(out_filename, "w")) 1.172 + for num, key in ipairs(translation_keys) do 1.173 + local value = translations[key] 1.174 + file:write('msgid "', key, '"\nmsgstr "', value or "", '"\n\n') 1.175 + end 1.176 + io.close(file) 1.177 +elseif out_filetype == "lua" then 1.178 + io.stderr:write('Writing translations to lua file "', out_filename, '".\n') 1.179 + local file = assert(io.open(out_filename, "w")) 1.180 + file:write("#!/usr/bin/env lua\n", "return {\n") 1.181 + for num, key in ipairs(translation_keys) do 1.182 + local value = translations[key] 1.183 + if value then 1.184 + file:write(string.format("[%q] = %q;\n", key, value)) 1.185 + else 1.186 + file:write(string.format("[%q] = false;\n", key)) 1.187 + end 1.188 + end 1.189 + file:write("}\n") 1.190 + io.close(file) 1.191 +end