webmcp

annotate framework/bin/langtool.lua @ 4:5e32ef998acf

Version 1.0.4

ui.link{...} with POST target can now be parameterized with BOTH content and text to allow HTML content for JavaScript browsers and a text-only version for accessiblity

Changes related to database selectors:
- Support for row-based locking
- New method :count(), caching and returning the number of rows, which WOULD have been returned by :exec()
- Bugfix: WHERE and HAVING expressions are now enclosed in parenthesis to avoid problems with operator precedence

ui.script{...} now supports external .js files

Changes in langtool.lua to cope with escaped new-line chars (\n)
author jbe/bsw
date Fri Dec 25 12:00:00 2009 +0100 (2009-12-25)
parents 9fdfb27f8e67
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

Impressum / About Us