Module GetText
In: lib/gettext/poparser.rb
lib/gettext/textdomain.rb
lib/gettext/utils.rb
lib/gettext/rails.rb
lib/gettext/version.rb
lib/gettext/rgettext.rb
lib/gettext/rmsgfmt.rb
lib/gettext/container.rb
lib/gettext/textdomainmanager.rb
lib/gettext/cgi.rb
lib/gettext/rmsgmerge.rb
lib/gettext/parser/glade.rb
lib/gettext/parser/ruby.rb
lib/gettext/parser/active_record.rb
lib/gettext/parser/erb.rb
lib/gettext/erb.rb
lib/gettext.rb

Methods

Included Modules

GetText GetText

Classes and Modules

Module GetText::ActiveRecordParser
Module GetText::Container
Module GetText::ErbContainer
Module GetText::ErbParser
Module GetText::GladeParser
Module GetText::Rails
Module GetText::RubyParser
Class GetText::NoboundTextDomainError
Class GetText::PoParser
Class GetText::TextDomain
Class GetText::TextDomainManager

Constants

BOM_UTF8 = [0xef, 0xbb, 0xbf].pack("c3")
VERSION = "1.93.0"

Public Instance methods

This function does nothing. But it is required in order to recognize the msgid by rgettext.

  • msgid: the message id.
  • Returns: msgid.

[Source]

     # File lib/gettext.rb, line 383
383:   def N_(msgid)
384:     msgid
385:   end

This is same function as N_ but for ngettext.

  • msgid: the message id.
  • msgid_plural: the plural message id.
  • Returns: msgid.

[Source]

     # File lib/gettext.rb, line 391
391:   def Nn_(msgid, msgid_plural)
392:     [msgid, msgid_plural]
393:   end
_(msgid)

Alias for gettext

Add default locale path.

  • path: a new locale path. (e.g.) "/usr/share/locale/%{locale}/LC_MESSAGES/%{name}.mo" (‘locale’ => "ja_JP", ‘name’ => "textdomain")
  • Returns: the new DEFAULT_LOCALE_PATHS

[Source]

     # File lib/gettext.rb, line 565
565:   def add_default_locale_path(path)
566:     TextDomain.add_default_locale_path(path)
567:   end

Bind a textdomain(%{path}/%{locale}/LC_MESSAGES/%{domainname}.mo) to your program. Normally, the texdomain scope becomes a ruby-script-file. So you need to call this function each ruby-script-files. On the other hand, if you call this function under GetText::Container (gettext/container, gettext/erb, gettext/rails), the textdomain scope becomes a Class/Module.

  • domainname: the textdomain name.
  • options: options as an Hash.
    • :path - the path to the mo-files. When the value is nil, it will search default paths such as /usr/share/locale, /usr/local/share/locale)
    • :locale - the locale string such as "ja_JP.UTF-8". Generally, you should use GetText.set_locale instead. The value is searched order by: the value of this value > System default language.
    • :charset - output charset. This affect the current textdomain only. Generally, you should use GetText.set_output_charset instead. The value is searched order by: the value of Locale.set_output_charset > ENV["OUTPUT_CHARSET"] > this value > System default charset.
  • Returns: the GetText::TextDomainManager.

Note: Don‘t use locale_, charset argument(not in options). They are remained for backward compatibility.

[Source]

     # File lib/gettext.rb, line 85
 85:   def bindtextdomain(domainname, options = {}, locale_ = nil, charset = nil)
 86:     opt = {}
 87:     if options.kind_of? String
 88:       # For backward compatibility
 89:       opt = {:path => options, :locale => locale_, :charset => charset}
 90:     elsif options
 91:       opt = options
 92:     end
 93:     opt[:locale] = opt[:locale] ? Locale::Object.new(opt[:locale]) : Locale.get
 94:     opt[:charset] = TextDomainManager.output_charset if TextDomainManager.output_charset
 95:     opt[:locale].charset = opt[:charset] if opt[:charset]
 96:     Locale.set_current(opt[:locale])
 97:     target_key = bound_target
 98:     manager = @@__textdomainmanagers[target_key]
 99:     if manager
