generated at
マルチプロジェクト版ランダムジャンプUserScript
概要

ランダム表示のマルチプロジェクト版

1. プロジェクトのリストのCSVファイル群の中から、ランダムにひとつを選択する
2. CSVファイルからプロジェクトをランダムにひとつ取り出す
3. プロジェクトの中から、ページをランダムにページを選ぶ
4. ページを表示する

ファイル仕様(暫定)

テーブル表記
Scrapboxのテーブル記法
1カラム目がプロジェクト名
プロジェクト名は、 [/$ProjectName] という書式

projects
プロジェクト説明
/masui増井俊之
/shokai橋本商会
/daiizdaiiz

ファイルを分割して表記も可能
projects
/rakusaiRakusai Public
/akiroom秋山界面帳

2カラム目以降は無視される
2カラム目以降には何を書いてもよい
たいていは、1カラム目のプロジェクト名の補足説明になる
テーブルには、有効な プロジェクト名がふたつ以上必要

ファイル名
ファイル名は任意
projects.csv(全部小文字)を推奨
API ではファイル名は大文字、小文字を区別するので注意が必要
大文字、小文字の混ざったファイルは作らないことを推奨

書式のエラー処理
基本的にエラーは無視する
書式外のカラムは無視される

スクリプト

script.js
const choice = (arr) => arr[Math.floor(Math.random()*arr.length)] const sources = [ '/api/table/villagepump/おもしろいScrapboxみつけた/projects.csv', '/api/table/villagepump/マルチプロジェクト版ランダムジャンプUserScript/projects.csv', '/api/table/suto3/suto3/projects.csv' ]

script.js
const lists = new Promise((resolve, reject) => { // 情報源をひとつ選ぶ const projects_url = choice(sources)
現状では
情報源を選ぶ
情報源から更にpublic projectを選ぶ
という形式になっているけど、ランダム選択をやるのが二度手間なので
情報源から全てのプロジェクト名を取り出してリストを作る
リストの中からプロジェクトをランダムに選ぶ
に変えてもいいかもしれないですtakker
これでどうだろう?
fetch_project_url.js
let project_lists=[]; const fetch_project_url= (source) => fetch(source) .then(response => response.text()) .then(text => text.split('\n') .map(line => line.split(',')) // column 1にプロジェクトリンクが入っているもののみ取り出す .filter(cells => /^\[\/[^\s\]\/]*\]$/.test(cells[0])) // [/project]からprojectを抜き出す .map(cells => cells[0].replace(/^\[\/([^\s\]\/]*)\]$/,'$1'))) // 非同期にprojectをリストに追加する .then(project_names => project_lists.push(...project_names)); sources.forEach(source => fetch_project_url(source));
あとは project_lists から適宜取り出す
ふむふむsuto3
グローバル汚染防止のために、ES Modules化するといいかも
ページタイトルの読み込みはこれを使うのはどうだろう
手前味噌ですがtakker

script.js
//const projects_url = '/api/table/suto3/suto3/projects.csv' // debug console.log(projects_url) fetch(projects_url) .then(response => response.text()) .then(text => text.split('\n') .map(line => line.replace(/^,/,"")) // 行頭のコンマがあった場合は削除 .join('\n') ) .then(resolve) .catch(reject) })

script.js
scrapbox.PageMenu.addItem({ title: 'ランダムジャンプ', onClick: async () => { await lists.then((text) => { const urls = text.split("\n") .map( line => { console.log(line) const regexp = /^\[\/.*\]$/gm const res = line.split(',') // 書式チェック if (regexp.test(res[0])) { const url = res[0].replace(/\[|\]/g,"") //console.log(url) return url } else { console.log('NG') return } }) .filter(line => line) //console.log(urls) const project = choice(urls) //console.log(project) const limit = 100 let skip = 0 const url =`/api/pages${project}?limit=${limit}&skip=${skip}` fetch(url) .then((response) => response.json()) .then((json) => { //console.log(json) const pagetitle = choice(json.pages.map(page => page.title)) console.log(pagetitle) window.open(`https://scrapbox.io${project}/${pagetitle}`) }).catch(err => { console.error('fetch failed', err) }) }) } })

js-script-button

既知の問題点

飯テロをくらう恐れがある
吹いたwtakker
テーブル内部では、使えない記法がある
アイコン記法
外部リンク
など
検索除外のしくみがない
18禁とかnsfwとか
/api/pages/$projectname/$page/text 正規表現で走査して弾くとか?takker
データチェックとかエラーチェックとか
ジャンプ先のプロジェクトから再ジャンプができない