generated at
omakase-links

選択範囲にある文章に含まれる、すでにページとして存在するタイトルを自動でリンク付けする機能
英文にも対応させた
ing, ed, es, sなどの変化形に対して対応
reなどのリンクが英単語に部分的に引っかからないようにした

script.js
function isEnglish(text) { return !text.split('').some(char => char.charCodeAt() > 255); }

script.js
// based on https://scrapbox.io/daiiz/omakase-links // 既に記法になっているなどの理由で、置換すべきでない範囲を取得する const detectLocked = text => { const syntax = /\[(\/\w|[^\[!"#%&'()\*\+,\-\.\/\{\|\}<>_~])[^\[\]]*\]/g; const locked = text.split('').map(_ => false) const matches = text.matchAll(syntax); for (const match of matches) { locked.fill(true, match.index, match.index + match[0].length); } return locked; } const escapeRegExp = string => string.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&'); const autoLink = text => { if (!text) return; const excluded_list = [ "できる", "re", "RE", "機能", "存在", "" ]; // リンクを長い順に並べる const titles = scrapbox.Project.pages .map(p => p.title) .sort((a, b) => b.length - a.length) .filter(e => e != scrapbox.Page.title && !excluded_list.includes(e) && e.length > 1 ) const is_english = isEnglish(text); const locked = detectLocked(text) const matched = text.split('').map(_ => null) const allNull = arr => arr.every(x => x === null); for (const title of titles) { const regexp_text = is_english ? `${escapeRegExp(title)}(ed|ing|s|es)?[/-;,. )]` : escapeRegExp(title); if (["but", "and"].includes(title.toLowerCase())) { continue; } const regexp = new RegExp(regexp_text , 'gi'); const matches = text.matchAll(regexp); for (const match of matches) { let len = title.length; let idx = match.index; if (is_english && !( idx == 0 || /[\s\n(]/.test(text[idx - 1])) ) { continue; } if (allNull(matched.slice(idx, idx + len)) && !locked[idx]) { for (let i = 0; i < len; i++) { let c = text[idx + i]; if (i === 0) c = `[${c}`; if (i === len - 1) c = `${c}]`; matched[idx + i] = c; } } } } // 無駄にテロメアがupdateされるのを防ぐ為、何も置換しない時は何も返さない if (allNull(matched)) return // 配列matchedでnullの位置を、元のtextの文字に置き換える return matched.map((c, idx) => c ?? text[idx]).join('') } scrapbox.PopupMenu.addButton({ title: '[✨]', onClick: autoLink })


script.js
// リンクを外す scrapbox.PopupMenu.addButton({ title: 'unlink', onClick: text => { const result = text.split(/\n/) .map(line => line.replace(/\[([^\[!"#%&'()\*\+,\-\.\/\{\|\}<>_~][^\[\]]*)\]/g,'$1')).join('\n'); // テロメアが無駄に更新されるのを防ぐ if(text == result) return; return result; } });


ctrl + alt + mでもリンクが貼られるようにした
今自分が操作しているページタイトルと、一文字タイトルを置換候補に含めないようにするなどした。R Kawaguchi
大文字小文字が一致している場合にのみマッチさせるようにするR Kawaguchi
reassembleでREが引っかかって困る
あかんわこれ マッチする単語が少なくなってしまう
文頭の"Short"がshortにひっかからなくなる
英語 = 空白になっているところだけを見る?
追加
ショートカットも実装したいな