濁点と半濁点の入力間違い
視力とディスプレイの問題があると思いますが「ブ」「プ」を間違って入力しているのに気付かない場合がたまにあります。 この間違いは、ローマ字入力の人には生じないでしょう。
ひらがな入力では、「ふ」を入力して「゛」か「゜」を打って「濁点」「半濁点」を決めます。 この時に「濁点」「半濁点」の記号が隣にあり、指の位置が少しズレると違った方になるわけです。
ローマ字入力では「pu /ぷ」「bu /ぶ」はキーが離れていて間違い様がないと思いますが、ローマ字入力でこういうタイプの誤入力の例は他の文字であるのかも?
で、この間違いを生じる文字は「は行」「ハ行」のみで、「日本語の文字」では「ひらかな」「カタカナ」の20文字しかありません。 つまり、「パピプ…」「バビブ…」の 20文字をチェックすれば、「濁点」「半濁点」の間違いはなくせます。
ブログ編集画面で「S-R in Editor ⭐」を使えば「パ」と「バ」のチェックは2回の検索で出来ますが、全20文字では20回が必要です。 検索語(文字)は決まっているので、自動的にこの20文字を拾い出す検索ツールを試作して見ました。
AIの漢字変換が出来て久しく、自動校正ツールなども世の中にありそうですが、編集画面の中では動作しそうにないので、実用性は作って見てから考える事に..
Dakuten ⭐
もちろん最初からツールを作る必要は無く、「S-R in Editor ⭐」を組み変えて2日余りの時間でツールが出来ました。
上の関数が、20文字を検索するエンジンです。 単純なもので、順番に本文の検索をくり返しているだけです。 検索の1回ごとに、ヒットした文字を「<mu>ぱ</mu>」と言った「muタグ」に書換えて行きます。「muタグ」は実際のHTMLには規定がない「独自仕様」ですが、このツール内ではタグとして機能します。
最後に、その「muタグ」のデザインを指定する事で、本文内で検索ヒットした文字をハイライト表示しますが、これも「S-R in Editor ⭐」の踏襲です。
編集画面で使える検索/置換えツール
初見の方のために「S-R in Editor ⭐」について少し。 編集画面内でブラウザによる「Ctrl+F」検索は可能ですが、置換えはできません。「S-R in Editor ⭐」はアメーバ編集画面専用の検索置換え機能です。 ヒット文字の記事上でのチェック、一括と点検しながらの置換え、複数記事での同作業の継続などが可能です。
「Dakuten ⭐」の操作方法
起動のショートカットは「F10」のダブル押下にしました。「ダブル押下」は、キーを2回、素早く押下する操作です。
● 編集画面で「F10」をダブル押下すると、記事タイトルの左横に「小パネル」が出ます。
▪「濁点/半濁点」の文字の総数が「Count」として表示されます。
▪ 本文中の「濁点/半濁点」の全ての文字に、「オレンジ」の下線が付きます。
▪「⇧」「⇨」「⇩」「⇦」のキーで、順に「濁点/半濁点」の文字が選択されて、選択された文字の下線が「赤下線」になります。 このマークは、チェックしている文字の場所を明示するためのマークです。
● 再度「F10」をダブル押下すると「小パネル」と「文字のマーク」が消え、ツールが終了します。
本文チェックと修正
このツールで「濁点」「半濁点」の入力間違いをチェックします。「⇧」「⇩」キーで順にヒットした文字を含む単語を確認します。 もし間違いを見つけた場合は、その場でキャレットを入れて文字を修正できます。
▪ このツールが動作中は、方向キーはキャレットの移動に使えません。 ツールを終了すると、通常の通りキャレット移動に使える様になります。
▪ 検索チェック時は、HTML表示を出来ない様に「通常表示」「HTML表示」のボタンが非表示になります。 ツールを終了するとボタンが使える様になります。
使用上の注意点
チェック・修正が終わったら、「F10」キーのダブル押下でツールを終了してから記事の保存を行ってください。 ツールの終了をせずに投稿・保存をした場合、ハイライト表示のタグが残らない様に自動的に消去をしますが、システムに絶対はないので。
「Dakuten ⭐」を利用するには
このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Dakuten ⭐ 〕 ver. 0.1
// ==UserScript== // @name Dakuten ⭐ // @namespace http://tampermonkey.net/ // @version 0.1 // @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; } } // 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タグ背景色⭕ 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」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。