Skip to content

Commit

Permalink
Merge branch 'v4' of https://github.com/jackyzha0/quartz into v4
Browse files Browse the repository at this point in the history
  • Loading branch information
Darakuu committed Feb 19, 2024
2 parents 2463226 + efd46f8 commit a30ca7e
Show file tree
Hide file tree
Showing 118 changed files with 4,267 additions and 1,999 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ Appunti di Algoritmi e Complessità, scritti a pochi giorni prima dai vari esami
- Tutte le formule sono scritte usando Latex, renderizzato con MathJax. Ho creato alcune macro per il plugin interno a Obsidian per velocizzarmi il lavoro;
- Eventuali disegni sono stati fatti usando il plugin Excalidraw (❤️);
- Infine, il sito web è realizzato automaticamente con [Quartz](https://github.com/jackyzha0/quartz)🌱 usando le GitHub Actions incluse.

<sup><sub>p.s. Ho leggermente modificato il sorgente per aggiungere dei Callouts personalizzati</sub></sup>
5 changes: 3 additions & 2 deletions docs/advanced/creating components.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,13 @@ document.addEventListener("nav", () => {
// do page specific logic here
// e.g. attach event listeners
const toggleSwitch = document.querySelector("#switch") as HTMLInputElement
toggleSwitch.removeEventListener("change", switchTheme)
toggleSwitch.addEventListener("change", switchTheme)
window.addCleanup(() => toggleSwitch.removeEventListener("change", switchTheme))
})
```

It is best practice to also unmount any existing event handlers to prevent memory leaks.
It is best practice to track any event handlers via `window.addCleanup` to prevent memory leaks.
This will get called on page navigation.

#### Importing Code

Expand Down
21 changes: 9 additions & 12 deletions docs/advanced/making plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ export const Latex: QuartzTransformerPlugin<Options> = (opts?: Options) => {
externalResources() {
if (engine === "katex") {
return {
css: ["https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css"],
css: ["https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.css"],
js: [
{
src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js",
src: "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/contrib/copy-tex.min.js",
loadTime: "afterDOMReady",
contentType: "external",
},
Expand Down Expand Up @@ -216,22 +216,19 @@ export type QuartzEmitterPlugin<Options extends OptionType = undefined> = (

export type QuartzEmitterPluginInstance = {
name: string
emit(
ctx: BuildCtx,
content: ProcessedContent[],
resources: StaticResources,
emitCallback: EmitCallback,
): Promise<FilePath[]>
emit(ctx: BuildCtx, content: ProcessedContent[], resources: StaticResources): Promise<FilePath[]>
getQuartzComponents(ctx: BuildCtx): QuartzComponent[]
}
```
An emitter plugin must define a `name` field an `emit` function and a `getQuartzComponents` function. `emit` is responsible for looking at all the parsed and filtered content and then appropriately creating files and returning a list of paths to files the plugin created.
An emitter plugin must define a `name` field, an `emit` function, and a `getQuartzComponents` function. `emit` is responsible for looking at all the parsed and filtered content and then appropriately creating files and returning a list of paths to files the plugin created.
Creating new files can be done via regular Node [fs module](https://nodejs.org/api/fs.html) (i.e. `fs.cp` or `fs.writeFile`) or via the `emitCallback` if you are creating files that contain text. The `emitCallback` function is the 4th argument of the emit function. Its interface looks something like this:
Creating new files can be done via regular Node [fs module](https://nodejs.org/api/fs.html) (i.e. `fs.cp` or `fs.writeFile`) or via the `write` function in `quartz/plugins/emitters/helpers.ts` if you are creating files that contain text. `write` has the following signature:
```ts
export type EmitCallback = (data: {
export type WriteOptions = (data: {
// the build context
ctx: BuildCtx
// the name of the file to emit (not including the file extension)
slug: ServerSlug
// the file extension
Expand Down Expand Up @@ -281,7 +278,7 @@ export const ContentPage: QuartzEmitterPlugin = () => {
allFiles,
}

const content = renderPage(slug, componentData, opts, externalResources)
const content = renderPage(cfg, slug, componentData, opts, externalResources)
const fp = await emit({
content,
slug: file.data.slug!,
Expand Down
18 changes: 5 additions & 13 deletions docs/authoring content.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
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.
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 initialized. 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, edit, and link your local files and attachments.

Expand All @@ -28,21 +28,13 @@ The rest of your content lives here. You can use **Markdown** here :)
Some common frontmatter fields that are natively supported by Quartz:

- `title`: Title of the page. If it isn't provided, Quartz will use the name of the file as the title.
- `description`: Description of the page used for link previews.
- `aliases`: Other names for this note. This is a list of strings.
- `tags`: Tags for this note.
- `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.

## Syncing your Content

When your Quartz is at a point you're happy with, you can save your changes to GitHub by doing `npx quartz sync`.

> [!hint] Flags and options
> For full help options, you can run `npx quartz sync --help`.
>
> Most of these have sensible defaults but you can override them if you have a custom setup:
>
> - `-d` or `--directory`: the content folder. This is normally just `content`
> - `-v` or `--verbose`: print out extra logging information
> - `--commit` or `--no-commit`: whether to make a `git` commit for your changes
> - `--push` or `--no-push`: whether to push updates to your GitHub fork of Quartz
> - `--pull` or `--no-pull`: whether to try and pull in any updates from your GitHub fork (i.e. from other devices) before pushing
When your Quartz is at a point you're happy with, you can save your changes to GitHub.
First, make sure you've [[setting up your GitHub repository|already setup your GitHub repository]] and then do `npx quartz sync`.
7 changes: 5 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ This part of the configuration concerns anything that can affect the whole 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
- `{ provider: 'google', tagId: '<your-google-tag>' }`: use Google Analytics;
- `{ provider: 'plausible' }` (managed) or `{ provider: 'plausible', host: '<your-plausible-host>' }` (self-hosted): use [Plausible](https://plausible.io/);
- `{ provider: 'umami', host: '<your-umami-host>', websiteId: '<your-umami-website-id>' }`: use [Umami](https://umami.is/);
- `locale`: used for [[i18n]] and date formatting
- `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.
- `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings.
- `theme`: configure how the site looks.
- `cdnCaching`: Whether to use Google CDN to cache the fonts (generally will be faster). Disable this if you want Quartz to be self-contained. Default to `true`
- `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.
Expand Down
2 changes: 2 additions & 0 deletions docs/features/Obsidian compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ Finally, Quartz also provides `Plugin.CrawlLinks` which allows you to customize
- `callouts`: whether to enable [[callouts]]. Defaults to `true`
- `mermaid`: whether to enable [[Mermaid diagrams]]. Defaults to `true`
- `parseTags`: whether to try and parse tags in the content body. Defaults to `true`
- `parseArrows`: whether to try and parse arrows in the content body. Defaults to `true`.
- `enableInHtmlEmbed`: whether to try and parse Obsidian flavoured markdown in raw HTML. Defaults to `false`
- `enableYouTubeEmbed`: whether to enable embedded YouTube videos using external image Markdown syntax. Defaults to `false`
- Link resolution behaviour:
- Disabling: remove all instances of `Plugin.CrawlLinks()` from `quartz.config.ts`
- Changing link resolution preference: set `markdownLinkResolution` to one of `absolute`, `relative` or `shortest`
2 changes: 1 addition & 1 deletion docs/features/breadcrumbs.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Component.Breadcrumbs({
rootName: "Home", // name of first/root element
resolveFrontmatterTitle: true, // whether to resolve folder names through frontmatter titles
hideOnRoot: true, // whether to hide breadcrumbs on root `index.md` page
showCurrentPage: true, // wether to display the current page in the breadcrumbs
showCurrentPage: true, // whether to display the current page in the breadcrumbs
})
```

Expand Down
22 changes: 20 additions & 2 deletions docs/features/callouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,32 @@ See [documentation on supported types and syntax here](https://help.obsidian.md
## Customization

- Disable callouts: simply pass `callouts: false` to the plugin: `Plugin.ObsidianFlavoredMarkdown({ callouts: false })`
- Editing icons: `quartz/plugins/transformers/ofm.ts`
- Editing icons: `quartz/styles/callouts.scss`

### Add custom callouts

By default, custom callouts are handled by applying the `note` style. To make fancy ones, you have to add these lines to `custom.scss`.

```scss title="quartz/styles/custom.scss"
.callout {
&[data-callout="custom"] {
--color: #customcolor;
--border: #custombordercolor;
--bg: #custombg;
--callout-icon: url("data:image/svg+xml; utf8, <custom formatted svg>"); //SVG icon code
}
}
```

> [!warning]
> Don't forget to ensure that the SVG is URL encoded before putting it in the CSS. You can use tools like [this one](https://yoksel.github.io/url-encoder/) to help you do that.
## Showcase

> [!info]
> Default title
> [!question]+ Can callouts be nested?
> [!question]+ Can callouts be _nested_?
>
> > [!todo]- Yes!, they can. And collapsed!
> >
Expand Down
9 changes: 9 additions & 0 deletions docs/features/darkmode.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@ Quartz supports darkmode out of the box that respects the user's theme preferenc
- Component: `quartz/components/Darkmode.tsx`
- Style: `quartz/components/styles/darkmode.scss`
- Script: `quartz/components/scripts/darkmode.inline.ts`

You can also listen to the `themechange` event to perform any custom logic when the theme changes.

```js
document.addEventListener("themechange", (e) => {
console.log("Theme changed to " + e.detail.theme) // either "light" or "dark"
// your logic here
})
```
117 changes: 89 additions & 28 deletions docs/features/explorer.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Component.Explorer({
title: "Explorer", // title of the explorer component
folderClickBehavior: "collapse", // what happens when you click a folder ("link" to navigate to folder page on click or "collapse" to collapse folder on click)
folderDefaultState: "collapsed", // default state of folders ("collapsed" or "open")
useSavedState: true, // wether to use local storage to save "state" (which folders are opened) of explorer
useSavedState: true, // whether to use local storage to save "state" (which folders are opened) of explorer
// Sort order: folders first, then files. Sort folders and files alphabetically
sortFn: (a, b) => {
... // default implementation shown later
Expand Down Expand Up @@ -179,6 +179,34 @@ Component.Explorer({

## Advanced examples

> [!tip]
> When writing more complicated functions, the `layout` file can start to look very cramped.
> You can fix this by defining your functions in another file.
>
> ```ts title="functions.ts"
> import { Options } from "./quartz/components/ExplorerNode"
> export const mapFn: Options["mapFn"] = (node) => {
> // implement your function here
> }
> export const filterFn: Options["filterFn"] = (node) => {
> // implement your function here
> }
> export const sortFn: Options["sortFn"] = (a, b) => {
> // implement your function here
> }
> ```
>
> You can then import them like this:
>
> ```ts title="quartz.layout.ts"
> import { mapFn, filterFn, sortFn } from "./functions.ts"
> Component.Explorer({
> mapFn: mapFn,
> filterFn: filterFn,
> sortFn: sortFn,
> })
> ```
### Add emoji prefix

To add emoji prefixes (📁 for folders, 📄 for files), you could use a map function like this:
Expand Down Expand Up @@ -216,30 +244,63 @@ Notice how we customized the `order` array here. This is done because the defaul

To fix this, we just changed around the order and apply the `sort` function before changing the display names in the `map` function.

> [!tip]
> When writing more complicated functions, the `layout` file can start to look very cramped.
> You can fix this by defining your functions in another file.
>
> ```ts title="functions.ts"
> import { Options } from "./quartz/components/ExplorerNode"
> export const mapFn: Options["mapFn"] = (node) => {
> // implement your function here
> }
> export const filterFn: Options["filterFn"] = (node) => {
> // implement your function here
> }
> export const sortFn: Options["sortFn"] = (a, b) => {
> // implement your function here
> }
> ```
>
> You can then import them like this:
>
> ```ts title="quartz.layout.ts"
> import { mapFn, filterFn, sortFn } from "./functions.ts"
> Component.Explorer({
> mapFn: mapFn,
> filterFn: filterFn,
> sortFn: sortFn,
> })
> ```
### Use `sort` with pre-defined sort order

Here's another example where a map containing file/folder names (as slugs) is used to define the sort order of the explorer in quartz. All files/folders that aren't listed inside of `nameOrderMap` will appear at the top of that folders hierarchy level.

It's also worth mentioning, that the smaller the number set in `nameOrderMap`, the higher up the entry will be in the explorer. Incrementing every folder/file by 100, makes ordering files in their folders a lot easier. Lastly, this example still allows you to use a `mapFn` or frontmatter titles to change display names, as it uses slugs for `nameOrderMap` (which is unaffected by display name changes).

```ts title="quartz.layout.ts"
Component.Explorer({
sortFn: (a, b) => {
const nameOrderMap: Record<string, number> = {
"poetry-folder": 100,
"essay-folder": 200,
"research-paper-file": 201,
"dinosaur-fossils-file": 300,
"other-folder": 400,
}

let orderA = 0
let orderB = 0

if (a.file && a.file.slug) {
orderA = nameOrderMap[a.file.slug] || 0
} else if (a.name) {
orderA = nameOrderMap[a.name] || 0
}

if (b.file && b.file.slug) {
orderB = nameOrderMap[b.file.slug] || 0
} else if (b.name) {
orderB = nameOrderMap[b.name] || 0
}

return orderA - orderB
},
})
```

For reference, this is how the quartz explorer window would look like with that example:

```
📖 Poetry Folder
📑 Essay Folder
⚗️ Research Paper File
🦴 Dinosaur Fossils File
🔮 Other Folder
```

And this is how the file structure would look like:

```
index.md
poetry-folder
index.md
essay-folder
index.md
research-paper-file.md
dinosaur-fossils-file.md
other-folder
index.md
```
18 changes: 18 additions & 0 deletions docs/features/i18n.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Internationalization
---

Internationalization allows users to translate text in the Quartz interface into various supported languages without needing to make extensive code changes. This can be changed via the `locale` [[configuration]] field in `quartz.config.ts`.

The locale field generally follows a certain format: `{language}-{REGION}`

- `{language}` is usually a [2-letter lowercase language code](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes).
- `{REGION}` is usually a [2-letter uppercase region code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)

> [!tip] Interested in contributing?
> We [gladly welcome translation PRs](https://github.com/jackyzha0/quartz/tree/v4/quartz/i18n/locales)! To contribute a translation, do the following things:
>
> 1. In the `quartz/i18n/locales` folder, copy the `en-US.ts` file.
> 2. Rename it to `{language}-{REGION}.ts` so it matches a locale of the format shown above.
> 3. Fill in the translations!
> 4. Add the entry under `TRANSLATIONS` in `quartz/i18n/index.ts`.
2 changes: 2 additions & 0 deletions docs/features/popover previews.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ By default, Quartz only fetches previews for pages inside your vault due to [COR

When [[creating components|creating your own components]], you can include this `popover-hint` class to also include it in the popover.

Similar to Obsidian, [[quartz layout.png|images referenced using wikilinks]] can also be viewed as popups.

## Configuration

- Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`.
Expand Down
2 changes: 1 addition & 1 deletion docs/features/recent notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Recent Notes
tags: component
---

Quartz can generate a list of recent notes for based on some filtering and sorting criteria. Though this component isn't included in any [[layout]] by default, you can add it by using `Component.RecentNotes`.
Quartz can generate a list of recent notes based on some filtering and sorting criteria. Though this component isn't included in any [[layout]] by default, you can add it by using `Component.RecentNotes` in `quartz.layout.ts`.

## Customization

Expand Down
Loading

0 comments on commit a30ca7e

Please sign in to comment.