Skip to content

Commit 2821655

Browse files
committed
feat(new tool): unicode to java entities
1 parent e876d03 commit 2821655

File tree

9 files changed

+184
-4
lines changed

9 files changed

+184
-4
lines changed

components.d.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
// @ts-nocheck
44
// Generated by unplugin-vue-components
55
// Read more: https://github.com/vuejs/core/pull/3399
6-
import '@vue/runtime-core'
7-
86
export {}
97

10-
declare module '@vue/runtime-core' {
8+
declare module 'vue' {
119
export interface GlobalComponents {
1210
'404.page': typeof import('./src/pages/404.page.vue')['default']
1311
About: typeof import('./src/pages/About.vue')['default']
@@ -90,16 +88,24 @@ declare module '@vue/runtime-core' {
9088
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
9189
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
9290
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
91+
IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default']
92+
IconMdiCamera: typeof import('~icons/mdi/camera')['default']
9393
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
9494
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
9595
IconMdiClose: typeof import('~icons/mdi/close')['default']
9696
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
97+
IconMdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
98+
IconMdiDownload: typeof import('~icons/mdi/download')['default']
9799
IconMdiEye: typeof import('~icons/mdi/eye')['default']
98100
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
99101
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
102+
IconMdiPause: typeof import('~icons/mdi/pause')['default']
103+
IconMdiPlay: typeof import('~icons/mdi/play')['default']
104+
IconMdiRecord: typeof import('~icons/mdi/record')['default']
100105
IconMdiSearch: typeof import('~icons/mdi/search')['default']
101106
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
102107
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
108+
IconMdiVideo: typeof import('~icons/mdi/video')['default']
103109
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
104110
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
105111
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
@@ -126,25 +132,33 @@ declare module '@vue/runtime-core' {
126132
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
127133
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
128134
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
135+
NAlert: typeof import('naive-ui')['NAlert']
129136
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
137+
NCheckbox: typeof import('naive-ui')['NCheckbox']
130138
NCode: typeof import('naive-ui')['NCode']
131139
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
140+
NColorPicker: typeof import('naive-ui')['NColorPicker']
132141
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
133142
NDivider: typeof import('naive-ui')['NDivider']
134143
NEllipsis: typeof import('naive-ui')['NEllipsis']
144+
NForm: typeof import('naive-ui')['NForm']
135145
NFormItem: typeof import('naive-ui')['NFormItem']
136146
NGi: typeof import('naive-ui')['NGi']
137147
NGrid: typeof import('naive-ui')['NGrid']
138148
NH1: typeof import('naive-ui')['NH1']
139149
NH3: typeof import('naive-ui')['NH3']
140150
NIcon: typeof import('naive-ui')['NIcon']
151+
NInputGroup: typeof import('naive-ui')['NInputGroup']
152+
NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
141153
NInputNumber: typeof import('naive-ui')['NInputNumber']
142-
NLabel: typeof import('naive-ui')['NLabel']
143154
NLayout: typeof import('naive-ui')['NLayout']
144155
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
145156
NMenu: typeof import('naive-ui')['NMenu']
146157
NScrollbar: typeof import('naive-ui')['NScrollbar']
158+
NSlider: typeof import('naive-ui')['NSlider']
147159
NSpin: typeof import('naive-ui')['NSpin']
160+
NSwitch: typeof import('naive-ui')['NSwitch']
161+
NTable: typeof import('naive-ui')['NTable']
148162
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
149163
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
150164
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
@@ -179,6 +193,7 @@ declare module '@vue/runtime-core' {
179193
'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default']
180194
ToolCard: typeof import('./src/components/ToolCard.vue')['default']
181195
UlidGenerator: typeof import('./src/tools/ulid-generator/ulid-generator.vue')['default']
196+
UnicodeCharactersToJavaEntities: typeof import('./src/tools/unicode-characters-to-java-entities-converter/unicode-characters-to-java-entities.vue')['default']
182197
UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default']
183198
UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default']
184199
UserAgentParser: typeof import('./src/tools/user-agent-parser/user-agent-parser.vue')['default']

locales/en.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,7 @@ tools:
391391
text-to-binary:
392392
title: Text to ASCII binary
393393
description: Convert text to its ASCII binary representation and vice-versa.
394+
395+
unicode-to-java-entites:
396+
title: Unicode Characters to Java Entities Converter
397+
description: Unicode Characters to Java Entities Converter and vice-versa

locales/vi.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,7 @@ tools:
380380
text-to-binary:
381381
title: Chuyển đổi văn bản thành nhị phân ASCII
382382
description: Chuyển đổi văn bản thành biểu diễn nhị phân ASCII của nó và ngược lại.
383+
384+
unicode-to-java-entites:
385+
title: Chuyển đổi ký tự Unicode sang thực thể Java
386+
description: Chuyển đổi ký tự Unicode sang thực thể Java và ngược lại

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ import { tool as uuidGenerator } from './uuid-generator';
8181
import { tool as macAddressLookup } from './mac-address-lookup';
8282
import { tool as xmlFormatter } from './xml-formatter';
8383
import { tool as yamlViewer } from './yaml-viewer';
84+
import { tool as unicodeToJavaEntities } from './unicode-characters-to-java-entities-converter';
8485

8586
export const toolsByCategory: ToolCategory[] = [
8687
{
@@ -107,6 +108,7 @@ export const toolsByCategory: ToolCategory[] = [
107108
listConverter,
108109
tomlToJson,
109110
tomlToYaml,
111+
unicodeToJavaEntities,
110112
],
111113
},
112114
{
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { TextWrapDisabled } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
import { translate } from '@/plugins/i18n.plugin';
4+
5+
export const tool = defineTool({
6+
name: translate('tools.unicode-to-java-entites.title'),
7+
path: '/unicode-to-java-entites',
8+
description: translate('tools.unicode-to-java-entites.description'),
9+
keywords: ['text', 'to', 'unicode'],
10+
component: () => import('./unicode-characters-to-java-entities.vue'),
11+
icon: TextWrapDisabled,
12+
createdAt: new Date('2024-01-31'),
13+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
function strlenFix(str: string): string {
2+
while (str.length < 4) {
3+
str = `0${str}`;
4+
}
5+
return str;
6+
}
7+
8+
function parseUnicodeToJavaEntities(source: string, direction: '0' | '-1'): string {
9+
let result = '';
10+
11+
if (direction === '0') {
12+
// UTF-8 to entities
13+
for (let i = 0; i < source.length; i++) {
14+
const charCode = source.charCodeAt(i);
15+
if (charCode <= 127) {
16+
result += source.charAt(i);
17+
}
18+
else {
19+
result += `\\u${strlenFix(charCode.toString(16).toUpperCase())}`;
20+
}
21+
}
22+
}
23+
else {
24+
// Entities to UTF-8
25+
let state: 0 | 1 | 2 = 0;
26+
let chars = 0;
27+
let value = '';
28+
for (let i = 0; i < source.length; i++) {
29+
switch (state) {
30+
case 0:
31+
if (source.charAt(i) === '\\') {
32+
state = 1;
33+
}
34+
else {
35+
result += source.charAt(i);
36+
}
37+
break;
38+
case 1:
39+
if (source.charAt(i) === 'u') {
40+
state = 2;
41+
chars = 0;
42+
value = '';
43+
}
44+
else {
45+
result += `\\${source.charAt(i)}`;
46+
state = 0;
47+
}
48+
break;
49+
case 2:
50+
chars++;
51+
value += source.charAt(i);
52+
if (chars >= 4) {
53+
result += String.fromCharCode(Number.parseInt(value, 16));
54+
state = 0;
55+
}
56+
break;
57+
}
58+
}
59+
}
60+
return result;
61+
}
62+
63+
export { parseUnicodeToJavaEntities };
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { expect, test } from '@playwright/test';
2+
3+
test.describe('Tool - Unicode to Java entities', () => {
4+
test.beforeEach(async ({ page }) => {
5+
await page.goto('/unicode-to-java-entites');
6+
});
7+
8+
test('Has correct title', async ({ page }) => {
9+
await expect(page).toHaveTitle('Unicode to Java Entities - IT Tools');
10+
});
11+
12+
test('Unicode to Entities conversion', async ({ page }) => {
13+
await page.getByTestId('unicode-to-entities-input').fill('việt nam');
14+
const unicode = await page.getByTestId('unicode-to-entities-output').inputValue();
15+
16+
expect(unicode).toEqual('vi\u1EC7t nam');
17+
});
18+
19+
test('Entities to Unicode conversion', async ({ page }) => {
20+
await page.getByTestId('entities-to-unicode-input').fill('vi\u1EC7t nam');
21+
const text = await page.getByTestId('entities-to-unicode-output').inputValue();
22+
23+
expect(text).toEqual('việt nam');
24+
});
25+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { parseUnicodeToJavaEntities } from './unicode-characters-to-java-entities.service';
3+
4+
describe('unicode-to-entities', () => {
5+
describe('convertTextToUnicode', () => {
6+
it('a unicode string is converted to java entities representation', () => {
7+
expect(parseUnicodeToJavaEntities('là', '0')).toBe('l\u00E0');
8+
expect(parseUnicodeToJavaEntities('sơn tùng MTP', '0')).toBe('s\u01A1n t\u00F9ng MTP');
9+
expect(parseUnicodeToJavaEntities('', '0')).toBe('');
10+
});
11+
});
12+
13+
describe('entities-to-unicode', () => {
14+
it('java entities string is converted to its unicode representation', () => {
15+
expect(parseUnicodeToJavaEntities('l\u00E0', '-1')).toBe('là');
16+
expect(parseUnicodeToJavaEntities('s\u01A1n t\u00F9ng MTP', '-1')).toBe('sơn tùng MTP');
17+
expect(parseUnicodeToJavaEntities('', '-1')).toBe('');
18+
});
19+
});
20+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script setup lang="ts">
2+
import { parseUnicodeToJavaEntities } from './unicode-characters-to-java-entities.service';
3+
import { useCopy } from '@/composable/copy';
4+
5+
const inputUnicode = ref('');
6+
const entitiesFromUnicode = computed(() => inputUnicode.value.trim() === '' ? '' : parseUnicodeToJavaEntities(inputUnicode.value, '0'));
7+
const { copy: copyUnicode } = useCopy({ source: entitiesFromUnicode });
8+
9+
const inputJavaEntities = ref('');
10+
const unicodeFromEntities = computed(() => inputJavaEntities.value.trim() === '' ? '' : parseUnicodeToJavaEntities(inputJavaEntities.value, '-1'));
11+
const { copy: copyText } = useCopy({ source: unicodeFromEntities });
12+
</script>
13+
14+
<template>
15+
<c-card title="Unicode Characters to Java entities">
16+
<c-input-text v-model:value="inputUnicode" multiline placeholder="e.g. 'Hello Avengers'" label="Enter Unicode Characters to convert to Java entities" autosize autofocus raw-text test-id="unicode-to-entities-input" />
17+
<c-input-text v-model:value="entitiesFromUnicode" label="Java entities from your text" multiline raw-text readonly mt-2 placeholder="The unicode representation of your text will be here" test-id="unicode-to-entities-output" />
18+
<div mt-2 flex justify-center>
19+
<c-button :disabled="!entitiesFromUnicode" @click="copyUnicode()">
20+
Copy unicode to clipboard
21+
</c-button>
22+
</div>
23+
</c-card>
24+
25+
<c-card title="Java entities to Unicode Characters">
26+
<c-input-text v-model:value="inputJavaEntities" multiline placeholder="Input Java entities" label="Enter Java entities to convert to Unicode Characters" autosize raw-text test-id="entities-to-unicode-input" />
27+
<c-input-text v-model:value="unicodeFromEntities" label="Text from your Java entities" multiline raw-text readonly mt-2 placeholder="The text representation of your unicode will be here" test-id="entities-to-unicode-output" />
28+
<div mt-2 flex justify-center>
29+
<c-button :disabled="!unicodeFromEntities" @click="copyText()">
30+
Copy text to clipboard
31+
</c-button>
32+
</div>
33+
</c-card>
34+
</template>

0 commit comments

Comments
 (0)