100:       manager.set_locale(opt[:locale]) 
101:     else
102:       manager = TextDomainManager.new(target_key, opt[:locale])
103:       @@__textdomainmanagers[target_key] = manager
104:     end
105:     manager.add_textdomain(domainname, opt)
106:     manager
107:   end

Includes GetText module and bind a textdomain to a class.

[Source]

     # File lib/gettext.rb, line 113
113:   def bindtextdomain_to(klass, domainname, options = {}) 
114:     ret = nil
115:     klass.module_eval {
116:       include GetText
117:       ret = bindtextdomain(domainname, options)
118:     }
119:     ret
120:   end

Set the value whether cache messages or not. true to cache messages, otherwise false.

Default is true. If $DEBUG is false, messages are not checked even if this value is true.

[Source]

    # File lib/gettext.rb, line 42
42:   def cached=(val)
43:     @@__cached = val
44:     GetText::TextDomain.check_mo = ! val
45:   end

Return the cached value.

[Source]

    # File lib/gettext.rb, line 48
48:   def cached?
49:     @@__cached
50:   end

Gets the CGI object. If it is nil, returns new CGI object.

  • Returns: the CGI object

[Source]

    # File lib/gettext/cgi.rb, line 36
36:   def cgi
37:     Locale.cgi
38:   end

Same as GetText.set_cgi.

  • cgi_: CGI object
  • Returns: cgi_

[Source]

    # File lib/gettext/cgi.rb, line 29
29:   def cgi=(cgi_)
30:     set_cgi(cgi_)
31:     cgi_
32:   end

Clear the cached messages.

[Source]

    # File lib/gettext.rb, line 53
53:   def clear_cache
54:     @@__cache_msgids = {}
55:     @@__cache_nmsgids = {}
56:     @@__cache_target_classes = {}
57:     @@__cache_bound_target = {}
58:     @@__cache_bound_targets = {}
59:   end

Creates mo-files using #{po_root}/#{lang}/*.po an put them to #{targetdir}/#{targetpath_rule}/.

This is a convenience function of GetText.rmsgfmt for plural target files.

  • verbose: true if verbose mode, otherwise false
  • po_root: the root directory of po-files.
  • targetdir: the target root directory where the mo-files are stored.
  • targetpath_rule: the target directory for each mo-files. "%s" becomes "#{lang}" under po_root.

[Source]

     # File lib/gettext/utils.rb, line 110
