840回  2行を書換える

2019年4月から JavaScriptを扱う様になり、約5年ほどツールの紹介記事を書いて来ました。それらの本文中で、ほぼ定型の下の2行を何度も使って来ました。

 

〔コピー方法〕 右サイドバーの   マークのボタンを1度押してください。

 コード枠内の右クリック ➔ コード全体の選択 ➔ コピー操作 が可能になります。

 

これは、記事中のコードを簡単にコピーできる様にする「右サイドバーの特別なボタン」の説明です。

 

しかし、最近のフリースペースの仕様変更で「   ボタン」のコピー機能が使えなくなり、上の2行の説明を下の説明に書換える事になりました。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

"〔コピー方法〕" の文字列でブログ内を検索すると 840件ほどありました。 それだけの記事を編集・修正するのはしんどい話です。

 

 

変形されにくい文字列なら自動化できる 

例えば「東京都渋谷区道玄坂二丁目」といった定形のシンプルな文字列なら、書換えは自動処理ツールに任せられます。 この様な定形文字列は変形が加えられ難いので、処理漏れとなる可能性が低いからです。

 

下は「文字列の検索」を自動処理するツールですが、このツールが各記事を開いて行う「検索」処理を、「書換」+「文書保存」に置き換えれば、文字列の書換え処理を自動化できます。

 

 

今回の2行には「FontAwesome」の絵文字が含まれ、置換える3行には文字リンクが含まれているので、この処理は「HTMLの検索・置換処理」が不可欠です。 そして、実際に処理を始めて判ったのですが、2行の文字列には、改行やスペースの変形パターンの複数種が出来ていて、2割ほどが自動化から漏れてしまうのです。

 

 

半自動化の処理 

こうなると、記事を開いて修正箇所を書換える作業が必要です。 しかし、件数からしてそれは困難。 そこで、以下の処理を行う半自動化のスクリプトを作りました。

 

❶ 編集画面を開いた時に2行を検索できた場合は、自動で書換える。

更に、自動処理の結果をチェックできる様に、編集対象の位置までスクロール。

 

◎ 編集対象は、記事の最後の「h3」までスクロールすると表示されます。

 

 

 

❷ 編集画面を開いた時に2行を検索できない場合は、「対象が見つからない」のアラートを表示。 この場合は、手作業での修正を行う。

 

◎「replace()」メソッドで ❶ は自動化できるが、❷ は出来ません。 問題の2行を見つけて削除(手作業)し、3行を書き込みます。 書込みは以下のツールを使えば、ショートカットのキー操作だけで出来ます。(3行のツールへの登録が必要です)

 

 

 

❸ 編集画面のバグで、編集を行うとたいてい文末に空白行が1行増えるので、それを修正。 この操作を素早くするのに、文末移動「Ctrl+End」を使う。

最後に、文書の投稿をマウス操作で行うのは手間なので、「Ctrl+Shift+Enter」で「投稿する」を押せる様にする。

 

❹ 投稿の結果で「投稿確認画面」と「記事の編集削除」のタブウインドウが生成されるが、これを毎回閉じる操作は大変なので、自動で閉じる様にする。

 

 

ツールを使用した結果 

実際の処理をしながらコードを練ったので、コードが最後の形になった時には、全ての1/3程度まで進んだ頃でした。 それでも、このツールが無かったらとても1日では作業が終わらなかったと思います。

 

ブログ内の検索結果のリストから直に編集画面を開くには、下のツールも、無くてはならないものでした。

 

 

 

 

このリストの 840件を編集したわけですが、8割は編集画面を開くと「置換」え済みの問題箇所が表示されます。 それを確認して文末に移動し、文末の行を修正して「投稿」という操作の繰り返しになります。

 

大量の処理になると、マウス操作とキーボード操作の持ち替えがスムーズかそうでないかで、ずいぶん能率が違って来ます。 そういう事にも対処しながら、このツールは出来上がったのです。

 

 

 

「Auto Worker 💢💢 Rewrite」

このツールは『変形パターンが多い定形文字列を、半分は自動、半分は手作業で別の文字列に置き換える』ためのツールです。

 

いわば、置換え作業のサポートツールですが、実際の処理をしながら頻繁に見つかる「変形パターン」については、1種だけですが ❶ の自動化を可能にしています。

 

過去記事の全域を修正する作業は、一般のユーザーには余り必要はないと思います。 しかし、同様の必要が生じた時には、このツールが参考になると思います。

 

 

カスタマイズと使用上の注意 

◎ 以下のソースコードは、この記事の検索対象の「2行」(2パターンに対応)と置換の文字列「3行」の「HTMLコード」が記入されています。 この文字列を書換える事で、任意の文字列の「検索・書換」に利用できます。 対象文字列のカスタマイズ箇所は「🟦⬜🟦」の表示を置いています。

 

◎「置換え処理後の自動スクロール 🟦⬜🟦」の関数は、最後の「h3」を表示するか、「h3」がなければ文末に移動する動作をします。「h3」表示は今回の作業に特化した動作で、以下に変更すれば「文末に移動」へ変更が出来ます。

 

function to_h3(iframe_doc){ // 処理後に文末へスクロール 🟦⬜🟦
        let html=iframe_doc.documentElement;
        html.scrollTop=html.scrollHeight; }

 

◎ このツールは文字列のHTML書換処理の専用で、通常時には正常な編集作業を阻害します。 目的の作業の終了後は速やかに「OFF」にする必要があります。

 

◎ JavaScriptの処理について理解が浅い状態で、このツールをカスタマイズして扱うと、既存の記事の内容を想定外に壊したり、失ったりする可能性があります。 カスタマイズして利用される場合は、失っても良いコピーをした記事などで厳密な処理テストをした上で利用してください。 結果は自己責任です。

 

 

 

  「Auto Worker 💢💢 Rewrite」を利用するには

