scrapboxのページカードを作成するscript_old
scrapbox-parserを使ったver.を作った
以下は、独自の簡易parserを使った方法
/icons/hr.icon
scrapboxの実装をほぼそのまま使う
説明文の実装
1行づつ<p>で囲む
↓構文解析が面倒なのでパス
リンクは<span class="page-link">を使う
外部リンクは<span class="link">を使う
アイコン記法は<img class="inline-icon" src='...'>を使う
srcは読み込み元のprojectに合わせる
インラインコードは<code>を使う
code:script.js
export function createPageCard(project,titleLc,descriptions,imageUrl = null) {
const wrapper = document.createElement('a');
wrapper.href = /${project}/${titleLc};
wrapper.rel = 'route';
const hover = document.createElement('div');
hover.classList.add('hover');
wrapper.appendChild(hover);
const content = document.createElement('div');
content.classList.add('content');
wrapper.appendChild(content);
// titleを入れる
const title = document.createElement('div');
title.classList.add('title');
title.textContent = decodeURIComponent(titleLc);
const header = document.createElement('div');
header.classList.add('header');
header.appendChild(title);
content.appendChild(header);
// thumbnail imageがある場合
if (imageUrl !== null) {
const image = document.createElement('img');
image.loading = 'lazy';
image.src= imageUrl;
const icon = document.createElement('div');
icon.classList.add('icon');
icon.appendChild(image);
content.appendChild(icon);
} else {
const text = document.createElement('div');
text.classList.add('description');
descriptions.forEach(description => {
const line = document.createElement('p');
line.appendChild(parseLine(description, project));
text.appendChild(line);
});
content.appendChild(text);
}
const card = document.createElement('li');
card.classList.add('page-list-item', 'grid-style-item');
card.appendChild(wrapper);
return card;
}
function parseLine(line, project) {
// []記法を探す
const reg = /(\^\s!"#%&'()\*\+,\-\.\{\|\}<>_~[\+[^\]*\])/u; const words = line.split(reg).filter(word => word !== '');
let fragment = document.createDocumentFragment();
for (const word of words) {
if(!reg.test(word)) {
fragment.appendChild(document.createTextNode(word));
continue;
}
const content = word.replace(/\(.+)\/,'$1'); // 外部リンクかどうか
if(/(?:^https*:\/\/)|(?:\shttps*:\/\/^\s+$)/.test(content)) { const link = document.createElement('span');
link.classList.add('link');
link.textContent = content.replace(/(?:^https*:\/\/^\s+\s)|(?:\shttps*:\/\/^\s+$).*/,''); fragment.appendChild(link);
continue;
}
// 記法によって分岐する
if(/\.icon$/.test(content)) {
const img = document.createElement('img');
img.classList.add('inline-icon');
const link = content.replace(/(.+)\.icon$/,'$1');
// 外部projectかどうか
const isExternalLink = /^\/a-zA-z\-+(?:\/|$)/.test(content); if(isExternalLink) {
img.src = /api/pages${link}/icon;
} else {
img.src = /api/pages/${project}/${link}/icon;
}
fragment.appendChild(img);
continue;
}
const link = document.createElement('span');
link.classList.add('page-link');
link.textContent = content;
fragment.appendChild(link);
}
return fragment;
}