docs + various polish
This commit is contained in:
parent
b06cf9bdac
commit
33c8c9c5f6
@ -0,0 +1,5 @@
|
||||
---
|
||||
title: Creating your own Quartz components
|
||||
---
|
||||
|
||||
See the [component listing](/tags/component) for a full-list of the Quartz built-in components.
|
@ -1,3 +1,20 @@
|
||||
---
|
||||
title: Making your own plugins
|
||||
---
|
||||
---
|
||||
|
||||
This part of the documentation will assume you have some basic coding knowledge and will include code snippets that describe the interface of what Quartz plugins should look like.
|
||||
|
||||
## Transformers
|
||||
```ts
|
||||
export type QuartzTransformerPluginInstance = {
|
||||
name: string
|
||||
textTransform?: (src: string | Buffer) => string | Buffer
|
||||
markdownPlugins?: () => PluggableList
|
||||
htmlPlugins?: () => PluggableList
|
||||
externalResources?: () => Partial<StaticResources>
|
||||
}
|
||||
```
|
||||
|
||||
## Filters
|
||||
|
||||
## Emitters
|
77
content/configuration.md
Normal file
77
content/configuration.md
Normal file
@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Configuration
|
||||
---
|
||||
|
||||
Quartz is meant to be extremely configurable, even if you don't know any coding. Most of the configuration you should need can be done by just editing `quartz.config.ts`.
|
||||
|
||||
If you edit this file using a text-editor that has TypeScript language support like VSCode, it will warn you when you you've made an error in your configuration.
|
||||
|
||||
This configuration can be broken down into two main parts:
|
||||
|
||||
```ts
|
||||
const config: QuartzConfig = {
|
||||
configuration: { ... },
|
||||
plugins: { ... },
|
||||
}
|
||||
```
|
||||
|
||||
## General Configuration
|
||||
This part of the configuration concerns anything that can affect the whole site. The following is a list breaking down all the things you can configure:
|
||||
|
||||
- `pageTitle`: used as an anchor to return to the home page. This is also used when generating the [[RSS Feed]] for your site.
|
||||
- `enableSPA`: whether to enable [[SPA Routing]] on your site.
|
||||
- `enablePopovers`: whether to enable [[popover previews]] on your site.
|
||||
- `analytics`: what to use for analytics on your site. Values can be
|
||||
- `null`: don't use analytics;
|
||||
- `{ provider: 'plausible' }`: use [Plausible](https://plausible.io/), a privacy-friendly alternative to Google Analytics; or
|
||||
- `{ provider: 'google', tagId: <your-google-tag> }`: use Google Analytics
|
||||
- `caononicalUrl`: sometimes called `baseURL` in other site generators. This is used for sitemaps and RSS feeds that require an absolute URL to know where the canonical 'home' of your site lives. This is normally the deployed URL of your site (e.g. `https://quartz.jzhao.xyz/` for this site). Note that Quartz 4 will avoid using this as much as possible and use relative URLs whenever it can to make sure your site works no matter *where* you end up actually deploying it.
|
||||
- `ignorePatterns`: a list of [glob](https://en.wikipedia.org/wiki/Glob_(programming)) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder.
|
||||
- `theme`: configure how the site looks.
|
||||
- `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here.
|
||||
- `header`: Font to use for headers
|
||||
- `code`: Font for inline and block quotes.
|
||||
- `body`: Font for everything
|
||||
- `colors`: controls the theming of the site.
|
||||
- `light`: page background
|
||||
- `lightgray`: borders
|
||||
- `gray`: graph links, heavier borders
|
||||
- `darkgray`: body text
|
||||
- `dark`: header text and icons
|
||||
- `secondary`: link colour, current [[graph view|graph]] node
|
||||
- `tertiary`: hover states and visited [[graph view|graph]] nodes
|
||||
- `highlight`: internal link background, highlighted text, highlighted [[syntax highlighting|lines of code]]
|
||||
|
||||
## Plugins
|
||||
You can think of Quartz plugins as a series of transformations over content.
|
||||
|
||||
```ts
|
||||
plugins: {
|
||||
transformers: [...],
|
||||
filters: [...],
|
||||
emitters: [...],
|
||||
}
|
||||
```
|
||||
|
||||
- [[making plugins#Transformers|Transformers]] **map** over content, taking a Markdown file and outputting modified content or adding metadata to the file itself (e.g. parsing frontmatter, generating a description)
|
||||
- [[making plugins#Filters|Filters]] **filter** content, taking the output of all the transformers and determining what files to actually keep and what to discord (e.g. filtering out drafts)
|
||||
- [[making plugins#Emitters|Emitters]] **reduce** over content, taking in a list of all the transformed and filtered content and creating output files (e.g. creating an RSS feed or pages that list all files with a specific tag)
|
||||
|
||||
By adding, removing, and reordering plugins from the `tranformers`, `filters`, and `emitters` fields, you can customize the behaviour of Quartz.
|
||||
|
||||
> [!note]
|
||||
> Note that each node is modified by every transformer *in order*. Some transformers are position-sensitive so you may need to take special note of whether it needs come before or after any other particular plugins.
|
||||
|
||||
Additionally, plugins may also have their own configuration settings that you can pass in. For example, the [[Latex]] plugin allows you to pass in a field specifying the `renderEngine` to choose between Katex and MathJax.
|
||||
|
||||
```ts
|
||||
transformers: [
|
||||
Plugin.FrontMatter(), // uses default options
|
||||
Plugin.Latex({ renderEngine: 'katex' }) // specify some options
|
||||
]
|
||||
```
|
||||
|
||||
### Layout
|
||||
Certain emitters may also output [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) files.
|
||||
|
||||
### Components
|
0
content/custom domain.md
Normal file
0
content/custom domain.md
Normal file
44
content/features/Latex.md
Normal file
44
content/features/Latex.md
Normal file
@ -0,0 +1,44 @@
|
||||
---
|
||||
tags:
|
||||
- plugins/transformer
|
||||
---
|
||||
|
||||
Quartz uses [Katex](https://katex.org/) by default to typeset both inline and block math expressions at build time.
|
||||
|
||||
## Formatting
|
||||
|
||||
### Block Math
|
||||
Block math can be rendered by delimiting math expression with `$$`.
|
||||
|
||||
```
|
||||
$$
|
||||
f(x) = \int_{-\infty}^\infty
|
||||
f\hat(\xi),e^{2 \pi i \xi x}
|
||||
\,d\xi
|
||||
$$
|
||||
```
|
||||
|
||||
$$
|
||||
f(x) = \int_{-\infty}^\infty
|
||||
f\hat(\xi),e^{2 \pi i \xi x}
|
||||
\,d\xi
|
||||
$$
|
||||
|
||||
### Inline Math
|
||||
Similarly, inline math can be rendered by delimiting math expression with a single `$`. For example, `$e^{i\pi} = -1$` produces $e^{i\pi} = -1$
|
||||
|
||||
### Escaping symbols
|
||||
There will be cases where you may have more than one `$` in a paragraph at once which may accidentally trigger MathJax/Katex.
|
||||
|
||||
To get around this, you can escape the dollar sign by doing `\$` instead.
|
||||
|
||||
For example:
|
||||
- Incorrect: `I have $1 and you have $2` produces I have $1 and you have $2
|
||||
- Correct: `I have \$1 and you have \$2` produces I have \$1 and you have \$2
|
||||
|
||||
## MathJax
|
||||
In `quartz.config.ts`, you can configure Quartz to use [MathJax SVG rendering](https://docs.mathjax.org/en/latest/output/svg.html) by replacing `Plugin.Latex({ renderEngine: 'katex' })` with `Plugin.Latex({ renderEngine: 'mathjax' })`
|
||||
|
||||
## Customization
|
||||
- Removing Latex support: remove all instances of `Plugin.Latex()` from `quartz.config.ts`.
|
||||
- Plugin: `quartz/plugins/transformers/latex.ts`
|
10
content/features/Mermaid diagrams.md
Normal file
10
content/features/Mermaid diagrams.md
Normal file
@ -0,0 +1,10 @@
|
||||
> [!warning]
|
||||
> Wondering why Mermaid diagrams may not be showing up even if you have them enabled? You may need to reorder your plugins so that `Plugin.ObsidianFlavoredMarkdown()` is *after* `Plugin.SyntaxHighlighting()`.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Alice->>+John: Hello John, how are you?
|
||||
Alice->>+John: John, can you hear me?
|
||||
John-->>-Alice: Hi Alice, I can hear you!
|
||||
John-->>-Alice: I feel great!
|
||||
```
|
0
content/features/RSS Feed.md
Normal file
0
content/features/RSS Feed.md
Normal file
1
content/features/SPA Routing.md
Normal file
1
content/features/SPA Routing.md
Normal file
@ -0,0 +1 @@
|
||||
Single-page-app style rendering. This prevents flashes of unstyled content and improves smoothness of Quartz
|
13
content/features/backlinks.md
Normal file
13
content/features/backlinks.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Backlinks
|
||||
tags:
|
||||
- component
|
||||
---
|
||||
|
||||
A backlink for a note is a link from another note to that note. Links in the backlink pane also feature rich [[popover previews]] if you have that feature enabled.
|
||||
|
||||
## Customization
|
||||
- Removing backlinks: delete all usages of `Component.Backlinks()` from `quartz.config.ts`.
|
||||
- Component: `quartz/components/Backlinks.tsx`
|
||||
- Style: `quartz/components/styles/backlinks.scss`
|
||||
- Script: `quartz/components/scripts/search.inline.ts`
|
62
content/features/callouts.md
Normal file
62
content/features/callouts.md
Normal file
@ -0,0 +1,62 @@
|
||||
---
|
||||
title: Callouts
|
||||
---
|
||||
|
||||
> [!warning]
|
||||
> Wondering why callouts may not be showing up even if you have them enabled? You may need to reorder your plugins so that `Plugin.ObsidianFlavoredMarkdown()` is *after* `Plugin.SyntaxHighlighting()`.
|
||||
|
||||
|
||||
> [!info]
|
||||
> Default title
|
||||
|
||||
> [!question]+ Can callouts be nested?
|
||||
> > [!todo]- Yes!, they can.
|
||||
> > > [!example] You can even use multiple layers of nesting.
|
||||
|
||||
> [!EXAMPLE] Examples
|
||||
>
|
||||
> Aliases: example
|
||||
|
||||
> [!note] Notes
|
||||
>
|
||||
> Aliases: note
|
||||
|
||||
> [!abstract] Summaries
|
||||
>
|
||||
> Aliases: abstract, summary, tldr
|
||||
|
||||
> [!info] Info
|
||||
>
|
||||
> Aliases: info, todo
|
||||
|
||||
> [!tip] Hint
|
||||
>
|
||||
> Aliases: tip, hint, important
|
||||
|
||||
> [!success] Success
|
||||
>
|
||||
> Aliases: success, check, done
|
||||
|
||||
> [!question] Question
|
||||
>
|
||||
> Aliases: question, help, faq
|
||||
|
||||
> [!warning] Warning
|
||||
>
|
||||
> Aliases: warning, caution, attention
|
||||
|
||||
> [!failure] Failure
|
||||
>
|
||||
> Aliases: failure, fail, missing
|
||||
|
||||
> [!danger] Error
|
||||
>
|
||||
> Aliases: danger, error
|
||||
|
||||
> [!bug] Bug
|
||||
>
|
||||
> Aliases: bug
|
||||
|
||||
> [!quote] Quote
|
||||
>
|
||||
> Aliases: quote, cite
|
0
content/features/folder and tag listings.md
Normal file
0
content/features/folder and tag listings.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Full-text Search
|
||||
tags:
|
||||
- component
|
||||
---
|
||||
|
||||
Full-text search in Quartz is powered by [Flexsearch](https://github.com/nextapps-de/flexsearch). It's fast enough to return search results in under 10ms for Quartzs as large as half a million words.
|
||||
|
||||
It can be opened by either clicking on the search bar or pressing ⌘+K. The top 5 search results are shown on each query. Matching subterms are highlighted and the most relevant 30 words are excerpted. Clicking on a search result will navigate to that page.
|
||||
|
||||
This component is also keyboard accessible: Tab and Shift+Tab will cycle forward and backward through search results and Enter will navigate to the highlighted result (first result by default).
|
||||
|
||||
> [!info]
|
||||
> Search requires the `ContentIndex` emitter plugin to be present in the [[configuration]].
|
||||
|
||||
### Indexing Behaviour
|
||||
By default, it indexes every page on the site with **Markdown syntax removed**. This means link URLs for instance are not indexed.
|
||||
|
||||
It properly tokenizes Chinese, Korean, and Japenese characters and constructs separate indexes for the title and content, weighing title matches above content matches.
|
||||
|
||||
## Customization
|
||||
- Removing search: delete all usages of `Component.Search()` from `quartz.config.ts`.
|
||||
- Component: `quartz/components/Search.tsx`
|
||||
- Style: `quartz/components/styles/search.scss`
|
||||
- Script: `quartz/components/scripts/search.inline.ts`
|
||||
- You can edit `contextWindowWords` or `numSearchResults` to suit your needs
|
58
content/features/graph view.md
Normal file
58
content/features/graph view.md
Normal file
@ -0,0 +1,58 @@
|
||||
---
|
||||
title: "Graph View"
|
||||
tags:
|
||||
- component
|
||||
---
|
||||
|
||||
Quartz features a graph-view that can show both a local graph view and a global graph view.
|
||||
|
||||
- The local graph view shows files that either link to the current file or are linked from the current file. In other words, it shows all notes that are *at most* one hop away.
|
||||
- The global graph view can be toggled by clicking the graph icon on the top-right of the local graph view. It shows *all* the notes in your graph and how they connect to each other.
|
||||
|
||||
By default, the node radius is proportional to the total number of incoming and outgoing internal links from that file.
|
||||
|
||||
Additionally, similar to how browsers highlight visited links a different colour, the graph view will also show nodes that you have visited in a different colour.
|
||||
|
||||
> [!info]
|
||||
> Graph View requires the `ContentIndex` emitter plugin to be present in the [[configuration]].
|
||||
|
||||
## Customization
|
||||
Most configuration can be done by passing in options to `Component.Graph()`.
|
||||
|
||||
For example, here's what the default configuration looks like:
|
||||
|
||||
```typescript title="quartz.config.ts"
|
||||
Component.Graph({
|
||||
localGraph: {
|
||||
drag: true, // whether to allow panning the view around
|
||||
zoom: true, // whether to allow zooming in and out
|
||||
depth: 1, // how many hops of notes to display
|
||||
scale: 1.1, // default view scale
|
||||
repelForce: 0.5, // how much nodes should repel each other
|
||||
centerForce: 0.3, // how much force to use when trying to center the nodes
|
||||
linkDistance: 30, // how long should the links be by default?
|
||||
fontSize: 0.6, // what size should the node labels be?
|
||||
opacityScale: 1 // how quickly do we fade out the labels when zooming out?
|
||||
},
|
||||
globalGraph: {
|
||||
drag: true,
|
||||
zoom: true,
|
||||
depth: -1,
|
||||
scale: 0.9,
|
||||
repelForce: 0.5,
|
||||
centerForce: 0.3,
|
||||
linkDistance: 30,
|
||||
fontSize: 0.6,
|
||||
opacityScale: 1
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
When passing in your own options, you can omit any or all of these fields if you'd like to keep the default value for that field.
|
||||
|
||||
Want to customize it even more?
|
||||
|
||||
- Removing graph view: delete all usages of `Component.Graph()` from `quartz.config.ts`.
|
||||
- Component: `quartz/components/Graph.tsx`
|
||||
- Style: `quartz/components/styles/graph.scss`
|
||||
- Script: `quartz/components/scripts/graph.inline.ts`
|
3
content/features/index.md
Normal file
3
content/features/index.md
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
title: Feature List
|
||||
---
|
0
content/features/no-code layout configuration.md
Normal file
0
content/features/no-code layout configuration.md
Normal file
14
content/features/popover previews.md
Normal file
14
content/features/popover previews.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
title: Popover Previews
|
||||
---
|
||||
|
||||
Like Wikipedia, when you hover over a link in Quartz, there is a popup of a page preview that you can scroll to see the entire content.
|
||||
|
||||
By default, Quartz only fetches previews for pages inside your vault due to [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). It does this by selecting all HTML elements with the `popover-hint` class. For most pages, this includes the page title, page metadata like words and time to read, tags, and the actual page content.
|
||||
|
||||
When [[creating components|creating your own components]], you can include this `popover-hint` class to also include it in the popover.
|
||||
|
||||
## Configuration
|
||||
- Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`.
|
||||
- Style: `quartz/components/styles/popover.scss`
|
||||
- Script: `quartz/components/scripts/popover.inline.ts`
|
128
content/features/syntax highlighting.md
Normal file
128
content/features/syntax highlighting.md
Normal file
@ -0,0 +1,128 @@
|
||||
---
|
||||
title: Syntax Highlighting
|
||||
tags:
|
||||
- plugins/transformer
|
||||
---
|
||||
|
||||
Syntax highlighting in Quartz is completely done at build-time. This means that Quartz only ships pre-calculated CSS to highlight the right words so there is no heavy client-side bundle that does the syntax highlighting.
|
||||
|
||||
And, unlike some client-side highlighters, it has a full TextMate parser grammar instead of using Regexes, allowing for highly accurate code highlighting.
|
||||
|
||||
In short, it generates HTML that looks exactly like your code in an editor like VS Code. Under the hood, it's powered by [Rehype Pretty Code](https://rehype-pretty-code.netlify.app/) which uses [Shiki](https://github.com/shikijs/shiki).
|
||||
|
||||
> [!warning]
|
||||
> Syntax highlighting does have an impact on build speed if you have a lot of code snippets in your notes.
|
||||
|
||||
## Formatting
|
||||
Text inside `backticks` on a line will be formatted like code.
|
||||
|
||||
````
|
||||
```ts
|
||||
export function trimPathSuffix(fp: string): string {
|
||||
fp = clientSideSlug(fp)
|
||||
let [cleanPath, anchor] = fp.split("#", 2)
|
||||
anchor = anchor === undefined ? "" : "#" + anchor
|
||||
|
||||
return cleanPath + anchor
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```ts
|
||||
export function trimPathSuffix(fp: string): string {
|
||||
fp = clientSideSlug(fp)
|
||||
let [cleanPath, anchor] = fp.split("#", 2)
|
||||
anchor = anchor === undefined ? "" : "#" + anchor
|
||||
|
||||
return cleanPath + anchor
|
||||
}
|
||||
```
|
||||
|
||||
### Titles
|
||||
Add a file title to your code block, with text inside double quotes (`""`):
|
||||
|
||||
````
|
||||
```js title="..."
|
||||
|
||||
```
|
||||
````
|
||||
|
||||
```ts title="quartz/path.ts"
|
||||
export function trimPathSuffix(fp: string): string {
|
||||
fp = clientSideSlug(fp)
|
||||
let [cleanPath, anchor] = fp.split("#", 2)
|
||||
anchor = anchor === undefined ? "" : "#" + anchor
|
||||
|
||||
return cleanPath + anchor
|
||||
}
|
||||
```
|
||||
|
||||
### Line highlighting
|
||||
Place a numeric range inside `{}`.
|
||||
|
||||
````
|
||||
```js {1-3,4}
|
||||
|
||||
```
|
||||
````
|
||||
|
||||
```ts {2-3,6}
|
||||
export function trimPathSuffix(fp: string): string {
|
||||
fp = clientSideSlug(fp)
|
||||
let [cleanPath, anchor] = fp.split("#", 2)
|
||||
anchor = anchor === undefined ? "" : "#" + anchor
|
||||
|
||||
return cleanPath + anchor
|
||||
}
|
||||
```
|
||||
|
||||
### Word highlighting
|
||||
A series of characters, like a literal regex.
|
||||
|
||||
````
|
||||
```js /useState/
|
||||
const [age, setAge] = useState(50);
|
||||
const [name, setName] = useState('Taylor');
|
||||
```
|
||||
````
|
||||
|
||||
```js /useState/
|
||||
const [age, setAge] = useState(50);
|
||||
const [name, setName] = useState('Taylor');
|
||||
```
|
||||
|
||||
### Line numbers
|
||||
Syntax highlighting has line numbers configured automatically. If you want to start line numbers at a specific number, use `showLineNumbers{number}`:
|
||||
|
||||
````
|
||||
```js showLineNumbers{number}
|
||||
|
||||
```
|
||||
````
|
||||
|
||||
```ts showLineNumbers{20}
|
||||
export function trimPathSuffix(fp: string): string {
|
||||
fp = clientSideSlug(fp)
|
||||
let [cleanPath, anchor] = fp.split("#", 2)
|
||||
anchor = anchor === undefined ? "" : "#" + anchor
|
||||
|
||||
return cleanPath + anchor
|
||||
}
|
||||
```
|
||||
|
||||
### Escaping code blocks
|
||||
You can format a codeblock inside of a codeblock by wrapping it with another level of backtick fences that has one more backtick than the previous fence.
|
||||
|
||||
`````
|
||||
````
|
||||
```js /useState/
|
||||
const [age, setAge] = useState(50);
|
||||
const [name, setName] = useState('Taylor');
|
||||
```
|
||||
````
|
||||
`````
|
||||
|
||||
## Customization
|
||||
- Removing syntax highlighting: delete all usages of `Plugin.SyntaxHighlighting()` from `quartz.config.ts`.
|
||||
- Style: By default, Quartz uses derivatives of the GitHub light and dark themes. You can customize the colours in the `quartz/styles/syntax.scss` file.
|
||||
- Plugin: `quartz/plugins/transformers/syntax.ts`
|
0
content/features/table of contents.md
Normal file
0
content/features/table of contents.md
Normal file
31
content/features/upcoming features.md
Normal file
31
content/features/upcoming features.md
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
- CLI
|
||||
- update
|
||||
- push
|
||||
- create → ask for link resolution strategy
|
||||
- cursor chat extension
|
||||
- [https://giscus.app/](https://giscus.app/) extension
|
||||
- breadcrumbs component
|
||||
- filetree component
|
||||
- recent notes component
|
||||
- custom md blocks (e.g. for poetry)
|
||||
- sidenotes? [https://github.com/capnfabs/paperesque](https://github.com/capnfabs/paperesque)
|
||||
- show orphans in graph
|
||||
- parse tags in content
|
||||
- watch mode
|
||||
- direct match in search using double quotes
|
||||
- obsidian quirks to account for:
|
||||
- attachments path
|
||||
- [https://help.obsidian.md/Advanced+topics/Using+Obsidian+URI](https://help.obsidian.md/Advanced+topics/Using+Obsidian+URI)
|
||||
- angle bracket url escape [https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Escape+blank+spaces+in+links](https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Escape+blank+spaces+in+links)
|
||||
- [https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Task+lists](https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Task+lists) task list styling
|
||||
- [https://help.obsidian.md/Editing+and+formatting/Tags#Nested+tags](https://help.obsidian.md/Editing+and+formatting/Tags#Nested+tags) nested tags??
|
||||
- public metadata [https://help.obsidian.md/Editing+and+formatting/Metadata#Metadata+for+Obsidian+Publish](https://help.obsidian.md/Editing+and+formatting/Metadata#Metadata+for+Obsidian+Publish)
|
||||
- metadata aliases: [https://help.obsidian.md/Editing+and+formatting/Metadata#Predefined+metadata](https://help.obsidian.md/Editing+and+formatting/Metadata#Predefined+metadata)
|
||||
- \%\% style comments
|
||||
- audio/video embed styling
|
||||
- Canvas
|
||||
- mermaid styling: [https://mermaid.js.org/config/theming.html#theme-variables-reference-table](https://mermaid.js.org/config/theming.html#theme-variables-reference-table)
|
||||
- [https://github.com/jackyzha0/quartz/issues/331](https://github.com/jackyzha0/quartz/issues/331)
|
||||
- block links: [https://help.obsidian.md/Linking+notes+and+files/Internal+links#Link+to+a+block+in+a+note](https://help.obsidian.md/Linking+notes+and+files/Internal+links#Link+to+a+block+in+a+note)
|
||||
- note/header/block transcludes: [https://help.obsidian.md/Linking+notes+and+files/Embedding+files](https://help.obsidian.md/Linking+notes+and+files/Embedding+files)
|
7
content/hosting.md
Normal file
7
content/hosting.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Hosting
|
||||
---
|
||||
|
||||
## GitHub Pages
|
||||
|
||||
## Cloudflare Pages
|
@ -1,27 +1,33 @@
|
||||
---
|
||||
title: Welcome to Quartz
|
||||
title: Welcome to Quartz 4
|
||||
---
|
||||
|
||||
Quartz is a framework for turning Markdown content into a website.
|
||||
Quartz is a fast, batteries-included static-site generator that transforms Markdown content into fully functional websites. Thousands of students, developers, and teachers are [[showcase|already using Quartz]] to publish personal notes, wikis, and [digital gardens](https://jzhao.xyz/posts/networked-thought/) to the web.
|
||||
|
||||
- reduce the friction to go from notes to site
|
||||
- should work for everyone, from non-technical people to senior developers
|
||||
- customizability and extensibility
|
||||
|
||||
See some of the [amazing gardens that community members](showcase.md) have published with Quartz or read about [[philosophy|why I made Quartz]] to begin with.
|
||||
|
||||
> [!info] You are currently looking at the documentation for Quartz 4
|
||||
> If you're looking for Quartz 3, you can find the source for that version on the `hugo` branch. Alternatively, you can browse [an archived version of the old documentation on the Wayback Machine](https://web.archive.org/web/20230628023708/https://quartz.jzhao.xyz/).
|
||||
|
||||
## Installation
|
||||
Ready to get started?
|
||||
|
||||
Prerequisites:
|
||||
- Node >v16
|
||||
## 🪴 Get Started
|
||||
Quartz requires **at least [Node](https://nodejs.org/) v16** to function correctly. In your terminal of choice, enter the following commands line by line:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/jackyzha0/quartz.git
|
||||
cd quartz
|
||||
git checkout v4-alpha
|
||||
npm i
|
||||
npx quartz create
|
||||
```
|
||||
```
|
||||
|
||||
This will guide you through initializing your Quartz with content and previewing it locally.
|
||||
|
||||
When you're ready, you can edit `quartz.config.ts` to customize and configure Quartz more. Read the [[configuration]] page for more information on what each field in the configuration does.
|
||||
|
||||
## 🔧 Features
|
||||
|
||||
- [[full-text search|Full-text search]], [[graph view]], [[backlinks]], [[Latex]], [[syntax highlighting]], [[popover previews]], and many more right out of the box
|
||||
- Simple JSX [[creating components|layouts and page components]]
|
||||
- [[SPA Routing|Ridiculously fast page loads]] and tiny bundle sizes
|
||||
- Fully-customizable parsing, filtering, and page generation through [[making plugins|plugins]]
|
||||
|
||||
For a comprehensive list of features, visit the [features page](/features). You can read more the *why* behind these features on the [[philosophy]] page.
|
||||
|
||||
### 🚧 Troubleshooting
|
||||
Having trouble with Quartz? Try searching for your issue using the search feature. If you're still having trouble, feel free to [submit an issue](https://github.com/jackyzha0/quartz/issues) if you feel you found a bug or ask for help in our [Discord Community](https://discord.gg/cRFFHYye7t).
|
||||
|
||||
|
@ -1,14 +1,27 @@
|
||||
---
|
||||
title: Philosophy
|
||||
title: Philosophy of Quartz
|
||||
---
|
||||
|
||||
## A garden should be a true hypertext
|
||||
|
||||
> The garden is the web as topology. Every walk through the garden creates new paths, new meanings, and when we add things to the garden we add them in a way that allows many future, unpredicted relationships.
|
||||
>
|
||||
> (The Garden and the Stream)
|
||||
|
||||
The problem with the file cabinet is that it focuses on efficiency of access and interoperability rather than generativity and creativity. Thinking is not linear, nor is it hierarchical. In fact, not many things are linear or hierarchical at all. Then why is it that most tools and thinking strategies assume a nice chronological or hierarchical order for my thought processes? The ideal tool for thought for me would embrace the messiness of my mind, and organically help insights emerge from chaos instead of forcing an artificial order. A rhizomatic, not arboresecent, form of note taking.
|
||||
|
||||
My goal with a digital garden is not purely as an organizing system and information store (though it works nicely for that). I want my digital garden to be a playground for new ways ideas can connect together. As a result, existing formal organizing systems like Zettelkasten or the hierarchical folder structures of Notion don’t work well for me. There is way too much upfront friction that by the time I’ve thought about how to organize my thought into folders categories, I’ve lost it.
|
||||
|
||||
Quartz embraces the inherent rhizomatic and web-like nature of our thinking and tries to encourage note-taking in a similar form.
|
||||
|
||||
---
|
||||
|
||||
## A garden should be shared
|
||||
|
||||
The goal of digital gardening should be to tap into your network’s collective intelligence to create constructive feedback loops. If done well, I have a shareable representation of my thoughts that I can send out into the world and people can respond. Even for my most half-baked thoughts, this helps me create a feedback cycle to strengthen and fully flesh out that idea.
|
||||
|
||||
Quartz is designed first and foremost as a tool for publishing [digital gardens](https://jzhao.xyz/posts/networked-thought/) to the web. To me, digital gardening is not just passive knowledge collection. It’s a form of expression and sharing.
|
||||
|
||||
> “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming
|
||||
|
||||
When I first started taking notes in Markdown, there weren't that many any out-of-the-box solutions to easily publish my notes as a website.
|
||||
|
||||
I've personally found that
|
||||
1. It's nice to access notes from anywhere
|
||||
2. Having a public digital garden invites open conversations
|
||||
3. It makes keeping personal notes and knowledge *playful and fun*
|
||||
|
||||
**The goal of Quartz is to make sharing your digital garden free and simple.** Quartz exists as a tool to accomodate
|
||||
**The goal of Quartz is to make sharing your digital garden free and simple.** At its core, Quartz is designed to be easy to use enough for non-technical people to get going but also powerful enough that senior developers can tweak it to work how they'd like it to work.
|
||||
|
@ -1,8 +1,8 @@
|
||||
---
|
||||
title: "Showcase"
|
||||
title: "Quartz Showcase"
|
||||
---
|
||||
|
||||
Want to see what Quartz can do? Here are some cool community gardens :)
|
||||
Want to see what Quartz can do? Here are some cool community gardens:
|
||||
|
||||
- [Quartz Documentation (this site!)](https://quartz.jzhao.xyz/)
|
||||
- [Jacky Zhao's Garden](https://jzhao.xyz/)
|
||||
@ -17,15 +17,3 @@ Want to see what Quartz can do? Here are some cool community gardens :)
|
||||
- [Mike's AI Garden 🤖🪴](https://mwalton.me/)
|
||||
|
||||
If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/v4-alpha/content/showcase.md)!
|
||||
|
||||
Left-aligned text | Center-aligned text | Right-aligned text
|
||||
:-- | :--: | --:
|
||||
Content | Content | Content
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Alice->>+John: Hello John, how are you?
|
||||
Alice->>+John: John, can you hear me?
|
||||
John-->>-Alice: Hi Alice, I can hear you!
|
||||
John-->>-Alice: I feel great!
|
||||
```
|
5
content/tags/component.md
Normal file
5
content/tags/component.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
title: Components
|
||||
---
|
||||
|
||||
Want to create your own custom component? Check out the advanced guide on [[creating components]] for more information.
|
593
package-lock.json
generated
593
package-lock.json
generated
@ -34,7 +34,8 @@
|
||||
"reading-time": "^1.5.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-katex": "^6.0.3",
|
||||
"rehype-pretty-code": "^0.9.6",
|
||||
"rehype-mathjax": "^4.0.2",
|
||||
"rehype-pretty-code": "^0.10.0",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"rehype-slug": "^5.1.0",
|
||||
"remark": "^14.0.2",
|
||||
@ -695,6 +696,14 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
|
||||
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cli-spinner": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cli-spinner/-/cli-spinner-0.2.1.tgz",
|
||||
@ -996,6 +1005,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz",
|
||||
"integrity": "sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA=="
|
||||
},
|
||||
"node_modules/@types/mathjax": {
|
||||
"version": "0.0.37",
|
||||
"resolved": "https://registry.npmjs.org/@types/mathjax/-/mathjax-0.0.37.tgz",
|
||||
"integrity": "sha512-y0WSZBtBNQwcYipTU/BhgeFu1EZNlFvUNCmkMXV9kBQZq7/o5z82dNVyH3yy2Xv5zzeNeQoHSL4Xm06+EQiH+g=="
|
||||
},
|
||||
"node_modules/@types/mdast": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz",
|
||||
@ -1048,6 +1062,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
|
||||
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
|
||||
},
|
||||
"node_modules/@types/web": {
|
||||
"version": "0.0.46",
|
||||
"resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.46.tgz",
|
||||
"integrity": "sha512-ki0OmbjSdAEfvmy5AYWFpMkRsPW+6h4ibQ4tzk8SJsS9dkrrD3B/U1eVvdNNWxAzntjq6o2sjSia6UBCoPH+Yg=="
|
||||
},
|
||||
"node_modules/@types/workerpool": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/workerpool/-/workerpool-6.4.0.tgz",
|
||||
@ -1072,6 +1091,61 @@
|
||||
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/abab": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
|
||||
"integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-globals": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
|
||||
"integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
|
||||
"dependencies": {
|
||||
"acorn": "^7.1.1",
|
||||
"acorn-walk": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-globals/node_modules/acorn": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
|
||||
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
@ -1129,6 +1203,11 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/bail": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
|
||||
@ -1170,6 +1249,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/browser-process-hrtime": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
|
||||
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||
@ -1327,6 +1411,17 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/comma-separated-tokens": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
|
||||
@ -1370,6 +1465,27 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/cssom": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
|
||||
"integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="
|
||||
},
|
||||
"node_modules/cssstyle": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
|
||||
"integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
|
||||
"dependencies": {
|
||||
"cssom": "~0.3.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cssstyle/node_modules/cssom": {
|
||||
"version": "0.3.8",
|
||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
|
||||
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
|
||||
},
|
||||
"node_modules/d3": {
|
||||
"version": "7.8.5",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
|
||||
@ -1740,6 +1856,31 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/data-urls": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz",
|
||||
"integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==",
|
||||
"dependencies": {
|
||||
"abab": "^2.0.6",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^11.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/data-urls/node_modules/whatwg-url": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
|
||||
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
|
||||
"dependencies": {
|
||||
"tr46": "^3.0.0",
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
@ -1756,6 +1897,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decimal.js": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
|
||||
"integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
|
||||
},
|
||||
"node_modules/decode-named-character-reference": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
|
||||
@ -1776,6 +1922,14 @@
|
||||
"robust-predicates": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
@ -1803,6 +1957,17 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/domexception": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
|
||||
"integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
|
||||
"dependencies": {
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
@ -1891,6 +2056,34 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/escodegen": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
|
||||
"integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
|
||||
"dependencies": {
|
||||
"esprima": "^4.0.1",
|
||||
"estraverse": "^5.2.0",
|
||||
"esutils": "^2.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"escodegen": "bin/escodegen.js",
|
||||
"esgenerate": "bin/esgenerate.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"source-map": "~0.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/esm": {
|
||||
"version": "3.2.25",
|
||||
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
|
||||
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
@ -1903,6 +2096,22 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/estraverse": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/esutils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
@ -1993,6 +2202,19 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/format": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
|
||||
@ -2375,6 +2597,17 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/html-encoding-sniffer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
|
||||
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
|
||||
"dependencies": {
|
||||
"whatwg-encoding": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/html-void-elements": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz",
|
||||
@ -2384,6 +2617,31 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/http-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
|
||||
"integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
|
||||
"dependencies": {
|
||||
"@tootallnate/once": "2",
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
@ -2541,6 +2799,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-potential-custom-element-name": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
|
||||
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@ -2574,6 +2837,56 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom": {
|
||||
"version": "18.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-18.1.1.tgz",
|
||||
"integrity": "sha512-NmJQbjQ/gpS/1at/ce3nCx89HbXL/f5OcenBe8wU1Eik0ROhyUc3LtmG3567dEHAGXkN8rmILW/qtCOPxPHQJw==",
|
||||
"dependencies": {
|
||||
"abab": "^2.0.5",
|
||||
"acorn": "^8.5.0",
|
||||
"acorn-globals": "^6.0.0",
|
||||
"cssom": "^0.5.0",
|
||||
"cssstyle": "^2.3.0",
|
||||
"data-urls": "^3.0.1",
|
||||
"decimal.js": "^10.3.1",
|
||||
"domexception": "^4.0.0",
|
||||
"escodegen": "^2.0.0",
|
||||
"form-data": "^4.0.0",
|
||||
"html-encoding-sniffer": "^3.0.0",
|
||||
"http-proxy-agent": "^5.0.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"is-potential-custom-element-name": "^1.0.1",
|
||||
"nwsapi": "^2.2.0",
|
||||
"parse5": "6.0.1",
|
||||
"saxes": "^5.0.1",
|
||||
"symbol-tree": "^3.2.4",
|
||||
"tough-cookie": "^4.0.0",
|
||||
"w3c-hr-time": "^1.0.2",
|
||||
"w3c-xmlserializer": "^3.0.0",
|
||||
"webidl-conversions": "^7.0.0",
|
||||
"whatwg-encoding": "^2.0.0",
|
||||
"whatwg-mimetype": "^3.0.0",
|
||||
"whatwg-url": "^10.0.0",
|
||||
"ws": "^8.2.3",
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"canvas": "^2.5.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"canvas": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom/node_modules/parse5": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
|
||||
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
|
||||
},
|
||||
"node_modules/jsonc-parser": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
|
||||
@ -2645,6 +2958,17 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/mathjax-full": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
|
||||
"integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
|
||||
"dependencies": {
|
||||
"esm": "^3.2.25",
|
||||
"mhchemparser": "^4.1.0",
|
||||
"mj-context-menu": "^0.6.1",
|
||||
"speech-rule-engine": "^4.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-definitions": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz",
|
||||
@ -2884,6 +3208,11 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/mhchemparser": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
|
||||
"integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
|
||||
},
|
||||
"node_modules/micromark": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
|
||||
@ -3515,6 +3844,11 @@
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/mj-context-menu": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
|
||||
"integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||
@ -3548,6 +3882,11 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nwsapi": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
|
||||
"integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ=="
|
||||
},
|
||||
"node_modules/parse-latin": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-5.0.1.tgz",
|
||||
@ -3690,11 +4029,21 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/psl": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
||||
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
|
||||
},
|
||||
"node_modules/querystringify": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@ -3773,10 +4122,30 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/rehype-mathjax": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-4.0.2.tgz",
|
||||
"integrity": "sha512-9q4Q4icTIbM5RtvQ4XquvEApGV2oDMaSVa5G3DwXomWU4fAPWYcOOt+iQRNaIH3RBMbFF239QbE5K7hm7rxMPQ==",
|
||||
"dependencies": {
|
||||
"@types/hast": "^2.0.0",
|
||||
"@types/mathjax": "^0.0.37",
|
||||
"@types/web": "^0.0.46",
|
||||
"hast-util-from-dom": "^4.0.0",
|
||||
"hast-util-to-text": "^3.1.0",
|
||||
"jsdom": "^18.0.0",
|
||||
"mathjax-full": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/rehype-pretty-code": {
|
||||
"version": "0.9.11",
|
||||
"resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.9.11.tgz",
|
||||
"integrity": "sha512-Eq90eCYXQJISktfRZ8PPtwc5SUyH6fJcxS8XOMnHPUQZBtC6RYo67gGlley9X2nR8vlniPj0/7oCDEYHKQa/oA==",
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.10.0.tgz",
|
||||
"integrity": "sha512-qCD071Y+vUxEy9yyrATPk2+W9q7qCbzZgtc9suZhu75bmRQvOlBhJt4d3WvqSMTamkKoFkvqtCjyAk+ggH+aXQ==",
|
||||
"dependencies": {
|
||||
"@types/hast": "^2.0.0",
|
||||
"hash-obj": "^4.0.0",
|
||||
@ -3786,7 +4155,7 @@
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"shiki": "*"
|
||||
"shiki": "0.x"
|
||||
}
|
||||
},
|
||||
"node_modules/rehype-raw": {
|
||||
@ -3945,6 +4314,11 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
@ -4110,6 +4484,17 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/saxes": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
|
||||
"integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
|
||||
"dependencies": {
|
||||
"xmlchars": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/section-matter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||
@ -4229,6 +4614,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
@ -4246,6 +4640,27 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/speech-rule-engine": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
|
||||
"integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
|
||||
"dependencies": {
|
||||
"commander": "9.2.0",
|
||||
"wicked-good-xpath": "1.3.0",
|
||||
"xmldom-sre": "0.1.31"
|
||||
},
|
||||
"bin": {
|
||||
"sre": "bin/sre"
|
||||
}
|
||||
},
|
||||
"node_modules/speech-rule-engine/node_modules/commander": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
|
||||
"integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
@ -4377,6 +4792,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
|
||||
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@ -4401,6 +4821,47 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie/node_modules/punycode": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
|
||||
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46/node_modules/punycode": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/trim-lines": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
|
||||
@ -4593,6 +5054,23 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/url-parse": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||
"dependencies": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uvu": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
|
||||
@ -4663,6 +5141,26 @@
|
||||
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/w3c-hr-time": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
||||
"integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
|
||||
"deprecated": "Use your platform's native performance.now() and performance.timeOrigin.",
|
||||
"dependencies": {
|
||||
"browser-process-hrtime": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-xmlserializer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz",
|
||||
"integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==",
|
||||
"dependencies": {
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/web-namespaces": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
|
||||
@ -4672,6 +5170,45 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-encoding": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
|
||||
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
|
||||
"dependencies": {
|
||||
"iconv-lite": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-mimetype": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
|
||||
"integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz",
|
||||
"integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==",
|
||||
"dependencies": {
|
||||
"tr46": "^3.0.0",
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@ -4686,6 +5223,11 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/wicked-good-xpath": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
|
||||
"integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
|
||||
},
|
||||
"node_modules/workerpool": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.4.0.tgz",
|
||||
@ -4772,6 +5314,47 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.13.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
|
||||
"integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xml-name-validator": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
|
||||
"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/xmlchars": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
|
||||
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
|
||||
},
|
||||
"node_modules/xmldom-sre": {
|
||||
"version": "0.1.31",
|
||||
"resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
|
||||
"integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
|
||||
"engines": {
|
||||
"node": ">=0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
@ -51,7 +51,8 @@
|
||||
"reading-time": "^1.5.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-katex": "^6.0.3",
|
||||
"rehype-pretty-code": "^0.9.6",
|
||||
"rehype-mathjax": "^4.0.2",
|
||||
"rehype-pretty-code": "^0.10.0",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"rehype-slug": "^5.1.0",
|
||||
"remark": "^14.0.2",
|
||||
|
@ -1,15 +1,54 @@
|
||||
import { PageLayout, QuartzConfig } from "./quartz/cfg"
|
||||
import { GlobalConfiguration, PageLayout, QuartzConfig } from "./quartz/cfg"
|
||||
import * as Component from "./quartz/components"
|
||||
import * as Plugin from "./quartz/plugins"
|
||||
|
||||
const generalConfiguration: GlobalConfiguration = {
|
||||
pageTitle: "🪴 Quartz 4.0",
|
||||
enableSPA: true,
|
||||
enablePopovers: true,
|
||||
analytics: {
|
||||
provider: 'plausible',
|
||||
},
|
||||
canonicalUrl: "quartz.jzhao.xyz",
|
||||
ignorePatterns: ["private", "templates"],
|
||||
theme: {
|
||||
typography: {
|
||||
header: "Schibsted Grotesk",
|
||||
body: "Source Sans Pro",
|
||||
code: "IBM Plex Mono",
|
||||
},
|
||||
colors: {
|
||||
lightMode: {
|
||||
light: '#faf8f8',
|
||||
lightgray: '#e5e5e5',
|
||||
gray: '#b8b8b8',
|
||||
darkgray: '#4e4e4e',
|
||||
dark: '#2b2b2b',
|
||||
secondary: '#284b63',
|
||||
tertiary: '#84a59d',
|
||||
highlight: 'rgba(143, 159, 169, 0.15)',
|
||||
},
|
||||
darkMode: {
|
||||
light: '#161618',
|
||||
lightgray: '#393639',
|
||||
gray: '#646464',
|
||||
darkgray: '#d4d4d4',
|
||||
dark: '#ebebec',
|
||||
secondary: '#7b97aa',
|
||||
tertiary: '#84a59d',
|
||||
highlight: 'rgba(143, 159, 169, 0.15)',
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sharedPageComponents = {
|
||||
head: Component.Head(),
|
||||
header: [],
|
||||
footer: Component.Footer({
|
||||
authorName: "Jacky",
|
||||
links: {
|
||||
"GitHub": "https://github.com/jackyzha0",
|
||||
"Twitter": "https://twitter.com/_jzhao"
|
||||
"GitHub": "https://github.com/jackyzha0/quartz",
|
||||
"Discord Community": "https://discord.gg/cRFFHYye7t"
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -47,45 +86,7 @@ const listPageLayout: PageLayout = {
|
||||
}
|
||||
|
||||
const config: QuartzConfig = {
|
||||
configuration: {
|
||||
pageTitle: "🪴 Quartz 4.0",
|
||||
enableSPA: true,
|
||||
enablePopovers: true,
|
||||
analytics: {
|
||||
provider: 'plausible',
|
||||
},
|
||||
canonicalUrl: "quartz.jzhao.xyz",
|
||||
ignorePatterns: ["private", "templates"],
|
||||
theme: {
|
||||
typography: { // loaded from Google Fonts
|
||||
header: "Schibsted Grotesk",
|
||||
body: "Source Sans Pro",
|
||||
code: "IBM Plex Mono",
|
||||
},
|
||||
colors: {
|
||||
lightMode: {
|
||||
light: '#faf8f8',
|
||||
lightgray: '#e5e5e5',
|
||||
gray: '#b8b8b8',
|
||||
darkgray: '#4e4e4e',
|
||||
dark: '#141021',
|
||||
secondary: '#284b63',
|
||||
tertiary: '#84a59d',
|
||||
highlight: 'rgba(143, 159, 169, 0.15)',
|
||||
},
|
||||
darkMode: {
|
||||
light: '#161618',
|
||||
lightgray: '#393639',
|
||||
gray: '#646464',
|
||||
darkgray: '#d4d4d4',
|
||||
dark: '#fbfffe',
|
||||
secondary: '#7b97aa',
|
||||
tertiary: '#84a59d',
|
||||
highlight: 'rgba(143, 159, 169, 0.15)',
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
configuration: generalConfiguration,
|
||||
plugins: {
|
||||
transformers: [
|
||||
Plugin.FrontMatter(),
|
||||
@ -93,11 +94,11 @@ const config: QuartzConfig = {
|
||||
Plugin.CreatedModifiedDate({
|
||||
priority: ['frontmatter', 'filesystem'] // you can add 'git' here for last modified from Git but this makes the build slower
|
||||
}),
|
||||
Plugin.SyntaxHighlighting(),
|
||||
Plugin.ObsidianFlavoredMarkdown(),
|
||||
Plugin.GitHubFlavoredMarkdown(),
|
||||
Plugin.CrawlLinks({ markdownLinkResolution: 'absolute' }),
|
||||
Plugin.SyntaxHighlighting(),
|
||||
Plugin.Katex(),
|
||||
Plugin.CrawlLinks({ markdownLinkResolution: 'shortest' }),
|
||||
Plugin.Latex({ renderEngine: 'katex' }),
|
||||
Plugin.Description(),
|
||||
],
|
||||
filters: [
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user