Skip to content

Commit

Permalink
feature docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jackyzha0 committed Aug 12, 2023
1 parent 259d0a6 commit 79e8286
Show file tree
Hide file tree
Showing 20 changed files with 160 additions and 94 deletions.
6 changes: 3 additions & 3 deletions content/advanced/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ This question is best answered by tracing what happens when a user (you!) runs `

## On the server

1. After running `npx quartz build`, npm will look at `package.json` to find the `bin.quartz` entry which points at `./quartz/bootstrap-cli.mjs`.
1. After running `npx quartz build`, npm will look at `package.json` to find the `bin` entry for `quartz` which points at `./quartz/bootstrap-cli.mjs`.
2. This file has a [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>) line at the top which tells npm to execute it using Node.
3. `bootstrap-cli.mjs` is responsible for a few things:
1. Parsing the command-line arguments using [yargs](http://yargs.js.org/).
2. Transpiling and bundling the rest of Quartz (which is in Typescript) to regular JavaScript using [esbuild](https://esbuild.github.io/). The `esbuild` configuration here is slightly special as it also handles `.scss` file imports using [esbuild-sass-plugin v2](https://www.npmjs.com/package/esbuild-sass-plugin). Additionally, we bundle 'inline' client-side scripts (any `.inline.ts` file) that components declare using a custom `esbuild` plugin that runs another instance of `esbuild` that bundles for the browser instead of `node`. Modules of both types are imported as plain text.
2. Transpiling and bundling the rest of Quartz (which is in Typescript) to regular JavaScript using [esbuild](https://esbuild.github.io/). The `esbuild` configuration here is slightly special as it also handles `.scss` file imports using [esbuild-sass-plugin v2](https://www.npmjs.com/package/esbuild-sass-plugin). Additionally, we bundle 'inline' client-side scripts (any `.inline.ts` file) that components declare using a custom `esbuild` plugin that runs another instance of `esbuild` which bundles for the browser instead of `node`. Modules of both types are imported as plain text.
3. Running the local preview server if `--serve` is set. This starts two servers:
1. A WebSocket server on port 3001 to handle hot-reload signals. This tracks all inbound connections and sends a 'rebuild' message a server-side change is detected (either content or configuration).
2. An HTTP file-server on a user defined port (normally 8080) to serve the actual website files.
Expand All @@ -35,7 +35,7 @@ This question is best answered by tracing what happens when a user (you!) runs `
4. Filter out unwanted content using plugins.
5. Emit files using plugins.
1. Gather all the static resources (e.g. external CSS, JS modules, etc.) each emitter plugin declares.
2. Emitters that emit HTML files do a bit of extra work here as they need to transform the [hast](https://github.com/syntax-tree/hast) produced in the parse step to JSX. This is done using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) with the [Preact](https://preactjs.com/) runtime. Finally, the JSX is rendered to HTML using [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) which statically renders the JSX to HTML (i.e. doesn't care about `useState`, `useEffect`, or any other React/Preact interactive bits). Here, we also do a bunch of fun stuff like assemble the page layout from `quartz.layout.ts`, assemble all the inline scripts that actually get shipped to the client, and all the transpiled styles. The bulk of this logic can be found in `quartz/components/renderPage.tsx`. Other fun things of note:
2. Emitters that emit HTML files do a bit of extra work here as they need to transform the [hast](https://github.com/syntax-tree/hast) produced in the parse step to JSX. This is done using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) with the [Preact](https://preactjs.com/) runtime. Finally, the JSX is rendered to HTML using [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) which statically renders the JSX to HTML (i.e. doesn't care about `useState`, `useEffect`, or any other React/Preact interactive bits). Here, we also do a bunch of fun stuff like assemble the page [[layout]] from `quartz.layout.ts`, assemble all the inline scripts that actually get shipped to the client, and all the transpiled styles. The bulk of this logic can be found in `quartz/components/renderPage.tsx`. Other fun things of note:
1. CSS is minified and transformed using [Lightning CSS](https://github.com/parcel-bundler/lightningcss) to add vendor prefixes and do syntax lowering.
2. Scripts are split into `beforeDOMLoaded` and `afterDOMLoaded` and are inserted in the `<head>` and `<body>` respectively.
3. Finally, each emitter plugin is responsible for emitting and writing it's own emitted files to disk.
Expand Down
12 changes: 6 additions & 6 deletions content/advanced/creating components.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Normally on the web, we write layout code using HTML which looks something like
</article>
```

This piece of HTML represents an article with a leading header that says "An article header" and a paragraph that contains the text "Some content". This is normally combined with CSS to style the page and JavaScript to add interactivity.
This piece of HTML represents an article with a leading header that says "An article header" and a paragraph that contains the text "Some content". This is combined with CSS to style the page and JavaScript to add interactivity.

However, HTML doesn't let you create reusable templates. If you wanted to create a new page, you would need to copy and paste the above snippet and edit the header and content yourself. This isn't great if we have a lot of content on our site that shares a lot of similar layout. The smart people who created React also had similar thoughts, inventing the concept of JSX Components to solve the code duplication problem.
However, HTML doesn't let you create reusable templates. If you wanted to create a new page, you would need to copy and paste the above snippet and edit the header and content yourself. This isn't great if we have a lot of content on our site that shares a lot of similar layout. The smart people who created React also had similar complaints and invented the concept of Components -- JavaScript functions that return JSX -- to solve the code duplication problem.

In effect, components allow you to write a JavaScript function that takes some data and produces HTML as an output. **While Quartz doesn't use React, it uses the same component concept to allow you to easily express layout templates in your Quartz site.**

Expand All @@ -26,7 +26,7 @@ In effect, components allow you to write a JavaScript function that takes some d

Component files are written in `.tsx` files that live in the `quartz/components` folder. These are re-exported in `quartz/components/index.ts` so you can use them in layouts and other components more easily.

Each component file should have a default export that satisfies the `QuartzComponentConstructor` function signature. It is a function that takes in a single optional parameter `opts` and returns a Quartz Component. The type of the parameters `ops` is defined by the interface `Options` which you as the component creator also decide.
Each component file should have a default export that satisfies the `QuartzComponentConstructor` function signature. It's a function that takes in a single optional parameter `opts` and returns a Quartz Component. The type of the parameters `opts` is defined by the interface `Options` which you as the component creator also decide.

In your component, you can use the values from the configuration option to change the rendering behaviour inside of your component. For example, the component in the code snippet below will not render if the `favouriteNumber` option is below 0.

Expand Down Expand Up @@ -57,7 +57,7 @@ export default ((userOpts?: Options) => {

The Quartz component itself (lines 11-17 highlighted above) looks like a React component. It takes in properties (sometimes called [props](https://react.dev/learn/passing-props-to-a-component)) and returns JSX.

All Quartz components accept the same set of props which are defined in `QuartzComponentProps`:
All Quartz components accept the same set of props:

```tsx title="quartz/components/types.ts"
// simplified for sake of demonstration
Expand All @@ -82,7 +82,7 @@ export type QuartzComponentProps = {
Quartz components can also define a `.css` property on the actual function component which will get picked up by Quartz. This is expected to be a CSS string which can either be inlined or imported from a `.scss` file.
Note that inlined styles **must** be plain vanilla CSS.
Note that inlined styles **must** be plain vanilla CSS:
```tsx {6-10} title="quartz/components/YourComponent.tsx"
export default (() => {
Expand All @@ -100,7 +100,7 @@ export default (() => {
}) satisfies QuartzComponentConstructor
```

Imported styles, however, can be from SCSS files.
Imported styles, however, can be from SCSS files:

```tsx {1-2,9} title="quartz/components/YourComponent.tsx"
// assuming your stylesheet is in quartz/components/styles/YourComponent.scss
Expand Down
12 changes: 6 additions & 6 deletions content/authoring content.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ title: Authoring Content

All of the content in your Quartz should go in the `/content` folder. The content for the home page of your Quartz lives in `content/index.md`. If you've [[index#🪴 Get Started|setup Quartz]] already, this folder should already be initailized. Any Markdown in this folder will get processed by Quartz.

It is recommended that you use [Obsidian](https://obsidian.md/) as a way to edit and maintain your Quartz. It comes with a nice editor and graphical interface to preview all of your local files and allow you to easily edit and link across files.
It is recommended that you use [Obsidian](https://obsidian.md/) as a way to edit and maintain your Quartz. It comes with a nice editor and graphical interface to preview, edit, and link your local files and attachments.

Got everything setup? Let's [[build]] and preview your Quartz locally!

## Syntax

As Quartz uses Markdown files as the main way of writing content, it fully supports Markdown syntax along with a few extensions like [Github Flavored Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) (footnotes, strikethrough, tables, tasklists) and [Obsidian Flavored Markdown](https://help.obsidian.md/Editing+and+formatting/Obsidian+Flavored+Markdown) ([[callouts]], [[wikilinks]]).
As Quartz uses Markdown files as the main way of writing content, it fully supports Markdown syntax. By default, Quartz also ships with a few syntax extensions like [Github Flavored Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) (footnotes, strikethrough, tables, tasklists) and [Obsidian Flavored Markdown](https://help.obsidian.md/Editing+and+formatting/Obsidian+Flavored+Markdown) ([[callouts]], [[wikilinks]]).

Additionally, Quartz also allows you to specify additional metadata in your notes called **frontmatter** using YAML.
Additionally, Quartz also allows you to specify additional metadata in your notes called **frontmatter**.

```md title="content/note.md"
---
Expand All @@ -27,7 +27,7 @@ The rest of your content lives here. You can use **Markdown** here :)

Some common frontmatter fields that are natively supported by Quartz:

- `title`: Quartz will use the name of the file as the title if this isn't provided. If it is provided, it should be a string.
- `draft`: Whether to publish the page or not. This is one way to make [[private pages|pages private]] in Quartz.
- `title`: Title of the page. If it isn't provided, Quartz will use the name of the file as the title.
- `aliases`: Other names for this note. This is a list of strings.
- `date`: A string representing the day the note was published. Normally uses `YYYY-MM-DD` format but other formats _may_ work.
- `draft`: Whether to publish the page or not. This is one way to make [[private pages|pages private]] in Quartz.
- `date`: A string representing the day the note was published. Normally uses `YYYY-MM-DD` format.
8 changes: 2 additions & 6 deletions content/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@
title: "Building your Quartz"
---

Once you've [[index#🪴 Get Started|initialized]] Quartz, let's see what it looks like locally.
Once you've [[index#🪴 Get Started|initialized]] Quartz, let's see what it looks like locally:

```bash
npx quartz build --serve
```

Then, open a web browser and visit `http://localhost:8080/` to view it.

Want to change how Quartz looks? You can edit `quartz.config.ts` to customize and configure your Quartz, including styles, layout, and more. Read the [[configuration]] page for more information on what each field in the configuration does.

Once you're happy with it, let's see how to [[hosting|deploy Quartz to the web]]!
This will start a local web server to run your Quartz on your computer. Open a web browser and visit `http://localhost:8080/` to view it.

> [!hint] Flags and options
> For full help options, you can run `npx quartz build --help`.
Expand Down
59 changes: 8 additions & 51 deletions content/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
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`.
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` or changing [[layout|the layout]] in `quartz.layout.ts`.

> [!tip]
> 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, helping you avoid configuration mistakes!
> If you edit Quartz configuration 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, helping you avoid configuration mistakes!
This configuration can be broken down into two main parts:
The configuration of Quartz can be broken down into two main parts:

```ts title="quartz.config.ts"
const config: QuartzConfig = {
Expand All @@ -20,15 +20,17 @@ const config: QuartzConfig = {

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.
- `pageTitle`: title of the site. 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.
- `baseUrl`: 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. `quartz.jzhao.xyz` for this site). Do not include the protocol (i.e. `https://`) or any leading or trailing slashes.
- This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz`
- 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. See [[private pages]] for more details.
- `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
Expand Down Expand Up @@ -77,48 +79,3 @@ transformers: [
```

If you'd like to make your own plugins, read the guide on [[making plugins]] for more information.

### Layout

Certain emitters may also output [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) files. To enable easy customization, these emitters allow you to fully rearrange the layout of the page. The default page layouts can be found in `quartz.layout.ts`.

Each page is composed of multiple different sections which contain `QuartzComponents`. The following code snippet lists all of the valid sections that you can add components to:

```typescript title="quartz/cfg.ts"
export interface FullPageLayout {
head: QuartzComponent // single component
header: QuartzComponent[] // laid out horizontally
beforeBody: QuartzComponent[] // laid out vertically
pageBody: QuartzComponent // single component
left: QuartzComponent[] // vertical on desktop, horizontal on mobile
right: QuartzComponent[] // vertical on desktop, horizontal on mobile
footer: QuartzComponent // single component
}
```

These correspond to following parts of the page:

![[quartz-layout.png|800]]

> [!note]
> There are two additional layout fields that are _not_ shown in the above diagram.
>
> 1. `head` is a single component that renders the `<head>` [tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head) in the HTML. This doesn't appear visually on the page and is only is responsible for metadata about the document like the tab title, scripts, and styles.
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. This enables you to replicate the old Quartz 3 header bar where the title, search bar, and dark mode toggle. By default, Quartz 4 doesn't place any components in the `header`.
Quartz **components**, like plugins, can take in additional properties as configuration options. If you're familiar with React terminology, you can think of them as Higher-order Components.

See [a list of all the components](./tags/component) for all available components along with their configuration options.

### Style

Most meaningful style changes like colour scheme and font can be done simply through the [[#General Configuration|general configuration]] options above.

However, if you'd like to make more involved style changes, you can do this by writing your own styles. Quartz 4, like Quartz 3, uses [Sass](https://sass-lang.com/guide/) for styling.

You can see the base style sheet in `quartz/styles/base.scss` and write your own in `quartz/styles/custom.scss`.

> [!note]
> Some components may provide their own styling as well! For example, `quartz/components/Darkmode.tsx` imports styles from `quartz/components/styles/darkmode.scss`. If you'd like to customize styling for a specific component, double check the component definition to see how its styles are defined.
When you're ready, see how [[build|build and preview]] Quartz locally.
2 changes: 1 addition & 1 deletion content/features/Latex.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ tags:

Quartz uses [Katex](https://katex.org/) by default to typeset both inline and block math expressions at build time.

## Formatting
## Syntax

### Block Math

Expand Down
Loading

0 comments on commit 79e8286

Please sign in to comment.