private static string SmartSplit(string text, uint columnWidth, ref int offset, SmartSplitSettings smartSplitSettings) { // TODO: smart-split, but that would require to know something about column content type (add hyphen in text, just break inside identifiers or numbers... // TODO: use Humanizer library perhaps? throw new NotImplementedException(); }
/// <summary> /// Splits text into lines that fit into designated column width /// </summary> /// <param name="text">Text to split</param> /// <param name="columnWidth">Area width to fit the string</param> /// <param name="smartSplitSettings">(Not implemented yet)</param> /// <returns>Text splinted into matching pieces.</returns> /// <remarks>Based on this imperfect solution for now: http://stackoverflow.com/a/1678162 /// This will not work properly for long "words" (and nicely for very narrow columns - do not expect miracles). /// This is not able to properly break the "words" in the middle to optimize space... /// </remarks> public static IEnumerable <string> SplitTextToFit(this string text, uint columnWidth, SmartSplitSettings smartSplitSettings = null) { text.Requires(nameof(text)).IsNotNull(); columnWidth.Requires(nameof(columnWidth)).IsGreaterOrEqual(MIN_FIT_AREA, $"This is just plain nonsense - area to fit text into must be at least {MIN_FIT_AREA} characters wide."); if (text == string.Empty) { yield return(string.Empty); yield break; } int offset = 0; while (offset < text.Length) { if (offset + (int)columnWidth < text.Length) { // TODO: do better splitting and cleaning of white spaces / keeping punctuation.... int index = text.LastIndexOfAny(SplitMatches, Math.Min(text.Length, offset + (int)columnWidth)); if (index > 0 && index >= offset) { if (index < 0 || text[index] == ' ') { string line = text.Substring(offset, (index - offset <= 0 ? text.Length : index) - offset); offset += line.Length + 1; yield return(line); } else { // keep punctuation character in upper line int cutLen = (index - offset <= 0 ? text.Length : index) - offset + 1; if (cutLen > columnWidth) { cutLen = (int)columnWidth; } string line = text.Substring(offset, cutLen); offset += line.Length; yield return(line); } } else { // split in the middle of long, unbreakable text if (smartSplitSettings != null) { yield return(SmartSplit(text, columnWidth, ref offset, smartSplitSettings)); } else { yield return(BruteSplit(text, columnWidth, ref offset)); } } } else { yield return(text.Substring(offset)); yield break; } } }