Sunday, June 05, 2016

Aligning text

I needed to write some code in a console app to align what a user was saying, in case it was longer than a line (80 characters):

marcel: blah blah blah a lot of text that doesn't fit in 80 characters more blah
         blah blah
long_username: Contrary to popular belief, Lorem Ipsum is not simply random text
               . It has roots in a piece of classical Latin literature from 45 B
               C, making it over 2000 years old. Richard McClintock, a Latin pro
               fessor at Hampden-Sydney College in Virginia, looked up one of th

I wrote the code in two ways: an imperative, mutating style and a functional (recursive) style. I find the second one to be more elegant but since the entire project is something done as a hobby I don't much care about speed; your mileage might vary. I'm also quite certain the first method can be improved but… again, I don't need to do that so it doesn't get done.

As usual, use at your own risk, I don't care about copyrights, blah, blah. Oh, and the result will look bad if the text contains non-printable characters.

        private static string Align(string prefix, string text, int length = 80)
        {
            Debug.Assert(prefix != null);
            Debug.Assert(text != null);
            Debug.Assert(length > prefix.Length);

            var prefixLength = prefix.Length;

            var sb = new StringBuilder();

            do
            {
                var limit = Math.Min(text.Length, length - prefixLength);

                var current = text.Substring(0, limit);
                sb.Append(prefix + current);

                prefix = new string(' ', prefixLength);
                text = text.Substring(limit);
            } while (text != "");

            return sb.ToString();
        }

        private static string Align2(string prefix, string text, int length = 80)
        {
            Debug.Assert(prefix != null);
            Debug.Assert(text != null);
            Debug.Assert(length > prefix.Length);

            var all = prefix + text;

            return all.Length <= length
                ? all
                : all.Substring(0, length) +
                  Align2(new string(' ', prefix.Length), all.Substring(length), length);
        }

Hmm... I think this would be an interesting exercise if I wanted to hire programmers.

No comments: