inline scripts
This commit is contained in:
parent
894c7ff4e7
commit
7b5df46f1c
12
package-lock.json
generated
12
package-lock.json
generated
@ -13,6 +13,7 @@
|
|||||||
"@napi-rs/simple-git": "^0.1.8",
|
"@napi-rs/simple-git": "^0.1.8",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"cli-spinner": "^0.2.10",
|
"cli-spinner": "^0.2.10",
|
||||||
|
"env-paths": "^3.0.0",
|
||||||
"esbuild-sass-plugin": "^2.9.0",
|
"esbuild-sass-plugin": "^2.9.0",
|
||||||
"github-slugger": "^2.0.0",
|
"github-slugger": "^2.0.0",
|
||||||
"globby": "^13.1.4",
|
"globby": "^13.1.4",
|
||||||
@ -1346,6 +1347,17 @@
|
|||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/env-paths": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.17.19",
|
"version": "0.17.19",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"@napi-rs/simple-git": "^0.1.8",
|
"@napi-rs/simple-git": "^0.1.8",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"cli-spinner": "^0.2.10",
|
"cli-spinner": "^0.2.10",
|
||||||
|
"env-paths": "^3.0.0",
|
||||||
"esbuild-sass-plugin": "^2.9.0",
|
"esbuild-sass-plugin": "^2.9.0",
|
||||||
"github-slugger": "^2.0.0",
|
"github-slugger": "^2.0.0",
|
||||||
"globby": "^13.1.4",
|
"globby": "^13.1.4",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import { readFileSync } from 'fs'
|
import { promises, readFileSync } from 'fs'
|
||||||
import yargs from 'yargs'
|
import yargs from 'yargs'
|
||||||
|
import path from 'path'
|
||||||
import { hideBin } from 'yargs/helpers'
|
import { hideBin } from 'yargs/helpers'
|
||||||
import esbuild from 'esbuild'
|
import esbuild from 'esbuild'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
@ -61,9 +62,34 @@ yargs(hideBin(process.argv))
|
|||||||
jsx: "automatic",
|
jsx: "automatic",
|
||||||
jsxImportSource: "preact",
|
jsxImportSource: "preact",
|
||||||
external: ["@napi-rs/simple-git", "shiki"],
|
external: ["@napi-rs/simple-git", "shiki"],
|
||||||
plugins: [sassPlugin({
|
plugins: [
|
||||||
type: 'css-text'
|
sassPlugin({
|
||||||
})]
|
type: 'css-text'
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: 'inline-script-loader',
|
||||||
|
setup(build) {
|
||||||
|
build.onLoad({ filter: /\.inline\.(ts|js)$/ }, async (args) => {
|
||||||
|
let text = await promises.readFile(args.path, 'utf8')
|
||||||
|
const transpiled = await esbuild.build({
|
||||||
|
stdin: {
|
||||||
|
contents: text,
|
||||||
|
sourcefile: path.relative(path.resolve('.'), args.path),
|
||||||
|
},
|
||||||
|
write: false,
|
||||||
|
bundle: true,
|
||||||
|
platform: "browser",
|
||||||
|
format: "esm",
|
||||||
|
})
|
||||||
|
const rawMod = transpiled.outputFiles[0].text
|
||||||
|
return {
|
||||||
|
contents: rawMod,
|
||||||
|
loader: 'text',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(`${chalk.red("Couldn't parse Quartz configuration:")} ${fp}`)
|
console.error(`${chalk.red("Couldn't parse Quartz configuration:")} ${fp}`)
|
||||||
console.log(`Reason: ${chalk.grey(err)}`)
|
console.log(`Reason: ${chalk.grey(err)}`)
|
||||||
|
@ -8,10 +8,9 @@ export interface HeadProps {
|
|||||||
externalResources: StaticResources
|
externalResources: StaticResources
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function({ title, description, slug, externalResources }: HeadProps) {
|
export function Component({ title, description, slug, externalResources }: HeadProps) {
|
||||||
const { css, js } = externalResources
|
const { css, js } = externalResources
|
||||||
const baseDir = resolveToRoot(slug)
|
const baseDir = resolveToRoot(slug)
|
||||||
const stylePath = baseDir + "/index.css"
|
|
||||||
const iconPath = baseDir + "/static/icon.png"
|
const iconPath = baseDir + "/static/icon.png"
|
||||||
const ogImagePath = baseDir + "/static/og-image.png"
|
const ogImagePath = baseDir + "/static/og-image.png"
|
||||||
return <head>
|
return <head>
|
||||||
@ -28,16 +27,7 @@ export default function({ title, description, slug, externalResources }: HeadPro
|
|||||||
<meta name="generator" content="Quartz" />
|
<meta name="generator" content="Quartz" />
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||||
<link rel="stylesheet" type="text/css" href={stylePath} />
|
|
||||||
{css.map(href => <link key={href} href={href} rel="stylesheet" type="text/css" />)}
|
{css.map(href => <link key={href} href={href} rel="stylesheet" type="text/css" />)}
|
||||||
{js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource => <script key={resource.src} src={resource.src} />)}
|
{js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource => <script key={resource.src} {...resource} />)}
|
||||||
</head>
|
</head>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function beforeDOMLoaded() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export function onDOMLoaded() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -5,10 +5,10 @@ export interface HeaderProps {
|
|||||||
slug: string
|
slug: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function({ title, slug }: HeaderProps) {
|
export function Component({ title, slug }: HeaderProps) {
|
||||||
const baseDir = resolveToRoot(slug)
|
const baseDir = resolveToRoot(slug)
|
||||||
return <header>
|
return <header>
|
||||||
<h1><a href={baseDir}>{title}</a></h1>
|
<h1><a href={baseDir}>{title}</a></h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
quartz/components/scripts/darkmode.inline.ts
Normal file
3
quartz/components/scripts/darkmode.inline.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default "Darkmode"
|
||||||
|
|
||||||
|
console.log("HELLOOOO FROM CONSOLE")
|
8
quartz/components/types.ts
Normal file
8
quartz/components/types.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { ComponentType } from "preact"
|
||||||
|
|
||||||
|
export type QuartzComponent<Props> = {
|
||||||
|
Component: ComponentType<Props>
|
||||||
|
css?: string,
|
||||||
|
beforeDOMLoaded?: string,
|
||||||
|
afterDOMLoaded?: string,
|
||||||
|
}
|
@ -60,7 +60,7 @@ export function buildQuartz(cfg: QuartzConfig) {
|
|||||||
const parsedFiles = await parseMarkdown(processor, argv.directory, filePaths, argv.verbose)
|
const parsedFiles = await parseMarkdown(processor, argv.directory, filePaths, argv.verbose)
|
||||||
const filteredContent = filterContent(cfg.plugins.filters, parsedFiles, argv.verbose)
|
const filteredContent = filterContent(cfg.plugins.filters, parsedFiles, argv.verbose)
|
||||||
await emitContent(argv.directory, output, cfg, filteredContent, argv.verbose)
|
await emitContent(argv.directory, output, cfg, filteredContent, argv.verbose)
|
||||||
console.log(chalk.green(`Done in ${perf.timeSince()}`))
|
console.log(chalk.green(`Done processing ${fps.length} files in ${perf.timeSince()}`))
|
||||||
|
|
||||||
if (argv.serve) {
|
if (argv.serve) {
|
||||||
const server = http.createServer(async (req, res) => {
|
const server = http.createServer(async (req, res) => {
|
||||||
|
@ -22,11 +22,15 @@ export function slugify(s: string): string {
|
|||||||
// resolve /a/b/c to ../../
|
// resolve /a/b/c to ../../
|
||||||
export function resolveToRoot(slug: string): string {
|
export function resolveToRoot(slug: string): string {
|
||||||
let fp = slug
|
let fp = slug
|
||||||
if (fp.endsWith("/index")) {
|
if (fp.endsWith("index")) {
|
||||||
fp = fp.slice(0, -"/index".length)
|
fp = fp.slice(0, -"index".length)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fp
|
if (fp === "") {
|
||||||
|
return "."
|
||||||
|
}
|
||||||
|
|
||||||
|
return "./" + fp
|
||||||
.split('/')
|
.split('/')
|
||||||
.filter(x => x !== '')
|
.filter(x => x !== '')
|
||||||
.map(_ => '..')
|
.map(_ => '..')
|
||||||
|
@ -4,17 +4,15 @@ import { EmitCallback, QuartzEmitterPlugin } from "../types"
|
|||||||
import { ProcessedContent } from "../vfile"
|
import { ProcessedContent } from "../vfile"
|
||||||
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
|
import { Fragment, jsx, jsxs } from 'preact/jsx-runtime'
|
||||||
import { render } from "preact-render-to-string"
|
import { render } from "preact-render-to-string"
|
||||||
import { ComponentType } from "preact"
|
|
||||||
import { HeadProps } from "../../components/Head"
|
import { HeadProps } from "../../components/Head"
|
||||||
import { googleFontHref, templateThemeStyles } from "../../theme"
|
|
||||||
import { GlobalConfiguration } from "../../cfg"
|
import { GlobalConfiguration } from "../../cfg"
|
||||||
import { HeaderProps } from "../../components/Header"
|
import { HeaderProps } from "../../components/Header"
|
||||||
|
import { QuartzComponent } from "../../components/types"
|
||||||
import styles from '../../styles/base.scss'
|
import { resolveToRoot } from "../../path"
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
Head: ComponentType<HeadProps>
|
Head: QuartzComponent<HeadProps>
|
||||||
Header: ComponentType<HeaderProps>
|
Header: QuartzComponent<HeaderProps>
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ContentPage extends QuartzEmitterPlugin {
|
export class ContentPage extends QuartzEmitterPlugin {
|
||||||
@ -26,40 +24,45 @@ export class ContentPage extends QuartzEmitterPlugin {
|
|||||||
this.opts = opts
|
this.opts = opts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getQuartzComponents(): QuartzComponent<any>[] {
|
||||||
|
return [...Object.values(this.opts)]
|
||||||
|
}
|
||||||
|
|
||||||
async emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emit: EmitCallback): Promise<string[]> {
|
async emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emit: EmitCallback): Promise<string[]> {
|
||||||
const fps: string[] = []
|
const fps: string[] = []
|
||||||
|
|
||||||
// emit styles
|
const { Head, Header } = this.opts
|
||||||
emit({
|
|
||||||
slug: "index",
|
|
||||||
ext: ".css",
|
|
||||||
content: templateThemeStyles(cfg.theme, styles)
|
|
||||||
})
|
|
||||||
fps.push("index.css")
|
|
||||||
resources.css.push(googleFontHref(cfg.theme))
|
|
||||||
|
|
||||||
for (const [tree, file] of content) {
|
for (const [tree, file] of content) {
|
||||||
// @ts-ignore (preact makes it angry)
|
// @ts-ignore (preact makes it angry)
|
||||||
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
|
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
|
||||||
|
|
||||||
|
const baseDir = resolveToRoot(file.data.slug!)
|
||||||
|
const pageResources: StaticResources = {
|
||||||
|
css: [baseDir + "/index.css", ...resources.css,],
|
||||||
|
js: [
|
||||||
|
{ src: baseDir + "/prescript.js", loadTime: "beforeDOMReady", type: 'module' },
|
||||||
|
...resources.js,
|
||||||
|
{ src: baseDir + "/postscript.js", loadTime: "afterDOMReady", type: 'module' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
const title = file.data.frontmatter?.title
|
const title = file.data.frontmatter?.title
|
||||||
const { Head, Header } = this.opts
|
|
||||||
const doc = <html>
|
const doc = <html>
|
||||||
<Head
|
<Head.Component
|
||||||
title={title ?? "Untitled"}
|
title={title ?? "Untitled"}
|
||||||
description={file.data.description ?? "No description provided"}
|
description={file.data.description ?? "No description provided"}
|
||||||
slug={file.data.slug!}
|
slug={file.data.slug!}
|
||||||
externalResources={resources} />
|
externalResources={pageResources} />
|
||||||
<body>
|
<body>
|
||||||
<div id="quartz-root" class="page">
|
<div id="quartz-root" class="page">
|
||||||
<Header title={cfg.siteTitle} slug={file.data.slug!} />
|
<Header.Component title={cfg.siteTitle} slug={file.data.slug!} />
|
||||||
<article>
|
<article>
|
||||||
{file.data.slug !== "index" && <h1>{title}</h1>}
|
{file.data.slug !== "index" && <h1>{title}</h1>}
|
||||||
{content}
|
{content}
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
{resources.js.filter(resource => resource.loadTime === "afterDOMReady").map(resource => <script key={resource.src} src={resource.src} />)}
|
{pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(resource => <script key={resource.src} {...resource} />)}
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
const fp = file.data.slug + ".html"
|
const fp = file.data.slug + ".html"
|
||||||
|
@ -1,5 +1,69 @@
|
|||||||
|
import { GlobalConfiguration } from '../cfg'
|
||||||
|
import { QuartzComponent } from '../components/types'
|
||||||
import { StaticResources } from '../resources'
|
import { StaticResources } from '../resources'
|
||||||
import { PluginTypes } from './types'
|
import { googleFontHref, joinStyles } from '../theme'
|
||||||
|
import { EmitCallback, PluginTypes } from './types'
|
||||||
|
import styles from '../styles/base.scss'
|
||||||
|
|
||||||
|
export type ComponentResources = {
|
||||||
|
css: string[],
|
||||||
|
beforeDOMLoaded: string[],
|
||||||
|
afterDOMLoaded: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
function joinScripts(scripts: string[]): string {
|
||||||
|
return scripts.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
export function emitComponentResources(cfg: GlobalConfiguration, resources: StaticResources, plugins: PluginTypes, emit: EmitCallback) {
|
||||||
|
const fps: string[] = []
|
||||||
|
const allComponents: Set<QuartzComponent<any>> = new Set()
|
||||||
|
for (const emitter of plugins.emitters) {
|
||||||
|
const components = emitter.getQuartzComponents()
|
||||||
|
for (const component of components) {
|
||||||
|
allComponents.add(component)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const componentResources: ComponentResources = {
|
||||||
|
css: [],
|
||||||
|
beforeDOMLoaded: [],
|
||||||
|
afterDOMLoaded: []
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const component of allComponents) {
|
||||||
|
const { css, beforeDOMLoaded, afterDOMLoaded } = component
|
||||||
|
if (css) {
|
||||||
|
componentResources.css.push(css)
|
||||||
|
}
|
||||||
|
if (beforeDOMLoaded) {
|
||||||
|
componentResources.beforeDOMLoaded.push(beforeDOMLoaded)
|
||||||
|
}
|
||||||
|
if (afterDOMLoaded) {
|
||||||
|
componentResources.beforeDOMLoaded.push(afterDOMLoaded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit({
|
||||||
|
slug: "index",
|
||||||
|
ext: ".css",
|
||||||
|
content: joinStyles(cfg.theme, styles, ...componentResources.css)
|
||||||
|
})
|
||||||
|
emit({
|
||||||
|
slug: "prescript",
|
||||||
|
ext: ".js",
|
||||||
|
content: joinScripts(componentResources.beforeDOMLoaded)
|
||||||
|
})
|
||||||
|
emit({
|
||||||
|
slug: "postscript",
|
||||||
|
ext: ".js",
|
||||||
|
content: joinScripts(componentResources.afterDOMLoaded)
|
||||||
|
})
|
||||||
|
|
||||||
|
fps.push("index.css", "prescript.js", "postscript.js")
|
||||||
|
resources.css.push(googleFontHref(cfg.theme))
|
||||||
|
return fps
|
||||||
|
}
|
||||||
|
|
||||||
export function getStaticResourcesFromPlugins(plugins: PluginTypes) {
|
export function getStaticResourcesFromPlugins(plugins: PluginTypes) {
|
||||||
const staticResources: StaticResources = {
|
const staticResources: StaticResources = {
|
||||||
@ -7,8 +71,8 @@ export function getStaticResourcesFromPlugins(plugins: PluginTypes) {
|
|||||||
js: [],
|
js: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const plugin of plugins.transformers) {
|
for (const transformer of plugins.transformers) {
|
||||||
const res = plugin.externalResources
|
const res = transformer.externalResources
|
||||||
if (res?.js) {
|
if (res?.js) {
|
||||||
staticResources.js = staticResources.js.concat(res.js)
|
staticResources.js = staticResources.js.concat(res.js)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ export interface Options {
|
|||||||
|
|
||||||
const defaultOptions: Options = {
|
const defaultOptions: Options = {
|
||||||
highlight: true,
|
highlight: true,
|
||||||
wikilinks: true
|
wikilinks: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ObsidianFlavoredMarkdown extends QuartzTransformerPlugin {
|
export class ObsidianFlavoredMarkdown extends QuartzTransformerPlugin {
|
||||||
@ -39,10 +39,10 @@ export class ObsidianFlavoredMarkdown extends QuartzTransformerPlugin {
|
|||||||
return (tree: Root, _file) => {
|
return (tree: Root, _file) => {
|
||||||
findAndReplace(tree, backlinkRegex, (value: string, ...capture: string[]) => {
|
findAndReplace(tree, backlinkRegex, (value: string, ...capture: string[]) => {
|
||||||
if (value.startsWith("!")) {
|
if (value.startsWith("!")) {
|
||||||
|
// TODO: handle embeds
|
||||||
} else {
|
} else {
|
||||||
const [path, rawHeader, rawAlias] = capture
|
const [path, rawHeader, rawAlias] = capture
|
||||||
const anchor = rawHeader?.slice(1).trim() ?? ""
|
const anchor = rawHeader?.trim() ?? ""
|
||||||
const alias = rawAlias?.slice(1).trim() ?? path
|
const alias = rawAlias?.slice(1).trim() ?? path
|
||||||
const url = slugify(path.trim() + anchor)
|
const url = slugify(path.trim() + anchor)
|
||||||
return {
|
return {
|
||||||
|
@ -2,6 +2,7 @@ import { PluggableList } from "unified"
|
|||||||
import { StaticResources } from "../resources"
|
import { StaticResources } from "../resources"
|
||||||
import { ProcessedContent } from "./vfile"
|
import { ProcessedContent } from "./vfile"
|
||||||
import { GlobalConfiguration } from "../cfg"
|
import { GlobalConfiguration } from "../cfg"
|
||||||
|
import { QuartzComponent } from "../components/types"
|
||||||
|
|
||||||
export abstract class QuartzTransformerPlugin {
|
export abstract class QuartzTransformerPlugin {
|
||||||
abstract name: string
|
abstract name: string
|
||||||
@ -25,6 +26,7 @@ export type EmitCallback = (data: EmitOptions) => Promise<string>
|
|||||||
export abstract class QuartzEmitterPlugin {
|
export abstract class QuartzEmitterPlugin {
|
||||||
abstract name: string
|
abstract name: string
|
||||||
abstract emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emitCallback: EmitCallback): Promise<string[]>
|
abstract emit(cfg: GlobalConfiguration, content: ProcessedContent[], resources: StaticResources, emitCallback: EmitCallback): Promise<string[]>
|
||||||
|
abstract getQuartzComponents(): QuartzComponent<any>[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginTypes {
|
export interface PluginTypes {
|
||||||
|
@ -2,7 +2,7 @@ import path from "path"
|
|||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import { QuartzConfig } from "../cfg"
|
import { QuartzConfig } from "../cfg"
|
||||||
import { PerfTimer } from "../perf"
|
import { PerfTimer } from "../perf"
|
||||||
import { getStaticResourcesFromPlugins } from "../plugins"
|
import { emitComponentResources, getStaticResourcesFromPlugins } from "../plugins"
|
||||||
import { EmitCallback } from "../plugins/types"
|
import { EmitCallback } from "../plugins/types"
|
||||||
import { ProcessedContent } from "../plugins/vfile"
|
import { ProcessedContent } from "../plugins/vfile"
|
||||||
import { QUARTZ, slugify } from "../path"
|
import { QUARTZ, slugify } from "../path"
|
||||||
@ -10,9 +10,6 @@ import { globbyStream } from "globby"
|
|||||||
|
|
||||||
export async function emitContent(contentFolder: string, output: string, cfg: QuartzConfig, content: ProcessedContent[], verbose: boolean) {
|
export async function emitContent(contentFolder: string, output: string, cfg: QuartzConfig, content: ProcessedContent[], verbose: boolean) {
|
||||||
const perf = new PerfTimer()
|
const perf = new PerfTimer()
|
||||||
|
|
||||||
|
|
||||||
const staticResources = getStaticResourcesFromPlugins(cfg.plugins)
|
|
||||||
const emit: EmitCallback = async ({ slug, ext, content }) => {
|
const emit: EmitCallback = async ({ slug, ext, content }) => {
|
||||||
const pathToPage = path.join(output, slug + ext)
|
const pathToPage = path.join(output, slug + ext)
|
||||||
const dir = path.dirname(pathToPage)
|
const dir = path.dirname(pathToPage)
|
||||||
@ -21,6 +18,9 @@ export async function emitContent(contentFolder: string, output: string, cfg: Qu
|
|||||||
return pathToPage
|
return pathToPage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const staticResources = getStaticResourcesFromPlugins(cfg.plugins)
|
||||||
|
emitComponentResources(cfg.configuration, staticResources, cfg.plugins, emit)
|
||||||
|
|
||||||
let emittedFiles = 0
|
let emittedFiles = 0
|
||||||
for (const emitter of cfg.plugins.emitters) {
|
for (const emitter of cfg.plugins.emitters) {
|
||||||
const emitted = await emitter.emit(cfg.configuration, content, staticResources, emit)
|
const emitted = await emitter.emit(cfg.configuration, content, staticResources, emit)
|
||||||
@ -35,6 +35,9 @@ export async function emitContent(contentFolder: string, output: string, cfg: Qu
|
|||||||
|
|
||||||
const staticPath = path.join(QUARTZ, "static")
|
const staticPath = path.join(QUARTZ, "static")
|
||||||
await fs.promises.cp(staticPath, path.join(output, "static"), { recursive: true })
|
await fs.promises.cp(staticPath, path.join(output, "static"), { recursive: true })
|
||||||
|
if (verbose) {
|
||||||
|
console.log(`[emit:Static] ${path.join(output, "static", "**")}`)
|
||||||
|
}
|
||||||
|
|
||||||
// glob all non MD/MDX/HTML files in content folder and copy it over
|
// glob all non MD/MDX/HTML files in content folder and copy it over
|
||||||
const assetsPath = path.join("public", "assets")
|
const assetsPath = path.join("public", "assets")
|
||||||
@ -54,8 +57,5 @@ export async function emitContent(contentFolder: string, output: string, cfg: Qu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
console.log(`Emitted ${emittedFiles} files to \`${output}\` in ${perf.timeSince()}`)
|
||||||
console.log(`[emit:Static] ${path.join(output, "static", "**")}`)
|
|
||||||
console.log(`Emitted ${emittedFiles} files to \`${output}\` in ${perf.timeSince()}`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,18 @@ export function filterContent(plugins: QuartzFilterPlugin[], content: ProcessedC
|
|||||||
const perf = new PerfTimer()
|
const perf = new PerfTimer()
|
||||||
const initialLength = content.length
|
const initialLength = content.length
|
||||||
for (const plugin of plugins) {
|
for (const plugin of plugins) {
|
||||||
content = content.filter(plugin.shouldPublish)
|
const updatedContent = content.filter(plugin.shouldPublish)
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
const diff = content.filter(x => !updatedContent.includes(x))
|
||||||
|
for (const file of diff) {
|
||||||
|
console.log(`[filter:${plugin.name}] ${file[1].data.slug}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content = updatedContent
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
console.log(`Filtered out ${initialLength - content.length} files in ${perf.timeSince()}`)
|
||||||
console.log(`Filtered out ${initialLength - content.length} files in ${perf.timeSince()}`)
|
|
||||||
}
|
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,6 @@ export async function parseMarkdown(processor: QuartzProcessor, baseDir: string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
console.log(`Parsed and transformed ${res.length} Markdown files in ${perf.timeSince()}`)
|
||||||
console.log(`Parsed and transformed ${res.length} Markdown files in ${perf.timeSince()}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export interface JSResource {
|
export interface JSResource {
|
||||||
src: string
|
src: string
|
||||||
loadTime: 'beforeDOMReady' | 'afterDOMReady'
|
loadTime: 'beforeDOMReady' | 'afterDOMReady'
|
||||||
|
type?: 'module'
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StaticResources {
|
export interface StaticResources {
|
||||||
|
@ -98,6 +98,8 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
margin: 0 0.5rem;
|
margin: 0 0.5rem;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.2s ease;
|
transition: opacity 0.2s ease;
|
||||||
|
transform: translateY(-0.1rem);
|
||||||
|
display: inline-block;
|
||||||
font-family: var(--codeFont);
|
font-family: var(--codeFont);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,8 @@ export function googleFontHref(theme: Theme) {
|
|||||||
return `https://fonts.googleapis.com/css2?family=${code}&family=${header}:wght@400;700&family=${body}:ital,wght@0,400;0,600;1,400;1,600&display=swap`
|
return `https://fonts.googleapis.com/css2?family=${code}&family=${header}:wght@400;700&family=${body}:ital,wght@0,400;0,600;1,400;1,600&display=swap`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function templateThemeStyles(theme: Theme, stylesheet: string) {
|
export function joinStyles(theme: Theme, ...stylesheet: string[]) {
|
||||||
return `
|
return `:root {
|
||||||
:root {
|
|
||||||
--light: ${theme.colors.lightMode.light};
|
--light: ${theme.colors.lightMode.light};
|
||||||
--lightgray: ${theme.colors.lightMode.lightgray};
|
--lightgray: ${theme.colors.lightMode.lightgray};
|
||||||
--gray: ${theme.colors.lightMode.gray};
|
--gray: ${theme.colors.lightMode.gray};
|
||||||
@ -54,6 +53,5 @@ export function templateThemeStyles(theme: Theme, stylesheet: string) {
|
|||||||
--highlight: ${theme.colors.darkMode.highlight};
|
--highlight: ${theme.colors.darkMode.highlight};
|
||||||
}
|
}
|
||||||
|
|
||||||
${stylesheet}
|
${stylesheet.join("\n\n")}`
|
||||||
`
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user