Last active
August 9, 2021 07:05
-
-
Save kaave/9c301f144528b795719282a2d964995d to your computer and use it in GitHub Desktop.
Scrapbox のバックアップ json から Markdown を作成
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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