{
  "schemaVersion": 1,
  "language": "tspl",
  "name": "TSPL",
  "fullName": "TSC Printer Language",
  "canonicalUrl": "https://rfid.me/reference/tspl/",
  "reuseNotice": "No reuse license is granted by this export. Consult the upstream package or repository terms before reusing the data.",
  "commandCount": 67,
  "commands": [
    {
      "command": "CLS",
      "name": "Clear Image Buffer",
      "description": "Clears the image buffer before drawing a new label. Think of it as pressing \"New Document\" — it erases any previous content so you start fresh. Every label should begin with CLS after SIZE and GAP.",
      "category": "control",
      "syntax": "CLS",
      "parameters": [],
      "whenToUse": "Always. Place it after SIZE and GAP to ensure a clean canvas before drawing.",
      "example": {
        "source": "SIZE 100 mm, 60 mm\nGAP 3 mm, 0 mm\nCLS\nTEXT 50,30,\"4\",0,1,1,\"Hello\"\nPRINT 1",
        "description": "Clear the buffer before drawing a label"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/cls/"
    },
    {
      "command": "PRINT",
      "name": "Print Label",
      "description": "Triggers printing of the label. The first parameter sets the number of label sets; the optional second sets the number of copies per set. This is always the last command in a TSPL label — like pressing \"Print\".",
      "category": "control",
      "syntax": "PRINT qty[,copies]",
      "parameters": [
        {
          "name": "qty",
          "description": "Number of label sets to print (1-999999)"
        },
        {
          "name": "copies",
          "description": "Number of copies per set (optional, default 1)"
        }
      ],
      "whenToUse": "Always. It is the very last command in every label. Without PRINT, nothing comes out of the printer.",
      "example": {
        "source": "SIZE 100 mm, 60 mm\nGAP 3 mm, 0 mm\nCLS\nTEXT 50,30,\"4\",0,1,1,\"Hello\"\nPRINT 1",
        "description": "Print one copy of the label"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/print/"
    },
    {
      "command": "FEED",
      "name": "Feed Label",
      "description": "Feeds the label stock forward by the specified number of dots. Useful for advancing past a label without printing, or for calibration.",
      "category": "control",
      "syntax": "FEED n",
      "parameters": [
        {
          "name": "n",
          "description": "Number of dots to feed forward"
        }
      ],
      "whenToUse": "When you need to advance the media without printing — calibration, alignment, or skipping labels.",
      "example": {
        "source": "FEED 100",
        "description": "Advance media by 100 dots"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/feed/"
    },
    {
      "command": "BACKFEED",
      "name": "Backfeed Label",
      "description": "Feeds the media backward by `n` dots (TSPL2 PG §BACKFEED p22–23). Range 1–9999. Used to retract the label after printing so the tear-off or cutter position is correct. TSPL printers use the alias `BACKUP n` for the same semantic (BACKFEED is the TSPL2 spelling; BACKUP is the older TSPL one). Conversion: at 200 DPI, 1 mm = 8 dots; at 300 DPI, 1 mm = 12 dots. ⚠️ Inappropriate values can cause paper jam or media wrinkle.",
      "category": "control",
      "syntax": "BACKFEED n",
      "parameters": [
        {
          "name": "n",
          "description": "Number of dots to back-feed (1–9999). Convert from mm: ×8 for 200 DPI printers, ×12 for 300 DPI."
        }
      ],
      "whenToUse": "With tear-off or cutter modes when the label needs to retract to the correct tear/cut position after each print.",
      "example": {
        "source": "SIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Cut after\"\nPRINT 1\nBACKFEED 50",
        "description": "Retract media by 50 dots after printing to align with the cutter"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/backfeed/"
    },
    {
      "command": "FORMFEED",
      "name": "Form Feed",
      "description": "Advances the media to the start of the next label (TSPL2 PG §FORMFEED p24). The printer uses the GAP or BLINE sensor to detect the boundary and stops there. Takes no parameters. Runtime hardware behaviour; no SVG rendering effect.",
      "category": "control",
      "syntax": "FORMFEED",
      "parameters": [],
      "whenToUse": "When you need to skip to the next label without printing — useful for alignment, skipping damaged labels, or as part of a counter-driven sequence (the PG example chains FORMFEED with SET COUNTER, BOX, TEXT, PRINT).",
      "example": {
        "source": "SIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Skip me\"\nFORMFEED\nPRINT 1",
        "description": "Skip the current label without printing, then print the next one"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/formfeed/"
    },
    {
      "command": "HOME",
      "name": "Home Position",
      "description": "Feeds the media until the internal sensor finds the next label origin (TSPL2 PG §HOME p25–26). Whether the printer back-feeds or feed-forwards to home depends on the per-model behaviour table on PG p25. Takes no parameters. ⚠️ `SIZE` and `GAP` (or `BLINE`) must have been issued first — HOME without prior geometry definition produces undefined behaviour. Runtime hardware behaviour; no SVG rendering effect.",
      "category": "control",
      "syntax": "HOME",
      "parameters": [],
      "whenToUse": "At the start of a print run after power-on or after manual media-load, so the printer knows where the first label begins.",
      "example": {
        "source": "SIZE 100 mm, 50 mm\nGAP 3 mm, 0 mm\nHOME\nCLS\nTEXT 50,30,\"3\",0,1,1,\"After homing\"\nPRINT 1",
        "description": "Calibrate to the first label position after defining geometry"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/home/"
    },
    {
      "command": "SELFTEST",
      "name": "Self-Test Page",
      "description": "Triggers the printer to print a diagnostic page covering its current configuration, firmware version, dot/line counters, and sensor state (TSPL2 PG §SELFTEST p31). Takes no parameters. Per-printer support table on PG p31 lists which TTP / TDP / M23 series models honour the command. Runtime hardware behaviour; the playground can't simulate a real self-test page (output depends on live printer state and counters).",
      "category": "control",
      "syntax": "SELFTEST",
      "parameters": [],
      "whenToUse": "Standalone diagnostic command — issue when you need to confirm printer settings, firmware, and sensor health without going through the front-panel menu.",
      "example": {
        "source": "SELFTEST",
        "description": "Print a self-test diagnostic page"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/selftest/"
    },
    {
      "command": "INITIALPRINTER",
      "name": "Factory Reset",
      "description": "⚠️ Factory-reset opcode — clears all `SET *` settings, downloaded fonts/images, and stored programs. Takes no parameters. Not in the 2009 TSPL2 PG; appears in later TSC firmware addenda for the TX/TE/MH-series. On models that don't expose the opcode, the equivalent recovery procedure is \"hold FEED during power-on\" (per the DOWNLOAD section's AUTO.BAS-disable note on PG p81). Runtime hardware behaviour; no SVG rendering effect. Use with care — this is destructive and irreversible.",
      "category": "control",
      "syntax": "INITIALPRINTER",
      "parameters": [],
      "whenToUse": "When you need to wipe a printer back to factory defaults — typically before re-deploying to a new site, or when troubleshooting requires a clean baseline. Avoid placing in production label scripts.",
      "example": {
        "source": "INITIALPRINTER",
        "description": "Reset printer to factory defaults (clears SET settings, downloaded fonts, stored programs)"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/initialprinter/"
    },
    {
      "command": "EOP",
      "name": "End of Program",
      "description": "Marks the end of a stored program. When downloading label templates to the printer's memory, EOP signals where the program ends.",
      "category": "control",
      "syntax": "EOP",
      "parameters": [],
      "whenToUse": "When storing label templates in the printer's flash memory using DOWNLOAD.",
      "example": {
        "source": "DOWNLOAD \"LABEL.BAS\"\nSIZE 100 mm, 60 mm\nGAP 3 mm, 0 mm\nCLS\nTEXT 50,30,\"4\",0,1,1,\"Stored\"\nPRINT 1\nEOP",
        "description": "Store a label program in the printer"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/eop/"
    },
    {
      "command": "SIZE",
      "name": "Label Size",
      "description": "Sets the width and height of the label. You can specify the dimensions in mm (millimetres) or inch. This must be the first configuration command — it tells the printer how big the label is.",
      "category": "label",
      "syntax": "SIZE w [unit], h [unit]",
      "parameters": [
        {
          "name": "w",
          "description": "Label width (numeric value)"
        },
        {
          "name": "h",
          "description": "Label height (numeric value)"
        },
        {
          "name": "unit",
          "description": "Unit: mm or inch (optional, default is mm)"
        }
      ],
      "whenToUse": "Always. It is the very first command in every TSPL label. Without SIZE, the printer does not know the label dimensions.",
      "example": {
        "source": "SIZE 100 mm, 60 mm",
        "description": "Set label size to 100mm wide by 60mm tall"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/size/"
    },
    {
      "command": "GAP",
      "name": "Gap Distance",
      "description": "Sets the gap distance between labels and the offset from the gap to the start of the printable area. The gap is the transparent space between die-cut labels on a roll.",
      "category": "label",
      "syntax": "GAP gap [unit], offset [unit]",
      "parameters": [
        {
          "name": "gap",
          "description": "Gap distance between labels"
        },
        {
          "name": "offset",
          "description": "Offset from gap edge to print area start"
        },
        {
          "name": "unit",
          "description": "Unit: mm or inch (optional, default is mm)"
        }
      ],
      "whenToUse": "Always for die-cut labels. Place it immediately after SIZE.",
      "example": {
        "source": "GAP 3 mm, 0 mm",
        "description": "Set 3mm gap between labels with no offset"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/gap/"
    },
    {
      "command": "BLINE",
      "name": "Black-Mark Media Mode",
      "description": "Configures black-mark media mode and extra-feeding offset (TSPL2 PG §BLINE p8). Used instead of GAP for continuous media with black registration marks printed on the backing. `m` is the height of the black mark (0–1 inch, or 0–25.4 mm). `n` is extra label-feeding length after the mark (0 to label-length; `0,0` = continuous label). Two forms: bare numbers = inches; numbers followed by ` mm` (with a leading space) = millimetres. ⚠️ When changing the sensor type from \"GAP\" to \"Black Mark\", BLINE **must** be sent to the printer first — before SIZE / GAP / TEXT. Engine-recognised but no visible SVG effect today (the playground treats labels as already-isolated).",
      "category": "label",
      "syntax": "BLINE m, n | BLINE m mm, n mm",
      "parameters": [
        {
          "name": "m",
          "description": "Black-mark height. Bare number = inches (0–1); followed by ` mm` (with leading space) = millimetres (0–25.4)."
        },
        {
          "name": "n",
          "description": "Extra label-feeding length after the black mark (0 to label-length; `0,0` means continuous label)."
        }
      ],
      "whenToUse": "When the deployed media uses black-mark registration on the backing rather than die-cut gaps. Issue once at the top of the label script, before any geometry-dependent commands.",
      "example": {
        "source": "BLINE 0.20, 0.50\nSIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Black-mark stock\"\nPRINT 1",
        "description": "Configure black-mark media (0.20 inch mark, 0.50 inch extra feed) before defining label geometry"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/bline/"
    },
    {
      "command": "REFERENCE",
      "name": "Reference Point",
      "description": "Sets the reference origin point for all coordinates on the label. All subsequent X,Y positions are relative to this point. It is like setting page margins — shifting the entire design.",
      "category": "label",
      "syntax": "REFERENCE x, y",
      "parameters": [
        {
          "name": "x",
          "description": "Horizontal reference offset in dots"
        },
        {
          "name": "y",
          "description": "Vertical reference offset in dots"
        }
      ],
      "whenToUse": "When you need to offset the entire label design, for example to account for pre-printed stock or to reposition a layout without changing every coordinate.",
      "example": {
        "source": "REFERENCE 10, 10",
        "description": "Offset all coordinates by 10 dots in both directions"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/reference/"
    },
    {
      "command": "DIRECTION",
      "name": "Print Direction",
      "description": "Sets the print direction. 0 = head moves forward (default), 1 = head moves backward. The optional second parameter mirrors the output.",
      "category": "label",
      "syntax": "DIRECTION n[,m]",
      "parameters": [
        {
          "name": "n",
          "description": "Direction: 0 (forward) or 1 (backward)"
        },
        {
          "name": "m",
          "description": "Mirror: 0 (normal) or 1 (mirror), optional"
        }
      ],
      "whenToUse": "When the label needs to print in a specific orientation — some applicator setups require reversed printing direction.",
      "example": {
        "source": "DIRECTION 0",
        "description": "Set forward print direction"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/direction/"
    },
    {
      "command": "OFFSET",
      "name": "Form-Feed Offset",
      "description": "⚠️ Despite the historical 'OFFSET' name, this is NOT a horizontal coordinate offset — for that, use REFERENCE (origin shift) or SHIFT (vertical translate). TSPL2 §OFFSET p9 defines it as the **selective extra label-feeding length** the printer takes on each form-feed, used in peel-off and cutter modes to adjust where the label stops. The printer back-tracks this extra length before the next print run. Range −1 ≤ m ≤ 1 (inch). Two forms: bare number = inches; followed by ` mm` (with leading space) = millimetres. ⚠️ An out-of-range or otherwise inappropriate value may cause a paper jam. Engine-recognised but no SVG effect today (playground does not simulate the feed/back-feed cycle).",
      "category": "label",
      "syntax": "OFFSET m | OFFSET m mm",
      "parameters": [
        {
          "name": "m",
          "description": "Extra feed distance. Bare number = inches (−1 to 1); followed by ` mm` (with leading space) = millimetres. Negative = back-feed (retract); positive = forward-feed."
        }
      ],
      "whenToUse": "Only with peel-off or cutter modes when the label stops a few mm short of (or past) the desired position after each print. Pair with `SET PEEL` or `SET CUTTER`.",
      "example": {
        "source": "SET PEEL ON\nOFFSET 0.1\nSIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Peel-mode label\"\nPRINT 1",
        "description": "Add 0.1 inch extra feeding on each form-feed in peel-off mode"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/offset/"
    },
    {
      "command": "TEXT",
      "name": "Text Field",
      "description": "Draws a text field at the specified position. You choose the font, rotation, and enlargement multipliers. TSPL combines position, font, and text data in a single command — unlike SBPL which uses separate commands for each.",
      "category": "text",
      "syntax": "TEXT x,y,\"font\",rotation,x-mul,y-mul,\"data\"",
      "parameters": [
        {
          "name": "x",
          "description": "Horizontal position in dots from the left edge"
        },
        {
          "name": "y",
          "description": "Vertical position in dots from the top edge"
        },
        {
          "name": "font",
          "description": "Font name: \"1\" (8x12), \"2\" (12x20), \"3\" (16x24), \"4\" (24x32), \"5\" (32x48), or TrueType name"
        },
        {
          "name": "rotation",
          "description": "0 (0 deg), 90, 180, or 270"
        },
        {
          "name": "x-mul",
          "description": "Horizontal enlargement (1-10)"
        },
        {
          "name": "y-mul",
          "description": "Vertical enlargement (1-10)"
        },
        {
          "name": "data",
          "description": "The text string to print (in double quotes)"
        }
      ],
      "whenToUse": "Whenever you need to print text on the label. This is the primary text command in TSPL.",
      "example": {
        "source": "TEXT 50,30,\"4\",0,1,1,\"Hello World\"",
        "description": "Print \"Hello World\" at position 50,30 using font 4"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/text/"
    },
    {
      "command": "BOX",
      "name": "Rectangle / Box",
      "description": "Draws a rectangle (box) from the top-left corner (x1,y1) to the bottom-right corner (x2,y2) with the specified line thickness. An optional radius parameter rounds the corners.",
      "category": "graphics",
      "syntax": "BOX x1,y1,x2,y2,thickness[,radius]",
      "parameters": [
        {
          "name": "x1",
          "description": "Top-left X coordinate in dots"
        },
        {
          "name": "y1",
          "description": "Top-left Y coordinate in dots"
        },
        {
          "name": "x2",
          "description": "Bottom-right X coordinate in dots"
        },
        {
          "name": "y2",
          "description": "Bottom-right Y coordinate in dots"
        },
        {
          "name": "thickness",
          "description": "Line thickness in dots"
        },
        {
          "name": "radius",
          "description": "Corner radius in dots (optional, default 0)"
        }
      ],
      "whenToUse": "For drawing borders, boxes, table cells, and rectangular frames on your label.",
      "example": {
        "source": "BOX 20,20,380,260,2",
        "description": "Draw a rectangle from (20,20) to (380,260) with 2-dot lines"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/box/"
    },
    {
      "command": "BAR",
      "name": "Filled Bar",
      "description": "Draws a filled rectangular bar (solid black) at the specified position with the given width and height. Use this for solid divider lines, section fills, or thick separators.",
      "category": "graphics",
      "syntax": "BAR x,y,width,height",
      "parameters": [
        {
          "name": "x",
          "description": "Left edge X coordinate in dots"
        },
        {
          "name": "y",
          "description": "Top edge Y coordinate in dots"
        },
        {
          "name": "width",
          "description": "Width of the bar in dots"
        },
        {
          "name": "height",
          "description": "Height of the bar in dots"
        }
      ],
      "whenToUse": "For solid lines, dividers, fills, and thick bars. A thin BAR (height=2) makes a clean divider line.",
      "example": {
        "source": "BAR 50,100,300,2",
        "description": "Draw a thin horizontal divider line at position (50,100)"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/bar/"
    },
    {
      "command": "REVERSE",
      "name": "Reverse Block",
      "description": "Inverts the specified rectangular area on the label — black becomes white and white becomes black. Use it over text to create white-on-black reversed text blocks.",
      "category": "graphics",
      "syntax": "REVERSE x,y,width,height",
      "parameters": [
        {
          "name": "x",
          "description": "Left edge X coordinate in dots"
        },
        {
          "name": "y",
          "description": "Top edge Y coordinate in dots"
        },
        {
          "name": "width",
          "description": "Width of the reversed area in dots"
        },
        {
          "name": "height",
          "description": "Height of the reversed area in dots"
        }
      ],
      "whenToUse": "When you want white text on a black background — draw the text first, then use REVERSE over the same area.",
      "example": {
        "source": "BAR 40,20,320,40\nTEXT 50,25,\"4\",0,1,1,\"CAUTION\"\nREVERSE 40,20,320,40",
        "description": "Create white-on-black \"CAUTION\" text"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/reverse/"
    },
    {
      "command": "ERASE",
      "name": "Erase Area",
      "description": "Erases (clears to white) the specified rectangular area in the image buffer. Anything previously drawn in that area is removed. Per TSPL2 PG §ERASE (p43); the PG's canonical example draws BAR 100,100,300,300 then ERASE 150,150,200,200 to carve a hole out of the centre — document order matters, since ERASE paints over earlier draw commands.",
      "category": "graphics",
      "syntax": "ERASE x,y,width,height",
      "parameters": [
        {
          "name": "x",
          "description": "Left edge X coordinate of the region in dots (TSPL2 PG: X_start)"
        },
        {
          "name": "y",
          "description": "Top edge Y coordinate of the region in dots (TSPL2 PG: Y_start)"
        },
        {
          "name": "width",
          "description": "Region width in the x-axis direction in dots (TSPL2 PG: X_width)"
        },
        {
          "name": "height",
          "description": "Region height in the y-axis direction in dots (TSPL2 PG: Y_height)"
        }
      ],
      "whenToUse": "When you need to clear a specific region of the label without clearing the entire buffer — carving holes, masking, or selective inverse of BAR. CLS clears the whole buffer; use ERASE for surgical strikes.",
      "example": {
        "source": "BAR 100,100,300,300\nERASE 150,150,200,200",
        "description": "Draw a 300x300 black bar at (100,100) then carve a 200x200 white hole out of its centre (TSPL2 PG §ERASE example)"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/erase/"
    },
    {
      "command": "DIAGONAL",
      "name": "Diagonal Line",
      "description": "Draws a straight line from (x1,y1) to (x2,y2) with the given stroke thickness. Useful for crosses, voided-label diagonals, and quick separator strokes.",
      "category": "graphics",
      "syntax": "DIAGONAL x1,y1,x2,y2,thickness",
      "parameters": [
        {
          "name": "x1",
          "description": "Start-point X coordinate in dots"
        },
        {
          "name": "y1",
          "description": "Start-point Y coordinate in dots"
        },
        {
          "name": "x2",
          "description": "End-point X coordinate in dots"
        },
        {
          "name": "y2",
          "description": "End-point Y coordinate in dots"
        },
        {
          "name": "thickness",
          "description": "Stroke thickness in dots"
        }
      ],
      "whenToUse": "When you need a single straight line at an arbitrary angle — a horizontal or vertical line is simpler with BAR.",
      "example": {
        "source": "DIAGONAL 50,50,300,200,3",
        "description": "Draw a 3-dot-thick line from (50,50) to (300,200)"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/diagonal/"
    },
    {
      "command": "BLOCK",
      "name": "Text Block (auto-wrap)",
      "description": "Draws a multi-line text block with automatic word-wrap inside a width × height bounding box. Like TEXT but words break at whitespace once they would exceed `width`, and the engine clips at `height` once `floor(height / fontHeight)` lines have been laid out. BLOCK is a TSPL2 firmware addendum (TX/TE/MH-series) — not in the 2009 PG.",
      "category": "graphics",
      "syntax": "BLOCK x,y,width,height,\"font\",rotation,x-mul,y-mul,\"data\"",
      "parameters": [
        {
          "name": "x",
          "description": "Top-left X coordinate of the bounding box in dots"
        },
        {
          "name": "y",
          "description": "Top-left Y coordinate of the bounding box in dots"
        },
        {
          "name": "width",
          "description": "Width of the wrap region in dots — words wrap when they would exceed this"
        },
        {
          "name": "height",
          "description": "Height of the wrap region in dots — clipped after floor(height/fontHeight) lines"
        },
        {
          "name": "font",
          "description": "Font identifier in double quotes (same set TEXT accepts: \"0\"–\"8\", \"ROMAN.TTF\", etc.)"
        },
        {
          "name": "rotation",
          "description": "0, 90, 180, or 270 degrees"
        },
        {
          "name": "x-mul",
          "description": "Horizontal magnification (1–10)"
        },
        {
          "name": "y-mul",
          "description": "Vertical magnification (1–10)"
        },
        {
          "name": "data",
          "description": "The text to render in double quotes; spaces are wrap points"
        }
      ],
      "whenToUse": "When you have variable-length text (description fields, multi-line addresses, product details) that needs to fit a fixed area without manual line-splitting. For single-line text use TEXT; for filled bars use BAR.",
      "example": {
        "source": "BLOCK 50,50,300,120,\"3\",0,1,1,\"Long description that wraps automatically\"",
        "description": "A 300×120 dot text block at (50,50), font \"3\", auto-wrapping the description"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/block/"
    },
    {
      "command": "CIRCLE",
      "name": "Circle",
      "description": "Draws a circle. (x,y) anchors the upper-left corner of the bounding box — not the centre — so the rendered centre lands at (x + diameter/2, y + diameter/2). Per TSPL2 PG §CIRCLE (p41).",
      "category": "graphics",
      "syntax": "CIRCLE x,y,diameter,thickness",
      "parameters": [
        {
          "name": "x",
          "description": "Upper-left X coordinate of the bounding box in dots (NOT the centre)"
        },
        {
          "name": "y",
          "description": "Upper-left Y coordinate of the bounding box in dots (NOT the centre)"
        },
        {
          "name": "diameter",
          "description": "Diameter of the circle in dots"
        },
        {
          "name": "thickness",
          "description": "Stroke thickness in dots; when ≥ radius the circle fills"
        }
      ],
      "whenToUse": "When you need a round outline on the label — logos, status dots, registration marks. For filled circles, set thickness ≥ radius; the renderer fills the shape.",
      "example": {
        "source": "CIRCLE 250,20,100,1",
        "description": "Draw a 100-dot-diameter circle anchored at (250,20) with a 1-dot outline (PG example)"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/circle/"
    },
    {
      "command": "ELLIPSE",
      "name": "Ellipse",
      "description": "Draws an ellipse inside a width × height bounding box. Like CIRCLE, (x,y) anchors the upper-left corner of the bounding box — not the centre — so the rendered centre lands at (x + width/2, y + height/2). ELLIPSE is a TSC firmware addendum (TX/TE/MH-series) — not in the 2009 TSPL2 PG.",
      "category": "graphics",
      "syntax": "ELLIPSE x,y,width,height,thickness",
      "parameters": [
        {
          "name": "x",
          "description": "Upper-left X coordinate of the bounding box in dots (NOT the centre)"
        },
        {
          "name": "y",
          "description": "Upper-left Y coordinate of the bounding box in dots (NOT the centre)"
        },
        {
          "name": "width",
          "description": "Width of the bounding box in dots"
        },
        {
          "name": "height",
          "description": "Height of the bounding box in dots"
        },
        {
          "name": "thickness",
          "description": "Stroke thickness in dots"
        }
      ],
      "whenToUse": "When you need an oval outline — chamfered seals, status indicators, decorative borders. For a true circle use CIRCLE (single diameter); ELLIPSE distinguishes horizontal and vertical radii.",
      "example": {
        "source": "ELLIPSE 100,100,200,150,3",
        "description": "Draw a 200×150 ellipse anchored at (100,100) with a 3-dot outline"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/ellipse/"
    },
    {
      "command": "BARCODE",
      "name": "1D Barcode",
      "description": "Draws a 1D barcode at the specified position. The \"type\" string selects the symbology — 30 values are valid per TSPL2 PG §BARCODE, covering Code 128, Code 39, EAN/UPC families, CODABAR, ITF, MSI, Plessey, and US/Chinese postal codes. The engine validates the type at parse time and emits a \"did you mean\" diagnostic on unknown values.",
      "category": "barcode",
      "syntax": "BARCODE x,y,\"type\",height,readable,rotation,narrow,wide,\"data\"",
      "parameters": [
        {
          "name": "x",
          "description": "Horizontal position in dots"
        },
        {
          "name": "y",
          "description": "Vertical position in dots"
        },
        {
          "name": "type",
          "description": "Barcode symbology. One of 30 values per TSPL2 PG §BARCODE p33–37.",
          "values": [
            {
              "value": "\"128\"",
              "description": "Code 128 (auto-subset)"
            },
            {
              "value": "\"128M\"",
              "description": "Code 128 manual subset selection"
            },
            {
              "value": "\"EAN128\"",
              "description": "GS1-128 (EAN-128) with FNC1"
            },
            {
              "value": "\"25\"",
              "description": "Interleaved 2 of 5 (I2of5)"
            },
            {
              "value": "\"25C\"",
              "description": "Interleaved 2 of 5 with mod-10 checksum"
            },
            {
              "value": "\"39\"",
              "description": "Code 39 (standard)"
            },
            {
              "value": "\"39C\"",
              "description": "Code 39 with mod-43 checksum"
            },
            {
              "value": "\"39S\"",
              "description": "Code 39 full ASCII"
            },
            {
              "value": "\"93\"",
              "description": "Code 93"
            },
            {
              "value": "\"EAN13\"",
              "description": "EAN-13"
            },
            {
              "value": "\"EAN13+2\"",
              "description": "EAN-13 with 2-digit add-on"
            },
            {
              "value": "\"EAN13+5\"",
              "description": "EAN-13 with 5-digit add-on"
            },
            {
              "value": "\"EAN8\"",
              "description": "EAN-8"
            },
            {
              "value": "\"EAN8+2\"",
              "description": "EAN-8 with 2-digit add-on"
            },
            {
              "value": "\"EAN8+5\"",
              "description": "EAN-8 with 5-digit add-on"
            },
            {
              "value": "\"CODA\"",
              "description": "Codabar"
            },
            {
              "value": "\"POST\"",
              "description": "USPS Postnet"
            },
            {
              "value": "\"UPCA\"",
              "description": "UPC-A"
            },
            {
              "value": "\"UPCA+2\"",
              "description": "UPC-A with 2-digit add-on"
            },
            {
              "value": "\"UPCA+5\"",
              "description": "UPC-A with 5-digit add-on"
            },
            {
              "value": "\"UPCE\"",
              "description": "UPC-E"
            },
            {
              "value": "\"UPCE+2\"",
              "description": "UPC-E with 2-digit add-on"
            },
            {
              "value": "\"UPCE+5\"",
              "description": "UPC-E with 5-digit add-on"
            },
            {
              "value": "\"CPOST\"",
              "description": "China Post 25"
            },
            {
              "value": "\"MSI\"",
              "description": "MSI Plessey"
            },
            {
              "value": "\"MSIC\"",
              "description": "MSI Plessey with mod-10 check digit"
            },
            {
              "value": "\"PLESSEY\"",
              "description": "Plessey (UK)"
            },
            {
              "value": "\"ITF14\"",
              "description": "ITF-14 (case/carton code)"
            },
            {
              "value": "\"EAN14\"",
              "description": "EAN-14 (DUN-14)"
            },
            {
              "value": "\"11\"",
              "description": "Code 11"
            }
          ]
        },
        {
          "name": "height",
          "description": "Barcode height in dots"
        },
        {
          "name": "readable",
          "description": "Human-readable text rendering mode",
          "values": [
            {
              "value": "0",
              "description": "No human-readable text"
            },
            {
              "value": "1",
              "description": "Text below the barcode"
            },
            {
              "value": "2",
              "description": "Text above the barcode"
            },
            {
              "value": "3",
              "description": "Text both above and below"
            }
          ]
        },
        {
          "name": "rotation",
          "description": "Rotation in degrees",
          "values": [
            {
              "value": "0",
              "description": "No rotation (left to right)"
            },
            {
              "value": "90",
              "description": "90° clockwise"
            },
            {
              "value": "180",
              "description": "180° (upside down)"
            },
            {
              "value": "270",
              "description": "270° clockwise (90° counter-clockwise)"
            }
          ]
        },
        {
          "name": "narrow",
          "description": "Narrow bar width in dots"
        },
        {
          "name": "wide",
          "description": "Wide bar width in dots"
        },
        {
          "name": "data",
          "description": "The data to encode (in double quotes)"
        }
      ],
      "whenToUse": "When you need any 1D barcode — shipping labels, product IDs, inventory tracking. Pick the symbology with the \"type\" parameter; for 2D codes use QRCODE, DMATRIX, PDF417, AZTEC, etc.",
      "example": {
        "source": "BARCODE 50,200,\"128\",80,1,0,2,4,\"ABC-12345\"",
        "description": "Code 128 barcode with human-readable text below"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/barcode/"
    },
    {
      "command": "QRCODE",
      "name": "QR Code",
      "description": "Draws a QR code at the specified position. You control the error correction level, cell size, encoding mode, and rotation. QR codes can store URLs, text, and other data.",
      "category": "barcode",
      "syntax": "QRCODE x,y,ECC,cell,mode,rotation,\"data\"",
      "parameters": [
        {
          "name": "x",
          "description": "Horizontal position in dots"
        },
        {
          "name": "y",
          "description": "Vertical position in dots"
        },
        {
          "name": "ECC",
          "description": "Error-correction level — higher recovers more of the symbol if damaged.",
          "values": [
            {
              "value": "L",
              "description": "~7% recovery"
            },
            {
              "value": "M",
              "description": "~15% recovery (typical default)"
            },
            {
              "value": "Q",
              "description": "~25% recovery"
            },
            {
              "value": "H",
              "description": "~30% recovery"
            }
          ]
        },
        {
          "name": "cell",
          "description": "Cell size in dots (1–10)"
        },
        {
          "name": "mode",
          "description": "Encoding mode",
          "values": [
            {
              "value": "A",
              "description": "Automatic — encoder picks numeric / alphanumeric / byte / kanji"
            },
            {
              "value": "M",
              "description": "Manual mode selection (legacy firmware)"
            }
          ]
        },
        {
          "name": "rotation",
          "description": "Rotation in degrees",
          "values": [
            {
              "value": "0",
              "description": "No rotation"
            },
            {
              "value": "90",
              "description": "90° clockwise"
            },
            {
              "value": "180",
              "description": "180° (upside down)"
            },
            {
              "value": "270",
              "description": "270° clockwise"
            }
          ]
        },
        {
          "name": "data",
          "description": "The data to encode (in double quotes)"
        }
      ],
      "whenToUse": "When you need a 2D barcode that can be scanned with a smartphone — URLs, asset IDs, or compact data encoding.",
      "example": {
        "source": "QRCODE 50,50,M,5,A,0,\"https://rfid.me\"",
        "description": "QR code linking to rfid.me"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/qrcode/"
    },
    {
      "command": "DMATRIX",
      "name": "Data Matrix",
      "description": "Draws a Data Matrix ECC 200 symbol — the compact square 2D barcode used for pharmaceutical labelling, automotive parts marking, and unit identification. (x,y) anchors the upper-left of the bounding rectangle; width × height define the maximum area the symbol may occupy. Real DataMatrix encoding is performed via `@rfid-me/epc-parser`. Per TSPL2 PG §DMATRIX (p47–48).",
      "category": "barcode",
      "syntax": "DMATRIX x,y,width,height,[xm,row,col,]\"data\"",
      "parameters": [
        {
          "name": "x",
          "description": "Upper-left X coordinate of the bounding rectangle in dots"
        },
        {
          "name": "y",
          "description": "Upper-left Y coordinate of the bounding rectangle in dots"
        },
        {
          "name": "width",
          "description": "Maximum width of the bounding rectangle in dots"
        },
        {
          "name": "height",
          "description": "Maximum height of the bounding rectangle in dots"
        },
        {
          "name": "xm",
          "description": "Optional module size in dots (1–9)"
        },
        {
          "name": "row",
          "description": "Optional forced row count (must be a legal ECC 200 row size — 10, 12, 14, … 144)"
        },
        {
          "name": "col",
          "description": "Optional forced column count (must be a legal ECC 200 column size — 10, 12, 14, … 144)"
        },
        {
          "name": "data",
          "description": "Data to encode in double quotes. Use `~1` for FNC1 (GS1 application identifiers), `~d###` for ASCII decimal escape sequences"
        }
      ],
      "whenToUse": "When you need a compact 2D barcode for small labels or high-density data — pharma serialisation (GS1 with FNC1 via `~1`), part marking, unit identification. For larger 2D codes use QRCODE; for 1D barcodes use BARCODE.",
      "example": {
        "source": "DMATRIX 100,100,400,400,\"DMATRIX EXAMPLE 1\"",
        "description": "A Data Matrix encoding the string \"DMATRIX EXAMPLE 1\" within a 400×400 dot bounding rectangle (PG example)"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/dmatrix/"
    },
    {
      "command": "DENSITY",
      "name": "Print Density",
      "description": "Sets the print darkness (density). Higher values produce darker output. The range is 0-15. Start at 8 and adjust up or down based on scan results and visual quality.",
      "category": "config",
      "syntax": "DENSITY n",
      "parameters": [
        {
          "name": "n",
          "description": "Density level 0 (lightest) to 15 (darkest)"
        }
      ],
      "whenToUse": "When you need to adjust print darkness — barcode scanning issues often stem from incorrect density settings.",
      "example": {
        "source": "DENSITY 8",
        "description": "Set print density to medium (8)"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/density/"
    },
    {
      "command": "SPEED",
      "name": "Print Speed",
      "description": "Sets the print speed in inches per second. Higher speeds are faster but may reduce print quality. Available speeds depend on your printer model.",
      "category": "config",
      "syntax": "SPEED n",
      "parameters": [
        {
          "name": "n",
          "description": "Speed in inches per second (1-12, model-dependent)"
        }
      ],
      "whenToUse": "When you need to balance speed and quality — slow down for barcodes that need to scan perfectly, speed up for text-only labels.",
      "example": {
        "source": "SPEED 4",
        "description": "Set print speed to 4 inches per second"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/speed/"
    },
    {
      "command": "CODEPAGE",
      "name": "Character Code Page",
      "description": "Selects the character encoding for TEXT data (TSPL2 PG §CODEPAGE p18–19). Different code pages support different glyph sets — critical for international characters. Default at power-on is `437` (US OEM). The PG enumerates four families: 7-bit national variants (USA / BRI / GER / FRE / DAN / ITA / SPA / SWE / SWI), 8-bit DOS codepages (437 / 850 / 852 / 860 / 863 / 865 / 857), Windows codepages (1250 / 1252 / 1253 / 1254 / WPC1251 / WPC1255 / WPC1257 / 866), plus per-model UTF-8 / CJK additions in the model-specific appendix. Engine-recognised but doesn't currently apply byte→glyph mapping in TEXT (always passes through UTF-8/ASCII). Follow-up tracked for the mapping work.",
      "category": "config",
      "syntax": "CODEPAGE n",
      "parameters": [
        {
          "name": "n",
          "description": "Code page identifier (case-insensitive).",
          "values": [
            {
              "value": "USA",
              "description": "7-bit USA"
            },
            {
              "value": "BRI",
              "description": "7-bit British"
            },
            {
              "value": "GER",
              "description": "7-bit German"
            },
            {
              "value": "FRE",
              "description": "7-bit French"
            },
            {
              "value": "DAN",
              "description": "7-bit Danish"
            },
            {
              "value": "ITA",
              "description": "7-bit Italian"
            },
            {
              "value": "SPA",
              "description": "7-bit Spanish"
            },
            {
              "value": "SWE",
              "description": "7-bit Swedish"
            },
            {
              "value": "SWI",
              "description": "7-bit Swiss"
            },
            {
              "value": "437",
              "description": "8-bit USA OEM (default at power-on)"
            },
            {
              "value": "850",
              "description": "8-bit Multilingual Latin-1"
            },
            {
              "value": "852",
              "description": "8-bit Slavic / Latin-2"
            },
            {
              "value": "857",
              "description": "8-bit Turkish"
            },
            {
              "value": "860",
              "description": "8-bit Portuguese"
            },
            {
              "value": "863",
              "description": "8-bit Canadian-French"
            },
            {
              "value": "865",
              "description": "8-bit Nordic"
            },
            {
              "value": "866",
              "description": "8-bit Cyrillic II"
            },
            {
              "value": "1250",
              "description": "Windows Central Europe"
            },
            {
              "value": "1252",
              "description": "Windows Latin I (Western Europe)"
            },
            {
              "value": "1253",
              "description": "Windows Greek"
            },
            {
              "value": "1254",
              "description": "Windows Turkish"
            },
            {
              "value": "WPC1251",
              "description": "Windows Cyrillic"
            },
            {
              "value": "WPC1255",
              "description": "Windows Hebrew"
            },
            {
              "value": "WPC1257",
              "description": "Windows Baltic"
            }
          ]
        }
      ],
      "whenToUse": "Once per label-script when printing non-ASCII characters whose mapping depends on encoding (e.g. accented Latin, Cyrillic, Greek, Turkish). Pair with COUNTRY for region-appropriate date/keyboard handling.",
      "example": {
        "source": "CODEPAGE 1252\nSIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Café Müller\"\nPRINT 1",
        "description": "Use Windows-1252 for Western-European characters"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/codepage/"
    },
    {
      "command": "SET",
      "name": "Printer Configuration Dispatcher",
      "description": "Generic printer-configuration dispatcher (TSPL2 PG §SET p132–148). The first word after SET picks the setting being changed. Engine-recognised sub-actions cover the full PG-documented set except GAP, which requires lexer-mode disambiguation (tracked separately). All SET settings are persistent across power cycles unless the sub-page says otherwise (RIBBON is non-persistent). Engine-recognised but not rendered — labels with SET configure the printer hardware rather than producing label content.",
      "category": "config",
      "syntax": "SET <sub-action> <args>",
      "parameters": [
        {
          "name": "sub-action",
          "description": "The printer setting to configure (case-insensitive).",
          "values": [
            {
              "value": "PEEL",
              "description": "Peel-off mode (ON/OFF)"
            },
            {
              "value": "TEAR",
              "description": "Tear-off mode (ON/OFF)"
            },
            {
              "value": "CUTTER",
              "description": "Auto-cutter mode (OFF/BATCH/<pieces>)"
            },
            {
              "value": "HEAD",
              "description": "Head-open sensor mode (ON/OFF)"
            },
            {
              "value": "RIBBON",
              "description": "Ribbon-detect mode (ON/OFF) — non-persistent"
            },
            {
              "value": "COUNTER",
              "description": "Initialise/step a counter variable (@n step)"
            },
            {
              "value": "PARTIAL_CUTTER",
              "description": "Partial-cut mode (OFF/BATCH/<pieces>)"
            },
            {
              "value": "BACK",
              "description": "Back-feed toggle (ON/OFF)"
            },
            {
              "value": "KEY1",
              "description": "Front-panel KEY1 remap (OFF/MENU/PAUSE/FEED/…)"
            },
            {
              "value": "KEY2",
              "description": "Front-panel KEY2 remap (OFF/MENU/PAUSE/FEED/…)"
            },
            {
              "value": "REWIND",
              "description": "External rewinder toggle (ON/OFF)"
            },
            {
              "value": "PRINTKEY",
              "description": "Print-key behaviour (OFF/ON/AUTO/<n>)"
            },
            {
              "value": "STRIPER",
              "description": "Alias of TEAR (PG p143–144)"
            }
          ]
        },
        {
          "name": "args",
          "description": "Sub-action-specific arguments — see the individual SET <sub-action> entries"
        }
      ],
      "whenToUse": "For advanced printer configuration — cutter control, tear-off settings, peel-off mode, ribbon/head sensor mode, counters, front-panel key remap, network/host config. Best placed once at the top of a label setup script; settings persist until changed.",
      "example": {
        "source": "SET CUTTER ON\nSET PEEL OFF\nSET TEAR ON",
        "description": "Enable the automatic cutter, disable peel-off mode, enable tear-off"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set/"
    },
    {
      "command": "SET PEEL",
      "name": "Peel-off Mode",
      "description": "Toggles the printer's peel-off mode (TSPL2 PG §SET p142). When ON, the printer waits for the operator to remove each label from the liner before printing the next; when OFF, labels print continuously. Persistent across power cycles.",
      "category": "config",
      "syntax": "SET PEEL ON | SET PEEL OFF",
      "parameters": [
        {
          "name": "state",
          "description": "Peel-off mode (case-insensitive).",
          "values": [
            {
              "value": "ON",
              "description": "Enable peel-off — pause between labels until taken"
            },
            {
              "value": "OFF",
              "description": "Disable peel-off — print continuously"
            }
          ]
        }
      ],
      "whenToUse": "Once per peel-equipped printer to match the deployment's label-presentation flow. Typically paired with a peel-sensor that gates the next print until the previous label is taken.",
      "example": {
        "source": "SET PEEL ON",
        "description": "Enable peel-off mode"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-peel/"
    },
    {
      "command": "SET TEAR",
      "name": "Tear-off Mode",
      "description": "Toggles the printer's tear-off behaviour (TSPL2 PG §SET p143–144; alias STRIPER on some models). When ON, the printer advances each label past the tear bar after printing so the operator can tear it off cleanly; when OFF, the label stops at the print head. Persistent across power cycles.",
      "category": "config",
      "syntax": "SET TEAR ON | SET TEAR OFF",
      "parameters": [
        {
          "name": "state",
          "description": "Tear-off mode (case-insensitive).",
          "values": [
            {
              "value": "ON",
              "description": "Enable tear-off — advance past tear bar after each label"
            },
            {
              "value": "OFF",
              "description": "Disable tear-off — stop at the print head"
            }
          ]
        }
      ],
      "whenToUse": "For tear-bar-equipped printers when the deployment requires the print head to advance the label for clean tearing.",
      "example": {
        "source": "SET TEAR ON",
        "description": "Enable tear-off advance after each label"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-tear/"
    },
    {
      "command": "SET CUTTER",
      "name": "Auto-Cutter Mode",
      "description": "Configures the optional auto-cutter (TSPL2 PG §SET p133). OFF disables the cutter; BATCH cuts once at the end of a print batch; a numeric argument cuts every N labels. Persistent across power cycles. Only effective on cutter-equipped printers — sending this to a non-cutter model is a recognised no-op.",
      "category": "config",
      "syntax": "SET CUTTER OFF | SET CUTTER BATCH | SET CUTTER <pieces>",
      "parameters": [
        {
          "name": "mode",
          "description": "Cutter mode (case-insensitive; OFF/BATCH/<pieces>).",
          "values": [
            {
              "value": "OFF",
              "description": "Disable the auto-cutter"
            },
            {
              "value": "BATCH",
              "description": "Cut once at the end of the batch"
            },
            {
              "value": "<pieces>",
              "description": "Numeric: cut every N labels (e.g. SET CUTTER 1 cuts every label)"
            }
          ]
        }
      ],
      "whenToUse": "Once at the top of a label-batch script on cutter-equipped printers. Pair with PRINT for predictable cut points.",
      "example": {
        "source": "SET CUTTER 1\nPRINT 5",
        "description": "Cut after every label across a 5-label batch"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-cutter/"
    },
    {
      "command": "SET HEAD",
      "name": "Head-Open Sensor Mode",
      "description": "Toggles the head-open sensor (TSPL2 PG §SET p147). When ON (the safe default), the printer halts printing if the print head is opened mid-job; when OFF, the sensor is ignored. Persistent across power cycles. **Do not disable in production** — head-open during printing can damage the print head or smear ink/ribbon.",
      "category": "config",
      "syntax": "SET HEAD ON | SET HEAD OFF",
      "parameters": [
        {
          "name": "state",
          "description": "Head-open sensor (case-insensitive).",
          "values": [
            {
              "value": "ON",
              "description": "Enable head-open sensor (safe default)"
            },
            {
              "value": "OFF",
              "description": "Disable head-open sensor (bench testing only)"
            }
          ]
        }
      ],
      "whenToUse": "Leave ON for production deployments. Only consider OFF during bench testing of head-sensor wiring, and re-enable before shipping.",
      "example": {
        "source": "SET HEAD ON",
        "description": "Enable the head-open sensor (safe default)"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-head/"
    },
    {
      "command": "SET RIBBON",
      "name": "Ribbon-Detect Mode",
      "description": "Toggles the ribbon-detect sensor (TSPL2 PG §SET p148). When ON, the printer halts if it doesn't detect a thermal-transfer ribbon (i.e. assumes thermal-transfer mode); when OFF, the printer assumes direct-thermal media and ignores the ribbon sensor. **Non-persistent — reverts on power cycle.** This is the only SET sub-action whose value isn't kept across reboots.",
      "category": "config",
      "syntax": "SET RIBBON ON | SET RIBBON OFF",
      "parameters": [
        {
          "name": "state",
          "description": "Ribbon-detect (case-insensitive). Non-persistent.",
          "values": [
            {
              "value": "ON",
              "description": "Thermal-transfer mode — require ribbon present"
            },
            {
              "value": "OFF",
              "description": "Direct-thermal mode — ignore ribbon sensor"
            }
          ]
        }
      ],
      "whenToUse": "Once per power cycle to match the loaded media. Direct-thermal media → OFF; thermal-transfer with ribbon → ON. Re-issue on every boot.",
      "example": {
        "source": "SET RIBBON OFF",
        "description": "Direct-thermal mode (no ribbon required)"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-ribbon/"
    },
    {
      "command": "SET COUNTER",
      "name": "Counter Variable",
      "description": "Initialises or increments a printer-side counter variable (TSPL2 PG §SET COUNTER p132). `@n` is the counter index (typically `@0`–`@9`); `step` is the increment applied between labels in a print batch. Counter values are referenced from TEXT/BARCODE payloads via the `@n` placeholder. Useful for serialised label batches without round-tripping to the host for each value. Engine recognises the command but doesn't currently model the `@n` placeholder substitution in TEXT/BARCODE — placeholder rendering is a separate feature.",
      "category": "config",
      "syntax": "SET COUNTER @n step",
      "parameters": [
        {
          "name": "@n",
          "description": "Counter variable name (e.g. `@0`, `@1`)."
        },
        {
          "name": "step",
          "description": "Increment applied between labels (integer; negative permitted to count down)."
        }
      ],
      "whenToUse": "For serialised batches (e.g. consecutive part numbers) when the host wants to send one label template and let the printer increment internally.",
      "example": {
        "source": "SET COUNTER @0 1\nSIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Serial: @0\"\nPRINT 10",
        "description": "Initialise counter @0 with step 1, then print 10 labels with auto-incrementing serial numbers"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-counter/"
    },
    {
      "command": "SET PARTIAL_CUTTER",
      "name": "Partial-Cut Mode",
      "description": "Configures the partial-cutter accessory (TSPL2 PG §SET PARTIAL_CUTTER p134). Sibling of `SET CUTTER` — partial cut leaves a small tab so the next label hangs from the previous, useful for catalog/peel-off workflows. OFF disables the partial cutter; BATCH cuts once at the end of a print batch; a numeric argument cuts every N labels. Persistent across power cycles. Only effective on partial-cutter-equipped hardware — sending this to a non-cutter model is a recognised no-op.",
      "category": "config",
      "syntax": "SET PARTIAL_CUTTER OFF | SET PARTIAL_CUTTER BATCH | SET PARTIAL_CUTTER <pieces>",
      "parameters": [
        {
          "name": "mode",
          "description": "Partial-cut mode (case-insensitive; OFF/BATCH/<pieces>).",
          "values": [
            {
              "value": "OFF",
              "description": "Disable the partial cutter"
            },
            {
              "value": "BATCH",
              "description": "Partial-cut once at the end of the batch"
            },
            {
              "value": "<pieces>",
              "description": "Numeric: partial-cut every N labels"
            }
          ]
        }
      ],
      "whenToUse": "On printers with a partial-cutter accessory when the workflow needs labels to hang together for downstream picking/peeling.",
      "example": {
        "source": "SET PARTIAL_CUTTER 1\nPRINT 5",
        "description": "Partial-cut after every label across a 5-label batch"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-partial-cutter/"
    },
    {
      "command": "SET BACK",
      "name": "Back-Feed Toggle",
      "description": "Toggles automatic back-feed after each print (TSPL2 PG §SET BACK p135). When ON, the printer retracts to its print-start position after each label — useful for peel-off and tear-off workflows where the label needs to be repositioned before the next print. Persistent across power cycles. Distinct from the top-level `BACKFEED n` command, which is a one-shot retract by N dots.",
      "category": "config",
      "syntax": "SET BACK ON | SET BACK OFF",
      "parameters": [
        {
          "name": "state",
          "description": "Back-feed toggle (case-insensitive).",
          "values": [
            {
              "value": "ON",
              "description": "Enable automatic back-feed after each print"
            },
            {
              "value": "OFF",
              "description": "Disable automatic back-feed"
            }
          ]
        }
      ],
      "whenToUse": "On peel-off or tear-off deployments when each label needs to retract to a consistent start position automatically.",
      "example": {
        "source": "SET BACK ON",
        "description": "Enable automatic back-feed after each printed label"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-back/"
    },
    {
      "command": "SET KEY1",
      "name": "Front-Panel KEY1 Remap",
      "description": "Remaps the printer's front-panel KEY1 to a chosen action (TSPL2 PG §SET KEY1 p136–137). Useful for tuning printer behaviour to a specific deployment — e.g. mapping KEY1 to PAUSE for an interactive workflow, or to CALIBRATION for a maintenance role. Persistent across power cycles.",
      "category": "config",
      "syntax": "SET KEY1 <action>",
      "parameters": [
        {
          "name": "action",
          "description": "Action enum (case-insensitive). Available actions per PG p136–137.",
          "values": [
            {
              "value": "OFF",
              "description": "KEY1 does nothing"
            },
            {
              "value": "MENU",
              "description": "Open the front-panel menu"
            },
            {
              "value": "PAUSE",
              "description": "Pause / resume the current print job"
            },
            {
              "value": "FEED",
              "description": "Feed one label"
            },
            {
              "value": "CALIBRATION",
              "description": "Run sensor calibration"
            },
            {
              "value": "BATCH",
              "description": "Reprint the last batch"
            }
          ]
        }
      ],
      "whenToUse": "Once per printer at provisioning — adjust the front-panel UX to match the deployment.",
      "example": {
        "source": "SET KEY1 PAUSE",
        "description": "Map the front-panel KEY1 to pause/resume the current job"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-key1/"
    },
    {
      "command": "SET KEY2",
      "name": "Front-Panel KEY2 Remap",
      "description": "Remaps the printer's front-panel KEY2 to a chosen action (TSPL2 PG §SET KEY2 p137–138). Identical action enum to `SET KEY1`. Persistent across power cycles. Useful for printers with a two-key front panel where each key gets a distinct workflow role (e.g. KEY1 = PAUSE, KEY2 = FEED).",
      "category": "config",
      "syntax": "SET KEY2 <action>",
      "parameters": [
        {
          "name": "action",
          "description": "Action enum (case-insensitive). Same actions as SET KEY1.",
          "values": [
            {
              "value": "OFF",
              "description": "KEY2 does nothing"
            },
            {
              "value": "MENU",
              "description": "Open the front-panel menu"
            },
            {
              "value": "PAUSE",
              "description": "Pause / resume the current print job"
            },
            {
              "value": "FEED",
              "description": "Feed one label"
            },
            {
              "value": "CALIBRATION",
              "description": "Run sensor calibration"
            },
            {
              "value": "BATCH",
              "description": "Reprint the last batch"
            }
          ]
        }
      ],
      "whenToUse": "Together with `SET KEY1` at provisioning to set up the dual-key front-panel UX.",
      "example": {
        "source": "SET KEY1 PAUSE\nSET KEY2 FEED",
        "description": "Set up a two-key panel: KEY1 = pause/resume, KEY2 = manual feed"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-key2/"
    },
    {
      "command": "SET REWIND",
      "name": "External-Rewinder Toggle",
      "description": "Toggles external-rewinder support (TSPL2 PG §SET REWIND p139). When ON, the printer drives an attached external-rewinder accessory; when OFF, no rewinder signalling is generated. Persistent across power cycles. Only effective on rewinder-equipped deployments — sending this to a printer without the accessory is a recognised no-op.",
      "category": "config",
      "syntax": "SET REWIND ON | SET REWIND OFF",
      "parameters": [
        {
          "name": "state",
          "description": "External-rewinder toggle (case-insensitive).",
          "values": [
            {
              "value": "ON",
              "description": "Enable external-rewinder drive"
            },
            {
              "value": "OFF",
              "description": "Disable external-rewinder drive"
            }
          ]
        }
      ],
      "whenToUse": "Once per printer at provisioning when an external rewinder is fitted, to enable the rewinder drive signal.",
      "example": {
        "source": "SET REWIND ON",
        "description": "Enable the external-rewinder accessory"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-rewind/"
    },
    {
      "command": "SET PRINTKEY",
      "name": "Print-Key Behaviour",
      "description": "Configures the front-panel print-key behaviour (TSPL2 PG §SET PRINTKEY p140). OFF disables the print key; ON makes a single press print one label; AUTO triggers auto-repeat printing while the key is held; a numeric value `<n>` prints N labels per press. Persistent across power cycles.",
      "category": "config",
      "syntax": "SET PRINTKEY OFF | SET PRINTKEY ON | SET PRINTKEY AUTO | SET PRINTKEY <n>",
      "parameters": [
        {
          "name": "mode",
          "description": "Print-key behaviour (case-insensitive, or numeric).",
          "values": [
            {
              "value": "OFF",
              "description": "Disable the print key"
            },
            {
              "value": "ON",
              "description": "Single-shot — one press prints one label"
            },
            {
              "value": "AUTO",
              "description": "Auto-repeat while held"
            },
            {
              "value": "<n>",
              "description": "Numeric: print N labels per press"
            }
          ]
        }
      ],
      "whenToUse": "When the operator workflow expects the front-panel print key to behave differently from the default single-shot — e.g. AUTO for a print-while-held demo mode, or numeric for fixed-count batches.",
      "example": {
        "source": "SET PRINTKEY AUTO",
        "description": "Make the print-key auto-repeat while held (useful for demos)"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-printkey/"
    },
    {
      "command": "SET STRIPER",
      "name": "Striper (alias of SET TEAR)",
      "description": "Alias of `SET TEAR` on some firmware revisions (TSPL2 PG §SET STRIPER p143–144). Same semantics, alternate keyword surfaced for models that ship with a \"striper\" label on the front panel. See `SET TEAR` for the canonical documentation — anything you can do with one, you can do with the other. Persistent across power cycles.",
      "category": "config",
      "syntax": "SET STRIPER ON | SET STRIPER OFF",
      "parameters": [
        {
          "name": "state",
          "description": "Striper / tear-off mode (case-insensitive).",
          "values": [
            {
              "value": "ON",
              "description": "Enable striper / tear-off — advance past tear bar after each label"
            },
            {
              "value": "OFF",
              "description": "Disable — stop at the print head"
            }
          ]
        }
      ],
      "whenToUse": "Use `SET TEAR` for new code (clearer naming, matches the front-panel label on most printers). Use `SET STRIPER` only when matching legacy or model-specific label scripts.",
      "example": {
        "source": "SET STRIPER ON",
        "description": "Enable tear-off advance via the striper alias"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/set-striper/"
    },
    {
      "command": "SHIFT",
      "name": "Vertical Label Shift",
      "description": "Shifts the entire imaged label vertically by `n` dots (positive or negative). Used to align with pre-printed stock, correct registration drift, or fine-tune the print position without re-issuing every coordinate. TSPL2 PG §SHIFT p15–16: range is ±203 dots on 200 DPI printers, ±300 on 300 DPI printers (max 1 inch absolute). A positive value moves the label further from the printing direction; negative moves it toward.",
      "category": "label",
      "syntax": "SHIFT n",
      "parameters": [
        {
          "name": "n",
          "description": "Vertical shift in dots (negative or positive). Range ±203 for 200 DPI, ±300 for 300 DPI; max ±1 inch."
        }
      ],
      "whenToUse": "When the printed image needs a small vertical nudge — typically after measuring registration on a test print and noticing the image is consistently a few dots off-target.",
      "example": {
        "source": "SIZE 100 mm, 50 mm\nSHIFT 12\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Shifted down by 12 dots\"\nPRINT 1",
        "description": "Shift the entire label image 12 dots further from the printing direction"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/shift/"
    },
    {
      "command": "LIMITFEED",
      "name": "Calibration Feed Limit",
      "description": "Caps the distance the printer feeds while searching for the next label gap during calibration / HOME. TSPL2 PG §LIMITFEED p30. Prevents runaway feeds on mis-cut or misaligned stock. Default 10 inches at boot. Two forms: `LIMITFEED n` (inches, English system) or `LIMITFEED n mm` (metric — must have a space before `mm`). Resident in memory across the session. No visual rendering effect — runtime hardware behaviour.",
      "category": "config",
      "syntax": "LIMITFEED n | LIMITFEED n mm",
      "parameters": [
        {
          "name": "n",
          "description": "Maximum sensor-detect length. Bare number = inches; followed by ` mm` (with leading space) = millimetres."
        }
      ],
      "whenToUse": "When working with unusual label stock where the auto-calibration could otherwise feed an excessive length searching for the next gap (e.g. die-cut stock with inconsistent gaps, or wide form-feed paper).",
      "example": {
        "source": "LIMITFEED 6\nHOME\nSIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Calibrated\"\nPRINT 1",
        "description": "Cap calibration feed at 6 inches before running HOME"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/limitfeed/"
    },
    {
      "command": "COUNTRY",
      "name": "Country / Language Code",
      "description": "Selects the country / language code that orients the KP-200-series LCD keyboard and affects special-character mapping for built-in fonts. TSPL2 PG §COUNTRY p17. `n` is a 3-digit code: 001 USA, 002 Canadian-French, 003 Spanish (Latin America), 031 Dutch, 032 Belgian, 033 French, 034 Spanish (Spain), 036 Hungarian, 038 Yugoslavian, 039 Italian, 041 Switzerland, 042 Slovak, 044 United Kingdom, 045 Danish, 046 Swedish, 047 Norwegian, 048 Polish, 049 German, 055 Brazil, 061 English (International), 351 Portuguese, 358 Finnish. Engine accepts the code but doesn't currently apply locale-specific TEXT formatting — flagged as supported:false until the date-placeholder feature lands.",
      "category": "config",
      "syntax": "COUNTRY n",
      "parameters": [
        {
          "name": "n",
          "description": "3-digit country code.",
          "values": [
            {
              "value": "001",
              "description": "USA"
            },
            {
              "value": "002",
              "description": "Canadian-French"
            },
            {
              "value": "003",
              "description": "Spanish (Latin America)"
            },
            {
              "value": "031",
              "description": "Dutch"
            },
            {
              "value": "032",
              "description": "Belgian"
            },
            {
              "value": "033",
              "description": "French (France)"
            },
            {
              "value": "034",
              "description": "Spanish (Spain)"
            },
            {
              "value": "036",
              "description": "Hungarian"
            },
            {
              "value": "038",
              "description": "Yugoslavian"
            },
            {
              "value": "039",
              "description": "Italian"
            },
            {
              "value": "041",
              "description": "Switzerland"
            },
            {
              "value": "042",
              "description": "Slovak"
            },
            {
              "value": "044",
              "description": "United Kingdom"
            },
            {
              "value": "045",
              "description": "Danish"
            },
            {
              "value": "046",
              "description": "Swedish"
            },
            {
              "value": "047",
              "description": "Norwegian"
            },
            {
              "value": "048",
              "description": "Polish"
            },
            {
              "value": "049",
              "description": "German"
            },
            {
              "value": "055",
              "description": "Brazil"
            },
            {
              "value": "061",
              "description": "English (International)"
            },
            {
              "value": "351",
              "description": "Portuguese"
            },
            {
              "value": "358",
              "description": "Finnish"
            }
          ]
        }
      ],
      "whenToUse": "When deploying to a region whose keyboard layout / date format differs from the printer's default. Pair with the appropriate CODEPAGE for character-set coverage.",
      "example": {
        "source": "COUNTRY 044\nCODEPAGE 1252\nSIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"UK locale\"\nPRINT 1",
        "description": "Configure UK locale and Windows-1252 codepage"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/country/"
    },
    {
      "command": "SOUND",
      "name": "Printer Beeper",
      "description": "Triggers the printer's beeper for a tone at the specified level and duration. TSPL2 PG §SOUND p28. `level` is the sound level / tone (0–9, 10 discrete steps), `interval` is the timing control (1–4095). Chain multiple SOUND lines to play a tune. No visual rendering effect — runtime hardware behaviour. Useful for signalling end-of-batch or alerting the operator.",
      "category": "control",
      "syntax": "SOUND level, interval",
      "parameters": [
        {
          "name": "level",
          "description": "Sound level / tone (0–9, 10 discrete steps)."
        },
        {
          "name": "interval",
          "description": "Timing control (1–4095)."
        }
      ],
      "whenToUse": "To signal job completion (e.g. end of a long print batch) or to alert the operator (e.g. after `SET HEAD OFF` debugging). Place anywhere in the label script.",
      "example": {
        "source": "SIZE 100 mm, 50 mm\nCLS\nTEXT 50,30,\"3\",0,1,1,\"Beep done\"\nPRINT 1\nSOUND 5, 200\nSOUND 9, 100",
        "description": "Print a label then play a two-note end-of-batch beep"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/sound/"
    },
    {
      "command": "DOWNLOAD",
      "name": "Download File",
      "description": "Begins downloading a file (program, font, or image) to the printer's internal flash memory. The data follows on subsequent lines until EOP.",
      "category": "config",
      "syntax": "DOWNLOAD \"filename\"",
      "parameters": [
        {
          "name": "filename",
          "description": "Name of the file to store (in double quotes)"
        }
      ],
      "whenToUse": "When storing label templates, custom fonts, or images in the printer's memory for later use.",
      "example": {
        "source": "DOWNLOAD \"LOGO.BMP\",1024,<binary data>",
        "description": "Download a bitmap image to the printer"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/download/"
    },
    {
      "command": "RFID",
      "name": "RFID Gen2 Operation",
      "description": "Dispatches an RFID Gen2 tag operation. The first word after RFID picks the action — READ pulls data out of a memory bank, WRITE encodes data into a bank, LOCK applies a Gen2 lock policy, KILL irreversibly disables the tag, and PERMALOCK irreversibly locks a bank. The bank selector (in quotes) is one of \"EPC\", \"USER\", \"TID\", or \"RESERVED\". This command only works on TSPL2 printers with an RFID head fitted (e.g. TSC TTP-247R, TTP-2410MT, MH-241).",
      "category": "rfid",
      "syntax": "RFID <sub-action> \"<bank>\"[, <args...>]",
      "parameters": [
        {
          "name": "sub-action",
          "description": "The Gen2 operation to dispatch (case-insensitive).",
          "values": [
            {
              "value": "READ",
              "description": "Read N bytes from a memory bank at a given offset"
            },
            {
              "value": "WRITE",
              "description": "Encode bytes into a memory bank at a given offset"
            },
            {
              "value": "LOCK",
              "description": "Apply a Gen2 access-policy lock to a memory bank"
            },
            {
              "value": "KILL",
              "description": "Irreversibly disable the tag (requires the kill password)"
            },
            {
              "value": "PERMALOCK",
              "description": "Irreversibly lock a memory bank (cannot be reversed)"
            }
          ]
        },
        {
          "name": "bank",
          "description": "Quoted Gen2 memory bank (omit for KILL — which takes only a password).",
          "values": [
            {
              "value": "\"EPC\"",
              "description": "Electronic Product Code bank"
            },
            {
              "value": "\"USER\"",
              "description": "User memory bank"
            },
            {
              "value": "\"TID\"",
              "description": "Tag Identifier bank (typically read-only)"
            },
            {
              "value": "\"RESERVED\"",
              "description": "Reserved bank (access/kill passwords)"
            }
          ]
        },
        {
          "name": "args",
          "description": "Sub-action-specific arguments — offset/length for READ, offset/data for WRITE, password/policy for LOCK, password for KILL, password for PERMALOCK"
        }
      ],
      "whenToUse": "Whenever you need to encode, read, or secure RFID tag memory as part of a label print job. Pair with normal print commands (TEXT, BARCODE) to print a human-readable tag alongside encoding.",
      "example": {
        "source": "SIZE 100 mm, 50 mm\nCLS\nRFID WRITE \"EPC\", 0, \"E2801160600002054E5F8B41\"\nTEXT 50,30,\"3\",0,1,1,\"Encoded\"\nPRINT 1",
        "description": "Encode a 96-bit EPC into the tag's EPC bank, print a confirmation label"
      },
      "previewSupported": true,
      "canonicalUrl": "https://rfid.me/reference/tspl/rfid/"
    },
    {
      "command": "RFID READ",
      "name": "RFID Read Bank",
      "description": "Reads `<length>` bytes from `<bank>` starting at byte `<offset>` (TSPL2 PG §RFID READ p113). Offset and length are byte counts, not word counts. The read result is returned to the host as a hex string over the back-channel and may be displayed on the printer LCD on firmware that supports it. Engine-recognised but no SVG output — RFID operations don't produce label content.",
      "category": "rfid",
      "syntax": "RFID READ \"<bank>\", <offset>, <length>",
      "parameters": [
        {
          "name": "bank",
          "description": "Quoted Gen2 memory bank.",
          "values": [
            {
              "value": "\"EPC\"",
              "description": "Electronic Product Code bank (typically 12 bytes for SGTIN-96)"
            },
            {
              "value": "\"USER\"",
              "description": "User memory bank (size varies by tag chip)"
            },
            {
              "value": "\"TID\"",
              "description": "Tag Identifier bank (read-only, factory-programmed)"
            },
            {
              "value": "\"RESERVED\"",
              "description": "Reserved bank (kill + access passwords, 8 bytes total)"
            }
          ]
        },
        {
          "name": "offset",
          "description": "Byte offset within the bank (0-based)."
        },
        {
          "name": "length",
          "description": "Number of bytes to read."
        }
      ],
      "whenToUse": "For host-driven inventory audits, read-back-after-write verification, or to pull TID data for tag-authentication workflows. Pair with the printer's back-channel reader on the host side.",
      "example": {
        "source": "RFID READ \"EPC\", 0, 12",
        "description": "Read the full 96-bit EPC (12 bytes from offset 0 of the EPC bank)"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/rfid-read/"
    },
    {
      "command": "RFID WRITE",
      "name": "RFID Write Bank",
      "description": "Encodes `<hex-data>` into `<bank>` starting at byte `<offset>` (TSPL2 PG §RFID WRITE p114). `<hex-data>` is a hex-character string — each pair of hex chars = 1 byte. EPC bank typically takes 24 hex chars for the 96-bit SGTIN-96 encoding. If `<data>` length doesn't match the bank's word boundary, the write is padded or truncated per the Gen2 spec. Note: the TID bank is factory-locked and not writable — the engine emits a warning when targeting it.",
      "category": "rfid",
      "syntax": "RFID WRITE \"<bank>\", <offset>, \"<hex-data>\"",
      "parameters": [
        {
          "name": "bank",
          "description": "Quoted Gen2 memory bank (writable subset).",
          "values": [
            {
              "value": "\"EPC\"",
              "description": "Electronic Product Code bank"
            },
            {
              "value": "\"USER\"",
              "description": "User memory bank"
            },
            {
              "value": "\"RESERVED\"",
              "description": "Reserved bank (kill + access passwords)"
            }
          ]
        },
        {
          "name": "offset",
          "description": "Byte offset within the bank (0-based)."
        },
        {
          "name": "hex-data",
          "description": "Quoted hex string. Each pair of hex chars = 1 byte (e.g. 24 chars = 12 bytes = 96-bit EPC)."
        }
      ],
      "whenToUse": "The core \"print-and-encode\" command: write the EPC (or any other bank) at the moment of label print, so the printed barcode/text and the encoded chip stay in lockstep.",
      "example": {
        "source": "SIZE 100 mm, 50 mm\nCLS\nRFID WRITE \"EPC\", 0, \"112233445566778899AABBCC\"\nTEXT 50,30,\"3\",0,1,1,\"Encoded\"\nPRINT 1",
        "description": "Encode a 96-bit EPC into the EPC bank and print a confirmation label"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/rfid-write/"
    },
    {
      "command": "RFID LOCK",
      "name": "RFID Lock Bank",
      "description": "Applies a Gen2 access-policy lock to `<bank>` using the 32-bit access password (TSPL2 PG §RFID LOCK p116). `<password>` is 8 hex characters. `<policy>` is the Gen2 lock-action enum (0–3). Policy 3 is irreversible (use `RFID PERMALOCK` as the convenience wrapper). Note: the RESERVED bank exposes two named partitions on some firmware — `\"KILL\"` for the kill-password area and `\"ACCESS\"` for the access-password area.",
      "category": "rfid",
      "syntax": "RFID LOCK \"<bank>\", \"<password>\", <policy>",
      "parameters": [
        {
          "name": "bank",
          "description": "Quoted Gen2 memory bank or RESERVED partition.",
          "values": [
            {
              "value": "\"EPC\"",
              "description": "Electronic Product Code bank"
            },
            {
              "value": "\"USER\"",
              "description": "User memory bank"
            },
            {
              "value": "\"TID\"",
              "description": "Tag Identifier bank (read-only on most tags)"
            },
            {
              "value": "\"RESERVED\"",
              "description": "Whole reserved bank"
            },
            {
              "value": "\"KILL\"",
              "description": "Kill-password partition of RESERVED"
            },
            {
              "value": "\"ACCESS\"",
              "description": "Access-password partition of RESERVED"
            }
          ]
        },
        {
          "name": "password",
          "description": "Quoted 8-hex-character access password (32 bits)."
        },
        {
          "name": "policy",
          "description": "Gen2 lock-action enum.",
          "values": [
            {
              "value": "0",
              "description": "Unlocked — writable without password"
            },
            {
              "value": "1",
              "description": "Locked — writable only with access password"
            },
            {
              "value": "2",
              "description": "Permanently unlocked — cannot be locked again"
            },
            {
              "value": "3",
              "description": "Permanently locked — cannot be unlocked (use RFID PERMALOCK as convenience wrapper)"
            }
          ]
        }
      ],
      "whenToUse": "After encoding the EPC (or other bank), to prevent unauthorised re-writes. Pair with `RFID WRITE`.",
      "example": {
        "source": "RFID LOCK \"EPC\", \"12345678\", 1",
        "description": "Lock the EPC bank so subsequent writes require the access password \"12345678\""
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/rfid-lock/"
    },
    {
      "command": "RFID KILL",
      "name": "RFID Kill (Permanent Disable)",
      "description": "⚠️ **Permanently and irreversibly disables the tag — cannot be undone.** Issues the Gen2 Kill command using the tag's 32-bit kill password (TSPL2 PG §RFID KILL p118). `<kill-password>` is 8 hex characters. A non-zero kill password is required by the Gen2 spec — the tag will reject KILL if its kill-password is all-zero (the engine surfaces this as a diagnostic). The kill password must have been previously written into the RESERVED bank (bytes 0–3) and is typically locked at the same time. Once successfully killed, the tag is permanently silent — no further reads or writes are possible. Used at end-of-life destruction stations for items leaving the supply chain.",
      "category": "rfid",
      "syntax": "RFID KILL \"<kill-password>\"",
      "parameters": [
        {
          "name": "kill-password",
          "description": "Quoted 8-hex-character kill password (32 bits). Must be non-zero per Gen2 spec — a tag with a zero kill-password rejects KILL."
        }
      ],
      "whenToUse": "Destruction-station workflows only — at end-of-life when the tag must never be readable again. Treat the kill password as a credential: do not commit label sources containing it to public repositories.",
      "example": {
        "source": "RFID KILL \"DEADBEEF\"",
        "description": "⚠️ Irreversibly destroy the tag using its 32-bit kill password"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/rfid-kill/"
    },
    {
      "command": "RFID PERMALOCK",
      "name": "RFID Permanent Lock",
      "description": "⚠️ **Irreversibly locks `<bank>` — the bank cannot be unlocked again.** Convenience wrapper for `RFID LOCK \"<bank>\", \"<password>\", 3` (Gen2 policy 3 = permanently-locked). `<password>` is the 8-hex-character (32-bit) access password. After successful execution, the bank's lock state cannot be changed — subsequent `RFID LOCK` or `RFID PERMALOCK` calls against that bank will fail.",
      "category": "rfid",
      "syntax": "RFID PERMALOCK \"<bank>\", \"<password>\"",
      "parameters": [
        {
          "name": "bank",
          "description": "Quoted Gen2 memory bank or RESERVED partition.",
          "values": [
            {
              "value": "\"EPC\"",
              "description": "Electronic Product Code bank"
            },
            {
              "value": "\"USER\"",
              "description": "User memory bank"
            },
            {
              "value": "\"TID\"",
              "description": "Tag Identifier bank"
            },
            {
              "value": "\"RESERVED\"",
              "description": "Whole reserved bank"
            },
            {
              "value": "\"KILL\"",
              "description": "Kill-password partition of RESERVED"
            },
            {
              "value": "\"ACCESS\"",
              "description": "Access-password partition of RESERVED"
            }
          ]
        },
        {
          "name": "password",
          "description": "Quoted 8-hex-character access password (32 bits)."
        }
      ],
      "whenToUse": "Supply-chain workflows where the EPC must never be rewritten after the tag leaves the encoding station. Use sparingly — once permalocked, you cannot recover the bank for re-use.",
      "example": {
        "source": "RFID WRITE \"EPC\", 0, \"E2801160600002054E5F8B41\"\nRFID PERMALOCK \"EPC\", \"12345678\"",
        "description": "⚠️ Encode a 96-bit EPC then irreversibly lock the EPC bank"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/rfid-permalock/"
    },
    {
      "command": "BT",
      "name": "Bluetooth Configuration Dispatcher",
      "description": "Generic Bluetooth configuration dispatcher. The first word after BT picks the sub-action — NAME sets the device name visible to pairing hosts, PIN sets the legacy-pairing PIN. Not in the 2009 TSPL2 PG: Bluetooth is an optional module on later TSC models (TX/TE/MH-series and Alpha-series with optional BT) and the commands are documented in per-model BT setup addenda. Engine-recognised but not rendered — labels with BT configure the printer hardware rather than producing label content.",
      "category": "config",
      "syntax": "BT <sub-action> <args>",
      "parameters": [
        {
          "name": "sub-action",
          "description": "The Bluetooth setting to configure (case-insensitive).",
          "values": [
            {
              "value": "NAME",
              "description": "Bluetooth friendly-name advertised over GAP"
            },
            {
              "value": "PIN",
              "description": "Bluetooth legacy-pairing PIN (BT 2.1+EDR; no-op on SSP-only firmware)"
            }
          ]
        },
        {
          "name": "args",
          "description": "Sub-action-specific arguments — see the BT NAME and BT PIN entries"
        }
      ],
      "whenToUse": "When configuring a BT-equipped TSC printer's Bluetooth radio in-band as part of a label setup script. Refer to the target model's BT setup guide for the supported sub-keyword set on that firmware revision.",
      "example": {
        "source": "BT NAME \"TSC-Printer-01\"\nBT PIN \"1234\"",
        "description": "Set the Bluetooth device name and pairing PIN"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/bt/"
    },
    {
      "command": "BT NAME",
      "name": "Bluetooth Device Name",
      "description": "Sets the Bluetooth friendly-name the printer advertises over GAP, visible to pairing hosts during device discovery. Not in the 2009 TSPL2 PG — refer to the target model's BT setup addendum for the supported character set and maximum length on that firmware.",
      "category": "config",
      "syntax": "BT NAME \"<device-name>\"",
      "parameters": [
        {
          "name": "device-name",
          "description": "Quoted friendly-name to advertise. Verify max-length and allowed characters against the model's addendum."
        }
      ],
      "whenToUse": "When provisioning a BT-equipped TSC printer and you want a meaningful name in the host's Bluetooth picker rather than the factory default.",
      "example": {
        "source": "BT NAME \"TSC-Printer-01\"",
        "description": "Advertise as \"TSC-Printer-01\" to BT pairing hosts"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/bt-name/"
    },
    {
      "command": "BT PIN",
      "name": "Bluetooth Pairing PIN",
      "description": "⚠️ Credential — appears in label source; do NOT commit to public repositories. Sets the Bluetooth legacy-pairing PIN (BT 2.1+EDR), typically a 4-digit numeric string. Modern Bluetooth SSP (Simple Secure Pairing) doesn't use a static PIN — on SSP-only firmware this command may document as a no-op. Not in the 2009 TSPL2 PG; refer to the target model's BT setup addendum.",
      "category": "config",
      "syntax": "BT PIN \"<pin>\"",
      "parameters": [
        {
          "name": "pin",
          "description": "Quoted PIN string. Typically 4-digit numeric per BT 2.1+EDR legacy pairing."
        }
      ],
      "whenToUse": "When provisioning a BT-equipped TSC printer that uses legacy pairing and you need to set a non-default PIN. Treat the PIN as a credential: keep label sources containing it out of version control or commit-time secret scanners.",
      "example": {
        "source": "BT PIN \"1234\"",
        "description": "Set the legacy-pairing PIN to \"1234\""
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/bt-pin/"
    },
    {
      "command": "WLAN",
      "name": "Wi-Fi Configuration Dispatcher",
      "description": "Generic Wi-Fi configuration dispatcher. The first word after WLAN picks the sub-action — SSID sets the network name, PSK sets the WPA passphrase, ENCRYPTION picks the security mode, IP/GATEWAY/NETMASK/DNS configure a static-IP profile, and DHCP toggles automatic addressing (which overrides the static-IP commands). Not in the 2009 TSPL2 PG: Wi-Fi is an optional module on later TSC models (TX/TE/MH-series and Alpha-series with optional Wi-Fi) and the commands are documented in per-model WLAN setup addenda. Engine-recognised but not rendered — labels with WLAN configure the printer hardware rather than producing label content.",
      "category": "config",
      "syntax": "WLAN <sub-action> <args>",
      "parameters": [
        {
          "name": "sub-action",
          "description": "The Wi-Fi setting to configure (case-insensitive).",
          "values": [
            {
              "value": "SSID",
              "description": "Wi-Fi network name (ESSID)"
            },
            {
              "value": "PSK",
              "description": "WPA/WPA2/WPA3 pre-shared key passphrase (credential)"
            },
            {
              "value": "ENCRYPTION",
              "description": "Security mode (OPEN, WEP, WPA, WPA2, WPA3, …)"
            },
            {
              "value": "IP",
              "description": "Static IPv4 address (ignored when DHCP=ON)"
            },
            {
              "value": "DHCP",
              "description": "Toggle DHCP client mode (ON/OFF)"
            },
            {
              "value": "GATEWAY",
              "description": "Default-gateway IPv4 address (ignored when DHCP=ON)"
            },
            {
              "value": "NETMASK",
              "description": "Subnet mask (ignored when DHCP=ON)"
            },
            {
              "value": "DNS",
              "description": "Primary DNS server address (ignored when DHCP=ON)"
            }
          ]
        },
        {
          "name": "args",
          "description": "Sub-action-specific arguments — see the individual WLAN <sub-action> entries"
        }
      ],
      "whenToUse": "When provisioning a Wi-Fi-equipped TSC printer in-band as part of a label setup script. Pair `WLAN SSID` + `WLAN ENCRYPTION` + `WLAN PSK` for WPA networks, or set `WLAN DHCP ON` to use a DHCP server's addressing.",
      "example": {
        "source": "WLAN SSID \"OfficeWiFi\"\nWLAN ENCRYPTION WPA2\nWLAN PSK \"ChangeThisPassphrase\"\nWLAN DHCP ON",
        "description": "Join WPA2 network \"OfficeWiFi\" with DHCP-assigned addressing"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan/"
    },
    {
      "command": "WLAN SSID",
      "name": "Wi-Fi Network Name",
      "description": "Sets the Wi-Fi network name (ESSID) the printer joins. Verify any length limits and allowed characters against the target model's WLAN setup addendum.",
      "category": "config",
      "syntax": "WLAN SSID \"<ssid>\"",
      "parameters": [
        {
          "name": "ssid",
          "description": "Quoted network name (ESSID)."
        }
      ],
      "whenToUse": "When provisioning a Wi-Fi-equipped TSC printer to join a specific access point. Pair with WLAN ENCRYPTION + WLAN PSK on WPA networks.",
      "example": {
        "source": "WLAN SSID \"OfficeWiFi\"",
        "description": "Set the target Wi-Fi network name"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-ssid/"
    },
    {
      "command": "WLAN PSK",
      "name": "Wi-Fi Pre-Shared Key",
      "description": "⚠️ Credential — appears in label source; do NOT commit to public repositories. Sets the WPA/WPA2/WPA3 pre-shared key passphrase (8–63 ASCII characters per IEEE 802.11i, or a 64-hex-char raw PSK). Effective only when `WLAN ENCRYPTION` is set to a WPA-family mode.",
      "category": "config",
      "syntax": "WLAN PSK \"<passphrase>\"",
      "parameters": [
        {
          "name": "passphrase",
          "description": "Quoted WPA passphrase (8–63 ASCII chars) or raw 64-hex-char PSK."
        }
      ],
      "whenToUse": "Together with WLAN SSID and WLAN ENCRYPTION to join a WPA-secured network. Treat the passphrase as a credential: keep label sources containing it out of version control or run them through a commit-time secret scanner.",
      "example": {
        "source": "WLAN PSK \"ChangeThisPassphrase\"",
        "description": "Set the WPA pre-shared key"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-psk/"
    },
    {
      "command": "WLAN ENCRYPTION",
      "name": "Wi-Fi Security Mode",
      "description": "Selects the Wi-Fi security mode the printer uses to associate. OPEN is unencrypted; WEP is legacy and insecure; WPA / WPA2 / WPA3 are the modern pre-shared-key modes (PSK comes from `WLAN PSK`). Enterprise-capable firmware may also accept WPA2-ENTERPRISE / WPA-EAP, which require certificate-handling sibling commands per the model's addendum. Verify exact spelling against the target model's WLAN setup addendum.",
      "category": "config",
      "syntax": "WLAN ENCRYPTION <mode>",
      "parameters": [
        {
          "name": "mode",
          "description": "Wi-Fi security mode (case-insensitive).",
          "values": [
            {
              "value": "OPEN",
              "description": "No encryption — for open networks only"
            },
            {
              "value": "WEP",
              "description": "Legacy WEP — insecure; avoid unless required by hardware"
            },
            {
              "value": "WPA",
              "description": "WPA-PSK (TKIP)"
            },
            {
              "value": "WPA2",
              "description": "WPA2-PSK (CCMP/AES) — recommended baseline"
            },
            {
              "value": "WPA3",
              "description": "WPA3-Personal (SAE) — if supported by firmware and AP"
            }
          ]
        }
      ],
      "whenToUse": "Once per Wi-Fi profile, before `WLAN PSK`. Must match the access point's configured security mode or association will fail.",
      "example": {
        "source": "WLAN ENCRYPTION WPA2",
        "description": "Select WPA2-PSK as the Wi-Fi security mode"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-encryption/"
    },
    {
      "command": "WLAN IP",
      "name": "Wi-Fi Static IP Address",
      "description": "Sets the static IPv4 address the Wi-Fi interface uses when DHCP is off. Ignored at boot when `WLAN DHCP ON` has been issued in the same profile.",
      "category": "config",
      "syntax": "WLAN IP \"<ipv4>\"",
      "parameters": [
        {
          "name": "ipv4",
          "description": "Quoted dotted-quad IPv4 address (e.g. \"192.168.1.50\")."
        }
      ],
      "whenToUse": "Only for static-IP deployments — typically paired with WLAN NETMASK + WLAN GATEWAY + WLAN DNS. Skip this command and use `WLAN DHCP ON` for DHCP-assigned addressing.",
      "example": {
        "source": "WLAN DHCP OFF\nWLAN IP \"192.168.1.50\"\nWLAN NETMASK \"255.255.255.0\"\nWLAN GATEWAY \"192.168.1.1\"",
        "description": "Configure a static IPv4 address"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-ip/"
    },
    {
      "command": "WLAN DHCP",
      "name": "Wi-Fi DHCP Toggle",
      "description": "Toggles DHCP client mode on the Wi-Fi interface. When ON, the printer obtains an IP/gateway/netmask/DNS automatically and the static-IP commands (`WLAN IP`, `WLAN GATEWAY`, `WLAN NETMASK`, `WLAN DNS`) are ignored at boot. When OFF, the static-IP commands take effect.",
      "category": "config",
      "syntax": "WLAN DHCP ON | WLAN DHCP OFF",
      "parameters": [
        {
          "name": "state",
          "description": "DHCP client mode (case-insensitive).",
          "values": [
            {
              "value": "ON",
              "description": "Obtain IP/gateway/netmask/DNS via DHCP — static-IP commands are ignored"
            },
            {
              "value": "OFF",
              "description": "Use the static-IP commands (WLAN IP, GATEWAY, NETMASK, DNS)"
            }
          ]
        }
      ],
      "whenToUse": "At most once per Wi-Fi profile. Default to `ON` for DHCP-managed networks; switch to `OFF` only when the deployment requires static addressing.",
      "example": {
        "source": "WLAN DHCP ON",
        "description": "Use DHCP for IPv4 addressing"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-dhcp/"
    },
    {
      "command": "WLAN GATEWAY",
      "name": "Wi-Fi Default Gateway",
      "description": "Sets the default-gateway IPv4 address the Wi-Fi interface routes traffic through when DHCP is off. Ignored at boot when `WLAN DHCP ON` has been issued.",
      "category": "config",
      "syntax": "WLAN GATEWAY \"<ipv4>\"",
      "parameters": [
        {
          "name": "ipv4",
          "description": "Quoted dotted-quad IPv4 address of the default gateway."
        }
      ],
      "whenToUse": "Together with WLAN IP + WLAN NETMASK for static-IP deployments.",
      "example": {
        "source": "WLAN GATEWAY \"192.168.1.1\"",
        "description": "Route traffic via 192.168.1.1"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-gateway/"
    },
    {
      "command": "WLAN NETMASK",
      "name": "Wi-Fi Subnet Mask",
      "description": "Sets the IPv4 subnet mask the Wi-Fi interface uses when DHCP is off. Ignored at boot when `WLAN DHCP ON` has been issued.",
      "category": "config",
      "syntax": "WLAN NETMASK \"<ipv4>\"",
      "parameters": [
        {
          "name": "ipv4",
          "description": "Quoted dotted-quad subnet mask (e.g. \"255.255.255.0\")."
        }
      ],
      "whenToUse": "Together with WLAN IP + WLAN GATEWAY for static-IP deployments.",
      "example": {
        "source": "WLAN NETMASK \"255.255.255.0\"",
        "description": "Use a /24 subnet mask"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-netmask/"
    },
    {
      "command": "WLAN DNS",
      "name": "Wi-Fi DNS Server",
      "description": "Sets the primary DNS server IPv4 address the Wi-Fi interface uses for hostname resolution when DHCP is off. Ignored at boot when `WLAN DHCP ON` has been issued.",
      "category": "config",
      "syntax": "WLAN DNS \"<ipv4>\"",
      "parameters": [
        {
          "name": "ipv4",
          "description": "Quoted dotted-quad IPv4 address of the primary DNS server."
        }
      ],
      "whenToUse": "Together with the other static-IP commands when the deployment can't rely on DHCP for DNS, or to override DHCP-supplied DNS on networks that mishandle it.",
      "example": {
        "source": "WLAN DNS \"8.8.8.8\"",
        "description": "Use 8.8.8.8 as the primary DNS resolver"
      },
      "previewSupported": false,
      "canonicalUrl": "https://rfid.me/reference/tspl/wlan-dns/"
    }
  ]
}
