思った以上に多い「パペポ」の文字
前ページの「ver.0.1」を実際に試していただくと判りますが、ヒットする文字数が予想した以上に多いと感じます。
この記事で90文字程度がヒットするので、記事を書くごとにこれをチェックするのはえらく手間です。 実際の間違いはたまにしか生じないのに。
私の一番用心しているのは、下の間違いです。
これは注意する様になって減ったらしく、時々ブログ内検索をかけてチェックしていますが、完全に無くならないものの、とても減りました。 最初に気付いた時は余りに多くて愕然としましたが。
同じ間違いは、アメーバブログ全体を検索して見ると何件かは見つかりましたが、思ったよりも少ないです。
スマホ入力は、PCのローマ字入力より生じ易いと思いますが、殆どがPCのかな入力に拠ると推測します。 かな入力は当然「漢字変換」が伴い「へりこぶたー」と間違って入力しても「ヘリコプター」に勝手に訂正されます。 この訂正機能があるので、間違った「濁点・半濁点」が入力される場合は、より少ないと思われます。
それだけに、「てにおは」の間違いより「濁点・半濁点」の間違いの方が気付き難く「闇討ち的」です。 校正・読み直しをすり抜けるタイプですから。
文字を大きくする事
これは、以前に作った「Editor Mag ⭐」の様な「文字自体の拡大表示」が手っ取り早い解決策かも知れません。 ブラウザの拡大と併用すると、文字が小さくて困っているユーザーには、かなり優れた編集環境になると思います。
まあ、それは最後の手段として、「Dakuten ⭐」をもう少し練ってみます。
フォントを変えてしまう
濁点と半濁点の物理的なサイズが、間違いに気付かない大きな理由なので、この「パペポ」の文字だけフォントを区別し易いデザインに変える事を考えました。
区別するには濁点の方はそのままで良く、半濁点の「〇」を大きくした活字があれば足りると思います。 特殊なフォントを用意するのは簡単ではないので、簡易な合字(Ligature)でテストする事にしました。 下のCSSが合字のデザイン適用です。
検索ヒットした「20の文字」は「muタグ」を付けています。 このタグを付ける事で、下線等のハイライト表示を行っています。
その中で、「ぱぴぷぺぽ」「パピプぺポ」の半濁点の文字だけ選択し、特別に「pp」のクラス名を付けます。 濁点の文字には着けません。
で、上の「mu.pp」に「疑似要素」で「o」の文字を重ねて「゜」を強調したのが以下です。
とってつけたテスト用の「合字」で、美しくはありません。「ver.0.2」は、この「合字」でのチェックのテストバージョンです。
「Dakuten ⭐」を利用するには
このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Dakuten ⭐ 〕 ver. 0.2
// ==UserScript== // @name Dakuten ⭐ // @namespace http://tampermonkey.net/ // @version 0.2 // @description 編集枠(通常表示)で濁点・半濁点のチェック 「F10」ダブルキー押下 // @author Ameba Blog User // @match https://blog.ameba.jp/ucs/entry/srventry* // @exclude https://blog.ameba.jp/ucs/entry/srventrylist.do* // @grant none // ==/UserScript== let retry=0; let interval=setInterval(wait_target, 100); function wait_target(){ retry++; if(retry>10){ // リトライ制限 10回 1sec clearInterval(interval); } let target=document.getElementById('cke_1_contents'); // 監視 target if(target){ clearInterval(interval); main(); }} function main(){ let act_mode=0; let buffer; let hk; // ハイライト要素のインデックス let native_hk; // フォーカス要素のインデックス履歴 let result_box; let count_t; let editor_iframe; let iframe_doc; let iframe_body; let iframe_html; let target=document.getElementById('cke_1_contents'); // 監視 target let monitor=new MutationObserver(catch_key); monitor.observe(target, {childList: true}); // ショートカット待受け開始 catch_key(); function catch_key(){ document.onkeydown=function(event){ check_key(event); } editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ iframe_doc.onkeydown=function(event){ check_key(event); }}} let clickCount=0; function check_key(event){ if(event.keyCode==121){ //「F10」ダブルキー押下 event.preventDefault(); if(!clickCount){ // シングルキー押下の場合 ++clickCount; setTimeout( function(){ clickCount=0; }, 500 ); } else{ // ダブルキー押下の場合 clickCount=0; check_act(); }} function check_act(){ if(if_check()){ if(act_mode==0){ act_mode=1; dis_html(0); setTimeout(()=>{ check_text(); }, 20); } else{ act_mode=0; dis_html(1); delete_mu(); remove_container(); }} } } // check_key() function if_check(){ editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ return true; } else{ return false; }} before_end(); // 編集終了時にマークを自動削除 } // catch_key function dis_html(n){ let editor_tab=document.querySelector('.p-editModeTab'); if(editor_tab){ if(n==0){ editor_tab.style.display='none'; } else{ editor_tab.style.display='block'; }}} function disp_container(){ monitor.disconnect(); // MutationObserverを 起動表示に反応させない let insert_div= '<div id="cds_container">'+ '<span id="cd_result"> </span>'+ '<style>'+ '#cds_container { position: absolute; top: 17px; left: 20px; '+ 'width: auto; padding: 3px 6px; background: #fff; '+ 'border: 1px solid #aaa; border-radius: 4px; z-index: 11; }'+ '#cd_result { display: inline-block; min-width: 70px; padding: 4px 6px 2px; '+ 'border: 1px solid #aaa; font-size: 16px; }'+ '</style></div>'; let l_body=document.querySelector('body.l-body'); if(!l_body.querySelector('#cds_container')){ l_body.insertAdjacentHTML('beforeend', insert_div); } add_mu_style(); // muタグを設定 monitor.observe(target, {childList: true}); } // disp_container() 「開始処理」 function remove_container(){ let cds_container=document.querySelector('#cds_container'); if(cds_container){ cds_container.remove(); }} function check_text(){ disp_container(); editor_iframe=document.querySelector('.cke_wysiwyg_frame'); // ここで取得 if(editor_iframe){ //「通常表示」が実行条件 iframe_doc=editor_iframe.contentWindow.document; iframe_body=iframe_doc.querySelector('.cke_editable'); buffer=iframe_body.innerHTML; // ハイライト表示のためソースコードを保存 🟦 t_process(); native_hk=-1; hk=0; next(hk); } function t_process(){ let search_word= ["ぱ","ぴ","ぷ","ぺ","ぽ","ば","び","ぶ","べ","ぼ","パ","ピ","プ","ペ","ポ","バ","ビ","ブ","ベ","ボ"]; let rep_word; let rep_buffer=buffer; for(let k=0; k<search_word.length; k++){ rep_word='<mu>'+ search_word[k] +'</mu>'; rep_buffer=rep_buffer.replace(new RegExp(search_word[k], 'g'), rep_word); } iframe_body.innerHTML=rep_buffer; let mu_all=iframe_body.querySelectorAll('mu'); count_t=mu_all.length; let search_word_p= ["ぱ","ぴ","ぷ","ぺ","ぽ","パ","ピ","プ","ペ","ポ"]; for(let i=0; i<mu_all.length; i++){ if(search_word_p.includes(mu_all[i].textContent)){ mu_all[i].classList.add('pp'); }}} } // check_text() function next(hk){ //「巡回表示」「選択置換」コード result_box=document.querySelector('#cd_result'); let mark=iframe_body.querySelectorAll('mu'); if(native_hk!=-1){ // 基本的に前回のインデックスを再現🅿 hk=native_hk; } else if(native_hk==-1 || !native_hk){ // 初期インデックス生成🅿 if(mark.length==1){ hk=0; } // 1個なら即決定 else{ let near_n; // 中央後方の要素のインデックス let editor_hight=editor_iframe.clientHeight; // 編集枠の高さ for(let k=1; k<mark.length; k++){ // スクロール位置中央を越えるmark[k]を取得 if(mark[k].getBoundingClientRect().top>editor_hight/2){ near_n=k; break; }} if(!near_n){ // スクロール位置中央より後方にmark[k]がない場合 hk=mark.length-1; } else{ // 直前の mark[k]と比較して、近い方を採る if(mark[near_n].getBoundingClientRect().top> editor_hight-mark[near_n-1].getBoundingClientRect().top){ hk=near_n-1; } else{ hk=near_n; }}}} view(hk); try{ mark[hk].classList.add("h"); } // 最初のハイライト色を変更 catch(e){ ; } result_box.textContent='Count:'+count_t+'│'+(hk+1); document.addEventListener("keydown", check_arrow); // documentは先に指定 iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ iframe_doc.addEventListener("keydown", check_arrow); }// iframeは後に指定 function check_arrow(event){ if(event.keyCode==38 && act_mode==1){ //「⇧」 event.preventDefault(); back(); } if(event.keyCode==37 && act_mode==1){ //「⇦」 event.preventDefault(); back(); } if(event.keyCode==40 && act_mode==1){ //「⇩」 event.preventDefault(); forward() } if(event.keyCode==39 && act_mode==1){ //「⇨」 event.preventDefault(); forward() } native_hk=hk; function back(){ if(hk>0){ // 標準のハイライト色に戻す mark[hk].classList.remove("h"); hk-=1; } else if(hk==0){ hk=0; } result_box.textContent='Count:'+count_t+'│'+(hk+1); try{ mark[hk].classList.add("h"); } catch(e){ ; } view(hk); } function forward(){ if(hk<mark.length-1){ // 標準のハイライト色に戻す mark[hk].classList.remove("h"); hk+=1; } else if(hk==mark.length-1){ hk=mark.length-1; } result_box.textContent='Count:'+count_t+'│'+(hk+1); try{ mark[hk].classList.add("h"); } catch(e){ ; } view(hk); } }} // next() インデックス取得🅿 function view(hk){ let l_body=document.querySelector('body.l-body'); let mark=iframe_body.querySelectorAll('mu'); try{ mark[hk].scrollIntoView({block: "center"}); iframe_html.scrollBy(0, -12); } // -1~-24 -12がクリープを無くす最適値 catch(e){ ; } l_body.scrollIntoView(); } function add_mu_style(){ editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ //「通常表示」の場合 iframe_doc=editor_iframe.contentWindow.document; iframe_html=iframe_doc.querySelector('html'); let css_iframe= '.cke_editable mu { box-shadow: inset 0 -6px 0 -1px #ffcc00; } '+ // ハイライト muタグ背景色⭕ '.cke_editable mu.h { box-shadow: inset 0 -6px 0 -1px red; } '+ // フォーカス muタグ背景色⭕ '.cke_editable mu.pp:before { content: "o"; font-size: 12px; '+ 'margin: 0 -17px 0 10px; vertical-align: 10px; }'; let style_tag_iframe=iframe_doc.createElement("style"); style_tag_iframe.setAttribute("class", "ep"); style_tag_iframe.appendChild(document.createTextNode(css_iframe)); if(iframe_html.querySelector('.ep')){ iframe_html.querySelector('.ep').remove(); } iframe_html.appendChild(style_tag_iframe); }} function delete_mu(){ editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ //「通常表示」の場合 iframe_doc=editor_iframe.contentWindow.document; iframe_body=iframe_doc.querySelector('.cke_editable'); if(iframe_body){ let mark=iframe_body.querySelectorAll('mu'); if(mark.length!=0){ iframe_body.innerHTML= iframe_body.innerHTML.replace(new RegExp('<mu.*?>', 'g'), ''); }}}} function before_end(){ editor_iframe=document.querySelector('.cke_wysiwyg_frame'); let submitButton=document.querySelectorAll('.js-submitButton'); submitButton[0].addEventListener("mousedown", all_clear, false); submitButton[1].addEventListener("mousedown", all_clear, false); function all_clear(){ if(!editor_iframe){ //「HTML表示」編集画面の場合 alert("⛔ Dakuten ⭐ の終了処理ができません\n\n"+ " 通常表示画面に戻り 編集を終了してください"); event.stopImmediatePropagation(); event.preventDefault(); } if(editor_iframe){ //「通常表示」編集画面の場合 if(act_mode==1){ dis_html(1); delete_mu(); remove_container(); }} }} // before_end() } // main()
「Dakuten ⭐」最新版について
旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
●「Dakuten」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。