docs + various polish
This commit is contained in:
@ -54,21 +54,16 @@ export default async function buildQuartz(argv: Argv, version: string) {
|
||||
|
||||
if (argv.serve) {
|
||||
const server = http.createServer(async (req, res) => {
|
||||
let status = 200
|
||||
const result = await serveHandler(req, res, {
|
||||
await serveHandler(req, res, {
|
||||
public: output,
|
||||
directoryListing: false,
|
||||
}, {
|
||||
async sendError() {
|
||||
status = 404
|
||||
},
|
||||
})
|
||||
const status = res.statusCode
|
||||
const statusString = status === 200 ? chalk.green(`[${status}]`) : chalk.red(`[${status}]`)
|
||||
console.log(statusString + chalk.grey(` ${req.url}`))
|
||||
return result
|
||||
})
|
||||
server.listen(argv.port)
|
||||
console.log(`Started a Quartz server listening at http://localhost:${argv.port}`)
|
||||
console.log(chalk.cyan(`Started a Quartz server listening at http://localhost:${argv.port}`))
|
||||
console.log('hint: exit with ctrl+c')
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ import { QuartzComponent } from "./components/types"
|
||||
import { PluginTypes } from "./plugins/types"
|
||||
import { Theme } from "./theme"
|
||||
|
||||
export type Analytics = null
|
||||
export type Analytics =
|
||||
| null
|
||||
| {
|
||||
provider: 'plausible'
|
||||
}
|
||||
@ -18,7 +19,7 @@ export interface GlobalConfiguration {
|
||||
/** Whether to display Wikipedia-style popovers when hovering over links */
|
||||
enablePopovers: boolean,
|
||||
/** Analytics mode */
|
||||
analytics: Analytics
|
||||
analytics: Analytics
|
||||
/** Glob patterns to not search */
|
||||
ignorePatterns: string[],
|
||||
/** Base URL to use for CNAME files, sitemaps, and RSS feeds that require an absolute URL.
|
||||
|
@ -1,19 +1,18 @@
|
||||
import { QuartzComponentConstructor } from "./types"
|
||||
import style from "./styles/footer.scss"
|
||||
import {version} from "../../package.json"
|
||||
|
||||
interface Options {
|
||||
authorName: string,
|
||||
links: Record<string, string>
|
||||
}
|
||||
|
||||
export default ((opts?: Options) => {
|
||||
function Footer() {
|
||||
const year = new Date().getFullYear()
|
||||
const name = opts?.authorName ?? "someone"
|
||||
const links = opts?.links ?? []
|
||||
return <footer>
|
||||
<hr />
|
||||
<p>Made by {name} using <a href="https://quartz.jzhao.xyz/">Quartz</a>, © {year}</p>
|
||||
<p>Created with <a href="https://quartz.jzhao.xyz/">Quartz v{version}</a>, © {year}</p>
|
||||
<ul>{Object.entries(links).map(([text, link]) => <li>
|
||||
<a href={link}>{text}</a>
|
||||
</li>)}</ul>
|
||||
|
@ -16,7 +16,7 @@ export interface D3Config {
|
||||
}
|
||||
|
||||
interface GraphOptions {
|
||||
localGraph: Partial<D3Config>,
|
||||
localGraph: Partial<D3Config> | undefined,
|
||||
globalGraph: Partial<D3Config> | undefined
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ export default ((opts?: GraphOptions) => {
|
||||
const localGraph = { ...opts?.localGraph, ...defaultOptions.localGraph }
|
||||
const globalGraph = { ...opts?.globalGraph, ...defaultOptions.globalGraph }
|
||||
return <div class="graph">
|
||||
<h3>Site Graph</h3>
|
||||
<h3>Graph View</h3>
|
||||
<div class="graph-outer">
|
||||
<div id="graph-container" data-cfg={JSON.stringify(localGraph)}></div>
|
||||
<svg version="1.1" id="global-graph-icon" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
|
@ -5,10 +5,11 @@ import path from "path"
|
||||
|
||||
import style from '../styles/listPage.scss'
|
||||
import { PageList } from "../PageList"
|
||||
import { clientSideSlug } from "../../path"
|
||||
|
||||
function FolderContent(props: QuartzComponentProps) {
|
||||
const { tree, fileData, allFiles } = props
|
||||
const folderSlug = fileData.slug!
|
||||
const folderSlug = clientSideSlug(fileData.slug!)
|
||||
const allPagesInFolder = allFiles.filter(file => {
|
||||
const fileSlug = file.slug ?? ""
|
||||
const prefixed = fileSlug.startsWith(folderSlug)
|
||||
@ -23,12 +24,9 @@ function FolderContent(props: QuartzComponentProps) {
|
||||
allFiles: allPagesInFolder
|
||||
}
|
||||
|
||||
const desc = props.fileData.description
|
||||
|
||||
// @ts-ignore
|
||||
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
|
||||
return <div class="popover-hint">
|
||||
{desc && <p>{desc}</p>}
|
||||
<article>{content}</article>
|
||||
<p>{allPagesInFolder.length} items under this folder.</p>
|
||||
<div>
|
||||
|
@ -17,12 +17,9 @@ function TagContent(props: QuartzComponentProps) {
|
||||
allFiles: allPagesWithTag
|
||||
}
|
||||
|
||||
const desc = props.fileData.description
|
||||
|
||||
// @ts-ignore
|
||||
const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' })
|
||||
return <div class="popover-hint">
|
||||
{desc && <p>{desc}</p>}
|
||||
<article>{content}</article>
|
||||
<p>{allPagesWithTag.length} items with this tag.</p>
|
||||
<div>
|
||||
|
@ -72,7 +72,7 @@ async function renderGraph(container: string, slug: string) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
links.flatMap(l => [l.source, l.target]).forEach((id) => neighbourhood.add(id))
|
||||
Object.keys(data).forEach(id => neighbourhood.add(id))
|
||||
}
|
||||
|
||||
const graphData: { nodes: NodeData[], links: LinkData[] } = {
|
||||
|
@ -10,6 +10,7 @@ interface Item {
|
||||
let index: Document<Item> | undefined = undefined
|
||||
|
||||
const contextWindowWords = 30
|
||||
const numSearchResults = 5
|
||||
function highlight(searchTerm: string, text: string, trim?: boolean) {
|
||||
// try to highlight longest tokens first
|
||||
const tokenizedTerms = searchTerm.split(/\s+/).filter(t => t !== "").sort((a, b) => b.length - a.length)
|
||||
@ -134,7 +135,7 @@ document.addEventListener("nav", async (e: unknown) => {
|
||||
|
||||
function onType(e: HTMLElementEventMap["input"]) {
|
||||
const term = (e.target as HTMLInputElement).value
|
||||
const searchResults = index?.search(term, 5) ?? []
|
||||
const searchResults = index?.search(term, numSearchResults) ?? []
|
||||
const getByField = (field: string): string[] => {
|
||||
const results = searchResults.filter((x) => x.field === field)
|
||||
return results.length === 0 ? [] : [...results[0].result] as string[]
|
||||
|
@ -1,6 +1,7 @@
|
||||
footer {
|
||||
text-align: left;
|
||||
margin-bottom: 4rem;
|
||||
opacity: 0.7;
|
||||
|
||||
& ul {
|
||||
list-style: none;
|
||||
|
@ -1,3 +1,5 @@
|
||||
@use "../../styles/variables.scss" as *;
|
||||
|
||||
.graph {
|
||||
& > h3 {
|
||||
font-size: 1rem;
|
||||
@ -59,6 +61,10 @@
|
||||
transform: translate(-50%, -50%);
|
||||
height: 60vh;
|
||||
width: 50vw;
|
||||
|
||||
@media all and (max-width: $fullPageWidth) {
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@
|
||||
& > .popover-inner {
|
||||
position: relative;
|
||||
width: 30rem;
|
||||
height: 20rem;
|
||||
padding: 0 1rem 1rem 1rem;
|
||||
max-height: 20rem;
|
||||
padding: 0 1rem 2rem 1rem;
|
||||
font-weight: initial;
|
||||
line-height: normal;
|
||||
font-size: initial;
|
||||
|
@ -31,6 +31,10 @@ button#toc {
|
||||
max-height: none;
|
||||
transition: max-height 0.5s ease;
|
||||
|
||||
&.collapsed > .overflow::after {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
& ul {
|
||||
list-style: none;
|
||||
margin: 0.5rem 0;
|
||||
|
@ -100,6 +100,7 @@ declare module 'vfile' {
|
||||
// inserted in processors.ts
|
||||
interface DataMap {
|
||||
slug: string
|
||||
allSlugs: string[]
|
||||
filePath: string
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import matter from "gray-matter"
|
||||
import remarkFrontmatter from 'remark-frontmatter'
|
||||
import { QuartzTransformerPlugin } from "../types"
|
||||
import yaml from 'js-yaml'
|
||||
import { slug as slugAnchor } from 'github-slugger'
|
||||
|
||||
export interface Options {
|
||||
language: 'yaml' | 'toml',
|
||||
@ -29,10 +30,18 @@ export const FrontMatter: QuartzTransformerPlugin<Partial<Options> | undefined>
|
||||
}
|
||||
})
|
||||
|
||||
// tag is an alias for tags
|
||||
if (data.tag) {
|
||||
data.tags = data.tag
|
||||
}
|
||||
|
||||
if (data.tags && !Array.isArray(data.tags)) {
|
||||
data.tags = data.tags.toString().split(",").map((tag: string) => tag.trim())
|
||||
}
|
||||
|
||||
// slug them all!!
|
||||
data.tags = data.tags?.map((tag: string) => slugAnchor(tag)) ?? []
|
||||
|
||||
// fill in frontmatter
|
||||
file.data.frontmatter = {
|
||||
title: file.stem ?? "Untitled",
|
||||
|
@ -1,7 +1,7 @@
|
||||
export { FrontMatter } from './frontmatter'
|
||||
export { GitHubFlavoredMarkdown } from './gfm'
|
||||
export { CreatedModifiedDate } from './lastmod'
|
||||
export { Katex } from './latex'
|
||||
export { Latex } from './latex'
|
||||
export { Description } from './description'
|
||||
export { CrawlLinks } from './links'
|
||||
export { ObsidianFlavoredMarkdown } from './ofm'
|
||||
|
@ -1,33 +1,43 @@
|
||||
import remarkMath from "remark-math"
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
import rehypeMathjax from 'rehype-mathjax/svg.js'
|
||||
import { QuartzTransformerPlugin } from "../types"
|
||||
|
||||
export const Katex: QuartzTransformerPlugin = () => ({
|
||||
name: "Katex",
|
||||
markdownPlugins() {
|
||||
return [remarkMath]
|
||||
},
|
||||
htmlPlugins() {
|
||||
return [
|
||||
[rehypeKatex, {
|
||||
output: 'html',
|
||||
}]
|
||||
]
|
||||
},
|
||||
externalResources() {
|
||||
return {
|
||||
css: [
|
||||
// base css
|
||||
"https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css",
|
||||
],
|
||||
js: [
|
||||
{
|
||||
// fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md
|
||||
src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js",
|
||||
loadTime: "afterDOMReady",
|
||||
contentType: 'external'
|
||||
}
|
||||
interface Options {
|
||||
renderEngine: 'katex' | 'mathjax'
|
||||
}
|
||||
|
||||
export const Latex: QuartzTransformerPlugin<Options> = (opts?: Options) => {
|
||||
const engine = opts?.renderEngine ?? 'katex'
|
||||
return {
|
||||
name: "Latex",
|
||||
markdownPlugins() {
|
||||
return [remarkMath]
|
||||
},
|
||||
htmlPlugins() {
|
||||
return [
|
||||
engine === 'katex'
|
||||
? [rehypeKatex, { output: 'html' }]
|
||||
: [rehypeMathjax]
|
||||
]
|
||||
},
|
||||
externalResources() {
|
||||
return engine === 'katex'
|
||||
? {
|
||||
css: [
|
||||
// base css
|
||||
"https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css",
|
||||
],
|
||||
js: [
|
||||
{
|
||||
// fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md
|
||||
src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js",
|
||||
loadTime: "afterDOMReady",
|
||||
contentType: 'external'
|
||||
}
|
||||
]
|
||||
}
|
||||
: {}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -29,13 +29,30 @@ export const CrawlLinks: QuartzTransformerPlugin<Partial<Options> | undefined> =
|
||||
return (tree, file) => {
|
||||
const curSlug = clientSideSlug(file.data.slug!)
|
||||
const transformLink = (target: string) => {
|
||||
const targetSlug = slugify(decodeURI(target).trim())
|
||||
const targetSlug = clientSideSlug(slugify(decodeURI(target).trim()))
|
||||
if (opts.markdownLinkResolution === 'relative' && !path.isAbsolute(targetSlug)) {
|
||||
return './' + relative(curSlug, targetSlug)
|
||||
} else {
|
||||
return './' + relativeToRoot(curSlug, targetSlug)
|
||||
} else if (opts.markdownLinkResolution === 'shortest') {
|
||||
// https://forum.obsidian.md/t/settings-new-link-format-what-is-shortest-path-when-possible/6748/5
|
||||
const allSlugs = file.data.allSlugs!
|
||||
|
||||
// if the file name is unique, then it's just the filename
|
||||
const matchingFileNames = allSlugs.filter(slug => {
|
||||
const parts = clientSideSlug(slug).split(path.posix.sep)
|
||||
const fileName = parts.at(-1)
|
||||
return targetSlug === fileName
|
||||
})
|
||||
|
||||
if (matchingFileNames.length === 1) {
|
||||
const targetSlug = clientSideSlug(matchingFileNames[0])
|
||||
return './' + relativeToRoot(curSlug, targetSlug)
|
||||
}
|
||||
|
||||
// if it's not unique, then it's the absolute path from the vault root
|
||||
// (fall-through case)
|
||||
}
|
||||
// todo: handle shortest path
|
||||
// treat as absolute
|
||||
return './' + relativeToRoot(curSlug, targetSlug)
|
||||
}
|
||||
|
||||
const outgoing: Set<string> = new Set()
|
||||
@ -53,7 +70,7 @@ export const CrawlLinks: QuartzTransformerPlugin<Partial<Options> | undefined> =
|
||||
if (!(isAbsoluteUrl(dest) || dest.startsWith("#"))) {
|
||||
node.properties.href = transformLink(dest)
|
||||
}
|
||||
|
||||
|
||||
dest = node.properties.href
|
||||
if (dest.startsWith(".")) {
|
||||
const normalizedPath = path.normalize(path.join(curSlug, dest))
|
||||
|
@ -12,6 +12,7 @@ import { JSResource } from "../../resources"
|
||||
import calloutScript from "../../components/scripts/callout.inline.ts"
|
||||
|
||||
export interface Options {
|
||||
comments: boolean
|
||||
highlight: boolean
|
||||
wikilinks: boolean
|
||||
callouts: boolean
|
||||
@ -19,6 +20,7 @@ export interface Options {
|
||||
}
|
||||
|
||||
const defaultOptions: Options = {
|
||||
comments: true,
|
||||
highlight: true,
|
||||
wikilinks: true,
|
||||
callouts: true,
|
||||
@ -101,11 +103,14 @@ const capitalize = (s: string): string => {
|
||||
// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name)
|
||||
// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link)
|
||||
// (|[^\[\]\|\#]+)? -> | then one or more non-special characters (alias)
|
||||
const backlinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g")
|
||||
const wikilinkRegex = new RegExp(/!?\[\[([^\[\]\|\#]+)(#[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/, "g")
|
||||
|
||||
// Match highlights
|
||||
const highlightRegex = new RegExp(/==(.+)==/, "g")
|
||||
|
||||
// Match comments
|
||||
const commentRegex = new RegExp(/%%(.+)%%/, "g")
|
||||
|
||||
// from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts
|
||||
const calloutRegex = new RegExp(/^\[\!(\w+)\]([+-]?)/)
|
||||
|
||||
@ -117,7 +122,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
// pre-transform wikilinks (fix anchors to things that may contain illegal syntax e.g. codeblocks, latex)
|
||||
if (opts.wikilinks) {
|
||||
src = src.toString()
|
||||
return src.replaceAll(backlinkRegex, (value, ...capture) => {
|
||||
return src.replaceAll(wikilinkRegex, (value, ...capture) => {
|
||||
const [fp, rawHeader, rawAlias] = capture
|
||||
const anchor = rawHeader?.trim().slice(1)
|
||||
const displayAnchor = anchor ? `#${slugAnchor(anchor)}` : ""
|
||||
@ -133,7 +138,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
if (opts.wikilinks) {
|
||||
plugins.push(() => {
|
||||
return (tree: Root, _file) => {
|
||||
findAndReplace(tree, backlinkRegex, (value: string, ...capture: string[]) => {
|
||||
findAndReplace(tree, wikilinkRegex, (value: string, ...capture: string[]) => {
|
||||
const [fp, rawHeader, rawAlias] = capture
|
||||
const anchor = rawHeader?.trim() ?? ""
|
||||
const alias = rawAlias?.slice(1).trim()
|
||||
@ -204,6 +209,19 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (opts.comments) {
|
||||
plugins.push(() => {
|
||||
return (tree: Root, _file) => {
|
||||
findAndReplace(tree, commentRegex, (_value: string, ..._capture: string[]) => {
|
||||
return {
|
||||
type: 'text',
|
||||
value: ''
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (opts.callouts) {
|
||||
plugins.push(() => {
|
||||
|
@ -6,19 +6,6 @@ export const SyntaxHighlighting: QuartzTransformerPlugin = () => ({
|
||||
htmlPlugins() {
|
||||
return [[rehypePrettyCode, {
|
||||
theme: 'css-variables',
|
||||
onVisitLine(node) {
|
||||
if (node.children.length === 0) {
|
||||
node.children = [{ type: 'text', value: ' ' }]
|
||||
}
|
||||
},
|
||||
onVisitHighlightedLine(node) {
|
||||
node.properties.className ??= []
|
||||
node.properties.className.push('highlighted')
|
||||
},
|
||||
onVisitHighlightedWord(node) {
|
||||
node.properties.className ??= []
|
||||
node.properties.className.push('word')
|
||||
},
|
||||
} satisfies Partial<CodeOptions>]]
|
||||
}
|
||||
})
|
||||
|
@ -73,7 +73,7 @@ async function transpileWorkerScript() {
|
||||
})
|
||||
}
|
||||
|
||||
export function createFileParser(transformers: QuartzTransformerPluginInstance[], baseDir: string, fps: string[], verbose: boolean) {
|
||||
export function createFileParser(transformers: QuartzTransformerPluginInstance[], baseDir: string, fps: string[], allSlugs: string[], verbose: boolean) {
|
||||
return async (processor: QuartzProcessor) => {
|
||||
const res: ProcessedContent[] = []
|
||||
for (const fp of fps) {
|
||||
@ -90,6 +90,7 @@ export function createFileParser(transformers: QuartzTransformerPluginInstance[]
|
||||
|
||||
// base data properties that plugins may use
|
||||
file.data.slug = slugify(path.relative(baseDir, file.path))
|
||||
file.data.allSlugs = allSlugs
|
||||
file.data.filePath = fp
|
||||
|
||||
const ast = processor.parse(file)
|
||||
@ -115,12 +116,16 @@ export async function parseMarkdown(transformers: QuartzTransformerPluginInstanc
|
||||
|
||||
const CHUNK_SIZE = 128
|
||||
let concurrency = fps.length < CHUNK_SIZE ? 1 : os.availableParallelism()
|
||||
let res: ProcessedContent[] = []
|
||||
|
||||
// get all slugs ahead of time as each thread needs a copy
|
||||
// const slugs: string[] = fps.map(fp => slugify(path))
|
||||
const allSlugs = fps.map(fp => slugify(path.relative(baseDir, path.resolve(fp))))
|
||||
|
||||
let res: ProcessedContent[] = []
|
||||
log.start(`Parsing input files using ${concurrency} threads`)
|
||||
if (concurrency === 1) {
|
||||
const processor = createProcessor(transformers)
|
||||
const parse = createFileParser(transformers, baseDir, fps, verbose)
|
||||
const parse = createFileParser(transformers, baseDir, fps, allSlugs, verbose)
|
||||
res = await parse(processor)
|
||||
} else {
|
||||
await transpileWorkerScript()
|
||||
@ -135,7 +140,7 @@ export async function parseMarkdown(transformers: QuartzTransformerPluginInstanc
|
||||
|
||||
const childPromises: WorkerPromise<ProcessedContent[]>[] = []
|
||||
for (const chunk of chunks(fps, CHUNK_SIZE)) {
|
||||
childPromises.push(pool.exec('parseFiles', [baseDir, chunk, verbose]))
|
||||
childPromises.push(pool.exec('parseFiles', [baseDir, chunk, allSlugs, verbose]))
|
||||
}
|
||||
|
||||
const results: ProcessedContent[][] = await WorkerPromise.all(childPromises)
|
||||
|
@ -15,16 +15,23 @@ body {
|
||||
}
|
||||
|
||||
.text-highlight {
|
||||
background-color: #fff236aa;
|
||||
background-color: #fff23688;
|
||||
padding: 0 0.1rem;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
p, ul, text, a, tr, td, li, ol, ul, .katex {
|
||||
p, ul, text, a, tr, td, li, ol, ul, .katex, .math {
|
||||
color: var(--darkgray);
|
||||
fill: var(--darkgray);
|
||||
}
|
||||
|
||||
.math {
|
||||
font-size: 1.1rem;
|
||||
&.math-display {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
@ -76,6 +83,10 @@ a {
|
||||
padding-left: 0;
|
||||
margin-left: -1.4rem;
|
||||
}
|
||||
|
||||
& li > * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& > #quartz-body {
|
||||
@ -144,6 +155,11 @@ a {
|
||||
}
|
||||
}
|
||||
|
||||
.footnotes {
|
||||
margin-top: 2rem;
|
||||
border-top: 1px solid var(--lightgray);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
transform: translateY(2px);
|
||||
color: var(--secondary);
|
||||
@ -168,7 +184,7 @@ thead {
|
||||
font-family: var(--headerFont);
|
||||
color: var(--dark);
|
||||
font-weight: revert;
|
||||
margin: 2rem 0 0;
|
||||
margin-bottom: 0;
|
||||
|
||||
article > & > a {
|
||||
color: var(--dark);
|
||||
@ -178,6 +194,8 @@ thead {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
&[id] > a[href^="#"] {
|
||||
margin: 0 0.5rem;
|
||||
@ -200,13 +218,17 @@ div[data-rehype-pretty-code-fragment] {
|
||||
& > div[data-rehype-pretty-code-title] {
|
||||
font-family: var(--codeFont);
|
||||
font-size: 0.9rem;
|
||||
padding: 0.1rem 0.8rem;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border: 1px solid var(--lightgray);
|
||||
width: max-content;
|
||||
border-radius: 5px;
|
||||
margin-bottom: -0.8rem;
|
||||
margin-bottom: -0.5rem;
|
||||
color: var(--darkgray);
|
||||
}
|
||||
|
||||
& > pre {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
@ -228,12 +250,17 @@ pre {
|
||||
counter-increment: line 0;
|
||||
display: grid;
|
||||
|
||||
& .line {
|
||||
& [data-highlighted-chars] {
|
||||
background-color: var(--highlight);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
& > [data-line] {
|
||||
padding: 0 0.25rem;
|
||||
box-sizing: border-box;
|
||||
border-left: 3px solid transparent;
|
||||
|
||||
&.highlighted {
|
||||
&[data-highlighted-line] {
|
||||
background-color: var(--highlight);
|
||||
border-left: 3px solid var(--secondary);
|
||||
}
|
||||
@ -245,9 +272,17 @@ pre {
|
||||
margin-right: 1rem;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
color: rgba(115, 138, 148, 0.4);
|
||||
color: rgba(115, 138, 148, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
&[data-line-numbers-max-digits='2'] > [data-line]::before {
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
&[data-line-numbers-max-digits='3'] > [data-line]::before {
|
||||
width: 3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,6 +300,7 @@ tbody, li, p {
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 1rem 0;
|
||||
border: 1px solid var(--gray);
|
||||
padding: 1.5rem;
|
||||
border-collapse: collapse;
|
||||
@ -294,21 +330,6 @@ hr {
|
||||
background-color: var(--lightgray);
|
||||
}
|
||||
|
||||
section {
|
||||
margin: 2rem auto;
|
||||
border-top: 1px solid var(--lightgray);
|
||||
|
||||
& > #footnote-label {
|
||||
& > a {
|
||||
color: var(--dark);
|
||||
}
|
||||
}
|
||||
|
||||
& ol, & ul {
|
||||
padding: 0 1em
|
||||
}
|
||||
}
|
||||
|
||||
audio, video {
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
@ -322,6 +343,10 @@ ul.overflow, ol.overflow {
|
||||
height: 400px;
|
||||
overflow-y: scroll;
|
||||
|
||||
// clearfix
|
||||
content: "";
|
||||
clear: both;
|
||||
|
||||
& > li:last-of-type {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
@ -334,6 +359,8 @@ ul.overflow, ol.overflow {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s ease;
|
||||
background: linear-gradient(transparent 0px, var(--light));
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ const transformers = config.plugins.transformers
|
||||
const processor = createProcessor(transformers)
|
||||
|
||||
// only called from worker thread
|
||||
export async function parseFiles(baseDir: string, fps: string[], verbose: boolean) {
|
||||
const parse = createFileParser(transformers, baseDir, fps, verbose)
|
||||
export async function parseFiles(baseDir: string, fps: string[], allSlugs: string[], verbose: boolean) {
|
||||
const parse = createFileParser(transformers, baseDir, fps, allSlugs, verbose)
|
||||
return parse(processor)
|
||||
}
|
||||
|
Reference in New Issue
Block a user