popup-menu-prettier
import
dependencies
code:script.js
import Prettier from '/api/code/takker/prettier@2.2.1/script.js'
import ParserBabel from '/api/code/takker/prettier@2.2.1%2Fparser-babel/script.js'
import {
parseToRows,
packRows,
} from '/api/code/takker/scrapbox-parser@7.1.0/script.js'
scrapbox.PopupMenu.addButton({
title: '\uf121', //(text) => (/\n\s*code:/.test(text) ? "Format" : ""),
onClick: (text) => {
const blocks = packRows(parseToRows(text), { hasTitle: false })
return blocks
.map(({ type, rows }) => {
switch (type) {
case 'line':
case 'table':
return rows.map(({ text: _text }) => _text).join('\n')
case 'codeBlock':
return formatCodeBlock(rows)
}
})
.join('\n')
},
})
const fileTypes = {
javascript: 'javascript',
js: 'javascript',
jsx: 'javascript',
mjs: 'javascript',
typescript: 'typescript',
ts: 'typescript',
tsx: 'typescript',
graphql: 'graphql',
gql: 'graphql',
}
const parserConfig = {
javascript: {
parser: 'babel',
semi: false,
singleQuote: true,
},
}
function formatCodeBlock(rows, config = {}) {
const fileLine = rows0.text const extention =
fileLine.match(/\.(.+)$/)?.1 ?? fileLine.match(/\((.+)\)$/)?.1 ?? fileLine.match(/\s*code:(.+)$/)?.1 const baseIndent = rows0.indent const code = rows
.slice(1)
.map((row) => row.text.slice(row.indent))
.join('\n')
const _config = parserConfig[fileTypesextention] if (!_config) return rows.map(({ text: _text }) => _text).join('\n')
const formattedCode = Prettier.format(code, { ...config, ..._config })
.split('\n')
.map((line) => ${' '.repeat(baseIndent + 1)}${line})
.join('\n')
.trimEnd() // prettierが末尾に改行を挿入するので削除する
}