[hyena] [Hyena] Add FormatInterleaved to StringUtil



commit cf2809f7db9383cc8f4e91d7643e5674d8fdd5a7
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Fri Oct 29 15:53:07 2010 -0500

    [Hyena] Add FormatInterleaved to StringUtil
    
    This lets you pass in a string format, and returns an enumerable of
    the objects passed in interleaved where appropriate with substrings of
    the format.  For example:
    
    FormatInterLeave ("Use {0} threads", new SpinButton ())
     => "Use", spin_button, "threads"
    
    If the format you pass in instead comes from Catalog.GetString, you now
    can interleave widgets with internationalized labels:
    
    var widgets = StringUtil.FormatInterleaved (
        Catalog.GetString ("Show only {0} episodes"), new_checkbox
    ).Select (o => (o as Widget) ?? new Label (o as string));

 Hyena/Hyena/StringUtil.cs            |   31 +++++++++++++++++++++++++++++++
 Hyena/Hyena/Tests/StringUtilTests.cs |   12 ++++++++++++
 2 files changed, 43 insertions(+), 0 deletions(-)
---
diff --git a/Hyena/Hyena/StringUtil.cs b/Hyena/Hyena/StringUtil.cs
index 99aaac5..6893370 100644
--- a/Hyena/Hyena/StringUtil.cs
+++ b/Hyena/Hyena/StringUtil.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
@@ -367,5 +368,35 @@ namespace Hyena
 
             return sb.ToString ();
         }
+
+        public static IEnumerable<object> FormatInterleaved (string format, params object [] objects)
+        {
+            var indices = new Dictionary<object, int> ();
+
+            for (int i = 0; i < objects.Length; i++) {
+                int j = format.IndexOf ("{" + i + "}");
+                if (j == -1) {
+                    Hyena.Log.ErrorFormat ("Translated string {0} should contain {{1}} in which to place object {2}", format, i, objects[i]);
+                }
+                indices[objects[i]] = j;
+            }
+
+            int str_pos = 0;
+            foreach (var obj in objects.OrderBy (w => indices[w])) {
+                int widget_i = indices[obj];
+                if (widget_i > str_pos) {
+                    var str = format.Substring (str_pos, widget_i - str_pos).Trim ();
+                    if (str != "") yield return str;
+                }
+
+                yield return obj;
+                str_pos = widget_i + 2 + Array.IndexOf (objects, obj).ToString ().Length;
+            }
+
+            if (str_pos < format.Length - 1) {
+                var str = format.Substring (str_pos, format.Length - str_pos).Trim ();
+                if (str != "") yield return str;
+            }
+        }
     }
 }
diff --git a/Hyena/Hyena/Tests/StringUtilTests.cs b/Hyena/Hyena/Tests/StringUtilTests.cs
index 637c027..66a27b7 100644
--- a/Hyena/Hyena/Tests/StringUtilTests.cs
+++ b/Hyena/Hyena/Tests/StringUtilTests.cs
@@ -161,6 +161,18 @@ href=http://lkjdflkjdflkjj>baz foo< /a> bar"));
         }
 
         [Test]
+        public void TestFormatInterleaved ()
+        {
+            var objects = new object [] { "one", 2 };
+            var format = new Func<string, string> ((fmt) => StringUtil.FormatInterleaved (fmt, objects).Select (o => o.ToString ()).Join (""));
+
+            Assert.AreEqual ("onefoo2bar", format ("{0} foo {1} bar"));
+            Assert.AreEqual ("fooone2bar", format ("foo {0} {1} bar"));
+            Assert.AreEqual ("fooonebar2", format ("foo {0} bar {1}"));
+            Assert.AreEqual ("onefoo bar2", format ("{0} foo bar {1}"));
+        }
+
+        [Test]
         public void TestSubstringBetween ()
         {
             Assert.AreEqual ("bar", "foobarbaz".SubstringBetween ("foo", "baz"));



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