.NET の Stringでのみ利用可能な.NETメソッド群を利用するには、javascriptの文字列を.NETの文字列に変換する必要があります。
これはなかなか気づきにくい方法となりますので、ここではその手法を紹介します。
#JS = loaddll( hidemarudir + @"\hmJS.dll" ); if ( !#JS ) { message "hmJS.dllが読み込めない"; } #r = dllfuncw( #JS, "DoString", """""""""""""""""""""""""""""""""""""""""""""""""" Object.prototype.toClr = function () { return host.newVar(this.valueOf()); } function ToDotNetString(jsText) { return jsText.toClr(); } var dotNetStr = ToDotNetString("養⽼の滝⼊⼝駐⾞場"); dotNetStr.Normalize(clr.System.Text.NormalizationForm.FormKC); hm.OutputPane.Output(b); """""""""""""""""""""""""""""""""""""""""""""""""" ); freedll( #JS );
このようにすることで、javascriptの文字列を.NETの文字列に変換し、.Normalizeメソッドを利用することが出来るようになりました。
#JS = loaddll( hidemarudir + @"\hmJS.dll" ); if ( !#JS ) { message "hmJS.dllが読み込めない"; } #r = dllfuncw( #JS, "DoString", """""""""""""""""""""""""""""""""""""""""""""""""" Object.prototype.toClr = function () { return host.newVar(this.valueOf()); } function toNETString(jsText) { return jsText.toClr(); } function getTargetString() { return gettotaltext(); } var walker = clr.System.Globalization.StringInfo.GetTextElementEnumerator(toNETString("養ぎ⽼の滝⼊⼝駐⾞場")); while (walker.MoveNext()) { var jsText = walker.GetTextElement(); var dnText = toNETString(jsText); var normalizedText = dnText.Normalize(clr.System.Text.NormalizationForm.FormKC); hm.OutputPane.Output(normalizedText); } """""""""""""""""""""""""""""""""""""""""""""""""" ); freedll( #JS );
サロゲートペアなどまでも考慮した、文字列の捜査も可能です。
#JS = loaddll( hidemarudir + @"\hmJS.dll" ); if ( !#JS ) { message "hmJS.dllが読み込めない"; } #r = dllfuncw( #JS, "DoString", """""""""""""""""""""""""""""""""""""""""""""""""" Object.prototype.toClr = function () { return host.newVar(this.valueOf()); } function main() { var srcText = gettotaltext(); var srcTextArray = srcText.split("\n"); for(var ix=0; ix < srcTextArray.length; ix++) { srcTextArray[ix] = normalizeLine(srcTextArray[ix]); } var dstText = srcTextArray.join("\n"); if (srcText != dstText) { settotaltext(dstText); } } function normalizeLine(text) { // 行全体がSJISの範疇に収まるなら、そのまま採用 if (canConvertSJIS(text)) { return text; } // JavaScriptの文字列を.NETの文字列に変換し、 var netSrcText = text.toClr(); // 合成文字やサロゲートペアも考慮した、ウォーカー(捜査オブジェクト)を構築 var walker = clr.System.Globalization.StringInfo.GetTextElementEnumerator(netSrcText); // 変換結果 var dstText = ""; // 次の文字が存在する限りにおいて、次の文字へと移動 while (walker.MoveNext()) { // 文字を取得。「複数の文字」で「1つの文字を形成」している場合、その複数を全部まとめて取得 var jsText = walker.GetTextElement(); // 特殊な正規化をしつつ、変換結果に追加していく dstText += customNormalize(jsText); } return dstText; } // 1文字ずつに対して処理する特殊な正規化 function customNormalize(jsText) { // SJISに収まるならそのまま採用 if (canConvertSJIS(jsText)) { return jsText; } // NFCで正規化をトライ var dnText = jsText.toClr(); var normNFC = dnText.Normalize(clr.System.Text.NormalizationForm.FormC); // なんか文字が変化してるならまぁそのまま採用。多分よく使う文字に変換されたんだろう。 if (jsText != normNFC) { return normNFC; } // 仕方がないので、NFKCで変換 var normNFKC = dnText.Normalize(clr.System.Text.NormalizationForm.FormKC); return normNFKC; } // SJISに変換して、元へともどした時、同じ文字なら、SJISに収まる文字 function canConvertSJIS(text) { try { if (!this.encoder) { this.encoder = clr.System.Text.Encoding.GetEncoding("Shift_JIS"); } var encodedBytes = this.encoder.GetBytes(text); var decodedText = this.encoder.GetString(encodedBytes); return text == decodedText; } catch(e) {} return false; } main(); """""""""""""""""""""""""""""""""""""""""""""""""" ); freedll( #JS );
このように.NETの文字列とjavascriptを経由して、秀丸エディタの編集文字をうまく編集することが可能です。