generated at
abetaka



日付書式
script.js
// Formats: https://momentjs.com/ scrapbox.TimeStamp.addFormat("[[]YYYY/MM/DD[]] HH:mm:ss") scrapbox.TimeStamp.addFormat("[[]YYYY/MM/DD[]]")


script.js
const number_finder = /\d{2,5}[-(]\d{1,4}[-)]\d{4}/g const menu_title = 'Call Button' let count_indent = text => /^(\s*)/.exec(text)[0].length scrapbox.PageMenu.addMenu({ title : menu_title, image : 'https://gyazo.com/979a476c4cd4da31dbcae27a0e2e598f/raw', /* icon by icon8 'https://icons8.com/icon/free-pack/call/metro' */ onClick: () => { scrapbox.PageMenu(menu_title).removeAllItems() const lines = scrapbox.Page.lines let upper_line, item_name let is_number_found = false for (let line of lines) { const found_number = line.text.match(number_finder) if (!found_number) { upper_line = line.text continue } item_name = found_number if ((upper_line) && (count_indent(line.text) > count_indent(upper_line))) { item_name = `${upper_line.trim()}: ${found_number}` } scrapbox.PageMenu(menu_title).addItem({ title : item_name, onClick: () => window.open(`tel:${found_number}`) }) is_number_found = true upper_line = '' } if (!is_number_found) { scrapbox.PageMenu(menu_title).addItem({ title :'No Telephone Number', onClick: function(){} }) } } })


チェックボックス
script.js
setTimeout(() => { // チェックボックスとして使用する文字セットのリスト const checkboxSetList = [ ['⬜', '☑️'], ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣'], ['😀', '😐', '😧', '😨'] ]; /* ['⬜', '✅'] ['🔲', '☑️'] */ const allBoxes = checkboxSetList.reduce((accu, current) => accu.concat(current), []); const startsWithBoxReg = new RegExp('^\\s*(' + allBoxes.join('|') + ')'); const targetProject = scrapbox.Project.name; class KeydownEvent { constructor() { this.textArea = document.getElementById('text-input'); this.event = document.createEvent('UIEvent'); this.event.initEvent('keydown', true, true); } dispatch(keyCode, withShift = false, withCtrl = false, withAlt = false, withCommand = false) { this.event.keyCode = keyCode; this.event.shiftKey = withShift; this.event.ctrlKey = withCtrl; this.event.altKey = withAlt; this.event.metaKey = withCommand; this.textArea.dispatchEvent(this.event); } } // ボックスクリックでオンオフする $('#app-container').off(`click.toggleCheckBox_${targetProject}`, '.lines'); $('#app-container').on(`click.toggleCheckBox_${targetProject}`, '.lines', async event => { if (scrapbox.Project.name !== targetProject) { $('#app-container').off(`click.toggleCheckBox_${targetProject}`, '.lines'); return; } const target = event.target; if (!isFirstElementChild(target)||!isCharSpan(target, allBoxes)) return; await new Promise(resolve => setTimeout(resolve, 30)); 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; const keydownEvent = new KeydownEvent(); if (cursorX <= targetX) { keydownEvent.dispatch(39); // → } keydownEvent.dispatch(8); // Backspace const newBox = (() => { const trimmedLineString = lineString.trim(); for (const checkboxSet of checkboxSetList) { for (let i = 0; i < checkboxSet.length; i++) { if (trimmedLineString.startsWith(checkboxSet[i])) { return checkboxSet[i + 1 < checkboxSet.length ? i + 1 : 0]; } } } return target.textContent; })(); writeText(newBox); // この下のコメントアウトを解除すると、checked時に取消線を入れて時刻を追記します // Mac、Porterでのみ動作します /* if (/Mobile/.test(navigator.userAgent)) return; const targetBoxSet = checkboxSetList[0]; if (!targetBoxSet.includes(newBox) || newBox === targetBoxSet[0]) return; await new Promise(resolve => setTimeout(resolve, 30)); keydownEvent.dispatch(39, true, false, false, true); // shift + command + → writeText('-'); keydownEvent.dispatch(39, false, false, false, true); // command + → const now = moment().format('HH:mm'); writeText(` ${now}`); */ }); // ボックス行で改行すると次行にボックス自動挿入 $('#text-input').off(`keydown.autoInsertCheckBox_${targetProject}`); $('#text-input').on(`keydown.autoInsertCheckBox_${targetProject}`, async event => { if (scrapbox.Project.name !== targetProject) { $('#text-input').off(`keydown.autoInsertCheckBox_${targetProject}`); return; } switch (event.key) { case 'Enter': { let currentLineString; try { currentLineString = getCursorLineString(); } catch (err) { console.log(err); return; } if (!startsWithBoxReg.test(currentLineString)) return; await new Promise(resolve => setTimeout(resolve, 30)); let nextLineString; try { nextLineString = getCursorLineString(); } catch (err) { console.log(err); return; } if (!startsWithBoxReg.test(nextLineString)) { const trimmedLineString = currentLineString.trim(); const targetBoxSet = checkboxSetList.find(boxSet => { return boxSet.some(box => trimmedLineString.startsWith(box)); }); writeText(targetBoxSet[0]); } return; } default: { return; } } }); function isFirstElementChild(element) { return element.parentNode.firstElementChild === element; } function getCursorLineString() { return document.querySelector('.lines div.line.cursor-line').textContent; } function isCharSpan(element, targetCharList) { return element.tagName === 'SPAN' && targetCharList.includes(element.textContent) && element.classList.value.split(' ').some(value => /^c\-\d+$/.test(value)); } function writeText(text) { const textArea = document.getElementById('text-input'); textArea.value = text; textArea.dispatchEvent(new InputEvent('input', {bubbles: true, cancelable: true})); } }, 1500);


大見出し
script.js
scrapbox.PopupMenu.addButton({ title: '見出し', onClick: text => { return '[** ' + text + ']'; } })

大切
script.js
scrapbox.PopupMenu.addButton({ title: '大切', onClick: text => { return '[+ ' + text + ']'; } })

コメント
script.js
scrapbox.PopupMenu.addButton({ title: 'コメント', onClick: text => { return '[# ' + text + ']'; } })


名前囲
script.js
scrapbox.PopupMenu.addButton({ title: '名前囲', onClick: text => { return '`' + text + '`'; } })