diff -r da74ed639346 docs/i18n.txt
--- a/docs/i18n.txt	Thu Mar 20 09:44:34 2008 -0300
+++ b/docs/i18n.txt	Sun Mar 23 16:18:31 2008 -0300
@@ -338,7 +338,7 @@ take a string as their first argument an
 take a string as their first argument and do something to that string. These
 functions are used by template filters as well as directly in other code.
 
-If you write your own similar functions and deal with translations, you'll 
+If you write your own similar functions and deal with translations, you'll
 face the problem of what to do when the first argument is a lazy translation
 object. You don't want to convert it to a string immediately, because you might
 be using this function outside of a view (and hence the current thread's locale
@@ -789,7 +789,7 @@ You can make the view dynamic by putting
 You can make the view dynamic by putting the packages into the URL pattern::
 
     urlpatterns = patterns('',
-        (r'^jsi18n/(?P<packages>\S+?)/$, 'django.views.i18n.javascript_catalog'),
+        (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
     )
 
 With this, you specify the packages as a list of package names delimited by '+'
@@ -811,24 +811,44 @@ interface to access it::
 
     document.write(gettext('this is to be translated'));
 
-There even is a ``ungettext`` interface and a string interpolation function::
+There is also a ``ngettext`` interface::
 
-    d = {
-        count: 10
-    };
-    s = interpolate(ungettext('this is %(count)s object', 'this are %(count)s objects', d.count), d);
+    var object_cnt = 1 // or 0, or 2, or 3, ...
+    s = ngettext('literal for the singular case', 'literal for the plural case', object_cnt);
 
-The ``interpolate`` function supports both positional interpolation and named
-interpolation. So the above could have been written as::
+and even a string interpolation function::
 
-    s = interpolate(ungettext('this is %s object', 'this are %s objects', 11), [11]);
+    function interpolate(fmt, obj, named);
 
-The interpolation syntax is borrowed from Python. You shouldn't go over the top
-with string interpolation, though: this is still JavaScript, so the code will
-have to do repeated regular-expression substitutions. This isn't as fast as
-string interpolation  in Python, so keep it to those cases where you really
-need it (for example, in conjunction with ``ungettext`` to produce proper
-pluralizations).
+The interpolation syntax is borrowed from Python, so the ``interpolate`` function
+supports both positional interpolation and named interpolation:
+
+    * Positional interpolation: *obj* contains a JavaScript Array object
+      whose elements values are then sequentially  interpolated in their
+      corresponding *fmt* placeholders in the same order they appear.
+      For example::
+
+        fmts = ngettext('There is %s object. Remaining: %s', 'There are %s objects. Remaining: %s', 11);
+        s = interpolate(fmts, [11, 20]);
+	// s is 'There are 11 objects. Remaining: 20'
+
+    * Named interpolation: This mode is selected by passing the optional
+      boolean *named* parameter as true. *obj* contains a JavaScript
+      object or associative array. For example::
+
+        d = {
+            count: 10
+            total: 50
+        };
+        fmts = ngettext('Total: %(total)s, there is %(count)s object',
+	    'there are %(count)s of a total of %(total)s objects', d.count);
+        s = interpolate(fmts, d, true);
+
+You shouldn't go over the top with string interpolation, though: this is still
+JavaScript, so the code will have to do repeated regular-expression
+substitutions. This isn't as fast as string interpolation  in Python, so keep
+it to those cases where you really need it (for example, in conjunction with
+``ngettext`` to produce proper pluralizations).
 
 Creating JavaScript translation catalogs
 ----------------------------------------
