generated at
scrapbox-edit-emulation
hr
UserScriptからScrapboxの編集を行うAPI

全機能import用
script.js
export { moveLeft, moveUp, moveDown, moveRight, goHeadWithoutBlank, goEndWithoutBlank, goHead, goEnd, goLine, goHeadLine, goLastLine, scrollUp, scrollDown, scrollHalfUp, scrollHalfDown, } from '../scrapbox-cursor-emulation/cursor.js'; export { enterEdit, leaveEdit, } from './focus.js'; export { launchDrawing, duplicatePage, jumpRandomPage, togglePin, togglePresentation, deletePage, } from './pageMenu.js'; export { getReadablePageURL, getReadableLineURL, } from './url.js'; export { indentLines, deindentLines, upLines, downLines, moveLines, moveLinesBefore, indentBlocks, deindentBlocks, upBlocks, downBlocks, moveBlocks, } from './outline.js'; export { undo, redo, insertTimestamp, } from './edit.js';

内容物
text編集
edit.js
import {press} from '../scrapbox-keyboard-emulation-2/script.js'; import {insertText} from '../scrapbox-insert-text-2/script.js'; const range = n => [...Array(n).keys()]; export function undo(count = 1) { for (const _ of range(count)) { press('z', {ctrlKey: true}); } } export function redo(count = 1) { for (const _ of range(count)) { press('z', {shiftKey: true, ctrlKey: true}); } } export function insertTimestamp(index = 1) { for (const _ of range(count)) { press('t', {altKey: true}); } }
editorにfocusを当てる/外す
focus.js
import {scrapboxDOM} from '/api/code/takker/scrapbox-dom-accessor/script.js'; export const enterEdit = () => scrapboxDOM.textInput.focus(); export const leaveEdit = () => scrapboxDOM.textInput.blur();
pageMenu.js
import {scrapboxDOM} from '/api/code/takker/scrapbox-dom-accessor/script.js'; const isPresentationMode = () => document.getElementsByTagName('html')[0].dataset.displayStyle === 'presentation'; export function launchDrawing() { if (isPresentationMode()) return; scrapboxDOM.pageEditButtons[2].click(); } export function duplicatePage() { if (isPresentationMode()) return; scrapboxDOM.pageEditButtons[3].click(); } export function jumpRandomPage() { if (isPresentationMode()) return; scrapboxDOM.randomJumpButton.click(); } export function togglePin() { if (isPresentationMode()) return; scrapboxDOM.pageEditButtons[4].click(); } export function togglePresentation() { if (isPresentationMode()) { scrapboxDOM.pageEditButtons[0].click(); } else { scrapboxDOM.pageEditButtons[5].click(); } } export function deletePage() { if (isPresentationMode()) return; scrapboxDOM.pageEditButtons[8].click(); }
選択範囲の取得
リンクを踏む
cursorの下にあるリンクを取得
行内のリンクを全て取得
URLの取得
url.js
export function getReadablePageURL() { return `${document.location.origin}${decodeURIComponent(document.location.pathname)}`; } export function getReadableLineURL({lineDOM}) { return `${getReadablePageURL()}${lineDOM.id.replace('L','#')}`; }
ページのURL
行URL
インデントの上げ下げ
outline.js
import {press} from '/api/code/takker/scrapbox-keyboard-emulation-2/script.js'; const range = n => [...Array(n).keys()]; export function indentLines(count = 1) { for (const _ of range(count)) { press('ArrowRight', {ctrlKey: true}); } } export function deindentLines(count = 1) { for (const _ of range(count)) { press('ArrowLeft', {ctrlKey: true}); } } export function moveLines(count) { if (count > 0) { downLines(count); } else { upLines(-count); } } // to行目の後ろに移動させる export function moveLinesBefore({from: From, to}) { const count = to - From; if (count >= 0) { downLines(count); } else { upLines(- count - 1); } } export function upLines(count = 1) { for (const _ of range(count)) { press('ArrowUp', {ctrlKey: true}); } } export function downLines(count = 1) { for (const _ of range(count)) { press('ArrowDown', {ctrlKey: true}); } } export function indentBlocks(count = 1) { for (const _ of range(count)) { press('ArrowRight', {altKey: true}); } } export function deindentBlocks(count = 1) { for (const _ of range(count)) { press('ArrowLeft', {altKey: true}); } } export function moveBlocks(count) { if (count > 0) { downBlocks(count); } else { upBlocks(-count); } } export function upBlocks(count = 1) { for (const _ of range(count)) { press('ArrowUp', {altKey: true}); } } export function downBlocks(count = 1) { for (const _ of range(count)) { press('ArrowDown', {altKey: true}); } }

