generated at
副表記へ自動的に転送するUserScript
fragment-linkを(勝手に)少し改造して副表記に❌をつけに対応させたMijinko_SD
基本的な仕様はfragment-linkと同じ(多分)
❌から始まるリンクを見つけて転送する点が違う
元々あった [# []] に飛ぶ機能は書き換えてあるので、 [# []] を置いても反応しません

これを自分のページに置けば動作する
js
import {runCrossLink} from "/api/code/villagepump/副表記へ自動的に転送するUserScript/script.js"; runCrossLink();

ソース
script.js
export const runCrossLink = async() => { let mutationObserver; /** * 副表記のリンクがあるページへリダイレクトする * 複数候補がある場合は該当ページをハイライトするに留める */ const highlightPagesOrRedirect = async() => { mutationObserver?.disconnect(); if (!scrapbox.Page.title || scrapbox.Page.title.indexOf("❌") != 0) { // ページタイトルがない or ❌から始まるページではない return; } // 開いているページの情報を取得 const pageAPIResponse = await fetch(`https://scrapbox.io/api/pages/${ encodeURIComponent(scrapbox.Project.name) }/${encodeURIComponent(scrapbox.Page.title)}`); if (!pageAPIResponse.ok) { throw new Error(`${pageAPIResponse.status} ${pageAPIResponse.statusText}`); } const page = await pageAPIResponse.json(); const linkedLinks = []; for (const { title } of page.relatedPages.links1hop) { // Links欄(1-hop)にあるページを取得 const relatedPageAPIResponse = await fetch(`https://scrapbox.io/api/pages/${ encodeURIComponent(scrapbox.Project.name) }/${encodeURIComponent(title)}`); if (!relatedPageAPIResponse.ok) { throw new Error(`${relatedPageAPIResponse.status} ${relatedPageAPIResponse.statusText}`); } const relatedPage = await relatedPageAPIResponse.json(); // 開いているページへのリンク(つまり逆リンク)を検索 relatedPage.lines.forEach(line => { if (line.text.indexOf(`[${scrapbox.Page.title}]`) >= 0) { linkedLinks.push({ line, page: relatedPage}) } }); } if (!isPageExists(scrapbox.Page.title) && linkedLinks.length === 1) { // ページ遷移 const link = document.createElement("a") link.href = `/${scrapbox.Project.name}/${encodeURIComponent(linkedLinks[0].page.title)}#${linkedLinks[0].line.id}` document.body.appendChild(link) link.click() } const highlightLinkedPages = () => { const relatedPageListItemElements = [ ...document.querySelectorAll(".related-page-list .grid li") ]; linkedLinks.forEach((linkedLink) => relatedPageListItemElements.forEach((relatedPageListItemElement) => { if (relatedPageListItemElement.dataset.pageTitle !== linkedLink.page.title) { return; } relatedPageListItemElement.querySelector("a .header").style.borderColor = "var(--telomere-unread, #41b059)"; }) ); }; highlightLinkedPages(); mutationObserver = new MutationObserver(highlightLinkedPages); mutationObserver.observe(document.body, { subtree: true, childList: true, characterData: true, }); }; await highlightPagesOrRedirect(); scrapbox.on('page:changed', highlightPagesOrRedirect); }; /** * ページが存在するか(既に作成されているか)を確かめる * @param pageTitle ページのタイトル * @returns 存在すればtrue, 存在しなければfalse */ function isPageExists(pageTitle) { const pages = scrapbox.Project.pages for(let page of pages) { if(page.title == pageTitle) { return page.exists } } return false }