[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [PATCH 4/4] Use gettext.ldngettext when necessary (#467603)



On 06/01/2009 10:42 PM, Hans de Goede wrote:
Hi,

See comments.

On 06/02/2009 05:51 AM, David Cantrell wrote:

<snip>

diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index 8215dc4..e75d6c6 100644
--- a/iw/partition_gui.py
+++ b/iw/partition_gui.py

Missing definition of P_

@@ -1216,15 +1216,18 @@ class PartitionWindow(InstallWindow):
maintable.set_col_spacings(5)
row = 0

- lbltxt = _("Software RAID allows you to combine "
- "several disks into a larger "
- "RAID device. A RAID device can be configured to "
- "provide additional speed and "
- "reliability compared to using an individual drive. "
- "For more information on using RAID devices "
- "please consult the %s documentation.\n\n"
- "You currently have %s software RAID "
- "partition(s) free to use.\n\n") % (productName, len(availraidparts))
+ numparts = P_("You currently have %d software RAID partition free to
use.",
+ "You currently have %d software RAID partitions free to use.",
+ len(availraidparts))
+

Missing "% len(availraidparts)" at the end.

Whoops.  Updated patch attached.  This one got tossed around too much.

+ lbltxt = _("Software RAID allows you to combine several disks into "
+ "a larger RAID device. A RAID device can be configured "
+ "to provide additional speed and reliability compared "
+ "to using an individual drive. For more information on "
+ "using RAID devices please consult the %s "
+ "documentation.") % (productName,)
+
+ lbltxt = lbltxt + "\n\n" + numparts + "\n\n"

if len(availraidparts)< 2:
lbltxt = lbltxt + _("To use RAID you must first "

<snip>

diff --git a/text.py b/text.py
index 70a5331..3d1c63d 100644
--- a/text.py
+++ b/text.py
@@ -40,6 +40,7 @@ import imputil

import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)

import logging
log = logging.getLogger("anaconda")
@@ -369,8 +370,12 @@ class LuksPassphraseWindow:
if len(passphrase)< self.minLength:
ButtonChoiceWindow(self.screen,
_("Error with passphrase"),
- _("The passphrase must be at least "
- "%d characters long.") % (self.minLength,),
+ P_("The passphrase must be at least "
+ "%d character long.",
+ "The passphrase must be at least "
+ "%d characters long.",
+ self.minLength)
+ % (self.minLength,),
buttons=[TEXT_OK_BUTTON])
passphraseentry.set("")
confirmentry.set("")


A+ for consistency, but are we ever going to have a minimum password
length of 1 character ?

diff --git a/vnc.py b/vnc.py
index 3e5d813..db119d0 100644
--- a/vnc.py
+++ b/vnc.py
@@ -32,6 +32,7 @@ import subprocess

import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)

import logging
log = logging.getLogger("anaconda")
@@ -185,7 +186,9 @@ class VncServer:
else:
log.critical(err)
sys.exit(1)
- self.log.error(_("Giving up attempting to connect after %d tries!\n"
% maxTries ))
+ self.log.error(P_("Giving up attempting to connect after %d try!\n",
+ "Giving up attempting to connect after %d tries!\n",
+ maxTries) % (maxTries,))
return False

def VNCListen(self):

Same here, are we ever going to have a maxTries of 1 ?

Regarding this and the above comment, the concern from the translators is more about picking the correct words under different contexts. I don't want to assume anything here and who knows what languages will be added in the future with grammar rules I don't understand. I'd rather be consistent now.

diff --git a/yuminstall.py b/yuminstall.py
index 0e7a4da..b39ecb9 100644
--- a/yuminstall.py
+++ b/yuminstall.py
@@ -51,6 +51,7 @@ import packages

import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)

import network

@@ -81,10 +82,7 @@ def size_string (size):
size = size / 1024
retval = _("%s KB") %(number_format(size),)
else:
- if size == 1:
- retval = _("%s Byte") %(number_format(size),)
- else:
- retval = _("%s Bytes") %(number_format(size),)
+ retval = P_("%s Byte", "%s Bytes", size) % (number_format(size),)

return to_unicode(retval)

@@ -209,8 +207,10 @@ class AnacondaCallback:
self.doneFiles += len(hdr[rpm.RPMTAG_BASENAMES])

if self.donepkgs<= self.numpkgs:
- self.progress.set_text(_("%s of %s packages completed")
- %(self.donepkgs, self.numpkgs))
+ self.progress.set_text(P_("Packages completed: %d of %d",
+ "Packages completed: %d of %d",
+ self.numpkgs)
+ % (self.donepkgs, self.numpkgs,))
self.progress.set_fraction(float(self.doneSize / self.totalSize))
self.progress.processEvents()


Here the singular form and the plural form of the string are the same,
so this
hunk is not needed.

