generated at
scrapboxのページカードを作成するscript
scrapboxのページカードを作成するscript
外部projectでも使える

説明文の実装
1行づつ <p> で囲む
各種構文
無視するもの
テーブル
コードブロック
数式
KaTeXを再現出来ない
画像
DOMじゃなくて element.insertAdjacentHTML() に入れられるtext形式で返したほうがいいな
textならWebWorkerでも計算できる
htmlをescapeできていない
script.js
import {ScrapboxParser} from '/api/code/takker/scrapbox-parser.min.js/parser.js'; export function createPageCard({project, title, description, imageUrl=undefined} = {}) { //console.log(`project: ${project}`); //console.log(`description: ${description}`); //console.log(`imageUrl: ${imageUrl}`); const content = imageUrl ? `<div class="icon"> <img loading="lazy" src="${imageUrl}"> </div>` : `<div class="description">${parse(description, project)}</div>`; return ` <li class="page-list-item grid-style-itme"> <a href="/${project}/${encodeURIComponent(title)}" rel="route"> <div class="hover"></div> <div class="content"> <div class="header"> <div class="title">${title}</div> </div> ${content} </div> </a> </li>`; } function parse(text, project) { const blocks = ScrapboxParser.parse(text, {hasTitle: false}); return blocks.map(block => convertSb2HTML(block, project)).join('\n'); } function convertSb2HTML(block, project) { switch (block.type) { case 'title': return ''; // タイトルは選択範囲に入らないので無視 case 'codeBlock': case 'table': return ''; case 'line': if (block.nodes.length === 0) return ''; if(block.nodes.length === 1) { const node = block.nodes[0]; if (node.type === 'blank') return ''; if (node.type === 'plain') return `<p>${node.text}</p>`; } return `<p>${block.nodes.map(node => '<span>' + convertNode(node, project) +'</span>').join('')}</p>`; } } function convertNode(node, project) { switch (node.type) { case 'quote': case 'image': case 'strongImage': case 'formula': case 'googleMap': return ''; case 'icon': case 'strongIcon': if (node.pathType ==='relative') { return `<img class="inline-icon" src="https://scrapbox.io/api/pages/${project}/${node.path}/icon" />`; } return `<img class="inline-icon" src="https://scrapbox.io/api/pages${node.path}/icon" />`; case 'strong': return `<strong>${node.text}</strong>`; case 'decoration': let result = node.nodes.map(node => convertNode(node)).join(''); if (node.decos.includes('/')) result = `<i>${result}</i>`; if (node.decos.some(deco => /\*-/.test(deco[0]))) result = `<strong>${result}</strong>`; if (node.decos.some(deco => deco[0] === '~')) result = `<strike>${result}</strike>`; return result; case 'helpfeel': return `<code>? ${node.text}</code>`; case 'code': return `<code>${node.text}</code>`; case 'commandLine': return `<code>${node.symbol} ${node.text}</code>`; case 'link': switch(node.pathType) { case 'root': return `<span class="page-link">${node.href}<span>`; case 'relative': return `<span class="page-link">${node.href}</span>`; case 'absolute': return `<span class="link">${node.content ?? node.href}</span>`; } case 'hashTag': return `<span class="page-link">${node.href}<span>`; case 'blank': case 'plain': return node.text; } }
#2021-02-11 17:43:04
#2020-10-25 15:12:12
#2020-10-23 06:44:19