110:   def create_mofiles(verbose = false, 
111:                      podir = "./po", targetdir = "./data/locale", 
112:                      targetpath_rule = "%s/LC_MESSAGES") 
113: 
114:     modir = File.join(targetdir, targetpath_rule)
115:     Dir.glob(File.join(podir, "*/*.po")) do |file|
116:       lang, basename = /\/([^\/]+?)\/(.*)\.po/.match(file[podir.size..-1]).to_a[1,2]
117:       outdir = modir % lang
118:       FileUtils.mkdir_p(outdir) unless File.directory?(outdir)
119:       $stderr.print %Q[#{file} -> #{File.join(outdir, "#{basename}.mo")} ... ] if verbose
120:       begin
121:         rmsgfmt(file, File.join(outdir, "#{basename}.mo"))
122:       rescue Exception => e
123:         $stderr.puts "Error." if verbose
124:         raise e
125:       end
126:       $stderr.puts "Done." if verbose
127:     end
128:   end

Show the current textdomain information. This function is for debugging.

  • options: options as a Hash.
    • :with_messages - show informations with messages of the current mo file. Default is false.
    • :out - An output target. Default is STDOUT.
    • :with_paths - show the load paths for mo-files.

[Source]

     # File lib/gettext.rb, line 574
574:   def current_textdomain_info(options = {})
575:     opts = {:with_messages => false, :with_paths => false, :out => STDOUT}.merge(options)
576:     ret = nil
577:     each_textdomain {|textdomain|
578:       opts[:out].puts "TextDomain name: \"#{textdomain.name}\""
579:       opts[:out].puts "TextDomain current locale: \"#{textdomain.current_locale}\""
580:       opts[:out].puts "TextDomain current mo filename: \"#{textdomain.current_mo.filename}\""
581:       if opts[:with_paths]
582:         opts[:out].puts "TextDomain locale file paths:"
583:         textdomain.locale_paths.each do |v|
584:           opts[:out].puts "  #{v}"
585:         end
586:       end
587:       if opts[:with_messages]
588:         opts[:out].puts "The messages in the mo file:"
589:         textdomain.current_mo.each{|k, v|
590:           opts[:out].puts "  \"#{k}\": \"#{v}\""
591:         }
592:       end
593:     }
594:   end

Translates msgid and return the message. This doesn‘t make a copy of the message.

You need to use String#dup if you want to modify the return value with destructive functions.

(e.g.1) _("Hello ").dup << "world"

But e.g.1 should be rewrite to:

(e.g.2) _("Hello %{val}") % {:val => "world"}

Because the translator may want to change the position of "world".

  • msgid: the message id.
  • Returns: localized text by msgid. If there are not binded mo-file, it will return msgid.

[Source]

     # File lib/gettext.rb, line 263
263:   def gettext(msgid)
264:     sgettext(msgid, nil)
265:   end

Gets the current locale.

[Source]

     # File lib/gettext.rb, line 557
557:   def locale
558:     Locale.current
559:   end

Sets the default/current locale. This method haves the strongest infulence. All of the Textdomains are set the new locale.

Note that you shouldn‘t use this for your own Libraries.

[Source]

     # File lib/gettext.rb, line 527
527:   def locale=(locale)
528:     Locale.default = locale
529:     set_locale_all(locale)
530:     Locale.default
531:   end

Merges two Uniforum style .po files together.

Note This function requires "msgmerge" tool included in GNU GetText. So you need to install GNU GetText.

The def.po file is an existing PO file with translations which will be taken over to the newly created file as long as they still match; comments will be preserved, but extracted comments and file positions will be discarded.

The ref.pot file is the last created PO file with up-to-date source references but old translations, or a PO Template file (generally created by rgettext); any translations or comments in the file will be discarded, however dot comments and file positions will be preserved. Where an exact match cannot be found, fuzzy matching is used to produce better results.

Usually you don‘t need to call this function directly. Use GetText.update_pofiles instead.

  • defpo: a po-file. translations referring to old sources
  • refpo: a po-file. references to new sources
  • app_version: the application information which appears "Project-Id-Version: #{app_version}" in the pot/po-files.
  • Returns: self

[Source]

    # File lib/gettext/utils.rb, line 60
60:   def msgmerge(defpo, refpo, app_version) 
61:     $stderr.print defpo + " "
62:     cmd = ENV["MSGMERGE_PATH"] || "msgmerge"
63: 
64:     cont = ""
65:     if FileTest.exist? defpo
66:       `#{cmd} --help`
67:       unless $? && $?.success?
68:         raise _("`%{cmd}' may not be found. \nInstall GNU Gettext then set PATH or MSGMERGE_PATH correctly.") % {:cmd => cmd}
69:       end
70:       remove_bom(defpo)
71:       cont = `#{cmd} #{defpo} #{refpo}`
72:     else
73:       File.open(refpo) do |io| 
74:         cont = io.read
75:       end
76:     end
77:     if cont.empty?
78:       failed_filename = refpo + "~"
79:       FileUtils.cp(refpo, failed_filename)
80:       $stderr.puts _("Failed to merge with %{defpo}") % {:defpo => defpo}
81:       $stderr.puts _("New .pot was copied to %{failed_filename}") %{:failed_filename => failed_filename}
82:       raise _("Check these po/pot-files. It may have syntax errors or something wrong.")
83:     else
84:       cont.sub!(/(Project-Id-Version\:).*$/, "\\1 #{app_version}\\n\"")
85:       File.open(defpo, "w") do |out|
86:         out.write(cont)
87:       end
88:     end
89:     self
90:   end
n_(arg1, arg2, arg3 = nil)

Alias for ngettext

The ngettext is similar to the gettext function as it finds the message catalogs in the same way. But it takes two extra arguments for plural form.

  • msgid: the singular form.
  • msgid_plural: the plural form.
  • n: a number used to determine the plural form.
  • Returns: the localized text which key is msgid_plural if n is plural(follow plural-rule) or msgid. "plural-rule" is defined in po-file.

[Source]

     # File lib/gettext.rb, line 340
340:   def ngettext(arg1, arg2, arg3 = nil)
341:     nsgettext(arg1, arg2, arg3, nil)
342:   end
np_(msgctxt, arg1, arg2 = nil, arg3 = nil)

Alias for npgettext

The npgettext is similar to the nsgettext function.

  e.g.) np_("Special", "An apple", "%{num} Apples", num) == ns_("Special|An apple", "%{num} Apples", num)
  • msgctxt: the message context.
  • msgid: the singular form.
  • msgid_plural: the plural form.
  • n: a number used to determine the plural form.
  • Returns: the localized text which key is msgid_plural if n is plural(follow plural-rule) or msgid. "plural-rule" is defined in po-file.

[Source]

     # File lib/gettext.rb, line 358
358:   def npgettext(msgctxt, arg1, arg2 = nil, arg3 = nil)
359:     if arg1.kind_of?(Array)
360:       msgid = arg1[0]
361:       msgid_ctxt = "#{msgctxt}\004#{msgid}"
362:       msgid_plural = arg1[1]
363:       opt1 = arg2
364:       opt2 = arg3
365:     else
366:       msgid = arg1
367:       msgid_ctxt = "#{msgctxt}\004#{msgid}"
368:       msgid_plural = arg2
369:       opt1 = arg3
370:       opt2 = nil
371:     end
372:     ret = nsgettext(msgid_ctxt, msgid_plural, opt1, opt2)
373:     
374:     if ret == msgid_ctxt
375:       ret = msgid
376:     end
377:     ret
378:   end
ns_(arg1, arg2, arg3 = "|", arg4 = "|")

Alias for nsgettext

The nsgettext is similar to the ngettext. But if there are no localized text, it returns a last part of msgid separeted "div".

  • msgid: the singular form with "div". (e.g. "Special|An apple")
  • msgid_plural: the plural form. (e.g. "%{num} Apples")
  • n: a number used to determine the plural form.
  • Returns: the localized text which key is msgid_plural if n is plural(follow plural-rule) or msgid. "plural-rule" is defined in po-file.

[Source]

     # File lib/gettext.rb, line 411
411:   def nsgettext(arg1, arg2, arg3 = "|", arg4 = "|")
412:     if arg1.kind_of?(Array)
413:       msgid = arg1[0]
414:       msgid_plural = arg1[1]
415:       n = arg2
416:       if arg3 and arg3.kind_of? Numeric
417:         raise ArgumentError, _("3rd parmeter is wrong: value = %{number}") % {:number => arg3}
418:       end
419:       div = arg3
420:     else
421:       msgid = arg1
422:       msgid_plural = arg2
423:       n = arg3
424:       div = arg4
425:     end
426: 
427:     cached_key = [bound_target, Locale.current, msgid + "\000" + msgid_plural]
428:     msgs = nil
429:     if @@__cached
430:       if @@__cache_nmsgids.has_key?(cached_key)
431:         msgs = @@__cache_nmsgids[cached_key]  # [msgstr, cond_as_string]
432:       end
433:     end
434:     unless msgs
435:       # Use "for"(not "each") to support JRuby 1.1.0.
436:       for target in bound_targets(self)
437:         manager = @@__textdomainmanagers[target]
438:         for textdomain in manager.textdomains
439:           msgs = textdomain[1].ngettext_data(msgid, msgid_plural)
440:           break if msgs
441:         end
442:         break if msgs
443:       end
444:       msgs = [[msgid, msgid_plural], "n != 1"] unless msgs
445:       @@__cache_nmsgids[cached_key] = msgs
446:     end
447:     msgstrs = msgs[0]
448:     if div and msgstrs[0] == msgid
449:       if index = msgstrs[0].rindex(div)
450:         msgstrs[0] = msgstrs[0][(index + 1)..-1]
451:       end
452:     end
453:     plural = eval(msgs[1])
454:     if plural.kind_of?(Numeric)
455:       ret = msgstrs[plural]
456:     else
457:       ret = plural ? msgstrs[1] : msgstrs[0]
458:     end
459:     ret
460:   end

Gets the current output_charset which is set using GetText.set_output_charset.

[Source]

     # File lib/gettext.rb, line 551
551:   def output_charset
552:     TextDomainManager.output_charset || locale.charset
553:   end

Same as GetText.set_output_charset

[Source]

     # File lib/gettext.rb, line 545
