generated at
replace text UserScript
良さそう

TODOスクショを貼る

使い方
選択範囲内の任意の場所に s/<before>/<after>/<flag> を書き込んでおく
先頭に書かないと認識できないようにした
ボタンを押すと置換する

実装
正規表現にマッチする正規表現 RegExp に入れる文字列を特定する

実装したいアイデア
置換対象の行のみ更新する
Page menuから実行する
mobile版scrapboxからも使えるようにする
global flagを正しく認識できていない
文字列結合→置換→文字列分割という二度手間をやらないと実装できなさそう
正規表現だと勘違いして不正な正規表現を読み込んだ結果、Unterminated character class errorが発生してscrapboxが落ちる事がある
とりあえず一行目に正規表現がない限り何もしないようにした

2023-02-14
03:17:39 動いていないっぽい?
一旦機能を変えないverを作って、しばらくそっちを使うことにしよう

script.js
const replaceReg = /^\s*s\/(.*?)\/(.*?)\/([gimyu]*)\s*$/; scrapbox.PopupMenu.addButton({ title: text => { const lines = text.split('\n'); const match = lines.shift().match(replaceReg); if (!match) return ''; const {index, length, reg} = getParam(match); const fragments = getFragments(lines.join('\n'), [{index, length}]); if (!fragments.some(fragment => fragment.replace ? reg.test(fragment.text) : false)) return ''; return 'replace'; }, onClick: text => { const match = text.match(replaceReg); if (!match) return; const {index, length, reg, after} = getParam(match); const fragments = getFragments(text, [{index, length}]); // 何も置換しない場合は何もしない if (!fragments.some(fragment => fragment.replace ? reg.test(fragment.text) : false)) return; return fragments.map(fragment => fragment.replace ? fragment.text.replace(reg, after) : fragment.text ).join(''); }, });

置換に使うparameterを抽出する
script.js
function getParam(match) { const {index} = match; const length = match[0].length; const [, before, after, flag] = match; const reg = new RegExp(before, flag); return {index, length, reg, after: after.replace(/\\n/g, '\n').replace(/\\t/g, '\t').replace(/\\\\/g, '\\')}; }

正規表現で置換する部分に印をつける
script.js
function getFragments(text, regLocations) { const fragments = []; regLocations = regLocations.sort((a, b) => a.index - b.index); let lastPos = 0; for (const {index, length} of regLocations) { if (index > lastPos) fragments.push({text: text.slice(lastPos, index), replace: true}); fragments.push({text: text.slice(index, length), replace: false}); lastPos = length; } fragments.push({text: text.slice(lastPos), replace: true}); return fragments; }

#2023-02-14 03:17:16
#2021-05-26 14:41:27
#2021-03-09 03:22:20