Compare commits

...

169 Commits

Author SHA1 Message Date
Jacky Zhao
4bbcc0c50a pkg: minor bump for breaking nodejs bump :) 2024-08-05 19:33:23 -07:00
Jacky Zhao
3938904cd0 fix: embed pdf aspect ratio (closes #1310) 2024-08-05 19:31:54 -07:00
Jacky Zhao
407fad384c fix: only one h1 on a page (closes #1269) 2024-08-05 19:18:48 -07:00
Jacky Zhao
ca3943b500 fix: responsive youtube embed (closes #1167) 2024-08-05 19:14:14 -07:00
dependabot[bot]
6c4ed249ba chore(deps): bump rimraf from 5.0.7 to 6.0.1 (#1277)
Bumps [rimraf](https://github.com/isaacs/rimraf) from 5.0.7 to 6.0.1.
- [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/rimraf/compare/v5.0.7...v6.0.1)

---
updated-dependencies:
- dependency-name: rimraf
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 18:54:10 -07:00
Jacky Zhao
563ab4aaaf docs: update node version in hosting docs 2024-08-05 18:49:20 -07:00
Jacky Zhao
1c2d542138 build: add .node-version 2024-08-05 18:48:29 -07:00
Pelayo Arbués
e864740df7 docs: Adds back Pelayo Arbues blog to showcase (#1314)
Co-authored-by: Pelayo Arbues <pgarbues@idealista.com>
2024-08-05 18:44:34 -07:00
Ellie Huxtable
efed544df1 docs: Add "Ellie's Notes" to the showcase (#1315)
Thank you for Quartz! I really love using it. Just adding my notes to the showcase 😊
2024-08-05 18:43:57 -07:00
Jacky Zhao
3d156b8497 deps(dev): bump nodejs in ci 2024-08-05 18:43:05 -07:00
Jacky Zhao
38361aaf48 deps: change min required nodejs to v20 (breaking) 2024-08-05 18:41:46 -07:00
dependabot[bot]
f3e07fd51c chore(deps-dev): bump prettier from 3.3.2 to 3.3.3 (#1293)
* chore(deps-dev): bump prettier from 3.3.2 to 3.3.3

Bumps [prettier](https://github.com/prettier/prettier) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.2...3.3.3)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* make prettier happy

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2024-08-05 18:38:07 -07:00
dependabot[bot]
d79911fa79 chore(deps): bump workerpool from 9.1.2 to 9.1.3 (#1318)
Bumps [workerpool](https://github.com/josdejong/workerpool) from 9.1.2 to 9.1.3.
- [Changelog](https://github.com/josdejong/workerpool/blob/master/HISTORY.md)
- [Commits](https://github.com/josdejong/workerpool/compare/v9.1.2...v9.1.3)

---
updated-dependencies:
- dependency-name: workerpool
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 18:46:00 -04:00
dependabot[bot]
963c7c8654 chore(deps-dev): bump @types/node from 20.14.11 to 22.1.0 (#1319)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.11 to 22.1.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 16:49:37 -04:00
dependabot[bot]
3728929ee6 chore(deps): bump preact-render-to-string from 6.5.5 to 6.5.7 (#1317)
Bumps [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) from 6.5.5 to 6.5.7.
- [Release notes](https://github.com/preactjs/preact-render-to-string/releases)
- [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md)
- [Commits](https://github.com/preactjs/preact-render-to-string/compare/v6.5.5...v6.5.7)

---
updated-dependencies:
- dependency-name: preact-render-to-string
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-05 16:49:19 -04:00
Aaron Pham
1224c7d32f refactor(comments): move script to files (#1308)
* refactor(comments): move script to files

for LSP, treesitter, and the whole galore.

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* fix(type): support removeEventListener with CustomEventMap

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* fix: parse bool to string first

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* chore: address comments and test on branch

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* revert: remove comments section from main quartz pages

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

---------

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
2024-08-05 15:17:11 -04:00
dependabot[bot]
bf1c9d1791 chore(deps): bump globby from 14.0.1 to 14.0.2 (#1301)
Bumps [globby](https://github.com/sindresorhus/globby) from 14.0.1 to 14.0.2.
- [Release notes](https://github.com/sindresorhus/globby/releases)
- [Commits](https://github.com/sindresorhus/globby/compare/v14.0.1...v14.0.2)

---
updated-dependencies:
- dependency-name: globby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-02 14:48:54 -04:00
Jacky Zhao
6264f5685c fix: comments on spa should work (closes #1296) (#1298)
* fix comments on spa

* fix giscus
2024-07-30 01:13:13 -07:00
Jacky Zhao
e1a9661be7 docs: cleanup showcase 2024-07-29 16:33:50 -07:00
dependabot[bot]
bc95332fce chore(deps-dev): bump @types/ws from 8.5.11 to 8.5.12 (#1300)
Bumps [@types/ws](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ws) from 8.5.11 to 8.5.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ws)

---
updated-dependencies:
- dependency-name: "@types/ws"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-29 13:14:34 -07:00
dependabot[bot]
740172acb6 chore(deps): bump vfile from 6.0.1 to 6.0.2 (#1299)
Bumps [vfile](https://github.com/vfile/vfile) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/vfile/vfile/releases)
- [Changelog](https://github.com/vfile/vfile/blob/main/changelog.md)
- [Commits](https://github.com/vfile/vfile/compare/6.0.1...6.0.2)

---
updated-dependencies:
- dependency-name: vfile
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-29 13:14:25 -07:00
dependabot[bot]
34fde07cf8 chore(deps-dev): bump tsx from 4.16.0 to 4.16.2 (#1292)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.16.0 to 4.16.2.
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.16.0...v4.16.2)

---
updated-dependencies:
- dependency-name: tsx
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 15:30:44 -07:00
dependabot[bot]
e688eeeaff chore(deps-dev): bump @types/node from 20.12.5 to 20.14.11 (#1291)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.5 to 20.14.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 15:30:35 -07:00
dependabot[bot]
5749fbbd75 chore(deps): bump @floating-ui/dom from 1.6.5 to 1.6.8 (#1290)
Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.6.5 to 1.6.8.
- [Release notes](https://github.com/floating-ui/floating-ui/releases)
- [Changelog](https://github.com/floating-ui/floating-ui/blob/master/packages/dom/CHANGELOG.md)
- [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.6.8/packages/dom)

---
updated-dependencies:
- dependency-name: "@floating-ui/dom"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-22 15:30:28 -07:00
Jacky Zhao
5f10df4d05 pkg 2024-07-21 17:49:28 -07:00
Jacky Zhao
03f23e5054 feat: comments (giscus) 2024-07-20 23:05:45 -07:00
Jacky Zhao
b9ee44aad7 i18n: disambiguate en-us and en-gb 2024-07-20 20:24:17 -07:00
dependabot[bot]
87f2b0c327 chore(deps): bump lightningcss from 1.24.1 to 1.25.1 (#1276)
Bumps [lightningcss](https://github.com/parcel-bundler/lightningcss) from 1.24.1 to 1.25.1.
- [Release notes](https://github.com/parcel-bundler/lightningcss/releases)
- [Commits](https://github.com/parcel-bundler/lightningcss/compare/v1.24.1...v1.25.1)

---
updated-dependencies:
- dependency-name: lightningcss
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-19 10:57:28 -07:00
dependabot[bot]
805d9e3226 chore(deps): bump ws and @types/ws (#1280)
Bumps [ws](https://github.com/websockets/ws) and [@types/ws](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ws). These dependencies needed to be updated together.

Updates `ws` from 8.17.1 to 8.18.0
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.17.1...8.18.0)

Updates `@types/ws` from 8.5.10 to 8.5.11
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ws)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/ws"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-19 10:02:06 -07:00
dependabot[bot]
5fcba1bfaf chore(deps): bump mdast-util-to-hast from 13.1.0 to 13.2.0 (#1279)
Bumps [mdast-util-to-hast](https://github.com/syntax-tree/mdast-util-to-hast) from 13.1.0 to 13.2.0.
- [Release notes](https://github.com/syntax-tree/mdast-util-to-hast/releases)
- [Commits](https://github.com/syntax-tree/mdast-util-to-hast/compare/13.1.0...13.2.0)

---
updated-dependencies:
- dependency-name: mdast-util-to-hast
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-19 10:02:03 -07:00
dependabot[bot]
942c35183a chore(deps): bump preact from 10.22.0 to 10.22.1 (#1278)
Bumps [preact](https://github.com/preactjs/preact) from 10.22.0 to 10.22.1.
- [Release notes](https://github.com/preactjs/preact/releases)
- [Commits](https://github.com/preactjs/preact/compare/10.22.0...10.22.1)

---
updated-dependencies:
- dependency-name: preact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-19 10:01:55 -07:00
sou7
b37c408985 Fix CreatedModifiedDate.md (#1281)
Fixed a broken parentheses correspondence for code fragments that appear in the documentation.
2024-07-16 09:08:58 -07:00
Emile Bangma
f37dbe1a59 fix(translusion): block reference not being recognized. (#1274) 2024-07-14 03:06:52 -07:00
Jacky Zhao
247625c4f5 feat(layout): add afterBody 2024-07-09 19:09:31 -07:00
Jacky Zhao
4b407e786f chore: format 2024-07-09 18:08:21 -07:00
Jacky Zhao
9cabf2b416 chore: update features 2024-07-09 18:07:00 -07:00
Jacky Zhao
965425d54d docs + chore: cleanup custom sort ordering for folder + tag listings, add docs 2024-07-09 17:55:19 -07:00
Cao Mingjun
ea92ed4f45 feat: Allow custom sorting of FolderPage and TagPage (#1250) 2024-07-09 17:42:33 -07:00
dependabot[bot]
596e06ab0e chore(deps-dev): bump typescript from 5.4.5 to 5.5.3 (#1254)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.5 to 5.5.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.5...v5.5.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 17:28:49 -07:00
Alex Nordstrom
c95f1d2336 feat: add alias/metadata to transclude tag (#1229) 2024-07-09 17:26:32 -07:00
Peter
b7793bd856 feat(style): Add textHighlight theme setting (#1242)
* Add textHighlight theme setting

* update docs to include textHighlight

* Remove errant `S`
2024-07-09 17:21:00 -07:00
dependabot[bot]
ef375d265d chore(deps): bump rfdc from 1.3.1 to 1.4.1 (#1235)
Bumps [rfdc](https://github.com/davidmarkclements/rfdc) from 1.3.1 to 1.4.1.
- [Release notes](https://github.com/davidmarkclements/rfdc/releases)
- [Commits](https://github.com/davidmarkclements/rfdc/compare/v1.3.1...1.4.1)

---
updated-dependencies:
- dependency-name: rfdc
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 17:20:37 -07:00
Jacky Zhao
2154d36d99 chore: use regex flag instead of string in regexp ctor 2024-07-09 17:20:13 -07:00
dependabot[bot]
3eda53cac7 chore(deps): bump remark-smartypants from 2.1.0 to 3.0.2 (#1263)
Bumps [remark-smartypants](https://github.com/silvenon/remark-smartypants) from 2.1.0 to 3.0.2.
- [Release notes](https://github.com/silvenon/remark-smartypants/releases)
- [Commits](https://github.com/silvenon/remark-smartypants/compare/v2.1.0...v3.0.2)

---
updated-dependencies:
- dependency-name: remark-smartypants
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 17:16:02 -07:00
Cao Mingjun
4eeacb7fbf Fix Non-English Anchor Popover Positioning Issue and Update Type Hint (#1252)
- [Major] Changed `hash` passed to `querySelector` to `decodeURIComponent(hash)` to fix the issue where non-English anchors were not correctly positioning the popover content to the corresponding title.
- [Minor] Updated the type hint from `HTMLLinkElement` to `HTMLAnchorElement` as the passed element is an `<a>` element, not a `<link>` element (reference: https://developer.mozilla.org/en-US/docs/Web/API/HTMLLinkElement).
2024-07-08 13:34:43 -07:00
dependabot[bot]
6245935c8c chore(deps): bump shiki from 1.6.0 to 1.10.3 (#1264)
Bumps [shiki](https://github.com/shikijs/shiki/tree/HEAD/packages/shiki) from 1.6.0 to 1.10.3.
- [Release notes](https://github.com/shikijs/shiki/releases)
- [Changelog](https://github.com/shikijs/shiki/blob/main/CHANGELOG.md)
- [Commits](https://github.com/shikijs/shiki/commits/v1.10.3/packages/shiki)

---
updated-dependencies:
- dependency-name: shiki
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 13:34:04 -07:00
MassiveJuice
e20dee2850 Fix: Table overflow-wrap: anywhere breaks words on mobile (#1259)
Closes #1258
2024-07-05 09:25:29 -07:00
dependabot[bot]
af1fdaac0a chore(deps-dev): bump tsx from 4.11.2 to 4.16.0 (#1256)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.11.2 to 4.16.0.
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.11.2...v4.16.0)

---
updated-dependencies:
- dependency-name: tsx
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-04 22:47:20 -04:00
Peter
5926d3f803 docs: replace .gitlab-ci.yml example with more reliable and faster ci job (#1243)
* replace .gitlab-ci.yml example with more reliable and faster ci job

* literally removing 1 space, inside a code block, in docs, just to make prettier not cry
2024-06-30 21:12:48 -07:00
Illia Pyshniak
e8277d017e i18n: Update uk-UA.ts (#1245)
Update the Ukrainian translation of Quartz according to the latest Ukrainian translation of Obsidian.
2024-06-30 21:11:21 -07:00
Christopher Tee
b053d354b6 deps: Bump Github Action versions (#1247) 2024-06-30 21:05:42 -07:00
L01D
dbe12c0d34 i18n: Improving Spanish & adding Catalan and British English (#1240)
* Create en-GB

* Rename en-GB to en-GB.ts

* Update es-ES.ts

* Update es-ES.ts

* Create ca-ES.ts

* Update es-ES.ts

* Update index.ts

* Update index.ts

* Update index.ts

* Update es-ES.ts
2024-06-30 21:03:45 -07:00
Seohyun Kim
21e75acc8d fix: "draft" true or false in frontmatter still removes from publishing #1244 (#1249)
* fix: draft bug #1244

* update: contents in folder before creating PR

* Update draft.ts
2024-06-30 20:59:08 -07:00
Sean Missingham
f7bd2137ec Permit Manual (and Scripted) Trigger of CI Job (#1251) 2024-06-30 20:58:34 -07:00
John Bowdre
3faf2ff6f5 feat(analytics): Cabin analytics support (#1221)
* add cabin analytics

* fix formatting
2024-06-18 13:38:45 -07:00
Jacky Zhao
1d94e9c303 css: use fit-content (closes #1194) 2024-06-17 22:13:31 -07:00
Jacky Zhao
48e16c943a chore(deps-dev): bump prettier 2024-06-17 21:46:43 -07:00
Jacky Zhao
cc5913b75c fix(ci): only publish tag on v4 origin 2024-06-17 21:45:58 -07:00
Jacky Zhao
265faef4e8 fix: properly compute relative path for explorer (closes #1055, #1066) 2024-06-17 21:43:32 -07:00
Jacky Zhao
541b470cfc fix: overflow fade for good (closes #1218) 2024-06-17 21:33:53 -07:00
dependabot[bot]
0a3be96dd6 chore(deps): bump ws from 8.17.0 to 8.17.1 (#1213)
Bumps [ws](https://github.com/websockets/ws) from 8.17.0 to 8.17.1.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.17.0...8.17.1)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-17 20:37:04 -07:00
dependabot[bot]
3cb9392a7a chore(deps): bump preact-render-to-string from 6.5.4 to 6.5.5 (#1214)
Bumps [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) from 6.5.4 to 6.5.5.
- [Release notes](https://github.com/preactjs/preact-render-to-string/releases)
- [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md)
- [Commits](https://github.com/preactjs/preact-render-to-string/compare/v6.5.4...v6.5.5)

---
updated-dependencies:
- dependency-name: preact-render-to-string
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-17 20:34:45 -07:00
dependabot[bot]
569ee74633 chore(deps): bump workerpool from 9.1.1 to 9.1.2 (#1215)
Bumps [workerpool](https://github.com/josdejong/workerpool) from 9.1.1 to 9.1.2.
- [Changelog](https://github.com/josdejong/workerpool/blob/master/HISTORY.md)
- [Commits](https://github.com/josdejong/workerpool/compare/v9.1.1...v9.1.2)

---
updated-dependencies:
- dependency-name: workerpool
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-17 20:33:00 -07:00
Paul Trotter
42640bceb5 Check link isExternal before adding target="_blank" (#1211)
Fixes #1186 openLinksInNewTab opens ALL links in new tabs. Fixed to reflect documented behavior here: https://quartz.jzhao.xyz/plugins/CrawlLinks
2024-06-16 22:33:28 -07:00
Emile Bangma
3e14b2b89b fix(wikilinks): pdf page linking (#1207) 2024-06-14 09:17:46 -07:00
Emile Bangma
81d00fc9c0 .callout-content support (#1188)
* .callout-content support

* Use BlockContent | FootnoteContent for callout body

* Update quartz/plugins/transformers/ofm.ts

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>

* Refactor

* Combine child selectors

* Fix multiple callout members

* Empty check

* Replace splice

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2024-06-13 16:02:00 -07:00
Callum Barker
a12d76afdb fix: fix explorer view gradient positioning on mobile (fixes #906) (#1206) 2024-06-13 12:47:22 -07:00
x4dr
19e127f6ad fix DOMLoaded in code examples (#1204) 2024-06-13 09:38:48 -07:00
Leo Lazou
0472daa003 homepage coloured as visited in the Graph (#1128)
simplifies slug from FullSlug to SimpleSlug before storing it in the visited pages list in memory
this leads to "index" page and "folder/index", "tags/tag/index" being stored a "/", "folder/" and "tags/tag/" respectively in the list of visited pages.
this ensures that the homepage is rightfully coloured as a visited page in the "color" function of the graph
2024-06-12 09:39:49 -07:00
dependabot[bot]
63d51a8cc5 chore(deps): bump preact-render-to-string from 6.4.2 to 6.5.4 (#1198)
Bumps [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) from 6.4.2 to 6.5.4.
- [Release notes](https://github.com/preactjs/preact-render-to-string/releases)
- [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md)
- [Commits](https://github.com/preactjs/preact-render-to-string/compare/v6.4.2...v6.5.4)

---
updated-dependencies:
- dependency-name: preact-render-to-string
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 09:34:36 -07:00
dependabot[bot]
9032717486 chore(deps): bump preact from 10.20.1 to 10.22.0 (#1195)
Bumps [preact](https://github.com/preactjs/preact) from 10.20.1 to 10.22.0.
- [Release notes](https://github.com/preactjs/preact/releases)
- [Commits](https://github.com/preactjs/preact/compare/10.20.1...10.22.0)

---
updated-dependencies:
- dependency-name: preact
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 09:31:50 -07:00
dependabot[bot]
3968b850c2 chore(deps): bump @floating-ui/dom from 1.6.3 to 1.6.5 (#1196)
Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.6.3 to 1.6.5.
- [Release notes](https://github.com/floating-ui/floating-ui/releases)
- [Changelog](https://github.com/floating-ui/floating-ui/blob/master/packages/dom/CHANGELOG.md)
- [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.6.5/packages/dom)

---
updated-dependencies:
- dependency-name: "@floating-ui/dom"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-10 13:57:08 -07:00
dependabot[bot]
688c5484a9 chore(deps-dev): bump tsx from 4.11.0 to 4.11.2 (#1183)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.11.0 to 4.11.2.
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.11.0...v4.11.2)

---
updated-dependencies:
- dependency-name: tsx
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-04 18:16:34 -04:00
dependabot[bot]
09038f1604 chore(deps): bump rehype-pretty-code from 0.13.0 to 0.13.2 (#1184)
Bumps [rehype-pretty-code](https://github.com/rehype-pretty/rehype-pretty-code/tree/HEAD/packages/core) from 0.13.0 to 0.13.2.
- [Release notes](https://github.com/rehype-pretty/rehype-pretty-code/releases)
- [Changelog](https://github.com/rehype-pretty/rehype-pretty-code/blob/master/packages/core/CHANGELOG.md)
- [Commits](https://github.com/rehype-pretty/rehype-pretty-code/commits/rehype-pretty-code@0.13.2/packages/core)

---
updated-dependencies:
- dependency-name: rehype-pretty-code
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-04 18:16:18 -04:00
Leo Lazou
244801af65 idea: Tags appear as hollow circles on the graph (#1129)
* Tags appear as hollow circles on the graph

Added a few lines to make tags appear as hollow circles on the graph, as opposed to pages which are plain circles, for better visual separation.

* Applied Prettier code style
2024-05-30 10:42:22 -07:00
Jacky Zhao
73a5ec87f1 docs: fix link to path tests (closes #1163) 2024-05-29 13:04:58 -07:00
Jacky Zhao
520acbbf6f docs: inline code syntax highlighting (closes #1162) 2024-05-29 13:04:03 -07:00
Dinu Blanovschi
0b9f79e1b7 feat(graph): obsidianLikeFocusOnHover (#1017)
* feat(graph): obsidianLikeFocusOnHover

* fix: prettier

* fix: remove option from config

* fix: for when opacityOld < 0.2

* fix: prettier
2024-05-29 12:53:23 -07:00
RunTheBot
94fbf5b066 fix: Reorder Unified.js plugins to fix #1132 (#1139)
* Reorder Unified.js to fix #1132

* moved latex farther down for bette luck
2024-05-29 12:52:53 -07:00
dependabot[bot]
3e0e06ff8a chore(deps): bump ws from 8.16.0 to 8.17.0 (#1169)
Bumps [ws](https://github.com/websockets/ws) from 8.16.0 to 8.17.0.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.16.0...8.17.0)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-29 12:49:55 -07:00
dependabot[bot]
e57984dafc chore(deps-dev): bump tsx from 4.9.3 to 4.11.0 (#1168)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.9.3 to 4.11.0.
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.9.3...v4.11.0)

---
updated-dependencies:
- dependency-name: tsx
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-29 12:48:55 -07:00
Alex Nordstrom
9ff4626d25 fix: change callout metadata regex to include non-letter characters (#1174)
* fix: change callout metadata regex to include non-letter characters

* fix: make metadata regex non-greedy

This allows for users to have callouts such as
> [!NOTE|left foo-bar 123] a ]+ title with square brackets [s] a
> Contents
2024-05-29 12:48:39 -07:00
Max
a99e854d1e docs: Update showcase.md (#1176)
Added Gatekeeper Wiki.
2024-05-29 12:47:45 -07:00
Alex Nordstrom
77d6d9623f feat: add callout metadata parsing (#1172) 2024-05-28 15:23:28 -07:00
James Bennion-Pedley
9c726efa33 feat(i18n): homepage link for 404 pages (#1117)
* Add homepage link with internationalization

* Construct pathname from baseUrl config value

* More robust URL manipulation

* Add Farsi (#1133)

* Fix bad rebase
2024-05-22 16:44:54 -04:00
Yohann Bacha
81a4e20236 feat: ability to hide tags in the recent notes component (#1147)
* feat: ability to hide tags in the recent notes component

* docs: recent notes custom parameters in a table

* docs: revert recent notes doc to bullet points

* fix: linter issues

* Update docs/features/recent notes.md

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2024-05-21 09:50:58 -07:00
dependabot[bot]
cf1b3f270b chore(deps): bump shiki from 1.2.3 to 1.6.0 (#1149)
updated-dependencies:
- dependency-name: shiki
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-20 13:11:16 -07:00
dependabot[bot]
a655cec9f6 chore(deps): bump rimraf from 5.0.5 to 5.0.7 (#1150)
updated-dependencies:
- dependency-name: rimraf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-20 13:11:08 -07:00
Bartłomiej Garbiec
a97e72f219 i18n: add Polish translation (#1148)
* Create pl-PL.ts

* add pl-PL to index.ts

* import pl-PL in index.ts
2024-05-20 12:36:32 -07:00
dependabot[bot]
e3cfe1f22f chore(deps-dev): bump typescript from 5.4.3 to 5.4.5 (#1092)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.3 to 5.4.5.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.3...v5.4.5)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-13 23:21:01 -07:00
dependabot[bot]
535af55ec8 chore(deps): bump hast-util-to-html from 9.0.0 to 9.0.1 (#1137)
Bumps [hast-util-to-html](https://github.com/syntax-tree/hast-util-to-html) from 9.0.0 to 9.0.1.
- [Release notes](https://github.com/syntax-tree/hast-util-to-html/releases)
- [Commits](https://github.com/syntax-tree/hast-util-to-html/compare/9.0.0...9.0.1)

---
updated-dependencies:
- dependency-name: hast-util-to-html
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-13 14:25:42 -07:00
Eledah
3c4d54352d feat(i18n): add Farsi (#1133)
* Add fa-IR translation via upload

* Add files via upload

* Ran npm run format
2024-05-13 09:12:06 -07:00
dependabot[bot]
67f3614f3d chore(deps-dev): bump tsx from 4.7.1 to 4.9.3 (#1120)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.7.1 to 4.9.3.
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](https://github.com/privatenumber/tsx/compare/v4.7.1...v4.9.3)

---
updated-dependencies:
- dependency-name: tsx
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-12 19:05:27 -07:00
zenodotus280
438ea6d73b docs(showcase): add patternlanguage.cc (#1135)
A self-contained hypertextual catalog of architectural ideas and aesthetic inquiry.
2024-05-12 19:04:21 -07:00
John Bowdre
d03fdc235a feat(analytics): Tinylytics support (#1118)
* add tinylytics support

* fix formatting

* add trailing semicolon for consistency
2024-05-06 09:30:21 -07:00
Emmanuel Ferdman
aee9145691 fix: update link to hosting page (#1054)
* fix: update link to hosting page

* chore: update correct path with using alias

---------

Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com>
2024-04-27 21:07:26 -07:00
dependabot[bot]
a37c7775e7 chore(deps): bump preact-render-to-string from 6.4.0 to 6.4.2 (#1094)
Bumps [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) from 6.4.0 to 6.4.2.
- [Release notes](https://github.com/preactjs/preact-render-to-string/releases)
- [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md)
- [Commits](https://github.com/preactjs/preact-render-to-string/compare/6.4.0...v6.4.2)

---
updated-dependencies:
- dependency-name: preact-render-to-string
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-27 21:04:38 -07:00
iacore
e763e1969e Allow pnpm quartz (#1078)
Co-authored-by: iacore <noreply+gpg-stub@1a-insec.net>
2024-04-19 13:02:49 -07:00
Lucas-BRT
6a019dae13 fix: unnecessery 'm' letter removed in pt-BR (#1100) 2024-04-16 18:02:59 -07:00
dependabot[bot]
4d73b8289d chore(deps): bump workerpool from 9.1.0 to 9.1.1 (#1073)
Bumps [workerpool](https://github.com/josdejong/workerpool) from 9.1.0 to 9.1.1.
- [Changelog](https://github.com/josdejong/workerpool/blob/master/HISTORY.md)
- [Commits](https://github.com/josdejong/workerpool/compare/v9.1.0...v9.1.1)

---
updated-dependencies:
- dependency-name: workerpool
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-12 02:33:05 -04:00
dependabot[bot]
8010093df7 chore(deps-dev): bump @types/node from 20.11.29 to 20.12.5 (#1074)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.29 to 20.12.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-12 02:30:21 -04:00
kwyuan
1f032f538b feat(analytics): PostHog support (#1072) 2024-04-08 18:43:09 -07:00
dependabot[bot]
83bdcd58e6 chore(deps): bump d3 from 7.8.5 to 7.9.0 (#1047)
Bumps [d3](https://github.com/d3/d3) from 7.8.5 to 7.9.0.
- [Release notes](https://github.com/d3/d3/releases)
- [Changelog](https://github.com/d3/d3/blob/main/CHANGES.md)
- [Commits](https://github.com/d3/d3/compare/v7.8.5...v7.9.0)

---
updated-dependencies:
- dependency-name: d3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 16:02:00 -04:00
Race Williams
dd82ab8d79 fix: broken doc links on /plugins/* (#1053)
* Update Assets.md

* expand fix for every /plugins page
2024-04-03 13:30:41 -07:00
dependabot[bot]
561dafce5f chore(deps): bump shiki from 1.2.0 to 1.2.3 (#1048)
Bumps [shiki](https://github.com/shikijs/shiki/tree/HEAD/packages/shiki) from 1.2.0 to 1.2.3.
- [Release notes](https://github.com/shikijs/shiki/releases)
- [Changelog](https://github.com/shikijs/shiki/blob/main/CHANGELOG.md)
- [Commits](https://github.com/shikijs/shiki/commits/v1.2.3/packages/shiki)

---
updated-dependencies:
- dependency-name: shiki
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 23:32:36 -04:00
Emile Bangma
5ec61468d5 fix(wikilinks): proper escaping of pipe character in wikilinks inside tables (#1040) 2024-03-31 09:44:50 -07:00
Hydrophobefireman
aa4f5294a3 fix: do not render <p> inside FolderContent article (#1044)
it can lead to nested <p>'s which is actually [invalid html](https://www.w3.org/TR/html401/struct/text.html#h-9.3.1:~:text=The%20P%20element%20represents%20a%20paragraph.%20It%20cannot%20contain%20block%2Dlevel%20elements%20(including%20P%20itself).)
2024-03-31 09:44:20 -07:00
dependabot[bot]
fafe50b0c5 chore(deps): bump preact from 10.19.6 to 10.20.1 (#1035)
Bumps [preact](https://github.com/preactjs/preact) from 10.19.6 to 10.20.1.
- [Release notes](https://github.com/preactjs/preact/releases)
- [Commits](https://github.com/preactjs/preact/compare/10.19.6...10.20.1)

---
updated-dependencies:
- dependency-name: preact
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-26 04:47:15 -04:00
dependabot[bot]
8f13a38b5a chore(deps-dev): bump typescript from 5.4.2 to 5.4.3 (#1036)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.2 to 5.4.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.2...v5.4.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-26 04:46:52 -04:00
Emile Bangma
d75928ad5c fix(assets): pdf page linking support. (#1025)
* github-slugger pdf workaround

* Skip sluggifying on pdf file extension

* Account for pdf files without anchor

* Address feedback
2024-03-24 16:23:25 -07:00
Jacky Zhao
0a2b52f618 simpler katex fix 2024-03-24 15:50:38 -07:00
Emile Bangma
8437d9da72 fix(style): LaTex/KaTeX overflow (#1027)
* LaTex/KaTeX overflow fix

* prettier

* Add !important modifier

* Added overflow-x override

* Refactor without !important

* Refactor scss notation

* Formatting scss
2024-03-24 15:43:36 -07:00
Jorge Marcelo Risco
70d86ff096 i18n: pt-BR translation (#1024)
* i18n: pt-br

* i18n: pt-br translation

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2024-03-24 09:40:01 -07:00
Kun-Szabó Kristóf
6efc4dd724 i18n: add Hungarian translations (#1023)
* add Hungarian translations

* typo: _ instead of - in hu-HU

* run prettier

* revert prettier messing up tsconfig

* Update hu-HU.ts
2024-03-24 09:35:07 -07:00
Xinyang Yu
85a737b4ee docs: Update showcase.md (#1031) 2024-03-24 09:33:53 -07:00
dependabot[bot]
de6f469011 chore(deps-dev): bump @types/node from 20.11.25 to 20.11.29 (#1010)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.25 to 20.11.29.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-18 18:54:12 -07:00
dependabot[bot]
668640d641 chore(deps): bump shiki from 1.1.7 to 1.2.0 (#1011)
Bumps [shiki](https://github.com/shikijs/shiki/tree/HEAD/packages/shiki) from 1.1.7 to 1.2.0.
- [Release notes](https://github.com/shikijs/shiki/releases)
- [Changelog](https://github.com/shikijs/shiki/blob/main/CHANGELOG.md)
- [Commits](https://github.com/shikijs/shiki/commits/v1.2.0/packages/shiki)

---
updated-dependencies:
- dependency-name: shiki
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-18 18:54:01 -07:00
dependabot[bot]
8007ec0f82 chore(deps): bump lightningcss from 1.24.0 to 1.24.1 (#1012)
Bumps [lightningcss](https://github.com/parcel-bundler/lightningcss) from 1.24.0 to 1.24.1.
- [Release notes](https://github.com/parcel-bundler/lightningcss/releases)
- [Commits](https://github.com/parcel-bundler/lightningcss/compare/v1.24.0...v1.24.1)

---
updated-dependencies:
- dependency-name: lightningcss
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-18 18:53:19 -07:00
Emile Bangma
7e22c38f8e fix(wikilinks): handle wikilinks inside tables seperately from other wikilinks (#1005)
* fix(wikilinks): handle wikilinks inside tables seperately from other wikilinks

* Prettier

* Cleaned up duplicate code

* Remove test logging

* Refactored and fixed for non-aliased wikilinks inside table

* Updated naming and comments

* Updated comment of wikilink regex

* Updated regex to match previous formatting

* Match table even if EOF is immediately after the table.

* Update quartz/plugins/transformers/ofm.ts

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>

* Change table escape replace to non-regex version

* Prettier

* Prettier

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2024-03-17 18:16:04 -07:00
Jacky Zhao
daa8796554 fix: format 2024-03-17 18:15:42 -07:00
Jacky Zhao
91f0a2abb2 feat: support rich descriptions in tag listing page (closes #908) 2024-03-17 18:00:04 -07:00
makondratev
38d9d52137 feat(search): add search by title/content index and tag at the same time (#978)
* feat(search): add search by title/content index and tag at the same time

* fix(search): set search type to basic and remove tag from term for proper highlightning and scroll when searched by tag and title/content index

* fix(search): use indexOf to find space so it is easier to read

* fix(search): trim trailing whitespaces before splitting

* fix(search): set limit to 10000 for combined search mode (to make filter by tag more accurate)
2024-03-17 17:48:00 -07:00
Denis Bezykornov
253497cad4 docs: add config for Caddy server (#1002) 2024-03-16 10:16:58 -07:00
Emile Bangma
4691369abf fix(wikilinks): only escape alias in wikilinks inside tables (#1000) 2024-03-16 09:23:08 -04:00
Aaron Pham
7164857f6e chore(ofm): remove unused (#999)
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
2024-03-15 18:17:42 -07:00
dependabot[bot]
47024022e8 chore(deps-dev): bump @types/node from 20.11.24 to 20.11.25 (#990)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.24 to 20.11.25.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-15 18:29:14 -04:00
Mara-Li
b98e4be665 feat(i18n): Add French translation for reading time (#998)
Signed-off-by: Mara-Li <lili.simonetti@outlook.fr>
2024-03-15 18:28:31 -04:00
catcodeme
8be51a0504 fix: wikiLink in table (#993)
* fix: wikiLink in table

- update regexp to make '\' to group in alias
- handle alias using block_id

* style: format with prettier

* style: add comment for block_ref(without alias) in table

---------

Co-authored-by: hulinjiang <hulinjiang@58.com>
2024-03-14 23:25:01 -07:00
Linus Sehn
92cc23dc45 feat(plugin): citations (#984)
* feat: add rehype-citations

* feat: add citations transformer plugin

* feat: add rehype-rewrite

* feat: add csl option and add no-popover to citation links

* revert: add rehype-rewrite

04b2692 'feat: add rehype-rewrite'

* feat: use existing package for html manipulation

* fix: remove `console.log()`
2024-03-13 03:59:37 -04:00
dependabot[bot]
097abc3cda chore(deps): bump async-mutex from 0.4.1 to 0.5.0 (#991)
Bumps [async-mutex](https://github.com/DirtyHairy/async-mutex) from 0.4.1 to 0.5.0.
- [Changelog](https://github.com/DirtyHairy/async-mutex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DirtyHairy/async-mutex/compare/v0.4.1...v0.5.0)

---
updated-dependencies:
- dependency-name: async-mutex
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 13:41:48 -07:00
dependabot[bot]
a00324ddfd chore(deps-dev): bump typescript from 5.3.3 to 5.4.2 (#989)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.3.3 to 5.4.2.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.3.3...v5.4.2)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-11 13:41:41 -07:00
Mara-Li
9fff6d7d0d fix: spelling error (#987)
I really don't know why I translated this like that into "pas trouvé", and it bugged me a lot. I finally fixed it…

Signed-off-by: Mara-Li <lili.simonetti@outlook.fr>
2024-03-11 09:46:53 -07:00
Matt Vogel
0f5a9d7b66 feat: separated content meta (#929)
to allow for CSS styling
2024-03-10 09:57:10 -07:00
kabirgh
b4236e5142 feat(perf:fast-rebuilds): Stop mutating resources param in ComponentResources emitter (#977)
* Stop mutating resources param in ComponentResources emitter

* Add done rebuilding log for fast rebuilds

* Move google font loading to Head component

* Simplify code and fix comment
2024-03-09 16:42:23 -08:00
Emile Bangma
6e0c102970 fix(transclusion): prevent duplicate transclusion if multiple transclusions are present. (#982) 2024-03-09 16:14:31 -08:00
Emile Bangma
94a54698ab fix(resources): Use full path to font when cdnCache is false (#976) 2024-03-09 11:59:55 -05:00
Emile Bangma
2e9a0c21db fix(description): first sentence no longer repeats until max length (#981) 2024-03-09 08:43:40 -08:00
Aaron Pham
b30a200bd4 fix(i18n): make sure to use correct fileData for manual localization (#975)
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
2024-03-08 09:14:22 -08:00
Emile Bangma
6d59aa8201 fix(description): counts characters instead of words (#972)
* fix(description): make sure description counts characters instead of words

* ref: removed duplicate ternary
2024-03-08 04:04:44 -05:00
Aaron Pham
141dd3b51f fix(description): make sure to we join space correctly (#970)
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
2024-03-06 19:45:02 -08:00
Tyler Funk
3d4a94dda3 feat(analytics): Goatcounter support (#956)
* Add options to support goatcounter analytics

* goatcounter: support self-hosted

* Add to configuration docs for goatcounter settings

* use https instead of protocol-relative link for goatcounter js
2024-03-06 19:44:34 -08:00
Jacky Zhao
ba6c7a73d1 fix: remove extra # from tag content 2024-03-06 19:00:37 -08:00
Aaron Pham
f44e4d25e6 fix(tag): remove hash on main page (#969)
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
2024-03-06 18:24:50 -08:00
Matt Vogel
001c166825 fix(tag): move hash to sass styling only (#930) 2024-03-06 20:25:39 -05:00
Emile Bangma
e13cafe070 feat: support youtube playlist iframe (#968)
* feat: support youtube playlist iframe

* chore: updated Youtube embed documentation to include playlists
2024-03-06 09:45:31 -08:00
Jacky Zhao
0ca8a2ac7c chore: transclude subsection without dynamic regex construction 2024-03-05 22:17:58 -08:00
dependabot[bot]
a506cedd7a chore(deps-dev): bump @types/node from 20.11.19 to 20.11.24 (#958)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.19 to 20.11.24.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-05 21:59:37 -08:00
Emile Bangma
5163504517 fix: transclude all subsections for embedded call (closes #963) (#964) 2024-03-06 00:53:35 -05:00
Aaron Pham
73a890ab12 revert: "fix(callout): reorder the plugins to render latex on callout… (#965)
This reverts commit 018c6358c4.
2024-03-05 19:37:28 -08:00
dependabot[bot]
83ab39c7bd chore(deps): bump shiki from 1.1.6 to 1.1.7 (#959)
Bumps [shiki](https://github.com/shikijs/shiki/tree/HEAD/packages/shiki) from 1.1.6 to 1.1.7.
- [Release notes](https://github.com/shikijs/shiki/releases)
- [Changelog](https://github.com/shikijs/shiki/blob/main/CHANGELOG.md)
- [Commits](https://github.com/shikijs/shiki/commits/v1.1.7/packages/shiki)

---
updated-dependencies:
- dependency-name: shiki
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-04 12:55:44 -08:00
dependabot[bot]
059dd1260e chore(deps): bump preact-render-to-string from 6.3.1 to 6.4.0 (#960)
Bumps [preact-render-to-string](https://github.com/developit/preact-render-to-string) from 6.3.1 to 6.4.0.
- [Release notes](https://github.com/developit/preact-render-to-string/releases)
- [Changelog](https://github.com/preactjs/preact-render-to-string/blob/main/CHANGELOG.md)
- [Commits](https://github.com/developit/preact-render-to-string/compare/v6.3.1...6.4.0)

---
updated-dependencies:
- dependency-name: preact-render-to-string
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-04 12:55:02 -08:00
dependabot[bot]
a13d8e84b2 chore(deps): bump lightningcss from 1.23.0 to 1.24.0 (#961)
Bumps [lightningcss](https://github.com/parcel-bundler/lightningcss) from 1.23.0 to 1.24.0.
- [Release notes](https://github.com/parcel-bundler/lightningcss/releases)
- [Commits](https://github.com/parcel-bundler/lightningcss/compare/v1.23.0...v1.24.0)

---
updated-dependencies:
- dependency-name: lightningcss
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-04 12:54:21 -08:00
Aaron Pham
cec3662c74 feat(graph): focusOnHover (#954)
by default, globalGraph will enable focusOnHover, similar to Obsidian.

---------

Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
2024-03-04 15:09:20 -05:00
Emile Bangma
bcb5b2df09 feat(frontmatter): configure max length for description (#946)
* Sentence length check

* Replace external links with domain name.

* Updated documentation.

* Updated replacement values.

* Updated Regex based on feedback.

* Check description for undefined

* Updated external url transform regex.

* Updated formatting
2024-03-04 09:52:28 -08:00
sventec
bd05950c2d fix(docs): correct ExplicitPublish as filters instead of transformers (#953) 2024-03-03 19:40:42 -05:00
Jacky Zhao
2a7e61ae2a feat: support transcluding codeblocks and blockquotes (closes #940) 2024-03-03 12:31:55 -08:00
dependabot[bot]
566f3cf9f8 chore(deps): bump remark-smartypants from 2.0.0 to 2.1.0 (#755)
Bumps [remark-smartypants](https://github.com/silvenon/remark-smartypants) from 2.0.0 to 2.1.0.
- [Release notes](https://github.com/silvenon/remark-smartypants/releases)
- [Commits](https://github.com/silvenon/remark-smartypants/compare/v2.0.0...v2.1.0)

---
updated-dependencies:
- dependency-name: remark-smartypants
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-03 11:27:54 -08:00
Aaron Pham
018c6358c4 fix(callout): reorder the plugins to render latex on callout title (closes #952) (#934)
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
2024-03-03 10:39:29 -08:00
HakuGuen
1c42b6365c feat(i18n): add Vietnamese translation (#950) 2024-02-29 19:14:20 -05:00
kon-foo
f200a0be22 fix: correct umami host for self-hosted (#939)
* fixed umami script path for self-hosted version

* Update quartz/plugins/emitters/componentResources.ts

Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com>

---------

Co-authored-by: Aaron Pham <29749331+aarnphm@users.noreply.github.com>
2024-02-27 11:05:28 -05:00
kon-foo
b9dee0775c docs: Clarifications in the Explorer Docs (#938)
add example to filter by tags.
2024-02-26 13:55:47 -08:00
dependabot[bot]
66a5855fad chore(deps): bump chokidar from 3.5.3 to 3.6.0 (#937)
Bumps [chokidar](https://github.com/paulmillr/chokidar) from 3.5.3 to 3.6.0.
- [Release notes](https://github.com/paulmillr/chokidar/releases)
- [Commits](https://github.com/paulmillr/chokidar/compare/3.5.3...3.6.0)

---
updated-dependencies:
- dependency-name: chokidar
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 13:54:15 -08:00
dependabot[bot]
4957eaa2d0 chore(deps): bump preact from 10.19.5 to 10.19.6 (#935)
Bumps [preact](https://github.com/preactjs/preact) from 10.19.5 to 10.19.6.
- [Release notes](https://github.com/preactjs/preact/releases)
- [Commits](https://github.com/preactjs/preact/compare/10.19.5...10.19.6)

---
updated-dependencies:
- dependency-name: preact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 16:17:42 -05:00
Aaron Pham
6b90d03ca6 chore(type): export attribute for theme key (#933)
Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com>
2024-02-26 09:53:45 -08:00
Aaron Pham
d6e79d1ea6 chore(types): update correct annotations for pages (#928) 2024-02-25 16:58:21 -08:00
Aaron Pham
2f10da7766 docs: fix tag page oops (#925) 2024-02-25 09:00:26 -08:00
Jacky Zhao
67647d9167 ci: also checkout and install node before tagging 2024-02-23 19:08:39 -08:00
Jacky Zhao
b88d3d292b ci: fix typo in runs-on 2024-02-23 19:05:26 -08:00
Jacky Zhao
c53fd5b56f ci: tag as a separate step 2024-02-23 19:04:38 -08:00
115 changed files with 2714 additions and 979 deletions

View File

@@ -7,6 +7,7 @@ on:
push:
branches:
- v4
workflow_dispatch:
jobs:
build-and-test:
@@ -18,17 +19,17 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -46,11 +47,23 @@ jobs:
- name: Ensure Quartz builds, check bundle info
run: npx quartz build --bundleInfo
publish-tag:
if: ${{ github.repository == 'jackyzha0/quartz' && github.ref == 'refs/heads/v4' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Get package version
run: node -p -e '`PACKAGE_VERSION=${require("./package.json").version}`' >> $GITHUB_ENV
- name: Create release tag
uses: pkgdeps/git-tag-action@v2
uses: pkgdeps/git-tag-action@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
github_repo: ${{ github.repository }}

1
.node-version Normal file
View File

@@ -0,0 +1 @@
v20.9.0

View File

@@ -129,11 +129,11 @@ export default (() => {
return <button id="btn">Click me</button>
}
YourComponent.beforeDOM = `
YourComponent.beforeDOMLoaded = `
console.log("hello from before the page loads!")
`
YourComponent.afterDOM = `
YourComponent.afterDOMLoaded = `
document.getElementById('btn').onclick = () => {
alert('button clicked!')
}
@@ -180,7 +180,7 @@ export default (() => {
return <button id="btn">Click me</button>
}
YourComponent.afterDOM = script
YourComponent.afterDOMLoaded = script
return YourComponent
}) satisfies QuartzComponentConstructor
```

View File

@@ -260,11 +260,11 @@ export const ContentPage: QuartzEmitterPlugin = () => {
...defaultContentPageLayout,
pageBody: Content(),
}
const { head, header, beforeBody, pageBody, left, right, footer } = layout
const { head, header, beforeBody, pageBody, afterBody, left, right, footer } = layout
return {
name: "ContentPage",
getQuartzComponents() {
return [head, ...header, ...beforeBody, pageBody, ...left, ...right, footer]
return [head, ...header, ...beforeBody, pageBody, ...afterBody, ...left, ...right, footer]
},
async emit(ctx, content, resources, emit): Promise<FilePath[]> {
const cfg = ctx.cfg.configuration

View File

@@ -48,4 +48,4 @@ Here are the main types of slugs with a rough description of each type of path:
- `SimpleSlug`: cannot be relative and shouldn't have `/index` as an ending or a file extension. It _can_ however have a trailing slash to indicate a folder path.
- `RelativeURL`: must start with `.` or `..` to indicate it's a relative URL. Shouldn't have `/index` as an ending or a file extension but can contain a trailing slash.
To get a clearer picture of how these relate to each other, take a look at the path tests in `quartz/path.test.ts`.
To get a clearer picture of how these relate to each other, take a look at the path tests in `quartz/util/path.test.ts`.

View File

@@ -28,6 +28,10 @@ This part of the configuration concerns anything that can affect the whole site.
- `{ 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/);
- `{ provider: 'goatcounter', websiteId: 'my-goatcounter-id' }` (managed) or `{ provider: 'goatcounter', websiteId: 'my-goatcounter-id', host: 'my-goatcounter-domain.com', scriptSrc: 'https://my-url.to/counter.js' }` (self-hosted) use [GoatCounter](https://goatcounter.com);
- `{ provider: 'posthog', apiKey: '<your-posthog-project-apiKey>', host: '<your-posthog-host>' }`: use [Posthog](https://posthog.com/);
- `{ provider: 'tinylytics', siteId: '<your-site-id>' }`: use [Tinylytics](https://tinylytics.app/);
- `{ provider: 'cabin' }` or `{ provider: 'cabin', host: 'https://cabin.example.com' }` (custom domain): use [Cabin](https://withcabin.com);
- `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`.
@@ -49,6 +53,7 @@ This part of the configuration concerns anything that can affect the whole site.
- `secondary`: link colour, current [[graph view|graph]] node
- `tertiary`: hover states and visited [[graph view|graph]] nodes
- `highlight`: internal link background, highlighted text, [[syntax highlighting|highlighted lines of code]]
- `textHighlight`: markdown highlighted text background
## Plugins
@@ -73,10 +78,10 @@ You can customize the behaviour of Quartz by adding, removing and reordering plu
> [!note]
> Each node is modified by every transformer _in order_. Some transformers are position sensitive, so you may need to pay particular attention to whether they need to come before or after certain other plugins.
You should take care to add the plugin to the right entry corresponding to its plugin type. For example, to add the [[ExplicitPublish]] plugin (a [[tags/plugin/transformer|Transformer]], you would add the following line:
You should take care to add the plugin to the right entry corresponding to its plugin type. For example, to add the [[ExplicitPublish]] plugin (a [[tags/plugin/filter|Filter]]), you would add the following line:
```ts title="quartz.config.ts"
transformers: [
filters: [
...
Plugin.ExplicitPublish(),
...

View File

@@ -39,6 +39,17 @@ a & b & c
\end{bmatrix}
$$
$$
\begin{array}{rll}
E \psi &= H\psi & \text{Expanding the Hamiltonian Operator} \\
&= -\frac{\hbar^2}{2m}\frac{\partial^2}{\partial x^2} \psi + \frac{1}{2}m\omega x^2 \psi & \text{Using the ansatz $\psi(x) = e^{-kx^2}f(x)$, hoping to cancel the $x^2$ term} \\
&= -\frac{\hbar^2}{2m} [4k^2x^2f(x)+2(-2kx)f'(x) + f''(x)]e^{-kx^2} + \frac{1}{2}m\omega x^2 f(x)e^{-kx^2} &\text{Removing the $e^{-kx^2}$ term from both sides} \\
& \Downarrow \\
Ef(x) &= -\frac{\hbar^2}{2m} [4k^2x^2f(x)-4kxf'(x) + f''(x)] + \frac{1}{2}m\omega x^2 f(x) & \text{Choosing $k=\frac{im}{2}\sqrt{\frac{\omega}{\hbar}}$ to cancel the $x^2$ term, via $-\frac{\hbar^2}{2m}4k^2=\frac{1}{2}m \omega$} \\
&= -\frac{\hbar^2}{2m} [-4kxf'(x) + f''(x)] \\
\end{array}
$$
> [!warn]
> Due to limitations in the [underlying parsing library](https://github.com/remarkjs/remark-math), block math in Quartz requires the `$$` delimiters to be on newlines like above.

83
docs/features/comments.md Normal file
View File

@@ -0,0 +1,83 @@
---
title: Comments
tags:
- component
---
Quartz also has the ability to hook into various providers to enable readers to leave comments on your site.
![[giscus-example.png]]
As of today, only [Giscus](https://giscus.app/) is supported out of the box but PRs to support other providers are welcome!
## Providers
### Giscus
First, make sure that the [[setting up your GitHub repository|GitHub]] repository you are using for your Quartz meets the following requirements:
1. The **repository is [public](https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/setting-repository-visibility#making-a-repository-public)**, otherwise visitors will not be able to view the discussion.
2. The **[giscus](https://github.com/apps/giscus) app is installed**, otherwise visitors will not be able to comment and react.
3. The **Discussions feature is turned on** by [enabling it for your repository](https://docs.github.com/en/github/administering-a-repository/managing-repository-settings/enabling-or-disabling-github-discussions-for-a-repository).
Then, use the [Giscus site](https://giscus.app/#repository) to figure out what your `repoId` and `categoryId` should be. Make sure you select `Announcements` for the Discussion category.
![[giscus-repo.png]]
![[giscus-discussion.png]]
After entering both your repository and selecting the discussion category, Giscus will compute some IDs that you'll need to provide back to Quartz. You won't need to manually add the script yourself as Quartz will handle that part for you but will need these values in the next step!
![[giscus-results.png]]
Finally, in `quartz.layout.ts`, edit the `afterBody` field of `sharedPageComponents` to include the following options but with the values you got from above:
```ts title="quartz.layout.ts"
afterBody: [
Component.Comments({
provider: 'giscus',
options: {
// from data-repo
repo: 'jackyzha0/quartz',
// from data-repo-id
repoId: 'MDEwOlJlcG9zaXRvcnkzODcyMTMyMDg',
// from data-category
category: 'Announcements',
// from data-category-id
categoryId: 'DIC_kwDOFxRnmM4B-Xg6',
}
}),
],
```
### Customization
Quartz also exposes a few of the other Giscus options as well and you can provide them the same way `repo`, `repoId`, `category`, and `categoryId` are provided.
```ts
type Options = {
provider: "giscus"
options: {
repo: `${string}/${string}`
repoId: string
category: string
categoryId: string
// how to map pages -> discussions
// defaults to 'url'
mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
// use strict title matching
// defaults to true
strict?: boolean
// whether to enable reactions for the main post
// defaults to true
reactionsEnabled?: boolean
// where to put the comment input box relative to the comments
// defaults to 'bottom'
inputPosition?: "top" | "bottom"
}
}
```

View File

@@ -61,7 +61,7 @@ export class FileNode {
children: FileNode[] // children of current node
name: string // last part of slug
displayName: string // what actually should be displayed in the explorer
file: QuartzPluginData | null // set if node is a file, see `QuartzPluginData` for more detail
file: QuartzPluginData | null // if node is a file, this is the file's metadata. See `QuartzPluginData` for more detail
depth: number // depth of current node
... // rest of implementation
@@ -167,6 +167,19 @@ Component.Explorer({
You can customize this by changing the entries of the `omit` set. Simply add all folder or file names you want to remove.
### Remove files by tag
You can access the frontmatter of a file by `node.file?.frontmatter?`. This allows you to filter out files based on their frontmatter, for example by their tags.
```ts title="quartz.layout.ts"
Component.Explorer({
filterFn: (node) => {
// exclude files with the tag "explorerexclude"
return node.file?.frontmatter?.tags?.includes("explorerexclude") !== true
},
})
```
### Show every element in explorer
To override the default filter function that removes the `tags` folder from the explorer, you can set the filter function to `undefined`.

View File

@@ -30,4 +30,4 @@ As with folder listings, you can also provide a description and title for a tag
## Customization
The folder listings are a functionality of the [[FolderPage]] plugin, the tag listings of the [[TagPage]] plugin. See the plugin pages for customization options.
Quartz allows you to define a custom sort ordering for content on both page types. The folder listings are a functionality of the [[FolderPage]] plugin, the tag listings of the [[TagPage]] plugin. See the plugin pages for customization options.

View File

@@ -9,6 +9,7 @@ Quartz can generate a list of recent notes based on some filtering and sorting c
- Changing the title from "Recent notes": pass in an additional parameter to `Component.RecentNotes({ title: "Recent writing" })`
- Changing the number of recent notes: pass in an additional parameter to `Component.RecentNotes({ limit: 5 })`
- Display the note's tags (defaults to true): `Component.RecentNotes({ showTags: false })`
- Show a 'see more' link: pass in an additional parameter to `Component.RecentNotes({ linkToMore: "tags/components" })`. This field should be a full slug to a page that exists.
- Customize filtering: pass in an additional parameter to `Component.RecentNotes({ filter: someFilterFunction })`. The filter function should be a function that has the signature `(f: QuartzPluginData) => boolean`.
- Customize sorting: pass in an additional parameter to `Component.RecentNotes({ sort: someSortFunction })`. By default, Quartz will sort by date and then tie break lexographically. The sort function should be a function that has the signature `(f1: QuartzPluginData, f2: QuartzPluginData) => number`. See `byDateAndAlphabetical` in `quartz/components/PageList.tsx` for an example.

View File

@@ -95,6 +95,16 @@ const [age, setAge] = useState(50)
const [name, setName] = useState("Taylor")
```
### Inline Highlighting
Append {:lang} to the end of inline code to highlight it like a regular code block.
```
This is an array `[1, 2, 3]{:js}` of numbers 1 through 3.
```
This is an array `[1, 2, 3]{:js}` of numbers 1 through 3.
### Line numbers
Syntax highlighting has line numbers configured automatically. If you want to start line numbers at a specific number, use `showLineNumbers{number}`:

View File

@@ -2,22 +2,12 @@
draft: true
---
## high priority backlog
- static dead link detection
- block links: 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
- docker support
## misc backlog
- breadcrumbs component
- static dead link detection
- cursor chat extension
- https://giscus.app/ extension
- sidenotes? https://github.com/capnfabs/paperesque
- direct match in search using double quotes
- https://help.obsidian.md/Advanced+topics/Using+Obsidian+URI
- audio/video embed styling
- Canvas
- parse all images in page: use this for page lists if applicable?
- CV mode? with print stylesheet

View File

@@ -57,18 +57,16 @@ jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for git info
- uses: actions/setup-node@v3
with:
node-version: 18.14
- uses: actions/setup-node@v4
- name: Install Dependencies
run: npm ci
- name: Build Quartz
run: npx quartz build
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
uses: actions/upload-pages-artifact@v3
with:
path: public
@@ -81,7 +79,7 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4
```
Then:
@@ -182,35 +180,31 @@ Using `docs.example.com` is an example of a subdomain. They're a simple way of c
## GitLab Pages
In your local Quartz, create a new file `.gitlab-ci.yaml`.
In your local Quartz, create a new file `.gitlab-ci.yml`.
```yaml title=".gitlab-ci.yaml"
```yaml title=".gitlab-ci.yml"
stages:
- build
- deploy
variables:
NODE_VERSION: "18.14"
image: node:20
cache: # Cache modules in between jobs
key: $CI_COMMIT_REF_SLUG
paths:
- .npm/
build:
stage: build
rules:
- if: '$CI_COMMIT_REF_NAME == "v4"'
before_script:
- apt-get update -q && apt-get install -y nodejs npm
- npm install -g n
- n $NODE_VERSION
- hash -r
- npm ci
- npm ci --cache .npm --prefer-offline
script:
- npx quartz build
artifacts:
paths:
- public
cache:
paths:
- ~/.npm/
key: "${CI_COMMIT_REF_SLUG}-node-${CI_COMMIT_REF_NAME}"
tags:
- docker
@@ -250,3 +244,21 @@ server {
}
}
```
### Using Caddy
Here's and example of how to do this with Caddy:
```caddy title="Caddyfile"
example.com {
root * /path/to/quartz/public
try_files {path} {path}.html {path}/ =404
file_server
encode gzip
handle_errors {
rewrite * /{err.status_code}.html
file_server
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

BIN
docs/images/giscus-repo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@@ -6,7 +6,7 @@ Quartz is a fast, batteries-included static-site generator that transforms Markd
## 🪴 Get Started
Quartz requires **at least [Node](https://nodejs.org/) v18.14** and `npm` v9.3.1 to function correctly. Ensure you have this installed on your machine before continuing.
Quartz requires **at least [Node](https://nodejs.org/) v20** and `npm` v9.3.1 to function correctly. Ensure you have this installed on your machine before continuing.
Then, in your terminal of choice, enter the following commands line by line:
@@ -31,7 +31,7 @@ If you prefer instructions in a video format you can try following Nicole van de
## 🔧 Features
- [[Obsidian compatibility]], [[full-text search]], [[graph view]], note transclusion, [[wikilinks]], [[backlinks]], [[features/Latex|Latex]], [[syntax highlighting]], [[popover previews]], [[Docker Support]], [[i18n|internationalization]] and [many more](./features) right out of the box
- [[Obsidian compatibility]], [[full-text search]], [[graph view]], note transclusion, [[wikilinks]], [[backlinks]], [[features/Latex|Latex]], [[syntax highlighting]], [[popover previews]], [[Docker Support]], [[i18n|internationalization]], [[comments]] and [many more](./features) right out of the box
- Hot-reload for both configuration and content
- Simple JSX layouts and [[creating components|page components]]
- [[SPA Routing|Ridiculously fast page loads]] and tiny bundle sizes

View File

@@ -12,6 +12,7 @@ export interface FullPageLayout {
header: QuartzComponent[] // laid out horizontally
beforeBody: QuartzComponent[] // laid out vertically
pageBody: QuartzComponent // single component
afterBody: QuartzComponent[] // laid out vertically
left: QuartzComponent[] // vertical on desktop, horizontal on mobile
right: QuartzComponent[] // vertical on desktop, horizontal on mobile
footer: QuartzComponent // single component

View File

@@ -26,7 +26,7 @@ The emitter supports the following aliases:
- `alias`
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -9,7 +9,7 @@ This plugin emits all non-Markdown static assets in your content folder (like im
Note that all static assets will then be accessible through its path on your generated site, i.e: `host.me/path/to/static.pdf`
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -8,10 +8,10 @@ This plugin emits a `CNAME` record that points your subdomain to the default dom
If you want to use a custom domain name like `quartz.example.com` for the site, then this is needed.
See [[Hosting]] for more information.
See [[hosting|Hosting]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -7,7 +7,7 @@ tags:
This plugin manages and emits the static resources required for the Quartz framework. This includes CSS stylesheets and JavaScript scripts that enhance the functionality and aesthetics of the generated site. See also the `cdnCaching` option in the `theme` section of the [[configuration]].
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -9,7 +9,7 @@ This plugin emits both RSS and an XML sitemap for your site. The [[RSS Feed]] al
This plugin emits a comprehensive index of the site's content, generating additional resources such as a sitemap, an RSS feed, and a
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -7,7 +7,7 @@ tags:
This plugin is a core component of the Quartz framework. It generates the HTML pages for each piece of Markdown content. It emits the full-page [[layout]], including headers, footers, and body content, among others.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -7,7 +7,7 @@ tags:
This plugin parses links and processes them to point to the right places. It is also needed for embedded links (like images). See [[Obsidian compatibility]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -7,11 +7,11 @@ tags:
This plugin determines the created, modified, and published dates for a document using three potential data sources: frontmatter metadata, Git history, and the filesystem. See [[authoring content#Syntax]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `priority`: The data sources to consult for date information. Highest priority first. Possible values are `"frontmatter"`, `"git"`, and `"filesystem"`. Defaults to `"frontmatter", "git", "filesystem"]`.
- `priority`: The data sources to consult for date information. Highest priority first. Possible values are `"frontmatter"`, `"git"`, and `"filesystem"`. Defaults to `["frontmatter", "git", "filesystem"]`.
> [!warning]
> If you rely on `git` for dates, make sure `defaultDateType` is set to `modified` in `quartz.config.ts`.

View File

@@ -9,11 +9,12 @@ This plugin generates descriptions that are used as metadata for the HTML `head`
If the frontmatter contains a `description` property, it is used (see [[authoring content#Syntax]]). Otherwise, the plugin will do its best to use the first few sentences of the content to reach the target description length.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
- `descriptionLength`: the maximum length of the generated description. Default is 150 characters. The cut off happens after the first _sentence_ that ends after the given length.
- `replaceExternalLinks`: If `true` (default), replace external links with their domain and path in the description (e.g. `https://domain.tld/some_page/another_page?query=hello&target=world` is replaced with `domain.tld/some_page/another_page`).
## API

View File

@@ -7,12 +7,12 @@ tags:
This plugin filters content based on an explicit `publish` flag in the frontmatter, allowing only content that is explicitly marked for publication to pass through. It's the opt-in version of [[RemoveDrafts]]. See [[private pages]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
## API
- Category: Emitter
- Category: Filter
- Function name: `Plugin.ExplicitPublish()`.
- Source: [`quartz/plugins/filters/explicit.ts`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/filters/explicit.ts).

View File

@@ -9,12 +9,14 @@ This plugin generates index pages for folders, creating a listing page for each
Example: [[advanced/|Advanced]]
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
The pages are displayed using the `defaultListPageLayout` in `quartz.layouts.ts`. For the content, the `FolderContent` component is used. If you want to modify the layout, you must edit it directly (`quartz/components/pages/FolderContent.tsx`).
This plugin accepts the following configuration options:
- `sort`: A function of type `(f1: QuartzPluginData, f2: QuartzPluginData) => number{:ts}` used to sort entries. Defaults to sorting by date and tie-breaking on lexographical order.
## API
- Category: Emitter

View File

@@ -7,7 +7,7 @@ tags:
This plugin parses the frontmatter of the page using the [gray-matter](https://github.com/jonschlinkert/gray-matter) library. See [[authoring content#Syntax]], [[Obsidian compatibility]] and [[OxHugo compatibility]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -9,7 +9,7 @@ This plugin enhances Markdown processing to support GitHub Flavored Markdown (GF
In addition, this plugin adds optional features for typographic refinement (such as converting straight quotes to curly quotes, dashes to en-dashes/em-dashes, and ellipses) and automatic heading links as a symbol that appears next to the heading on hover.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -7,7 +7,7 @@ tags:
This plugin automatically converts single line breaks in Markdown text into hard line breaks in the HTML output. This plugin is not enabled by default as this doesn't follow the semantics of actual Markdown but you may enable it if you'd like parity with [[Obsidian compatibility|Obsidian]].
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -7,7 +7,7 @@ tags:
This plugin adds LaTeX support to Quartz. See [[features/Latex|Latex]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -7,7 +7,7 @@ tags:
This plugin emits a 404 (Not Found) page for broken or non-existent URLs.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -7,7 +7,7 @@ tags:
This plugin provides support for [[Obsidian compatibility]].
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:
@@ -20,7 +20,7 @@ This plugin accepts the following configuration options:
- `parseArrows`: If `true` (default), transforms arrow symbols into their HTML character equivalents.
- `parseBlockReferences`: If `true` (default), handles block references, linking to specific content blocks.
- `enableInHtmlEmbed`: If `true`, allows embedding of content directly within HTML. Defaults to `false`.
- `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos using external image Markdown syntax.
- `enableYouTubeEmbed`: If `true` (default), enables the embedding of YouTube videos and playlists using external image Markdown syntax.
- `enableVideoEmbed`: If `true` (default), enables the embedding of video files.
- `enableCheckbox`: If `true`, adds support for interactive checkboxes in content. Defaults to `false`.

View File

@@ -7,7 +7,7 @@ tags:
This plugin provides support for [ox-hugo](https://github.com/kaushalmodi/ox-hugo) compatibility. See [[OxHugo compatibility]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -7,7 +7,7 @@ tags:
This plugin filters out content from your vault, so that only finalized content is made available. This prevents [[private pages]] from being published. By default, it filters out all pages with `draft: true` in the frontmatter and leaves all other pages intact.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -10,7 +10,7 @@ This plugin emits all static resources needed by Quartz. This is used, for examp
> This is different from [[Assets]]. The resources from the [[Static]] plugin are located under `quartz/static`, whereas [[Assets]] renders all static resources under `content` and is used for images, videos, audio, etc. that are directly referenced by your markdown content.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin has no configuration options.

View File

@@ -7,7 +7,7 @@ tags:
This plugin is used to add syntax highlighting to code blocks in Quartz. See [[syntax highlighting]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -7,7 +7,7 @@ tags:
This plugin generates a table of contents (TOC) for Markdown documents. See [[table of contents]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
This plugin accepts the following configuration options:

View File

@@ -7,14 +7,16 @@ tags:
This plugin emits dedicated pages for each tag used in the content. See [[folder and tag listings]] for more information.
> [!note]
> For information on how to add, remove or configure plugins, see the [[Configuration#Plugins|Configuration]] page.
This plugin has no configuration options.
> For information on how to add, remove or configure plugins, see the [[configuration#Plugins|Configuration]] page.
The pages are displayed using the `defaultListPageLayout` in `quartz.layouts.ts`. For the content, the `TagContent` component is used. If you want to modify the layout, you must edit it directly (`quartz/components/pages/TagContent.tsx`).
This plugin accepts the following configuration options:
- `sort`: A function of type `(f1: QuartzPluginData, f2: QuartzPluginData) => number{:ts}` used to sort entries. Defaults to sorting by date and tie-breaking on lexographical order.
## API
- Category: Emitter
- Function name: `Plugin.AliasRedirects()`.
- Function name: `Plugin.TagPage()`.
- Source: [`quartz/plugins/emitters/tagPage.tsx`](https://github.com/jackyzha0/quartz/blob/v4/quartz/plugins/emitters/tagPage.tsx).

View File

@@ -7,24 +7,23 @@ 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/)
- [Socratica Toolbox](https://toolbox.socratica.info/)
- [oldwinter の数字花园](https://garden.oldwinter.top/)
- [Morrowind Modding Wiki](https://morrowind-modding.github.io/)
- [Aaron Pham's Garden](https://aarnphm.xyz/)
- [The Quantum Garden](https://quantumgardener.blog/)
- [Abhijeet's Math Wiki](https://abhmul.github.io/quartz/Math-Wiki/)
- [Matt Dunn's Second Brain](https://mattdunn.info/)
- [Pelayo Arbues' Notes](https://pelayoarbues.github.io/)
- [Vince Imbat's Talahardin](https://vinceimbat.com/)
- [Pelayo Arbues' Notes](https://pelayoarbues.com/)
- [Stanford CME 302 Numerical Linear Algebra](https://ericdarve.github.io/NLA/)
- [A Pattern Language - Christopher Alexander (Architecture)](https://patternlanguage.cc/)
- [oldwinter の数字花园](https://garden.oldwinter.top/)
- [Eilleen's Everything Notebook](https://quartz.eilleeenz.com/)
- [🧠🌳 Chad's Mind Garden](https://www.chadly.net/)
- [Pedro MC Fernandes's Topo da Mente](https://www.pmcf.xyz/topo-da-mente/)
- [Mau Camargo's Notkesto](https://notes.camargomau.com/)
- [Caicai's Novels](https://imoko.cc/blog/caicai/)
- [🌊 Collapsed Wave](https://collapsedwave.com/)
- [Sideny's 3D Artist's Handbook](https://sidney-eliot.github.io/3d-artists-handbook/)
- [Mike's AI Garden 🤖🪴](https://mwalton.me/)
- [Brandon Boswell's Garden](https://brandonkboswell.com)
- [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/)
- [Data Dictionary 🧠](https://glossary.airbyte.com/)
- [sspaeti.com's Second Brain](https://brain.sspaeti.com/)
- [🪴Aster's notebook](https://notes.asterhu.com)
- [Gatekeeper Wiki](https://www.gatekeeper.wiki)
- [Ellie's Notes](https://ellie.wtf)
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/docs/showcase.md)!

4
globals.d.ts vendored
View File

@@ -4,6 +4,10 @@ export declare global {
type: K,
listener: (this: Document, ev: CustomEventMap[K]) => void,
): void
removeEventListener<K extends keyof CustomEventMap>(
type: K,
listener: (this: Document, ev: CustomEventMap[K]) => void,
): void
dispatchEvent<K extends keyof CustomEventMap>(ev: CustomEventMap[K] | UIEvent): void
}
interface Window {

1435
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
"name": "@jackyzha0/quartz",
"description": "🌱 publish your digital garden and notes as a website",
"private": true,
"version": "4.2.3",
"version": "4.3.0",
"type": "module",
"author": "jackyzha0 <j.zhao2k19@gmail.com>",
"license": "MIT",
@@ -12,6 +12,7 @@
"url": "https://github.com/jackyzha0/quartz.git"
},
"scripts": {
"quartz": "./quartz/bootstrap-cli.mjs",
"docs": "npx quartz build --serve -d docs",
"check": "tsc --noEmit && npx prettier . --check",
"format": "npx prettier . --write",
@@ -20,7 +21,7 @@
},
"engines": {
"npm": ">=9.3.1",
"node": ">=18.14"
"node": "20 || >=22"
},
"keywords": [
"site generator",
@@ -35,37 +36,38 @@
},
"dependencies": {
"@clack/prompts": "^0.7.0",
"@floating-ui/dom": "^1.6.3",
"@floating-ui/dom": "^1.6.8",
"@napi-rs/simple-git": "0.1.16",
"async-mutex": "^0.4.1",
"async-mutex": "^0.5.0",
"chalk": "^5.3.0",
"chokidar": "^3.5.3",
"chokidar": "^3.6.0",
"cli-spinner": "^0.2.10",
"d3": "^7.8.5",
"d3": "^7.9.0",
"esbuild-sass-plugin": "^2.16.1",
"flexsearch": "0.7.43",
"github-slugger": "^2.0.0",
"globby": "^14.0.1",
"globby": "^14.0.2",
"gray-matter": "^4.0.3",
"hast-util-to-html": "^9.0.0",
"hast-util-to-html": "^9.0.1",
"hast-util-to-jsx-runtime": "^2.3.0",
"hast-util-to-string": "^3.0.0",
"is-absolute-url": "^4.0.1",
"js-yaml": "^4.1.0",
"lightningcss": "^1.23.0",
"lightningcss": "^1.25.1",
"mdast-util-find-and-replace": "^3.0.1",
"mdast-util-to-hast": "^13.1.0",
"mdast-util-to-hast": "^13.2.0",
"mdast-util-to-string": "^4.0.0",
"micromorph": "^0.4.5",
"preact": "^10.19.5",
"preact-render-to-string": "^6.3.1",
"preact": "^10.22.1",
"preact-render-to-string": "^6.5.7",
"pretty-bytes": "^6.1.1",
"pretty-time": "^1.1.0",
"reading-time": "^1.5.0",
"rehype-autolink-headings": "^7.1.0",
"rehype-citation": "^2.0.0",
"rehype-katex": "^7.0.0",
"rehype-mathjax": "^6.0.0",
"rehype-pretty-code": "^0.13.0",
"rehype-pretty-code": "^0.13.2",
"rehype-raw": "^7.0.0",
"rehype-slug": "^6.0.0",
"remark": "^15.0.1",
@@ -75,19 +77,19 @@
"remark-math": "^6.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.0",
"remark-smartypants": "^2.0.0",
"rfdc": "^1.3.1",
"rimraf": "^5.0.5",
"remark-smartypants": "^3.0.2",
"rfdc": "^1.4.1",
"rimraf": "^6.0.1",
"serve-handler": "^6.1.5",
"shiki": "^1.1.6",
"shiki": "^1.10.3",
"source-map-support": "^0.5.21",
"to-vfile": "^8.0.0",
"toml": "^3.0.0",
"unified": "^11.0.4",
"unist-util-visit": "^5.0.0",
"vfile": "^6.0.1",
"workerpool": "^9.1.0",
"ws": "^8.15.1",
"vfile": "^6.0.2",
"workerpool": "^9.1.3",
"ws": "^8.18.0",
"yargs": "^17.7.2"
},
"devDependencies": {
@@ -95,14 +97,14 @@
"@types/d3": "^7.4.3",
"@types/hast": "^3.0.4",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.11.19",
"@types/node": "^22.1.0",
"@types/pretty-time": "^1.1.5",
"@types/source-map-support": "^0.5.10",
"@types/ws": "^8.5.10",
"@types/ws": "^8.5.12",
"@types/yargs": "^17.0.32",
"esbuild": "^0.19.9",
"prettier": "^3.2.4",
"tsx": "^4.7.1",
"typescript": "^5.3.3"
"prettier": "^3.3.3",
"tsx": "^4.16.2",
"typescript": "^5.5.3"
}
}

View File

@@ -19,6 +19,7 @@ const config: QuartzConfig = {
ignorePatterns: ["private", "templates", ".obsidian"],
defaultDateType: "created",
theme: {
fontOrigin: "googleFonts",
cdnCaching: true,
typography: {
header: "Schibsted Grotesk",
@@ -35,6 +36,7 @@ const config: QuartzConfig = {
secondary: "#284b63",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
textHighlight: "#fff23688",
},
darkMode: {
light: "#161618",
@@ -45,6 +47,7 @@ const config: QuartzConfig = {
secondary: "#7b97aa",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
textHighlight: "#b3aa0288",
},
},
},
@@ -55,7 +58,6 @@ const config: QuartzConfig = {
Plugin.CreatedModifiedDate({
priority: ["frontmatter", "filesystem"],
}),
Plugin.Latex({ renderEngine: "katex" }),
Plugin.SyntaxHighlighting({
theme: {
light: "github-light",
@@ -68,11 +70,12 @@ const config: QuartzConfig = {
Plugin.TableOfContents(),
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
Plugin.Description(),
Plugin.Latex({ renderEngine: "katex" }),
],
filters: [Plugin.RemoveDrafts()],
emitters: [
Plugin.AliasRedirects(),
Plugin.ComponentResources({ fontOrigin: "googleFonts" }),
Plugin.ComponentResources(),
Plugin.ContentPage(),
Plugin.FolderPage(),
Plugin.TagPage(),

View File

@@ -5,6 +5,7 @@ import * as Component from "./quartz/components"
export const sharedPageComponents: SharedLayout = {
head: Component.Head(),
header: [],
afterBody: [],
footer: Component.Footer({
links: {
GitHub: "https://github.com/jackyzha0/quartz",

View File

@@ -309,6 +309,8 @@ async function partialRebuildFromEntrypoint(
}
await rimraf([...destinationsToDelete])
console.log(chalk.green(`Done rebuilding in ${perf.timeSince()}`))
toRemove.clear()
release()
clientRefresh()

View File

@@ -19,6 +19,25 @@ export type Analytics =
websiteId: string
host?: string
}
| {
provider: "goatcounter"
websiteId: string
host?: string
scriptSrc?: string
}
| {
provider: "posthog"
apiKey: string
host?: string
}
| {
provider: "tinylytics"
siteId: string
}
| {
provider: "cabin"
host?: string
}
export interface GlobalConfiguration {
pageTitle: string
@@ -58,10 +77,11 @@ export interface FullPageLayout {
header: QuartzComponent[]
beforeBody: QuartzComponent[]
pageBody: QuartzComponent
afterBody: QuartzComponent[]
left: QuartzComponent[]
right: QuartzComponent[]
footer: QuartzComponent
}
export type PageLayout = Pick<FullPageLayout, "beforeBody" | "left" | "right">
export type SharedLayout = Pick<FullPageLayout, "head" | "header" | "footer">
export type SharedLayout = Pick<FullPageLayout, "head" | "header" | "footer" | "afterBody">

View File

@@ -0,0 +1,44 @@
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import { classNames } from "../util/lang"
// @ts-ignore
import script from "./scripts/comments.inline"
type Options = {
provider: "giscus"
options: {
repo: `${string}/${string}`
repoId: string
category: string
categoryId: string
mapping?: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
strict?: boolean
reactionsEnabled?: boolean
inputPosition?: "top" | "bottom"
}
}
function boolToStringBool(b: boolean): string {
return b ? "1" : "0"
}
export default ((opts: Options) => {
const Comments: QuartzComponent = ({ displayClass, cfg }: QuartzComponentProps) => {
return (
<div
class={classNames(displayClass, "giscus")}
data-repo={opts.options.repo}
data-repo-id={opts.options.repoId}
data-category={opts.options.category}
data-category-id={opts.options.categoryId}
data-mapping={opts.options.mapping ?? "url"}
data-strict={boolToStringBool(opts.options.strict ?? true)}
data-reactions-enabled={boolToStringBool(opts.options.reactionsEnabled ?? true)}
data-input-position={opts.options.inputPosition ?? "bottom"}
></div>
)
}
Comments.afterDOMLoaded = script
return Comments
}) satisfies QuartzComponentConstructor<Options>

View File

@@ -3,16 +3,20 @@ import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
import readingTime from "reading-time"
import { classNames } from "../util/lang"
import { i18n } from "../i18n"
import { JSX } from "preact"
import style from "./styles/contentMeta.scss"
interface ContentMetaOptions {
/**
* Whether to display reading time
*/
showReadingTime: boolean
showComma: boolean
}
const defaultOptions: ContentMetaOptions = {
showReadingTime: true,
showComma: true,
}
export default ((opts?: Partial<ContentMetaOptions>) => {
@@ -23,7 +27,7 @@ export default ((opts?: Partial<ContentMetaOptions>) => {
const text = fileData.text
if (text) {
const segments: string[] = []
const segments: (string | JSX.Element)[] = []
if (fileData.dates) {
segments.push(formatDate(getDate(cfg, fileData)!, cfg.locale))
@@ -38,17 +42,19 @@ export default ((opts?: Partial<ContentMetaOptions>) => {
segments.push(displayedTime)
}
return <p class={classNames(displayClass, "content-meta")}>{segments.join(", ")}</p>
const segmentsElements = segments.map((segment) => <span>{segment}</span>)
return (
<p show-comma={options.showComma} class={classNames(displayClass, "content-meta")}>
{segmentsElements}
</p>
)
} else {
return null
}
}
ContentMetadata.css = `
.content-meta {
margin-top: 0;
color: var(--gray);
}
`
ContentMetadata.css = style
return ContentMetadata
}) satisfies QuartzComponentConstructor

View File

@@ -92,7 +92,7 @@ export default ((userOpts?: Partial<Options>) => {
data-savestate={opts.useSavedState}
data-tree={jsonTree}
>
<h1>{opts.title ?? i18n(cfg.locale).components.explorer.title}</h1>
<h2>{opts.title ?? i18n(cfg.locale).components.explorer.title}</h2>
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"

View File

@@ -168,10 +168,8 @@ export function ExplorerNode({ node, opts, fullPath, fileData }: ExplorerNodePro
const isDefaultOpen = opts.folderDefaultState === "open"
// Calculate current folderPath
let folderPath = ""
if (node.name !== "") {
folderPath = joinSegments(fullPath ?? "", node.name)
}
const folderPath = node.name !== "" ? joinSegments(fullPath ?? "", node.name) : ""
const href = resolveRelative(fileData.slug!, folderPath as SimpleSlug) + "/"
return (
<>
@@ -205,11 +203,7 @@ export function ExplorerNode({ node, opts, fullPath, fileData }: ExplorerNodePro
{/* render <a> tag if folderBehavior is "link", otherwise render <button> with collapse click event */}
<div key={node.name} data-folderpath={folderPath}>
{folderBehavior === "link" ? (
<a
href={resolveRelative(fileData.slug!, folderPath as SimpleSlug)}
data-for={node.name}
class="folder-title"
>
<a href={href} data-for={node.name} class="folder-title">
{node.displayName}
</a>
) : (

View File

@@ -13,7 +13,6 @@ export default ((opts?: Options) => {
const links = opts?.links ?? []
return (
<footer class={`${displayClass ?? ""}`}>
<hr />
<p>
{i18n(cfg.locale).components.footer.createdWith}{" "}
<a href="https://quartz.jzhao.xyz/">Quartz v{version}</a> © {year}

View File

@@ -17,6 +17,7 @@ export interface D3Config {
opacityScale: number
removeTags: string[]
showTags: boolean
focusOnHover?: boolean
}
interface GraphOptions {
@@ -37,6 +38,7 @@ const defaultOptions: GraphOptions = {
opacityScale: 1,
showTags: true,
removeTags: [],
focusOnHover: false,
},
globalGraph: {
drag: true,
@@ -50,6 +52,7 @@ const defaultOptions: GraphOptions = {
opacityScale: 1,
showTags: true,
removeTags: [],
focusOnHover: true,
},
}

View File

@@ -1,6 +1,7 @@
import { i18n } from "../i18n"
import { FullSlug, joinSegments, pathToRoot } from "../util/path"
import { JSResourceToScriptElement } from "../util/resources"
import { googleFontHref } from "../util/theme"
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
export default (() => {
@@ -21,10 +22,11 @@ export default (() => {
<head>
<title>{title}</title>
<meta charSet="utf-8" />
{cfg.theme.cdnCaching && (
{cfg.theme.cdnCaching && cfg.theme.fontOrigin === "googleFonts" && (
<>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link rel="stylesheet" href={googleFontHref(cfg.theme)} />
</>
)}
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

View File

@@ -4,9 +4,9 @@ import { Date, getDate } from "./Date"
import { QuartzComponent, QuartzComponentProps } from "./types"
import { GlobalConfiguration } from "../cfg"
export function byDateAndAlphabetical(
cfg: GlobalConfiguration,
): (f1: QuartzPluginData, f2: QuartzPluginData) => number {
export type SortFn = (f1: QuartzPluginData, f2: QuartzPluginData) => number
export function byDateAndAlphabetical(cfg: GlobalConfiguration): SortFn {
return (f1, f2) => {
if (f1.dates && f2.dates) {
// sort descending
@@ -27,10 +27,12 @@ export function byDateAndAlphabetical(
type Props = {
limit?: number
sort?: SortFn
} & QuartzComponentProps
export const PageList: QuartzComponent = ({ cfg, fileData, allFiles, limit }: Props) => {
let list = allFiles.sort(byDateAndAlphabetical(cfg))
export const PageList: QuartzComponent = ({ cfg, fileData, allFiles, limit, sort }: Props) => {
const sorter = sort ?? byDateAndAlphabetical(cfg)
let list = allFiles.sort(sorter)
if (limit) {
list = list.slice(0, limit)
}
@@ -63,7 +65,7 @@ export const PageList: QuartzComponent = ({ cfg, fileData, allFiles, limit }: Pr
class="internal tag-link"
href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)}
>
#{tag}
{tag}
</a>
</li>
))}

View File

@@ -7,14 +7,15 @@ const PageTitle: QuartzComponent = ({ fileData, cfg, displayClass }: QuartzCompo
const title = cfg?.pageTitle ?? i18n(cfg.locale).propertyDefaults.title
const baseDir = pathToRoot(fileData.slug!)
return (
<h1 class={classNames(displayClass, "page-title")}>
<h2 class={classNames(displayClass, "page-title")}>
<a href={baseDir}>{title}</a>
</h1>
</h2>
)
}
PageTitle.css = `
.page-title {
font-size: 1.75rem;
margin: 0;
}
`

View File

@@ -12,6 +12,7 @@ interface Options {
title?: string
limit: number
linkToMore: SimpleSlug | false
showTags: boolean
filter: (f: QuartzPluginData) => boolean
sort: (f1: QuartzPluginData, f2: QuartzPluginData) => number
}
@@ -19,6 +20,7 @@ interface Options {
const defaultOptions = (cfg: GlobalConfiguration): Options => ({
limit: 3,
linkToMore: false,
showTags: true,
filter: () => true,
sort: byDateAndAlphabetical(cfg),
})
@@ -56,18 +58,20 @@ export default ((userOpts?: Partial<Options>) => {
<Date date={getDate(cfg, page)!} locale={cfg.locale} />
</p>
)}
<ul class="tags">
{tags.map((tag) => (
<li>
<a
class="internal tag-link"
href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)}
>
#{tag}
</a>
</li>
))}
</ul>
{opts.showTags && (
<ul class="tags">
{tags.map((tag) => (
<li>
<a
class="internal tag-link"
href={resolveRelative(fileData.slug!, `tags/${tag}` as FullSlug)}
>
{tag}
</a>
</li>
))}
</ul>
)}
</div>
</li>
)

View File

@@ -9,12 +9,11 @@ const TagList: QuartzComponent = ({ fileData, displayClass }: QuartzComponentPro
return (
<ul class={classNames(displayClass, "tags")}>
{tags.map((tag) => {
const display = `#${tag}`
const linkDest = baseDir + `/tags/${slugTag(tag)}`
return (
<li>
<a href={linkDest} class="internal tag-link">
{display}
{tag}
</a>
</li>
)

View File

@@ -19,6 +19,7 @@ import DesktopOnly from "./DesktopOnly"
import MobileOnly from "./MobileOnly"
import RecentNotes from "./RecentNotes"
import Breadcrumbs from "./Breadcrumbs"
import Comments from "./Comments"
export {
ArticleTitle,
@@ -42,4 +43,5 @@ export {
RecentNotes,
NotFound,
Breadcrumbs,
Comments,
}

View File

@@ -1,11 +1,16 @@
import { i18n } from "../../i18n"
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types"
const NotFound: QuartzComponent = ({ cfg }: QuartzComponentProps) => {
// If baseUrl contains a pathname after the domain, use this as the home link
const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`)
const baseDir = url.pathname
function NotFound({ cfg }: QuartzComponentProps) {
return (
<article class="popover-hint">
<h1>404</h1>
<p>{i18n(cfg.locale).pages.error.notFound}</p>
<a href={baseDir}>{i18n(cfg.locale).pages.error.home}</a>
</article>
)
}

View File

@@ -1,7 +1,7 @@
import { htmlToJsx } from "../../util/jsx"
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types"
function Content({ fileData, tree }: QuartzComponentProps) {
const Content: QuartzComponent = ({ fileData, tree }: QuartzComponentProps) => {
const content = htmlToJsx(fileData.filePath!, tree)
const classes: string[] = fileData.frontmatter?.cssclasses ?? []
const classString = ["popover-hint", ...classes].join(" ")

View File

@@ -1,8 +1,8 @@
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types"
import path from "path"
import style from "../styles/listPage.scss"
import { PageList } from "../PageList"
import { PageList, SortFn } from "../PageList"
import { stripSlashes, simplifySlug } from "../../util/path"
import { Root } from "hast"
import { htmlToJsx } from "../../util/jsx"
@@ -13,6 +13,7 @@ interface FolderContentOptions {
* Whether to display number of folders
*/
showFolderCount: boolean
sort?: SortFn
}
const defaultOptions: FolderContentOptions = {
@@ -22,7 +23,7 @@ const defaultOptions: FolderContentOptions = {
export default ((opts?: Partial<FolderContentOptions>) => {
const options: FolderContentOptions = { ...defaultOptions, ...opts }
function FolderContent(props: QuartzComponentProps) {
const FolderContent: QuartzComponent = (props: QuartzComponentProps) => {
const { tree, fileData, allFiles, cfg } = props
const folderSlug = stripSlashes(simplifySlug(fileData.slug!))
const allPagesInFolder = allFiles.filter((file) => {
@@ -37,6 +38,7 @@ export default ((opts?: Partial<FolderContentOptions>) => {
const classes = ["popover-hint", ...cssClasses].join(" ")
const listProps = {
...props,
sort: options.sort,
allFiles: allPagesInFolder,
}
@@ -47,9 +49,7 @@ export default ((opts?: Partial<FolderContentOptions>) => {
return (
<div class={classes}>
<article>
<p>{content}</p>
</article>
<article>{content}</article>
<div class="page-listing">
{options.showFolderCount && (
<p>

View File

@@ -1,107 +1,127 @@
import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "../types"
import style from "../styles/listPage.scss"
import { PageList } from "../PageList"
import { PageList, SortFn } from "../PageList"
import { FullSlug, getAllSegmentPrefixes, simplifySlug } from "../../util/path"
import { QuartzPluginData } from "../../plugins/vfile"
import { Root } from "hast"
import { htmlToJsx } from "../../util/jsx"
import { i18n } from "../../i18n"
const numPages = 10
function TagContent(props: QuartzComponentProps) {
const { tree, fileData, allFiles, cfg } = props
const slug = fileData.slug
if (!(slug?.startsWith("tags/") || slug === "tags")) {
throw new Error(`Component "TagContent" tried to render a non-tag page: ${slug}`)
}
const tag = simplifySlug(slug.slice("tags/".length) as FullSlug)
const allPagesWithTag = (tag: string) =>
allFiles.filter((file) =>
(file.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes).includes(tag),
)
const content =
(tree as Root).children.length === 0
? fileData.description
: htmlToJsx(fileData.filePath!, tree)
const cssClasses: string[] = fileData.frontmatter?.cssclasses ?? []
const classes = ["popover-hint", ...cssClasses].join(" ")
if (tag === "/") {
const tags = [
...new Set(
allFiles.flatMap((data) => data.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes),
),
].sort((a, b) => a.localeCompare(b))
const tagItemMap: Map<string, QuartzPluginData[]> = new Map()
for (const tag of tags) {
tagItemMap.set(tag, allPagesWithTag(tag))
}
return (
<div class={classes}>
<article>
<p>{content}</p>
</article>
<p>{i18n(cfg.locale).pages.tagContent.totalTags({ count: tags.length })}</p>
<div>
{tags.map((tag) => {
const pages = tagItemMap.get(tag)!
const listProps = {
...props,
allFiles: pages,
}
const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`)[0]
const content = contentPage?.description
return (
<div>
<h2>
<a class="internal tag-link" href={`../tags/${tag}`}>
#{tag}
</a>
</h2>
{content && <p>{content}</p>}
<div class="page-listing">
<p>
{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}
{pages.length > numPages && (
<>
{" "}
<span>
{i18n(cfg.locale).pages.tagContent.showingFirst({ count: numPages })}
</span>
</>
)}
</p>
<PageList limit={numPages} {...listProps} />
</div>
</div>
)
})}
</div>
</div>
)
} else {
const pages = allPagesWithTag(tag)
const listProps = {
...props,
allFiles: pages,
}
return (
<div class={classes}>
<article>{content}</article>
<div class="page-listing">
<p>{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}</p>
<div>
<PageList {...listProps} />
</div>
</div>
</div>
)
}
interface TagContentOptions {
sort?: SortFn
numPages: number
}
TagContent.css = style + PageList.css
export default (() => TagContent) satisfies QuartzComponentConstructor
const defaultOptions: TagContentOptions = {
numPages: 10,
}
export default ((opts?: Partial<TagContentOptions>) => {
const options: TagContentOptions = { ...defaultOptions, ...opts }
const TagContent: QuartzComponent = (props: QuartzComponentProps) => {
const { tree, fileData, allFiles, cfg } = props
const slug = fileData.slug
if (!(slug?.startsWith("tags/") || slug === "tags")) {
throw new Error(`Component "TagContent" tried to render a non-tag page: ${slug}`)
}
const tag = simplifySlug(slug.slice("tags/".length) as FullSlug)
const allPagesWithTag = (tag: string) =>
allFiles.filter((file) =>
(file.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes).includes(tag),
)
const content =
(tree as Root).children.length === 0
? fileData.description
: htmlToJsx(fileData.filePath!, tree)
const cssClasses: string[] = fileData.frontmatter?.cssclasses ?? []
const classes = ["popover-hint", ...cssClasses].join(" ")
if (tag === "/") {
const tags = [
...new Set(
allFiles.flatMap((data) => data.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes),
),
].sort((a, b) => a.localeCompare(b))
const tagItemMap: Map<string, QuartzPluginData[]> = new Map()
for (const tag of tags) {
tagItemMap.set(tag, allPagesWithTag(tag))
}
return (
<div class={classes}>
<article>
<p>{content}</p>
</article>
<p>{i18n(cfg.locale).pages.tagContent.totalTags({ count: tags.length })}</p>
<div>
{tags.map((tag) => {
const pages = tagItemMap.get(tag)!
const listProps = {
...props,
allFiles: pages,
}
const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`).at(0)
const root = contentPage?.htmlAst
const content =
!root || root?.children.length === 0
? contentPage?.description
: htmlToJsx(contentPage.filePath!, root)
return (
<div>
<h2>
<a class="internal tag-link" href={`../tags/${tag}`}>
{tag}
</a>
</h2>
{content && <p>{content}</p>}
<div class="page-listing">
<p>
{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}
{pages.length > options.numPages && (
<>
{" "}
<span>
{i18n(cfg.locale).pages.tagContent.showingFirst({
count: options.numPages,
})}
</span>
</>
)}
</p>
<PageList limit={options.numPages} {...listProps} sort={opts?.sort} />
</div>
</div>
)
})}
</div>
</div>
)
} else {
const pages = allPagesWithTag(tag)
const listProps = {
...props,
allFiles: pages,
}
return (
<div class={classes}>
<article>{content}</article>
<div class="page-listing">
<p>{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}</p>
<div>
<PageList {...listProps} />
</div>
</div>
</div>
)
}
}
TagContent.css = style + PageList.css
return TagContent
}) satisfies QuartzComponentConstructor

View File

@@ -14,11 +14,13 @@ interface RenderComponents {
header: QuartzComponent[]
beforeBody: QuartzComponent[]
pageBody: QuartzComponent
afterBody: QuartzComponent[]
left: QuartzComponent[]
right: QuartzComponent[]
footer: QuartzComponent
}
const headerRegex = new RegExp(/h[1-6]/)
export function pageResources(
baseDir: FullSlug | RelativeURL,
staticResources: StaticResources,
@@ -105,18 +107,24 @@ export function renderPage(
// header transclude
blockRef = blockRef.slice(1)
let startIdx = undefined
let startDepth = undefined
let endIdx = undefined
for (const [i, el] of page.htmlAst.children.entries()) {
if (el.type === "element" && el.tagName.match(/h[1-6]/)) {
if (endIdx) {
break
}
// skip non-headers
if (!(el.type === "element" && el.tagName.match(headerRegex))) continue
const depth = Number(el.tagName.substring(1))
if (startIdx !== undefined) {
endIdx = i
} else if (el.properties?.id === blockRef) {
// lookin for our blockref
if (startIdx === undefined || startDepth === undefined) {
// skip until we find the blockref that matches
if (el.properties?.id === blockRef) {
startIdx = i
startDepth = depth
}
} else if (depth <= startDepth) {
// looking for new header that is same level or higher
endIdx = i
break
}
}
@@ -180,6 +188,7 @@ export function renderPage(
header,
beforeBody,
pageBody: Content,
afterBody,
left,
right,
footer: Footer,
@@ -203,7 +212,7 @@ export function renderPage(
</div>
)
const lang = componentData.frontmatter?.lang ?? cfg.locale?.split("-")[0] ?? "en"
const lang = componentData.fileData.frontmatter?.lang ?? cfg.locale?.split("-")[0] ?? "en"
const doc = (
<html lang={lang}>
<Head {...componentData} />
@@ -225,6 +234,12 @@ export function renderPage(
</div>
</div>
<Content {...componentData} />
<hr />
<div class="page-footer">
{afterBody.map((BodyComponent) => (
<BodyComponent {...componentData} />
))}
</div>
</div>
{RightComponent}
</Body>

View File

@@ -0,0 +1,67 @@
const changeTheme = (e: CustomEventMap["themechange"]) => {
const theme = e.detail.theme
const iframe = document.querySelector("iframe.giscus-frame") as HTMLIFrameElement
if (!iframe) {
return
}
if (!iframe.contentWindow) {
return
}
iframe.contentWindow.postMessage(
{
giscus: {
setConfig: {
theme: theme,
},
},
},
"https://giscus.app",
)
}
type GiscusElement = Omit<HTMLElement, "dataset"> & {
dataset: DOMStringMap & {
repo: `${string}/${string}`
repoId: string
category: string
categoryId: string
mapping: "url" | "title" | "og:title" | "specific" | "number" | "pathname"
strict: string
reactionsEnabled: string
inputPosition: "top" | "bottom"
}
}
document.addEventListener("nav", () => {
const giscusContainer = document.querySelector(".giscus") as GiscusElement
if (!giscusContainer) {
return
}
const giscusScript = document.createElement("script")
giscusScript.src = "https://giscus.app/client.js"
giscusScript.async = true
giscusScript.crossOrigin = "anonymous"
giscusScript.setAttribute("data-loading", "lazy")
giscusScript.setAttribute("data-emit-metadata", "0")
giscusScript.setAttribute("data-repo", giscusContainer.dataset.repo)
giscusScript.setAttribute("data-repo-id", giscusContainer.dataset.repoId)
giscusScript.setAttribute("data-category", giscusContainer.dataset.category)
giscusScript.setAttribute("data-category-id", giscusContainer.dataset.categoryId)
giscusScript.setAttribute("data-mapping", giscusContainer.dataset.mapping)
giscusScript.setAttribute("data-strict", giscusContainer.dataset.strict)
giscusScript.setAttribute("data-reactions-enabled", giscusContainer.dataset.reactionsEnabled)
giscusScript.setAttribute("data-input-position", giscusContainer.dataset.inputPosition)
const theme = document.documentElement.getAttribute("saved-theme")
if (theme) {
giscusScript.setAttribute("data-theme", theme)
}
giscusContainer.appendChild(giscusScript)
document.addEventListener("themechange", changeTheme)
window.addCleanup(() => document.removeEventListener("themechange", changeTheme))
})

View File

@@ -1,4 +1,4 @@
import type { ContentDetails, ContentIndex } from "../../plugins/emitters/contentIndex"
import type { ContentDetails } from "../../plugins/emitters/contentIndex"
import * as d3 from "d3"
import { registerEscapeHandler, removeAllChildren } from "./util"
import { FullSlug, SimpleSlug, getFullSlug, resolveRelative, simplifySlug } from "../../util/path"
@@ -44,6 +44,7 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
opacityScale,
removeTags,
showTags,
focusOnHover,
} = JSON.parse(graph.dataset["cfg"]!)
const data: Map<SimpleSlug, ContentDetails> = new Map(
@@ -101,7 +102,7 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
const graphData: { nodes: NodeData[]; links: LinkData[] } = {
nodes: [...neighbourhood].map((url) => {
const text = url.startsWith("tags/") ? "#" + url.substring(5) : data.get(url)?.title ?? url
const text = url.startsWith("tags/") ? "#" + url.substring(5) : (data.get(url)?.title ?? url)
return {
id: url,
text: text,
@@ -189,6 +190,8 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
return 2 + Math.sqrt(numLinks)
}
let connectedNodes: SimpleSlug[] = []
// draw individual nodes
const node = graphNode
.append("circle")
@@ -202,17 +205,37 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
window.spaNavigate(new URL(targ, window.location.toString()))
})
.on("mouseover", function (_, d) {
const neighbours: SimpleSlug[] = data.get(slug)?.links ?? []
const neighbourNodes = d3
.selectAll<HTMLElement, NodeData>(".node")
.filter((d) => neighbours.includes(d.id))
const currentId = d.id
const linkNodes = d3
.selectAll(".link")
.filter((d: any) => d.source.id === currentId || d.target.id === currentId)
// highlight neighbour nodes
neighbourNodes.transition().duration(200).attr("fill", color)
if (focusOnHover) {
// fade out non-neighbour nodes
connectedNodes = linkNodes.data().flatMap((d: any) => [d.source.id, d.target.id])
d3.selectAll<HTMLElement, NodeData>(".link")
.transition()
.duration(200)
.style("opacity", 0.2)
d3.selectAll<HTMLElement, NodeData>(".node")
.filter((d) => !connectedNodes.includes(d.id))
.transition()
.duration(200)
.style("opacity", 0.2)
d3.selectAll<HTMLElement, NodeData>(".node")
.filter((d) => !connectedNodes.includes(d.id))
.nodes()
.map((it) => d3.select(it.parentNode as HTMLElement).select("text"))
.forEach((it) => {
let opacity = parseFloat(it.style("opacity"))
it.transition()
.duration(200)
.attr("opacityOld", opacity)
.style("opacity", Math.min(opacity, 0.2))
})
}
// highlight links
linkNodes.transition().duration(200).attr("stroke", "var(--gray)").attr("stroke-width", 1)
@@ -231,6 +254,16 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
.style("font-size", bigFont + "em")
})
.on("mouseleave", function (_, d) {
if (focusOnHover) {
d3.selectAll<HTMLElement, NodeData>(".link").transition().duration(200).style("opacity", 1)
d3.selectAll<HTMLElement, NodeData>(".node").transition().duration(200).style("opacity", 1)
d3.selectAll<HTMLElement, NodeData>(".node")
.filter((d) => !connectedNodes.includes(d.id))
.nodes()
.map((it) => d3.select(it.parentNode as HTMLElement).select("text"))
.forEach((it) => it.transition().duration(200).style("opacity", it.attr("opacityOld")))
}
const currentId = d.id
const linkNodes = d3
.selectAll(".link")
@@ -249,6 +282,13 @@ async function renderGraph(container: string, fullSlug: FullSlug) {
// @ts-ignore
.call(drag(simulation))
// make tags hollow circles
node
.filter((d) => d.id.startsWith("tags/"))
.attr("stroke", color)
.attr("stroke-width", 2)
.attr("fill", "var(--light)")
// draw labels
const labels = graphNode
.append("text")
@@ -321,7 +361,7 @@ function renderGlobalGraph() {
document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
const slug = e.detail.url
addToVisited(slug)
addToVisited(simplifySlug(slug))
await renderGraph("graph-container", slug)
const containerIcon = document.getElementById("global-graph-icon")

View File

@@ -3,7 +3,7 @@ import { normalizeRelativeURLs } from "../../util/path"
const p = new DOMParser()
async function mouseEnterHandler(
this: HTMLLinkElement,
this: HTMLAnchorElement,
{ clientX, clientY }: { clientX: number; clientY: number },
) {
const link = this
@@ -33,7 +33,7 @@ async function mouseEnterHandler(
thisUrl.hash = ""
thisUrl.search = ""
const targetUrl = new URL(link.href)
const hash = targetUrl.hash
const hash = decodeURIComponent(targetUrl.hash)
targetUrl.hash = ""
targetUrl.search = ""
@@ -100,7 +100,7 @@ async function mouseEnterHandler(
}
document.addEventListener("nav", () => {
const links = [...document.getElementsByClassName("internal")] as HTMLLinkElement[]
const links = [...document.getElementsByClassName("internal")] as HTMLAnchorElement[]
for (const link of links) {
link.addEventListener("mouseenter", mouseEnterHandler)
window.addCleanup(() => link.removeEventListener("mouseenter", mouseEnterHandler))

View File

@@ -21,6 +21,7 @@ let index = new FlexSearch.Document<Item>({
encode: encoder,
document: {
id: "id",
tag: "tags",
index: [
{
field: "title",
@@ -405,11 +406,33 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => {
let searchResults: FlexSearch.SimpleDocumentSearchResultSetUnit[]
if (searchType === "tags") {
searchResults = await index.searchAsync({
query: currentSearchTerm.substring(1),
limit: numSearchResults,
index: ["tags"],
})
currentSearchTerm = currentSearchTerm.substring(1).trim()
const separatorIndex = currentSearchTerm.indexOf(" ")
if (separatorIndex != -1) {
// search by title and content index and then filter by tag (implemented in flexsearch)
const tag = currentSearchTerm.substring(0, separatorIndex)
const query = currentSearchTerm.substring(separatorIndex + 1).trim()
searchResults = await index.searchAsync({
query: query,
// return at least 10000 documents, so it is enough to filter them by tag (implemented in flexsearch)
limit: Math.max(numSearchResults, 10000),
index: ["title", "content"],
tag: tag,
})
for (let searchResult of searchResults) {
searchResult.result = searchResult.result.slice(0, numSearchResults)
}
// set search type to basic and remove tag from term for proper highlightning and scroll
searchType = "basic"
currentSearchTerm = query
} else {
// default search by tags index
searchResults = await index.searchAsync({
query: currentSearchTerm,
limit: numSearchResults,
index: ["tags"],
})
}
} else if (searchType === "basic") {
searchResults = await index.searchAsync({
query: currentSearchTerm,

View File

@@ -0,0 +1,14 @@
.content-meta {
margin-top: 0;
color: var(--gray);
&[show-comma="true"] {
> span:not(:last-child) {
margin-right: 8px;
&::after {
content: ",";
}
}
}
}

View File

@@ -11,7 +11,7 @@ button#explorer {
display: flex;
align-items: center;
& h1 {
& h2 {
font-size: 1rem;
display: inline-block;
margin: 0;

View File

@@ -11,7 +11,7 @@ li.section-li {
& > .section {
display: grid;
grid-template-columns: 6em 3fr 1fr;
grid-template-columns: fit-content(8em) 3fr 1fr;
@media all and (max-width: $mobileBreakpoint) {
& > .tags {
@@ -24,8 +24,7 @@ li.section-li {
}
& > .meta {
margin: 0;
flex-basis: 6em;
margin: 0 1em 0 0;
opacity: 0.6;
}
}
@@ -33,7 +32,8 @@ li.section-li {
// modifications in popover context
.popover .section {
grid-template-columns: 6em 1fr !important;
grid-template-columns: fit-content(8em) 1fr !important;
& > .tags {
display: none;
}

View File

@@ -1,20 +1,28 @@
import { Translation, CalloutTranslation } from "./locales/definition"
import en from "./locales/en-US"
import enUs from "./locales/en-US"
import enGb from "./locales/en-GB"
import fr from "./locales/fr-FR"
import it from "./locales/it-IT"
import ja from "./locales/ja-JP"
import de from "./locales/de-DE"
import nl from "./locales/nl-NL"
import ro from "./locales/ro-RO"
import ca from "./locales/ca-ES"
import es from "./locales/es-ES"
import ar from "./locales/ar-SA"
import uk from "./locales/uk-UA"
import ru from "./locales/ru-RU"
import ko from "./locales/ko-KR"
import zh from "./locales/zh-CN"
import vi from "./locales/vi-VN"
import pt from "./locales/pt-BR"
import hu from "./locales/hu-HU"
import fa from "./locales/fa-IR"
import pl from "./locales/pl-PL"
export const TRANSLATIONS = {
"en-US": en,
"en-US": enUs,
"en-GB": enGb,
"fr-FR": fr,
"it-IT": it,
"ja-JP": ja,
@@ -23,6 +31,7 @@ export const TRANSLATIONS = {
"nl-BE": nl,
"ro-RO": ro,
"ro-MD": ro,
"ca-ES": ca,
"es-ES": es,
"ar-SA": ar,
"ar-AE": ar,
@@ -48,6 +57,11 @@ export const TRANSLATIONS = {
"ru-RU": ru,
"ko-KR": ko,
"zh-CN": zh,
"vi-VN": vi,
"pt-BR": pt,
"hu-HU": hu,
"fa-IR": fa,
"pl-PL": pl,
} as const
export const defaultTranslation = "en-US"

View File

@@ -70,6 +70,7 @@ export default {
error: {
title: "غير موجود",
notFound: "إما أن هذه الصفحة خاصة أو غير موجودة.",
home: "العوده للصفحة الرئيسية",
},
folderContent: {
folder: "مجلد",

View File

@@ -0,0 +1,84 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Sense títol",
description: "Sense descripció",
},
components: {
callout: {
note: "Nota",
abstract: "Resum",
info: "Informació",
todo: "Per fer",
tip: "Consell",
success: "Èxit",
question: "Pregunta",
warning: "Advertència",
failure: "Fall",
danger: "Perill",
bug: "Error",
example: "Exemple",
quote: "Cita",
},
backlinks: {
title: "Retroenllaç",
noBacklinksFound: "No s'han trobat retroenllaços",
},
themeToggle: {
lightMode: "Mode clar",
darkMode: "Mode fosc",
},
explorer: {
title: "Explorador",
},
footer: {
createdWith: "Creat amb",
},
graph: {
title: "Vista Gràfica",
},
recentNotes: {
title: "Notes Recents",
seeRemainingMore: ({ remaining }) => `Vegi ${remaining} més →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `Transcluit de ${targetSlug}`,
linkToOriginal: "Enllaç a l'original",
},
search: {
title: "Cercar",
searchBarPlaceholder: "Cerca alguna cosa",
},
tableOfContents: {
title: "Taula de Continguts",
},
contentMeta: {
readingTime: ({ minutes }) => `Es llegeix en ${minutes} min`,
},
},
pages: {
rss: {
recentNotes: "Notes recents",
lastFewNotes: ({ count }) => `Últimes ${count} notes`,
},
error: {
title: "No s'ha trobat.",
notFound: "Aquesta pàgina és privada o no existeix.",
home: "Torna a la pàgina principal",
},
folderContent: {
folder: "Carpeta",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 article en aquesta carpeta." : `${count} articles en esta carpeta.`,
},
tagContent: {
tag: "Etiqueta",
tagIndex: "índex d'Etiquetes",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 article amb aquesta etiqueta." : `${count} article amb aquesta etiqueta.`,
showingFirst: ({ count }) => `Mostrant les primeres ${count} etiquetes.`,
totalTags: ({ count }) => `S'han trobat ${count} etiquetes en total.`,
},
},
} as const satisfies Translation

View File

@@ -65,6 +65,7 @@ export default {
error: {
title: "Nicht gefunden",
notFound: "Diese Seite ist entweder nicht öffentlich oder existiert nicht.",
home: "Return to Homepage",
},
folderContent: {
folder: "Ordner",

View File

@@ -67,6 +67,7 @@ export interface Translation {
error: {
title: string
notFound: string
home: string
}
folderContent: {
folder: string

View File

@@ -0,0 +1,84 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Untitled",
description: "No description provided",
},
components: {
callout: {
note: "Note",
abstract: "Abstract",
info: "Info",
todo: "To-Do",
tip: "Tip",
success: "Success",
question: "Question",
warning: "Warning",
failure: "Failure",
danger: "Danger",
bug: "Bug",
example: "Example",
quote: "Quote",
},
backlinks: {
title: "Backlinks",
noBacklinksFound: "No backlinks found",
},
themeToggle: {
lightMode: "Light mode",
darkMode: "Dark mode",
},
explorer: {
title: "Explorer",
},
footer: {
createdWith: "Created with",
},
graph: {
title: "Graph View",
},
recentNotes: {
title: "Recent Notes",
seeRemainingMore: ({ remaining }) => `See ${remaining} more →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `Transclude of ${targetSlug}`,
linkToOriginal: "Link to original",
},
search: {
title: "Search",
searchBarPlaceholder: "Search for something",
},
tableOfContents: {
title: "Table of Contents",
},
contentMeta: {
readingTime: ({ minutes }) => `${minutes} min read`,
},
},
pages: {
rss: {
recentNotes: "Recent notes",
lastFewNotes: ({ count }) => `Last ${count} notes`,
},
error: {
title: "Not Found",
notFound: "Either this page is private or doesn't exist.",
home: "Return to Homepage",
},
folderContent: {
folder: "Folder",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 item under this folder." : `${count} items under this folder.`,
},
tagContent: {
tag: "Tag",
tagIndex: "Tag Index",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 item with this tag." : `${count} items with this tag.`,
showingFirst: ({ count }) => `Showing first ${count} tags.`,
totalTags: ({ count }) => `Found ${count} total tags.`,
},
},
} as const satisfies Translation

View File

@@ -65,6 +65,7 @@ export default {
error: {
title: "Not Found",
notFound: "Either this page is private or doesn't exist.",
home: "Return to Homepage",
},
folderContent: {
folder: "Folder",

View File

@@ -22,8 +22,8 @@ export default {
quote: "Cita",
},
backlinks: {
title: "Enlaces de Retroceso",
noBacklinksFound: "No se han encontrado enlaces traseros",
title: "Retroenlaces",
noBacklinksFound: "No se han encontrado retroenlaces",
},
themeToggle: {
lightMode: "Modo claro",
@@ -54,17 +54,18 @@ export default {
title: "Tabla de Contenidos",
},
contentMeta: {
readingTime: ({ minutes }) => `${minutes} min read`,
readingTime: ({ minutes }) => `Se lee en ${minutes} min`,
},
},
pages: {
rss: {
recentNotes: "Notas recientes",
lastFewNotes: ({ count }) => `Últimás ${count} notas`,
lastFewNotes: ({ count }) => `Últimas ${count} notas`,
},
error: {
title: "No se encontró.",
title: "No se ha encontrado.",
notFound: "Esta página es privada o no existe.",
home: "Regresa a la página principal",
},
folderContent: {
folder: "Carpeta",
@@ -77,7 +78,7 @@ export default {
itemsUnderTag: ({ count }) =>
count === 1 ? "1 artículo con esta etiqueta." : `${count} artículos con esta etiqueta.`,
showingFirst: ({ count }) => `Mostrando las primeras ${count} etiquetas.`,
totalTags: ({ count }) => `Se encontraron ${count} etiquetas en total.`,
totalTags: ({ count }) => `Se han encontrado ${count} etiquetas en total.`,
},
},
} as const satisfies Translation

View File

@@ -0,0 +1,84 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "بدون عنوان",
description: "توضیح خاصی اضافه نشده است",
},
components: {
callout: {
note: "یادداشت",
abstract: "چکیده",
info: "اطلاعات",
todo: "اقدام",
tip: "نکته",
success: "تیک",
question: "سؤال",
warning: "هشدار",
failure: "شکست",
danger: "خطر",
bug: "باگ",
example: "مثال",
quote: "نقل قول",
},
backlinks: {
title: "بک‌لینک‌ها",
noBacklinksFound: "بدون بک‌لینک",
},
themeToggle: {
lightMode: "حالت روشن",
darkMode: "حالت تاریک",
},
explorer: {
title: "مطالب",
},
footer: {
createdWith: "ساخته شده با",
},
graph: {
title: "نمای گراف",
},
recentNotes: {
title: "یادداشت‌های اخیر",
seeRemainingMore: ({ remaining }) => `${remaining} یادداشت دیگر →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `از ${targetSlug}`,
linkToOriginal: "پیوند به اصلی",
},
search: {
title: "جستجو",
searchBarPlaceholder: "مطلبی را جستجو کنید",
},
tableOfContents: {
title: "فهرست",
},
contentMeta: {
readingTime: ({ minutes }) => `زمان تقریبی مطالعه: ${minutes} دقیقه`,
},
},
pages: {
rss: {
recentNotes: "یادداشت‌های اخیر",
lastFewNotes: ({ count }) => `${count} یادداشت اخیر`,
},
error: {
title: "یافت نشد",
notFound: "این صفحه یا خصوصی است یا وجود ندارد",
home: "بازگشت به صفحه اصلی",
},
folderContent: {
folder: "پوشه",
itemsUnderFolder: ({ count }) =>
count === 1 ? ".یک مطلب در این پوشه است" : `${count} مطلب در این پوشه است.`,
},
tagContent: {
tag: "برچسب",
tagIndex: "فهرست برچسب‌ها",
itemsUnderTag: ({ count }) =>
count === 1 ? "یک مطلب با این برچسب" : `${count} مطلب با این برچسب.`,
showingFirst: ({ count }) => `در حال نمایش ${count} برچسب.`,
totalTags: ({ count }) => `${count} برچسب یافت شد.`,
},
},
} as const satisfies Translation

View File

@@ -54,7 +54,7 @@ export default {
title: "Table des Matières",
},
contentMeta: {
readingTime: ({ minutes }) => `${minutes} min read`,
readingTime: ({ minutes }) => `${minutes} min de lecture`,
},
},
pages: {
@@ -63,8 +63,9 @@ export default {
lastFewNotes: ({ count }) => `Les dernières ${count} notes`,
},
error: {
title: "Pas trouvé",
title: "Introuvable",
notFound: "Cette page est soit privée, soit elle n'existe pas.",
home: "Retour à la page d'accueil",
},
folderContent: {
folder: "Dossier",

View File

@@ -0,0 +1,82 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Névtelen",
description: "Nincs leírás",
},
components: {
callout: {
note: "Jegyzet",
abstract: "Abstract",
info: "Információ",
todo: "Tennivaló",
tip: "Tipp",
success: "Siker",
question: "Kérdés",
warning: "Figyelmeztetés",
failure: "Hiba",
danger: "Veszély",
bug: "Bug",
example: "Példa",
quote: "Idézet",
},
backlinks: {
title: "Visszautalások",
noBacklinksFound: "Nincs visszautalás",
},
themeToggle: {
lightMode: "Világos mód",
darkMode: "Sötét mód",
},
explorer: {
title: "Fájlböngésző",
},
footer: {
createdWith: "Készítve ezzel:",
},
graph: {
title: "Grafikonnézet",
},
recentNotes: {
title: "Legutóbbi jegyzetek",
seeRemainingMore: ({ remaining }) => `${remaining} további megtekintése →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `${targetSlug} áthivatkozása`,
linkToOriginal: "Hivatkozás az eredetire",
},
search: {
title: "Keresés",
searchBarPlaceholder: "Keress valamire",
},
tableOfContents: {
title: "Tartalomjegyzék",
},
contentMeta: {
readingTime: ({ minutes }) => `${minutes} perces olvasás`,
},
},
pages: {
rss: {
recentNotes: "Legutóbbi jegyzetek",
lastFewNotes: ({ count }) => `Legutóbbi ${count} jegyzet`,
},
error: {
title: "Nem található",
notFound: "Ez a lap vagy privát vagy nem létezik.",
home: "Vissza a kezdőlapra",
},
folderContent: {
folder: "Mappa",
itemsUnderFolder: ({ count }) => `Ebben a mappában ${count} elem található.`,
},
tagContent: {
tag: "Címke",
tagIndex: "Címke index",
itemsUnderTag: ({ count }) => `${count} elem található ezzel a címkével.`,
showingFirst: ({ count }) => `Első ${count} címke megjelenítve.`,
totalTags: ({ count }) => `Összesen ${count} címke található.`,
},
},
} as const satisfies Translation

View File

@@ -65,6 +65,7 @@ export default {
error: {
title: "Non trovato",
notFound: "Questa pagina è privata o non esiste.",
home: "Ritorna alla home page",
},
folderContent: {
folder: "Cartella",

View File

@@ -65,6 +65,7 @@ export default {
error: {
title: "Not Found",
notFound: "ページが存在しないか、非公開設定になっています。",
home: "ホームページに戻る",
},
folderContent: {
folder: "フォルダ",

View File

@@ -65,6 +65,7 @@ export default {
error: {
title: "Not Found",
notFound: "페이지가 존재하지 않거나 비공개 설정이 되어 있습니다.",
home: "홈페이지로 돌아가기",
},
folderContent: {
folder: "폴더",

View File

@@ -66,6 +66,7 @@ export default {
error: {
title: "Niet gevonden",
notFound: "Deze pagina is niet zichtbaar of bestaat niet.",
home: "Keer terug naar de start pagina",
},
folderContent: {
folder: "Map",

View File

@@ -0,0 +1,84 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Bez nazwy",
description: "Brak opisu",
},
components: {
callout: {
note: "Notatka",
abstract: "Streszczenie",
info: "informacja",
todo: "Do zrobienia",
tip: "Wskazówka",
success: "Zrobione",
question: "Pytanie",
warning: "Ostrzeżenie",
failure: "Usterka",
danger: "Niebiezpieczeństwo",
bug: "Błąd w kodzie",
example: "Przykład",
quote: "Cytat",
},
backlinks: {
title: "Odnośniki zwrotne",
noBacklinksFound: "Brak połączeń zwrotnych",
},
themeToggle: {
lightMode: "Trzyb jasny",
darkMode: "Tryb ciemny",
},
explorer: {
title: "Przeglądaj",
},
footer: {
createdWith: "Stworzone z użyciem",
},
graph: {
title: "Graf",
},
recentNotes: {
title: "Najnowsze notatki",
seeRemainingMore: ({ remaining }) => `Zobacz ${remaining} nastepnych →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `Osadzone ${targetSlug}`,
linkToOriginal: "Łącze do oryginału",
},
search: {
title: "Szukaj",
searchBarPlaceholder: "Search for something",
},
tableOfContents: {
title: "Spis treści",
},
contentMeta: {
readingTime: ({ minutes }) => `${minutes} min. czytania `,
},
},
pages: {
rss: {
recentNotes: "Najnowsze notatki",
lastFewNotes: ({ count }) => `Ostatnie ${count} notatek`,
},
error: {
title: "Nie znaleziono",
notFound: "Ta strona jest prywatna lub nie istnieje.",
home: "Powrót do strony głównej",
},
folderContent: {
folder: "Folder",
itemsUnderFolder: ({ count }) =>
count === 1 ? "W tym folderze jest 1 element." : `Elementów w folderze: ${count}.`,
},
tagContent: {
tag: "Znacznik",
tagIndex: "Spis znaczników",
itemsUnderTag: ({ count }) =>
count === 1 ? "Oznaczony 1 element." : `Elementów z tym znacznikiem: ${count}.`,
showingFirst: ({ count }) => `Pokazuje ${count} pierwszych znaczników.`,
totalTags: ({ count }) => `Znalezionych wszystkich znaczników: ${count}.`,
},
},
} as const satisfies Translation

View File

@@ -0,0 +1,84 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Sem título",
description: "Sem descrição",
},
components: {
callout: {
note: "Nota",
abstract: "Abstrato",
info: "Info",
todo: "Pendência",
tip: "Dica",
success: "Sucesso",
question: "Pergunta",
warning: "Aviso",
failure: "Falha",
danger: "Perigo",
bug: "Bug",
example: "Exemplo",
quote: "Citação",
},
backlinks: {
title: "Backlinks",
noBacklinksFound: "Sem backlinks encontrados",
},
themeToggle: {
lightMode: "Tema claro",
darkMode: "Tema escuro",
},
explorer: {
title: "Explorador",
},
footer: {
createdWith: "Criado com",
},
graph: {
title: "Visão de gráfico",
},
recentNotes: {
title: "Notas recentes",
seeRemainingMore: ({ remaining }) => `Veja mais ${remaining}`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `Transcrever de ${targetSlug}`,
linkToOriginal: "Link ao original",
},
search: {
title: "Pesquisar",
searchBarPlaceholder: "Pesquisar por algo",
},
tableOfContents: {
title: "Sumário",
},
contentMeta: {
readingTime: ({ minutes }) => `Leitura de ${minutes} min`,
},
},
pages: {
rss: {
recentNotes: "Notas recentes",
lastFewNotes: ({ count }) => `Últimas ${count} notas`,
},
error: {
title: "Não encontrado",
notFound: "Esta página é privada ou não existe.",
home: "Retornar a página inicial",
},
folderContent: {
folder: "Arquivo",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 item neste arquivo." : `${count} items neste arquivo.`,
},
tagContent: {
tag: "Tag",
tagIndex: "Sumário de Tags",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 item com esta tag." : `${count} items com esta tag.`,
showingFirst: ({ count }) => `Mostrando as ${count} primeiras tags.`,
totalTags: ({ count }) => `Encontradas ${count} tags.`,
},
},
} as const satisfies Translation

View File

@@ -66,6 +66,7 @@ export default {
error: {
title: "Pagina nu a fost găsită",
notFound: "Fie această pagină este privată, fie nu există.",
home: "Reveniți la pagina de pornire",
},
folderContent: {
folder: "Dosar",

View File

@@ -67,6 +67,7 @@ export default {
error: {
title: "Страница не найдена",
notFound: "Эта страница приватная или не существует",
home: "Вернуться на главную страницу",
},
folderContent: {
folder: "Папка",

View File

@@ -54,7 +54,7 @@ export default {
title: "Зміст",
},
contentMeta: {
readingTime: ({ minutes }) => `${minutes} min read`,
readingTime: ({ minutes }) => `${minutes} хв читання`,
},
},
pages: {
@@ -65,19 +65,20 @@ export default {
error: {
title: "Не знайдено",
notFound: "Ця сторінка або приватна, або не існує.",
home: "Повернутися на головну сторінку",
},
folderContent: {
folder: "Папка",
folder: "Тека",
itemsUnderFolder: ({ count }) =>
count === 1 ? "У цій папці 1 елемент." : `Елементів у цій папці: ${count}.`,
count === 1 ? "У цій теці 1 елемент." : `Елементів у цій теці: ${count}.`,
},
tagContent: {
tag: "Тег",
tagIndex: "Індекс тегу",
tag: "Мітка",
tagIndex: "Індекс мітки",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 елемент з цим тегом." : `Елементів з цим тегом: ${count}.`,
showingFirst: ({ count }) => `Показ перших ${count} тегів.`,
totalTags: ({ count }) => `Всього знайдено тегів: ${count}.`,
count === 1 ? "1 елемент з цією міткою." : `Елементів з цією міткою: ${count}.`,
showingFirst: ({ count }) => `Показ перших ${count} міток.`,
totalTags: ({ count }) => `Всього знайдено міток: ${count}.`,
},
},
} as const satisfies Translation

View File

@@ -0,0 +1,84 @@
import { Translation } from "./definition"
export default {
propertyDefaults: {
title: "Không có tiêu đề",
description: "Không có mô tả được cung cấp",
},
components: {
callout: {
note: "Ghi Chú",
abstract: "Tóm Tắt",
info: "Thông tin",
todo: "Cần Làm",
tip: "Gợi Ý",
success: "Thành Công",
question: "Nghi Vấn",
warning: "Cảnh Báo",
failure: "Thất Bại",
danger: "Nguy Hiểm",
bug: "Lỗi",
example: "Ví Dụ",
quote: "Trích Dẫn",
},
backlinks: {
title: "Liên Kết Ngược",
noBacklinksFound: "Không có liên kết ngược được tìm thấy",
},
themeToggle: {
lightMode: "Sáng",
darkMode: "Tối",
},
explorer: {
title: "Trong bài này",
},
footer: {
createdWith: "Được tạo bởi",
},
graph: {
title: "Biểu Đồ",
},
recentNotes: {
title: "Bài viết gần đây",
seeRemainingMore: ({ remaining }) => `Xem ${remaining} thêm →`,
},
transcludes: {
transcludeOf: ({ targetSlug }) => `Bao gồm ${targetSlug}`,
linkToOriginal: "Liên Kết Gốc",
},
search: {
title: "Tìm Kiếm",
searchBarPlaceholder: "Tìm kiếm thông tin",
},
tableOfContents: {
title: "Bảng Nội Dung",
},
contentMeta: {
readingTime: ({ minutes }) => `đọc ${minutes} phút`,
},
},
pages: {
rss: {
recentNotes: "Những bài gần đây",
lastFewNotes: ({ count }) => `${count} Bài gần đây`,
},
error: {
title: "Không Tìm Thấy",
notFound: "Trang này được bảo mật hoặc không tồn tại.",
home: "Trở về trang chủ",
},
folderContent: {
folder: "Thư Mục",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 mục trong thư mục này." : `${count} mục trong thư mục này.`,
},
tagContent: {
tag: "Thẻ",
tagIndex: "Thẻ Mục Lục",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 mục gắn thẻ này." : `${count} mục gắn thẻ này.`,
showingFirst: ({ count }) => `Hiển thị trước ${count} thẻ.`,
totalTags: ({ count }) => `Tìm thấy ${count} thẻ tổng cộng.`,
},
},
} as const satisfies Translation

View File

@@ -65,6 +65,7 @@ export default {
error: {
title: "无法找到",
notFound: "私有笔记或笔记不存在。",
home: "返回首页",
},
folderContent: {
folder: "文件夹",

View File

@@ -8,7 +8,6 @@ import popoverScript from "../../components/scripts/popover.inline"
import styles from "../../styles/custom.scss"
import popoverStyle from "../../components/styles/popover.scss"
import { BuildCtx } from "../../util/ctx"
import { StaticResources } from "../../util/resources"
import { QuartzComponent } from "../../components/types"
import { googleFontHref, joinStyles } from "../../util/theme"
import { Features, transform } from "lightningcss"
@@ -69,13 +68,8 @@ async function joinScripts(scripts: string[]): Promise<string> {
return res.code
}
function addGlobalPageResources(
ctx: BuildCtx,
staticResources: StaticResources,
componentResources: ComponentResources,
) {
function addGlobalPageResources(ctx: BuildCtx, componentResources: ComponentResources) {
const cfg = ctx.cfg.configuration
const reloadScript = ctx.argv.serve
// popovers
if (cfg.enablePopovers) {
@@ -85,12 +79,12 @@ function addGlobalPageResources(
if (cfg.analytics?.provider === "google") {
const tagId = cfg.analytics.tagId
staticResources.js.push({
src: `https://www.googletagmanager.com/gtag/js?id=${tagId}`,
contentType: "external",
loadTime: "afterDOMReady",
})
componentResources.afterDOMLoaded.push(`
const gtagScript = document.createElement("script")
gtagScript.src = "https://www.googletagmanager.com/gtag/js?id=${tagId}"
gtagScript.async = true
document.head.appendChild(gtagScript)
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag("js", new Date());
@@ -120,12 +114,44 @@ function addGlobalPageResources(
} else if (cfg.analytics?.provider === "umami") {
componentResources.afterDOMLoaded.push(`
const umamiScript = document.createElement("script")
umamiScript.src = "${cfg.analytics.host}" ?? "https://analytics.umami.is/script.js"
umamiScript.src = "${cfg.analytics.host ?? "https://analytics.umami.is"}/script.js"
umamiScript.setAttribute("data-website-id", "${cfg.analytics.websiteId}")
umamiScript.async = true
document.head.appendChild(umamiScript)
`)
} else if (cfg.analytics?.provider === "goatcounter") {
componentResources.afterDOMLoaded.push(`
const goatcounterScript = document.createElement("script")
goatcounterScript.src = "${cfg.analytics.scriptSrc ?? "https://gc.zgo.at/count.js"}"
goatcounterScript.async = true
goatcounterScript.setAttribute("data-goatcounter",
"https://${cfg.analytics.websiteId}.${cfg.analytics.host ?? "goatcounter.com"}/count")
document.head.appendChild(goatcounterScript)
`)
} else if (cfg.analytics?.provider === "posthog") {
componentResources.afterDOMLoaded.push(`
const posthogScript = document.createElement("script")
posthogScript.innerHTML= \`!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('${cfg.analytics.apiKey}',{api_host:'${cfg.analytics.host ?? "https://app.posthog.com"}'})\`
document.head.appendChild(posthogScript)
`)
} else if (cfg.analytics?.provider === "tinylytics") {
const siteId = cfg.analytics.siteId
componentResources.afterDOMLoaded.push(`
const tinylyticsScript = document.createElement("script")
tinylyticsScript.src = "https://tinylytics.app/embed/${siteId}.js"
tinylyticsScript.defer = true
document.head.appendChild(tinylyticsScript)
`)
} else if (cfg.analytics?.provider === "cabin") {
componentResources.afterDOMLoaded.push(`
const cabinScript = document.createElement("script")
cabinScript.src = "${cfg.analytics.host ?? "https://scripts.cabin.dev"}/cabin.js"
cabinScript.defer = true
cabinScript.async = true
document.head.appendChild(cabinScript)
`)
}
if (cfg.enableSPA) {
@@ -138,115 +164,72 @@ function addGlobalPageResources(
document.dispatchEvent(event)
`)
}
let wsUrl = `ws://localhost:${ctx.argv.wsPort}`
if (ctx.argv.remoteDevHost) {
wsUrl = `wss://${ctx.argv.remoteDevHost}:${ctx.argv.wsPort}`
}
if (reloadScript) {
staticResources.js.push({
loadTime: "afterDOMReady",
contentType: "inline",
script: `
const socket = new WebSocket('${wsUrl}')
// reload(true) ensures resources like images and scripts are fetched again in firefox
socket.addEventListener('message', () => document.location.reload(true))
`,
})
}
}
interface Options {
fontOrigin: "googleFonts" | "local"
}
const defaultOptions: Options = {
fontOrigin: "googleFonts",
}
export const ComponentResources: QuartzEmitterPlugin<Options> = (opts?: Partial<Options>) => {
const { fontOrigin } = { ...defaultOptions, ...opts }
// This emitter should not update the `resources` parameter. If it does, partial
// rebuilds may not work as expected.
export const ComponentResources: QuartzEmitterPlugin = () => {
return {
name: "ComponentResources",
getQuartzComponents() {
return []
},
async getDependencyGraph(ctx, content, _resources) {
// This emitter adds static resources to the `resources` parameter. One
// important resource this emitter adds is the code to start a websocket
// connection and listen to rebuild messages, which triggers a page reload.
// The resources parameter with the reload logic is later used by the
// ContentPage emitter while creating the final html page. In order for
// the reload logic to be included, and so for partial rebuilds to work,
// we need to run this emitter for all markdown files.
const graph = new DepGraph<FilePath>()
for (const [_tree, file] of content) {
const sourcePath = file.data.filePath!
const slug = file.data.slug!
graph.addEdge(sourcePath, joinSegments(ctx.argv.output, slug + ".html") as FilePath)
}
return graph
async getDependencyGraph(_ctx, _content, _resources) {
return new DepGraph<FilePath>()
},
async emit(ctx, _content, resources): Promise<FilePath[]> {
async emit(ctx, _content, _resources): Promise<FilePath[]> {
const promises: Promise<FilePath>[] = []
const cfg = ctx.cfg.configuration
// component specific scripts and styles
const componentResources = getComponentResources(ctx)
let googleFontsStyleSheet = ""
if (fontOrigin === "local") {
if (cfg.theme.fontOrigin === "local") {
// let the user do it themselves in css
} else if (fontOrigin === "googleFonts") {
if (cfg.theme.cdnCaching) {
resources.css.push(googleFontHref(cfg.theme))
} else {
let match
} else if (cfg.theme.fontOrigin === "googleFonts" && !cfg.theme.cdnCaching) {
// when cdnCaching is true, we link to google fonts in Head.tsx
let match
const fontSourceRegex = /url\((https:\/\/fonts.gstatic.com\/s\/[^)]+\.(woff2|ttf))\)/g
const fontSourceRegex = /url\((https:\/\/fonts.gstatic.com\/s\/[^)]+\.(woff2|ttf))\)/g
googleFontsStyleSheet = await (
await fetch(googleFontHref(ctx.cfg.configuration.theme))
).text()
googleFontsStyleSheet = await (
await fetch(googleFontHref(ctx.cfg.configuration.theme))
).text()
while ((match = fontSourceRegex.exec(googleFontsStyleSheet)) !== null) {
// match[0] is the `url(path)`, match[1] is the `path`
const url = match[1]
// the static name of this file.
const [filename, ext] = url.split("/").pop()!.split(".")
while ((match = fontSourceRegex.exec(googleFontsStyleSheet)) !== null) {
// match[0] is the `url(path)`, match[1] is the `path`
const url = match[1]
// the static name of this file.
const [filename, ext] = url.split("/").pop()!.split(".")
googleFontsStyleSheet = googleFontsStyleSheet.replace(
url,
`/static/fonts/${filename}.ttf`,
)
googleFontsStyleSheet = googleFontsStyleSheet.replace(
url,
`https://${cfg.baseUrl}/static/fonts/${filename}.ttf`,
)
promises.push(
fetch(url)
.then((res) => {
if (!res.ok) {
throw new Error(`Failed to fetch font`)
}
return res.arrayBuffer()
})
.then((buf) =>
write({
ctx,
slug: joinSegments("static", "fonts", filename) as FullSlug,
ext: `.${ext}`,
content: Buffer.from(buf),
}),
),
)
}
promises.push(
fetch(url)
.then((res) => {
if (!res.ok) {
throw new Error(`Failed to fetch font`)
}
return res.arrayBuffer()
})
.then((buf) =>
write({
ctx,
slug: joinSegments("static", "fonts", filename) as FullSlug,
ext: `.${ext}`,
content: Buffer.from(buf),
}),
),
)
}
}
// important that this goes *after* component scripts
// as the "nav" event gets triggered here and we should make sure
// that everyone else had the chance to register a listener for it
addGlobalPageResources(ctx, resources, componentResources)
addGlobalPageResources(ctx, componentResources)
const stylesheet = joinStyles(
ctx.cfg.configuration.theme,

View File

@@ -59,14 +59,25 @@ export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOp
...userOpts,
}
const { head: Head, header, beforeBody, pageBody, left, right, footer: Footer } = opts
const { head: Head, header, beforeBody, pageBody, afterBody, left, right, footer: Footer } = opts
const Header = HeaderConstructor()
const Body = BodyConstructor()
return {
name: "ContentPage",
getQuartzComponents() {
return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer]
return [
Head,
Header,
Body,
...header,
...beforeBody,
pageBody,
...afterBody,
...left,
...right,
Footer,
]
},
async getDependencyGraph(ctx, content, _resources) {
const graph = new DepGraph<FilePath>()

Some files were not shown because too many files have changed in this diff Show More