diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt index f72e45c..412c3d0 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/BarCode.kt @@ -20,7 +20,7 @@ internal data class BarCode( } override val command: CharSequence = "^B1" - override val parameters: LinkedHashMap = linkedMapOf( + override val parameters: Map = addParameters( "o" to orientation.code, "c" to checkDigit.toString(), "h" to height, diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt index 09f2d79..4632a77 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldBlock.kt @@ -18,7 +18,7 @@ internal data class FieldBlock( } override val command: CharSequence = "^FB" - override val parameters: LinkedHashMap = linkedMapOf( + override val parameters: Map = addParameters( "w" to width, "l" to maxLines, "s" to lineSpacing, @@ -58,7 +58,7 @@ fun ZplBuilder.fieldBlock( * @param x horizontal position of fieldBlock * @param y vertical position of fieldBlock * @param width The width of the text block. - * @param data content of block + * @param data content of block. Any newlines are substituted with \& * @param maxLines The number of lines in the text block. * @param lineSpacing The space between lines. * @param alignment The text alignment within the block. diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt index 8ca4dee..cb05247 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldData.kt @@ -4,7 +4,22 @@ import com.sainsburys.k2zpl.builder.ZplBuilder internal data class FieldData(val data: String) : ZplCommand { override val command: CharSequence = "^FD" - override val parameters: LinkedHashMap = linkedMapOf("d" to data) + override val parameters: Map = addParameters("d" to data) + + override fun build(stringBuilder: StringBuilder): StringBuilder { + return stringBuilder + .append(command) + .append( + (parameters["d"] as? CharSequence).convertNewlines() + ) + } + + private fun CharSequence?.convertNewlines(): String { + return when { + this == null -> "" + else -> toString().replace("\n", "\\&") + } + } } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt index d22af97..1321442 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/FieldOrigin.kt @@ -14,11 +14,11 @@ internal data class FieldOrigin( } override val command: CharSequence = "^FO" - override val parameters: LinkedHashMap = buildLinkedMap { - put("x", x) - put("y", y) - put("j", justification) - } + override val parameters: Map = addParameters( + "x" to x, + "y" to y, + "j" to justification + ) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt index 4a878cb..11e6708 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/Font.kt @@ -17,8 +17,8 @@ internal data class Font( } override val command: CharSequence = "^A${font}" - override val parameters: LinkedHashMap = - linkedMapOf("o" to orientation, "h" to height, "w" to width) + override val parameters: Map = + addParameters("o" to orientation, "h" to height, "w" to width) } diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt index 9aefa42..092318c 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicBox.kt @@ -18,12 +18,13 @@ internal data class GraphicBox( } override val command: CharSequence = "^GB" - override val parameters: LinkedHashMap = - buildLinkedMap { - putAll( - mapOf("w" to width, "h" to height, "t" to thickness, "c" to color.code, "r" to rounding) - ) - } + override val parameters: Map = + addParameters( + "w" to width, + "h" to height, + "t" to thickness, "c" to color.code, + "r" to rounding + ) } /** @@ -41,13 +42,15 @@ fun ZplBuilder.graphicBox( color: ZplLineColor = ZplLineColor.BLACK, rounding: Int = 0 ) { - command(GraphicBox( - width = width, - height = height, - thickness = thickness, - color = color, - rounding = rounding - )) + command( + GraphicBox( + width = width, + height = height, + thickness = thickness, + color = color, + rounding = rounding + ) + ) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt index 4fd33c2..1790078 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/GraphicField.kt @@ -17,7 +17,7 @@ internal data class GraphicField( } override val command: CharSequence = "^GF" - override val parameters: LinkedHashMap = linkedMapOf( + override val parameters: Map = addParameters( "f" to format, "db" to dataBytes, "tb" to totalBytes, diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt index 30e02c1..2d48acf 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelHome.kt @@ -4,7 +4,7 @@ import com.sainsburys.k2zpl.builder.ZplBuilder internal data class LabelHome(val x: Int, val y: Int) : ZplCommand { override val command: CharSequence = "^LH" - override val parameters: LinkedHashMap = linkedMapOf("x" to x, "y" to y) + override val parameters: Map = addParameters("x" to x, "y" to y) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt index 685502e..94df7d7 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/LabelLength.kt @@ -8,7 +8,7 @@ internal data class LabelLength(val length: Int) : ZplCommand { } override val command: CharSequence = "^LL" - override val parameters: LinkedHashMap = linkedMapOf("l" to length) + override val parameters: Map = addParameters("l" to length) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt index 1e06fd4..15d7e4d 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/MediaMode.kt @@ -10,8 +10,8 @@ internal data class MediaMode( val prePeelSelect: ZplYesNo ) : ZplCommand { override val command: CharSequence = "^MM" - override val parameters: LinkedHashMap = - linkedMapOf("m" to mediaMode, "p" to prePeelSelect) + override val parameters: Map = + addParameters("m" to mediaMode, "p" to prePeelSelect) } /** diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt index f27ec33..4fa69f5 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/PrintWidth.kt @@ -8,7 +8,7 @@ internal data class PrintWidth(val width: Int) : ZplCommand { } override val command: CharSequence = "^PW" - override val parameters: LinkedHashMap = linkedMapOf("w" to width) + override val parameters: Map = addParameters("w" to width) } diff --git a/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt b/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt index c406504..ec45921 100644 --- a/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt +++ b/src/main/kotlin/com/sainsburys/k2zpl/command/ZplCommand.kt @@ -2,7 +2,7 @@ package com.sainsburys.k2zpl.command interface ZplCommand { val command: CharSequence - val parameters: LinkedHashMap get() = linkedMapOf() + val parameters: Map get() = addParameters() fun build(stringBuilder: StringBuilder) = stringBuilder.apply { append(command) with(parameters.values.iterator()) { @@ -25,5 +25,8 @@ private fun Iterator.nextNotNull(block: (T) -> Unit) { next()?.let { block(it) } } -internal fun buildLinkedMap(block: LinkedHashMap.() -> Unit) = - linkedMapOf().apply(block) \ No newline at end of file +/** + * A shortcut to adding parameters that helps to enforce use of [LinkedHashMap] + * so that entry order is preserved. + */ +internal fun ZplCommand.addParameters(vararg pairs: Pair) = linkedMapOf(*pairs) diff --git a/src/test/kotlin/com/sainsburys/k2zpl/command/FieldDataTest.kt b/src/test/kotlin/com/sainsburys/k2zpl/command/FieldDataTest.kt index ab55f0f..9514cf8 100644 --- a/src/test/kotlin/com/sainsburys/k2zpl/command/FieldDataTest.kt +++ b/src/test/kotlin/com/sainsburys/k2zpl/command/FieldDataTest.kt @@ -23,5 +23,23 @@ class FieldDataTest : DescribeSpec({ } result shouldBe "^FDsome-other-data\n" } + it("outputs correct command using raw string") { + val result = k2zpl { + val data = + """ + some data + with line breaks + + """.trimIndent() + fieldData(data = data) + } + result shouldBe "^FDsome data\\&with line breaks\\&\n" + } + it("outputs correct command using string") { + val result = k2zpl { + fieldData(data = "some data\nwith line breaks\n") + } + result shouldBe "^FDsome data\\&with line breaks\\&\n" + } } }) \ No newline at end of file diff --git a/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt b/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt index 6a15748..0046bb5 100644 --- a/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt +++ b/src/test/kotlin/com/sainsburys/k2zpl/command/ZplCommandTest.kt @@ -33,28 +33,31 @@ class ZplCommandWithoutParameters : ZplCommand { class ZplCommandWithOneParameter : ZplCommand { override val command = "^ZCP" - override val parameters: LinkedHashMap = buildLinkedMap { - putAll(mapOf("param-one" to "value-one")) - } + override val parameters: Map = addParameters( + "param-one" to "value-one" + ) } class ZplCommandWithMultipleParameters : ZplCommand { override val command = "^ZCPS" - override val parameters: LinkedHashMap = buildLinkedMap { - putAll(mapOf("param-one" to "value-one", "param-two" to "value-two")) - } + override val parameters: Map = addParameters( + "param-one" to "value-one", + "param-two" to "value-two" + ) } class ZplCommandWitNullFirstParameter : ZplCommand { override val command = "^ZCPN" - override val parameters: LinkedHashMap = buildLinkedMap { - putAll(mapOf("param-one" to null, "param-two" to "value-two")) - } + override val parameters: Map = addParameters( + "param-one" to null, + "param-two" to "value-two" + ) } class ZplCommandWitNullSecondParameter : ZplCommand { override val command = "^ZCPNS" - override val parameters: LinkedHashMap = buildLinkedMap { - putAll(mapOf("param-one" to "value-one", "param-two" to null)) - } + override val parameters: Map = addParameters( + "param-one" to "value-one", + "param-two" to null + ) } \ No newline at end of file