Skip to content

Commit

Permalink
Started implementing labels layer. Added label implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
kemkriszt committed Jan 2, 2024
1 parent f457da2 commit 0359dc4
Show file tree
Hide file tree
Showing 16 changed files with 194 additions and 25 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Label Print
# Label Printer

> :warning: `label-printer` is still under heavy development and is subject to frequent API changes
This package provides a js based implementation for variouse languages used for label printers

Expand Down
16 changes: 16 additions & 0 deletions src/commands/CommandGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { UnitSystem } from "..";
import Command from "./Command";
import CommandGroup from "./CommandGroup";
import { LabelDirection } from "./tspl";

/**
* Interface that should be implemented by a command generator object for each language
*/
export default interface CommandGenerator<T extends Command> {
commandGroup: (commands: T[]) => CommandGroup<T>
print: (sets: number, copiesPerSet: number) => T
/**
* This should generate the needed commands to set up a label before printing
*/
setUp: (width: number, height: number, gap: number, offset: number, direction: LabelDirection, mirror: boolean, unitSystem: UnitSystem) => T
}
1 change: 1 addition & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export { default as Command } from "./Command"
export { default as CommandGroup } from "./CommandGroup"

export type PrinterLanguage = "tspl"
export type UnitSystem = "imperial"|"metric"|"dot"

export * as tspl from "./tspl"
31 changes: 31 additions & 0 deletions src/commands/tspl/TSPLCommandGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { UnitSystem } from "..";
import CommandGenerator from "../CommandGenerator";
import TSPLCommand from "./TSPLCommand";
import { TSPLCLSCommand, TSPLCommandGroup, TSPLDirectionCommand, TSPLGapCommand, TSPLPrintCommand, TSPLSizeCommand } from "./commands";
import { LabelDirection } from "./types";

/**
* Command generator for tspl commands
*/
class TSPLCommandGenerator implements CommandGenerator<TSPLCommand> {
commandGroup(commands: TSPLCommand[]) {
return new TSPLCommandGroup(commands)
}

print(sets: number, copiesPerSet: number): TSPLCommand {
return new TSPLPrintCommand(sets, copiesPerSet)
}

setUp(width: number, height: number, gap: number, offset: number, direction: LabelDirection, mirror: boolean = false, unitSystem: UnitSystem): TSPLCommand {
const commands = [
new TSPLSizeCommand(width, height, unitSystem),
new TSPLGapCommand(gap, offset, unitSystem),
new TSPLDirectionCommand(direction, mirror),
new TSPLCLSCommand()
]

return new TSPLCommandGroup(commands)
}
}

export default new TSPLCommandGenerator()
3 changes: 2 additions & 1 deletion src/commands/tspl/commands/basic/TSPLDirectionCommand.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import TSPLCommand from "../../TSPLCommand";
import { LabelDirection } from "../../types";

