複数行に打ち消し線を引くPopup Menu その2
突貫工事でやってみたけど、意外と一筋縄では行かない
上位のnodeに文字装飾記法がないときだけ、 -
で囲むようにしないと、リンクが出来てしまう
Gyazoの画像がリンクに変換されてしまう
Gyazoのサムネイル画像を検出して、それをGyazoのpermalinkに変換する処理を入れる必要がある
打ち消し記法がかなり細かくなってしまう
隣にリンクやplain textがあるときは、まとめて打消し線を引けるように変えるべきだが、flag処理とか色々やる必要が出てきそう
変換する必要のない記法に対する処理も書かなくてはいけない
「元に戻す」処理を書く
dependencies
script.jsimport {ScrapboxParser} from '../scrapbox-parser.min.js/parser.js';
scrapbox.PopupMenu.addButton({
title: '\uf0cc',
onClick: text => {
const result = convert(text);
if (text === result) return; // 変更がなければ何もしない
return result;
},
});
変換する関数
script.jsfunction convert(text) {
const blocks = ScrapboxParser.parse(text, {hasTitle: false});
return blocks.flatMap(block => {
switch (block.type) {
case 'title':
return [];
case 'codeBlock':
return convertCodeBlock(block);
case 'table':
return convertTable(block);
case 'line':
return convertLine(block);
}
})
.map((line, i) => `${' '.repeat(blocks[i].indent)}${line}`)
.join('\n');
}
function convertCodeBlock({fileName, content}) {
return [`code:${fileName}`, ...content.split('\n').map(line => ` ${line}`)];
}
function convertTable({fileName, cells}) {
return [`table:${fileName}`, ...cells.map(cell => ` ${cell.map(([{text}]) => text).join('\t')}`),];
}
function convertLine({nodes}) {
return [nodes.map(node => `${' '.repeat(node.indent)}${convertNode(node)}`).join('')];
}
function convertNode(node, noStrike) {
switch (node.type) {
case 'quote':
return `> ${node.nodes.map(node => convertNode(node)).join('')}`;
case 'helpfeel':
return `[${noStrike ? '' : '- '}? ${node.text}]`;
case 'image':
return `[${node.src}${node.link ? ` ${node.link}` : ''}]`;
case 'strongImage':
return `[[${node.src}${node.link ? ` ${node.link}` : ''}]]`;
case 'icon':
return `[${node.path}.icon]`;
case 'strongIcon':
return `[[${node.path}.icon]]`;
case 'strong':
return `[[${node.nodes.map(node => convertNode(node)).join('')}]]`;
case 'formula':
return `[$ ${node.formula}]`;
case 'decoration':
if (!node.decos.includes('-')) node.decos.push('-');
const deco = node.decos.map(deco => {
if (/\*-/.test(deco)) {
const num = deco.match(/\*-(\d)/)[1];
return '*'.repeat(num);
}
return deco;
}).join('');
return `[${deco ? `${deco} ` : ''}${node.nodes.map(node => convertNode(node, deco.includes('-'))).join('')}]`;
case 'code':
return `\`${node.text}\``;
case 'commandLine':
return `[${noStrike ? '' : '- '}${node.symbol} ${node.text}]`;
case 'link':
switch(node.pathType) {
case 'root':
case 'relative':
return `[${noStrike ? '' : '- '}[${node.href}]]`;
case 'absolute':
return `[${noStrike ? '' : '- '}[${node.content ? `${node.content} ` : ''}${node.href}]]`;
}
case 'googleMap':
return `[N${node.latitude},E${node.longitude},Z${node.zoom} ${node.place}]`;
case 'hashTag':
return `[${noStrike ? '' : '- '}#${node.href}]`;
case 'blank':
case 'plain':
return noStrike ? node.text :`[- ${node.text}]`;
}
}