Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / frontend / i18n_phase.nit
index f068dc1..14bf436 100644 (file)
@@ -58,7 +58,7 @@ private class I18NPhase
 
                var pot_path = locale_dir / module_name
                var arr = vi.strings.values.to_a
-               var po = new POFile.with_strings(arr)
+               var po = new POFile(arr)
                po.write_template(pot_path)
 
                if lang != null then
@@ -108,6 +108,19 @@ private class StringFinder
                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
@@ -117,17 +130,41 @@ end
 redef class AStringExpr
 
        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
+               var str = value.escape_to_gettext
+               var code = "\"{str}\".get_translation(\"{v.domain}\", \"{v.languages_location}\")"
+               var parse = v.toolcontext.parse_expr(code)
                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 AStartStringExpr or i isa AEndStringExpr or i isa AMidStringExpr then
+                               assert i isa AStringFormExpr
+                               var str = i.value
+                               fmt += str.replace("%", "%%")
+                       else
+                               fmt += "%"
+                               exprs.push i
+                               fmt += (exprs.length-1).to_s
+                       end
+               end
+               fmt = fmt.escape_to_gettext
+               v.add_string(fmt, location)
+               var code = "\"{fmt}\".get_translation(\"{v.domain}\", \"{v.languages_location}\").format()"
+               var parse = v.toolcontext.parse_expr(code)
+               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
 
@@ -155,12 +192,6 @@ class POFile
        # Read from a PO file
        var strings: Array[PObject]
 
-       # Creates a PO file with strings built-in
-       init with_strings(sm: Array[PObject])do
-               strings = new Array[PObject].with_capacity(sm.length)
-               strings.add_all sm
-       end
-
        redef fun write_to_file(path) do
                if not path.has_suffix(".po") then path += ".po"
                super path
@@ -183,3 +214,10 @@ class POFile
                f.close
        end
 end
+
+redef class Text
+       private fun escape_to_gettext: String
+       do
+               return escape_to_c.replace("\{", "\\\{").replace("\}", "\\\}")
+       end
+end