diff --git a/package.json b/package.json index a389dba..001e431 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,18 @@ "!**/__mocks__", "!**/.*" ], + "exports": { + ".": { + "require": "./lib/commonjs/index", + "import": "./lib/module/index", + "types": "./lib/typescript/src/index.d.ts" + }, + "./patterns": { + "require": "./lib/commonjs/patterns/index", + "import": "./lib/module/patterns/index", + "types": "./lib/typescript/src/patterns/index.d.ts" + } + }, "scripts": { "test": "jest", "typecheck": "tsc --noEmit", diff --git a/src/patterns/__tests__/hex-color.test.ts b/src/patterns/__tests__/hex-color.test.ts new file mode 100644 index 0000000..dc44624 --- /dev/null +++ b/src/patterns/__tests__/hex-color.test.ts @@ -0,0 +1,22 @@ +import { hexColorFinder, hexColorValidator } from '..'; + +test('hexColorValidator', () => { + expect(hexColorValidator).toMatchString('#ffffff'); + expect(hexColorValidator).toMatchString('#000'); + + expect(hexColorValidator).not.toMatchString('#000 '); + expect(hexColorValidator).not.toMatchString(' #000'); + expect(hexColorValidator).not.toMatchString('#0'); + expect(hexColorValidator).not.toMatchString('#11'); + expect(hexColorValidator).not.toMatchString('#4444'); + expect(hexColorValidator).not.toMatchString('#55555'); + expect(hexColorValidator).not.toMatchString('#7777777'); +}); + +test('hexColorFinder', () => { + expect(hexColorFinder).toMatchAllGroups('The color is #ffffff', [['#ffffff']]); + expect(hexColorFinder).toMatchAllGroups('The colors are #1, #22, #333, #4444, #55555, #666666', [ + ['#333'], + ['#666666'], + ]); +}); diff --git a/src/patterns/hex-color.ts b/src/patterns/hex-color.ts new file mode 100644 index 0000000..1a1a50c --- /dev/null +++ b/src/patterns/hex-color.ts @@ -0,0 +1,38 @@ +import { buildRegExp } from '../builders'; +import { endOfString, startOfString, wordBoundary } from '../constructs/anchors'; +import { charClass, charRange, digit } from '../constructs/character-class'; +import { choiceOf } from '../constructs/choice-of'; +import { repeat } from '../constructs/repeat'; + +const hexDigit = charClass(digit, charRange('a', 'f')); + +/** Find hex color strings in a text. */ +export const hexColorFinder = buildRegExp( + [ + '#', + choiceOf( + repeat(hexDigit, 6), // #rrggbb + repeat(hexDigit, 3), // #rgb + ), + wordBoundary, + ], + { ignoreCase: true, global: true }, +); + +/** + * Check that given text is a valid hex color. + * + * Allows both 3 and 6 digit hex colors. + * */ +export const hexColorValidator = buildRegExp( + [ + startOfString, // Match whole string + '#', + choiceOf( + repeat(hexDigit, 6), // #rrggbb + repeat(hexDigit, 3), // #rgb + ), + endOfString, + ], + { ignoreCase: true }, +); diff --git a/src/patterns/index.ts b/src/patterns/index.ts new file mode 100644 index 0000000..3222ce7 --- /dev/null +++ b/src/patterns/index.ts @@ -0,0 +1 @@ +export { hexColorFinder, hexColorValidator } from './hex-color';