Added the support of superstrings in the i18n annotation.
The first commit introduces a string format to use when replacing superstrings.
The second and third commits are updates to the i18n annotation and the test that goes along with it.
Pull-Request: #1319
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Jean Privat <jean@pryen.org>
of the language annotation capacities
"""
+
+var s = "example"
+
+print "This superstring {s} rocks"
+
+print "This superstring %1 rocks".format(s)
msgid "Multiline string\n\nexample\n\n\nof the language annotation capacities\n"
msgstr "Multiline string\n\nexample\n\n\nof the language annotation capacities\n"
+#: langannot::langannot 39--9:17
+msgid "example"
+msgstr "example"
+
+#: langannot::langannot 41--7:34, langannot::langannot 43--7:33
+msgid "This superstring %1 rocks"
+msgstr "This superstring %1 rocks"
+
# Generated file, do not modify
msgid "Multiline string\n\nexample\n\n\nof the language annotation capacities\n"
msgstr "Example de\n\nchaine multiligne\n\n\navec annotation de localisation\n"
+#: langannot::langannot 39--9:17
+msgid "example"
+msgstr "exemple"
+
+#: langannot::langannot 41--7:34, langannot::langannot 43--7:33
+msgid "This superstring %1 rocks"
+msgstr "Cet %1 de superstring est génial"
+
# Generated file, do not modify
msgid "Multiline string\n\nexample\n\n\nof the language annotation capacities\n"
msgstr "複数行の文字列\n\nなサンプルプログラム\n\n\n新しい国際化アノテーションとともに\n"
+#: langannot::langannot 39--9:17
+msgid "example"
+msgstr "サンプル"
+
+#: langannot::langannot 41--7:34, langannot::langannot 43--7:33
+msgid "This superstring %1 rocks"
+msgstr "このスパ文字列%1は驚くべきです"
+
# Generated file, do not modify
msgid "Multiline string\n\nexample\n\n\nof the language annotation capacities\n"
msgstr ""
+#: langannot::langannot 39--9:17
+msgid "example"
+msgstr ""
+
+#: langannot::langannot 41--7:34, langannot::langannot 43--7:33
+msgid "This superstring %1 rocks"
+msgstr ""
+
# Generated file, do not modify
return hash_cache.as(not null)
end
+ # Gives the formatted string back as a Nit string with `args` in place
+ #
+ # assert "This %1 is a %2.".format("String", "formatted String") == "This String is a formatted String"
+ # assert "\\%1 This string".format("String") == "\\%1 This string"
+ fun format(args: Object...): String do
+ var s = new Array[Text]
+ var curr_st = 0
+ var i = 0
+ while i < length do
+ # Skip escaped characters
+ if self[i] == '\\' then
+ i += 1
+ # In case of format
+ else if self[i] == '%' then
+ var fmt_st = i
+ i += 1
+ var ciph_st = i
+ while i < length and self[i].is_numeric do
+ i += 1
+ end
+ i -= 1
+ var fmt_end = i
+ var ciph_len = fmt_end - ciph_st + 1
+ s.push substring(curr_st, fmt_st - curr_st)
+ s.push args[substring(ciph_st, ciph_len).to_i - 1].to_s
+ curr_st = i + 1
+ end
+ i += 1
+ end
+ s.push substring(curr_st, length - curr_st)
+ return s.to_s
+ end
+
end
# All kinds of array-based text representations.
if e isa AAnnotation then return
super
end
+
+ # Adds a String to the list of strings of the module
+ #
+ # The string needs to be pre-formatted to C standards (escape_to_c)
+ fun add_string(s: String, loc: Location) do
+ var locstr = "{amodule.mmodule.mgroup.name}::{amodule.mmodule.name} {loc.line_start}--{loc.column_start}:{loc.column_end}"
+ if not strings.has_key(s) then
+ var po = new PObject([locstr], s, "")
+ strings[s] = po
+ else
+ strings[s].locations.push locstr
+ end
+ end
end
redef class ANode
redef fun accept_string_finder(v) do
var str = value.as(not null).escape_to_c
var parse = v.toolcontext.parse_expr("\"{str}\".get_translation(\"{v.domain}\", \"{v.languages_location}\").unescape_nit")
- var loc = location
- var locstr = "{v.amodule.mmodule.mgroup.name}::{v.amodule.mmodule.name} {loc.line_start}--{loc.column_start}:{loc.column_end}"
- if not v.strings.has_key(str) then
- var po = new PObject([locstr], str, "")
- v.strings[str] = po
- else
- v.strings[str].locations.push locstr
- end
replace_with(parse)
+ v.add_string(str, location)
+ end
+end
+
+redef class ASuperstringExpr
+
+ redef fun accept_string_finder(v) do
+ var fmt = ""
+ var exprs = new Array[AExpr]
+ for i in n_exprs do
+ if i isa AStringFormExpr then
+ fmt += i.value.as(not null)
+ else
+ fmt += "%"
+ exprs.push i
+ fmt += exprs.length.to_s
+ end
+ end
+ fmt = fmt.escape_to_c
+ v.add_string(fmt, location)
+ var parse = v.toolcontext.parse_expr("\"{fmt}\".get_translation(\"{v.domain}\", \"{v.languages_location}\").unescape_nit.format()")
+ if not parse isa ACallExpr then
+ v.toolcontext.error(location, "Fatal error in i18n annotation, the parsed superstring could not be generated properly")
+ return
+ end
+ var parse_exprs = parse.n_args.n_exprs
+ parse_exprs.add_all exprs
+ replace_with parse
end
end