/**
* This command defines in which direction will the label be printed and wether or not to mirror the image
Expand All @@ -12,7 +13,7 @@ export default class TSPLDirectionCommand extends TSPLCommand {
* @param direction Controls the orientation of the resulting label compared to the printer
* @param mirror Controls mirroring relative to the center line of the label perpendicular to the printhead. See the documentsion for examples
*/
constructor(direction: "normal"|"inverse", mirror?: boolean) {
constructor(direction: LabelDirection, mirror?: boolean) {
super()
this.direction = direction == "normal" ? 1 : 0
this.mirror = mirror ? 1 : 0
Expand Down
13 changes: 3 additions & 10 deletions src/commands/tspl/commands/basic/TSPLGapCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { valueWithUnit } from "@/helpers/UnitUtils";
import TSPLCommand from "../../TSPLCommand";
import { UnitSystem } from "../../types";
import { UnitSystem } from "@/commands";

/**
* Defines the gap between two labels
Expand All @@ -25,14 +26,6 @@ export default class TSPLGapCommand extends TSPLCommand {
}

get commandString(): string {
return `GAP ${this.valueWithUnit(this.gap)}, ${this.valueWithUnit(this.offset)}`
}

private valueWithUnit(value: number) {
switch(this.unitSystem) {
case "dot": return `${value} dot`
case "imperial": return value
case "metric": return `${value} mm`
}
return `GAP ${valueWithUnit(this.gap, this.unitSystem)}, ${valueWithUnit(this.offset, this.unitSystem)}`
}
}
13 changes: 3 additions & 10 deletions src/commands/tspl/commands/basic/TSPLSizeCommand.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { valueWithUnit } from "@/helpers/UnitUtils";
import TSPLCommand from "../../TSPLCommand";
import { UnitSystem } from "../../types";
import { UnitSystem } from "@/commands";

/**
* Defines the size of the label to rpint
Expand All @@ -24,14 +25,6 @@ export default class TSPLSizeCommand extends TSPLCommand {
}

get commandString(): string {
return `SIZE ${this.valueWithUnit(this.width)}, ${this.valueWithUnit(this.height)}`
}

private valueWithUnit(value: number) {
switch(this.unitSystem) {
case "dot": return `${value} dot`
case "imperial": return value
case "metric": return `${value} mm`
}
return `SIZE ${valueWithUnit(this.width, this.unitSystem)}, ${valueWithUnit(this.height, this.unitSystem)}`
}
}
1 change: 1 addition & 0 deletions src/commands/tspl/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as TSPLCommand } from "./TSPLCommand"
export { default as commandGenerator } from "./TSPLCommandGenerator"

export * from "./commands"
export * from "./types"
2 changes: 1 addition & 1 deletion src/commands/tspl/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const alignmentToNumber = (alignment: Alignment): 0|1|2|3 => {
* on the values
*/
export type GraphicMode = "overwrite"|"or"|"xor"
export type UnitSystem = "imperial"|"metric"|"dot"
export type LabelDirection = "normal"|"inverse"
export type ECCLevel = "L"|"M"|"Q"|"H"
export type AutoManual = "A"|"M"
export type QRModel = "M1"|"M2"
Expand Down
9 changes: 9 additions & 0 deletions src/helpers/UnitUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { UnitSystem } from "@/commands"

export function valueWithUnit(value: number, unitSystem: UnitSystem) {
switch(unitSystem) {
case "dot": return `${value} dot`
case "imperial": return value
case "metric": return `${value} mm`
}
}
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * as commands from "./commands"
export * as printers from "./printers"
export * from "./commands"
export * from "./printers"
export * from "./labels"
78 changes: 78 additions & 0 deletions src/labels/Label.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Command, PrinterLanguage } from "@/commands";
import Printable from "./Printable";
import { UnitSystem } from "@/commands";
import { LabelDirection } from "@/commands/tspl";
import LabelField from "./fields/LabelField";

/**
* Holds the content of a label and handles printing
*/
export default class Label extends Printable {
/**
* Width of label in dots, mm or inch
*/
private readonly width: number
/**
* Height of label in dots, mm or inch
*/
private readonly height: number

/**
* Units for width, height, gap and offset
*/
private readonly unitSystem: UnitSystem


constructor(width: number, height: number, dimensionUnit: UnitSystem = "metric") {
super()
this.width = width
this.height = height
this.unitSystem = dimensionUnit
}

/**
* List of fields on the label
*/
private fields: LabelField[] = []

async commandForLanguage(language: PrinterLanguage): Promise<Command> {
const commandList = await Promise.all(this.fields.map(field => field.commandForLanguage(language)))
return this.commandGeneratorFor(language).commandGroup(commandList)
}

add(field: LabelField) {
this.fields.push(field)
}

/**
* Generate a command that is complete for printing
* @param language Printing language to use
* @param gap Distance between two labels. It is measured between the two points where the sensor
* leaves the label and enters the next one
* @param direction Direction relative to printing direction. See documentation for more details
* @param sets Number of sets to print. If you have counters for example, it will not change in a set
* @param copiesPerSet Number of labels per set
* @param mirror Mirror the label along the vertical axis
* @param gapOffset Used with non uniform shaped labels. Is the distance between the point where the sensor leaves the label and the
* furthest point of the label in the direction of printing. Check documentation for more info
* TODO: Is this too TSPL Specific?
*/
async fullPrintCommand(language: PrinterLanguage,
gap: number,
direction: LabelDirection,
sets: number,
copiesPerSet: number = 1,
mirror: boolean = false,
gapOffset: number = 0
): Promise<Command> {

const generator = this.commandGeneratorFor(language)
const commands = [
...generator.setUp(this.width, this.height, gap, gapOffset, direction, mirror, this.unitSystem),
this.commandForLanguage(language),
generator.print(sets, copiesPerSet)
]

return generator.commandGroup(commands)
}
}
34 changes: 34 additions & 0 deletions src/labels/Printable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Command, PrinterLanguage, tspl } from "@/commands";
import CommandGenerator from "@/commands/CommandGenerator";
import { Printer } from "@/printers";

/**
* A component that can be directly printed to label printer
*/
export default abstract class Printable {
/**
* Generates a printable command
* @param language The printing language that should be used
* @returns A promise of a command that can be printed
*/
abstract commandForLanguage(language: PrinterLanguage): Promise<Command>

/**
* Generates printable command for the given printer. Can be used to obtain a command for fields supported by the package then customizing it before printing
* @param printer Printer to generate the command. Important because the command is printer language specific
* @returns A promise for a command. Most commands are syncronouse but some may require to access async resources
*/
async commandForPrinter(printer: Printer): Promise<Command> {
return await this.commandForLanguage(printer.language)
}

/**
* Obtain a command generator for the given language
* @param language Language to get generator for
*/
protected commandGeneratorFor(language: PrinterLanguage): CommandGenerator<any> {
switch(language) {
case "tspl": return tspl.commandGenerator
}
}
}
5 changes: 5 additions & 0 deletions src/labels/fields/LabelField.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Printable from "../Printable";

export default abstract class LabelField extends Printable {

}
1 change: 1 addition & 0 deletions src/labels/fields/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./LabelField"
3 changes: 3 additions & 0 deletions src/labels/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as Label } from "./Label"
export * from "./fields"
export * from "./types"

0 comments on commit 0359dc4

Please sign in to comment.