Created
September 12, 2019 15:31
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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