Actually, the "%s of %s packages completed" is what bothered the translators in the first place. Turns out this is impossible to translate in all languages. They asked for the rewrite to "Packages completed: %d of %d" and for the addition of a plural form. Some languages have multiple plural forms depending on the values of self.donepkgs and self.numpkgs. Crazy.

The main goal of this patch was to solve some problems that translators kept hitting. Since we're early in the F-12 process, now seems like a good time.

--
David Cantrell <dcantrell redhat com>
Red Hat / Honolulu, HI
>From fd78e4b6eee394946c0f4c55d7c8ff0eb166429b Mon Sep 17 00:00:00 2001
From: David Cantrell <dcantrell redhat com>
Date: Wed, 27 May 2009 17:00:49 -1000
Subject: [PATCH] Use gettext.ldngettext when necessary (#467603)

The i18n people have suggested using ngettext when we need to have
singular and plural forms of strings, where the count will vary as to
what we are reporting to the user.

I've made the changes they have suggested.  I created a new lambda
function called P_() to use for the plural cases.  P_() takes in three
parameters:

    1) The singular form of the string.
    2) The plural form of the string.
    3) A count.

Here's an example:

    ....some loop runs doing stuff
    bytesWritten = 47
    msg = P_("Wrote %d byte.",
             "Wrote %d bytes.",
             bytesWritten) % (bytesWritten,)
    print msg

The % substitution is correct at the end because P_() returns a single
string, so we only need the format string to account for that.

Some strings have been changed slightly to make it easier for
translations to other languages, particularly when choosing plural forms.
---
 iw/lvm_dialog_gui.py |   17 +++++++++++------
 iw/partition_gui.py  |   22 +++++++++++++---------
 po/Makefile          |    4 ++--
 storage/__init__.py  |    2 +-
 text.py              |    9 +++++++--
 vnc.py               |    5 ++++-
 yuminstall.py        |   12 ++++++------
 7 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/iw/lvm_dialog_gui.py b/iw/lvm_dialog_gui.py
index 733b776..18e140a 100644
--- a/iw/lvm_dialog_gui.py
+++ b/iw/lvm_dialog_gui.py
@@ -34,6 +34,7 @@ from storage.deviceaction import *
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
 
 import logging
 log = logging.getLogger("anaconda")
@@ -764,12 +765,16 @@ class VolumeGroupEditor:
 	self.editLogicalVolume(lv)
 
     def addLogicalVolumeCB(self, widget):
