Appleファイルシステム等で分離した濁点・半濁点を置換で結合するマクロ|サクラエディタ JavaScriptマクロ (bregonig.dll / 古いJScript環境対応)
// ================================================================================
// サクラエディタ JavaScriptマクロ (bregonig.dll / 古いJScript環境対応)
// Appleファイルシステム等で分離した濁点・半濁点を置換で結合するマクロ
// ================================================================================
// 1. 全選択してテキストを取得
Editor.SelectAll();
var text = Editor.GetSelectedString();
// 2. 制御文字の除去
text = text.replace(/[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFE00-\uFE0F\uFEFF]/g, '');
// 3. 濁点・半濁点の置換マップ(Unicode文字とHTMLエンティティの両方に対応)
// ※「本体 + 結合用濁点(U+3099 または ゙)」を1文字の濁音に置換します
var dakutenMap = [
// --- カタカナ 濁音 ---
{ from: /カ([\u3099]|゙)/g, to: 'ガ' },
{ from: /キ([\u3099]|゙)/g, to: 'ギ' },
{ from: /ク([\u3099]|゙)/g, to: 'グ' },
{ from: /ケ([\u3099]|゙)/g, to: 'ゲ' },
{ from: /コ([\u3099]|゙)/g, to: 'ゴ' },
{ from: /サ([\u3099]|゙)/g, to: 'ザ' },
{ from: /シ([\u3099]|゙)/g, to: 'ジ' },
{ from: /ス([\u3099]|゙)/g, to: 'ズ' },
{ from: /セ([\u3099]|゙)/g, to: 'ゼ' },
{ from: /ソ([\u3099]|゙)/g, to: 'ゾ' },
{ from: /タ([\u3099]|゙)/g, to: 'ダ' },
{ from: /チ([\u3099]|゙)/g, to: 'ヂ' },
{ from: /ツ([\u3099]|゙)/g, to: 'ヅ' },
{ from: /テ([\u3099]|゙)/g, to: 'デ' },
{ from: /ト([\u3099]|゙)/g, to: 'ド' },
{ from: /ハ([\u3099]|゙)/g, to: 'バ' },
{ from: /ヒ([\u3099]|゙)/g, to: 'ビ' },
{ from: /フ([\u3099]|゙)/g, to: 'ブ' },
{ from: /ヘ([\u3099]|゙)/g, to: 'ベ' },
{ from: /ホ([\u3099]|゙)/g, to: 'ボ' },
{ from: /ウ([\u3099]|゙)/g, to: 'ヴ' },
// --- カタカナ 半濁音 ---
{ from: /ハ([\u309A]|゚)/g, to: 'パ' },
{ from: /ヒ([\u309A]|゚)/g, to: 'ピ' },
{ from: /フ([\u309A]|゚)/g, to: 'プ' },
{ from: /ヘ([\u309A]|゚)/g, to: 'ペ' },
{ from: /ホ([\u309A]|゚)/g, to: 'ポ' },
// --- ひらがな 濁音 ---
{ from: /か([\u3099]|゙)/g, to: 'が' },
{ from: /き([\u3099]|゙)/g, to: 'ぎ' },
{ from: /く([\u3099]|゙)/g, to: 'ぐ' },
{ from: /け([\u3099]|゙)/g, to: 'げ' },
{ from: /こ([\u3099]|゙)/g, to: 'ご' },
{ from: /さ([\u3099]|゙)/g, to: 'ざ' },
{ from: /し([\u3099]|゙)/g, to: 'じ' },
{ from: /す([\u3099]|゙)/g, to: 'ず' },
{ from: /せ([\u3099]|゙)/g, to: 'ぜ' },
{ from: /そ([\u3099]|゙)/g, to: 'ぞ' },
{ from: /た([\u3099]|゙)/g, to: 'だ' },
{ from: /ち([\u3099]|゙)/g, to: 'ぢ' },
{ from: /つ([\u3099]|゙)/g, to: 'づ' },
{ from: /て([\u3099]|゙)/g, to: 'で' },
{ from: /と([\u3099]|゙)/g, to: 'ど' },
{ from: /は([\u3099]|゙)/g, to: 'ば' },
{ from: /ひ([\u3099]|゙)/g, to: 'び' },
{ from: /ふ([\u3099]|゙)/g, to: 'ぶ' },
{ from: /へ([\u3099]|゙)/g, to: 'べ' },
{ from: /ほ([\u3099]|゙)/g, to: 'ぼ' },
{ from: /う([\u3099]|゙)/g, to: 'ゔ' },
// --- ひらがな 半濁音 ---
{ from: /は([\u309A]|゚)/g, to: 'ぱ' },
{ from: /ひ([\u309A]|゚)/g, to: 'ぴ' },
{ from: /ふ([\u309A]|゚)/g, to: 'ぷ' },
{ from: /へ([\u309A]|゚)/g, to: 'ぺ' },
{ from: /ほ([\u309A]|゚)/g, to: 'ぽ' }
];
// 4. ループで順番に置換を実行
for (var i = 0; i < dakutenMap.length; i++) {
text = text.replace(dakutenMap[i].from, dakutenMap[i].to);
}
// 5. 改行の整理
text = text.replace(/^[\r\n]+/gm, '');
text = text.replace(/\r?\n/g, '\r\n');
// 6. 書き戻しとコピー
Editor.SelectAll();
Editor.InsText(text);
Editor.SelectAll();
Editor.Copy();