545:   def output_charset=(charset)
546:     TextDomainManager.output_charset = charset
547:   end
p_(msgctxt, msgid)

Alias for pgettext

Translates msgid with msgctxt. This methods is similer with s_().

 e.g.) p_("File", "New")   == s_("File|New")
       p_("File", "Open")  == s_("File|Open")
  • msgctxt: the message context.
  • msgid: the message id.
  • Returns: the localized text by msgid. If there are no localized text, it returns msgid.

See: www.gnu.org/software/autoconf/manual/gettext/Contexts.html

[Source]

     # File lib/gettext.rb, line 320
320:   def pgettext(msgctxt, msgid)
321:     sgettext(msgctxt + "\004" + msgid, "\004")
322:   end

for testing.

[Source]

     # File lib/gettext.rb, line 597
597:   def remove_all_textdomains
598:     clear_cache
599:     @@__textdomainmanagers = {}
600:   end

Creates a po-file from targetfiles(ruby-script-files, ActiveRecord, .rhtml files, glade-2 XML files), then output the result to out. If no parameter is set, it behaves same as command line tools(rgettet).

This function is a part of GetText.create_pofiles. Usually you don‘t need to call this function directly.

Note for ActiveRecord, you need to run your database server and configure the config/database.xml correctly before execute this function.

  • targetfiles: An Array of po-files or nil.
  • out: output IO or output path.
  • Returns: self

[Source]

     # File lib/gettext/rgettext.rb, line 265
265:   def rgettext(targetfiles = nil, out = STDOUT)
266:     RGetText.run(targetfiles, out)
267:     self
268:   end

Creates a mo-file from a targetfile(po-file), then output the result to out. If no parameter is set, it behaves same as command line tools(rmsgfmt).

  • targetfile: An Array of po-files or nil.
  • output_path: output path.
  • Returns: the MOFile object.

[Source]

    # File lib/gettext/rmsgfmt.rb, line 79
79:   def rmsgfmt(targetfile = nil, output_path = nil)
80:     RMsgfmt.run(targetfile, output_path)
81:   end

Experimental

[Source]

     # File lib/gettext/rmsgmerge.rb, line 489
489:   def rmsgmerge(reference = nil, definition = nil, out = STDOUT)
490:     RMsgMerge.run(reference, definition, out)
491:   end
s_(msgid, div = '|')

Alias for sgettext

Sets a CGI object.

  • cgi_: CGI object
  • Returns: self

[Source]

    # File lib/gettext/cgi.rb, line 22
22:   def set_cgi(cgi_)
23:     Locale.set_cgi(cgi_)
24:   end

Sets the current locale to the current class/module

Notice that you shouldn‘t use this for your own Libraries.

Otherwise, this changes the locale of the current class/module and its ancestors. Default is false.

  • Returns: self

[Source]

     # File lib/gettext.rb, line 470
470:   def set_locale(locale, this_target_only = false)
471:     ret = nil
472:     if locale
473:       if locale.kind_of? Locale::Object
474:         ret = locale
475:       else
476:         ret = Locale::Object.new(locale.to_s)
477:       end
478:       ret.charset = TextDomainManager.output_charset if TextDomainManager.output_charset
479:       Locale.set(ret)
480:     else
481:       Locale.set(nil)
482:       ret = Locale.get
483:     end
484:     if this_target_only
485:       manager = @@__textdomainmanagers[bound_target]
486:       if manager
487:         manager.set_locale(ret, ! cached?)
488:       end
489:     else
490:       each_textdomain {|textdomain|
491:         textdomain.set_locale(ret, ! cached?)
492:       }
493:     end
494:     self
495:   end

Sets current locale to the all textdomains.

Note that you shouldn‘t use this for your own Libraries.

[Source]

     # File lib/gettext.rb, line 502
502:   def set_locale_all(locale)
503:     ret = nil
504:     if locale
505:       if locale.kind_of? Locale::Object
506:         ret = locale
507:       else
508:         ret = Locale::Object.new(locale.to_s)
509:       end
510:     else
511:       ret = Locale.default
512:     end
513:     ret.charset = TextDomainManager.output_charset if TextDomainManager.output_charset
514:     Locale.set_current(ret)
515:     TextDomainManager.each_all {|textdomain|
516:       textdomain.set_locale(ret, ! cached?)
517:     }
518:     self
519:   end

