auto.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { A_START_CHAR, B_START_CHAR, C_START_CHAR, A_CHARS, B_CHARS, C_CHARS } from './constants';
  2. // Match Set functions
  3. const matchSetALength = (string) => string.match(new RegExp(`^${A_CHARS}*`))[0].length;
  4. const matchSetBLength = (string) => string.match(new RegExp(`^${B_CHARS}*`))[0].length;
  5. const matchSetC = (string) => string.match(new RegExp(`^${C_CHARS}*`))[0];
  6. // CODE128A or CODE128B
  7. function autoSelectFromAB(string, isA){
  8. const ranges = isA ? A_CHARS : B_CHARS;
  9. const untilC = string.match(new RegExp(`^(${ranges}+?)(([0-9]{2}){2,})([^0-9]|$)`));
  10. if (untilC) {
  11. return (
  12. untilC[1] +
  13. String.fromCharCode(204) +
  14. autoSelectFromC(string.substring(untilC[1].length))
  15. );
  16. }
  17. const chars = string.match(new RegExp(`^${ranges}+`))[0];
  18. if (chars.length === string.length) {
  19. return string;
  20. }
  21. return (
  22. chars +
  23. String.fromCharCode(isA ? 205 : 206) +
  24. autoSelectFromAB(string.substring(chars.length), !isA)
  25. );
  26. }
  27. // CODE128C
  28. function autoSelectFromC(string) {
  29. const cMatch = matchSetC(string);
  30. const length = cMatch.length;
  31. if (length === string.length) {
  32. return string;
  33. }
  34. string = string.substring(length);
  35. // Select A/B depending on the longest match
  36. const isA = matchSetALength(string) >= matchSetBLength(string);
  37. return cMatch + String.fromCharCode(isA ? 206 : 205) + autoSelectFromAB(string, isA);
  38. }
  39. // Detect Code Set (A, B or C) and format the string
  40. export default (string) => {
  41. let newString;
  42. const cLength = matchSetC(string).length;
  43. // Select 128C if the string start with enough digits
  44. if (cLength >= 2) {
  45. newString = C_START_CHAR + autoSelectFromC(string);
  46. } else {
  47. // Select A/B depending on the longest match
  48. const isA = matchSetALength(string) > matchSetBLength(string);
  49. newString = (isA ? A_START_CHAR : B_START_CHAR) + autoSelectFromAB(string, isA);
  50. }
  51. return newString.replace(
  52. /[\xCD\xCE]([^])[\xCD\xCE]/, // Any sequence between 205 and 206 characters
  53. (match, char) => String.fromCharCode(203) + char
  54. );
  55. };