d-examples/source/examples/common/splittext.d

93 lines
3.6 KiB
D
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module examples.common.splittext;
import std.conv : to;
import std.uni : isWhite;
import std.array : split;
import std.stdio : writeln;
private dstring[] splitText(string[] text, size_t length = 50) {
// Инициализация массива для хранения результата
dstring[] result;
// Перебор каждой строки входного текста
foreach (line; text) {
// Преобразование строки в dstring для поддержки Unicode
dstring lineD = line.to!dstring;
// Разделение строки на слова по пробелам
dstring[] words = lineD.split();
// Если строка пустая или содержит только пробелы, добавляем пустую строку
if (!words.length) {
result ~= "";
continue;
}
// Инициализация текущей строки для сборки результата
dstring currentLine;
// Проверка, начинается ли строка с пробела, и добавление пробела к первому слову
if (isWhite(lineD[0])) {
words[0] = ' ' ~ words[0];
}
// Перебор всех слов в строке
foreach (idx, word; words) {
// Если слово длиннее максимальной длины строки
if (word.length > length) {
// Начальная позиция для разбиения слова
size_t start = 0;
// Разбиение длинного слова на части
while (start < word.length) {
// Вычисление конца текущего фрагмента слова
size_t end = start + length;
if (end > word.length) end = word.length;
// Если добавление фрагмента превысит длину строки
if (currentLine.length + (end - start) > length) {
// Сохраняем текущую строку и начинаем новую с фрагмента слова
result ~= currentLine;
currentLine = word[start .. end];
} else {
// Добавляем пробел, если текущая строка не пуста
if (currentLine.length) {
currentLine ~= " ";
}
// Добавляем фрагмент слова к текущей строке
currentLine ~= word[start .. end];
}
// Сдвигаем начальную позицию для следующего фрагмента
start += length;
}
} else {
// Если добавление слова (и пробела, если нужно) превысит длину строки
if (currentLine.length + word.length + (currentLine.length ? 1 : 0) > length) {
// Сохраняем текущую строку и начинаем новую со слова
result ~= currentLine;
currentLine = word;
} else {
// Добавляем пробел, если текущая строка не пуста
if (currentLine.length) {
currentLine ~= ' ';
}
// Добавляем слово к текущей строке
currentLine ~= word;
}
}
}
// Если текущая строка не пуста, добавляем её в результат
if (currentLine.length) {
result ~= currentLine;
}
}
// Возвращаем массив строк с учётом ограничения длины
return result;
}
void formatLines() {
auto lines = [" Hello world this is a very long line", " Another line"];
foreach (line; splitText(lines, 10)) {
writeln(line);
}
}