docs2website/src/themes.ts

65 lines
1.5 KiB
TypeScript

import { glob } from 'glob';
import { Config } from './conf';
import { load_from_dir } from './fs';
import { ColorTheme, themes as builtin_themes, load_theme as load_builtin_theme, validate_theme } from '@doc-utils/color-themes';
export async function load_themes(conf: Config) {
const themes: Record<string, ColorTheme> = { };
for (const theme of builtin_themes) {
themes[theme] = load_builtin_theme(theme);
}
if (conf.templates?.themes) {
const local_themes = await glob(conf.templates.themes + '/**/theme.json');
for (const theme_path of local_themes) {
const segments = theme_path.split('/');
const theme = segments[segments.length - 2];
themes[theme] = await load_local_theme(conf, theme);
}
}
return themes;
}
export async function load_theme(conf: Config, name: string) {
if (name.includes('/')) {
return null;
}
const local_theme = await load_local_theme(conf, name);
if (local_theme) {
return local_theme;
}
return load_builtin_theme(name);
}
export async function load_local_theme(conf: Config, name: string) {
let json: string;
try {
json = await load_from_dir(conf.templates?.themes, `./${name}/theme.json`);
}
catch (error) {
return null;
}
const theme = JSON.parse(json);
validate_theme(theme);
return theme;
}
export function render_theme_css_properties(theme: ColorTheme) {
return Object
.entries(theme.colors)
.map(([ name, color ]) => {
return `--theme-${name.replace(/_/g, '-')}: ${color};`;
})
.join('\n') + '\n';
}