このツールは Chrome / Edge の 拡張機能「Tampermonkey」に以下のソースコードをコピーして登録する事で利用できます。 Firefoxではテストをしていません。

 

◎「Tampermonkey」の「」マークの「新規スクリプト」タブを開きます。

 

◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。

 

◎ 前項の「カスタマイズと使用上の注意」に従って、登録したソースコードをカスタマイズした上で使用してください。 

 

 

「Auto Worker 💢💢 Rewrite」 ver.0.1

// ==UserScript==
// @name          Auto Worker 💢💢 Rewrite
// @namespace  http://tampermonkey.net/
// @version       0.1
// @description  ブログ記事の自動編集(検索と置換)+「Ctrl+Shift+Enter」で投稿を実行
// @author        Ameba Blog User
// @match        https://blog.ameba.jp/ucs/entry/srventryupdate*
// @match        https://blog.ameba.jp/ucs/entry/srventrylist.do?*
// @run-at        document-start
// @grant         none
// ==/UserScript==


let search_word1= // 検索候補1 HTML 🟦⬜🟦
    '<p>〔コピー方法〕 右サイドバーの&nbsp;<i class="fa-regular fa-clone" style="color: #2196f3; '+
    'padding: 3px; border: 1px solid #2196f3; border-radius: 4px;"> </i>&nbsp;マークのボタンを1度押してください。</p>'+
    '<p> コード枠内の右クリック ➔&nbsp;コード全体の選択 ➔&nbsp;コピー操作 が可能になります。</p>';
let search_worde1=escapeRegExp(search_word1);

let search_word2= // 検索候補2 HTML 🟦⬜🟦
    '<p>〔コピー方法〕 右サイドバーの&nbsp;<i class="fa-regular fa-clone" style="color: #2196f3; '+
    'padding: 3px; border: 1px solid #2196f3; border-radius: 4px;"> </i>&nbsp;マークのボタンを1度押してください。</p>'+
    '<div><p> コード枠内の右クリック ➔&nbsp;コード全体の選択 ➔&nbsp;コピー操作 が可能になります。</p></div>';
let search_worde2=escapeRegExp(search_word2);

let rewrite_word= // 置換え文字列 HTML 🟦⬜🟦
    '<p>〔コピー方法〕 軽量シンプルなツール「<a href="https://ameblo.jp/personwritep/entry-12818954389.html" '+
    'rel="noopener noreferrer" target="_blank"><b style="font-weight:bold;">PreBox Button</b>&nbsp;'+
    '<i class="fas fa-external-link-alt fa-sm"> </i>&nbsp;</a>」を使うと</p>'+
    '<p>  コード枠内を「Ctrl+左Click」➔「Copy code <i class="fa-regular fa-clone"> </i>」を「左Click」</p>'+
    '<p>  の操作で、掲載コードのコピーが可能になります。</p>';


let interval=setInterval(find_iframe, 50); // iframe 読込み待機
function find_iframe(){
    let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
    if(editor_iframe){
        let iframe_doc=editor_iframe.contentWindow.document;
        if(iframe_doc){
            clearInterval(interval);
            task(iframe_doc); }}}



function task(iframe_doc){ // ブログ本文のHTML検索・置換
    let interval=setInterval(find_doc, 50); // iframe 読込み待機
    function find_doc(){
        let body=iframe_doc.querySelector('.cke_editable');
        if(body){
            clearInterval(interval);
            setTimeout(()=>{
                rewrite(body);
            }, 800); }}


    function rewrite(body){
        let cke_text=body.innerHTML;
        if(cke_text){
            let regex1=new RegExp(search_worde1);
            let result1=regex1.test(cke_text); //  検索候補1 の検索結果

            if(result1==true){
                body.innerHTML=cke_text.replace(search_worde1, rewrite_word);
                to_h3(iframe_doc); }

            else {
                let regex2=new RegExp(search_worde2);
                let result2=regex2.test(cke_text); //  検索候補2 の検索結果

                if(result2==true){
                    body.innerHTML=cke_text.replace(search_worde2, rewrite_word);
                    to_h3(iframe_doc); }

                else{
                    alert("Not Found"); }}
        }}


    fast_publish(iframe_doc); //「Ctrl+Shift+Enter」で記事投稿


} // task()



function escapeRegExp(string){ // エスケープ文字の処理
    let reRegExp=/[\\^$.*+?()[\]{}|]/g;
    let reHasRegExp=new RegExp(reRegExp.source);
    return (string && reHasRegExp.test(string))
        ? string.replace(reRegExp, '\\$&')
    : string; }



function to_h3(iframe_doc){ // 置換え処理後の自動スクロール 🟦⬜🟦
    let h3s=iframe_doc.querySelectorAll('h3');
    if(h3s.length>0){
        let h3=h3s[h3s.length-1];
        h3.scrollIntoView({ block: "start" }); }
    else{
        let html=iframe_doc.documentElement;
        html.scrollTop=html.scrollHeight; }}



function fast_publish(iframe_doc){
    iframe_doc.addEventListener('keydown', check_key);
    function check_key(event){
        if(event.ctrlKey && event.shiftKey && event.keyCode==13){
            let publish=document.querySelector('button.js-submitButton[publishflg="0"]');
            if(publish){
                publish.click(); }}}}



if(location.pathname.includes('/entry/srventrylist.do')){ // 記事の編集・削除
    setTimeout(()=>{
        window.close(); }, 1000); }

if(location.pathname.includes('/entry/srventryupdateend.do')){ // 投稿確認画面
    setTimeout(()=>{
        window.close(); }, 1000); }