複数dotを含む数値塊をカウントする
今回、「path」コードに、「nnn.nnn.nnn」の様に、dotが2個ある「数値塊」と、更に3個以上ある「数値塊」のカウント機能を作りました。 これは、このタイプの「数値塊」の出現数を調べるためです。
「F3」以外のキーを押した場合は、「数値塊」の処理コードが動作するので、ついでにカウント機能を動作させています。 これは、本来の処理に影響しませんが、その結果を毎回報告します。 報告する場所は、記事タイトルの入力枠です。(このツールの使用時は記事は書かないと思うので)
で、この機能で、「Shift+F1」「Shift+F2」の時に、2回報告を表示するのに気付きました。 コードをよく見ると、ショートカットを判断するコードの分岐の書き方が悪く、「Shift+F1」は、同時に「F1」と判断され、2回処理しているのでした。 まぁ、初歩的なミスです xx);
3個のdotタイプは出て来ない
理屈からは「123.45」「0.67」「0.89」を「123.45.67.89」と省略・連結する事は可能なはずです。 しかし、現在の所は「3個」のタイプは出て来ません。 「path」コードの数値は座標が主なので、2個以上を連結しない約束なのか?
でも、確実な事が判るまで、3個以上も想定してコードを作る必要があります。
2個のdotタイプを処理する
何度か失敗した「2個」タイプの「数値塊」の処理コードを作りました。 この処理では、JavaScriptの処理関数が返す数値の厳密なチェックが必要です。
◎「0.1」を「Math.round」で四捨五入した場合は「0」を返します。 その手前の区切り文字が「-」の場合、「-.1」の四捨五入の結果は「-0」になります。「path」の「d属性」の表記で、これは問題にならない様です。 区切り文字が「アルファベット」なら、「0」は座標の数値でアリなので問題なしです。
◎「dot」で分けた後方の数の処理で、多くの問題が生じます。 後方の数は「.nnn」の形で、必ず「1以下」の値です。 これを四捨五入すると、結果は「1」か「0」になります。 繰り上げの「1」は「dot」が無く、手前の数に繋ぐ事ができません。 また「0」も「dot」が無いので繋ぐ事は出来ません。
従って、後方の数の四捨五入は、必ず手前に「半角スペース」を追加して繋ぐ必要があります。
◎「1以下」の小数と判っている後方を四捨五入するのは空しく、後方は「小数第2位」で四捨五入する事にします。 その場合、後方が「.96…」などなら、桁上がりして「1.0」の結果が返ります。 こうなると、やはり前の数との間に「半角スペース」を追加しないと繋げません。「.95」未満の場合は「dot」付の値になりますが、結果には「0.941」➔「0.9」の様に「0」が付き、そのまま繋ぐ事ができません。
◎ 前方の数を通常の四捨五入、後方の「小数第2位」で四捨五入する場合は、
「12.34.941」➔「120.9」(望む結果は「12 0.9」か「12 .9」です)
の様に、前方の数との間に「半角スペース」が必要になります。
◎ 前方も後方も「小数第2位」で四捨五入する場合は、普通は両方とも「dot」付の数になり、その場合は、
「12.34.941」➔「12.30.9」という結果になり「0」を省かなくてもエラーにはなりません。 ただし、手前の数が「0」になる事があり、これは1個の数と判断されエラーになるでしょう。(「小数第2位」の四捨五入は「0」を返す事がある)
「0.02.941」➔「00.9」(望む結果は「0 0.9」か「0 .9」です)
以上の様に、前方の「dot」の有無を条件に入れると分岐がどんどん複雑になるので^^; ここは後方の数の処理のみで分岐する様にしました。
以下は「dot 2個」タイプの「数値塊」を処理するコードです。 その手前で「dot」の個数で分岐して、「dot 3個」は処理をしない様にしています。
前半のループで「数値塊」を2個目の「dot」の前後で分割して、「tmp_num1」と「tmp_num2」の2個の数値にしています。 正規表現を使えばもっとスマートに分割できるかも知れません。
後半は「f_mode」によって処理方法を別けています。「f_mode」は「Fn」キー押下時に選択されます。
上半分は前方の数「tmp_num1」を「小数第2位」で四捨五入するコードで、下半分は、通常の四捨五入処理です。
但し、後方の数「tmp_num2」は常に「小数第2位」で四捨五入する仕様です。 先に書いた様に、「tmp_num2」の結果が桁上がりして「1.0」になるか、ならないかで条件分岐し、前の数との間に「半角スペース」を置いたり、自らの「0」を削除するなどの「繋ぐ方法」を変えています。
なんとか「2個」タイプを攻略したが
漸くエラーなしで「dot 2個」タイプの「数値塊」も処理するコードが出来ました。 しかし、SVGを幾つか処理して見たところ、従来の「小数第2位」で四捨五入するコードと比べて、結果の文字数が変わらないか少し増えます。 せっかく「2個タイプ」を攻略したのに、明らかな効果が見えません。
これは、「dot 2個」タイプの「数値塊」の数が、そんなに多く出現しないのが、ひとつの理由でしょう。 また、分割処理で「半角スペース」を追加して繋ぐので、文字数を増やします。 全数値が下6桁といったコードなら、前方の数の処理で最大「7」文字を減らせますが、下2桁程度なら効果は隠れてしまいそうです。 苦労したわりには、効果は判らないという結果ですが、時には有効な対象があるかも知れません。
「Simple SVG」の扱い方
SVGアイコンを自作するなどの詳しい方法は、下のページに纏めています。
以下は、現在のバージョンの基本的な操作方法です。
◎「Tampermonkey」で「Simple SVG」を「ON」にします。このツールは、SVG画像のコードを処理する場合にのみ「ON」にしてください。(非常駐型ツール)
◎ このツールは編集画面を利用してSVG画像を処理し、ブログ記事の通常の編集とは別の状態になります。 処理操作時の記事を投稿・保存が出来ますが、記事内容は保証されません。 ブログ記事の編集は、必ずこのツールを「OFF」にしてから、新たに別の編集画面を開いて行ってください。
◎ 新しい編集画面を開き、「HTML表示」で「SVG画像」のソースコードをペーストします。 この場合のソースコードとは、画像の「svgタグ」の内容全ての事です。
この際、不要な付帯タグなどが削除できるものは、手作業で削除します。 編集枠には、元画像のソースコードを記入するだけで、他の記入はしないのがベストです。
◎「通常表示」に戻りSVGコードの整形処理と簡略化処理を行います。
現在利用できる機能は以下です。
●「F1」:「半角スペース」区切りのコードの簡略化
●「Shift+F1」:「半角スペース」区切りのコードの簡略化(小数第1位まで出力)
●「F2」:「カンマ」区切りのコードの簡略化
●「Shift+F2」:「カンマ」区切りのコードの簡略化(小数第1位まで出力)
●「F3」: SVGコードの整形処理(一般的な不要タグ・属性などの削除)
◎「F1」または「F2」を押し、処理後のSVG画像の劣化が許容できない場合は、「Shift」を同時に押して処理します。 画質が改善する代わり文字数が増えます。
◎「HTML表示」で処理元のSVG画像のコードを手作業で修正したり、処理元のSVG画像を差替えて、新しいSVG画像を処理することができます。
◎「F1」「F2」を押した瞬間に処理が行われます。 処理前と処理後の「SVG画像」が表示されるので、画像の劣化や崩れが無いかなどが判ります。 元の画像は上側に表示され続けますが、「F3」を押すと下側に元画像と同等の画像が表示され、微妙な変化が確認できます。
◎「F3」以外の「Fn」キーを押した処理操作の度に、記事タイトルに「dot2個」「dot3個(以上)」の「数値塊」の数をカウントして表示します。
◎「カンマ」区切りの「path」を「半角スペース」区切りで処理した場合などは、処理後のSVG画像が崩れて表示される場合が多く、同時に「dot」カウントが異常値を示す事があります。 処理間違いは、ツールや元画像に影響はありません。
「Simple SVG」を利用するには
このツールは Chrome / Edge / Firefox の拡張機能「Tampermonkey」上で動作します。 このツールは処理操作をする場合のみ「ON」にする非常駐型ツールです。 処理の必要がなくなった時に、必ず「OFF」にしてください。
以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。 以下のページに簡単な導入の説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
●「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
●「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
● 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Simple SVG 〕 ver. 0.4
// ==UserScript== // @name Simple SVG ⭐ // @namespace http://tampermonkey.net/ // @version 0.4 // @description ブログ編集画面でpathコードを簡略化 // 実行キー「F1」「Shift+F1」「F2」「Shift+F2」「F3」 // @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 editor_iframe; let iframe_doc; let iframe_body; let f_mode; // 処理形式 let target=document.querySelector('#cke_1_contents'); let monitor=new MutationObserver( catch_key ); monitor.observe(target, {childList: true}); catch_key(); function catch_key(){ editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ iframe_doc.addEventListener('keydown', check_key); document.addEventListener('keydown', check_key); function check_key(event){ if(event.keyCode==112){ if(!event.shiftKey){ // ショートカット「F1」 event.preventDefault(); event.stopImmediatePropagation(); f_mode=1; clear_space(); svg_arrange(); } else{ // ショートカット「Shift+F1」 event.preventDefault(); event.stopImmediatePropagation(); f_mode=2; clear_space(); svg_arrange(); }} if(event.keyCode==113){ if(!event.shiftKey){ // ショートカット「F2」 event.preventDefault(); event.stopImmediatePropagation(); f_mode=3; clear_space(); svg_arrange(); } else{ // ショートカット「Shift+F2」 event.preventDefault(); event.stopImmediatePropagation(); f_mode=4; clear_space(); svg_arrange(); }} if(event.keyCode==114){ // ショートカット「F3」 event.preventDefault(); event.stopImmediatePropagation(); f_mode=5; clear_space(); svg_arrange(); } }}} } // catch_key() function svg_arrange(){ if(document.querySelector('.cke_wysiwyg_frame') !=null){ //「通常表示」で実行 editor_iframe=document.querySelector('.cke_wysiwyg_frame'); iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ iframe_body=iframe_doc.querySelector('.cke_editable'); if(iframe_body){ let svg_or; let path_or; let svg_n svg_or=iframe_doc.querySelector('.cke_editable svg');// 処理元のSVG if(svg_or){ // 元のSVG画像が無いと動作しない if(f_mode==5){ beautify(svg_or); clear_comment(); clear_comment();} let line=iframe_doc.createElement('p'); line.id='line'; line.textContent= '========================================='; if(!iframe_body.querySelector('#line')){ iframe_body.appendChild(line); } svg_n=svg_or.cloneNode(true); let svg_all=iframe_body.querySelectorAll('svg') for(let k=0; k<svg_all.length-1; k++){ svg_all[k+1].remove(); } // 最初のSVG以降は削除 iframe_body.appendChild(svg_n); path_or=svg_n.querySelectorAll('path'); // 処理元のSVGの全てのpath let dot2=0; // 💢 let dot3=0; // 💢 for(let k=0; k<path_or.length; k++){ let d_or=path_or[k].getAttribute("d"); path_or[k].setAttribute("d", path_trim(d_or)); } disp_result(dot2, dot3); // 💢 function path_trim(D_or){ let d_all=[]; if(f_mode==1 || f_mode==2){ d_all=D_or.split(' '); } else if(f_mode==3 || f_mode==4 || f_mode==5){ d_all=D_or.split(','); } if(f_mode==5){ let temp_d; temp_d=d_all.join(' '); return temp_d; } // 処理後のpath出力 if(f_mode<5){ let temp_d; temp_d=d_all.join(' '); return arrange_i_code(temp_d); } function arrange_i_code(Temp_d){ // path全体の処理 let c_count=0; // 数として処理した文字数 let i_code=[]; // 全pathを1文字ずつにした配列 let i_code_new=[]; // 処理後の数と文字を格納する配列 i_code=Temp_d.split(''); // pathの全体を文字1個ずつに分解 for(let k=0; k<i_code.length; k++){ if(i_code[k].match(/[A-Za-z]| |-/g)){ if(c_count==0){ i_code_new.push(i_code[k]); } else{ i_code_new.push(arr_i_code(c_count, k)); c_count=0; }} else{ // 数字または「.」の場合 c_count+=1; }} return i_code_new.join(''); // 処理後のpath function arr_i_code(Count, K){ let tmp=[]; let tmp_num; // 再構成した数値(小数を含む) let tmp_round; // 四捨五入した数値 for(let i=0; i<Count; i++){ tmp.push(i_code[K-Count+i]); } if(count_dot(tmp.join(''))<2){ //「.」が1個以内 if(count_dot(tmp.join(''))==1){ tmp_num=parseFloat(tmp.join('')); if(f_mode==2 || f_mode==4){ tmp_round=(Math.round(tmp_num*10))/10; } else{ tmp_round=Math.round(tmp_num); }} else if(count_dot(tmp.join(''))==0){ tmp_round=parseInt(tmp.join('')); } return tmp_round.toString()+i_code[K]; } else if(count_dot(tmp.join(''))==2){ //「.」が2個 dot2+=1; // 💢 let sub_count=0; let sub_tmp1=[]; let sub_tmp2=[]; let tmp_num1; let tmp_num2; let r_tmp_num2; for(let i=0; i<tmp.length; i++){ if(sub_count==0){ sub_tmp1.push(tmp[i]); if(tmp[i]=="."){ sub_count=1; }} else if(sub_count==1){ if(tmp[i]!="."){ sub_tmp1.push(tmp[i]); } if(tmp[i]=="."){ sub_count=2; sub_tmp2.push(tmp[i]); }} else{ sub_tmp2.push(tmp[i]); }} tmp_num1=parseFloat(sub_tmp1.join('')); tmp_num2=parseFloat(sub_tmp2.join('')); r_tmp_num2=(Math.round(tmp_num2*10))/10; if(f_mode==2 || f_mode==4){ if(r_tmp_num2<1 && r_tmp_num2!=0){ return ((Math.round(tmp_num1*10))/10).toString()+ ' '+r_tmp_num2.toString().slice(1)+ i_code[K]; } else if(r_tmp_num2==0){ return ((Math.round(tmp_num1*10))/10).toString()+ ' 0'+i_code[K]; } else{ return ((Math.round(tmp_num1*10))/10).toString()+ ' 1'+i_code[K]; }} else{ if(r_tmp_num2<1 && r_tmp_num2!=0){ return (Math.round(tmp_num1)).toString()+ ' '+r_tmp_num2.toString().slice(1)+ i_code[K]; } else if(r_tmp_num2==0){ return (Math.round(tmp_num1)).toString()+ ' 0'+i_code[K]; } else{ return (Math.round(tmp_num1)).toString()+ ' 1'+i_code[K]; }}} // 桁上がりして1.0になる else{ //「.」が3個以上 dot3+=1; // 💢 return tmp.join('')+i_code[K]; } function count_dot(str){ let count=0; for (let i=0; i<str.length; i++){ if(str[i]=="."){ count++; }} return count; } } // arr_i_code } // arrange_i_code() } // path_trim }}}}} // svg_arrange() function beautify(Svg_or){ let title=Svg_or.querySelector('title'); if(title){ title.remove(); } // titleタグを削除 Svg_or.removeAttribute("xmlns"); } function clear_comment(){ // コメントタグを削除 editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ let iframe_body=iframe_doc.querySelector('.cke_editable'); if(iframe_body){ let iframe_node=iframe_body.childNodes; for(let k=0; k<iframe_node.length; k++){ if(iframe_node[k].nodeType==8){ iframe_node[k].remove(); }} }}}} // clear_comment() function clear_space(){ // svgタグの後に増殖する空白行を削除 editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ let iframe_body=iframe_doc.querySelector('.cke_editable'); if(iframe_body){ let elements=iframe_body.querySelectorAll('p'); for(let k=0; k<elements.length; k++){ if(elements[k].childNodes.length=="1"){ if(elements[k].firstElementChild){ if(elements[k].firstElementChild.tagName=="BR"){ elements[k].remove(); }}}} }}}} // clear_space() function disp_result(Dot2, Dot3){ let p_title=document.querySelector('.p-title__text'); if(p_title){ if(f_mode!=5){ p_title.value='Dot2: '+Dot2 +' Dot3: '+Dot3; } else{ p_title.value=''; }}} } // main() // ブログ記事にSVGをHTMLで書き込む // 通常表示に戻り「F1」または「F2」を押すと、処理したSVGが追加される
〔参考〕 以下は、SVG画像のサンプルのソースコードです。「HTML表示」にペーストして表示させ、「Simple SVG」のテストをする事ができます。
<style>.cls{fill:#ff005c;}</style>
<path d="M16.86 3.4h-1.6l-.52.71c-.3.43-.73 1-1.22 1.8-2.78 4.21-7.72 12.74-6.23 18.2a6.62 6.62 0 0 0 .43 1.15 5.78 5.78 0 0 0 1 1.45c1.48 1.52 3.86 2.29 7.1 2.29 4.31 0 7.13-1.3 8.41-3.85C27.79 18.1 17.31 4 16.86 3.4Zm5.61 20.86C21.56 26.08 19.33 27 15.85 27a14.58 14.58 0 0 1-1.95-.12 5.65 5.65 0 0 1-4.07-2 2.72 2.72 0 0 1-.32-.51c-1.94-3.88 2-11.62 5.16-16.56.43-.68.84-1.3 1.22-1.85l.17-.24C19.2 10.2 24.73 19.74 22.47 24.26Z"></path><path class="cls" d="M22.47 24.26C21.56 26.08 19.33 27 15.85 27a14.58 14.58 0 0 1-1.95-.12c3.17-.35 5.3-1.61 6.36-3.73 2.32-4.63-1.41-12.31-4.37-17.2l.17-.24C19.2 10.2 24.73 19.74 22.47 24.26Z"></path></svg>
「Simple SVG」最新版について
旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
●「Simple SVG」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。