UserScript
https://gyazo.com/197d3d789171b6df7fa30422a3ed75e7
留意事項
⇩
JavaScriptのコードは、
「自分のページ」に
書く必要がある
---
設定の反映は、プロジェクトを開いているページを更新する必要がある
---
UserScript を記述し、
適用後にバグが発生し、UserScript での編集ができなくなってしまった
場合、
別のブラウザで開くと、コードを読み込んでよいかどうかの確認画面をまた出せる
ので、ボタンを押さずに記述を直すことができる
---
import を使った UserScript は実行されないことがあるらしい
現在の Scrapbox のバージョンでもそのバグが残っているかわからないが、もし気になるようであれば
以下のリンク先のようにrun~~~() を使用して実行すること
⇧ 留意事項
UserScript: 右クリックから文字色をつけられるようにする
https://gyazo.com/226d235a527b037b55ebb463c2fb1e83
上のように、範囲選択後に右クリックで色付きの📕などのボタンが表示されるので、
それを選択するとブラケットと特殊文字で色付きの文字にすることができる
code:colorChar.js
scrapbox.PopupMenu.addButton({
title: '📕',
onClick: text => text.split('\n').map(line => [! ${line}]).join('\n')
})
scrapbox.PopupMenu.addButton({
title: '📙',
onClick: text => text.split('\n').map(line => [% ${line}]).join('\n')
})
scrapbox.PopupMenu.addButton({
title: '📗',
onClick: text => text.split('\n').map(line => [# ${line}]).join('\n')
})
scrapbox.PopupMenu.addButton({
title: '📘',
onClick: text => text.split('\n').map(line => [~ ${line}]).join('\n')
})
UserScript: ページ内の文字カウント
https://gyazo.com/d671a9b7c2e19b055335fa5aab484dcb
上の赤枠内のように、PageMenuのボタンをタップすると
文字数、単語数、行数が表示される
code:countChar.js
scrapbox.PageMenu.addItem({
title: () => {
if (!scrapbox.Page.lines) return
const chars = scrapbox.Page.lines.map(line => line.text.length).reduce((a,b) => a + b)
const words = scrapbox.Page.lines.map(line => line.text.split(/\s+/).length).reduce((a,b) => a + b)
return ${chars}文字 ${words}単語 ${scrapbox.Page.lines.length}行
},
onClick: () => null
})
UserScript: 範囲選択して文字カウント
https://gyazo.com/a2b95a3fccc3a6fa45e9d9666ba1c116
上のように、範囲選択後に右クリックすると一番右に表示される118c 16wの部分が
それぞれ文字数と単語数となる
code:countCharRange.js
scrapbox.PopupMenu.addButton({
title: function (text) {
const chars = text.replace(/\r\n/g, '').length const words = text.trim().split(/\r\n\s+/).length return ${chars}c ${words}w
},
onClick: () => null
})
UserScript: 見出し(目次)のボタンを右のメニューに作成
https://gyazo.com/8a676d6d3a8800707648c495890b0818
上のように、PageMenuの見出しボタンをタップすると、
2回以上改行した行が見出しとなり表示されるようになる
これは import しないと動作してくれない
code:index.js
(function () {
scrapbox.PageMenu.addMenu({
title: '見出し',
onClick: () => {
scrapbox.PageMenu('見出し').removeAllItems()
for (let line of scrapbox.Page.lines) {
if (!line.section.start) continue
const image = line.nodes && getIconUrl(line.nodes)
const noIcon = !!image
const title = line.nodes ? renderPlainText(line.nodes, {noIcon}) : line.text
const onClick = () => location.hash = line.id
scrapbox.PageMenu('見出し').addItem({title, image, onClick})
}
}
})
function renderPlainText (node, options) {
if (node instanceof Array) return node.map(node => renderPlainText(node, options)).join('')
if (typeof node === 'string') return node
switch (node.type) {
case 'icon':
case 'strong-icon':
return options.noIcon ? ' ' : node.unit.page
}
return renderPlainText(node.children, options)
}
function getIconUrl (node) {
if (/icon/.test(node.type)) {
return /api/pages/${node.unit.project||scrapbox.Project.name}/${node.unit.page}/icon
}
if (node instanceof Array) {
return node.map(getIconUrl).find(img => img)
}
if (node.children) return getIconUrl(node.children)
return null
}
})()
UserScript: タイムスタンプの設定
デフォルトに存在するタイムスタンプのフォーマットを全て消したあと1つだけ日付のフォーマットを指定する
Alt + t で入力可能
code:timeStamp.js
scrapbox.TimeStamp.removeAllFormats() /* デフォルトのフォーマットを全て削除する */
scrapbox.TimeStamp.addFormat(']YYYY/M[/D HH:mm') /* タイムスタンプを追加(年月で関連リンクを作成する) */
UserScript: 関連ページのタイトルと内容を取得し、結合して表示
https://gyazo.com/d5ed620411661bcd8bbc3a010cd551f3
PageMenuの「関連ページ取得」で実行可能。ページ下部の「Links」のみのページを取得する
code:getRelatedPages.js
const makepage = function () {
const url = location.href.replace("io/", "io/api/pages/");
let x = new XMLHttpRequest();
x.open("get", url, false);
x.send(null);
let json = x.responseText;
let pagedata = JSON.parse( json );
let relatedPagesDatalinks1hop = relatedPagesData"links1hop"; //ループで回して、関連ページの本文を取得していく
let pageContents = [];
let rooturl = location.href.replace("io/", "io/api/pages/").replace(new RegExp("/" + encodeURI(scrapbox.Page.title) + "$"),"/");
for (let i = 0, len = relatedPagesDatalinks1hop.length; i < len; ++i) {
let relatedurl = rooturl + relatedPagesDatalinks1hopi"title" + "/text"; //これでXMLHttpRequestを回していく
let y = new XMLHttpRequest();
y.open("get", relatedurl, false);
y.send(null);
let c = y.responseText;
c = removehashtag(c,scrapbox.Page.title); //もとハッシュタグを削除しない場合はこの行をコメントアウト
c = removebracket(c)//本文中からブラケット[]を取り除かない場合はこの行をコメントアウト
pageContents.push(addmargin(c));
}
//取得したページの中身を使って、新しいwindowをオープンする。
var win = window.open();
win.document.open();
win.document.write(<title>temporary</title>);
win.document.write('<pre>');
win.document.write(pageContents.join('\n'));
win.document.write('</pre>');
win.document.close();
}
function removehashtag(text,pageTitle){//本文中からもともとのハッシュタグを削除する
return text.replace(new RegExp('#' + scrapbox.Page.title),"")
}
function removebracket(text){//本文中から閉じと開きのブラケットを削除する
return text.replace(/\|\/g,"") }
function addmargin(text){ //二行目以降に半角スペースを追加する
return text.replace(/\n/g,"\n ")
}
scrapbox.PageMenu.addMenu({
title: '関連ページ取得',
onClick:makepage
})
UserScript: リンクページのタイトルと内容を取得し、結合して表示
https://gyazo.com/288abadf4965c9f234674d077bf33a49
PageMenuの「リンクページ取得」で実行可能
code:getLinkPages.js
const getlinkpage = function () {
const url = location.href.replace("io/", "io/api/pages/");
let x = new XMLHttpRequest();
x.open("get", url, false);
x.send(null);
let json = x.responseText;
let pagedata = JSON.parse( json );
let linkPagesData = pagedata"links"; //ループで回して、リンクページの本文を取得していく
let pageContents = [];
let rooturl = location.href.replace("io/", "io/api/pages/").replace(new RegExp("/" + encodeURI(scrapbox.Page.title) + "$"),"/");
for (let i = 0, len = linkPagesData.length; i < len; ++i) {
let relatedurl = rooturl + encodeURI(linkPagesDatai) + "/text"; //これでXMLHttpRequestを回していく
let y = new XMLHttpRequest();
y.open("get", relatedurl, false);
y.send(null);
let c = y.responseText;
if (! (c == '{"name":"NotFoundError","message":"Page not found."}') ){
c = removehashtag2(c,scrapbox.Page.title); //もとハッシュタグを削除しない場合はこの行をコメントアウト
c = removebracket2(c);//本文中からブラケット[]を取り除かない場合はこの行をコメントアウト
pageContents.push(addmargin2(c));
}
}
//取得したページの中身を使って、新しいwindowをオープンする。
var win = window.open();
win.document.open();
win.document.write(<title>temporary</title>);
win.document.write('<pre>');
win.document.write(pageContents.join('\n'));
win.document.write('</pre>');
win.document.close();
}
function removehashtag2(text,pageTitle){//本文中からもともとのハッシュタグを削除する
return text.replace(new RegExp('#' + scrapbox.Page.title),"")
}
function removebracket2(text){//本文中から閉じと開きのブラケットを削除する
return text.replace(/\|\/g,"") }
function addmargin2(text){ //二行目以降に半角スペースを追加する
return text.replace(/\n/g,"\n ")
}
scrapbox.PageMenu.addMenu({
title: 'リンクページ取得',
onClick:getlinkpage
})
UserScript: 関連ページを左に表示するかどうかの切り替え
https://gyazo.com/74dee5024b195a25c2d52af56a9b2243
PageMenuの「関連ページの表示切替」で実行可能
現在表示しているページの関連ページを左に表示する(ボタンを再度押すとデフォルト表示に切り替える)
これをオンにしている状態だとPageMenu が固定できない(スクロールすると上に隠れてしまう)ので注意
code:relatedPageList_left.js
scrapbox.PageMenu.addMenu({
title: '関連リンクの表示切替',
onClick: () => {
const cssid = "related-left"; // 適当なidを設定する
let e = document.getElementById(cssid);
if(e){ // 既に設定されている時
e.remove(); // 除去する
}else{ // 設定されていない時
let css;
fetch('/api/code/ayasata/_CSS_related-page-list_left/style.css')
.then(response => response.text())
.then(text => {
css = text;
const style = document.createElement('style');
style.id = cssid;
style.appendChild(document.createTextNode(css));
// document.head.appendChild(style);
document.body.appendChild(style);
});
};
},
})
UserScript: カーソルが行頭にない状態でも、Tabで現在行をインデントする
Tabを押すとインデント。
Shift + Tab を押すとアンインデント。
code:indent.js
(() => {
$('#text-input').on('keydown', e => {
if (e.keyCode != 0x09) return true;
if ($('.cursor-line .code-block').length != 0) return true;
if ($('.cursor-line .table-block').length != 0) return true;
if ($('.popup-menu').length != 0) return true;
let keydown = document.createEvent('Events');
keydown.initEvent('keydown', true, true);
keydown.keyCode = e.which = (e.shiftKey ? 37 : 39);
keydown.ctrlKey = true;
$('#text-input')0.dispatchEvent(keydown); return false;
});
})();