diff --git a/src/app/globals.css b/src/app/globals.css
index 8fe13d1..03abcc5 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,6 +1,6 @@
:root {
--main_1: #735cd6;
- --main_2: #d13fbe;
+ --main_2: #db52c9;
--light_1: #a598e0;
--text_light: #727272;
}
@@ -127,5 +127,4 @@ th,
td {
padding: 0.25rem 1rem;
text-align: left;
- vertical-align: top;
}
diff --git a/src/app/page.module.css b/src/app/page.module.css
index 3cae7e0..3f5295c 100644
--- a/src/app/page.module.css
+++ b/src/app/page.module.css
@@ -44,16 +44,23 @@
margin-top: 1rem;
padding: 0 3rem;
color: var(--text_light);
+ font-size: 0.8rem;
}
.table_container {
overflow-x: scroll;
+ padding-bottom: 1rem;
}
-#output_table tbody td:nth-child(1) {
+#output_table {
+ margin: 0 auto;
+}
+
+#output_table tbody th:nth-child(1) {
text-align: center;
}
-#output_table thead th:nth-child(2) {
- min-width: 10em;
+#output_table td,
+#output_table th {
+ white-space: nowrap;
}
diff --git a/src/components/inspector.tsx b/src/components/inspector.tsx
index cd0d542..747598b 100644
--- a/src/components/inspector.tsx
+++ b/src/components/inspector.tsx
@@ -1,9 +1,10 @@
'use client';
-import { useContext, useState } from 'react';
+import { useState } from 'react';
import styles from '@/app/page.module.css'
import { TextField } from './textfield';
-import { UtfdumpContext, UtfdumpContextProvider } from '@/context/utfdump';
+import { UtfdumpContextProvider } from '@/context/utfdump';
+import { OutputTable } from './output_table';
type InspectorProps = {
sourceUrl: string,
@@ -29,59 +30,8 @@ export function Inspector(props: InspectorProps) {
-
+
);
}
-
-function Out(props: { currentString: string }) {
- const ctx = useContext(UtfdumpContext);
-
- let rows = [];
-
- if (ctx.utfdump) {
- for (const codepointStr of props.currentString) {
- const codepoint = codepointStr.codePointAt(0);
-
- if (codepoint !== undefined) {
- const charData = ctx.utfdump.codepoint_char_data(codepoint);
-
- rows.push((
-
- | {codepointStr.replace(/\s+/, ' ')} |
- {charData?.name()} |
- U+{codepoint.toString(16).padStart(4, '0')} |
-
- ));
-
- charData?.free();
- }
- }
- }
-
- return (
-
-
-
-
-
- | Char |
- Name |
- Codepoint |
- UTF-8 |
- UTF-16 |
- Category |
- Combining |
- Bidirectional |
- Numeric value |
-
-
-
- {rows}
-
-
-
-
- );
-}
diff --git a/src/components/output_table.tsx b/src/components/output_table.tsx
new file mode 100644
index 0000000..c32986e
--- /dev/null
+++ b/src/components/output_table.tsx
@@ -0,0 +1,100 @@
+import { useContext } from 'react';
+import styles from '@/app/page.module.css'
+import { UtfdumpContext } from '@/context/utfdump';
+import { EncodedCodepoint } from 'utfdump_wasm';
+
+export function OutputTable(props: { currentString: string }) {
+ const ctx = useContext(UtfdumpContext);
+
+ let rows = [];
+
+ if (ctx.utfdump) {
+ for (const codepointStr of props.currentString) {
+ const codepoint = codepointStr.codePointAt(0);
+
+ if (codepoint !== undefined) {
+ const charData = ctx.utfdump.codepoint_char_data(codepoint);
+
+ if (charData !== undefined) {
+ const encodedUtf8 = charData.encoded_utf8();
+ let encodedUtf8Str;
+ if (encodedUtf8 !== undefined) {
+ encodedUtf8Str = codepointToString(encodedUtf8);
+ encodedUtf8.free();
+ }
+
+ const encodedUtf16 = charData.encoded_utf16_le();
+ let encodedUtf16Str;
+ if (encodedUtf16 !== undefined) {
+ encodedUtf16Str = codepointToString(encodedUtf16);
+ encodedUtf16.free();
+ }
+
+ const combiningClassNum = charData.combining_class();
+ const combiningClassName = ctx.utfdump.combining_class_name(combiningClassNum);
+
+ let charDisplayStr = codepointStr.replace(/\s+/, ' ');
+ if (combiningClassNum !== 0) {
+ charDisplayStr = '\u25cc' + charDisplayStr;
+ }
+
+ rows.push((
+
+ | {charDisplayStr} |
+ {charData.name()} |
+ U+{codepoint.toString(16).padStart(4, '0')} |
+ {encodedUtf8Str} |
+ {encodedUtf16Str} |
+ {charData.category_full()} |
+ {combiningClassName || combiningClassNum} |
+ {charData.bidi_full()} |
+ {charData.numeric_value() || 'Not numeric'} |
+
+ ));
+
+ charData.free();
+ }
+
+ else {
+ // TODO: push "invalid character" row in this case
+ }
+ }
+ }
+ }
+
+ return (
+
+
+
+
+
+ |
+ Name |
+ Code |
+ UTF-8 |
+ UTF-16LE |
+ Category |
+ Combining |
+ Bidirectional |
+ Numeric value |
+
+
+
+ {rows}
+
+
+
+
+ );
+}
+
+function codepointToString(codepoint: EncodedCodepoint): string {
+ const bytes = [
+ codepoint.b0,
+ codepoint.b1,
+ codepoint.b2,
+ codepoint.b3
+ ].slice(0, codepoint.len);
+
+ return bytes.map((b) => b.toString(16).padStart(2, '0')).join(' ');
+}