Sets charset(String) such as "euc-jp", "sjis", "CP932", "utf-8", … You shouldn‘t use this in your own Libraries.

[Source]

     # File lib/gettext.rb, line 537
537:   def set_output_charset(charset)
538:     TextDomainManager.output_charset = charset
539:     self
540:   end
setlocale(locale)

Alias for locale=

Translates msgid, but if there are no localized text, it returns a last part of msgid separeted "div".

  • msgid: the message id.
  • div: separator or nil.
  • Returns: the localized text by msgid. If there are no localized text, it returns a last part of msgid separeted "div".

See: www.gnu.org/software/gettext/manual/html_mono/gettext.html#SEC151

[Source]

     # File lib/gettext.rb, line 279
279:   def sgettext(msgid, div = '|')
280:     cached_key = [bound_target, Locale.current, msgid]
281:     if cached?
282:       if @@__cache_msgids[cached_key]
283:         return @@__cache_msgids[cached_key]
284:       end
285:     end
286:     msg = nil
287: 
288:     # Use "for"(not "each") to support JRuby 1.1.0.
289:     for target in bound_targets(self)
290:       manager = @@__textdomainmanagers[target]
291:       for textdomain in manager.textdomains
292:         msg = textdomain[1].gettext(msgid)
293:         break if msg
294:       end
295:       break if msg
296:     end
297: 
298:     msg ||= msgid
299:     if div and msg == msgid
300:       if index = msg.rindex(div)
301:         msg = msg[(index + 1)..-1]
302:       end
303:     end
304:     @@__cache_msgids[cached_key] = msg
305:   end

Binds a existed textdomain to your program. This is the same function with GetText.bindtextdomain but simpler(and faster) than bindtextdomain. Notice that you need to call GetText.bindtextdomain first. If the domainname hasn‘t bound yet, raises GetText::NoboundTextDomainError.

[Source]

     # File lib/gettext.rb, line 128
128:   def textdomain(domainname)
129:     domain = TextDomainManager.textdomain(domainname)
130:     raise NoboundTextDomainError, "#{domainname} is not bound." unless domain
131:     target_key = bound_target
132:     manager = @@__textdomainmanagers[target_key]
133:     unless manager
134:       manager = TextDomainManager.new(target_key, Locale.get)
135:       @@__textdomainmanagers[target_key] = manager
136:     end
137:     manager.set_locale(Locale.get)
138:     manager.add_textdomain(domainname)
139:     manager
140:   end

Includes GetText module and bind an exsited textdomain to a class. See textdomain for more detail.

  • klass: the target ruby class.
  • domainname: the textdomain name.

[Source]

     # File lib/gettext.rb, line 146
146:   def textdomain_to(klass, domainname) 
147:     ret = nil
148:     klass.module_eval {
149:       include GetText
150:       ret = textdomain(domainname)
151:     }
152:     ret
153:   end

At first, this creates the #{po_root}/#{domainname}.pot file using GetText.rgettext. Since 2nd time, this updates(merges) the #{po_root}/#{domainname}.pot and all of the #{po_root}/#{lang}/#{domainname}.po files under "po_root" using "msgmerge".

Note "msgmerge" tool is included in GNU GetText. So you need to install GNU GetText.

See <HOWTO maintain po/mo files(www.yotabanana.com/hiki/ruby-gettext-howto-manage.html)> for more detals.

  • domainname: the textdomain name.
  • targetfiles: An Array of target files or nil (See GetText.rgettext for more details).
  • app_version: the application information which appears "Project-Id-Version: #{app_version}" in the pot/po-files.
  • po_root: the root directory of po-files.
  • refpot: set the temporary file name. You shouldn‘t use this(It will be removed).
 (e.g.) GetText.update_pofiles("myapp", Dir.glob("lib/*.rb"), "myapp 1.0.0")

[Source]

     # File lib/gettext/utils.rb, line 145
145:   def update_pofiles(textdomain, files, app_version, po_root = "po", refpot = "tmp.pot")
146:     rgettext(files, refpot)
147:     msgmerge_all(textdomain, app_version, po_root, refpot)
148:     File.delete(refpot)
149:   end

[Validate]