generated from obsidian-community/obsidian-theme-template
-
-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathcustom-functions.ts
More file actions
90 lines (84 loc) · 2.85 KB
/
custom-functions.ts
File metadata and controls
90 lines (84 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { readdirSync, readFileSync } from 'fs'
import { SassString, type CustomFunction } from 'sass'
import { version } from '../package.json'
import { icons as lucide } from '@iconify-json/lucide'
import { icons as bootstrap } from '@iconify-json/bi'
import { icons as tabler } from '@iconify-json/tabler'
const resourceDir = 'resource'
function getIconUrl(name: string, color?: string) {
const parseSvgUrl = (svg: string, color?: string) => {
if (color) {
svg = svg.replaceAll('currentColor', Bun.color(color, 'HEX') || '#0000')
}
svg = svg
.replace(/"/g, "'")
.replace(/%/g, '%25')
.replace(/#/g, '%23')
.replace(/\s+/g, ' ')
.replace(/> </g, '><')
return 'url("data:image/svg+xml,' + svg + '")'
}
let data
let set
if (name.startsWith('bi:')) {
data = bootstrap.icons[name.substring(3)]
set = bootstrap
} else if (name.startsWith('tb:')) {
data = tabler.icons[name.substring(3)]
set = tabler
} else {
data = lucide.icons[name]
set = lucide
}
const fileIconDir = `${resourceDir}/svg`
const fileIcons = readdirSync(fileIconDir)
if (!data) {
if (fileIcons.some((i) => i.startsWith(name))) {
const svg = readFileSync(fileIconDir + '/' + name + '.svg', 'utf-8')
return parseSvgUrl(svg, color)
}
throw new Error(`No such icon: ${name}`)
}
const viewBox = [0, 0, set.width || 16, set.height || 16].join(' ')
const w = set.width || '1em'
const h = set.height || '1em'
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}" width="${w}" height="${h}">${data.body}</svg>`
return parseSvgUrl(svg, color)
}
export const FUNCTIONS: Record<string, CustomFunction<'sync'>> = {
'version()': () => {
return new SassString(`Maple ${version}`)
},
'unescape($str)': ([str]) => {
return new SassString(str.assertString().text.replace(/\\/g, ''))
},
'icon($icon-name, $color: "")': ([name, color]) => {
return new SassString(
getIconUrl(name.assertString().text, color.assertString().text),
{
quotes: false,
},
)
},
'font($style)': ([name]) => {
const styleVar = name.assertString().text
const style = styleVar.charAt(0).toUpperCase() + styleVar.slice(1)
if (style !== 'Regular' && style !== 'Italic') {
throw new Error('style must be regular or italic')
}
const source = readFileSync(
`${resourceDir}/font/MapleMono-${style}.woff2`,
).toBase64()
return new SassString(`url("data:font/woff2;base64,${source}")`, {
quotes: false,
})
},
// 'img($image-name)': ([name]) => {
// const imageName = name.assertString().text
// const buffer = readFileSync(
// join(`${resourceDir}/image${imageName}.webp`),
// )
// const url = 'url("data:image/webp;base64,' + buffer.toBase64() + '")'
// return new SassString(url, { quotes: false })
// },
}