npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@levischuck/receiptline

v0.1.5

Published

Markdown for receipts. Printable digital receipts. Generate receipt printer commands and images.

Readme

ReceiptLine

Markdown for receipts. Printable digital receipts. 茶 Generate receipt printer commands, SVG images, and HTML documents.

ReceiptLine is the receipt description language that expresses the output image of small roll paper. It supports printing paper receipts using a receipt printer and displaying electronic receipts on a POS system or smartphone. It can be described simply with receipt markdown text data that does not depend on the paper width.

Installation

$ npm install @levischuck/receiptline

Usage

receiptline.transform() method transforms ReceiptLine document to printer commands, SVG images, or HTML documents.

import { transform, SvgTarget, HtmlTarget } from "@levischuck/receiptline";

const body = `Example Receipt
{image:iVBORw0KGgoAAAANSUhEUgAAAHAAAAAYCAMAAAAVmYlOAAAAAXNSR0IB2cksfwAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZQTFRFAAAA////pdmf3QAAAAlwSFlzAAAuIwAALiMBeKU/dgAAALZJREFUSMftlVESgCAIROH+l25qLIUFRMfpw9EvU5ZnuBTxz4MOcAsglRFEyU0lCKUR0Nc5wLI6A3zTpIGtYBbIo0BeA1TFfeYpoL4VyBIC69I9HQC+kZilRDklFblooKTG2pckMo0IGjGNFOLxrLaoDz7QbAsUymgyG1/sxkB84TSQ3cuL2sK8I7ek6NIuMOQvASqX5oE+kfAIbeeRfuqYllj1HtrC0bceypUUPkraOOePvwvwAi2zCEzzMOsBAAAAAElFTkSuQmCC}
(Merchant Copy)
---

{w: * 4 8}
{b:line}
|Product | Qty| Price
--
|Pad Thai | 1| 14.99
|Spring Roll | 1| 4.99
--
{w:* 8}
| Subtotal| 19.98
| Tax (6%)| 1.20
| Convenience Fee| 0.99
| Total| 22.17
---
{b:space}
{w:auto}
Please Sign:



---

{c:https://levischuck.com;o:qrcode,6}

Please Take our Survey`;

// SVG Target
const svgTarget = new SvgTarget();
svgTarget.setDefaultFont("'Atkinson Hyperlegible Mono'");
const {content: svg, width, height} = await transform(body, {
  cpl: charactersPerLine,
  charWidth: charWidth,
  target: svgTarget,
});

// HTML Target
const htmlTarget = new HtmlTarget();
htmlTarget.setDefaultFont("'Google Sans Code', monospace");
htmlTarget.setActualFontCharacterWidth(13.2); // Actual measured width of your font
htmlTarget.setCharHeight(24); // Character height in pixels
const {content: html, width: htmlWidth, height: htmlHeight} = await transform(body, {
  cpl: charactersPerLine,
  charWidth: charWidth,
  target: htmlTarget,
});
c
// Do something interesting with the SVG or HTML afterwards

Method

transform(doc[, options])

Parameters

  • doc
    • a string of ReceiptLine document
  • options
    • an object of printer configuration

Return value

  • content: SVG Image (for SvgTarget) or HTML string (for HtmlTarget)
  • width: Width of the generated content in pixels
  • height: Height of the generated content in pixels

Printer configuration

  • cpl
    • characters per line (default: 48)
  • charWidth
    • dot width of each character (default: 12).
  • spacing
    • false: no line spacing (default)
    • true: line spacing
  • margin (for printer)
    • print margin (left) (range: 0 - 24, default: 0)
  • marginRight (for printer)
    • print margin (right) (range: 0 - 24, default: 0)
  • target What implementation to use (SvgTarget for SVG output, HtmlTarget for HTML output, instantiate your own to set additional configuration like font)
  • encoding
    • cp437 (default), others exist if you need to look. They mostly adjust line spacing and default fonts.

cpl * charWidth will be the output width, which by default is 576 dots.

HTML Target Configuration

The HTML target provides additional configuration options to account for differences with web fonts and the defaults this library expects for a thermal printer.

  • setDefaultFont(font: string) - Sets the CSS font-family for the receipt (default: "'Courier Prime', monospace")
  • setActualFontCharacterWidth(width: number | undefined) - Sets the actual measured character width of your font in pixels. It'll keep the text from going off the side when correctly set.
  • setCharHeight(height: number | undefined) - Explicitly sets the character height in pixels. If not set, defaults to charWidth * 2 (usually 12 * 2)

When using the HTML target, you may need to measure your font's actual character width for optimal layout. This is especially important when using web fonts that don't fit the 12 dot wide, 24 dot tall convention.

const htmlTarget = new HtmlTarget();
htmlTarget.setDefaultFont("'Google Sans Code', monospace");
htmlTarget.setActualFontCharacterWidth(13.2);
htmlTarget.setCharHeight(24.7);

Examples

