You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.9 KiB
TypeScript
101 lines
2.9 KiB
TypeScript
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((
|
|
<tr>
|
|
<th>{charDisplayStr}</th>
|
|
<td>{charData.name()}</td>
|
|
<td>U+{codepoint.toString(16).padStart(4, '0')}</td>
|
|
<td>{encodedUtf8Str}</td>
|
|
<td>{encodedUtf16Str}</td>
|
|
<td>{charData.category_full()}</td>
|
|
<td>{combiningClassName || combiningClassNum}</td>
|
|
<td>{charData.bidi_full()}</td>
|
|
<td>{charData.numeric_value() || 'Not numeric'}</td>
|
|
</tr>
|
|
));
|
|
|
|
charData.free();
|
|
}
|
|
|
|
else {
|
|
// TODO: push "invalid character" row in this case
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (
|
|
<section className={styles.table_container}>
|
|
<div className={styles.overflow_scroll}>
|
|
<table id={styles.output_table}>
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th>Name</th>
|
|
<th>Code</th>
|
|
<th>UTF-8</th>
|
|
<th>UTF-16LE</th>
|
|
<th>Category</th>
|
|
<th>Combining</th>
|
|
<th>Bidirectional</th>
|
|
<th>Numeric value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{rows}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
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(' ');
|
|
}
|