import
js
import {press} from '/api/code/takker/scrapbox-keyboard-emulation-2/script.js'; import {getLinkIncludingCursor} from '/api/code/takker/Scrapboxでcursor下のリンクを取得する/script.js'; import {cursor} from '/api/code/takker/scrapbox-cursor-position-2/script.js'; import {char as c} from '/api/code/takker/scrapbox-char-info/script.js'; import {line as l} from '/api/code/takker/scrapbox-line-info-2/script.js'; import {jumpToLF, jumpToChar} from '/api/code/takker/scrapbox-cursor-jumper/script.js'; import {splitWords, splitWORDs} from '/api/code/takker/ScrapVim-lite-2%2FwordSplitter/script.js'; import {scrapboxDOM} from '/api/code/takker/scrapbox-dom-accessor/script.js';

f{char}
js
jump_f: ({count = 1, char} = {}) { const index = l(cursor.line).charDOMs .slice(cursor.index) // cursor下の文字より後ろのみを取得 .find(span => span.textContent === char); if (!index) return; _log(`move to ${index} at %o`, cursor.line); jumpToChar({id: cursor.line.id, index}); }
単語移動
後方のWordsの先頭に移動する
js
goWordHead: ({count = 1} = {}) => { //後方検索 _log('splitted words: %o, cursor.line: %o, cursor.index: %o', splitWords(line.textContent), line, index); let match = splitWords(line.textContent) .find(word => word.index > cursor.index); // 単語の先頭がこれ以上なければ、次行に進む if (!match) { //先頭に進むのは確実なので、End+→で飛ぶ _log('Go to the next line.'); press('End'); press('ArrowRight'); return; } _log('the present line: %o', line); _log('the next word: %o', match); jumpToChar({id: line.id, index: match.index, shiftKey: visual}); },

前方のWordsの先頭に移動する
js
backWordHead: ({count = 1, visual = false, cursor: {line, index}} = {}) => { // 前方検索 _log('splitted words: %o, cursor.line: %o, cursor.index: %o', splitWords(line.textContent), line, index); let match = splitWords(line.textContent) .filter(word => word.index < index)?.pop(); let pressNum = 0; if (!match) { // なければ前の行に入る _log('Go to the previous line.'); const prevLine = line.previousElementSibling; if (!prevLine) return; // 先頭行だったら何もしない match = splitWords(prevLine.textContent)?.pop(); _log('the previous line: %o', prevLine); _log('the next word: %o', match); jumpToLF({id: prevLine.id, shiftKey: visual}); jumpToChar({id: prevLine.id, index: match.index, shiftKey: visual}); return; } _log('the present line: %o', line); _log('the next word: %o', match); jumpToChar({id: line.id, index: match.index, shiftKey: visual}); },

後方のWordsの末尾に移動する
js
goWordEnd: ({count = 1, visual = false, cursor: {line, index}} = {}) => { //後方検索 _log('splitted words: %o, cursor.line: %o, cursor.index: %o', splitWords(line.textContent), line, index); let match = splitWords(line.textContent) .find(word => word.index + (word.length - 1) > index); if (!match) { // なければ次の行に入る _log('Go to the next line.'); const nextLine = line.nextElementSibling; if (!nextLine) return; // 最後の行だったら何もしない match = splitWords(line.textContent)[0]; _log('the next line: %o', nextLine); _log('the next word: %o', match); jumpToLF({id: nextLine.id, shiftKey: visual}); jumpToChar({id: nextLine.id, index: match.index + match.length - 1, shiftKey: visual}); return; } _log('the present line: %o', line); _log('the next word: %o', match); jumpToChar({id: line.id, index: match.index + match.length - 1, shiftKey: visual}); },

前方のWordsの末尾に移動する
js
backWordEnd: ({count = 1, visual = false, cursor: {line, index}} = {}) => { // 前方検索 _log('splitted words: %o, cursor.line: %o, cursor.index: %o', splitWords(line.textContent), line, index); let match = splitWords(line.textContent) .filter(word => word.index + (word.length - 1) < index)?.pop(); // 単語の末尾が前方になければ前の行に移動する if (!match) { // 行末に移動することがわかっているので、Home + ←を使う _log('Go to the previous line.'); emulator.press('Home', {shiftKey: visual}); emulator.press('ArrowLeft', {shiftKey: visual}); emulator.press('ArrowLeft', {shiftKey: visual}); return; } _log('the present line: %o', line); _log('the next word: %o', match); jumpToChar({id: line.id, index: match.index + match.length - 1, shiftKey: visual}); },

#2021-03-15 00:50:18
#2021-01-21 15:20:29
#2020-12-24 02:00:04
#2020-12-18 05:46:55