バラバラに作った小道具
- 正規化表現
- コード ポイント の表示
- innerHTML 代入テスト
- 英数字の変換
- 円内文字への変換
- 丸括弧付き文字への変換
を1つにまとめてみた。
See the Pen 文字変換と確認 by Ikiuo (@ikiuo) on CodePen.
ソースコード (HTML+JavaScript)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>各種処理</title>
<style>
table {
border: solid 1px #ccc;
border-collaspe: collaspe;
border-spacing: 0;
}
th, td {
border: solid 1px #ccc;
}
th {
background: #eee;
}
td {
padding: 0px;
margin: 0px;
}
.left {
text-align: left;
}
</style>
</head>
<body>
<table>
<tr>
<th>入<br>力</th>
<td>
<textarea cols="80" rows="8" oninput="onInput(this.value)"></textarea>
</td>
</tr>
<tr>
<th>形<br/>式</th>
<td>
<button onclick="onClick('Normalize')">正規化表現</button>
<button onclick="onClick('CodePoint')">コード ポイント</button>
<button onclick="onClick('InnerHTML')">innerHTML</button>
<br/>
<button onclick="onClick('AlphaNumeric')">英数字の変換</button>
<button onclick="onClick('Circled')">円内文字への変換</button>
<button onclick="onClick('Parenthesized')">丸括弧付き文字への変換</button>
</td>
</tr>
</table>
<p>出力:項目ボタンのクリックで、クリップボードへ結果(テキスト)をコピーします。</p>
<table id="Normalize">
<tr><th colspan="2">正規化表現</th></tr>
<tr><th>種類</th><th>結果</th></tr>
</table>
<table id="CodePoint">
<tr><th colspan="2">コード ポイント</th></tr>
<tr><th>種類</th><th>結果</th></tr>
</table>
<table id="InnerHTML">
<tr><th colspan="2">InnerHTML</th></tr>
<tr><td id="InnerHTML_output"></td></tr>
</table>
<table id="AlphaNumeric">
<tr><th colspan="2">英数字の変換</th></tr>
<tr><th>種類</th><th>結果</th></tr>
</table>
<table id="Circled">
<tr><th colspan="2">円内文字への変換</th></tr>
<tr><th>種類</th><th>結果</th></tr>
</table>
<table id="Parenthesized">
<tr><th colspan="2">丸括弧付き文字への変換</th></tr>
<tr><th>種類</th><th>結果</th></tr>
<tr>
<th class="left">
<button onclick="toClipboard(Parenthesized_output.innerText)">
Parenthesized
</button>
</th>
<td id="Parenthesized_output"></td>
</tr>
</table>
<script>
// ----------------------------------------------------------------------
const OutputTable = [
'Normalize', 'CodePoint', 'InnerHTML',
'AlphaNumeric', 'Circled', 'Parenthesized',
];
var lastMode = '';
var lastText = '';
// ----------------------------------------------------------------------
function toUTF8(ucs4) {
return ((ucs4 < 0x00080) ? [ucs4] :
(ucs4 < 0x00800) ? [0xc0 | ((ucs4 >> 6) & 0x1f),
0x80 | ((ucs4 >> 0) & 0x3f)] :
(ucs4 < 0x10000) ? [0xe0 | ((ucs4 >> 12) & 0x0f),
0x80 | ((ucs4 >> 6) & 0x3f),
0x80 | ((ucs4 >> 0) & 0x3f)] :
[0xf0 | ((ucs4 >> 18) & 0x07),
0x80 | ((ucs4 >> 12) & 0x3f),
0x80 | ((ucs4 >> 6) & 0x3f),
0x80 | ((ucs4 >> 0) & 0x3f)]);
}
const toDec = (code => code.toString(10));
const toHex = ((code, prefix) => (prefix ? '0x' : '') + (
`00000000${code.toString(16).toUpperCase()}`
.substr(-(((8 + 31 - Math.clz32(code)) >> 3) << 1))));
const toString = ((code, base, prefix) =>
((base == 16) ? toHex(code, prefix) : toDec(code)));
function encodeHTML(inp) {
const m = { '<':'<', '&':'&', '>':'>', '\n':'<br/>' };
return [...inp].map((c) => m[c] ?? c).join('');
}
function encodeHTMLN(inp) {
const m = {
'<':'<', '&':'&', '>':'>',
'\n':'<span style="color: red"><small>\\n</small></span>'
};
return [...inp].map((c) => m[c] ?? c).join('');
}
// ----------------------------------------------------------------------
class CodePointRuby {
static TypeTable = ['UTF-32', 'UTF-16', 'UTF-8'];
static flagSet = new Set([...Array(0x1f200 - 0x1f1e6)].map((_, n) => n + 0x1f1e6));
static varselSet = new Set([
[...Array(0x10)].map((_, n) => n + 0x0ff00),
[...Array(0xf0)].map((_, n) => n + 0xe0100),
].flat());
constructor(text) {
const C = CodePointRuby;
this.C = C;
const lines = [];
{
let line = '';
for (const c of text) {
line = line + c;
if (c == '\n') {
lines.push(line);
line = '';
}
}
if (line.length)
lines.push(line);
}
this.lines = [];
for (const line of lines) {
const chars = [];
let lastChar = '';
[...line].forEach(c => {
const lc = lastChar;
lastChar = c;
if (C.varselSet.has(c)) {
if (chars.length) {
chars[chars.length - 1] += c;
return;
}
} else if (C.flagSet.has(c)) {
if (C.flagSet.has(lastChar)) {
chars[chars.length - 1] += c;
lastChar = '';
return;
}
}
chars.push(c);
});
this.lines.push(chars);
}
}
toHTML(mode) {
const C = this.C;
const bUTF8 = (mode == 'UTF-8');
const bUTF16 = (mode == 'UTF-16');
const bUTF32 = (mode == 'UTF-32');
const nBase = 16;
const bPrefix = false;
let out = '';
for (const line of this.lines) {
out += '<p>';
for (const data of line) {
let codes;
let ruby = `<ruby>${encodeHTMLN(data)}<rp>(</rp>`;
if (bUTF32)
codes = [...data].map(c => c.codePointAt(0));
else if (bUTF16) {
codes = [];
for (const n in data)
codes.push(data.charCodeAt(n));
} else if (bUTF8)
codes = [...data].map(c => toUTF8(c.codePointAt(0))).flat();
ruby += `<rt>[${codes.map(c => toString(c, nBase, bPrefix)).join(',')}]</rt>`;
ruby += '<rp>)</rp></ruby>';
out += ruby;
}
out += '</p>';
}
return out;
}
static toId(name) {
return `CodePoint_${name.replaceAll('-', '_')}`;
}
}
// ----------------------------------------------------------------------
class NormalizeDiff {
static TypeTable = ['NFC', 'NFD', 'NFKC', 'NFKD'];
constructor(mode, text) {
this.mode = mode;
this.characters = [...text].map(c => {
const n = c.normalize(mode);
return { chk:(c == n), inp:c, out:n }
});
let pos = 0;
let end = this.characters.length;
while (pos < end)
pos += this.checkComposite(pos, end);
this.characters.forEach(c => c.out = encodeHTML(c.out));
}
checkComposite(start, end) {
const mode = this.mode;
const inp = this.characters;
let pos = start;
if (!inp[pos].chk)
return 1;
let s = inp[pos].inp;
let t = s;
while (++pos < end) {
const c = inp[pos];
if (!c.chk)
break;
s += c.inp;
t = s.normalize(mode);
if (s == t)
continue;
const sc = [...s];
if (sc.length == 1)
continue;
const tc = [...t];
if (sc.pop() != tc.pop())
continue;
s = sc.join('');
t = tc.join('');
break;
}
const len = pos - start;
{
const sc = [...s];
const tc = [...t];
let scnt;
for (scnt = 0; scnt < sc.length; scnt++)
if (sc[scnt] != tc[scnt])
break;
start += scnt;
}
if (start < pos) {
s = '';
for (let p = start; p < pos; p++)
s += inp[p].inp;
t = s.normalize(mode);
inp[start].chk = false;
inp[start].out = t;
while (++start < pos) {
inp[start].chk = false;
inp[start].out = '';
}
}
return len;
}
toHTML() {
return this.characters.map(
(c) => c.chk ? c.out : !c.out.length ? '' :
`<span style="background-color: #fbb">${c.out}</span>`
).join('');
}
static toId(name) {
return `Normalize_${name}`;
}
}
// ----------------------------------------------------------------------
class ConvertAlphaNumeric {
static TypeTable = {
'FULLWIDTH': ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'],
'MATHEMATICAL BOLD': ['𝟎','𝟏','𝟐','𝟑','𝟒','𝟓','𝟔','𝟕','𝟖','𝟗','𝐀','𝐁','𝐂','𝐃','𝐄','𝐅','𝐆','𝐇','𝐈','𝐉','𝐊','𝐋','𝐌','𝐍','𝐎','𝐏','𝐐','𝐑','𝐒','𝐓','𝐔','𝐕','𝐖','𝐗','𝐘','𝐙','𝐚','𝐛','𝐜','𝐝','𝐞','𝐟','𝐠','𝐡','𝐢','𝐣','𝐤','𝐥','𝐦','𝐧','𝐨','𝐩','𝐪','𝐫','𝐬','𝐭','𝐮','𝐯','𝐰','𝐱','𝐲','𝐳'],
'MATHEMATICAL ITALIC': ['','','','','','','','','','','𝐴','𝐵','𝐶','𝐷','𝐸','𝐹','𝐺','𝐻','𝐼','𝐽','𝐾','𝐿','𝑀','𝑁','𝑂','𝑃','𝑄','𝑅','𝑆','𝑇','𝑈','𝑉','𝑊','𝑋','𝑌','𝑍','𝑎','𝑏','𝑐','𝑑','𝑒','𝑓','𝑔','ℎ','𝑖','𝑗','𝑘','𝑙','𝑚','𝑛','𝑜','𝑝','𝑞','𝑟','𝑠','𝑡','𝑢','𝑣','𝑤','𝑥','𝑦','𝑧'],
'MATHEMATICAL BOLD ITALIC': ['','','','','','','','','','','𝑨','𝑩','𝑪','𝑫','𝑬','𝑭','𝑮','𝑯','𝑰','𝑱','𝑲','𝑳','𝑴','𝑵','𝑶','𝑷','𝑸','𝑹','𝑺','𝑻','𝑼','𝑽','𝑾','𝑿','𝒀','𝒁','𝒂','𝒃','𝒄','𝒅','𝒆','𝒇','𝒈','𝒉','𝒊','𝒋','𝒌','𝒍','𝒎','𝒏','𝒐','𝒑','𝒒','𝒓','𝒔','𝒕','𝒖','𝒗','𝒘','𝒙','𝒚','𝒛'],
'MATHEMATICAL SCRIPT': ['','','','','','','','','','','𝒜','ℬ','𝒞','𝒟','ℰ','ℱ','𝒢','ℋ','ℐ','𝒥','𝒦','ℒ','ℳ','𝒩','𝒪','𝒫','𝒬','ℛ','𝒮','𝒯','𝒰','𝒱','𝒲','𝒳','𝒴','𝒵','𝒶','𝒷','𝒸','𝒹','ℯ','𝒻','ℊ','𝒽','𝒾','𝒿','𝓀','𝓁','𝓂','𝓃','ℴ','𝓅','𝓆','𝓇','𝓈','𝓉','𝓊','𝓋','𝓌','𝓍','𝓎','𝓏'],
'MATHEMATICAL SCRIPT (CHANCERY)': ['','','','','','','','','','','𝒜︀','︀','𝒞︀','𝒟︀','︀','︀','𝒢︀','︀','︀','𝒥︀','𝒦︀','︀','︀','𝒩︀','𝒪︀','𝒫︀','𝒬︀','︀','𝒮︀','𝒯︀','𝒰︀','𝒱︀','𝒲︀','𝒳︀','𝒴︀','𝒵︀','𝒶','𝒷','𝒸','𝒹','ℯ','𝒻','ℊ','𝒽','𝒾','𝒿','𝓀','𝓁','𝓂','𝓃','ℴ','𝓅','𝓆','𝓇','𝓈','𝓉','𝓊','𝓋','𝓌','𝓍','𝓎','𝓏'],
'MATHEMATICAL SCRIPT (ROUNDHAND)': ['','','','','','','','','','','𝒜︁','︁','𝒞︁','𝒟︁','︁','︁','𝒢︁','︁','︁','𝒥︁','𝒦︁','︁','︁','𝒩︁','𝒪︁','𝒫︁','𝒬︁','︁','𝒮︁','𝒯︁','𝒰︁','𝒱︁','𝒲︁','𝒳︁','𝒴︁','𝒵︁','𝒶','𝒷','𝒸','𝒹','ℯ','𝒻','ℊ','𝒽','𝒾','𝒿','𝓀','𝓁','𝓂','𝓃','ℴ','𝓅','𝓆','𝓇','𝓈','𝓉','𝓊','𝓋','𝓌','𝓍','𝓎','𝓏'],
'MATHEMATICAL BOLD SCRIPT': ['','','','','','','','','','','𝓐','𝓑','𝓒','𝓓','𝓔','𝓕','𝓖','𝓗','𝓘','𝓙','𝓚','𝓛','𝓜','𝓝','𝓞','𝓟','𝓠','𝓡','𝓢','𝓣','𝓤','𝓥','𝓦','𝓧','𝓨','𝓩','𝓪','𝓫','𝓬','𝓭','𝓮','𝓯','𝓰','𝓱','𝓲','𝓳','𝓴','𝓵','𝓶','𝓷','𝓸','𝓹','𝓺','𝓻','𝓼','𝓽','𝓾','𝓿','𝔀','𝔁','𝔂','𝔃'],
'MATHEMATICAL FRAKTUR': ['','','','','','','','','','','𝔄','𝔅','ℭ','𝔇','𝔈','𝔉','𝔊','ℌ','ℑ','𝔍','𝔎','𝔏','𝔐','𝔑','𝔒','𝔓','𝔔','ℜ','𝔖','𝔗','𝔘','𝔙','𝔚','𝔛','𝔜','ℨ','𝔞','𝔟','𝔠','𝔡','𝔢','𝔣','𝔤','𝔥','𝔦','𝔧','𝔨','𝔩','𝔪','𝔫','𝔬','𝔭','𝔮','𝔯','𝔰','𝔱','𝔲','𝔳','𝔴','𝔵','𝔶','𝔷'],
'MATHEMATICAL BOLD FRAKTUR': ['','','','','','','','','','','𝕬','𝕭','𝕮','𝕯','𝕰','𝕱','𝕲','𝕳','𝕴','𝕵','𝕶','𝕷','𝕸','𝕹','𝕺','𝕻','𝕼','𝕽','𝕾','𝕿','𝖀','𝖁','𝖂','𝖃','𝖄','𝖅','𝖆','𝖇','𝖈','𝖉','𝖊','𝖋','𝖌','𝖍','𝖎','𝖏','𝖐','𝖑','𝖒','𝖓','𝖔','𝖕','𝖖','𝖗','𝖘','𝖙','𝖚','𝖛','𝖜','𝖝','𝖞','𝖟'],
'MATHEMATICAL DOUBLE STRUCK': ['𝟘','𝟙','𝟚','𝟛','𝟜','𝟝','𝟞','𝟟','𝟠','𝟡','𝔸','𝔹','ℂ','𝔻','𝔼','𝔽','𝔾','ℍ','𝕀','𝕁','𝕂','𝕃','𝕄','ℕ','𝕆','ℙ','ℚ','ℝ','𝕊','𝕋','𝕌','𝕍','𝕎','𝕏','𝕐','ℤ','𝕒','𝕓','𝕔','𝕕','𝕖','𝕗','𝕘','𝕙','𝕚','𝕛','𝕜','𝕝','𝕞','𝕟','𝕠','𝕡','𝕢','𝕣','𝕤','𝕥','𝕦','𝕧','𝕨','𝕩','𝕪','𝕫'],
'MATHEMATICAL SANS SERIF': ['𝟢','𝟣','𝟤','𝟥','𝟦','𝟧','𝟨','𝟩','𝟪','𝟫','𝖠','𝖡','𝖢','𝖣','𝖤','𝖥','𝖦','𝖧','𝖨','𝖩','𝖪','𝖫','𝖬','𝖭','𝖮','𝖯','𝖰','𝖱','𝖲','𝖳','𝖴','𝖵','𝖶','𝖷','𝖸','𝖹','𝖺','𝖻','𝖼','𝖽','𝖾','𝖿','𝗀','𝗁','𝗂','𝗃','𝗄','𝗅','𝗆','𝗇','𝗈','𝗉','𝗊','𝗋','𝗌','𝗍','𝗎','𝗏','𝗐','𝗑','𝗒','𝗓'],
'MATHEMATICAL SANS SERIF BOLD': ['𝟬','𝟭','𝟮','𝟯','𝟰','𝟱','𝟲','𝟳','𝟴','𝟵','𝗔','𝗕','𝗖','𝗗','𝗘','𝗙','𝗚','𝗛','𝗜','𝗝','𝗞','𝗟','𝗠','𝗡','𝗢','𝗣','𝗤','𝗥','𝗦','𝗧','𝗨','𝗩','𝗪','𝗫','𝗬','𝗭','𝗮','𝗯','𝗰','𝗱','𝗲','𝗳','𝗴','𝗵','𝗶','𝗷','𝗸','𝗹','𝗺','𝗻','𝗼','𝗽','𝗾','𝗿','𝘀','𝘁','𝘂','𝘃','𝘄','𝘅','𝘆','𝘇'],
'MATHEMATICAL SANS SERIF ITALIC': ['','','','','','','','','','','𝘈','𝘉','𝘊','𝘋','𝘌','𝘍','𝘎','𝘏','𝘐','𝘑','𝘒','𝘓','𝘔','𝘕','𝘖','𝘗','𝘘','𝘙','𝘚','𝘛','𝘜','𝘝','𝘞','𝘟','𝘠','𝘡','𝘢','𝘣','𝘤','𝘥','𝘦','𝘧','𝘨','𝘩','𝘪','𝘫','𝘬','𝘭','𝘮','𝘯','𝘰','𝘱','𝘲','𝘳','𝘴','𝘵','𝘶','𝘷','𝘸','𝘹','𝘺','𝘻'],
'MATHEMATICAL SANS SERIF BOLD ITALIC': ['','','','','','','','','','','𝘼','𝘽','𝘾','𝘿','𝙀','𝙁','𝙂','𝙃','𝙄','𝙅','𝙆','𝙇','𝙈','𝙉','𝙊','𝙋','𝙌','𝙍','𝙎','𝙏','𝙐','𝙑','𝙒','𝙓','𝙔','𝙕','𝙖','𝙗','𝙘','𝙙','𝙚','𝙛','𝙜','𝙝','𝙞','𝙟','𝙠','𝙡','𝙢','𝙣','𝙤','𝙥','𝙦','𝙧','𝙨','𝙩','𝙪','𝙫','𝙬','𝙭','𝙮','𝙯'],
'MATHEMATICAL MONOSPACE': ['𝟶','𝟷','𝟸','𝟹','𝟺','𝟻','𝟼','𝟽','𝟾','𝟿','𝙰','𝙱','𝙲','𝙳','𝙴','𝙵','𝙶','𝙷','𝙸','𝙹','𝙺','𝙻','𝙼','𝙽','𝙾','𝙿','𝚀','𝚁','𝚂','𝚃','𝚄','𝚅','𝚆','𝚇','𝚈','𝚉','𝚊','𝚋','𝚌','𝚍','𝚎','𝚏','𝚐','𝚑','𝚒','𝚓','𝚔','𝚕','𝚖','𝚗','𝚘','𝚙','𝚚','𝚛','𝚜','𝚝','𝚞','𝚟','𝚠','𝚡','𝚢','𝚣'],
'CIRCLED': ['⓪','➀','➁','➂','➃','➄','➅','➆','➇','➈','Ⓐ','Ⓑ','Ⓒ','Ⓓ','Ⓔ','Ⓕ','Ⓖ','Ⓗ','Ⓘ','Ⓙ','Ⓚ','Ⓛ','Ⓜ','Ⓝ','Ⓞ','Ⓟ','Ⓠ','Ⓡ','Ⓢ','Ⓣ','Ⓤ','Ⓥ','Ⓦ','Ⓧ','Ⓨ','Ⓩ','ⓐ','ⓑ','ⓒ','ⓓ','ⓔ','ⓕ','ⓖ','ⓗ','ⓘ','ⓙ','ⓚ','ⓛ','ⓜ','ⓝ','ⓞ','ⓟ','ⓠ','ⓡ','ⓢ','ⓣ','ⓤ','ⓥ','ⓦ','ⓧ','ⓨ','ⓩ'],
'NEGATIVE CIRCLED': ['⓿','❶','❷','❸','❹','❺','❻','❼','❽','❾','🅐','🅑','🅒','🅓','🅔','🅕','🅖','🅗','🅘','🅙','🅚','🅛','🅜','🅝','🅞','🅟','🅠','🅡','🅢','🅣','🅤','🅥','🅦','🅧','🅨','🅩','','','','','','','','','','','','','','','','','','','','','','','','','',''],
'SQUARED': ['','','','','','','','','','','🄰','🄱','🄲','🄳','🄴','🄵','🄶','🄷','🄸','🄹','🄺','🄻','🄼','🄽','🄾','🄿','🅀','🅁','🅂','🅃','🅄','🅅','🅆','🅇','🅈','🅉','','','','','','','','','','','','','','','','','','','','','','','','','',''],
'NEGATIVE SQUARED': ['','','','','','','','','','','🅰','🅱','🅲','🅳','🅴','🅵','🅶','🅷','🅸','🅹','🅺','🅻','🅼','🅽','🅾','🅿','🆀','🆁','🆂','🆃','🆄','🆅','🆆','🆇','🆈','🆉','','','','','','','','','','','','','','','','','','','','','','','','','',''],
'PARENTHESIZED': ['','⑴','⑵','⑶','⑷','⑸','⑹','⑺','⑻','⑼','🄐','🄑','🄒','🄓','🄔','🄕','🄖','🄗','🄘','🄙','🄚','🄛','🄜','🄝','🄞','🄟','🄠','🄡','🄢','🄣','🄤','🄥','🄦','🄧','🄨','🄩','⒜','⒝','⒞','⒟','⒠','⒡','⒢','⒣','⒤','⒥','⒦','⒧','⒨','⒩','⒪','⒫','⒬','⒭','⒮','⒯','⒰','⒱','⒲','⒳','⒴','⒵'],
'LISU': ['','','','','','','','','','','ꓮ','ꓐ','ꓚ','ꓓ','ꓰ','ꓝ','ꓖ','ꓧ','ꓲ','ꓙ','ꓗ','ꓡ','ꓟ','ꓠ','ꓳ','ꓑ','','ꓣ','ꓢ','ꓔ','ꓴ','ꓦ','ꓪ','ꓫ','ꓬ','ꓜ','','','','','','','','','','','','','','','','','','','','','','','','','',''],
'TURNED + LISU': ['','','↊','↋','','','','','','','ꓯ','ꓭ','ꓛ','ꓷ','ꓱ','ꓞ','ꓨ','ꓧ','ꓲ','ꓩ','ꓘ','ꓶ','ꓪ','ꓠ','ꓳ','ꓒ','','ꓤ','ꓢ','ꓕ','ꓵ','ꓥ','ꓟ','ꓫ','⅄','ꓜ','ɐ','','ɔ','','ǝ','ɟ','ᵷ','ɥ','ᴉ','','ʞ','ꞁ','ɯ','','','','','ɹ','','ʇ','','ʌ','ʍ','','ʎ',''],
'TURNED': ['','','↊','↋','','','','','','','Ɐ','','Ɔ','','Ǝ','Ⅎ','','Ɥ','','','Ʞ','Ꞁ','Ɯ','','','','','','','Ʇ','','Ʌ','','','𑾰','','ɐ','','ɔ','','ǝ','ɟ','ᵷ','ɥ','ᴉ','','ʞ','ꞁ','ɯ','','','','','ɹ','','ʇ','','ʌ','ʍ','','ʎ',''],
};
static replace(table, inp) {
let out = '';
for (const n in inp) {
const c = inp.charCodeAt(n) >>> 0; /*INT化のお呪い*/
let t = '';
if (0x30 <= c && c <= 0x39)
t = table[c - 0x30];
else if (0x41 <= c && c <= 0x5a)
t = table[c - 0x41 + 10];
else if (0x61 <= c && c <= 0x7a)
t = table[c - 0x61 + 36];
out += (t ? t : String.fromCharCode(c));
}
return out;
}
static convert(mode, text) {
return ConvertAlphaNumeric.replace(
ConvertAlphaNumeric.TypeTable[mode],
text.normalize('NFKC'));
}
static toId(name) {
return `AlphaNumeric ${name}`.replaceAll(' ', '_');
}
}
// ----------------------------------------------------------------------
class ConvertCircled {
static TypeTable = {
'CIRCLED': {
'0':'⓪',
'1':'①', '2':'②', '3':'③', '4':'④', '5':'⑤',
'6':'⑥', '7':'⑦', '8':'⑧', '9':'⑨', '10':'⑩',
'11':'⑪', '12':'⑫', '13':'⑬', '14':'⑭', '15':'⑮',
'16':'⑯', '17':'⑰', '18':'⑱', '19':'⑲', '20':'⑳',
'21':'㉑', '22':'㉒', '23':'㉓', '24':'㉔', '25':'㉕',
'26':'㉖', '27':'㉗', '28':'㉘', '29':'㉙', '30':'㉚',
'31':'㉛', '32':'㉜', '33':'㉝', '34':'㉞', '35':'㉟',
'36':'㊱', '37':'㊲', '38':'㊳', '39':'㊴', '40':'㊵',
'41':'㊶', '42':'㊷', '43':'㊸', '44':'㊹', '45':'㊺',
'46':'㊻', '47':'㊼', '48':'㊽', '49':'㊾', '50':'㊿',
'A':'Ⓐ', 'B':'Ⓑ', 'C':'Ⓒ', 'D':'Ⓓ', 'E':'Ⓔ', 'F':'Ⓕ',
'G':'Ⓖ', 'H':'Ⓗ', 'I':'Ⓘ', 'J':'Ⓙ', 'K':'Ⓚ', 'L':'Ⓛ',
'M':'Ⓜ', 'N':'Ⓝ', 'O':'Ⓞ', 'P':'Ⓟ', 'Q':'Ⓠ', 'R':'Ⓡ',
'S':'Ⓢ', 'T':'Ⓣ', 'U':'Ⓤ', 'V':'Ⓥ', 'W':'Ⓦ', 'X':'Ⓧ',
'Y':'Ⓨ', 'Z':'Ⓩ',
'a':'ⓐ', 'b':'ⓑ', 'c':'ⓒ', 'd':'ⓓ', 'e':'ⓔ', 'f':'ⓕ',
'g':'ⓖ', 'h':'ⓗ', 'i':'ⓘ', 'j':'ⓙ', 'k':'ⓚ', 'l':'ⓛ',
'm':'ⓜ', 'n':'ⓝ', 'o':'ⓞ', 'p':'ⓟ', 'q':'ⓠ', 'r':'ⓡ',
's':'ⓢ', 't':'ⓣ', 'u':'ⓤ', 'v':'ⓥ', 'w':'ⓦ', 'x':'ⓧ',
'y':'ⓨ', 'z':'ⓩ',
'CD':'🄭', 'WZ':'🄮',
'ア':'㋐', 'イ':'㋑', 'ウ':'㋒', 'エ':'㋓', 'オ':'㋔',
'カ':'㋕', 'キ':'㋖', 'ク':'㋗', 'ケ':'㋘', 'コ':'㋙',
'サ':'㋚', 'シ':'㋛', 'ス':'㋜', 'セ':'㋝', 'ソ':'㋞',
'タ':'㋟', 'チ':'㋠', 'ツ':'㋡', 'テ':'㋢', 'ト':'㋣',
'ナ':'㋤', 'ニ':'㋥', 'ヌ':'㋦', 'ネ':'㋧', 'ノ':'㋨',
'ハ':'㋩', 'ヒ':'㋪', 'フ':'㋫', 'ヘ':'㋬', 'ホ':'㋭',
'マ':'㋮', 'ミ':'㋯', 'ム':'㋰', 'メ':'㋱', 'モ':'㋲',
'ヤ':'㋳', 'ユ':'㋴', 'ヨ':'㋵',
'ラ':'㋶', 'リ':'㋷', 'ル':'㋸', 'レ':'㋹', 'ロ':'㋺',
'ワ':'㋻', 'ヰ':'㋼', 'ヱ':'㋽', 'ヲ':'㋾',
'一':'㊀', '二':'㊁', '三':'㊂', '四':'㊃', '五':'㊄',
'六':'㊅', '七':'㊆', '八':'㊇', '九':'㊈', '十':'㊉',
'月':'㊊', '火':'㊋', '水':'㊌', '木':'㊍', '金':'㊎', '土':'㊏',
'日':'㊐', '株':'㊑', '有':'㊒', '社':'㊓', '名':'㊔', '特':'㊕',
'財':'㊖', '祝':'㊗', '労':'㊘', '秘':'㊙', '男':'㊚', '女':'㊛',
'適':'㊜', '優':'㊝', '印':'㊞', '注':'㊟', '項':'㊠', '休':'㊡',
'写':'㊢', '正':'㊣', '上':'㊤', '中':'㊥', '下':'㊦', '左':'㊧',
'右':'㊨', '医':'㊩', '宗':'㊪', '学':'㊫', '監':'㊬', '企':'㊭',
'資':'㊮', '協':'㊯', '夜':'㊰', '問':'㉄', '幼':'㉅', '文':'㉆',
'箏':'㉇',
'ᄀ':'㉠', 'ᄂ':'㉡', 'ᄃ':'㉢', 'ᄅ':'㉣', 'ᄆ':'㉤',
'ᄇ':'㉥', 'ᄉ':'㉦', 'ᄋ':'㉧', 'ᄌ':'㉨', 'ᄎ':'㉩',
'ᄏ':'㉪', 'ᄐ':'㉫', 'ᄑ':'㉬', 'ᄒ':'㉭',
'가':'㉮', '나':'㉯', '다':'㉰', '라':'㉱', '마':'㉲', '바':'㉳',
'사':'㉴', '아':'㉵', '자':'㉶', '차':'㉷', '카':'㉸', '타':'㉹',
'파':'㉺', '하':'㉻', '참고':'㉼','주의':'㉽','우':'㉾',
},
'NEGATIVE CIRCLED': {
'0':'⓿',
'1':'❶', '2':'❷', '3':'❸', '4':'❹', '5':'❺',
'6':'❻', '7':'❼', '8':'❽', '9':'❾', '10':'❿',
'11':'⓫', '12':'⓬', '13':'⓭', '14':'⓮', '15':'⓯',
'16':'⓰', '17':'⓱', '18':'⓲', '19':'⓳', '20':'⓴',
'A':'🅐', 'B':'🅑', 'C':'🅒', 'D':'🅓', 'E':'🅔', 'F':'🅕',
'G':'🅖', 'H':'🅗', 'I':'🅘', 'J':'🅙', 'K':'🅚', 'L':'🅛',
'M':'🅜', 'N':'🅝', 'O':'🅞', 'P':'🅟', 'Q':'🅠', 'R':'🅡',
'S':'🅢', 'T':'🅣', 'U':'🅤', 'V':'🅥', 'W':'🅦', 'X':'🅧',
'Y':'🅨', 'Z':'🅩',
},
'DINGBAT CIRCLED': {
'0':'🄋',
'1':'➀', '2':'➁', '3':'➂', '4':'➃', '5':'➄',
'6':'➅', '7':'➆', '8':'➇', '9':'➈', '10':'➉',
},
'DINGBAT NEGATIVE CIRCLED': {
'0':'🄌',
'1':'➊', '2':'➋', '3':'➌', '4':'➍', '5':'➎',
'6':'➏', '7':'➐', '8':'➑', '9':'➒', '10':'➓',
},
'DINGBAT CIRCLED SANS SERIF': {
'1':'⓵', '2':'⓶', '3':'⓷', '4':'⓸', '5':'⓹',
'6':'⓺', '7':'⓻', '8':'⓼', '9':'⓽', '10':'⓾',
},
}
static replace(table, text) {
if (!text)
return text;
const chars = [...text];
let [last, str] = [chars.length-1, ''];
for (let i = 0; i < chars.length;) {
const [c1, c2] = [chars[i], chars[i+1]];
const k = c1 + c2;
const v = table[k];
if (v) {
str += v;
i += k.length;
continue;
} else {
str += table[c1] ?? c1;
i += c1.length;
}
}
return str;
}
static convert(mode, text) {
return ConvertCircled.replace(
ConvertCircled.TypeTable[mode],
text.normalize('NFKC'));
}
static toId(name) {
return `Circled ${name}`.replaceAll(' ', '_');
}
}
// ----------------------------------------------------------------------
class ConvertParenthesized {
static Table = {
"1":"⑴", "2":"⑵", "3":"⑶", "4":"⑷", "5":"⑸",
"6":"⑹", "7":"⑺", "8":"⑻", "9":"⑼", "10":"⑽",
"11":"⑾", "12":"⑿", "13":"⒀", "14":"⒁", "15":"⒂",
"16":"⒃", "17":"⒄", "18":"⒅", "19":"⒆", "20":"⒇",
"A":"🄐", "B":"🄑", "C":"🄒", "D":"🄓", "E":"🄔",
"F":"🄕", "G":"🄖", "H":"🄗", "I":"🄘", "J":"🄙",
"K":"🄚", "L":"🄛", "M":"🄜", "N":"🄝", "O":"🄞",
"P":"🄟", "Q":"🄠", "R":"🄡", "S":"🄢", "T":"🄣",
"U":"🄤", "V":"🄥", "W":"🄦", "X":"🄧", "Y":"🄨",
"Z":"🄩",
"a":"⒜", "b":"⒝", "c":"⒞", "d":"⒟", "e":"⒠",
"f":"⒡", "g":"⒢", "h":"⒣", "i":"⒤", "j":"⒥",
"k":"⒦", "l":"⒧", "m":"⒨", "n":"⒩", "o":"⒪",
"p":"⒫", "q":"⒬", "r":"⒭", "s":"⒮", "t":"⒯",
"u":"⒰", "v":"⒱", "w":"⒲", "x":"⒳", "y":"⒴",
"z":"⒵",
"一":"㈠", "二":"㈡", "三":"㈢", "四":"㈣", "五":"㈤",
"六":"㈥", "七":"㈦", "八":"㈧", "九":"㈨", "十":"㈩",
"月":"㈪", "火":"㈫", "水":"㈬", "木":"㈭", "金":"㈮",
"土":"㈯", "日":"㈰",
"株":"㈱", "有":"㈲", "社":"㈳", "名":"㈴", "特":"㈵",
"財":"㈶", "祝":"㈷", "労":"㈸", "代":"㈹", "呼":"㈺",
"学":"㈻", "監":"㈼", "企":"㈽", "資":"㈾", "協":"㈿",
"祭":"㉀", "休":"㉁", "自":"㉂", "至":"㉃",
"ᄀ":"㈀", "ᄂ":"㈁", "ᄃ":"㈂", "ᄅ":"㈃", "ᄆ":"㈄",
"ᄇ":"㈅", "ᄉ":"㈆", "ᄋ":"㈇", "ᄌ":"㈈", "ᄎ":"㈉",
"ᄏ":"㈊", "ᄐ":"㈋", "ᄑ":"㈌", "ᄒ":"㈍",
"가":"㈎", "나":"㈏", "다":"㈐", "라":"㈑", "마":"㈒",
"바":"㈓", "사":"㈔", "아":"㈕", "자":"㈖", "차":"㈗",
"카":"㈘", "타":"㈙", "파":"㈚", "하":"㈛", "주":"㈜",
"오전":"㈝", "오후":"㈞",
}
static replace(text) {
return text.replace(/(\([^()]+\))/g, ((_, p) =>
ConvertParenthesized.Table[p.slice(1, p.length - 1)] ?? p));
}
}
// ----------------------------------------------------------------------
function toClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
// success
}, () => {
// failed
});
}
function onInput(text) {
lastText = text;
if (lastMode == 'Normalize') {
const C = NormalizeDiff;
C.TypeTable.forEach(name => document.getElementById(C.toId(name)).innerHTML = new C(name, text).toHTML());
return;
}
if (lastMode == 'InnerHTML') {
InnerHTML_output.innerHTML = text;
return;
}
if (lastMode == 'CodePoint') {
const C = CodePointRuby;
const gen = new C(text);
C.TypeTable.forEach(name => document.getElementById(C.toId(name)).innerHTML = gen.toHTML(name));
return;
}
if (lastMode == 'AlphaNumeric') {
const C = ConvertAlphaNumeric;
Object.keys(C.TypeTable).forEach(name =>
document.getElementById(C.toId(name)).innerText = C.convert(name, text));
return;
}
if (lastMode == 'Circled') {
const C = ConvertCircled;
Object.keys(C.TypeTable).forEach(name =>
document.getElementById(C.toId(name)).innerText = C.convert(name, text));
return;
}
if (lastMode == 'Parenthesized') {
Parenthesized_output.innerHTML = encodeHTML(ConvertParenthesized.replace(text));
return;
}
}
function onClick(mode) {
OutputTable.forEach(name =>
document.getElementById(name).hidden = (name != mode));
lastMode = mode;
onInput(lastText);
}
window.onload = function() {
const gentab = ((C, O, tab, button, nfilter) => {
tab.forEach(name => {
const id = C.toId(name);
const thn = (!nfilter ? name : nfilter(name)).replaceAll(' ', ' ');
const tht = !button ? thn : `<button onclick="toClipboard(${id}.innerText)">${thn}</button>`;
O.insertAdjacentHTML('beforeend', `<tr><th class="left">${tht}</th><td id="${id}"></td></tr>`);
});
});
gentab(CodePointRuby, CodePoint, CodePointRuby.TypeTable);
gentab(NormalizeDiff, Normalize, NormalizeDiff.TypeTable, true);
gentab(ConvertAlphaNumeric, AlphaNumeric,
Object.keys(ConvertAlphaNumeric.TypeTable), true,
n => n.replace('MATHEMATICAL ', 'MATHEMATICAL<br/>'));
gentab(ConvertCircled, Circled, Object.keys(ConvertCircled.TypeTable), true);
onClick(OutputTable[0]);
}
</script>
</body>
</html>