diff options
-rw-r--r-- | libs/web/luasrc/dispatcher.lua | 1 | ||||
-rw-r--r-- | libs/web/luasrc/i18n.lua | 28 | ||||
-rw-r--r-- | libs/web/src/template_parser.c | 56 | ||||
-rw-r--r-- | libs/web/src/template_parser.h | 4 |
4 files changed, 44 insertions, 45 deletions
diff --git a/libs/web/luasrc/dispatcher.lua b/libs/web/luasrc/dispatcher.lua index ad4f24dc7..6445c124e 100644 --- a/libs/web/luasrc/dispatcher.lua +++ b/libs/web/luasrc/dispatcher.lua @@ -235,6 +235,7 @@ function dispatch(request) include = function(name) tpl.Template(name):render(getfenv(2)) end; translate = function(...) return require("luci.i18n").translate(...) end; striptags = util.striptags; + pcdata = util.pcdata; media = media; theme = fs.basename(media); resource = luci.config.main.resourcebase diff --git a/libs/web/luasrc/i18n.lua b/libs/web/luasrc/i18n.lua index 9a11a9dc8..816d90310 100644 --- a/libs/web/luasrc/i18n.lua +++ b/libs/web/luasrc/i18n.lua @@ -93,42 +93,38 @@ function setlanguage(lang) end --- Return the translated value for a specific translation key. --- @param key Translation key --- @param def Default translation +-- @param key Default translation text -- @return Translated string -function translate(key, def) +function translate(key) return (table[context.lang] and table[context.lang][key]) or (table[context.parent] and table[context.parent][key]) or (table[default] and table[default][key]) - or def + or key end --- Return the translated value for a specific translation key and use it as sprintf pattern. --- @param key Translation key --- @param default Default translation +-- @param key Default translation text -- @param ... Format parameters -- @return Translated and formatted string -function translatef(key, default, ...) - return tostring(translate(key, default)):format(...) +function translatef(key, ...) + return tostring(translate(key)):format(...) end --- Return the translated value for a specific translation key -- and ensure that the returned value is a Lua string value. -- This is the same as calling <code>tostring(translate(...))</code> --- @param key Translation key --- @param default Default translation +-- @param key Default translation text -- @return Translated string -function string(key, default) - return tostring(translate(key, default)) +function string(key) + return tostring(translate(key)) end --- Return the translated value for a specific translation key and use it as sprintf pattern. -- Ensure that the returned value is a Lua string value. -- This is the same as calling <code>tostring(translatef(...))</code> --- @param key Translation key --- @param default Default translation +-- @param key Default translation text -- @param ... Format parameters -- @return Translated and formatted string -function stringf(key, default, ...) - return tostring(translate(key, default)):format(...) +function stringf(key, ...) + return tostring(translate(key)):format(...) end diff --git a/libs/web/src/template_parser.c b/libs/web/src/template_parser.c index fe324cedc..a0a400bdf 100644 --- a/libs/web/src/template_parser.c +++ b/libs/web/src/template_parser.c @@ -20,11 +20,12 @@ /* leading and trailing code for different types */ -const char * gen_code[6][2] = { +const char * gen_code[7][2] = { { "write(\"", "\")" }, { NULL, NULL }, { "write(tostring(", " or \"\"))" }, { "include(\"", "\")" }, + { "write(pcdata(translate(\"", "\")))" }, { "write(translate(\"", "\"))" }, { NULL, " " } }; @@ -127,7 +128,7 @@ static const char * generate_expression(struct template_parser *data, size_t *sz int i; int size = 0; int start = 0; - int i18n_hasdef = 0; + int whitespace = 0; memset(tmp, 0, T_OUTBUFSZ); @@ -142,31 +143,35 @@ static const char * generate_expression(struct template_parser *data, size_t *sz for( i = 0; i < data->outsize; i++ ) { /* Skip leading whitespace for non-raw and non-expr chunks */ - if( !start && isspace(data->out[i]) && (data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) ) + if( !start && isspace(data->out[i]) && (data->type == T_TYPE_I18N || + data->type == T_TYPE_I18N_RAW || data->type == T_TYPE_INCLUDE) ) continue; else if( !start ) start = 1; /* Found whitespace after i18n key */ - if( (data->type == T_TYPE_I18N) && (i18n_hasdef == 1) ) + if( data->type == T_TYPE_I18N || data->type == T_TYPE_I18N_RAW ) { - /* At non-whitespace char, inject seperator token */ - if( !isspace(data->out[i]) ) + /* Is initial whitespace, insert space */ + if( !whitespace && isspace(data->out[i]) ) { - memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP)); - size += strlen(T_TOK_I18NSEP); - i18n_hasdef = 2; + tmp[size++] = ' '; + whitespace = 1; } - /* At further whitespace, skip */ - else + /* Suppress subsequent whitespace, escape special chars */ + else if( !isspace(data->out[i]) ) { - continue; + if( data->out[i] == '\\' || data->out[i] == '"' ) + tmp[size++] = '\\'; + + tmp[size++] = data->out[i]; + whitespace = 0; } } - /* Escape quotes, backslashes and newlines for plain, i18n and include expressions */ - if( (data->type == T_TYPE_TEXT || data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) && + /* Escape quotes, backslashes and newlines for plain and include expressions */ + else if( (data->type == T_TYPE_TEXT || data->type == T_TYPE_INCLUDE) && (data->out[i] == '\\' || data->out[i] == '"' || data->out[i] == '\n' || data->out[i] == '\t') ) { tmp[size++] = '\\'; @@ -186,12 +191,6 @@ static const char * generate_expression(struct template_parser *data, size_t *sz } } - /* Found first whitespace in i18n expression, raise flag */ - else if( isspace(data->out[i]) && (data->type == T_TYPE_I18N) && (i18n_hasdef == 0) ) - { - i18n_hasdef = 1; - } - /* Normal char */ else { @@ -199,16 +198,14 @@ static const char * generate_expression(struct template_parser *data, size_t *sz } } - /* Processed i18n expression without default text, inject separator */ - if( (data->type == T_TYPE_I18N) && (i18n_hasdef < 2) ) - { - memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP)); - size += strlen(T_TOK_I18NSEP); - } - /* Inject trailing expression code (if any) */ if( (what & T_GEN_END) && (gen_code[data->type][1] != NULL) ) { + /* Strip trailing space for i18n expressions */ + if( data->type == T_TYPE_I18N || data->type == T_TYPE_I18N_RAW ) + if( (size > 0) && (tmp[size-1] == ' ') ) + size--; + memcpy(&tmp[size], gen_code[data->type][1], strlen(gen_code[data->type][1])); size += strlen(gen_code[data->type][1]); } @@ -403,6 +400,11 @@ const char *template_reader(lua_State *L, void *ud, size_t *sz) data->type = T_TYPE_I18N; break; + case '_': + off++; + data->type = T_TYPE_I18N_RAW; + break; + default: data->type = T_TYPE_CODE; break; diff --git a/libs/web/src/template_parser.h b/libs/web/src/template_parser.h index 42ebdff69..24933f0c9 100644 --- a/libs/web/src/template_parser.h +++ b/libs/web/src/template_parser.h @@ -49,7 +49,6 @@ #define T_TOK_START "<%" #define T_TOK_END "%>" #define T_TOK_SKIPWS "-" -#define T_TOK_I18NSEP "\", \"" /* generator flags */ #define T_GEN_START 0x01 @@ -61,7 +60,8 @@ #define T_TYPE_EXPR 2 #define T_TYPE_INCLUDE 3 #define T_TYPE_I18N 4 -#define T_TYPE_CODE 5 +#define T_TYPE_I18N_RAW 5 +#define T_TYPE_CODE 6 /* parser state */ struct template_parser { |