diff --git a/components.d.ts b/components.d.ts
index be80e56e..db37f842 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -82,6 +82,7 @@ declare module '@vue/runtime-core' {
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default']
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
+ IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default']
IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default']
IconMdiCamera: typeof import('~icons/mdi/camera')['default']
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
@@ -159,6 +160,7 @@ declare module '@vue/runtime-core' {
NSwitch: typeof import('naive-ui')['NSwitch']
NTable: typeof import('naive-ui')['NTable']
NTag: typeof import('naive-ui')['NTag']
+ NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
NUpload: typeof import('naive-ui')['NUpload']
NUploadDragger: typeof import('naive-ui')['NUploadDragger']
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
diff --git a/src/tools/index.ts b/src/tools/index.ts
index 22db0770..fa63d3d1 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,6 +1,7 @@
import { tool as base64FileConverter } from './base64-file-converter';
import { tool as base64StringConverter } from './base64-string-converter';
import { tool as basicAuthGenerator } from './basic-auth-generator';
+import { tool as numeronymGenerator } from './numeronym-generator';
import { tool as macAddressGenerator } from './mac-address-generator';
import { tool as textToBinary } from './text-to-binary';
import { tool as ulidGenerator } from './ulid-generator';
@@ -153,7 +154,7 @@ export const toolsByCategory: ToolCategory[] = [
},
{
name: 'Text',
- components: [loremIpsumGenerator, textStatistics, emojiPicker, stringObfuscator, textDiff],
+ components: [loremIpsumGenerator, textStatistics, emojiPicker, stringObfuscator, textDiff, numeronymGenerator],
},
{
name: 'Data',
diff --git a/src/tools/numeronym-generator/index.ts b/src/tools/numeronym-generator/index.ts
new file mode 100644
index 00000000..19686922
--- /dev/null
+++ b/src/tools/numeronym-generator/index.ts
@@ -0,0 +1,12 @@
+import { defineTool } from '../tool';
+import n7mIcon from './n7m-icon.svg?component';
+
+export const tool = defineTool({
+ name: 'Numeronym generator',
+ path: '/numeronym-generator',
+ description: 'A numeronym is a word where a number is used to form an abbreviation. For example, "i18n" is a numeronym of "internationalization" where 18 stands for the number of letters between the first i and the last n in the word.',
+ keywords: ['numeronym', 'generator', 'abbreviation', 'i18n', 'a11y', 'l10n'],
+ component: () => import('./numeronym-generator.vue'),
+ icon: n7mIcon,
+ createdAt: new Date('2023-11-05'),
+});
diff --git a/src/tools/numeronym-generator/n7m-icon.svg b/src/tools/numeronym-generator/n7m-icon.svg
new file mode 100644
index 00000000..2470e44b
--- /dev/null
+++ b/src/tools/numeronym-generator/n7m-icon.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/tools/numeronym-generator/numeronym-generator.e2e.spec.ts b/src/tools/numeronym-generator/numeronym-generator.e2e.spec.ts
new file mode 100644
index 00000000..974a869a
--- /dev/null
+++ b/src/tools/numeronym-generator/numeronym-generator.e2e.spec.ts
@@ -0,0 +1,25 @@
+import { expect, test } from '@playwright/test';
+
+test.describe('Tool - Numeronym generator', () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto('/numeronym-generator');
+ });
+
+ test('Has correct title', async ({ page }) => {
+ await expect(page).toHaveTitle('Numeronym generator - IT Tools');
+ });
+
+ test('a numeronym is generated when a word is entered', async ({ page }) => {
+ await page.getByTestId('word-input').fill('internationalization');
+ const numeronym = await page.getByTestId('numeronym').inputValue();
+
+ expect(numeronym).toEqual('i18n');
+ });
+
+ test('when a word has 3 letters or less, the numeronym is the word itself', async ({ page }) => {
+ await page.getByTestId('word-input').fill('abc');
+ const numeronym = await page.getByTestId('numeronym').inputValue();
+
+ expect(numeronym).toEqual('abc');
+ });
+});
diff --git a/src/tools/numeronym-generator/numeronym-generator.service.test.ts b/src/tools/numeronym-generator/numeronym-generator.service.test.ts
new file mode 100644
index 00000000..ce92f891
--- /dev/null
+++ b/src/tools/numeronym-generator/numeronym-generator.service.test.ts
@@ -0,0 +1,15 @@
+import { describe, expect, it } from 'vitest';
+import { generateNumeronym } from './numeronym-generator.service';
+
+describe('numeronym-generator service', () => {
+ describe('generateNumeronym', () => {
+ it('a numeronym of a word is the first letter, the number of letters between the first and the last letter, and the last letter', () => {
+ expect(generateNumeronym('internationalization')).toBe('i18n');
+ expect(generateNumeronym('accessibility')).toBe('a11y');
+ expect(generateNumeronym('localization')).toBe('l10n');
+ });
+ it('a numeronym of a word with 3 letters is the word itself', () => {
+ expect(generateNumeronym('abc')).toBe('abc');
+ });
+ });
+});
diff --git a/src/tools/numeronym-generator/numeronym-generator.service.ts b/src/tools/numeronym-generator/numeronym-generator.service.ts
new file mode 100644
index 00000000..1c844715
--- /dev/null
+++ b/src/tools/numeronym-generator/numeronym-generator.service.ts
@@ -0,0 +1,11 @@
+export { generateNumeronym };
+
+function generateNumeronym(word: string): string {
+ const wordLength = word.length;
+
+ if (wordLength <= 3) {
+ return word;
+ }
+
+ return `${word.at(0)}${wordLength - 2}${word.at(-1)}`;
+}
diff --git a/src/tools/numeronym-generator/numeronym-generator.vue b/src/tools/numeronym-generator/numeronym-generator.vue
new file mode 100644
index 00000000..2332b338
--- /dev/null
+++ b/src/tools/numeronym-generator/numeronym-generator.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+