-	if self.numAvailableLVSlots() < 1:
-	    self.intf.messageWindow(_("No free slots"),
-				    _("You cannot create more than %s logical "
-				    "volumes per volume group.") % (lvm.MAX_LV_SLOTS,), custom_icon="error")
-	    return
-	
+        if self.numAvailableLVSlots() < 1:
+            self.intf.messageWindow(_("No free slots"),
+                P_("You cannot create more than %d logical volume "
+                   "per volume group.",
+                   "You cannot create more than %d logical volumes "
+                   "per volume group.", lvm.MAX_LV_SLOTS)
+                % (lvm.MAX_LV_SLOTS,),
+                custom_icon="error")
+            return
+
         (total, used, free) = self.computeSpaceValues()
 	if free <= 0:
 	    self.intf.messageWindow(_("No free space"),
diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index 8215dc4..a08d07b 100644
--- a/iw/partition_gui.py
+++ b/iw/partition_gui.py
@@ -50,6 +50,7 @@ from storage.devices import devicePathToName, PartitionDevice
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
 
 import logging
 log = logging.getLogger("anaconda")
@@ -1216,15 +1217,18 @@ class PartitionWindow(InstallWindow):
         maintable.set_col_spacings(5)
         row = 0
 
-	lbltxt = _("Software RAID allows you to combine "
-		   "several disks into a larger "
-		   "RAID device.  A RAID device can be configured to "
-		   "provide additional speed and "
-		   "reliability compared to using an individual drive.  "
-		   "For more information on using RAID devices "
-		   "please consult the %s documentation.\n\n"
-		   "You currently have %s software RAID "
-		   "partition(s) free to use.\n\n") % (productName, len(availraidparts))
+	numparts = P_("You currently have %d software RAID partition free to use.",
+		    "You currently have %d software RAID partitions free to use.",
+		    len(availraidparts)) % len(availraidparts,)
+
+	lbltxt = _("Software RAID allows you to combine several disks into "
+		    "a larger RAID device.  A RAID device can be configured "
+		    "to provide additional speed and reliability compared "
+		    "to using an individual drive.  For more information on "
+		    "using RAID devices please consult the %s "
+		    "documentation.") % (productName,)
+
+	lbltxt = lbltxt + "\n\n" + numparts + "\n\n"
 
         if len(availraidparts) < 2:
 	    lbltxt = lbltxt + _("To use RAID you must first "
diff --git a/po/Makefile b/po/Makefile
index 6e5b1d2..b33aee7 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -28,9 +28,9 @@ all: $(FMTCATALOGS)
 
 $(NLSPACKAGE).pot: $(POTFILES) $(NONPOTFILES) intltool-po
 	xgettext --from-code=UTF-8 --default-domain=$(NLSPACKAGE) \
-		 --keyword=_ --keyword=N_ --lang=python $(PYPOTFILES)
+		 --keyword=_ --keyword=N_ --keyword=P_:1,2 --lang=python $(PYPOTFILES)
 	xgettext --from-code=UTF-8 --default-domain=$(NLSPACKAGE) -j \
-		 --keyword=_ --keyword=N_ --lang=c $(CPOTFILES) tmp/*.h
+		 --keyword=_ --keyword=N_ --keyword=P_:1,2 --lang=c $(CPOTFILES) tmp/*.h
 	cat ../lang-table | cut -f1 | while read line; do echo -e "\n#. generated from lang-table\nmsgid \"$$line\"\nmsgstr \"\""; done >> $(NLSPACKAGE).po
 	if cmp -s $(NLSPACKAGE).po $(NLSPACKAGE).pot; then \
 	    rm -f $(NLSPACKAGE).po; \
diff --git a/storage/__init__.py b/storage/__init__.py
index ab636b9..e87db9b 100644
--- a/storage/__init__.py
+++ b/storage/__init__.py
@@ -827,7 +827,7 @@ class Storage(object):
         if (root and
             root.size < self.anaconda.backend.getMinimumSizeMB("/")):
             errors.append(_("Your / partition is less than %s "
-                            "megabytes which is lower than recommended "
+                            "MB which is lower than recommended "
                             "for a normal %s install.")
                           %(self.anaconda.backend.getMinimumSizeMB("/"),
                             productName))
diff --git a/text.py b/text.py
index 70a5331..3d1c63d 100644
--- a/text.py
+++ b/text.py
@@ -40,6 +40,7 @@ import imputil
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
 
 import logging
 log = logging.getLogger("anaconda")
@@ -369,8 +370,12 @@ class LuksPassphraseWindow:
                 if len(passphrase) < self.minLength:
                     ButtonChoiceWindow(self.screen,
                                        _("Error with passphrase"),
-                                       _("The passphrase must be at least "
-                                         "%d characters long.") % (self.minLength,),
+                                       P_("The passphrase must be at least "
+                                          "%d character long.",
+                                          "The passphrase must be at least "
+                                          "%d characters long.",
+                                          self.minLength)
+                                         % (self.minLength,),
                                        buttons=[TEXT_OK_BUTTON])
                     passphraseentry.set("")
                     confirmentry.set("")
diff --git a/vnc.py b/vnc.py
index 3e5d813..db119d0 100644
--- a/vnc.py
+++ b/vnc.py
@@ -32,6 +32,7 @@ import subprocess
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
 
 import logging
 log = logging.getLogger("anaconda")
@@ -185,7 +186,9 @@ class VncServer:
             else:
                 log.critical(err)
                 sys.exit(1)
-        self.log.error(_("Giving up attempting to connect after %d tries!\n" % maxTries ))
+        self.log.error(P_("Giving up attempting to connect after %d try!\n",
+                          "Giving up attempting to connect after %d tries!\n",
+                          maxTries) % (maxTries,))
         return False
 
     def VNCListen(self):
diff --git a/yuminstall.py b/yuminstall.py
index 34e3c18..784cfb1 100644
--- a/yuminstall.py
+++ b/yuminstall.py
@@ -51,6 +51,7 @@ import packages
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
 
 import network
 
@@ -81,10 +82,7 @@ def size_string (size):
         size = size / 1024
         retval = _("%s KB") %(number_format(size),)
     else:
-        if size == 1:
-            retval = _("%s Byte") %(number_format(size),)
-        else:
-            retval = _("%s Bytes") %(number_format(size),)
+        retval = P_("%s Byte", "%s Bytes", size) % (number_format(size),)
 
     return to_unicode(retval)
 
@@ -209,8 +207,10 @@ class AnacondaCallback:
             self.doneFiles += len(hdr[rpm.RPMTAG_BASENAMES])
 
             if self.donepkgs <= self.numpkgs:
-                self.progress.set_text(_("%s of %s packages completed")
-                                       %(self.donepkgs, self.numpkgs))
+                self.progress.set_text(P_("Packages completed: %d of %d",
+                                          "Packages completed: %d of %d",
+                                          self.numpkgs)
+                                       % (self.donepkgs, self.numpkgs,))
             self.progress.set_fraction(float(self.doneSize / self.totalSize))
             self.progress.processEvents()
 
-- 
1.6.2.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]