2021-02-15 20:56:41 +00:00
|
|
|
import { readFileSync } from "fs";
|
|
|
|
import path from "path";
|
|
|
|
import { stringify, parse } from "css";
|
|
|
|
export { stringify, parse };
|
|
|
|
|
2021-02-18 16:43:25 +00:00
|
|
|
export const CORE = parse(`p, pre, ul, blockquote, h1, h2, h3 {
|
|
|
|
margin-top: 0;
|
|
|
|
margin-bottom: 0;
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
hyphens: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
a { display: block; }
|
2021-02-15 20:56:41 +00:00
|
|
|
|
2021-02-18 16:43:25 +00:00
|
|
|
img, audio, video {
|
2021-02-15 20:56:41 +00:00
|
|
|
display: block;
|
|
|
|
max-width: 100%;
|
2021-02-18 16:43:25 +00:00
|
|
|
}
|
|
|
|
`);
|
2021-02-15 20:56:41 +00:00
|
|
|
|
2021-02-18 16:43:25 +00:00
|
|
|
// TODO import.meta.resolve is supposed to accomplish this without "path"
|
|
|
|
export const FULL = parse(
|
|
|
|
readFileSync(
|
|
|
|
path.resolve(path.dirname(new URL(import.meta.url).pathname), "./gmi.css"),
|
|
|
|
"utf-8"
|
|
|
|
)
|
|
|
|
);
|
2021-02-15 20:56:41 +00:00
|
|
|
|
|
|
|
export function rootVariables({ stylesheet }) {
|
|
|
|
return stylesheet.rules
|
|
|
|
.find(
|
|
|
|
({ type, selectors }) => type === "rule" && selectors.includes(":root")
|
|
|
|
)
|
|
|
|
.declarations.reduce(
|
|
|
|
(obj, { property, value }) =>
|
|
|
|
!/^\-\-/.test(property)
|
|
|
|
? obj
|
|
|
|
: Object.assign(obj, { [property.replace("--", "")]: value }),
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-02-18 16:43:25 +00:00
|
|
|
export function override(options) {
|
|
|
|
if (options.css !== "full") return "";
|
|
|
|
const vars = rootVariables(FULL);
|
|
|
|
|
|
|
|
return Object.keys(vars).reduce((styles, key) => {
|
|
|
|
if (typeof options[key] !== undefined && options[key] !== vars[key]) {
|
|
|
|
let value = options[key];
|
|
|
|
if (["a-prefix", "ul-bullet"].includes(key) && value !== "none") {
|
|
|
|
value = `"${value}"`;
|
|
|
|
}
|
|
|
|
styles += `--${key}:${value};`;
|
|
|
|
}
|
|
|
|
return styles;
|
2021-02-18 19:11:03 +00:00
|
|
|
}, " ");
|
2021-02-18 16:43:25 +00:00
|
|
|
}
|
|
|
|
|
2021-02-18 19:11:03 +00:00
|
|
|
export function style({ inline, css }) {
|
|
|
|
if (inline || css === "none") return "";
|
2021-02-18 16:43:25 +00:00
|
|
|
if (css === "core")
|
|
|
|
return `<style>${stringify(CORE, { compress: true })}</style>`;
|
|
|
|
if (css === "full")
|
|
|
|
return `<style>${stringify(FULL, { compress: true })}</style>`;
|
|
|
|
|
2021-02-18 19:11:03 +00:00
|
|
|
return `<style>${stringify(load(css, { compress: true }))}</style>`;
|
2021-02-18 16:43:25 +00:00
|
|
|
}
|
|
|
|
|
2021-02-18 19:11:03 +00:00
|
|
|
export function inline(tag, { inline, css }) {
|
|
|
|
if (!inline || css === "full") return "";
|
|
|
|
const { stylesheet } = css === "core" ? CORE : load(css);
|
2021-02-18 16:43:25 +00:00
|
|
|
const styles = stylesheet.rules
|
|
|
|
.filter(({ type, selectors }) => type === "rule" && selectors.includes(tag))
|
|
|
|
.reduce((style, { declarations }) => {
|
|
|
|
declarations.forEach(({ property, value }) => {
|
|
|
|
style = `${style}${property}:${value};`;
|
|
|
|
});
|
|
|
|
return style;
|
|
|
|
}, "");
|
|
|
|
|
|
|
|
return styles !== "" ? ` style="${styles}"` : "";
|
|
|
|
}
|
|
|
|
|
|
|
|
export function load(file, options) {
|
2021-02-18 19:11:03 +00:00
|
|
|
if (fs.existsSync(file)) {
|
2021-02-18 16:43:25 +00:00
|
|
|
return parse(readFileSync(path.resolve(file), "utf-8"));
|
|
|
|
} else {
|
2021-02-18 19:11:03 +00:00
|
|
|
throw new Error(`Cannot find file ${file}.`);
|
2021-02-18 16:43:25 +00:00
|
|
|
}
|
2021-02-15 20:56:41 +00:00
|
|
|
}
|