// SPDX-License-Identifier: BSD-3-Clause package org.islandoftex.arara.utils import kotlin.math.ceil /** * Abbreviate a String to a maximal width. * * @param maxWidth The maximal width to truncate to. * @param ellipsis The string to use to indicate an ellipsis. * @throws IllegalArgumentException If the string would consist only of the * ellipsis after shortening. * @return The abbreviated string. */ @Throws(IllegalArgumentException::class) fun String.abbreviate(maxWidth: Int, ellipsis: String = "…"): String { return when { maxWidth < ellipsis.length + 1 -> throw IllegalArgumentException("Can't abbreviate text further") this.length < maxWidth -> this else -> this.substring(0, maxWidth - ellipsis.length) + ellipsis } } /** * Center a string within a specified number of columns. * * This does not center anything if the string is longer than the specified * width. * * @param width The number of columns. * @param padChar The char to pad with. * @return The padded string. */ fun String.center(width: Int, padChar: Char): String { return if (this.length > width) this else { val charsLeft = width - this.length padChar.toString().repeat(charsLeft / 2) + this + padChar.toString().repeat(ceil(charsLeft.toDouble() / 2.0).toInt()) } } /** * Wrap text at a specified width. * * Algorithm from Wikipedia: * https://en.wikipedia.org/wiki/Line_wrap_and_word_wrap#Minimum_number_of_lines * * @param width The width to wrap at. * @return Wrapped text. */ fun String.wrap(width: Int): String { val words = this.split(" ") var wrapped = words[0] var spaceLeft = width - wrapped.length words.drop(1).forEach { val len = it.length wrapped += if (len + 1 > spaceLeft) { spaceLeft = width - len "\n$it" } else { spaceLeft -= len + 1 " $it" } } return wrapped }