Barcode
A Code 128 barcode drawn as SVG from text, switching to the compact digit set for long numbers, with the text under it.
Demo
12 symbols, drawn in the browser as you type.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/barcode.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/barcode.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/barcode.qwe
component BarcodeDemoLive() { state text = "Hello 2026" <div.demo-stack style="justify-items: start"> <label style="display: grid; gap: 4px; font-size: 13px; width: min(320px, 100%)">Text to encode <input id="barcode-demo-input" value={text} @input={(e) => { text = e.value }} style="height: 34px; padding: 0 10px; border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); background: var(--ui-surface); color: var(--ui-fg); font: inherit"/> </label> <Barcode id="barcode-demo-live" text={text}/> <p.demo-note>{len(barcode_values(text))} symbols, drawn in the browser as you type.</p> </div>}view BarcodeDemo() = <div.demo-stack> <div.demo-row style="align-items: flex-end; gap: 28px"> <Barcode id="barcode-demo-ticket" text="QA204-LHR-OPO"/> <Barcode id="barcode-demo-digits" text="0012345678905" bar={1.5} height={48}/> <Barcode id="barcode-demo-bare" text="Order 98765" show_text={false} height={40} themed={true} label="Order number"/> </div> <BarcodeDemoLive/> </div>Source
ui/barcode.qwe
// Barcode: a Code 128 barcode as SVG from text: an order number, a parcel's label,// a ticket's code. The encoder is written here in Quillo (no library), so it draws// the same on the server and in the browser. It uses code set B for text and// switches to code set C (two digits a bar pattern) for runs of four digits or// more, so long numbers stay short; the check symbol is the standard's (mod 103).//// <Barcode text="QA204-LHR-OPO"/>// <Barcode text="0012345678905" bar={1.5} height={48} show_text={false}/>//// text: what it encodes: printable ASCII (space to ~); another character is// written as "?". bar: the width of the narrowest bar in px (2). height: the bars'// height in px (64). show_text: the text written under it (true). label: what// screen readers hear ("Barcode: " and the text by default). quiet: the light// margin at each end, in narrow bars (10, as the standard asks). themed: false// (default) keeps it dark on light whatever the page's theme; true follows it.// barcode_values(text) gives the symbols' values (start, data, check, stop) and// barcode_modules(text) the bars as a string of 1 (bar) and 0 (space).import ui/theme.qwe use ui_clslet barcode_css = css`.ui-barcode { display: inline-grid; justify-items: center; gap: 4px; max-width: 100%; margin: 0; padding: 6px 0 4px; background: var(--ui-surface); color: var(--ui-fg); border-radius: 4px; font: 13px/1.2 var(--ui-mono); }.ui-barcode svg { display: block; max-width: 100%; }.ui-barcode figcaption { letter-spacing: .12em; white-space: pre; }`// The patterns of values 0 to 105 (11 modules each, 1 a bar), and the stop's (13).let barcode_patterns = [ "11011001100", "11001101100", "11001100110", "10010011000", "10010001100", "10001001100", "10011001000", "10011000100", "10001100100", "11001001000", "11001000100", "11000100100", "10110011100", "10011011100", "10011001110", "10111001100", "10011101100", "10011100110", "11001110010", "11001011100", "11001001110", "11011100100", "11001110100", "11101101110", "11101001100", "11100101100", "11100100110", "11101100100", "11100110100", "11100110010", "11011011000", "11011000110", "11000110110", "10100011000", "10001011000", "10001000110", "10110001000", "10001101000", "10001100010", "11010001000", "11000101000", "11000100010", "10110111000", "10110001110", "10001101110", "10111011000", "10111000110", "10001110110", "11101110110", "11010001110", "11000101110", "11011101000", "11011100010", "11011101110", "11101011000", "11101000110", "11100010110", "11101101000", "11101100010", "11100011010", "11101111010", "11001000010", "11110001010", "10100110000", "10100001100", "10010110000", "10010000110", "10000101100", "10000100110", "10110010000", "10110000100", "10011010000", "10011000010", "10000110100", "10000110010", "11000010010", "11001010000", "11110111010", "11000010100", "10001111010", "10100111100", "10010111100", "10010011110", "10111100100", "10011110100", "10011110010", "11110100100", "11110010100", "11110010010", "11011011110", "11011110110", "11110110110", "10101111000", "10100011110", "10001011110", "10111101000", "10111100010", "11110101000", "11110100010", "10111011110", "10111101110", "11101011110", "11110101110", "11010000100", "11010010000", "11010011100", "1100011101011",]let barcode_ascii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"// How many digits run from place i.fn barcode_digits(chars: list, i: int) -> int { let n = 0 while i + n < len(chars) && contains("0123456789", chars[i + n]) { n = n + 1 } n}// The values of the symbols: start, data (in set B or C), check symbol, stop.fn barcode_values(text: str) -> list { let chars = split(text, "") | map((c) => index_of(barcode_ascii, c) != null ? c : "?") let lead = barcode_digits(chars, 0) let c_first = len(chars) >= 2 && lead % 2 == 0 && (lead >= 4 || lead == len(chars)) let out = [c_first ? 105 : 104] let in_c = c_first let i = 0 while i < len(chars) { let run = barcode_digits(chars, i) if in_c { if run >= 2 { out = push(out, int(chars[i] + chars[i + 1])) i = i + 2 } else { out = push(out, 100) in_c = false } } else if run >= 4 && run % 2 == 0 { out = push(out, 99) in_c = true } else { out = push(out, index_of(barcode_ascii, chars[i])) i = i + 1 } } let check = (out[0] + sum(for [k, v] in enumerate(drop(out, 1)) => (k + 1) * v)) % 103 push(push(out, check), 106)}// The bars and spaces of a text, as a string of 1 and 0.fn barcode_modules(text: str) -> str = join(barcode_values(text) | map((v) => barcode_patterns[v]), "")view Barcode(text: str, bar: num = 2, height: int = 64, show_text: bool = true, label: str? = null, quiet: int = 10, themed: bool = false, id: str? = null, class: str? = null) { style global barcode_css let mods = barcode_modules(text) let total = len(mods) + 2 * quiet // Written as the browser would: 396, not 396.0. let w = round(total * bar * 10) / 10 let width = w == floor(w) ? str(floor(w)) : str(w) let d = join(re.find_all(mods, "1+") | map((m) => `M${m.start + quiet} 0h${len(m.text)}v1h-${len(m.text)}z`), "") <figure class={ui_cls(["ui-barcode", !themed && "ui-light", class])} id={id}> <svg width={width} height={height} viewBox={`0 0 ${total} 1`} preserveAspectRatio="none" role="img" aria-label={label ?? `Barcode: ${text}`} shape-rendering="crispEdges"> <path fill="currentColor" d={d}/> </svg> {show_text && <figcaption aria-hidden="true">{text}</figcaption>} </figure>}Related
QrCodeA QR code drawn as SVG by an encoder written in Quillo: any text as UTF-8, level M, versions 1 to 10, the same on the server and in the browser.10 views · 8 downloadsChangelogReleases with version, date and label, their changes grouped by kind: Added, Changed, Fixed, Security and the rest.6 views · 7 downloadsComparisonTableFeatures down the side and options across, with ticks, crosses and values in the cells, and one option picked out.5 views · 6 downloadsInvoiceA printable invoice: parties, number and dates, lines with quantity and unit price, totals, paid and balance, notes and terms.6 views · 6 downloadsPriceBreakdownWhat a price is made of, a line each (a discount in green), and the total.6 views · 4 downloadsRatingSummaryThe average rating out of 5, how many ratings, and a bar per star count, each a filter button or link if you like.6 views · 5 downloads
Thread
Thread 0 posts
On Barcode: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.