I have a working solution right now, but it seems really ugly for something so (seemingly) simple.
I tried just breaking it when adding a word goes over the halfway mark, both splitting before and after adding the word, but depending on the length of the words it's either imbalanced towards the first or second line.
Sample inputs that I was initially having trouble with before the convoluted fix:
Input "Macaroni Cheese"
and "Cheese Macaroni"
Should output "Macaroni<br/> Cheese"
and "Cheese<br/> Macaroni"
respectively.
But simpler solutions either worked on the first but not the second, or the other way around.
So here's what I have that works, but I'm wondering if there's a more elegant way to do this.
public string Get2LineDisplayText(string original)
{
string[] words = original.Split(new[] {' ', '\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
//Degenerate case with only 1 word
if (words.Length <= 1)
{
return original;
}
StringBuilder builder = new StringBuilder();
builder.Append(words[0]); //Add first word without prepending space
bool addedBr = false;
foreach (string word in words.Skip(1))
{
if (builder.Length + word.Length < original.Length / 2) //Word fits on the first line without passing halfway mark
{
builder.Append(' ' + word);
}
else if (!addedBr) //Adding word goes over half, need to see if it's more balanced on the 1st or 2nd line
{
int diffOnLine1 = Math.Abs((builder.Length + word.Length) - (original.Length - builder.Length - word.Length));
int diffOnLine2 = Math.Abs((builder.Length) - (original.Length - builder.Length));
if (diffOnLine1 < diffOnLine2)
{
builder.Append(' ' + word);
builder.Append("<br/>");
}
else
{
builder.Append("<br/>");
builder.Append(' ' + word);
}
addedBr = true;
}
else //Past halfway and already added linebreak, just append
{
builder.Append(' ' + word);
}
}
return builder.ToString();
}
Sample input/output: