fix color-schemes
This commit is contained in:
parent
17a2ab7f5e
commit
94abcfd542
|
@ -162,15 +162,13 @@ gmi-web --config web.json $(find ~/gmi/dst -name '*.gmi')
|
|||
|
||||
## custom css
|
||||
|
||||
It is possible to use your own set of completely custom CSS rules by pointing to a .css file containing them.
|
||||
It is possible to use your own set of completely custom CSS rules _and_ variables by pointing to a .css file containing them.
|
||||
|
||||
```sh
|
||||
gmi-web --body --css custom.css < doc.gmi
|
||||
```
|
||||
|
||||
gmi-web auto-detects the need for the `<meta>` color-schemes and allows for using `--inline` to insert the declarations as `style` properties on their respective blocks.
|
||||
|
||||
[gmi.css](./gmi.css) is a good starting point!
|
||||
gmi-web auto-detects the need for the `<meta>` color-schemes and allows for using `--inline` to insert the declarations as `style` properties on their respective blocks. Variables defined in `:root` will be picked up and made available for customization via command-line flags.
|
||||
|
||||
# license
|
||||
|
||||
|
|
3
cli.js
3
cli.js
|
@ -104,6 +104,9 @@ if (!argv.html && !argv.body) {
|
|||
cli.exit(1);
|
||||
}
|
||||
|
||||
argv.inlineCSS = CSS.inline(argv);
|
||||
argv.styleTag = CSS.style(argv);
|
||||
|
||||
if (!argv.files) {
|
||||
let gemtext;
|
||||
try {
|
||||
|
|
65
css.js
65
css.js
|
@ -6,10 +6,10 @@ import { stringify, parse } from "css";
|
|||
export function style(options) {
|
||||
if (options.inline || options.css === "none") return "";
|
||||
const rules = load(options);
|
||||
const schemes = rules.find(({ media }) => media === "preferes-color-scheme")
|
||||
? `<meta name="color-scheme" content="dark light">\n`
|
||||
const schemes = rules.find(({ media }) => media)
|
||||
? `<meta name="color-scheme" content="dark light">`
|
||||
: "";
|
||||
return `<style>${stringify(
|
||||
return `\n${schemes}\n<style>${stringify(
|
||||
{
|
||||
stylesheet: { rules: reduceVariables(rules, options) },
|
||||
},
|
||||
|
@ -19,7 +19,7 @@ export function style(options) {
|
|||
|
||||
export const inline = (options) => {
|
||||
const rules = load(options);
|
||||
return (tag) => {
|
||||
return function inlineCSS(tag) {
|
||||
if (!options.inline || options.css === "none") return "";
|
||||
const styles = reduceVariables(rules, options)
|
||||
.filter(({ selectors }) => selectors && selectors.includes(tag))
|
||||
|
@ -37,25 +37,22 @@ export function load(options) {
|
|||
options.css =
|
||||
options.css ||
|
||||
(!options.body || !options.inline ? "gmi-web.css" : "gmi.css");
|
||||
console.log("load:", options.css);
|
||||
if (
|
||||
["gmi", "web", "gmi.css", "gmi-web.css"].includes(options.css) ||
|
||||
["gmi.css", "gmi-web.css"].includes(options.css) ||
|
||||
existsSync(options.css)
|
||||
) {
|
||||
const packageRoot = (file) =>
|
||||
const internal = (file) =>
|
||||
path.resolve(path.dirname(new URL(import.meta.url).pathname), file);
|
||||
return parse(
|
||||
readFileSync(
|
||||
path.resolve(
|
||||
["gmi-web.css", "web"].includes(options.css)
|
||||
? packageRoot("gmi-web.css")
|
||||
: ["gmi.css", "gmi"].includes(options.css)
|
||||
? packageRoot("gmi.css")
|
||||
["gmi-web.css", "gmi.css"].includes(options.css)
|
||||
? internal(options.css)
|
||||
: resolve(options.css)
|
||||
),
|
||||
"utf-8"
|
||||
)
|
||||
).stylesheet.rules
|
||||
).stylesheet.rules;
|
||||
} else {
|
||||
throw new Error(`Cannot find file ${options.css}.`);
|
||||
}
|
||||
|
@ -77,21 +74,55 @@ function reduceVariables(rules, options) {
|
|||
const defaultVariables = rootVariables(rules);
|
||||
const CSS_VAR = /(^var\((?<key>.+)\)|(?<val>.+))/;
|
||||
return rules
|
||||
.filter(({ selectors }) => selectors && !selectors.includes(":root"))
|
||||
.map((rule) => {
|
||||
return Object.assign(rule, {
|
||||
.map((rule) =>
|
||||
Object.assign(
|
||||
rule,
|
||||
rule.declarations
|
||||
? {
|
||||
declarations: rule.declarations.map((declaration) => {
|
||||
let { key, val } = CSS_VAR.exec(declaration.value).groups;
|
||||
// only one level of variable referencing is supported
|
||||
key =
|
||||
CSS_VAR.exec(options[key] || defaultVariables[key]).groups.key ||
|
||||
key;
|
||||
CSS_VAR.exec(options[key] || defaultVariables[key]).groups
|
||||
.key || key;
|
||||
return Object.assign(declaration, {
|
||||
value: key
|
||||
? options[key] || defaultVariables[key]
|
||||
: declaration.value,
|
||||
});
|
||||
}),
|
||||
}
|
||||
: {}
|
||||
)
|
||||
)
|
||||
.map((rule) => {
|
||||
if (!rule.media) return rule;
|
||||
return Object.assign(rule, {
|
||||
rules: rule.rules.map((rule) =>
|
||||
Object.assign(
|
||||
rule,
|
||||
rule.declarations
|
||||
? {
|
||||
declarations: rule.declarations.map((declaration) => {
|
||||
let { key, val } = CSS_VAR.exec(declaration.value).groups;
|
||||
// only one level of variable referencing is supported
|
||||
key =
|
||||
CSS_VAR.exec(options[key] || defaultVariables[key]).groups
|
||||
.key || key;
|
||||
return Object.assign(declaration, {
|
||||
value: key
|
||||
? options[key] || defaultVariables[key]
|
||||
: declaration.value,
|
||||
});
|
||||
}),
|
||||
}
|
||||
: {}
|
||||
)
|
||||
),
|
||||
});
|
||||
})
|
||||
.filter(
|
||||
({ selectors, media }) =>
|
||||
media || (selectors && !selectors.includes(":root"))
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,20 +30,21 @@ fashion!
|
|||
file as the description <meta> tag. _LIMIT_ may be used to truncate the text
|
||||
with an ellipsis at that number of characters.
|
||||
|
||||
*--css* _MODE_ | _FILE_
|
||||
*--html* will default _MODE_ to *web* enabling a handful of font and color
|
||||
variables. See *--help* for the complete list.
|
||||
*--css* _FILE_
|
||||
*--body* will default to the internal *gmi.css* and use just what is needed
|
||||
to fix CSS Normal Flow quirks.
|
||||
|
||||
*--body* will default _MODE_ to *gmi* and use just what is needed to fix
|
||||
CSS Normal Flow quirks.
|
||||
*--html* will default to the internal *gmi-web.css* enabling a handful of font
|
||||
and color variables. See *--help* for the complete list.
|
||||
|
||||
Pointing to a CSS _FILE_ will use those styles. This works with *--body* or
|
||||
*--inline* and auto-detects the need for the <meta> color-schemes.
|
||||
Pointing to a CSS _FILE_ will use those styles _and_ variables. This works
|
||||
with *--body* or *--inline* and auto-detects the need for the <meta>
|
||||
color-schemes.
|
||||
|
||||
*--inline* will insert the declarations as "style" properties on their
|
||||
respective blocks. This is the only behavior when using *--body*.
|
||||
|
||||
Choosing _MODE_ *none* will not include any style information.
|
||||
Using *none* will not include any style information.
|
||||
|
||||
*--image | --audio | --video* _EXTENSIONS_
|
||||
Include media extensions inline. You can provide multiple extensions per flag
|
||||
|
|
7
html.js
7
html.js
|
@ -95,7 +95,6 @@ export function body(tokens, options) {
|
|||
|
||||
export function toHTML(gemtext, options) {
|
||||
const tokens = tokenize(gemtext);
|
||||
options.inlineCSS = CSS.inline(options);
|
||||
|
||||
if (options.body) return body(tokens, options);
|
||||
|
||||
|
@ -119,9 +118,9 @@ ${body(tokens, options)}
|
|||
export function head(options) {
|
||||
return `
|
||||
<meta charset="${options.charset}">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">${CSS.style(
|
||||
options
|
||||
)}
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">${
|
||||
options.styleTag
|
||||
}
|
||||
<title>${options.title}</title>${
|
||||
!options.author ? "" : `\n<meta name="author" content="${options.author}">`
|
||||
}${
|
||||
|
|
Loading…
Reference in a new issue