Skip to content

Instantly share code, notes, and snippets.

@kaave
Last active August 9, 2021 07:05
Show Gist options
  • Save kaave/9c301f144528b795719282a2d964995d to your computer and use it in GitHub Desktop.
Save kaave/9c301f144528b795719282a2d964995d to your computer and use it in GitHub Desktop.
Scrapbox のバックアップ json から Markdown を作成
import scrapboxData from '../scrapbox.json';
import fs from 'fs-extra';
import path from 'path';
const distPath = path.join(process.cwd(), 'dist');
async function main() {
fs.mkdirp(distPath);
scrapboxData.pages.forEach(page => {
const fileName = page.title.replace(/\//g, '-');
fs.writeFileSync(
path.join(distPath, `${fileName}.md`),
convertTable(convertCodeBlock(page.lines.slice(1))).map(line =>
line
// 見出し
.replace(/^\[(\*{1,}) (.+)\]$/, (_, p1, p2) => `${'#'.repeat(6 - p1.length)} ${p2}\n`)
// 斜体 + 太字
.replace(/\[\/\* (.*)\]/, (_, p1) => ` ___${p1}___ `)
// 斜体
.replace(/\[\/ (.*)\]/, (_, p1) => ` _${p1}_ `)
// 太字
.replace(/\[\[(.*)\]\]/, (_, p1) => ` __${p1}__ `)
// 太字(たぶん本来不正だが使っとる場所がありがち)
.replace(/^\[\*{1} (.+)\]/, (_, p1) => `__${p1}__ `)
// リンク
.replace(/\[([^ ]*) (.+)\]/, (_, p1: string, p2: string) => p2.startsWith('http://') || p2.startsWith('https://') ? `[${p1}](${p2})` : `[${p2}](${p1})`)
// リスト
.replace(/^( +)/, (_, p1) => `${' '.repeat((p1.length - 1) * 2)}- `)
// 引用
.replace(/^(>+)([^ ])/, (_, __, p2) => `> ${p2}`)
)
.join('\n')
);
// code や table はかなり怪しいので plain も用意
fs.writeFileSync(
path.join(distPath, `${fileName}.plain.md`),
page.lines.slice(1).join('\n')
);
});
}
function convertCodeBlock(lines: readonly string[]): readonly string[] {
let inCodeBlock = false;
return lines.map(line => {
if (line.startsWith('code:')) {
inCodeBlock = true;
return line.replace(/^code:(.*)/, (_, p1) => `\`\`\`${p1}`)
} else if (inCodeBlock && line === '') {
inCodeBlock = false;
return '```\n'
} else if (inCodeBlock) {
return line.substring(1);
}
return line;
});
}
function convertTable(lines: readonly string[]): readonly string[] {
let inTableBlock = false;
let tableCellCount: number | undefined;
return lines.map(line => {
if (line.startsWith('table:')) {
inTableBlock = true;
return line.replace(/^table:(.*)/, (_, p1) => `__${p1}__\n\n`)
} else if (inTableBlock && tableCellCount == null) {
// 見出し
tableCellCount = (line.match(/\t/g) ?? []).length + 1;
return `${line.replace(/^ /, '| ').replace(/\t/g, ' | ')} |\n| ${'--- | '.repeat(tableCellCount)}`.trim();
} else if (inTableBlock && line === '') {
inTableBlock = false;
tableCellCount = undefined;
} else if (inTableBlock) {
return line.replace(/^ /, '| ').replace(/\t/g, ' | ').replace(/ ?$/g, ' |');
}
return line;
});
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment