UNPKG

bwip-js

Version:

JavaScript barcode generator supporting over 100 types and standards.

305 lines (297 loc) 13.3 kB
#!/usr/bin/env node 'use strict'; var fs = require('fs'); var bwipjs = require('..'); var symdesc = require('../lib/symdesc'); function usage(exit) { console.log( "Usage: bwip-js symbol-name text [options...] file.{png,svg}\n" + " bwip-js --bcid=symbol-name --text=text [options...] file.{png,svg}\n" + "\n" + "Examples:\n" + " bwip-js code128 012345678 includetext textcolor=ff0000 my-code128.png\n" + " bwip-js qrcode 'https://bwip-js.metafloor.com' qrcode.svg\n" + "\n" + "'bwip-js --help' for more information.\n" + "'bwip-js --symbols' for a list of supported barcode symbols.\n" + "'bwip-js --version' for version information.\n" + ""); if (exit) { process.exit(1); } } function help() { usage(); for (var i = 0; i < optlist.length; i++) { console.log(' --' + optlist[i].name) console.log(indent(optlist[i].desc)); } console.log( "\nThe double-dashes '--' are not required before each option.\n" + "For example, you can specify '--includetext' or 'includetext'."); } // Indent the text 8 spaces function indent(text) { return text.replace(/^/, ' ').replace(/\n/g, '\n '); } // spec is one of: "font-name,y-mult,x-mult,path-to-font-file" // "font-name,size-mult,path-to-font-file" // "font-name,path-to-font-file" function loadfont(spec) { var vals = spec.split(','); try { if (vals.length == 4) { bwipjs.loadFont(vals[0], +vals[1], +vals[2], fs.readFileSync(vals[3])); } else if (vals.length == 3) { bwipjs.loadFont(vals[0], +vals[1], fs.readFileSync(vals[2])); } else if (vals.length == 2) { bwipjs.loadFont(vals[0], fs.readFileSync(vals[1])); } else { console.log("Invalid --loadfont format."); console.log("Try 'bwip-js --help' for more information."); process.exit(1); } } catch(e) { console.log('bwip-js: ' + e); process.exit(1); } } var optlist = [ { name: 'help', type: 'boolean', desc: 'Displays this help message.' }, { name: 'version', type: 'boolean', desc: 'Displays the bwip-js and BWIPP version strings.' }, { name: 'symbols', type: 'boolean', desc: 'Display a list of the supported barcode types.' }, { name: 'loadfont', type: 'string', desc: 'Loads a truetype/opentype font. Format of this option is one of:\n\n' + ' --loadfont=font-name,y-mult,x-mult,path-to-font-file\n' + ' --loadfont=font-name,size-mult,path-to-font-file\n' + ' --loadfont=font-name,path-to-font-file\n\n' + 'For example: --loadfont=Courier,100,120,c:\\windows\\fonts\\cour.ttf' }, // bwipjs options { name: 'bcid', type: 'string', desc: 'Barcode symbol name/type. Required.' }, { name: 'text', type: 'string', desc: 'The text to encode. Required.\n' + 'Use single quotes around the text to protect from the shell.' }, { name: 'scaleX', type: 'int', desc: 'The x-axis scaling factor. Must be an integer > 0. Default is 2.' }, { name: 'scaleY', type: 'int', desc: 'The y-axis scaling factor. Must be an integer > 0. Default is scaleX.' }, { name: 'scale', type: 'int', desc: 'Sets both the x-axis and y-axis scaling factors. Must be an integer > 0.' }, { name: 'rotate', type: 'string', desc: 'Rotates the image to one of the four orthogonal orientations.\n' + 'A string value. Must be one of:\n' + ' N : Normal orientation.\n' + ' R : Rotated right 90 degrees.\n' + ' L : Rotated left 90 degrees.\n' + ' I : Inverted, rotated 180 degrees.' }, { name: 'padding', type: 'int', desc: 'Shorthand for setting paddingtop, paddingleft, paddingright, and paddingbottom.' }, { name: 'paddingwidth', type: 'int', desc: 'Shorthand for setting paddingleft and paddingright.' }, { name: 'paddingheight', type: 'int', desc: 'Shorthand for setting paddingtop and paddingbottom.' }, { name: 'paddingtop', type: 'int', desc: 'Sets the height of the padding area, in points, on the top of\n' + 'the barcode image. Rotates and scales with the image.' }, { name: 'paddingleft', type: 'int', desc: 'Sets the width of the padding area, in points, on the left side\n' + 'of the barcode image. Rotates and scales with the image.' }, { name: 'paddingright', type: 'int', desc: 'Sets the width of the padding area, in points, on the right side\n' + 'of the barcode image. Rotates and scales with the image.' }, { name: 'paddingbottom', type: 'int', desc: 'Sets the height of the padding area, in points, on the bottom of\n' + 'the barcode image. Rotates and scales with the image.' }, // { name: 'monochrome', type: 'boolean', // desc: 'Sets the human-readable text to render in monochrome.\n' // 'Default is false which renders 256-level gray-scale anti-aliased text.' }, // bwipp options { name: 'alttext', type: 'string', desc: 'The human-readable text to use instead of the encoded text.' }, { name: 'includecheck', type: 'boolean', desc: 'Generate check digit(s) for symbologies where the use of check digits is\n' + 'optional.' }, { name: 'includecheckintext', type: 'boolean', desc: 'Show the calculated check digit in the human readable text.' }, { name: 'parse', type: 'boolean', desc: 'In supporting barcode symbologies, when the parse option is specified,\n' + 'any instances of ^NNN in the data field are replaced with their equivalent\n' + 'ASCII value, useful for specifying unprintable characters.' }, { name: 'parsefnc', type: 'boolean', desc: 'In supporting barcode symbologies, when the parsefnc option is specified,\n' + 'non-data function characters can be specified by escaped combinations such\n' + 'as ^FNC1, ^FNC4 and ^SFT.' }, { name: 'height', type: 'float', desc: 'Height of longest bar, in millimeters.' }, { name: 'width', type: 'float', desc: 'Stretch the symbol to approximately this width, in millimeters.\n' + 'Not recommended unless scale is at least 5.' }, { name: 'inkspread', type: 'float', desc: 'Amount by which to reduce the bar widths to compensate for inkspread,\n' + 'in points. Not recommended unless scale is at least 5.' }, { name: 'inkspreadh', type: 'float', desc: 'For matrix barcodes, the amount by which to reduce the width of dark\n' + 'modules to compensate for inkspread, in points.\n' + 'Not recommended unless scale is at least 5.\n\n' + 'Note: inkspreadh is most useful for stacked-linear type barcodes such as\n' + 'PDF417 and Codablock F.' }, { name: 'inkspreadv', type: 'float', desc: 'For matrix barcodes, the amount by which to reduce the height of dark\n' + 'modules to compensate for inkspread, in points.\n' + 'Not recommended unless scale is at least 5.' }, { name: 'dotty', type: 'boolean', desc: 'For matrix barcodes, render the modules as dots rather than squares.\n' + 'The dot radius can be adjusted using the inkspread option.' }, { name: 'includetext', type: 'boolean', desc: 'Show human readable text for data in symbol.' }, { name: 'textfont', type: 'string', desc: 'The font name to use for the text.' }, { name: 'textsize', type: 'int', desc: 'The font size of the text, in points.' }, { name: 'textgaps', type: 'int', desc: 'The inter-character spacing of the text.' }, { name: 'textxalign', type: 'string', desc: 'Specifies where to horizontally position the text.' }, { name: 'textyalign', type: 'string', desc: 'Specifies where to vertically position the text.' }, { name: 'textxoffset', type: 'int', desc: 'The horizontal position of the text, in points, relative to the\n' + 'default position.' }, { name: 'textyoffset', type: 'int', desc: 'The vertical position of the text, in points, relative to the\n' + 'default position.' }, { name: 'showborder', type: 'boolean', desc: 'Display a border around the symbol.' }, { name: 'borderwidth', type: 'int', desc: 'Width of a border, in points.' }, { name: 'borderleft', type: 'int', desc: 'Left margin gap of the border, in points.' }, { name: 'borderright', type: 'int', desc: 'Right margin gap of the border, in points.' }, { name: 'bordertop', type: 'int', desc: 'Top margin gap of the border, in points.' }, { name: 'borderbottom', type: 'int', desc: 'Bottom margin gap of the border, in points.' }, { name: 'barcolor', type: 'string', desc: 'Color of the bars, either as a hex RGB or RRGGBB value or a hex CCMMYYKK value.' }, { name: 'backgroundcolor', type: 'string', desc: 'Color of the image background, either as a hex RGB or RRGGBB value or a\n' + 'hex CCMMYYKK value. The default is a transparent background.' }, { name: 'bordercolor', type: 'string', desc: 'Color of the border, either as a hex RGB or RRGGBB value or a hex CCMMYYKK value.\n' + 'You must specify --showborder for this setting to take effect.' }, { name: 'textcolor', type: 'string', desc: 'Color of the text, either as a hex RGB or RRGGBB value or a hex CCMMYYKK value.' }, /* { name: 'addontextfont', type: 'string', desc: 'The font name to use for the add-on text in ISBN, ISMN, and ISSN barcodes.' }, { name: 'addontextsize', type: 'int', desc: 'The font size of the add on text, in points.' }, { name: 'addontextxoffset', type: 'int', desc: 'Overrides the default positioning for the add on text.' }, { name: 'addontextyoffset', type: 'int', desc: 'Overrides the default positioning for the add on text.' }, */ { name: 'guardwhitespace', type: 'boolean', desc: 'Display white space guards.' }, { name: 'guardwidth', type: 'int', desc: 'Width of white space guards, in points.' }, { name: 'guardheight', type: 'int', desc: 'Height of white space guards, in points.' }, { name: 'guardleftpos', type: 'int', desc: 'Amount of white space to guard to left of the symbol, in points.' }, { name: 'guardrightpos', type: 'int', desc: 'Amount of white space to guard to right of the symbol, in points.' }, { name: 'guardleftypos', type: 'int', desc: 'Vertical position of the guard symbols on the left, in points.' }, { name: 'guardrightypos', type: 'int', desc: 'Vertical position of the guard symbols on the right, in points.' }, ]; var optmap = optlist.reduce(function(map, elt) { map[elt.name] = elt; return map; }, {}); var opts = {}; var argv = process.argv; var outfile; if (argv.length == 2) { usage(true); } if (argv.length > 2 && !/^(--|bcid=)/.test(argv[2])) { argv[2] = 'bcid=' + argv[2]; } if (argv.length > 3 && !/^(--|text=)/.test(argv[3])) { argv[3] = 'text=' + argv[3]; } if (argv.length > 4 && !/^(--|\w+=)/.test(argv[argv.length-1])) { outfile = argv.pop(); if (!/\.(png|svg)$/.test(outfile)) { console.log(outfile + ": last argument must be a png or svg file name"); usage(true); } } for (var i = 2, l = argv.length; i < l; i++) { var a = argv[i]; if (/^--/.test(a)) { a = a.substr(2); } var eq = a.indexOf('='); if (eq > 0) { var name = a.substr(0, eq); var val = a.substr(eq+1); if (name == 'loadfont') { loadfont(val); } else { opts[name] = val; } } else if (optmap[a]) { if (optmap[a].type != 'boolean') { console.log('--' + a + ' : A value is expected.'); help(); process.exit(1); } opts[a] = true; } else { opts[a] = true; } } if (opts.help) { help(); } else if (opts.symbols) { var arr = []; for (var sym in symdesc) { arr.push(sym + ' : ' + symdesc[sym].desc); } arr.sort(); for (var i = 0; i < arr.length; i++) { console.log(' ' + arr[i]); } } else if (opts.version && !opts.bcid) { console.log('bwip-js: ' + bwipjs.BWIPJS_VERSION + '\nBWIPP: ' + bwipjs.BWIPP_VERSION); } else { if (!opts.bcid) { console.log('bwip-js: missing bcid'); usage(true); } else if (!opts.text) { console.log('bwip-js: missing text'); usage(true); } else if (!outfile) { console.log('bwip-js: missing outfile'); usage(true); } else if (outfile.slice(-3) == 'png') { bwipjs.toBuffer(opts, function (err, png) { if (err) { console.error(''+err); process.exit(1); } try { fs.writeFileSync(outfile, png); } catch (e) { console.log('bwip-js: ' + e); } }); } else { fs.writeFileSync(outfile, bwipjs.toSVG(opts)); } }