Skip to content

Instantly share code, notes, and snippets.

@FrostBird347
Last active July 19, 2024 13:32
Show Gist options
  • Save FrostBird347/b3483b4f6b67a98d81a00c3b129a1ec9 to your computer and use it in GitHub Desktop.
Save FrostBird347/b3483b4f6b67a98d81a00c3b129a1ec9 to your computer and use it in GitHub Desktop.
A poorly made script that generates a scannable barcode out of unicode characters.
#!/usr/bin/env node
//code39.js
//A poorly made script that generates a scannable barcode out of unicode characters
//It was written after I found out that:
// - https://github.com/osresearch/barcode/ doesn't produce a scannable barcode in just about any font
// - There is a scannable unicode barcode shown in the unregistered preview of https://medium.com/weekly-webtips/how-to-generate-barcodes-code39-in-unicode-symbols-with-javascript-3d53559b877c
const Version = "1.1.0"
const RawMap = Object.freeze({
'A': '█▌▌▌*▌█▌',
'B': '▌█▌▌*▌█▌',
'C': '█▌█▌▌*▌▌',
'D': '▌▌█▌*▌█▌',
'E': '█▌▌█▌*▌▌',
'F': '▌█▌█▌*▌▌',
'G': '▌▌▌*█▌█▌',
'H': '█▌▌▌*█▌▌',
'I': '▌█▌▌*█▌▌',
'J': '▌▌█▌*█▌▌',
'K': '█▌▌▌▌*█▌',
'L': '▌█▌▌▌*█▌',
'M': '█▌█▌▌▌*▌',
'N': '▌▌█▌▌*█▌',
'O': '█▌▌█▌▌*▌',
'P': '▌█▌█▌▌*▌',
'Q': '▌▌▌█▌*█▌',
'R': '█▌▌▌█▌*▌',
'S': '▌█▌▌█▌*▌',
'T': '▌▌█▌█▌*▌',
'U': '█▌*▌▌▌█▌',
'V': '▌*█▌▌▌█▌',
'W': '█▌*█▌▌▌▌',
'X': '▌*▌█▌▌█▌',
'Y': '█▌*▌█▌▌▌',
'Z': '▌*█▌█▌▌▌',
'0': '▌▌*█▌█▌▌',
'1': '█▌▌*▌▌█▌',
'2': '▌█▌*▌▌█▌',
'3': '█▌█▌*▌▌▌',
'4': '▌▌*█▌▌█▌',
'5': '█▌▌*█▌▌▌',
'6': '▌█▌*█▌▌▌',
'7': '▌▌*▌█▌█▌',
'8': '█▌▌*▌█▌▌',
'9': '▌█▌*▌█▌▌',
' ': '▌*█▌▌█▌▌',
'-': '▌*▌▌█▌█▌',
'$': '▌*▌*▌*▌▌',
'%': '▌▌*▌*▌*▌',
'.': '█▌*▌▌█▌▌',
'/': '▌*▌*▌▌*▌',
'+': '▌*▌▌*▌*▌'
});
const AsciiMap = Object.freeze({
'\x00': RawMap['%'] + RawMap['U'],
'\x01': RawMap['$'] + RawMap['A'],
'\x02': RawMap['$'] + RawMap['B'],
'\x03': RawMap['$'] + RawMap['C'],
'\x04': RawMap['$'] + RawMap['D'],
'\x05': RawMap['$'] + RawMap['E'],
'\x06': RawMap['$'] + RawMap['F'],
'\x07': RawMap['$'] + RawMap['G'],
'\x08': RawMap['$'] + RawMap['H'],
'\x09': RawMap['$'] + RawMap['I'],
'\x0A': RawMap['$'] + RawMap['J'],
'\x0B': RawMap['$'] + RawMap['K'],
'\x0C': RawMap['$'] + RawMap['L'],
'\x0D': RawMap['$'] + RawMap['M'],
'\x0E': RawMap['$'] + RawMap['N'],
'\x0F': RawMap['$'] + RawMap['O'],
'\x10': RawMap['$'] + RawMap['P'],
'\x11': RawMap['$'] + RawMap['Q'],
'\x12': RawMap['$'] + RawMap['R'],
'\x13': RawMap['$'] + RawMap['S'],
'\x14': RawMap['$'] + RawMap['T'],
'\x15': RawMap['$'] + RawMap['U'],
'\x16': RawMap['$'] + RawMap['V'],
'\x17': RawMap['$'] + RawMap['W'],
'\x18': RawMap['$'] + RawMap['X'],
'\x19': RawMap['$'] + RawMap['Y'],
'\x1A': RawMap['$'] + RawMap['Z'],
'\x1B': RawMap['%'] + RawMap['A'],
'\x1C': RawMap['%'] + RawMap['B'],
'\x1D': RawMap['%'] + RawMap['C'],
'\x1E': RawMap['%'] + RawMap['D'],
'\x1F': RawMap['%'] + RawMap['E'],
'\x20': RawMap[' '],
'\x21': RawMap['/'] + RawMap['A'],
'\x22': RawMap['/'] + RawMap['B'],
'\x23': RawMap['/'] + RawMap['C'],
'\x24': RawMap['/'] + RawMap['D'],
'\x25': RawMap['/'] + RawMap['E'],
'\x26': RawMap['/'] + RawMap['F'],
'\x27': RawMap['/'] + RawMap['G'],
'\x28': RawMap['/'] + RawMap['H'],
'\x29': RawMap['/'] + RawMap['I'],
'\x2A': RawMap['/'] + RawMap['J'],
'\x2B': RawMap['/'] + RawMap['K'],
'\x2C': RawMap['/'] + RawMap['L'],
'\x2D': RawMap['-'],
'\x2E': RawMap['.'],
'\x2F': RawMap['/'] + RawMap['O'],
'\x30': RawMap['0'],
'\x31': RawMap['1'],
'\x32': RawMap['2'],
'\x33': RawMap['3'],
'\x34': RawMap['4'],
'\x35': RawMap['5'],
'\x36': RawMap['6'],
'\x37': RawMap['7'],
'\x38': RawMap['8'],
'\x39': RawMap['9'],
'\x3A': RawMap['/'] + RawMap['Z'],
'\x3B': RawMap['%'] + RawMap['F'],
'\x3C': RawMap['%'] + RawMap['G'],
'\x3D': RawMap['%'] + RawMap['H'],
'\x3E': RawMap['%'] + RawMap['I'],
'\x3F': RawMap['%'] + RawMap['J'],
'\x40': RawMap['%'] + RawMap['V'],
'\x41': RawMap['A'],
'\x42': RawMap['B'],
'\x43': RawMap['C'],
'\x44': RawMap['D'],
'\x45': RawMap['E'],
'\x46': RawMap['F'],
'\x47': RawMap['G'],
'\x48': RawMap['H'],
'\x49': RawMap['I'],
'\x4A': RawMap['J'],
'\x4B': RawMap['K'],
'\x4C': RawMap['L'],
'\x4D': RawMap['M'],
'\x4E': RawMap['N'],
'\x4F': RawMap['O'],
'\x50': RawMap['P'],
'\x51': RawMap['Q'],
'\x52': RawMap['R'],
'\x53': RawMap['S'],
'\x54': RawMap['T'],
'\x55': RawMap['U'],
'\x56': RawMap['V'],
'\x57': RawMap['W'],
'\x58': RawMap['X'],
'\x59': RawMap['Y'],
'\x5A': RawMap['Z'],
'\x5B': RawMap['%'] + RawMap['K'],
'\x5C': RawMap['%'] + RawMap['L'],
'\x5D': RawMap['%'] + RawMap['M'],
'\x5E': RawMap['%'] + RawMap['N'],
'\x5F': RawMap['%'] + RawMap['O'],
'\x60': RawMap['%'] + RawMap['W'],
'\x61': RawMap['+'] + RawMap['A'],
'\x62': RawMap['+'] + RawMap['B'],
'\x63': RawMap['+'] + RawMap['C'],
'\x64': RawMap['+'] + RawMap['D'],
'\x65': RawMap['+'] + RawMap['E'],
'\x66': RawMap['+'] + RawMap['F'],
'\x67': RawMap['+'] + RawMap['G'],
'\x68': RawMap['+'] + RawMap['H'],
'\x69': RawMap['+'] + RawMap['I'],
'\x6A': RawMap['+'] + RawMap['J'],
'\x6B': RawMap['+'] + RawMap['K'],
'\x6C': RawMap['+'] + RawMap['L'],
'\x6D': RawMap['+'] + RawMap['M'],
'\x6E': RawMap['+'] + RawMap['N'],
'\x6F': RawMap['+'] + RawMap['O'],
'\x70': RawMap['+'] + RawMap['P'],
'\x71': RawMap['+'] + RawMap['Q'],
'\x72': RawMap['+'] + RawMap['R'],
'\x73': RawMap['+'] + RawMap['S'],
'\x74': RawMap['+'] + RawMap['T'],
'\x75': RawMap['+'] + RawMap['U'],
'\x76': RawMap['+'] + RawMap['V'],
'\x77': RawMap['+'] + RawMap['W'],
'\x78': RawMap['+'] + RawMap['X'],
'\x79': RawMap['+'] + RawMap['Y'],
'\x7A': RawMap['+'] + RawMap['Z'],
'\x7B': RawMap['%'] + RawMap['P'],
'\x7C': RawMap['%'] + RawMap['Q'],
'\x7D': RawMap['%'] + RawMap['R'],
'\x7E': RawMap['%'] + RawMap['S'],
//idk which to use so we just pick a random one on startup because why not
'\x7F': [RawMap['%'] + RawMap['T'], RawMap['%'] + RawMap['X'], RawMap['%'] + RawMap['Y'], RawMap['%'] + RawMap['Z']][Math.floor(Math.random() * 4)]
});
const Marker = "▌*▌█▌█▌▌";// 
let Map = null;
function PrintHelp() {
console.log(`code39.js (version ${Version})\n`);
console.log("usage:");
console.log(" code39 [input]");
console.log(" code39 -r [input]");
console.log(" code39 -s [space length] [input]");
console.log(" code39 -rs [space length] [input]");
//Also there's a hidden mode for discord that minimises barcode size by using spoilers and other formatting
}
function CheckArgs() {
if (process.argv[2 + argOffset] == undefined) {
PrintHelp();
process.exit(1);
}
}
//let process = {argv: ["", "", "test"]};
let input = "";
let spaceCount = 1;
let argOffset = 0;
switch (process.argv[2]) {
case undefined:
case "-h":
PrintHelp()
process.exit(0);
break;
case "-s":
case "-sr":
case "-rs":
spaceCount = parseInt(process.argv[3]);
if (process.argv[3] == "d") {
spaceCount = 2;
}
argOffset++;
if (isNaN(spaceCount) || spaceCount < 0) {
PrintHelp();
process.exit(1);
}
case "-r":
argOffset++;
if (process.argv[2] != "-s") {
CheckArgs();
input = process.argv[2 + argOffset].toUpperCase().split("");
Map = RawMap;
break;
}
default:
CheckArgs();
input = process.argv[2 + argOffset].split("");
Map = AsciiMap;
}
let output = Marker.replaceAll("*", " ".repeat(spaceCount));
for (let i = 0; i < input.length; i++) {
output += Map[input[i]].replaceAll("*", " ".repeat(spaceCount));
}
output += Marker.replaceAll("*", " ".repeat(spaceCount));
if (process.argv[3] == "d") {
output = "-# " + output.replaceAll("▌", "|| || ").replaceAll("█", "|| ||");
}
console.log(output);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment