康煕部首、CJK部首補助、サロゲートペアの検出

康煕部首を検出して修正案を表示するコードをGeminiに作ってもらったが、CJK部首補助やサロゲートペアも問題を起こしそうなので検出する必要が生じた。そこで、CJK部首補助も検出して修正案を表示できるようにコードを変更し、サロゲートペアを検出して表示するコードも作成してもらった後、それらをまとめた。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="康煕部首とCJK部首補助を検出して修正案を示したり、サロゲートペアを検出してUnicodeを示す">
    <title>康煕部首、CJK部首補助、サロゲートペアの検出</title>
    <style>
        body { font-family: sans-serif; }
        table { border-collapse: collapse; width: auto; /* テーブルの幅を内容に合わせて調整 */ }
        th, td { border: 1px solid #ccc; padding: 8px; text-align: left; white-space: nowrap; /* セルの内容が折り返されないように */ }
        th { background-color: #f0f0f0; }
    </style>
</head>
<body>
    <h1>康煕部首、CJK部首補助、サロゲートペアの検出</h1>
    <textarea id="inputText" rows="10" cols="80" placeholder="ここに文章を入力してください"></textarea>
    <div id="caretLineNumber">現在のキャレット行番号: 1</div>
    <button onclick="findKangxiRadicals()">康煕部首、CJK部首補助の検出</button>
    <button onclick="findSurrogatePairs()">サロゲートペアの検出</button>
    <div id="result"></div>

    <script>
        function getUnicode(char) {
            return char.charCodeAt(0).toString(16).padStart(4, '0').toUpperCase();
        }

    // 康煕部首、CJK部首補助の検出と修正案の表示
        function findKangxiRadicals() {
            const inputText = document.getElementById("inputText").value;
            const resultDiv = document.getElementById("result");
            resultDiv.innerHTML = ""; // 結果をクリア

            // 康煕部首のUnicodeと対応する修正案の文字
            const kangxiToModified = {
                '\u2F00': '一', '\u2F01': '丨', '\u2F02': '丶', '\u2F03': '丿', '\u2F04': '乙', '\u2F05': '亅',
                '\u2F06': '二', '\u2F07': '亠', '\u2F08': '人', '\u2F09': '儿', '\u2F0A': '入', '\u2F0B': '八',
                '\u2F0C': '冂', '\u2F0D': '冖', '\u2F0E': '冫', '\u2F0F': '几', '\u2F10': '凵', '\u2F11': '刀',
                '\u2F12': '力', '\u2F13': '勹', '\u2F14': '匕', '\u2F15': '匚', '\u2F16': '匸', '\u2F17': '十',
                '\u2F18': '卜', '\u2F19': '卩', '\u2F1A': '厂', '\u2F1B': '厶', '\u2F1C': '又', '\u2F1D': '口',
                '\u2F1E': '囗', '\u2F1F': '土', '\u2F20': '士', '\u2F21': '夂', '\u2F22': '夊', '\u2F23': '夕',
                '\u2F24': '大', '\u2F25': '女', '\u2F26': '子', '\u2F27': '宀', '\u2F28': '寸', '\u2F29': '小',
                '\u2F2A': '尢', '\u2F2B': '尸', '\u2F2C': '屮', '\u2F2D': '山', '\u2F2E': '巛', '\u2F2F': '工',
                '\u2F30': '己', '\u2F31': '巾', '\u2F32': '干', '\u2F33': '幺', '\u2F34': '广', '\u2F35': '廴',
                '\u2F36': '廾', '\u2F37': '弋', '\u2F38': '弓', '\u2F39': '彐', '\u2F3A': '彡', '\u2F3B': '彳',
                '\u2F3C': '心', '\u2F3D': '戈', '\u2F3E': '戸', '\u2F3F': '手', '\u2F40': '支', '\u2F41': '攵',
                '\u2F42': '文', '\u2F43': '斗', '\u2F44': '斤', '\u2F45': '方', '\u2F46': '无', '\u2F47': '日',
                '\u2F48': '曰', '\u2F49': '月', '\u2F4A': '木', '\u2F4B': '欠', '\u2F4C': '止', '\u2F4D': '歹',
                '\u2F4E': '殳', '\u2F4F': '毋', '\u2F50': '比', '\u2F51': '毛', '\u2F52': '氏', '\u2F53': '气',
                '\u2F54': '水', '\u2F55': '火', '\u2F56': '爪', '\u2F57': '父', '\u2F58': '爻', '\u2F59': '爿',
                '\u2F5A': '片', '\u2F5B': '牙', '\u2F5C': '牛', '\u2F5D': '犬', '\u2F5E': '玄', '\u2F5F': '玉',
                '\u2F60': '瓜', '\u2F61': '瓦', '\u2F62': '甘', '\u2F63': '生', '\u2F64': '用', '\u2F65': '田',
                '\u2F66': '疋', '\u2F67': '疒', '\u2F68': '癶', '\u2F69': '白', '\u2F6A': '皮', '\u2F6B': '皿',
                '\u2F6C': '目', '\u2F6D': '矛', '\u2F6E': '矢', '\u2F6F': '石', '\u2F70': '示', '\u2F71': '禸',
                '\u2F72': '禾', '\u2F73': '穴', '\u2F74': '立', '\u2F75': '竹', '\u2F76': '米', '\u2F77': '糸',
                '\u2F78': '缶', '\u2F79': '网', '\u2F7A': '羊', '\u2F7B': '羽', '\u2F7C': '老', '\u2F7D': '而',
                '\u2F7E': '耒', '\u2F7F': '耳', '\u2F80': '聿', '\u2F81': '肉', '\u2F82': '臣', '\u2F83': '自',
                '\u2F84': '至', '\u2F85': '臼', '\u2F86': '舌', '\u2F87': '舛', '\u2F88': '舟', '\u2F89': '艮',
                '\u2F8A': '色', '\u2F8B': '艸', '\u2F8C': '虍', '\u2F8D': '虫', '\u2F8E': '血', '\u2F8F': '行',
                '\u2F90': '衣', '\u2F91': '西', '\u2F92': '見', '\u2F93': '角', '\u2F94': '言', '\u2F95': '谷',
                '\u2F96': '豆', '\u2F97': '豕', '\u2F98': '豸', '\u2F99': '貝', '\u2F9A': '赤', '\u2F9B': '走',
                '\u2F9C': '足', '\u2F9D': '身', '\u2F9E': '車', '\u2F9F': '辛', '\u2FAA': '隶', '\u2FAB': '隹',
                '\u2FAC': '雨', '\u2FAD': '青', '\u2FAE': '非', '\u2FAF': '面', '\u2FB0': '革', '\u2FB1': '韋',
                '\u2FB2': '韭', '\u2FB3': '音', '\u2FB4': '頁', '\u2FB5': '風', '\u2FB6': '飛', '\u2FB7': '食',
                '\u2FB8': '首', '\u2FB9': '香', '\u2FBA': '馬', '\u2FBB': '骨', '\u2FBC': '高', '\u2FBD': '髟',
                '\u2FBE': '鬥', '\u2FBF': '鬯', '\u2FC0': '鬲', '\u2FC1': '鬼', '\u2FC2': '魚', '\u2FC3': '鳥',
                '\u2FC4': '鹵', '\u2FC5': '鹿', '\u2FC6': '麥', '\u2FC7': '麻', '\u2FC8': '黃', '\u2FC9': '黍',
                '\u2FCA': '黒', '\u2FCB': '黹', '\u2FCC': '黽', '\u2FCD': '鼎', '\u2FCE': '鼓', '\u2FCF': '鼠',
                '\u2FD0': '鼻', '\u2FD1': '齊', '\u2FD2': '齒', '\u2FD3': '龍', '\u2FD4': '龜', '\u2FD5': '龠',
                '\u2FD6': '', '\u2FD7': '', '\u2FD8': '', '\u2FD9': '', '\u2FDA': '', '\u2FDB': '',
                '\u2FDC': '', '\u2FDD': '', '\u2FDE': '', '\u2FDF': '', '\u2FE0': '', '\u2FE1': '',
                '\u2FE2': '', '\u2FE3': '', '\u2FE4': '', '\u2FE5': '', '\u2FE6': '', '\u2FE7': '',
                '\u2FE8': '', '\u2FE9': '', '\u2FEA': '', '\u2FEB': '', '\u2FEC': '', '\u2FED': '',
                '\u2FEE': '', '\u2FEF': '', '\u2FF0': '', '\u2FF1': '', '\u2FF2': '', '\u2FF3': '',
                '\u2FF4': '', '\u2FF5': '', '\u2FF6': '', '\u2FF7': '', '\u2FF8': '', '\u2FF9': '',
                '\u2FFA': '', '\u2FFB': '', '\u2FFC': '', '\u2FFD': '', '\u2FFE': '', '\u2FFF': '',
                '\u2E80': '〃', '\u2E81': '厂', '\u2E82': '乛', '\u2E83': '乚', '\u2E84': '乙', '\u2E85': '亻',
                '\u2E86': '冂', '\u2E87': '几', '\u2E88': '刀', '\u2E89': '刂', '\u2E8A': '卜', '\u2E8B': '㔾',
                '\u2E8C': '小', '\u2E8D': '小', '\u2E8E': '兀', '\u2E8F': '尣', '\u2E90': '尢', '\u2E91': '尣',
                '\u2E92': '巳', '\u2E93': '幺', '\u2E94': '彑', '\u2E95': '彐', '\u2E96': '忄', '\u2E97': '心',
                '\u2E98': '扌', '\u2E99': '攵', '\u2E9B': '旡', '\u2E9C': '冃', '\u2E9D': '月', '\u2E9E': '歺',
                '\u2E9F': '母', '\u2EA0': '民', '\u2EA1': '氵', '\u2EA2': '氺', '\u2EA3': '灬', '\u2EA4': '爫',
                '\u2EA5': '爫', '\u2EA6': '丬', '\u2EA7': '牛', '\u2EA8': '犭', '\u2EA9': '王', '\u2EAA': '疋',
                '\u2EAB': '目', '\u2EAC': '示', '\u2EAD': '礻', '\u2EAE': '竹', '\u2EAF': '糹', '\u2EB0': '纟',
                '\u2EB1': '罓', '\u2EB2': '罒', '\u2EB3': '网', '\u2EB4': '网', '\u2EB5': '网', '\u2EB6': '羊',
                '\u2EB7': '羊', '\u2EB8': '羋', '\u2EB9': '耂', '\u2EBA': '肀', '\u2EBB': '聿', '\u2EBC': '肉',
                '\u2EBD': '臼', '\u2EBE': '艹', '\u2EBF': '艹', '\u2EC0': '艹', '\u2EC1': '虎', '\u2EC2': '衤',
                '\u2EC3': '覀', '\u2EC4': '西', '\u2EC5': '见', '\u2EC6': '角', '\u2EC7': '角', '\u2EC8': '讠',
                '\u2EC9': '贝', '\u2ECA': '足', '\u2ECB': '车', '\u2ECC': '辶', '\u2ECD': '辶', '\u2ECE': '辶',
                '\u2ECF': '阝', '\u2ED0': '钅', '\u2ED1': '長', '\u2ED2': '镸', '\u2ED3': '长', '\u2ED4': '门',
                '\u2ED5': '阜', '\u2ED6': '阝', '\u2ED7': '雨', '\u2ED8': '青', '\u2ED9': '韦', '\u2EDA': '页',
                '\u2EDB': '风', '\u2EDC': '飞', '\u2EDD': '食', '\u2EDE': '飠', '\u2EDF': '飠', '\u2EE0': '饣',
                '\u2EE1': '首', '\u2EE2': '马', '\u2EE3': '骨', '\u2EE4': '鬼', '\u2EE5': '鱼', '\u2EE6': '鸟',
                '\u2EE7': '卤', '\u2EE8': '麦', '\u2EE9': '黄', '\u2EEA': '黾', '\u2EEB': '斉', '\u2EEC': '齐',
                '\u2EED': '歯', '\u2EEE': '齿', '\u2EEF': '竜', '\u2EF0': '龙', '\u2EF1': '龜', '\u2EF2': '亀',
                '\u2EF3': '龟'
            };

            const lines = inputText.split('\n');
            let outputHTML = "<table><thead><tr><th>行</th><th>検出された文字</th><th>Unicode</th><th>修正案</th><th>Unicode</th></tr></thead><tbody>";

            for (let i = 0; i < lines.length; i++) {
                const line = lines[i];
                for (let j = 0; j < line.length; j++) {
                    const char = line[j];
                    if (kangxiToModified.hasOwnProperty(char)) {
                        const modifiedChar = kangxiToModified[char];
                        outputHTML += `<tr><td>${i + 1}</td><td>${char}</td><td>U+${getUnicode(char)}</td><td>${modifiedChar}</td><td>U+${getUnicode(modifiedChar)}</td></tr>`;
                    }
                }
            }

            outputHTML += "</tbody></table>";
            resultDiv.innerHTML = outputHTML;
        }

    // サロゲートペアの検出
        function findSurrogatePairs() {
            const inputText = document.getElementById("inputText").value;
            const resultDiv = document.getElementById("result");
            resultDiv.innerHTML = ""; // 結果をクリア

            function getCodePointUnicode(codePoint) {
                return codePoint.toString(16).toUpperCase();
            }

            const lines = inputText.split('\n');
            let outputHTML = "<table><thead><tr><th>行</th><th>検出された文字</th><th>結合後 Unicode</th><th>Unicode (上位/下位)</th></tr></thead><tbody>";

            for (let i = 0; i < lines.length; i++) {
                const line = lines[i];
                for (let j = 0; j < line.length; j++) {
                    const charCode = line.charCodeAt(j);
                    if (0xD800 <= charCode && charCode <= 0xDBFF) {
                        if (j + 1 < line.length) {
                            const nextCharCode = line.charCodeAt(j + 1);
                            if (0xDC00 <= nextCharCode && nextCharCode <= 0xDFFF) {
                                const surrogatePair = line.substring(j, j + 2);
                                const highSurrogate = line[j];
                                const lowSurrogate = line[j + 1];
                                const codePoint = 0x10000 + ((charCode - 0xD800) << 10) + (nextCharCode - 0xDC00);

                                outputHTML += `<tr><td>${i + 1}</td><td>${surrogatePair}</td><td>U+${getCodePointUnicode(codePoint)}</td><td>U+${getUnicode(highSurrogate)} U+${getUnicode(lowSurrogate)}</td></tr>`;
                                j++;
                            }
                        }
                    }
                }
            }

            outputHTML += "</tbody></table>";
            resultDiv.innerHTML = outputHTML;
        }

    // URLの?の後ろをTextAreaに入力
        window.onload = function() {
            document.getElementById("inputText").value = decodeURIComponent(location.search.substring(1));
            document.getElementById("inputText").focus(); // カーソルを合わせる
        };

    // TextArea キャレット行番号取得
        const textarea = document.getElementById('inputText');
        const caretLineNumberDiv = document.getElementById('caretLineNumber');

        function updateCaretLineNumber() {
            const caretPosition = textarea.selectionStart;
            const textBeforeCaret = textarea.value.substring(0, caretPosition);
            const lineNumber = textBeforeCaret.split('\n').length;
            caretLineNumberDiv.textContent = `現在のキャレット行番号: ${lineNumber}`;
        }

        textarea.addEventListener('input', updateCaretLineNumber);
        textarea.addEventListener('mouseup', updateCaretLineNumber);
        textarea.addEventListener('keyup', updateCaretLineNumber);

        // 初期表示
        updateCaretLineNumber();
    </script>
</body>
</html>

コメント