example/data/*

The documents (receipt markdown text) are the same as the examples in the OFSC ReceiptLine Specification.

Grammar

Structure

The receipt is made of a table, which separates each column with a pipe |.

|Line|Content|Description| |---|---|---| |column| column || columncolumn ||TextProperty|Single column| |column | column | column | column || column | columncolumn | column ||Text|Double column| |column | ... | column| column | ... | column || column | ... | columncolumn | ... | column ||Text|Multiple columns|

Alignment

The column is attracted to the pipe | like a magnet. means one or more whitespaces.

|Column|Description| |---|---| |column|column||␣column␣||Center| ||column|column␣|column␣||Left| |column||␣column||␣column|Right|

Text

The text is valid for any column.

Asparagus | 0.99
Broccoli | 1.99
Carrot | 2.99
---
^TOTAL | ^5.97

Characters are printed in a monospace font (12 x 24 px). Wide characters are twice as wide as Latin characters (24 x 24 px). Control characters are ignored.

Special characters in text

Special characters are assigned to characters that are rarely used in the receipt.

|Special character|Description| |---|---| |\|Character escape| |||Column delimiter| |{|Property delimiter (Start)| |}|Property delimiter (End)| |- (1 or more, exclusive)|Horizontal rule| |= (1 or more, exclusive)|Paper cut| |~|Space| |_|Underline| |"|Emphasis| |`|Invert| |^|Double width| |^^|Double height| |^^^|2x size| |^^^^|3x size| |^^^^^|4x size| |^^^^^^|5x size| |^^^^^^^ (7 or more)|6x size|

Escape sequences in text

Escape special characters.

|Escape sequence|Description| |---|---| |\\|\| |\|||| |\{|{| |\}|}| |\-|- (Cancel horizontal rule)| |\=|= (Cancel paper cut)| |\~|~| |\_|_| |\"|_| |\` |`| |\^|^| |\n|Wrap text manually| |\xnn|Hexadecimal character code| |\char (Others)|Ignore|

Properties

The property is valid for lines with a single column.

{ width: * 10; comment: the column width is specified in characters }

|Key|Abbreviation|Value|Case-sensitive|Default|Saved|Description| |---|---|---|---|---|---|---| |image|i|base64 png format|✓|-|-|Image(Recommended: monochrome, critical chunks only)| |code|c|textdata|✓|-|-|Barcode / 2D code| |option|o|see below|-|code128 2 72 nohri 3 l|✓|Barcode / 2D code options(Options are separated by commas or one or more whitespaces)| |align|a|leftcenterright|-|center|✓|Line alignment(Valid when line width < CPL)| |width|w|auto*0 -|-|auto(* for all columns)|✓|Column widths (chars)(Widths are separated by commas or one or more whitespaces)| |border|b|linespacenone0 - 2|-|space|✓|Column border (chars)(Border width: line=1, space=1, none=0)| |text|t|wrapnowrap|-|wrap|✓|Text wrapping| |command|x|textdata|✓|-|-|Device-specific commands| |comment|_|textdata|✓|-|-|Comment|

Barcode options

Barcode options are separated by commas or one or more whitespaces.

|Barcode option|Description| |---|---| |upc|UPC-A, UPC-E(Check digit can be omitted)| |eanjan|EAN-13, EAN-8(Check digit can be omitted)| |code39|CODE39| |itf|Interleaved 2 of 5| |codabarnw7|Codabar (NW-7)| |code93|CODE93| |code128|CODE128| |2 - 4|Barcode module width (px)| |24 - 240|Barcode module height (px)| |hri|With human readable interpretation| |nohri|Without human readable interpretation|

2D code options

2D code options are separated by commas or one or more whitespaces.

|2D code option|Description| |---|---| |qrcode|QR Code| |3 - 8|Cell size (px)| |lmqh|Error correction level|

Special characters in property values

Special characters in property values are different from special characters in text.

|Special character|Description| |---|---| |\|Character escape| |||Column delimiter| |{|Property delimiter (Start)| |}|Property delimiter (End)| |:|Key-value separator| |;|Key-value delimiter|

Escape sequences in property values

Escape special characters.

|Escape sequence|Description| |---|---| |\\|\| |\|||| |\{|{| |\}|}| |\;|;| |\n|New line| |\xnn|Hexadecimal character code| |\char (Others)|Ignore|

Why use this one over the reference implementation?

The original library has a weird hack to generate UUIDs on insecure contexts to get around a currently debated WebCrypto standards detail. This prevented me from deploying to Cloudflare workers. This fork and typescript adjustment is enough to unblock my objective.

I also wanted to use a diferent font.

License

Apache 2 Licensed, per the original source

The word "QR Code" is registered trademark of DENSO WAVE INCORPORATED http://www.denso-wave.com/qrcode/faqpatent-e.html

Author

Open Foodservice System Consortium http://www.ofsc.or.jp/

Levi Schuck https://levischuck.com/