UserScript@sni-aichi
code:script.js
// チェックボックスを追加
scrapbox.PopupMenu.addButton({
title: '⬜',
onClick: text => ⬜${text}
})
// 選択した文字列にマーカー
scrapbox.PopupMenu.addButton({
title: 'マーカー',
onClick: text => [%* ${text}]
})
// 選択した文字列に重要
scrapbox.PopupMenu.addButton({
title: '重要',
onClick: text => [! ${text}]
})
// 選択した文字列に見出し①
scrapbox.PopupMenu.addButton({
title: '見出し①',
onClick: text => [#** ${text}]
})
// 選択した文字列に見出し②
scrapbox.PopupMenu.addButton({
title: '見出し②',
onClick: text => [_* ${text}]
})
code:script.js
import "/api/code/scrasobox/見える文字数カウンター/script.js";
code:script.js
setTimeout(() => {
// チェックボックスとして使用する文字のリスト
const textArea = document.getElementById('text-input');
const keydownEvent = {
event: document.createEvent('Event'),
dispatch: function(keycode, withShift = false, withCommand = false) {
this.event.keyCode = keycode;
this.event.shiftKey = withShift;
this.event.metaKey = withCommand;
textArea.dispatchEvent(this.event);
}
};
keydownEvent.event.initEvent('keydown', true, true);
const inputEvent = {
event: document.createEvent('Event'),
dispatch: function(string) {
textArea.value = string;
textArea.dispatchEvent(this.event);
}
};
inputEvent.event.initEvent('input', true, true);
const isBoxCharSpan = (element) => {
if (element.tagName !== 'SPAN') return false;
const boxReg = new RegExp(^(${checkBoxList.join('|')})$);
for (const className of element.classList) {
if (/^c\-\d+$/.test(className)) {
return boxReg.test(element.textContent);
}
}
return false;
};
const startsWithBoxReg = new RegExp('^\\s*(' + checkBoxList.join('|') + ')');
// ボックスクリックでオンオフする
$('#app-container').off('click.toggleCheckBox', '.lines');
$('#app-container').on('click.toggleCheckBox', '.lines', event => {
const target = event.target;
if (!isFirstElementChild(target)||!isBoxCharSpan(target)) return;
setTimeout(() => {
let lineString;
try {
lineString = getCursorLineString();
} catch (err) {
console.log(err);
return;
}
if (!startsWithBoxReg.test(lineString)) return;
const targetX = target.getBoundingClientRect().left;
const cursorX = document.getElementsByClassName('cursor')0.getBoundingClientRect().left; if (cursorX <= targetX) {
keydownEvent.dispatch(39); // →
}
keydownEvent.dispatch(8); // Backspace
const newBox = (() => {
const trimmedLineString = lineString.trim();
for (let i = 0; i < checkBoxList.length; i++) {
if (trimmedLineString.startsWith(checkBoxListi)) { if (i + 1 < checkBoxList.length) {
return checkBoxListi + 1; } else {
}
}
}
})();
inputEvent.dispatch(newBox);
// この下のコメントアウトを解除すると、checked時に取消線を入れて時刻を追記します
// Mac、Porterでのみ動作します
/*
if (/Mobile/.test(navigator.userAgent) || newBox === checkBoxList0) return; setTimeout(() => {
keydownEvent.dispatch(39, true, true); // shift + command + →
inputEvent.dispatch('-');
keydownEvent.dispatch(39, false, true); // command + →
const now = moment().format('HH:mm');
inputEvent.dispatch( ${now});
}, 50);
*/
}, 50);
});
// ボックス行で改行すると次行にボックス自動挿入
$('#text-input').off('keydown.autoInsertCheckBox');
$('#text-input').on('keydown.autoInsertCheckBox', event => {
switch (event.key) {
case 'Enter': {
let lineString;
try {
lineString = getCursorLineString();
} catch (err) {
console.log(err);
return;
}
if (!startsWithBoxReg.test(lineString)) return;
setTimeout(() => {
let lineString;
try {
lineString = getCursorLineString();
} catch (err) {
console.log(err);
return;
}
if (!startsWithBoxReg.test(lineString)) {
inputEvent.dispatch(checkBoxList0); }
}, 50);
return;
}
default: {
return;
}
}
});
function isFirstElementChild(element) {
return element.parentNode.firstElementChild === element;
}
function getCursorLineString() {
return document.querySelector('.lines div.line.cursor-line').textContent;
}
}, 1500);
code:script.js
javascript:(function(){
var p = document.getElementById("productTitle");
if (!p) var p = document.getElementById("ebooksProductTitle");
var title=window.prompt('Scrap "Amazon" to your scrapbox.', p.innerHTML);
if (!title) return;
title = '『'+ title +'』';
var imagecontainer=document.getElementById("imageBlockContainer");
if (!imagecontainer) var imagecontainer = document.getElementById("ebooksImageBlockContainer");
var image = imagecontainer.getElementsByTagName("img")0; var imageurl = image.getAttribute("src");
var pub = [];
var c = document.getElementsByClassName('author');
for (g=0; g < c.length ;g++){
let at = cg.innerText.replace(/,/,''); let pu = at.match(/\(.+\)/);
let ct = at.replace(/\(.+\)/,'').replace(/ /g,'');
pub.push(pu + ' + ct + '');
}
var body=encodeURIComponent(lines);
})();
code:script.js
scrapbox.PageMenu.addMenu({
title: '見出し',
onClick: () => {
scrapbox.PageMenu('見出し').removeAllItems()
for (let line of scrapbox.Page.lines) {
if (!line.section.start) continue
if (!line.text.startsWith("[* ") && !line.text.startsWith("[** ") && !line.text.startsWith("[*** ")) continue
if (!line.nodes) continue
const image = ""
const noIcon = false
// hogeとhogeは先頭をインデントする。
const marginLeft = line.text.startsWith("[* ") ? " ・" : ""
const marginLeft2 = line.text.startsWith("[** ") ? "●" : ""
const title = marginLeft + marginLeft2 + renderPlainText(line.nodes)
const onClick = () => location.hash = line.id
scrapbox.PageMenu('見出し').addItem({ title, image, onClick })
}
}
})
function renderPlainText(node) {
if (node instanceof Array) return node.map(node => renderPlainText(node)).join('')
if (typeof node === 'string') return node
switch (node.type) {
case 'icon':
case 'strong-icon':
return node.unit.page
}
return renderPlainText(node.children)
}
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)
}
return null
}