import { A_START_CHAR, B_START_CHAR, C_START_CHAR, A_CHARS, B_CHARS, C_CHARS } from './constants'; // Match Set functions const matchSetALength = (string) => string.match(new RegExp(`^${A_CHARS}*`))[0].length; const matchSetBLength = (string) => string.match(new RegExp(`^${B_CHARS}*`))[0].length; const matchSetC = (string) => string.match(new RegExp(`^${C_CHARS}*`))[0]; // CODE128A or CODE128B function autoSelectFromAB(string, isA){ const ranges = isA ? A_CHARS : B_CHARS; const untilC = string.match(new RegExp(`^(${ranges}+?)(([0-9]{2}){2,})([^0-9]|$)`)); if (untilC) { return ( untilC[1] + String.fromCharCode(204) + autoSelectFromC(string.substring(untilC[1].length)) ); } const chars = string.match(new RegExp(`^${ranges}+`))[0]; if (chars.length === string.length) { return string; } return ( chars + String.fromCharCode(isA ? 205 : 206) + autoSelectFromAB(string.substring(chars.length), !isA) ); } // CODE128C function autoSelectFromC(string) { const cMatch = matchSetC(string); const length = cMatch.length; if (length === string.length) { return string; } string = string.substring(length); // Select A/B depending on the longest match const isA = matchSetALength(string) >= matchSetBLength(string); return cMatch + String.fromCharCode(isA ? 206 : 205) + autoSelectFromAB(string, isA); } // Detect Code Set (A, B or C) and format the string export default (string) => { let newString; const cLength = matchSetC(string).length; // Select 128C if the string start with enough digits if (cLength >= 2) { newString = C_START_CHAR + autoSelectFromC(string); } else { // Select A/B depending on the longest match const isA = matchSetALength(string) > matchSetBLength(string); newString = (isA ? A_START_CHAR : B_START_CHAR) + autoSelectFromAB(string, isA); } return newString.replace( /[\xCD\xCE]([^])[\xCD\xCE]/, // Any sequence between 205 and 206 characters (match, char) => String.fromCharCode(203) + char ); };