Skip to content

Instantly share code, notes, and snippets.

@ha-yi
Created September 12, 2019 15:31
Show Gist options
  • Save ha-yi/2569d333f467360ed213ec55d814f417 to your computer and use it in GitHub Desktop.
Save ha-yi/2569d333f467360ed213ec55d814f417 to your computer and use it in GitHub Desktop.
This is an example of code to create a table like string with multiple lines. this is useful to create an invoice data before printing it into thermal printer
enum class Alignment {
CENTER, LEFT, RIGHT
}
class TextData {
var text: String = ""
var maxLength: Int = 0
var alignment: Alignment = Alignment.CENTER
}
fun main(vararg args: String) {
val data = format(
textData {
text = "99"
maxLength = 4
alignment = Alignment.CENTER
},
textData {
text = "x"
maxLength = 3
alignment = Alignment.CENTER
},
textData {
text = "900000900"
maxLength = 6
alignment = Alignment.CENTER
},
textData {
text = "="
maxLength = 3
alignment = Alignment.CENTER
},
textData {
text = "99"
maxLength = 6
alignment = Alignment.CENTER
}
)
println(data)
}
fun textData(init: TextData.() -> Unit): TextData = TextData().apply(init)
fun format(vararg data: TextData): String {
val lines = mutableListOf<String>()
// 1. process each data in argument
data.forEach {
// 2. chunk text into its maxLength (the result will be list)
it.text.chunked(it.maxLength)
// for each of chunked string
.forEachIndexed { index, str ->
// check if lines already added in these index, if not create line with empty string on it
if (lines.size <= index) {
lines.add("")
}
val dt = lines[index]
// now, prepare for alignment
var curline = when (it.alignment) {
Alignment.RIGHT -> str.padStart(it.maxLength) // add empty string before
Alignment.LEFT -> str.padEnd(it.maxLength) // add empty string after
else -> { // for center, divide into 2 part
val startPad = ((it.maxLength - str.length) / 2) + str.length
// add pad on start and end
val newStr = str.padStart(startPad).padEnd(it.maxLength)
// chunk if over sized
if (newStr.length > it.maxLength) {
newStr.chunked(it.maxLength).first()
} else {
newStr
}
}
}
// check if lines is blank (empty spaces)
curline = if (dt.trim().isBlank()) {
// if blank add pad at first
curline.padStart(lines.first().length)
} else {
// if not blank add pad at the end
(dt + curline).padEnd(lines.first().length)
}
lines[index] = curline
}
// do cleanup, this is necessary if the current processed data is much lesser than the previous one
lines.forEachIndexed { index, s ->
lines[index] = s.padEnd(lines.first().length)
}
}
// finally wrap it up in a string
var result = ""
lines.forEach { s ->
result += s + "\n"
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment