subframe7536_obsidian-theme.../compile.ts
2026-04-13 15:12:52 +08:00

157 lines
3.5 KiB
TypeScript

import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { homedir, platform } from 'node:os'
import { basename, extname, resolve, join, parse } from 'node:path'
import { styleText } from 'node:util'
import { watch } from 'chokidar'
import { compile } from 'sass'
import { version } from './package.json'
import { FUNCTIONS } from './src/custom-functions'
import settings from './src/style-settings/index'
function setup(baseDir: string) {
if (!existsSync(baseDir)) {
mkdirSync(baseDir, { recursive: true })
}
const testFile = join(baseDir, 'index.md')
if (existsSync(testFile)) {
return
}
writeFileSync(
testFile,
`---
tags:
- test
---
**Please install "Style Settings" plugin for further develop**
## Heading 2
> Quote
>> text
- list
- list
- sublist
- sublist
### Heading 3
1. asd
2. asdasd
3. asdasdasd
---
[URL](https://github.com/subframe7536/obsidian-theme-maple)
| table1 | table2 |
| ------ | ------ |
| cell1 | cell2 |
`,
)
}
function compileCss(output: string, src: string, prepend?: string) {
try {
let { css } = compile(src, {
sourceMap: false,
functions: FUNCTIONS,
charset: false,
})
css = css.replace(/\s+[\w-]+\b:\s*ignore;/g, '')
writeFileSync(output, prepend ? `${prepend}\n${css}` : css, 'utf-8')
console.log(
styleText('gray', new Date().toLocaleTimeString(['zh'])),
styleText('greenBright', `Compile to ${output}`),
)
} catch (err) {
console.error(err)
}
}
function build(src: string, out: string) {
const manifestPath = 'manifest.json'
const manifest = readFileSync(manifestPath, 'utf-8')
writeFileSync(
manifestPath,
JSON.stringify(
{
...JSON.parse(manifest),
version,
},
null,
2,
),
)
compileCss(out, src, settings)
}
function test(src: string) {
const p = parse(src)
compileCss(`${p.dir}/${p.name}.css`, src)
}
async function dev(src: string, out: string) {
try {
const latestSettings = await Bun.$`bun ${process.cwd()}/src/style-settings/index.ts`.text()
compileCss(out, src, latestSettings)
} catch (err) {
console.error(err)
}
}
function move() {
const vaultRoots = process.env.VAULT_DIRS?.split(',').filter(Boolean)
if (!vaultRoots?.length) {
console.log('No chosen vault, skip moving')
return
}
console.log(`choose ${vaultRoots?.length ?? 0} vaults`)
for (const root of vaultRoots) {
const themeRoot = join(root, '.obsidian', 'themes', 'Maple')
if (!existsSync(themeRoot)) {
mkdirSync(themeRoot, { recursive: true })
}
copyFileSync('theme.css', join(themeRoot, 'theme.css'))
copyFileSync('manifest.json', join(themeRoot, 'manifest.json'))
console.log(`> ${root}`)
}
}
function main() {
const devVaultRoot =
platform() === 'win32' ? 'D:/note/dev-vault' : `${homedir()}/Desktop/note/dev-vault`
const baseDir = resolve(devVaultRoot, 'test')
setup(baseDir)
const input = process.argv?.filter((s) => !s.startsWith('--'))[2] ?? 'src/index.scss'
const output = `${devVaultRoot}/.obsidian/snippets/${basename(input).replace(extname(input), '.css')}`
const isBuild = process.argv?.includes('--build')
const isTest = process.argv?.includes('--test')
if (isBuild) {
build(input, 'theme.css')
move()
return
}
if (isTest) {
test(input)
return
}
void dev(input, output)
watch(join(process.cwd(), 'src')).on('change', () => dev(input, output))
watch(join(process.cwd(), 'compile.ts')).on('change', () => dev(input, output))
}
main()