generated at
Scrapbox記法をBlock kitに変換するscript
Scrapbox記法で書かれたテキストをBlock kitのjson dataに変換するscript.

Google Apps Script用にしてある
ESModuleで使うときは、先頭に import {ScrapboxParser} from '/path/to/parser.js'; などと追記すること
sb2mrkdwn.gs(js)
function sb2mrkdwn(text, { project }) { const blocks = ScrapboxParser.parse(text, { hasTitle: false }); return blocks.map(block => convertSb2Md(block, { project })); } function convertSb2Md(block, { project }) { switch (block.type) { case 'title': return; // タイトルは選択範囲に入らないので無視 case 'codeBlock': return { type: 'section', text: { type: 'mrkdwn', text: `\`${block.fileName}\`\n\`\`\`${block.content}\`\`\``, }, }; case 'table': return { type: 'section', text: { type: 'mrkdwn', text: `\`table:${block.fileName}\``, }, }; case 'line': return convertLine(block, { project }); } } function convertLine(line, { project }) { const objects = line.nodes .flatMap(node => convertNode(node, { project })); //console.log(objects); // 画像のみの行は大きく表示する。アイコンは除く if (objects.length === 1 && objects[0] && objects[0].type === 'image' && !/^https:\/\/scrapbox\.io\/api\/pages\/.+\/.+\/icon$/.test(objects[0])) return objects[0]; // elementsの上限を越えないように、mrkdwnを結合する //全部結合するのではyyなく、上限を越える場合のみ結合するようにする? const elements = []; let chunk = undefined; for (const object of objects) { if (object.type !== 'mrkdwn') { if (chunk) elements.push(chunk); chunk = undefined; elements.push(object); continue; } chunk = { type: 'mrkdwn', text: `${chunk ? chunk.text : ''}${object.text}`, }; } if (chunk) elements.push(chunk); if (elements.length === 0) elements.push({ type: 'plain_text', text: ' ', // 空文字列だとエラーになる }); return { type: 'context', elements, }; } function convertNode(node, { project }) { switch (node.type) { case 'quote': const objects = node.nodes.flatMap(node => convertNode(node, { project })); switch (objects[0].type) { case 'plain_text': case 'mrkdwn': return [{ type: 'mrkdwn', text: `>${objects[0].text}`, }, ...objects.slice(1)]; default: return objects; } case 'image': case 'strongImage': return [{ type: 'image', image_url: node.src, alt_text: 'image', }] case 'icon': case 'strongIcon': /*const path = (() => { if (node.pathType === 'relative') { return `/${project}/${encodeURIComponent(node.path)}`; } else { const root = node.path.split('/')[1]; const iconName = node.path.slice(`/${root}/`.length); return `/${root}/${encodeURIComponent(iconName)}`; } })();*/ const path = node.pathType === 'relative' ? `/${project}/${node.path}` : node.path; return [{ type: 'image', image_url: `https://scrapbox.io/api/pages${path}/icon`, alt_text: node.path, }]; case 'formula': return [{ type: 'mrkdwn', text: `\`${node.formula}\``, }]; case 'helpfeel': return [{ type: 'mrkdwn', text: `\`? ${node.text}\``, }]; case 'commandLine': return [{ type: 'mrkdwn', text: `\`${node.symbol} ${node.text}\``, }]; case 'decoration': const hasStrong = node.decos.some(deco => /\*-/.test(deco[0])); const hasItalic = node.decos.includes('/'); const hasStrike = node.decos.includes('-'); return node.nodes.flatMap(node => convertNode(node, { project })) .map(object => { if (object.type !== 'plain_text' || !/^\s*$/.test(object.text) || !/^<https?:\/\/.+\|.+>$/.test(object.text)) return object; let text = object.text; if (hasStrong) text = `*${text}*`; if (hasItalic) text = `_${text}_`; if (hasStrike) text = `~${text}~`; return { type: 'mrkdwn', text: text, }; }); case 'strong': return node.nodes.flatMap(node => convertNode(node, { project })) .map(object => { if (object.type !== 'plain_text') return object; return { type: 'mrkdwn', text: `*${object.text}*`, }; }); case 'code': return [{ type: 'mrkdwn', text: `\`${node.text}\``, }]; case 'googleMap': return [{ type: 'mrkdwn', text: `<${node.url}|${node.place}>`, }]; case 'link': switch (node.pathType) { case 'root': return [{ type: 'mrkdwn', text: `<https://scrapbox.io${node.href}|${node.href}>`, }]; case 'relative': return [{ type: 'mrkdwn', text: `<https://scrapbox.io/${project}/${node.href}|${node.href}>`, }]; case 'absolute': return [{ type: 'mrkdwn', text: `<${node.href}|${node.content || node.href}>`, }]; } case 'hashTag': return [{ type: 'mrkdwn', text: `<https://scrapbox.io/${project}/${node.href}|#${node.href}>`, }]; case 'blank': case 'plain': return [{ type: 'mrkdwn', text: node.text, }]; } }