// This method formats a sequence of words (Strings obtained from // an enumerator) into lines of text, padding the inter-word // gaps with extra spaces to obtain lines of length lineWidth, and // thus a straight right margin. // // There are the following exceptions: // * if a word is longer than lineWidth, it is put on a line by // itself (producing a line longer than lineWidth) // * a single word may appear on a line by itself (producing a line // shorter than lineWidth) if adding the next word to the line // would make the line longer than lineWidth // * the last line of the output is not padded with extra spaces. // // The algorithm for padding with extra spaces ensures that the // spaces are evenly distributed over inter-word gaps, using modulo // arithmetics. An Assert method call asserts that the resulting // output line has the correct length unless the line contains only // a single word or is the last line of the output. public static void Format(IEnumerator <String> words, int lineWidth, TextWriter tw) { lineWidth = Math.Max(0, lineWidth); WordList curLine = new WordList(); bool moreWords = words.MoveNext(); while (moreWords) { while (moreWords && curLine.Length < lineWidth) { String word = words.Current; if (word != null && word != "") { curLine.AddLast(word); } moreWords = words.MoveNext(); } int wordCount = curLine.Count; if (wordCount > 0) { int extraSpaces = lineWidth - curLine.Length; if (wordCount > 1 && extraSpaces < 0) // last word goes on next line { int lastWordLength = curLine.GetLast.Length; extraSpaces += 1 + lastWordLength; wordCount -= 1; } else if (!moreWords) // last line, do not pad { extraSpaces = 0; } // Pad inter-word space with evenly distributed extra blanks int holes = wordCount - 1; int spaces = holes / 2; StringBuilder sb = new StringBuilder(); sb.Append(curLine.RemoveFirst()); for (int i = 1; i < wordCount; i++) { spaces += extraSpaces; appendBlanks(sb, 1 + spaces / holes); spaces %= holes; sb.Append(curLine.RemoveFirst()); } String res = sb.ToString(); Debug.Assert(res.Length == lineWidth || wordCount == 1 || !moreWords); tw.WriteLine(res); } } tw.Flush(); }