Compare commits

...

804 Commits

Author SHA1 Message Date
Gal 6ba49a99c7
Remove /content directory 2024-02-11 15:58:48 +01:00
Gal eadfd84b41
Initial commit 2024-02-11 15:52:45 +01:00
Gal 88966b0709
Update 2024-01-21 21:56:22 +07:00
Gal 5b843015b0
test 2023-12-30 00:01:03 +01:00
Gal 108c5cb7e1
test 2023-12-29 22:41:52 +01:00
Gal d5862e920c
test 2023-12-29 22:40:22 +01:00
Gal f3409ab966
test 2023-12-29 22:38:22 +01:00
Gal df0f8997aa
test 2023-12-29 22:36:31 +01:00
Gal 818c5be46e
test 2023-12-29 18:26:41 +01:00
Gal b68c00a081
test 2023-12-29 18:18:45 +01:00
Gal d18338f463
Change config 2023-12-29 18:13:23 +01:00
Galuh Sahid 649f2884bd add network 2023-12-28 22:55:02 +01:00
Galuh Sahid 42c1b3ee3a remove network 2023-12-27 23:53:57 +01:00
Galuh Sahid d95cab7eb8 change port 2023-12-27 23:47:43 +01:00
Galuh Sahid fada9db801 change port 2023-12-27 23:43:03 +01:00
Galuh Sahid ffa806ef51 change port 2023-12-27 23:42:38 +01:00
Galuh Sahid 416997f7fc change port 2023-12-27 23:41:25 +01:00
Galuh Sahid 61f34b8d60 Add traefik 2023-12-27 23:28:24 +01:00
Galuh Sahid c383f93016 Update 2023-12-27 22:11:25 +01:00
Galuh Sahid b4af071290 update readme 2023-12-27 22:09:22 +01:00
Galuh Sahid 7ec45a5f1d Add env 2023-12-27 22:06:00 +01:00
Galuh Sahid 4c2d57de12 Add script 2023-12-27 22:04:30 +01:00
Galuh Sahid f0966984b6 Update makefile 2023-12-27 22:04:12 +01:00
Galuh Sahid 736e12d643 Update makefile 2023-12-27 21:38:36 +01:00
Galuh Sahid 17e334a3ff Update makefile 2023-12-27 21:38:12 +01:00
Gal 1a9b2d3508 Add scripts 2023-12-27 21:35:10 +01:00
Galuh Sahid 20a4ca534b change port 2023-12-27 00:58:43 +01:00
Galuh Sahid 2f07d22c75 change port 2023-12-27 00:30:20 +01:00
Galuh Sahid d350d94e68 test change 2023-12-26 14:25:27 +01:00
Galuh Sahid d5d00fbe16 update 2023-12-26 14:22:56 +01:00
Galuh Sahid 9ebf84d1d4 Add npm install 2023-12-26 13:57:39 +01:00
Galuh Sahid fccaeac7c3 change port 2023-12-26 13:49:23 +01:00
Galuh Sahid bdf7e88d3b Add dc 2023-12-26 13:48:48 +01:00
Galuh Sahid b8127b95a9 Add website 2023-12-12 00:49:06 +01:00
Galuh Sahid de8dc6a3e3 Add website 2023-12-12 00:44:33 +01:00
Galuh Sahid 8fa9aad9da Quartz sync: Dec 9, 2023, 5:36 PM 2023-12-09 17:36:33 +01:00
Jacky Zhao 296c1cf83f fix: spa shouldn't use popover script directly 2023-11-18 18:46:58 -08:00
Jacky Zhao 516d9a27e7 fix: explicit undefined check in header transclude 2023-11-18 18:27:44 -08:00
Jacky Zhao 6a05fa777c fix: bad transform in wikilink pre-transform (closes #598) 2023-11-17 14:00:49 -08:00
Jacky Zhao 3f0be7fbe4 fix: check content-type before applying spa patch (closes #597) 2023-11-17 10:46:23 -08:00
Jacky Zhao ea08c0511a fix: dont run explorer scripts on non-explorer pages (closes #596) 2023-11-17 10:29:24 -08:00
Matt Vogel 727b9b5d72
feat: add class `alias` to aliases (#585) 2023-11-17 10:23:39 -08:00
Zijing Zhang 50f0ba29a2
feat: cname emitter (#590)
* feat: cname emitter

* feat: impl cname.ts

* Update cname.ts

* Update index.ts

* Update cname.ts

* Update cname.ts

* Update cname.ts

* Update cname.ts
2023-11-16 15:31:20 -08:00
Jacky Zhao 95b1141b9d fix: include anchor when normalizing urls for spa/popovers 2023-11-15 20:35:45 -08:00
Jacky Zhao a26eb59392 feat: scrub link formatting from toc entries 2023-11-15 20:13:28 -08:00
Jacky Zhao 5befcf4780 fix: format 2023-11-15 19:32:25 -08:00
Jacky Zhao f861a7c160 fix: regression where clicking anchors on the same page wouldn't set the anchor in the url 2023-11-15 19:31:18 -08:00
Jacky Zhao 06426c8f7e feat: support repeated anchor tag (closes #592) 2023-11-15 19:27:54 -08:00
Jacky Zhao 8fc7b9f4c6 feat: deref symlinks when copying static assets (closes #588) 2023-11-15 09:43:30 -08:00
Jacky Zhao 2de48b267a fix: set htmlAst after walking tree in ofm (closes #589) 2023-11-14 20:01:48 -08:00
Jacky Zhao 76f2664277 versioning: bump to v4.1.1 2023-11-13 22:57:05 -08:00
Jacky Zhao 74777118a7 feat: header and full-page transcludes (closes #557) 2023-11-13 22:51:40 -08:00
Jacky Zhao 8223465bda fix: make :has img selector direct 2023-11-12 14:33:19 -08:00
Jacky Zhao cf6ab9e933 feat: option to specify npx quartz sync message (closes #583) 2023-11-12 14:27:53 -08:00
Jacky Zhao 74c63e448e fix(style): dont internal-link highlight when image (closes #581) 2023-11-11 21:13:10 -08:00
Jacky Zhao 43d638a6de perf: compute mapping of folder name to file data for faster breadcrumbs 2023-11-11 21:06:37 -08:00
Jacky Zhao d1551872ff fix: check if popover exists after fetching and before inserting 2023-11-11 20:46:57 -08:00
Jacky Zhao 275bea3051 style + cfg: resolve breadcrumb titles by default and change arrow character 2023-11-11 20:46:29 -08:00
Jacky Zhao bc02791734 fix: .date.getTime() based sort 2023-11-11 20:28:26 -08:00
Jacky Zhao bf603c49c2 fix: sort rss feed by date 2023-11-11 12:08:54 -08:00
Jacky Zhao f67356c3d2 lint: format 2023-11-11 12:02:34 -08:00
Jacky Zhao 5d666d1860 fix: normalize relative urls (closes #569) 2023-11-11 11:59:05 -08:00
Jacky Zhao 22b7cf135e types: cast in jsx.tsx to avoid @ts-ignore 2023-11-11 11:41:44 -08:00
Jacky Zhao 50a87d0d86 style: scrollable tables 2023-11-11 11:39:56 -08:00
Jacky Zhao 134b6ed582 fix: anchors links shouldnt cause reload (closes #574) 2023-11-11 10:11:31 -08:00
Jacky Zhao 99e8f5944f fix: trailing slash aliases (closes #577) 2023-11-11 09:56:30 -08:00
Yes365 e9f4e28a2d
fix: adapt vercel cleanurls (#487)
Co-authored-by: Harrison <Harrison@fanruan.com>
2023-11-09 19:44:16 -08:00
Niklas Schröder 2a6b9a9ea0
docs: fix property name for ToC toggle (#573) 2023-11-07 09:16:48 -08:00
Mau Camargo e806c30fa1
docs: Add Mau Camargo's Notkesto to showcase (#570) 2023-11-05 11:30:10 -08:00
Anson Yu aac7b7e97d
docs: Update making plugins.md (#567)
:)
2023-11-04 14:20:16 -07:00
Jacky Zhao 101e9946bd feat: add collapseByDefault option to TableOfContents (closes #566) 2023-11-04 12:11:42 -07:00
Emil Rofors a62a97c7ab
docs: add GitLab pages CI (#549)
* add .gitlab-ci.yml

* move GitLab CI to hosting.md

* remove extra folder name

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

* remove test from gitlab instructions

* run prettier

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2023-11-03 16:40:43 -07:00
Jacky Zhao 923b72fb67 feat: auto-tag releases (closes #560) 2023-11-01 10:04:41 -07:00
Florence 05a1c34c6f
docs: remove dead link (#561) 2023-11-01 09:57:32 -07:00
Blue Rose 06ccb89cd7
docs: clarifications about globs (#559)
* Add note about fast-glob

* Add warning about non-markdown files

Also added a glob pattern to filter out all non-markdown files outside of a specified folder.

* run npm format

---------

Co-authored-by: wych <wychwitchcraft@gmail.com>
2023-10-31 13:53:49 -07:00
Jacky Zhao 01fc8e4640 fix: disable semi-broken flexsearch cache 2023-10-25 09:40:43 -07:00
Jacky Zhao 7c01e8dde0 feat: openLinksInNewTab option for link transformer 2023-10-22 09:54:12 -07:00
Jacky Zhao b7ae7a99db fix: styling for nested popover tag in page list 2023-10-21 21:12:11 -07:00
Jacky Zhao 60b3bc34cb fix: catch html to jsx errors (closes #547) 2023-10-21 21:06:02 -07:00
Jacky Zhao dc834015d0 fix(style): tag float orientation for long tags on page listing 2023-10-21 21:06:02 -07:00
Jacky Zhao 1e357ef5ac fix(style): prioritize base and custom scss over component css 2023-10-21 21:06:02 -07:00
freenandes 54e722a55d
docs: Update showcase.md (#540)
changed URL
2023-10-17 19:43:41 -07:00
Thomas 86d16b12a2
docs(explorer): Fixed small typo with extra } in explorer.md (#541) 2023-10-17 19:43:20 -07:00
freenandes ed971800c0
Update showcase.md (#539) 2023-10-17 08:58:28 -07:00
Jacky Zhao af9ddadc4d
fix(css): import base from custom instead of the other way around (#536) 2023-10-14 13:45:56 -07:00
Jacky Zhao da0a062c05 feat: docker support for v4 (closes #530) 2023-10-08 09:59:18 -07:00
Jacky Zhao f66d2c23ac fix: ctrl+click with spa enabled 2023-10-08 09:15:06 -07:00
Jacky Zhao 3268d45a20 css: make article relative 2023-10-05 13:48:52 -07:00
Jacky Zhao afa163f2fe
style: styling for codeblocks without langs (#527) 2023-10-05 13:30:06 -07:00
Ben Schlegel cec4877adb
fix(breadcrumbs): problem with folder whitespace (#522)
* fix(breadcrumbs): problem with folder whitespace

use slugs for folder hrefs so folder paths get resolved properly

* feat: only use `slug` for constructing crumbs

* fix: remove capitalization
2023-10-05 09:19:56 -07:00
Jacky Zhao cf0c090e3c specify minimum npm version 2023-10-04 09:23:56 -07:00
Luca Salvarani c8f5dbbad3
fix: Fix `Backlinks` not applying the display class (#519)
* fix: Fix `Backlinks` not applying the display class

Fix #518

* fix: Apply `displayClass` to all layout components

* refactor: Use same style

* fix: Remove `undefined` class using coalescing operator
2023-10-01 17:20:55 -07:00
bfahrenfort ab5efac75f
Fix: RSS title escaping (#521)
* Fix title escaping

* npm run format
2023-10-01 09:47:22 -07:00
Hrishikesh Barman 2f99339dcf
feat: add transformations for latex in oxhugofm (#510)
ox-hugo currently supports the following syntax for latex equations:
- https://orgmode.org/manual/LaTeX-fragments.html
- https://ox-hugo.scripter.co/doc/equations

This syntax is supported by mathjax as is mentioned in the ox-hugo documentation.

But quartz uses remark-math which has some issues with the \( \) syntax.
See https://github.com/remarkjs/remark-math/issues/39

This change adds few more transformations to the OxHugoFlavouredMarkdown
plugin, which makes a best effort conversion of this syntax into what
the Quartz Latex transformer plugin supports.

With these changes, the generated files show latex formatting with
default quartz configuration.

Sidenote on `\_` escape by ox-hugo:

ox-hugo escapes, _ using \_, we match against it after we transform
equations into what quartz supports($$ and $).

This could be achieved using lookaround like regex as follows
```js
(?<=(\$|\$\$)[\s\S]*) -> Positive lookbehind for $ or $$
\\_ -> Matches \_
(?=[\s\S]*(?:\1)) Positive lookahead for $ or $$ if matched
const escapedUnderscoreRegex = new RegExp(/(?<=(\$|\$\$)[\s\S]*)\\_(?=[\s\S]*(?:\1))/, "g")
````

But since lookahead/behind can slow things down on large files, we just
look up all equations with $ and $$ delimiters and then try replacing \_
2023-09-29 11:35:26 -07:00
ArtfulAzeria 5232d09af5
feat: Better and more responsive tag behavior (#515)
* fix(explorer): default sortFn implementation (#511)

* fix: use `numeric` + `base` for localeCompare

* docs(explorer): update default sortFn

* fix: better and more responsive tag behavior

* tags css moved to TagList.tsx

* used npm run format

* merged tag declarations

---------

Co-authored-by: Ben Schlegel <31989404+benschlegel@users.noreply.github.com>
2023-09-29 11:17:48 -07:00
Catchears 0138085c16
docs: fix typo in breadcrumbs documentation (#513) 2023-09-29 08:19:10 -07:00
Ben Schlegel 0b61f6fbfd
feat: implement breadcrumb component (#508)
* feat: implement breadcrumbs

* style: fix styling, move breadcrumbs to top

* refactor: move `capitalize to `lang.ts``

* refactor: clean breadcrumb generation

* feat: add options to breadcrumbs

* feat: implement `resolveFrontmatterTitle`

* feat: add `hideOnRoot` option

* feat(consistency): capitalize every crumb

* style: add `flex-wrap` to parent container

* refactor: clean `Breadcrumbs.tsx`

* feat(accessibility): use `nav`, add aria label

* style: improve look in popovers by adding margin

* docs: write docs for breadcrumb component

* refactor: collapse `if` condition for hideOnRoot

* chore: add todo for perf optimization

* docs: update introduction
2023-09-29 10:26:15 +02:00
Ben Schlegel d4c122646c
fix(explorer): default sortFn implementation (#511)
* fix: use `numeric` + `base` for localeCompare

* docs(explorer): update default sortFn
2023-09-28 08:39:44 -07:00
Jacky Zhao d22c3c107a fix: coerce title to string 2023-09-25 18:15:55 -07:00
Jacky Zhao 697bffdb8b fix: treat the 0 time as invalid too 2023-09-24 14:47:30 -07:00
Jacky Zhao ea5742c328 fix: mermaid copy source position 2023-09-24 10:31:54 -07:00
Chad Lee 95eec5b49d
add site to showcase (#504) 2023-09-24 10:27:42 -07:00
Vince Imbat c5b9137f12
docs: Adds Vince Imbat to showcase (#501) 2023-09-22 19:39:02 -07:00
Jacky Zhao 13c8673226 feat: add warning for invalid date format 2023-09-22 10:04:50 -07:00
Jacky Zhao a897cc1f53 feat: add warning for missing home page 2023-09-22 10:04:50 -07:00
Ben Schlegel d93599364a
docs(showcase): fix pull request redirect link (#500) 2023-09-22 08:20:19 -07:00
Ben Schlegel fa69c2a565
fix(explorer): increase consistency, explicitly use font-family (#496)
* fix(explorer): display name for folders without `index` file

* docs(explorer): add section for folder display names

* docs(explorer): fix broken wikilink

* fix(consistency): explicitly set font + label/link fix

Use consistent styling between folders with `folderClickBehavior: "link"` and `"collapse`

* Update quartz/components/styles/explorer.scss

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

* Update quartz/components/styles/explorer.scss

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

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2023-09-21 19:35:11 +02:00
Ben Schlegel 8eb1554b13
fix(explorer): display names for folders without frontmatter (#494)
* fix(explorer): display name for folders without `index` file

* docs(explorer): add section for folder display names
2023-09-21 18:54:33 +02:00
Ben Schlegel dcdeae4e7b
docs(explorer): update default config + new example (#493) 2023-09-21 18:53:19 +02:00
Jacky Zhao 48452231d5
perf: memoize filetree computation (#490)
* perf: memoize filetree computation

* format

* var -> let
2023-09-20 16:09:18 -07:00
Jacky Zhao 16d33fb771
feat: display name for folders, expand explorer a little bit (#489)
* feat: display name for folders, expand explorer a little bit

* update docs
2023-09-20 16:08:54 -07:00
Ben Schlegel b029eeadab
feat(explorer): improve accessibility and consistency (+ bug fix) (#488)
* feat(consistency): use `all: unset` on button

* style: improve accessibility and consistency for explorer

* fix: localStorage bug with folder name changes

* chore: bump quartz version
2023-09-20 13:55:29 -07:00
Jacky Zhao 6a9e6352e8 Revert "feat: Making Quartz available offline by making it a PWA (#465)"
This reverts commit d6301fae90.
2023-09-20 13:52:45 -07:00
Jacky Zhao 70e029d151 Revert "docs: wording changes for offline support"
This reverts commit 52a172d1a4.
2023-09-20 13:52:29 -07:00
Jacky Zhao 0bad3ce799 docs: document enableToc 2023-09-20 11:58:52 -07:00
Jacky Zhao 52a172d1a4 docs: wording changes for offline support 2023-09-20 11:40:36 -07:00
Adam Brangenberg d6301fae90
feat: Making Quartz available offline by making it a PWA (#465)
* Adding PWA and chaching for offline aviability

* renamed workbox config to fit Quartz' scheme

* Documenting new configuration

* Added missig umami documentation

* Fixed formatting so the build passes, thank you prettier :)

* specified caching strategies to improve performance

* formatting...

* fixing "404 manifest.json not found" on subdirectories by adding a / to manifestpath

* turning it into a plugin

* Removed Workbox-cli and updated @types/node

* Added Serviceworkercode to offline.ts

* formatting

* Removing workbox from docs

* applied suggestions

* Removed path.join for sw path

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

* Removed path.join for manifest path

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

* Removing path module import

* Added absolute path to manifests start_url and manifest "import" using baseUrl

* Adding protocol to baseurl

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

* Adding protocol to start_url too then

* formatting...

* Adding fallback page

* Documenting offline plugin

* formatting...

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* merge suggestion

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

* formatting...

* Fixing manifest path, all these nits hiding the actual issues .-.

* Offline fallback page through plugins, most things taken from 404 Plugin

* adding Offline Plugin to config

* formatting...

* Turned offline off as default and removed offline.md

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2023-09-20 11:38:13 -07:00
rwutscher 27a6087dd5
fix: tag regex no longer includes purely numerical 'tags' (#485)
* fix: tag regex no longer includes purely numerical 'tags'

* fix: formatting

* fix: use guard in findAndReplace() instead of expanding the regex
2023-09-19 12:26:30 -07:00
Jacky Zhao 1bf7e3d8b3 fix(nit): make defaultOptions on explorer not a function 2023-09-19 10:22:39 -07:00
David Fischer cc31a40b0c
feat: support changes in system theme (#484)
* feat: support changes in system theme

* fix: run prettier

* fix: add content/.gitkeep
2023-09-19 09:25:51 -07:00
Ben Schlegel 0d3cf29226
docs: fix explorer example (#483) 2023-09-18 14:32:00 -07:00
Ben Schlegel 6a2e0b3ad3
fix: bad visibility for last explorer item (#478)
* fix: bad visibility for last explorer item

* feat(explorer): add pseudo element for observer
2023-09-17 22:04:44 +02:00
Ben Schlegel e67f409ec1
Merge pull request #479 from benschlegel/explorer-config
feat(explorer): add config for custom sort/map/filter functions
2023-09-17 21:36:04 +02:00
Ben Schlegel 4afb099bf3
docs: fix examples 2023-09-17 21:32:23 +02:00
Ben Schlegel 6914d4b40c
docs: fix intra page links 2023-09-17 21:20:09 +02:00
Christian Gill af41f34bfd
fix(slug): Handle question mark (#481) 2023-09-17 11:02:00 -07:00
Ben Schlegel 7ac772fca8
fix: darkmode scroll bars (#480) 2023-09-17 10:29:20 -07:00
Ben Schlegel 5cc9253c41
docs(explorer): write docs for new features 2023-09-17 16:41:23 +02:00
Ben Schlegel 94a04ab1c9
fix(explorer): filter function in `ExplorerNode` 2023-09-17 15:51:08 +02:00
Ben Schlegel 9358f73f1c
fix: display name for file nodes 2023-09-17 12:41:06 +02:00
Ben Schlegel f7029012df
feat: black magic
add config for `order` array, which determines the order in which all passed config functions for explorer will get executed in.

functions will now dynamically be called on `fileTree` via array accessor (e.g. fileTree["sort"].call(...)) with corresponding function from options being passed to call)
2023-09-16 21:58:38 +02:00
Ben Schlegel fea352849c
fix: create deep copy of file passed into tree 2023-09-16 19:45:21 +02:00
Ben Schlegel 3d8c470c0d
feat(explorer): implement `map` fn argument
Add a function for mapping over all FileNodes as an option for `Explorer`
2023-09-16 19:35:27 +02:00
Ben Schlegel 31d16fbd2c
feat(explorer): integrate filter option 2023-09-16 19:18:59 +02:00
Ben Schlegel 036a33f70b
fix: use correct import for `QuartzPluginData` 2023-09-16 17:47:44 +02:00
Ben Schlegel 58aea1cb07
feat: implement filter function for explorer 2023-09-16 17:28:58 +02:00
Ben Schlegel c7d3474ba8
feat(explorer): add config to support custom sort fn 2023-09-16 12:40:19 +02:00
Yuto Nagata 422ba5c365
fix: umami analytics date attribute (#477) 2023-09-15 19:17:20 -07:00
Jacky Zhao 9ae6343dd0 Revert "fix: use git dates by default, @napi/git is fast enough"
This reverts commit 5dcb7e83fc.
2023-09-15 10:33:38 -07:00
Jacky Zhao 5dcb7e83fc fix: use git dates by default, @napi/git is fast enough 2023-09-15 09:46:06 -07:00
Ben Schlegel 91f9ae2d71
feat: implement file explorer component (closes #201) (#452)
* feat: add basic explorer structure„

* feat: integrate new component/plugin

* feat: add basic explorer structure

* feat: add sort to FileNodes

* style: improve style for explorer

* refactor: remove unused explorer plugin

* refactor: clean explorer structure, fix base (toc)

* refactor: clean css, respect displayClass

* style: add styling to chevron

* refactor: clean up debug statements

* refactor: remove unused import

* fix: clicking folder icon sometimes turns invisible

* refactor: clean css

* feat(explorer): add config for title

* feat: add config for folder click behavior

* fix: `no-pointer` not being set for all elements

new approach, have one `no-pointer` class, that removes pointer events and one `clickable` class on the svg and button (everything that can normally be clicked). then, find all children with `clickable` and toggle `no-pointer`

* fix: bug where nested folders got incorrect height

this fixes the bug where nested folders weren't calculating their total height correctly. done by adding class to main container of all children and calculating total

* feat: introduce `folderDefaultState` config

* feat: store depth for explorer nodes

* feat: implement option for collapsed state + bug fixes

folderBehavior: "link" still has bad styling, but major bugs with pointers fixed (not clean yet, but working)

* fix: default folder icon rotation

* fix: hitbox problem with folder links, fix style

* fix: redirect url for nested folders

* fix: inconsistent behavior with 'collapseFolders' opt

* chore: add comments to `ExplorerNode`

* feat: save explorer state to local storage (not clean)

* feat: rework `getFolders()`, fix localstorage read + write

* feat: set folder state from localStorage

needs serious refactoring but functional (except folder icon orientation)

* fix: folder icon orientation after local storage

* feat: add config for `useSavedState`

* refactor: clean `explorer.inline.ts`

remove unused functions, comments, unused code, add types to EventHandler

* refactor: clean explorer

merge `isSvg` paths, remove console logs

* refactor: add documentation, remove unused funcs

* feat: rework folder collapse logic

use grids instead of jank scuffed solution with calculating total heights

* refactor: remove depth arg from insert

* feat: restore collapse functionality to clicks

allow folder icon + folder label to collapse folders again

* refactor: remove `pointer-event` jank

* feat: improve svg viewbox + remove unused props

* feat: use css selector to toggle icon

rework folder icon to work purely with css instead of JS manipulation

* refactor: remove unused cfg

* feat: move TOC to right sidebar

* refactor: clean css

* style: fix overflow + overflow margin

* fix: use `resolveRelative` to resolve file paths

* fix: `defaultFolderState` config option

* refactor: rename import, rename `folderLi` + ul

* fix: use `QuartzPluginData` type

* docs: add explorer documentation
2023-09-15 09:39:16 -07:00
Oskar Manhart 14cbbdb8a2
feat: display tag in graph view (#466)
* feat: tags in graph view

* fix: revert changing graph forces

* fix: run prettier
2023-09-13 20:55:59 -07:00
Jacky Zhao cce389c81d
feat: note transclusion (#475)
* basic transclude

* feat: note transclusion
2023-09-13 11:28:53 -07:00
Jacky Zhao 4461748a85 fix dont show html in search when rssFullHtml is true (closes #474) 2023-09-13 09:43:30 -07:00
Jacky Zhao 6ecdcb5e24 feat: resolve block references in obsidian markdown 2023-09-12 22:55:50 -07:00
Jacky Zhao e3b879741b feat: rich html rss (closes #460) 2023-09-12 21:44:03 -07:00
Jacky Zhao 60a3c54339 fix: 404 page styling for nested pages (closes #458) 2023-09-12 21:29:57 -07:00
Jacky Zhao 71d81bde1d feat: rss limit (closes #459) 2023-09-12 19:18:44 -07:00
hcplantern a19df64be8
fix: callout parsing (#469) 2023-09-11 23:00:21 -07:00
Oskar Manhart 4e23e67244
feat: plugin for remark-breaks (#467)
* feat: plugin for remark-breaks

* fix: update package-lock.json

* fix: styling

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

* Update linebreaks.ts

* Update index.ts

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2023-09-10 23:11:42 -07:00
Jacky Zhao a66c239797 ci: print bundleInfo 2023-09-10 23:07:17 -07:00
Jacky Zhao 53f1c88738 fix: more lenient date parsing for templates 2023-09-08 09:29:57 -07:00
Stefano Cecere 06df00b186
typo (it's draft, not drafts) (#456) 2023-09-07 08:13:41 -07:00
Jacky Zhao 2525bfbab5 fix: links to index not showing in graph (closes #450) 2023-09-06 22:24:15 -07:00
Jacky Zhao 828aa71fe3 fix: escape encoding for titles in rss 2023-09-06 21:47:59 -07:00
Jacky Zhao ef1ead31dc fix: encodeuri for slugs in rss 2023-09-06 21:31:01 -07:00
Jacky Zhao 989bee5979 docs: correct field for ignorePatterns 2023-09-06 21:08:08 -07:00
Jacky Zhao 8d6029b7b8 feat: 404 page emitter 2023-09-06 21:02:21 -07:00
Jacky Zhao 2d52eba413 fix: dont transform external links 2023-09-06 20:25:50 -07:00
Ben Schlegel 6ef4246cf1
docs: update `full-text-search.md` (#447) 2023-09-03 22:36:30 -07:00
Dr Kim Foale 616a7f148a
docs: Make it clearer that wikilinks go to paths not page titles (#448) 2023-09-03 21:29:58 -07:00
Adam Brangenberg e8a04efaf1
feat(analytics): Support for Umami (#449) 2023-09-03 21:28:57 -07:00
Ben Schlegel 7e42be8e46
feat(search): add arrow key navigation (#442)
* feat(search): add arrow navigation

* chore: format

* refactor: simplify arrow navigation

* chore: remove comment

* feat: rework arrow navigation to work without state

* feat: make pressing enter work with arrow navigation

* fix: remove unused css class

* chore: correct comment

* refactor(search): use optional chaining
2023-09-03 09:32:46 -07:00
Ben Schlegel 8c354f6261
fix: clipboard button visible in search (#445) 2023-09-03 09:06:05 -07:00
Jacky Zhao 505673acd7 feat: pluralize things in lists 2023-09-02 18:07:26 -07:00
Ben Schlegel 23f43045c4
fix(search): matches getting highlighted in title (#440) 2023-09-01 14:12:32 -07:00
Ben Schlegel 90dac31216
feat: Implement search for tags (#436)
* Quartz sync: Aug 29, 2023, 10:17 PM

* style: add basic style to tags in search

* feat: add SearchType + tags to search preview

* feat: support multiple matches

* style(search): add style to matching tags

* feat(search): add content to preview for tag search

* fix: only display tags on tag search

* feat: support basic + tag search

* refactor: extract common `fillDocument`, format

* feat: add hotkey to search for tags

* chore: remove logs

* fix: dont render empty `<ul>` if tags not present

* fix(search-tag): make case insensitive

* refactor: clean `hideSearch` and `showSearch`

* feat: trim content similar to `description.ts`

* fix(search-tag): hotkey for windows

* perf: re-use main index for tag search
2023-09-01 10:09:58 -07:00
Pelayo Arbués 2d6dc176c3
Adds Pelayo Arbues to showcase (#435) 2023-08-31 12:12:06 -07:00
Ben Schlegel b213ba45e2
fix: regex for matching highlights (closes #437) (#438)
* fix:  regex for matching highlights

* fix: regex for empty highlights
2023-08-31 11:55:04 -07:00
Jacky Zhao 5fa6fc9789 fix: aliasredirects not using full path, add permalink support 2023-08-29 10:37:00 -07:00
Jeffrey Fabian 1cc09ef76d
feat: support kebab-case and nested tags in Obsidian-flavored Markdown tag-in-content parsing (#425)
* enhancement: support kebab-case and nested tags in ofm transformer

* update regex/capture groups to allow for (arbitrarily) nested values and tags of only -/_

* Update quartz/plugins/transformers/ofm.ts

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2023-08-29 10:14:54 -07:00
Ben Schlegel c35cd422c6
fix: correct graph labels for `index.md` nodes (#431) 2023-08-28 10:00:49 -07:00
Jeremy Press 082fdf2e80
Fix typo :) (#430) 2023-08-27 20:57:19 -07:00
Jeremy Press b6b1dabde0
feat: support configurable ws port and remote development (#429)
Co-authored-by: Jeremy Press <jeremy@replit.com>
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2023-08-27 17:39:42 -07:00
Ben Schlegel 4b89202f7e
cleanup: rework cli to allow invoking create and build outside of cli (#428)
* refactor: move `bootstrap-cli.mjs` tp cli

also update reference in docs

* refactor(cli): move build handler to `cli-functions`

* refactor(cli): move create to handler + helpers

* refactor(cli): extract arg definitions

* refactor: rename handlers and helpers

* refactor(cli): move update, await handlers

* refactor(cli): create constants, migrate to helpers

* refactor(cli): migrate `restore`

* refactor(cli): migrate `sync`

* format

* refactor(cli): remove old imports/functions

* refactor(cli): remove unused imports + format

* chore: remove old log statement

* fix: fix imports, clean duplicate code

* fix: relative import

* fix: simplified cacheFile path

* fix: update cacheFile import path

* refactor: move bootstrap-cli to quartz

* format

* revert: revert path to bootstrap-cli

* ci: re-run

* ci: fix  execution permission
2023-08-27 15:59:51 -07:00
Jacky Zhao 52ca312f41 fix: slugify tag on page before adding (closes #411) 2023-08-27 12:27:55 -07:00
Ben Schlegel c91e62c376
Fix search bar after navigate (#424) 2023-08-26 17:19:45 -07:00
Ben Schlegel ad4145fb10
feat: support CLI arguments for `npx quartz create` (#421)
* feat(cli): add new args for content + link resolve

* feat(cli): validate cmd args

* feat(cli): add chalk + error code to errors

* feat(cli): support for setup/link via args

* refactor(cli): use yargs choices instead of manual

Scrap manual check if arguments are valid, use yargs "choices" field instead.

* feat(cli): add in-dir argument+ handle errors

add new "in-directory" argument, used if "setup" is "copy" or "symlink" to determine source. add error handling for invalid permutations of arguments or non existent path

* feat(cli): dynamically use cli or provided args

use "in-directory" arg as `originalFolder` if available, otherwise get it from manual cli process

* run format

* fix: use process.exit instead of return

* refactor: split CommonArgv and CreateArgv

* refactor(cli): rename create args, use ${} syntax

* fix(cli): fix link resolution strategy arg

* format

* feat(consistency): allow partial cmd args
2023-08-26 13:21:44 -07:00
Jacky Zhao 74c3ebb7bd style: fix mulitline callout styling 2023-08-26 10:48:34 -07:00
Jacky Zhao e3265f8416 docs: simplify oxhugo page 2023-08-26 10:42:55 -07:00
Hrishikesh Barman bc543f81d9
feat(plugins): add OxHugoFlavouredMarkdown (#419)
* feat(plugins): add OxHugoFlavouredMarkdown

ox-hugo is an org exporter backend that exports org files to
hugo-compatible markdown in an opinionated way. This plugin adds some
tweaks to the generated markdown to make it compatible with quartz but
the list of changes applied it is not extensive.

In the future however, we could leapfrog ox-hugo altogether and
create a quartz site directly out of org-roam files. That way we won't
have to do all the ritual dancing that this plugin has to perform.
See https://github.com/k2052/org-to-markdown

* fix: add toml to remarkFrontmatter configuration

* docs: add docs for OxHugoFlavouredMarkdown

* fixup! docs: add docs for OxHugoFlavouredMarkdown
2023-08-25 22:52:23 -07:00
Hrishikesh Barman 5c6d1e27ba
feat(plugins): add toml support for frontmatter (#418)
* feat(plugins): add toml support for frontmatter

Currently frontmatter is expected to be yaml, with delimiter set to
"---". This might not always be the case, for example ox-hugo(a hugo
exporter for org-mode files) exports in toml format with the delimiter
set to "+++" by default.

With this change, the users will be able use frontmatter plugin to
support this toml frontmatter format.

Example usage: `Plugin.FrontMatter({delims: "+++", language: 'toml'})`

- [0] https://ox-hugo.scripter.co/doc/org-meta-data-to-hugo-front-matter/

* fixup! feat(plugins): add toml support for frontmatter
2023-08-25 10:25:46 -07:00
Ben Schlegel 340e3ef511
feat(consistency): Add `.obsidian` to ignorePatterns (#420) 2023-08-25 09:03:49 -07:00
Jacky Zhao 953ef29f4e format, ensure ci runs on prs 2023-08-24 12:31:15 -07:00
Ben Schlegel 94ce0883e7
style: integrate tertiary color to text-select (#413) 2023-08-24 12:28:06 -07:00
Zero King 8cf7280614
feat: reproducible build (#412)
for sitemap, RSS and contentIndex.json.
2023-08-24 11:41:20 -07:00
Jacky Zhao c8412a5b0a format 2023-08-24 10:03:14 -07:00
Jacky Zhao fc4b8f3d3f fix: ensure recentnotes uses proper date 2023-08-24 09:38:00 -07:00
Jacky Zhao 6cd0612d40 fix: add better warning when defaultDateType is not set due to upgrade 2023-08-24 09:17:43 -07:00
Jacky Zhao 9851697b58 version bump to 4.0.10 2023-08-24 09:05:19 -07:00
Jacky Zhao c36a9f3fb7 feat: add defaultDateType config 2023-08-24 08:56:40 -07:00
Jacky Zhao 98d82415dc fix: lock to never read when site is building 2023-08-24 08:31:12 -07:00
Ben Schlegel 9d2340e90b
docs: fix typo in `authoring content.md` (#408) 2023-08-24 08:14:52 -07:00
bfahrenfort 8200c8d040
Revert contentIndex to RSS 2.0 (#407) 2023-08-23 22:57:49 -07:00
Jacky Zhao 2e0e518f5d format 2023-08-23 15:16:04 -07:00
Zane Helton 632c27b7ec
docs: update `hosting.md` with Vercel hosting instructions (#406)
* Update hosting.md with Vercel hosting instructions

* Update docs/hosting.md

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

* Update docs/hosting.md

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

* Run npm run format

---------

Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2023-08-23 15:14:23 -07:00
Jacky Zhao bfb416b35a fix: text wrap in popover 2023-08-23 13:10:23 -07:00
Jacky Zhao 960c1814d0 docs: make incompability of trailing slashes clear 2023-08-23 12:23:49 -07:00
Jacky Zhao eed4472aee fix: use proper full base for links.ts 2023-08-23 12:18:50 -07:00
Jacky Zhao b99eb7ebce docs: whitespace 2023-08-23 12:11:24 -07:00
kanpov 0aaf88b852
Fix #403 by moving documentation to separate directory to avoid merge conflicts (#405) 2023-08-23 12:09:04 -07:00
Jacky Zhao a1a1e7e1e0 fix: builds should no accumulate on repeated changes (closes #404) 2023-08-23 11:36:34 -07:00
Jacky Zhao 3209f7c3b7 deps: native addons for lightningcss 2023-08-23 09:19:00 -07:00
Jacky Zhao cde1e26129 deps: install exact 2023-08-23 09:16:44 -07:00
Jacky Zhao 1128efcf23 deps: esbuild and esbuild-sass-plugin 2023-08-23 09:10:30 -07:00
Aaron Pham d2f5254995
fix(esbuild): conflict with esbuild-sass-plugin (#402) 2023-08-23 09:05:01 -07:00
Jacky Zhao 3064839c2d version bump to 4.0.9 2023-08-22 23:37:02 -07:00
Jacky Zhao b444c5c13b fix: percent-encoding for files with %, contentIndex for non-latin chars (closes #397, closes #399) 2023-08-22 23:34:28 -07:00
Jacky Zhao 36548d5986 fix: toc for cyrillic and other non-latin alphabets (closes #396) 2023-08-22 22:41:50 -07:00
Jacky Zhao 99dbe525d9 fix: properly lock across source and content refresh by sharing a mutex 2023-08-22 22:27:41 -07:00
Jacky Zhao 8b63ff882a fix: tag support for non-latin alphabets (fixes #398) 2023-08-22 22:14:16 -07:00
Jacky Zhao b991cf2ee8 fix: spa hijacks back button (closes #400) 2023-08-22 21:30:31 -07:00
松浦 知也 Matsuura Tomoya bb677840fc
fixed broken CJK links (#390) 2023-08-22 09:16:55 -07:00
Ikko Eltociear Ashimine c60b3d5e34
fix: typo in bootstrap-cli.mjs (#394) 2023-08-22 09:16:21 -07:00
Jacky Zhao e10de3febf fix: server-handler crash from filename (closes #386) 2023-08-21 17:01:18 -07:00
Jacky Zhao b69556c918 fix: async-mutex not exclusively locking correectly 2023-08-21 16:43:32 -07:00
Jacky Zhao ce70571072 docs: use canonical quartz.jzhao.xyz, update bootstrap script to point to correct hosting link 2023-08-21 09:15:01 -07:00
Jacky Zhao 8c943f47d6 format, update default sidepanel width 2023-08-21 09:00:13 -07:00
松浦 知也 Matsuura Tomoya 2774e976d2
fix: opts being overriden in graph option (#384) 2023-08-21 08:45:47 -07:00
Jacky Zhao bb93ac1c83 docs: fix links to networked thought 2023-08-20 23:50:29 -07:00
Jacky Zhao 777ff51c7a format 2023-08-20 20:48:35 -07:00
Jacky Zhao 4e42d52e16 fix: ctrl + k breaking after page nav 2023-08-20 20:47:07 -07:00
Jacky Zhao d0f67d9935 move wss server start after http 2023-08-20 18:41:37 -07:00
Jacky Zhao 952d6cb3dd fix: nav event with spa off, anchor nav refresh page 2023-08-20 18:08:44 -07:00
Jacky Zhao 173ec240d2 fix: jump to anchor on deployed site triggering spa refresh 2023-08-20 17:50:56 -07:00
Jacky Zhao 425c9789a4 remove checkout step from instructions as v4 is the default branch 2023-08-20 16:59:25 -07:00
Jacky Zhao 7b7064ad2b fix: ensure code exists inside pre before adding clipboard 2023-08-20 15:38:37 -07:00
Jacky Zhao ca17af4ae2 fix: dont show index page for folder in its own listing 2023-08-20 15:02:24 -07:00
Jacky Zhao 71471117c5 fix: ci runs on v4 2023-08-20 14:34:00 -07:00
Jacky Zhao e65ea48fae fix: add async-mutex to builds on large vaults 2023-08-20 14:27:44 -07:00
Jacky Zhao b99d4cd8ce recent notes css fixes 2023-08-20 14:05:37 -07:00
Jacky Zhao 1bb00e72bb add docs for recent notes 2023-08-20 13:00:33 -07:00
Jacky Zhao 236130ac22 css fixes, add recent notes, more robust quartz update 2023-08-20 12:46:37 -07:00
Jacky Zhao 5adf3c67a8 add engines field 2023-08-20 08:57:56 -07:00
Jacky Zhao 9d77edaf94 fix description not being used in folder and tag listings 2023-08-20 01:08:18 -07:00
Jacky Zhao 0ef1b5b522 update plausible url 2023-08-20 00:54:13 -07:00
Jacky Zhao cfb7d1232e docs: update notes for tag and folder listings 2023-08-20 00:52:49 -07:00
Jacky Zhao 03fd62496f docs: note about updating default branch 2023-08-20 00:02:41 -07:00
Jacky Zhao d205eb5686 docs: make setting upstream more clear, docs on npx quartz restore 2023-08-19 22:19:49 -07:00
Jacky Zhao 96a3bfeafb fix: put quotations around font 2023-08-19 22:04:29 -07:00
Jacky Zhao 95fb6ccfcb readme fix 2023-08-19 21:59:20 -07:00
Jacky Zhao e262482921 fix: string for aliases being treated as array of chars 2023-08-19 21:59:01 -07:00
Jacky Zhao eb4d3dc5b4 css: fix scrollbars on windows 2023-08-19 21:55:09 -07:00
Jacky Zhao 90d6c1ed24 add git fetch to migration instructions 2023-08-19 21:38:10 -07:00
Jacky Zhao 443c182890 Merge branch 'v4' of https://github.com/jackyzha0/quartz into v4 2023-08-19 21:16:31 -07:00
Jacky Zhao 791b8e2d9f add sponsors 2023-08-19 21:16:24 -07:00
Matt Dunn a6236d97cf
Adding to Showcase page (#367) 2023-08-19 19:15:14 -07:00
Jacky Zhao b1debaebff update docs 2023-08-19 18:56:45 -07:00
Jacky Zhao 7b8017413c impl baseDir option for quartz build --serve for local testing 2023-08-19 18:04:17 -07:00
Jacky Zhao 6681f28af0 fix trailing slash causing folder listing to not fetch content correctly 2023-08-19 16:55:36 -07:00
Jacky Zhao 78f4cdbe10 avoid 404 on icon for spa navigations with anchors 2023-08-19 16:40:02 -07:00
Jacky Zhao dd47be1bc6 improve path resolution stability 2023-08-19 16:28:44 -07:00
Jacky Zhao c874e7e937 base path refactor to better support subpath hosting 2023-08-19 15:52:25 -07:00
Jacky Zhao 3201f83b70 v4-alpha -> v4 2023-08-18 18:24:09 -07:00
Jacky Zhao d8bec631b6 update docs on github pages and syncing 2023-08-18 18:22:38 -07:00
Jacky Zhao 6f1f820289 fix typo in docs 2023-08-17 23:39:15 -07:00
Jacky Zhao 8bc7a50dfa format 2023-08-17 21:54:42 -07:00
Jacky Zhao 569beb410b ensure sync includes untracked files 2023-08-17 21:49:58 -07:00
Jacky Zhao 5713d30670 ensure contentfolder is passed to popContentFolder 2023-08-17 21:24:41 -07:00
Jacky Zhao a130945443 fix when symlink targ is calculated and added npx quartz restore 2023-08-17 21:20:15 -07:00
Jacky Zhao e10f6da011 format 2023-08-17 21:08:26 -07:00
Jacky Zhao a7cca3242a deref symlink on quartz sync 2023-08-17 21:07:40 -07:00
Jacky Zhao 0998bc355e fix rebuild debouncing 2023-08-17 01:58:11 -07:00
Jacky Zhao 07a327e05a fix back button in spa not working between two pages that both have hash fragments 2023-08-17 01:34:50 -07:00
Jacky Zhao 58d9dc0528 format 2023-08-17 00:55:52 -07:00
Jacky Zhao 0c199975f2 various path fixes for links to extensions, fix relative paths in links 2023-08-17 00:55:28 -07:00
Jacky Zhao 2dc0ae279c fix import paths 2023-08-16 22:09:11 -07:00
Jacky Zhao 2f6747b166 fix relative path resolution in router and link crawling 2023-08-16 22:04:15 -07:00
Sohaib 232652149a
Update hosting.md (#371) 2023-08-14 17:59:47 -07:00
Jacky Zhao 7bde99b4e2 fix: add trailing slash to local serving 2023-08-13 17:47:18 -07:00
vintro f1c9ca495e
docs: note about existing content at same path on different branches 2023-08-13 17:19:50 -07:00
Jacky Zhao 4f4b04eeb4 format docs 2023-08-12 21:18:51 -07:00
Jacky Zhao d6e73f221c fix relative path resolution logic, add more path tests 2023-08-12 21:16:43 -07:00
Jacky Zhao 6d9ffd6da5 404 page styling on local 2023-08-12 21:16:43 -07:00
Jacky Zhao c89f8b1a9a fix nested callout folding 2023-08-12 21:16:43 -07:00
Sohaib 8fd496bbef
Update hosting.md (#368) 2023-08-12 13:52:16 -07:00
Jacky Zhao aed3f5fccb fmt 2023-08-12 10:17:07 -07:00
Jacky Zhao c55d54f068 enable rich text in callout title 2023-08-12 10:16:55 -07:00
Jacky Zhao 7bffc2183e include home page in search 2023-08-12 00:24:30 -07:00
Jacky Zhao 827dd91847 format, make search async 2023-08-12 00:03:11 -07:00
Jacky Zhao e1dd6aee86 fix wikilinks to anchors in the same document 2023-08-11 23:55:17 -07:00
Jacky Zhao 83269ac26e fix scanning for tags in content 2023-08-11 23:40:06 -07:00
Jacky Zhao ed62ece491 fix broken tag listing links to tags 2023-08-11 23:27:59 -07:00
Jacky Zhao 736c3981c4 fix emit filepaths, tag emit being overriden by content 2023-08-11 23:25:44 -07:00
Jacky Zhao 79e828696a feature docs 2023-08-11 22:47:50 -07:00
Jacky Zhao 259d0a6d9a more documentation 2023-08-11 00:31:44 -07:00
Jacky Zhao df02ea20d7 spacing fix 2023-08-10 21:32:11 -07:00
Jacky Zhao 21cc6a5da9 run prettier 2023-08-10 21:29:11 -07:00
Jacky Zhao cefbca4753 docs on making plugins 2023-08-10 21:16:07 -07:00
Jacky Zhao ad3f7b2d5f format 2023-08-09 09:18:44 -07:00
Jacky Zhao ebf3263b7e update npx quartz update script 2023-08-09 09:10:40 -07:00
Jacky Zhao cea6834fef profiling, better concurrency heuristics 2023-08-09 00:26:33 -07:00
Jacky Zhao 68ccd1d79d format 2023-08-08 22:53:01 -07:00
Jacky Zhao 49bd6bc3ff better concurrency debugging, --concurrency flag for npx quartz build 2023-08-08 22:52:49 -07:00
Jacky Zhao e4950e06a1 fix getFileExtension missing numeric extensions (e.g. mp4) 2023-08-08 21:31:36 -07:00
Jacky Zhao e21f0f9bb9 change reading time to content meta 2023-08-08 21:28:09 -07:00
Jacky Zhao ee9ed4f287 fix head.tsx 2023-08-08 20:36:24 -07:00
Jacky Zhao 2706a137a0 guide to creating components 2023-08-08 20:18:31 -07:00
Jacky Zhao 09d4eb0684 fix notes 2023-08-07 23:57:24 -07:00
Jacky Zhao 533d68e642 most of creating components, increase legibility of bold in article and callouts 2023-08-07 23:56:50 -07:00
Jacky Zhao 774a162850 format 2023-08-07 21:51:23 -07:00
Jacky Zhao 2ac5dd49da fix regression in code block font-size boosting on safari mobile 2023-08-07 21:51:06 -07:00
Jacky Zhao 527ce6546e various css fixes, fix new image loading bug when previewing, path docs 2023-08-07 21:41:18 -07:00
Jacky Zhao d02af6a8ae architecture, fix vendor prefixing 2023-08-07 17:34:38 -07:00
Jacky Zhao b4cacd5956 format 2023-08-06 22:07:33 -07:00
Jacky Zhao cd9dc6ecb5 fix css transforms for mobile 2023-08-06 22:07:08 -07:00
Jacky Zhao d8d9dd22c9 fix shortest path for non-md files, mobile fix 2023-08-06 20:52:17 -07:00
Jacky Zhao 075ac33474 note formatting 2023-08-06 19:54:11 -07:00
Jacky Zhao 3adc73a703 docs upgrade, ci changes 2023-08-06 19:52:30 -07:00
Jacky Zhao 028bcec62c mobile fixes, fix bug when linking to anchor on home, docs 2023-08-06 17:09:29 -07:00
Jacky Zhao db6054a8c1 format, remove markdown from being procesed 2023-08-05 18:00:52 -07:00
Jacky Zhao a0d651d64d reverse query param hack to re-add sourcemap support 2023-08-05 17:53:29 -07:00
Jacky Zhao 1da467d214 non-admonition callout fix 2023-08-05 16:43:50 -07:00
Jacky Zhao 7c09627df4 improve hot reload robustness 2023-08-05 15:34:10 -07:00
Jacky Zhao c402f0c385 more robust error handling, config hotreload 2023-08-05 11:28:09 -07:00
Jacky Zhao 9e76b257d4 fix mermaid initialization 2023-08-04 22:35:21 -07:00
Jacky Zhao 21a7ec2307 bump mathjax version 2023-08-03 23:36:00 -07:00
Jacky Zhao 6423f85614 fix execsync 2023-08-03 23:28:34 -07:00
Jacky Zhao 3a2eae0a16 fix fetch flags 2023-08-03 23:24:34 -07:00
Jacky Zhao 2acfb9e870 format, add upstream 2023-08-03 23:08:04 -07:00
Jacky Zhao 93986c6e7c update pull strategy 2023-08-03 22:29:46 -07:00
Jacky Zhao 4877a9c934 fix callout aliases not being used properly 2023-08-03 00:08:13 -07:00
Jacky Zhao 6457496b4b readme fixes, force 2023-08-02 23:42:49 -07:00
Jacky Zhao fdf1e2a41d use checkout for pulling updates 2023-08-02 23:29:28 -07:00
Jacky Zhao 663c41fa41 use posix style paths for all path ops 2023-08-02 23:04:26 -07:00
Jacky Zhao de72dd4e4a format 2023-08-02 22:16:46 -07:00
Jacky Zhao 5537ca41e0 use autostash and pull 2023-08-02 22:16:32 -07:00
Jacky Zhao 558a509164 format 2023-08-02 22:11:46 -07:00
Jacky Zhao d7842e0ce7 make path and globbing more platform invariant 2023-08-02 22:10:13 -07:00
Jacky Zhao 264ea3d544 add gitattributes for windows 2023-08-02 20:59:56 -07:00
Jacky Zhao 0a33ff7a82 fix test matrix for ci 2023-08-02 20:56:31 -07:00
Jacky Zhao 429f331c21 make ci also run on windows, re-add css minification 2023-08-02 20:53:13 -07:00
Jacky Zhao 9a0f20012a windows patches 2023-08-02 00:07:41 -07:00
Jacky Zhao c8c108c7f7 change default strategy to be rebase 2023-08-01 23:29:58 -07:00
Jacky Zhao aaae7d46c2 Merge branch 'v4-alpha' of https://github.com/jackyzha0/quartz into v4-alpha 2023-08-01 22:48:32 -07:00
Jacky Zhao a70e846b0a flag to allow ofm replace in html embed 2023-08-01 22:47:16 -07:00
Adam Brangenberg cbae88fc4e
Removing redundant properties (#356) 2023-07-30 21:08:32 -07:00
Jacky Zhao cc79502670 make layouts simpler to think about 2023-07-25 23:37:24 -07:00
Jacky Zhao 45f9087f03 fix checkbox/tasklist styling 2023-07-25 22:27:59 -07:00
Jacky Zhao 1c1a569023 fix formatting 2023-07-25 21:11:06 -07:00
Jacky Zhao cee2883c08 nested tag support and tag index page 2023-07-25 21:10:37 -07:00
Jacky Zhao c0278a8c65 font loading options, optimize css 2023-07-24 21:54:47 -07:00
Jacky Zhao e82ba97a39 actually add processed tag to frontmatter 2023-07-24 00:07:58 -07:00
Jacky Zhao 041a4ce7bc fix watch-mode batching 2023-07-24 00:04:01 -07:00
Jacky Zhao 569ff1a801 npm i on quartz update 2023-07-23 21:53:34 -07:00
Jacky Zhao 351b4ab13b styling fixes for stacking order and overflow 2023-07-23 21:41:09 -07:00
Jacky Zhao 4811500b1b make component resources a proper emitter 2023-07-23 18:20:43 -07:00
Jacky Zhao 236ba56be1 version bump, update doc 2023-07-23 17:59:44 -07:00
Jacky Zhao 7c2bb4ee4c bundleinfo flag, minify scripts 2023-07-23 17:58:35 -07:00
Jacky Zhao 8fd75ffbfd support attachments folder 2023-07-23 17:42:00 -07:00
Jacky Zhao 55a1fb8c41 format 2023-07-23 17:09:12 -07:00
Jacky Zhao 9e83af04a7 refactor static and asset emission to be actual emitter plugins 2023-07-23 17:07:19 -07:00
Jacky Zhao 000eb4c3c0 update feature list 2023-07-23 15:37:06 -07:00
Jacky Zhao 5599eb590e feat: process tags in content 2023-07-23 14:02:57 -07:00
Jacky Zhao ae2e3b463a improve error handling while serving 2023-07-23 11:49:26 -07:00
Jacky Zhao fd7c33c537 style fixes for search bar and title on mobile 2023-07-23 11:19:15 -07:00
Jacky Zhao 76fdb3b4d8 fix styles 2023-07-23 11:04:20 -07:00
Jacky Zhao 27a5f7ef8e various typography and styling fixes 2023-07-23 11:02:45 -07:00
Jacky Zhao ab228748ab oops actually use npm run check 2023-07-22 17:42:13 -07:00
Jacky Zhao 76fa9bbe00 run prettier on ci 2023-07-22 17:39:10 -07:00
Jacky Zhao 7db2eda76c run prettier 2023-07-22 17:27:41 -07:00
Jacky Zhao 2034b970b6 configure prettier 2023-07-22 17:26:03 -07:00
Jacky Zhao 8dd73704e6 hot content reload 2023-07-22 16:06:36 -07:00
Jacky Zhao b7966ff7fa update features list 2023-07-20 21:51:55 -07:00
Jacky Zhao 01d7d8e554 fix tag pages to emit to tag/index.html to override content and folder pages 2023-07-19 23:03:59 -07:00
Jacky Zhao 83d47f7aaa rename github action 2023-07-19 22:00:44 -07:00
Jacky Zhao 76c092dcf2 add custom.scss 2023-07-19 21:59:48 -07:00
Jacky Zhao 410fc9c8d3 quartz update and quartz sync 2023-07-19 21:59:39 -07:00
Jacky Zhao 8e0ba45789 add link resolution prompt to quartz create 2023-07-16 10:39:35 -07:00
Jacky Zhao f82282367e treat _index as index 2023-07-15 23:33:06 -07:00
Jacky Zhao a3e4c86a4c fix ci, disable strict path type checks by default 2023-07-15 23:05:17 -07:00
Jacky Zhao 3ac6b42e16 finish path refactoring, add sourcemap + better trace support 2023-07-15 23:02:12 -07:00
Jacky Zhao 906f91f8ee base path refactor, more docs 2023-07-13 00:19:35 -07:00
Jacky Zhao 08f8e3b4a4 docs + various polish 2023-07-09 19:32:24 -07:00
Jacky Zhao b90590b9f4 polish 2023-07-08 14:36:02 -07:00
Jacky Zhao b3480bdc49 fix styling for bullet points 2023-07-06 19:18:18 -07:00
Jacky Zhao 9cbacca2d4 handle dates as tags 2023-07-06 18:45:38 -07:00
Jacky Zhao 05d1ca01c3 handle string tags 2023-07-06 18:32:48 -07:00
Jacky Zhao f7bf4038dc fix path parsing 2023-07-06 16:56:30 -07:00
Jacky Zhao 465804a389 basic docs, remove publish, add quartz create 2023-07-05 00:16:06 -07:00
Jacky Zhao 92ca787092 fix default callout state 2023-07-04 18:26:11 -07:00
Jacky Zhao fe2852ff25 update package 2023-07-04 18:08:36 -07:00
Jacky Zhao 974b0da308 folder and tag descriptions, re-enable relative pathing 2023-07-04 18:02:59 -07:00
Jacky Zhao 2a17431460 fix popover zindex 2023-07-04 17:14:15 -07:00
Jacky Zhao 38cff2d670 more visual polish, adjust colours and spacing 2023-07-04 16:48:36 -07:00
Jacky Zhao ab9da02c60 fix indexing causing main thread freeze, various polish 2023-07-04 10:08:32 -07:00
Jacky Zhao e0ebee5aa9 various polish 2023-07-02 13:08:29 -07:00
Jacky Zhao 4c904d88ab rss + sitemap 2023-07-01 13:35:27 -07:00
Jacky Zhao ba9f243728 tag and folder pages 2023-07-01 00:03:01 -07:00
Jacky Zhao 24348b24a9 fix: parsing wikilinks that have codeblock anchors, scroll to anchor 2023-06-19 22:50:25 -07:00
Jacky Zhao fd5c8d17d3 basic search implementation 2023-06-19 20:37:45 -07:00
Jacky Zhao c4cf0dcb02 local and global graph 2023-06-18 10:47:07 -07:00
Jacky Zhao 8bfee04c8c popovers 2023-06-17 16:05:46 -07:00
Jacky Zhao cb89cce183 basic left,right layout 2023-06-17 14:36:06 -07:00
Jacky Zhao b587782450 collapsible callout 2023-06-17 13:08:06 -07:00
Jacky Zhao 6d5491fdcb collapsible toc 2023-06-17 12:07:40 -07:00
Jacky Zhao 917d5791ac modern toc tweaks 2023-06-16 19:41:59 -07:00
Jacky Zhao 9d2024b11c taglist, mermaid 2023-06-12 22:41:42 -07:00
Jacky Zhao 2bfe90b7e6 add config to components 2023-06-11 23:46:38 -07:00
Jacky Zhao 352075ae81 refactor plugins to be functions instead of classes 2023-06-11 23:26:43 -07:00
Jacky Zhao b8c011410d toc 2023-06-09 23:06:02 -07:00
Jacky Zhao 3a29f4c86e add custom spa solution 2023-06-09 19:58:58 -07:00
Jacky Zhao 59109a8c1d add flamethrower router 2023-06-07 22:38:45 -07:00
Jacky Zhao 317cce9314 generic quartz component for layout 2023-06-07 22:27:32 -07:00
Jacky Zhao dde36fa558 update gh actions 2023-06-07 10:52:53 -07:00
Jacky Zhao 1cb4dadf13 codeblock copy 2023-06-06 21:19:00 -07:00
Jacky Zhao 0813f127a3 fix darkmode script load 2023-06-06 20:58:26 -07:00
Jacky Zhao 4d3579ca98 darkmode scripts 2023-06-06 19:48:37 -07:00
Jacky Zhao 89e0311a98 embeds 2023-06-06 00:00:38 -07:00
Jacky Zhao 700036e84c callouts 2023-06-05 22:14:17 -07:00
Jacky Zhao 1406ee0f05 update spinners 2023-06-04 13:37:43 -04:00
Jacky Zhao 9ad89997a5 multi-core builds 2023-06-04 12:35:45 -04:00
Jacky Zhao 4bdc17d4a1 inline scripts 2023-06-03 15:07:19 -04:00
Jacky Zhao fcd81353f8 heading linking 2023-06-01 19:48:38 -04:00
Jacky Zhao 04eeb2d10c syntax higlighting 2023-06-01 19:05:14 -04:00
Jacky Zhao 42d3a7de17 scss support 2023-06-01 17:35:31 -04:00
Jacky Zhao c1c46ad67e obsidian flavored markdown support 2023-06-01 12:33:20 -04:00
Jacky Zhao 3636c052eb link processing 2023-05-31 17:41:44 -04:00
Jacky Zhao 21c007e2fc rendering, link resolution, asset copying 2023-05-31 17:01:23 -04:00
Jacky Zhao ad6ce0d73f plugin integration round 2 2023-05-30 08:02:20 -07:00
Jacky Zhao a757521313 base setup 2023-05-28 17:44:08 -07:00
BSD-Yassin 7b1da7a845
i18n: Update fr.toml (#313) 2023-04-27 11:12:56 -07:00
Jacky Zhao e482fa1097 fix: graph and tooltip sometimes not showing 2023-04-06 15:06:01 -07:00
Mattia Ippoliti ba7a968881
fix: padding for empty title callouts (#308) 2023-04-01 13:50:08 -07:00
Md Jawad Noor Asif db27557aa3
fix: search highlight not showing because for trailing slash (#306) 2023-03-30 07:14:06 -04:00
Mike Walton b7c305e002
adding myself to the showcase (#301) 2023-03-23 00:56:20 -05:00
Daniel Lazaro 74fe4d6813
docs: Update link to callouts documentation (#300) 2023-03-18 09:20:56 -07:00
Jacky Zhao d6c31595b3 deps: bump hugo-obsidian 2023-03-16 10:33:01 -07:00
Jacky Zhao aa5ab03d4a docs: update to account for github changes 2023-03-02 09:14:29 -08:00
Jacky Zhao ecba6071b8 deps: bump hugo-obsidian 2023-02-25 13:04:15 -08:00
Jacky Zhao 983efab94c fix: recent notes partial sorting 2023-02-12 16:46:11 -08:00
Dev Uni 10e41743e5
fix: Bad UI due to head.html (#284) 2023-02-07 08:38:20 -08:00
Simon Späti bde44fadf2
feat: Adding Twitter and Social image preview including description (#207) 2023-02-07 00:16:15 -08:00
Jacky Zhao 6885651f7b feat: max-width for large screens 2023-02-06 12:58:34 -08:00
Jacky Zhao 7df2bb6f5e fix: fix duplicate link click tracking 2023-02-05 12:01:49 -08:00
Jacky Zhao 11959de11c feat: add more plausible events 2023-02-05 11:34:39 -08:00
Jacky Zhao a73aca8ed9 feat: switch from GA to Plausible for analytics 2023-02-05 10:39:58 -08:00
Adam Brangenberg 93610e232b
feat: Remove leading slash of folders in graph view (#282) 2023-02-01 12:34:18 -08:00
Jacky Zhao 712dab5c8c docs: remove broken links from showcase 2023-01-31 11:00:28 -08:00
Olivér Falvai 77b3907b23
docs: Clarify Obsidian settings (#280) 2023-01-31 10:48:20 -08:00
herrwinfried 8fc63586c4
feat: Added Turkish translation (#275) 2023-01-29 12:14:11 -08:00
Apoorv Khandelwal 24c9777a52
feat: Embedding multimodal assets (#274) 2023-01-21 10:01:05 -08:00
Quadrubo 7a8811a184
added the liveReloadPort as an option for docker (#272) 2023-01-18 08:25:01 -08:00
chaosarium eb2f6aeca8
Fix callout behaviour inconsistent with Obsidian (closes #168) (#268) 2023-01-09 14:14:11 -08:00
Md Jawad Noor Asif b78008532f
feat: Added Bangla translations (#266) 2023-01-09 14:12:52 -08:00
Md Jawad Noor Asif c5b103c85f
fix: fix unicode broken tags (#261) 2023-01-03 22:10:25 -05:00
Adam Brangenberg 614a6222a1
refactor: General performance/style improvements (#262) 2022-12-29 10:43:41 -05:00
chaosarium dc43737896
fix edge cases link processing (#258)
Fixes https://github.com/jackyzha0/quartz/issues/176
2022-12-24 12:10:59 -05:00
toof ea37486309
fix: fix misspelling (#259) 2022-12-24 10:38:49 -05:00
chaosarium c1b0eafce6
feat: Added simplified Chinese translations (#257) 2022-12-22 10:34:21 -08:00
Jacky Zhao ce5df837f5 feat: latex in search results 2022-12-03 21:03:12 -08:00
Jacky Zhao 4cd6f7efdf fix: text highlighting 2022-11-30 18:00:12 -08:00
Apoorv Khandelwal 5a7936e23a
fix: Replacing "internal-link broken" with link to asset (#232) 2022-11-30 17:41:05 -08:00
Jon Erling Hustadnes 5fd707714f
feat: Added Norwegian localization (#242) 2022-11-27 10:55:43 -08:00
Filippo Andrea Sighinolfi 717a13a580
feat: Added italian localization in i18n/it.toml (#239) 2022-11-27 10:55:13 -08:00
Brendan Ang 5f3d430699
feat: add support for mermaid diagrams (#244) 2022-11-27 10:53:52 -08:00
Jacky Zhao 66f3e249fe fix: only run docker publish on main repository 2022-11-23 08:34:19 -08:00
Jacky Zhao e374e3abd4 fix: jump to search for operand 2022-11-21 23:36:27 -08:00
SafEight f08a76a738
fix: External links ending in .md don't get trimmed (#236)
Co-authored-by: SAF <saf@saf.saf>
fixes https://github.com/jackyzha0/quartz/issues/229
2022-11-21 13:05:46 -08:00
Morgan Gallant d80f6946c8
fix: Semantic Search: Use Operand Beta API (#235) 2022-11-21 08:54:45 -08:00
Jacky Zhao 120d104230 update config for search 2022-11-20 15:14:48 -08:00
Jacky Zhao e9aa6ae9e7 feat: docker docs, semantic search alpha 2022-11-20 15:09:58 -08:00
Apoorv Khandelwal c12af32a5a
feat: Dockerfile and automated container build (#230) 2022-11-20 14:03:53 -08:00
SafEight de2b6b9a1b
feat: Replace == with <mark> (#234)
Co-authored-by: SAF <saf@saf.saf>
2022-11-19 13:17:55 -08:00
Jacky Zhao 7f9f58860d feat: allow enableToc to override default no TOC on a per-page basis 2022-11-19 11:18:57 -08:00
jet457 151b9851d6
docs: add Abhijeet's math-wiki to the showcase (#228) 2022-11-19 11:10:41 -08:00
saucecoat d56a58044d
Added German translation (#223) 2022-10-29 23:08:44 -07:00
Conor 689201bfbd
feat: Add French translation (#221) 2022-10-26 09:12:35 -07:00
Jacky Zhao 9b72edcd9c Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-10-25 13:14:13 -07:00
Jacky Zhao 8704edcca2 deps: bump ubuntu version (closes #218) 2022-10-25 13:14:06 -07:00
Evan Cater 0a602eda1b
fix euler's identity (#220) 2022-10-24 09:13:35 -07:00
Javier Zaleta Martínez 72571a7588
feat: Add Spanish translation (#217) 2022-10-18 17:25:55 -07:00
Charles Chamberlain 3409a49f15
fix: Apply monospace style to all meta in a popover (#216) 2022-10-16 09:43:43 -07:00
Pavol Komlos 666ffebe90
Decode the heading id from split link (#214) 2022-10-12 08:21:28 -07:00
Seth 8ea1525df4
Add SethMB Work (#203) 2022-10-03 11:45:54 -07:00
Jacky Zhao dd11d56dd9 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-09-23 10:17:34 -07:00
Jacky Zhao cd7e2088d5 feat: hide TOC when no headers (closes #204) 2022-09-23 10:17:28 -07:00
Simon Späti 169ef442b9
Adding reference projects (#196)
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2022-09-14 10:05:51 -07:00
DongDong Chen 8e3042df49
add my showcase : oldwinterの数字花园 (#192) 2022-09-14 10:05:20 -07:00
Jacky Zhao 2145e92b00 fix: make latex rendering size more simialr to obsidian 2022-09-12 11:08:07 -07:00
Jacky Zhao e6c7a4e1e2 fix: latex rendering bugs + patch for #195 2022-09-11 18:03:55 -07:00
Nikola Georgiev ca84da5b31
feat: Hide full path to file in Wikilinks by default (#195) 2022-09-11 17:05:14 -07:00
Jacky Zhao 0d1670adba Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-08-29 14:23:19 -04:00
Jacky Zhao 5c770f965a Update Quartz version in documentation 2022-08-29 14:23:04 -04:00
Andrii Yefremov ce55eca73b
Add Ukrainian translation (#191) 2022-08-29 14:15:18 -04:00
Jacky Zhao 591c4813ec deps: bump hugo-obsidian version 2022-08-28 01:09:52 -04:00
Jacky Zhao 83e7aec3c9 fix: tag list styling 2022-08-24 00:45:08 -04:00
Youssif Shaaban Alsager 25ba1159ad
feat: Add internationalization (i18n) support (#182) 2022-08-23 23:32:40 -04:00
Vincent Huang e38eaa94d6
Popover preview should show relevant heading (#180) 2022-08-20 21:31:06 -04:00
Jacky Zhao a78926ede5 feat: link previews to page-list (closes #173) 2022-08-11 11:42:16 -07:00
Jacky Zhao 5c76d8dad9 fix: make callout detection case-insensitive (closes #171) 2022-08-05 11:08:52 -07:00
Jacky Zhao 3dcc1f1106 feat: better graph scaling (closes #170) 2022-08-05 11:04:01 -07:00
Jacky Zhao ff770927fd
style: _callouts.scss simplification (#169) 2022-08-04 14:50:24 -07:00
Jacky Zhao 7ffc907907 fix: CJK search (closes #163) 2022-08-03 23:46:55 -07:00
Jacky Zhao 6dd4c64a4c fix: highlights being stripped in non-semantic search mode 2022-08-01 07:59:49 -07:00
Jacky Zhao 8fc6b8e28e docs: update, re-added debounce 2022-07-31 18:21:17 -07:00
Jacky Zhao b10b23a47b docs: add documentation for Operand Search, remove debounce 2022-07-31 18:02:06 -07:00
Jacky Zhao 23380d0519 fix: title not being selected properly, bump hugo-obsidian for uri fix 2022-07-31 16:55:25 -07:00
Jacky Zhao dd047305af deps: bump hugo-obsidian to fix bug of writing to non-existent directory during build 2022-07-31 12:33:36 -07:00
Jacky Zhao 54a8fd4a56 deps: bump hugo-obsidian to properly copy linkmap 2022-07-31 12:24:53 -07:00
Jacky Zhao 5ef9aad501 feat: add support for semantic search using operand 2022-07-31 12:16:36 -07:00
Jacky Zhao 14b89105dc refactor: move search utils to util.js 2022-07-31 10:54:23 -07:00
Jacky Zhao 93d039fe7c deps: bump hugo-obsidian version 2022-07-31 10:14:36 -07:00
Jacky Zhao 234c707a93 docs: improve scss structure and admonition styling, update docs 2022-07-30 18:46:19 -07:00
Emile Bangma 728d8529ec
Support Admonition callouts (#166) (closes #88) 2022-07-30 17:29:26 -07:00
Jacky Zhao e142f37e8d Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-07-19 09:03:26 -07:00
Jacky Zhao d747b19e61 docs: copy edits 2022-07-19 09:03:19 -07:00
Pranav M 1f3da4b829
feat: edit the clipboard button to change border colour on success (#162)
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2022-07-18 08:45:36 -07:00
Jacky Zhao e15e39155d fix: give precedence to date created over last modified if defined (#101) 2022-07-15 14:26:31 -07:00
Jacky Zhao dff5ae0d4d style: improve header anchor styling 2022-07-14 13:09:21 -07:00
Jacky Zhao b2555ced61 feat: add description section to section/term/taxonomies, fix header margin 2022-07-14 12:02:54 -07:00
Jacky Zhao 7ccff2cf3d fix: styling on page-list for smaller screens 2022-07-14 11:49:47 -07:00
Jacky Zhao e0b6606d50 fix: make section-li scss more generic 2022-07-14 10:38:34 -07:00
Jacky Zhao d7a42a2fd7 feat: improve styling for lists, fix anchor offset 2022-07-14 10:30:07 -07:00
Jacky Zhao 422b6cc25b feat: css typography improvements 2022-07-13 23:51:33 -07:00
Jacky Zhao 22c8981bb9 feat: css refactor for easy font change 2022-07-13 23:37:54 -07:00
Jacky Zhao 8b2a82a96a fix: change / to use base url 2022-07-13 22:27:13 -07:00
y1450 81af8c459b
fix: remove console log (#159) 2022-07-13 15:02:11 -07:00
Jacky Zhao ffe22689eb feat: use floating-ui for better popover positioning 2022-07-13 15:01:50 -07:00
Jacky Zhao c1b8fe1221 feat: restyle search icon 2022-07-13 14:32:32 -07:00
Jacky Zhao b7a619bbd7 fix: tabsize not being respected 2022-07-12 14:37:10 -07:00
Jacky Zhao 74993d19b7 docs + fix: broken partial and description of enableGitHubEdit 2022-07-05 15:42:57 -07:00
rphla 25a4d3b6e1
Add GitHub "edit" button (#157) 2022-07-05 15:39:29 -07:00
Jacky Zhao aaf31f419e fix: copy code block logic for non code pages 2022-07-03 11:50:13 -07:00
Geoffrey Garrett f54df35767
Copy to clipboard feature for code block (#152)
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2022-07-03 11:42:35 -07:00
Aiden Bai 白宇彤 015ed4cfa2
Fix `width: auto` for SPA routing (#156) 2022-07-02 19:40:18 -07:00
Jacky Zhao a8137edf24 fix: adjust weird colours for err highlighting 2022-07-02 17:14:17 -07:00
Jacky Zhao eda370334a fix: image scaling for md-style links (closes #155) 2022-07-01 11:27:50 -07:00
Geoffrey Garrett d3e20b8b94
Added optional rendering of code block titles (#148) 2022-07-01 11:03:52 -07:00
Jacky Zhao 8d7a7b712f fix: non-SPA fn defs (closes #154) 2022-07-01 11:03:04 -07:00
Jacky Zhao 0896814959 docs: remove test image from hosting 2022-06-29 17:35:29 -07:00
Jacky Zhao 8b2fba895a feat: image scaling (closes #131) 2022-06-29 17:34:05 -07:00
Jacky Zhao e884f4927f fix: anchor formatting (closes #141) 2022-06-29 17:17:53 -07:00
Jacky Zhao 2b0482ae4c docs: fix page weight 2022-06-29 17:03:41 -07:00
Jacky Zhao 8a100edeb8 docs: polish and update 2022-06-29 16:57:36 -07:00
Jacky Zhao 200c605142 feat: enable raw html by default (fixes #143) 2022-06-29 16:16:06 -07:00
Jacky Zhao f2078ee621 fix: prefix images with base url for non-root quartz 2022-06-29 16:15:40 -07:00
Jacky Zhao 916c51c19c
Merge pull request #150 from aidenybai/bump-million 2022-06-28 23:21:25 -07:00
Aiden Bai 67a7ba37e8
Bump million to 1.11.3 2022-06-28 21:43:28 -07:00
Jacky Zhao 72941965ab
Merge pull request #146 from geoffreygarrett/hugo 2022-06-27 16:27:57 -07:00
Geoffrey Garrett b732293f65 fix(head.html): Adds robustness to `config.yaml` favicon definitions
Initially assumed that `href` definitions should have `/...` as their
pattern, and `baseURL` would always end with `/`, however the omission
of `/` as the prefix of the former and suffix of the latter
simultaneously, would result in broken favicon paths. Final comment:
`..///...` is not breaking, which is worst case scenario with this fix.
2022-06-28 01:21:22 +02:00
Geoffrey Garrett 7070a1992a docs(config.md): Fixed multi-favicon examples and general favicon explanation throughout 2022-06-28 01:15:33 +02:00
Geoffrey Garrett 997937af5a docs(config.md): Added short explainer on favicons 2022-06-28 00:45:48 +02:00
Geoffrey Garrett a334b45b17 docs(content/notes/config.md): Adds documentation for the new favicon support 2022-06-27 22:05:35 +02:00
Geoffrey Garrett 473ea2c66f feat(layouts/partials/head.html): Adds general favicon support with dict and string input format 2022-06-27 22:04:32 +02:00
Jacky Zhao 34b0353797
Merge pull request #140 from DhammaCharts/hugo 2022-06-07 08:43:52 -07:00
DhammaCharts 52a185f73b change enableGlobalGraph to false 2022-06-06 16:49:01 +01:00
DhammaCharts 69c74ca6b5 minor adjustment 2022-06-06 16:48:16 +01:00
DhammaCharts ab809249c8
Update layouts/partials/head.html
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2022-06-06 16:42:53 +01:00
DhammaCharts 84c75d0546
Merge branch 'hugo' into hugo 2022-06-06 12:56:47 +01:00
Jacky Zhao dbd4fb7595
Merge pull request #139 from aidenybai/prerender-latex 2022-06-03 10:59:18 -07:00
DhammaCharts a275123be2 better font behaviour 2022-06-02 08:35:28 +01:00
DhammaCharts c88f31c364 change to object destructuring for drawGraph() arguments 2022-06-02 08:16:02 +01:00
DhammaCharts d261655d96 remove unnecessary ternary 2022-06-02 07:49:09 +01:00
DhammaCharts c0800a8749 change baseURL back to original 2022-06-02 07:45:44 +01:00
DhammaCharts ac0dd50c04 uncomment window.Million 2022-06-01 21:30:40 +01:00
DhammaCharts e809896338 increase scale 2022-06-01 21:22:31 +01:00
DhammaCharts 19606ba63d add www. 2022-06-01 21:19:03 +01:00
DhammaCharts 1e237ef677 change baseURL 2022-06-01 20:15:44 +01:00
DhammaCharts 5a1fbc9374 Improve graph display, options and ability to have a global graph on the home page, local graphs on subpage. 2022-06-01 13:49:27 +01:00
Aiden Bai a1293f820a
Prerender latex 2022-05-29 20:40:44 -07:00
Jacky Zhao 84c6e1efed
Merge pull request #138 from aidenybai/add-footer-config 2022-05-28 23:27:54 -07:00
Aiden Bai 8673a7bc3d
Add option to toggle footer 2022-05-28 22:52:18 -07:00
Jacky Zhao 775a1b2490
Merge pull request #137 from aidenybai/fix-non-spa-routing 2022-05-27 19:21:05 -07:00
Aiden Bai 006b74ec6f
Fix formatting 2022-05-27 18:45:42 -07:00
Aiden Bai 8aba612a00
Fix non-spa fallback 2022-05-27 18:42:01 -07:00
Jacky Zhao cbc2bea413
Merge pull request #136 from aidenybai/custom-progress-bar-color 2022-05-27 18:32:49 -07:00
Aiden Bai ae240ff82c
Remove redundant CSS rule 2022-05-27 18:31:36 -07:00
Jacky Zhao ba586adc76
Merge pull request #135 from aidenybai/bump-million 2022-05-27 17:14:55 -07:00
Aiden Bai 159deabfe1
Bump to 1.9.6 2022-05-27 16:14:17 -07:00
Aiden Bai 44984cdaf4
Add support for progress bar 2022-05-27 13:27:13 -07:00
Aiden Bai 683cb53cbd
Bump million to 1.9.5 2022-05-27 13:19:19 -07:00
Jacky Zhao 232bd2f016
Merge pull request #134 from aidenybai/add-prefetching-within-graph 2022-05-27 11:01:20 -07:00
Aiden Bai e0fd9570d7
Bump million to 1.9.4 2022-05-27 09:49:28 -07:00
Aiden Bai bc32bbeaed
Bump milliomn to 1.9.3 2022-05-27 09:02:01 -07:00
Aiden Bai efb6c7845f
Add prefetch to graph 2022-05-27 08:40:00 -07:00
Aiden Bai bd316d8249
Bump million to 1.9.2 2022-05-27 08:39:44 -07:00
Jacky Zhao 0293c12217 feat: recent posts section/partial 2022-05-23 22:25:13 -07:00
Jacky Zhao 0439c163a0 fix: js not executing if spa disabled 2022-05-20 16:50:56 -04:00
Jacky Zhao 0b6711c218 fix: tag boxes overlapping for content with many tags (closes #130) 2022-05-14 16:47:50 -04:00
Jacky Zhao ed9a8efd1f fix inline link highlighting, safer latex render 2022-05-05 21:11:23 -04:00
Jacky Zhao e302f6c423 fix: more generic style to match bad nesting generated by popover interp 2022-05-05 20:35:32 -04:00
Jacky Zhao b21b27d1d3 fix: clean wikilinks and render latex in popover 2022-05-05 20:30:55 -04:00
Jacky Zhao 364aee36fc fix: merge conf 2022-05-05 01:03:09 -04:00
Jacky Zhao cea0f3eb74 feat: contextual backlinks (closes #106) 2022-05-05 00:58:50 -04:00
Jacky Zhao 8b855b522a
Merge pull request #125 from aidenybai/fix-latex 2022-05-04 11:40:38 -04:00
Aiden Bai 7b3696b877
Remove pnpm debug log 2022-05-04 08:39:25 -07:00
Aiden Bai b4ff12ca0b
Fix latex 2022-05-04 08:10:59 -07:00
Jacky Zhao b67a389bea
Merge pull request #124 from aidenybai/hugo 2022-05-03 13:59:02 -04:00
Aiden Bai 2b5c03c972
Remove redundant URL construction 2022-05-03 10:55:45 -07:00
Aiden Bai aaed5dc1f1
Support /path root sites 2022-05-03 10:54:39 -07:00
Aiden Bai 1a5d158fce
Support active node with other data at end of url 2022-05-03 10:38:41 -07:00
Jacky Zhao a09974446d
Merge pull request #123 from aidenybai/fix-popover 2022-05-03 13:21:32 -04:00
Aiden Bai 9fc71603ba
Merge 2022-05-03 10:18:41 -07:00
Aiden Bai d38f9bec70
Rename API and generalize router API 2022-05-03 10:16:09 -07:00
Aiden Bai 771ebd8031
Merge 2022-05-03 10:07:38 -07:00
Aiden Bai e4cc625c33
Add future note about init function 2022-05-03 09:34:27 -07:00
Aiden Bai 白宇彤 3789df80e4
Merge branch 'hugo' into fix-popover 2022-05-03 09:33:00 -07:00
Jacky Zhao 037426217c
Merge pull request #122 from aidenybai/fix-active-graph-node 2022-05-03 12:29:26 -04:00
Aiden Bai e646cdb0be
Use explicit regex for trailing slash trim 2022-05-03 09:27:25 -07:00
Aiden Bai 8d092a3a4a
Remove unnecessary 'url' argument in graph.html 2022-05-03 09:22:51 -07:00
Aiden Bai 32c79a561f
Remove unnecessary 'url' argument in graph.html 2022-05-03 09:21:44 -07:00
Aiden Bai 3c660dd9b5
Remove unnecessary 'url' param in drawGraph 2022-05-03 09:20:01 -07:00
Aiden Bai 4cca3c1f2d
Peg router version 2022-05-03 09:04:15 -07:00
Aiden Bai 9d3bbd6076
Fix active node on graph 2022-05-03 08:53:18 -07:00
Aiden Bai 9c71f07355
Enable config for testing 2022-05-03 08:48:35 -07:00
Aiden Bai 77485b754d
Fix popover 2022-05-03 08:47:42 -07:00
Jacky Zhao 6e6dd4cb0b fix: trim trailing slash when calculating popover 2022-05-03 10:57:20 -04:00
Jacky Zhao 81fe2d2493 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-05-03 10:44:56 -04:00
Jacky Zhao 24d08d580d cfg: make SPA optional 2022-05-03 10:43:22 -04:00
Jacky Zhao 321e19dc41
Merge pull request #121 from benbohmer/patch-1 2022-05-03 09:48:50 -04:00
Jacky Zhao 12d33619a2
Merge pull request #120 from straightupjac/fix/github-info 2022-05-03 09:47:48 -04:00
benbohmer 97607c3ca5
fix: keep / at end of URL to avoid redirects
Removed strings.TrimRight "/" in line 10 to keep the trailing slash at the end of URLs in regular links. This avoids having every single internal link being a 301 redirect.
2022-05-03 09:10:45 +02:00
straightupjac 4197ad460a fix github info 2022-05-03 01:51:15 -04:00
Jacky Zhao fc89ff2680 fix: broken semi and graph min-height 2022-05-02 13:00:41 -04:00
Jacky Zhao e9a33c04b5 fmt: remove semis for good 2022-05-02 12:56:44 -04:00
Jacky Zhao b0e15e0cbc
Merge pull request #118 from aidenybai/add-router 2022-05-02 12:19:26 -04:00
Jacky Zhao 9ba0a4b34f fmt: remove semis :) 2022-05-02 12:14:51 -04:00
Aiden Bai f1b85fb6d9
Fix clarification comment 2022-05-02 09:10:40 -07:00
Jacky Zhao 66304da027
Merge pull request #119 from aidenybai/add-prettier
Add prettier config
2022-05-02 12:06:57 -04:00
Aiden Bai 40d216759c
Expand template 2022-05-02 09:05:02 -07:00
Aiden Bai 5c602ab16f
Add clarification comments 2022-05-02 09:04:36 -07:00
Aiden Bai 87144fca21
Use semi: false for prettier config 2022-05-02 08:57:25 -07:00
Aiden Bai a9523dd39b
Add prettier config 2022-05-01 22:08:14 -07:00
Aiden Bai bcb166c21c
Add router 2022-05-01 22:06:33 -07:00
Jacky Zhao 416dc0b85c fix: add update for local hugo-obsidian on make update 2022-04-30 13:13:30 -07:00
Jacky Zhao b8a660e208 feat: copyable header anchors (fixes #86) 2022-04-30 13:10:12 -07:00
Jacky Zhao ec86cca97b Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-28 15:53:57 -07:00
Jacky Zhao 87b5a7a251 feat: show graph titles on zoom (fixes #92) 2022-04-28 15:49:16 -07:00
Jacky Zhao c8d390dbc5 fix: always hide popover on mobile (fixes #104) 2022-04-28 13:45:29 -07:00
Jacky Zhao 3c7ece5405 fix: append trailing slash, fixes #111 2022-04-28 10:48:31 -07:00
Jacky Zhao f7027e7ecd
Merge pull request #108 from exu3/patch-1 2022-04-20 09:20:21 -07:00
Ella 0cfd93c57c
Fix another typo 2022-04-17 02:11:17 -07:00
Ella 3f8c473678
Fix typo: recomment -> recommend 2022-04-17 01:33:16 -07:00
Jacky Zhao f05ff5e62d fix: add dropshadow to popover, cleanup animation 2022-04-05 23:19:33 -07:00
Jacky Zhao 12ed9722d8 fix: popover selection wrongly including line breaks 2022-04-05 22:43:11 -07:00
Jacky Zhao 887d4d4f5e deps: bump hugo -> v0.96.0 2022-04-05 21:40:59 -07:00
Jacky Zhao f9c7cdf928 fix: check for src before attempting to add popover 2022-04-05 20:44:39 -07:00
Jacky Zhao 2d55b6ac2e fix: missing whitespace chomp in link render hook 2022-04-05 18:07:40 -07:00
Jacky Zhao d5884aedb7 fix: wikilink patch not applying to transformed text like apostrophes 2022-04-05 14:14:19 -07:00
Jacky Zhao 66eaa444a4 fix: wikilink image relURL for images with spaces 2022-04-05 14:08:36 -07:00
Jacky Zhao 0ddc48a452 fix: wikilink-like text in code fences #95, #97 2022-04-05 13:47:24 -07:00
Jacky Zhao cd19159c53 feat: wikilink img support 2022-04-05 12:47:28 -07:00
Jacky Zhao 7808c66c4d fix: align footer links 2022-04-05 09:41:13 -07:00
Jacky Zhao a7abc6ab96 docs: make update command and clarify update steps/potential danger 2022-04-05 00:09:56 -07:00
Jacky Zhao 9509a64354 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-05 00:02:48 -07:00
Jacky Zhao 53242b1e57 add update target to Makefile 2022-04-05 00:02:37 -07:00
Jacky Zhao 3ce6944c18
Merge pull request #93 from meleu/patch-3 2022-04-04 23:56:28 -07:00
Jacky Zhao 3cec4fd950 update screenshot 2022-04-04 23:30:28 -07:00
Jacky Zhao e245505082 feat: hide toc for short notes 2022-04-04 23:25:24 -07:00
Jacky Zhao fc4b9ded76
Merge pull request #94 from meleu/patch-4 2022-04-04 23:20:43 -07:00
meleu 27c4761fe0
link to home goes to baseURL 2022-04-04 20:15:40 -03:00
meleu 3583265f80
docs: warn about possible lost of customization 2022-04-04 17:30:23 -03:00
Jacky Zhao 3781b67707
Merge pull request #91 from meleu/patch-2 2022-04-04 13:08:42 -07:00
meleu 671fe05312
padding and border-radius matching bottom cards
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2022-04-04 17:07:43 -03:00
Jacky Zhao 1613511f39 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-04 09:45:05 -07:00
Jacky Zhao acab488784 re-add obsidian file 2022-04-04 09:44:58 -07:00
meleu ff91dcd196
Merge branch 'jackyzha0:hugo' into patch-2 2022-04-03 22:14:12 -03:00
meleu a287d11246 add a collapsible ToC 2022-04-03 22:12:55 -03:00
Jacky Zhao 575288ece9
Merge pull request #88 from meleu/patch-2 2022-04-03 17:57:46 -07:00
Jacky Zhao 25b5ac43dd fix: favicon not showing on non-root domain #89 2022-04-03 17:43:37 -07:00
meleu 1d9c0e4a44 use "enableToc: false" 2022-04-03 16:31:29 -03:00
meleu e62d512d95 disable ToC if frontmatter has "enableToc: false" 2022-04-03 16:29:10 -03:00
meleu 8f15c5f8c1
disable ToC if enableToc: false 2022-04-03 16:22:32 -03:00
Jacky Zhao efeaf9b49c Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-03 11:44:39 -07:00
Jacky Zhao 91c4e3fb3a fix: multiline code block #87 2022-04-03 11:44:33 -07:00
Jacky Zhao 22f11711b2
Merge pull request #85 from meleu/patch-1
Ah my git was being really weird with cases :')) thank you
2022-04-03 08:17:13 -07:00
meleu 5c3ef884c7
duplicated file 2022-04-03 11:19:21 -03:00
Jacky Zhao 16b177ce66 README update 2022-04-02 21:04:20 -07:00
Jacky Zhao 14c6181d24 bump hugo version v0.82 -> v0.92.2 2022-04-02 20:37:42 -07:00
Jacky Zhao e6e04c03c4 fix latex misrendering 2022-04-02 20:34:55 -07:00
Jacky Zhao 146e975932 bump hugo obsidian, fix backlinks for subpathed quartz, update homepage 2022-04-02 20:21:16 -07:00
Jacky Zhao c117e38899 feat: wikilinks implementation 2022-04-02 20:06:31 -07:00
Jacky Zhao 4fd983277e fix: cjk support + demo page 2022-04-02 17:38:39 -07:00
Jacky Zhao cc86136bcb feat: basic latex support 2022-04-02 17:00:14 -07:00
Jacky Zhao 8e083d4a93
Merge pull request #83 from meleu/patch-2 2022-04-02 14:53:05 -07:00
meleu 03b574b160 cleanup 2022-04-02 18:51:45 -03:00
meleu a469653f75 separate contact links semantically 2022-04-02 18:50:58 -03:00
Jacky Zhao c51573efa9 feat: grey out broken links 2022-04-02 13:34:26 -07:00
Jacky Zhao 902d0f2a0f Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-02 12:59:47 -07:00
Jacky Zhao 1ddd15afc6 fix: non-unicode character in popover and search #67, #68 2022-04-02 12:59:38 -07:00
meleu 16f8cd7100
separate links with &ZeroWidthSpace; 2022-04-02 13:37:12 -03:00
Jacky Zhao 9c5ecccf25
Merge pull request #82 from meleu/patch-1 2022-04-01 14:17:35 -07:00
meleu e3cd531c53
fix custom.scss path 2022-04-01 18:13:49 -03:00
Jacky Zhao 3674df48b8 fix pagination styling 2022-04-01 10:13:01 -07:00
Jacky Zhao 9e8c5587e4 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-03-31 23:16:00 -07:00
Jacky Zhao 6605b13b86 more troubleshooting, backlinks reference private page fix 2022-03-31 23:15:54 -07:00
Jacky Zhao 6edc979896
Merge pull request #71 from siyangsun/patch-1 2022-03-21 09:15:35 -07:00
Siyang fc43922445
add to showcase and fix link to file 2022-03-20 22:37:05 -07:00
Jacky Zhao 54a68e6e5c patch image 2022-03-18 10:53:39 -07:00
Jacky Zhao a6ab2f92ef add update 2022-03-16 17:54:24 -07:00
Jacky Zhao fda481fbb9 fix: bump hugo-obsidian version to account for contentIndex paths on windows 2022-03-15 01:12:08 -07:00
Jacky Zhao 94e987dab5 feat: better titles for empty pages #61 2022-03-15 00:37:56 -07:00
Jacky Zhao e981c76ed4
Merge pull request #65 from claudio4/fix-text 2022-03-09 10:11:36 -08:00
Claudio Yanes f70128a3de
Prevent overflow of long links and words
When a word (or any string withtout breakpoints (spaces, dashes....), making links the most common place where this becamoes an issue)  is wider than its container, the text will simply overflow any container, including the viewport. This commit fixes this behaviour by making the word-drap strategy of the browser more aggresive.
2022-03-09 17:58:01 +00:00
Jacky Zhao 651bfc5cd2
Merge pull request #62 from claudio4/hugo 2022-03-07 10:45:07 -08:00
Claudio Yanes 6079420178 Merge branch 'jackyzha0-hugo' into hugo 2022-03-07 18:28:14 +00:00
Claudio Yanes b96c60edfc Merge branch 'hugo' of https://github.com/jackyzha0/quartz into jackyzha0-hugo 2022-03-07 18:27:45 +00:00
Claudio Yanes 978d5ca1ae Format JS 2022-03-07 18:25:02 +00:00
Jacky Zhao 907270992d fix: hide popover on mobile to prevent overflow 2022-03-04 23:55:07 -08:00
Claudio Yanes 6f9283e95b Update makefile and docs
The artifacts produced by hugo-obsidian are now expected to be placed in
the assets/indices directory. This commit reflects this change in the
Makefile and in the docs.
2022-03-04 22:27:21 +00:00
Claudio Yanes 0fad5570d3 Add .gitkeep to assets/indices 2022-03-04 04:14:42 +00:00
Claudio Yanes dc9b421e21 Remove unnecessary scrollbars
The margin property can escape the parent node and move it alongside
its child. This happens with singlePage div and the body, resulting in
scrollbars appearing as the body has the size of the viewport but
does not align with it. This phenomenon can be always observed
in the vertical axis and it can also be observed in the horizontal axis
when the viewport it’s not wide enough (mostly in mobile).

Using paddings prevents this “extra space” from scraping and displacing
the body.

Also, the value 100vw does not take into account the space taken by the
vertical scrollbar, thus making the body wider than the actual viewport,
producing a horizontal scrollbar.
2022-03-04 04:12:43 +00:00
Claudio Yanes 8779e72c77 Add attribute property to scripts from jsdelivr
Adding the integrity attribute protects the website (by refusing to load
the script) against malicious modifications of the script
in the case of jsdelivr gets hacked
2022-03-04 03:34:45 +00:00
Claudio Yanes 7f6523337c Move popover to the end of the page
The popover script doesn’t ever start in until the DOM has finished
Loading, so wait for the script to be downloaded and parsed before
Showing the content to the user makes no sense.
2022-03-04 03:24:32 +00:00
Claudio Yanes 7e0f2e4449 Fix fetchData
The fetchData function suffer from a race condition. If the function is
called before the promise finishes, it will result in another pair of
HTTP request. This does not only make the function useless but
Actually, it makes it harmful as the data might be redownloaded twice.

Now fetchData is not a function but rather the promise by itself.
Previous callers are expected to await the variable instead, this
should be not concern as awaiting a promise multiple time in
JavaScript is completely safe.
2022-03-04 02:25:30 +00:00
Claudio Yanes 1313bd9779 Move css and js to appropriate files
Having the CSS and JS in the html template produces pages larger
than necessary, as each page need to contain all the js/css.
Separating them in appropriate files allow the browser to just download
them once and use them for all the pages. This is even more effective
with an aggressive cache policy for the js and css, something that can
be done without fear thanks to the implemented cache-busting.
Also, having then in separate files allows us to use Hugo pipelines
for minimizing the code.
2022-03-04 02:07:51 +00:00
Jacky Zhao 5234fae080 fix backlinks not using baseurl 2022-02-28 08:24:29 -08:00
Jacky Zhao 0ee0855e1c bump hugo-obsidian to support root 2022-02-28 07:30:59 -08:00
Jacky Zhao e06e341468 fix: explicitly set root as current directory to fix ignore files 2022-02-28 07:14:55 -08:00
Jacky Zhao 73e526a7d5 add screenshot to readme 2022-02-23 12:28:25 -05:00
Jacky Zhao cdc4f1a840 fix: relink search button (move outside content load listener) 2022-02-22 13:36:08 -05:00
Jacky Zhao 714b4fcfa3 fix links being broken for pages with spaces 2022-02-20 21:40:10 -05:00
Jacky Zhao 9c04ca0266 rtl docs 2022-02-17 10:49:41 -05:00
Jacky Zhao 388a2bf78b docs updates 2022-02-17 10:44:39 -05:00
Jacky Zhao f192f9a23d fix #54: root all image urls 2022-02-15 23:03:02 -05:00
Jacky Zhao 3b3e6ec3b2 fix relative pathing for dynamic fetch 2022-02-15 22:54:20 -05:00
Jacky Zhao 8e85e274f6 change output to static instead of data 2022-02-15 19:42:45 -05:00
Jacky Zhao fcd5d2807d feat: dynamically fetch indices 2022-02-15 19:39:14 -05:00
Jacky Zhao 4587b13360 feat: add rtl support as part of #47 2022-02-15 17:12:08 -05:00
Jacky Zhao fb9ea8dcb8 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-02-15 16:52:49 -05:00
Jacky Zhao c520db4882 fix: #50, change css load order 2022-02-15 16:52:32 -05:00
Jacky Zhao 10f9843bb6
Merge pull request #51 from brandonkboswell/patch-1 2022-02-15 14:51:29 -05:00
Jacky Zhao 0dc51ff39c Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-02-15 14:50:34 -05:00
Jacky Zhao c35086c510 visibility fix 2022-02-15 14:50:25 -05:00
Brandon Boswell 31297b7e5a
Added to the Showcase 2022-02-12 22:35:03 -05:00
Jacky Zhao fa3bc3de92
Merge pull request #48 from earnestma/earne/configurable-page-toc 2022-02-11 17:24:54 -05:00
earnest ma 41c443dbf0
Add disableToc parameter to not show TOC on a page 2022-02-11 17:15:28 -05:00
Jacky Zhao a271fb9d74
Merge pull request #46 from adube/patch-1 2022-01-31 12:28:40 -08:00
Alexandre Dubé 49cdca5dfc
Specify Hugo requires extended Sass/SCSS version
Hugo needs to be installed with its "extended" Sass/SCSS version, otherwise this template does not work.
2022-01-31 15:18:26 -05:00
Jacky Zhao 9645f00317 link fixing 2022-01-27 09:38:28 -08:00
Jacky Zhao 57ebf4c21c underscore fix, fix relative path being weird for graph 2022-01-10 13:08:50 -08:00
Jacky Zhao 54e3e071d1 fix popover regex 2022-01-10 09:00:45 -08:00
Jacky Zhao d46e223831 revert baseurl fix 2022-01-10 08:51:00 -08:00
Jacky Zhao 6f9a29c174 various path fixes 2022-01-10 08:49:29 -08:00
Jacky Zhao 532bc61025 set relativeUrls to true 2022-01-05 19:42:13 -05:00
Jacky Zhao 99aea48260 docs update 2022-01-04 11:39:22 -05:00
Jacky Zhao 4a3766db56 update featurelist 2022-01-03 16:37:24 -05:00
Jacky Zhao 4e639979f8 fix copy selection 2022-01-03 15:36:58 -05:00
Jacky Zhao e49a1ac9db made link preview optional 2022-01-03 13:22:04 -05:00
Jacky Zhao 4a3c4fdef5 popover implementation 2022-01-03 13:18:31 -05:00
Jacky Zhao 2b432d7f0b fix flex gap 2022-01-02 20:02:47 -05:00
Jacky Zhao 7507fd2991 fix search styling 2022-01-02 19:49:41 -05:00
Jacky Zhao ca886e4075 fix render link for apostrophe 2021-12-28 14:28:08 -05:00
Jacky Zhao 3722e600ee bump hugo-obsidian 2021-12-27 20:52:30 -05:00
Jacky Zhao efeaf0f4e4 add pagination to section, fix graph linking 2021-12-27 20:16:21 -05:00
Jacky Zhao 1a8cdaad24 remove console.log 2021-12-27 19:43:01 -05:00
Jacky Zhao e4caa0d1d7 add taxonomy and term lists 2021-12-27 19:35:42 -05:00
Jacky Zhao a45856d788 fix last modified not working for capitalized pages 2021-12-27 17:53:33 -05:00
Jacky Zhao dbe9b338cc fix capitalization 2021-12-27 17:44:39 -05:00
Jacky Zhao 000fcdbf99 fix casing 2021-12-27 17:43:27 -05:00
Jacky Zhao 612c44d719 modify obsidian 2021-12-27 17:34:53 -05:00
Jacky Zhao e1911a58ff enable last modified info 2021-12-27 17:28:53 -05:00
Jacky Zhao b4e2697116 content section 2021-12-27 15:59:19 -05:00
Jacky Zhao 094ab9d064 dedupe backlinks 2021-12-27 13:15:10 -05:00
Jacky Zhao 39592347cc add graph depth config 2021-12-27 13:06:58 -05:00
Jacky Zhao 165d33810d base tags 2021-12-26 21:13:21 -05:00
Jacky Zhao 6fbfa7170b various font and colour fixes 2021-12-26 00:09:15 -05:00
Jacky Zhao 43837f9e2e add makefile, fix link padding, test capitalization 2021-12-25 23:45:30 -05:00
Jacky Zhao 2ba01c8311 fix untitled #36 2021-12-24 15:51:37 -05:00
Jacky Zhao 114b7ca913 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2021-12-24 09:48:41 -05:00
Jacky Zhao 5bd5642c99 add toLowerCase to id 2021-12-24 09:48:22 -05:00
Jacky Zhao 48d01810c4 fix config setting, fix font size for h1 in article 2021-12-23 14:40:59 -08:00
Jacky Zhao 3a98c8b554 actually display site title 2021-12-23 14:32:47 -08:00
Jacky Zhao 69c86e407f update subdomain docs 2021-12-23 14:21:39 -08:00
Jacky Zhao 56d2382c28 fix relative link styling, change graph and backlinks to refer to name rather than path 2021-12-23 14:05:27 -08:00
Jacky Zhao 091be7040b
Create CODE_OF_CONDUCT.md 2021-12-23 13:37:29 -08:00
Jacky Zhao 09b5522a48 Update issue templates 2021-12-23 13:22:22 -08:00
Jacky Zhao b9d7adafcc
Create FUNDING.yml 2021-12-23 13:18:03 -08:00
Jacky Zhao afeb18212d
Merge pull request #28 from juaoose/overflow 2021-12-02 20:06:18 -08:00
Juaoose bc90955959 remove horizontal scrollbar 2021-12-02 22:58:34 -05:00
Jacky Zhao c64322ad3f remove bad wikilink 2021-11-20 22:55:53 -08:00
Jacky Zhao 48eb9ebc5f better search, fix spacing support, bump hugo-obsidian 2021-11-20 22:53:26 -08:00
Jacky Zhao 82ba843e42 search styling 2021-11-15 15:54:18 -08:00
Jacky Zhao 8ca31df3f2 search patch 2021-10-31 09:59:38 -07:00
Jacky Zhao df23b99951 more search improvements 2021-10-30 23:27:33 -07:00
Jacky Zhao 6005a2e0a0 css fixes 2021-10-27 20:10:04 -07:00
Jacky Zhao de940d6a4b update graph redir 2021-10-26 17:06:00 -07:00
Jacky Zhao 806d11f874
Merge pull request #23 from bur3ku/hugo 2021-10-26 17:03:07 -07:00
Blake Allen 1fc2da4fe2 Merge branch 'hugo' of https://github.com/bur3ku/quartz into hugo 2021-10-26 16:58:37 -07:00
Blake Allen 9292de6333 remove unnecessary regex, use encodeuri for label instead of replace 2021-10-26 16:58:08 -07:00
Blake Allen 2477662404
Merge branch 'hugo' into hugo 2021-10-26 12:46:03 -07:00
Blake Allen a14d06aa3d fix conflict fix 2021-10-26 12:44:25 -07:00
Blake Allen e0535dbe32 fix conflict 2021-10-26 12:43:55 -07:00
Blake Allen 8eca1e60f7 change %20 in node labels to whitespace, change %20 in node hrefs to hyphen 2021-10-26 12:36:20 -07:00
Jacky Zhao 03bb3a3bae normalize search styling 2021-10-25 15:06:29 -07:00
Jacky Zhao f7b89db8ee search fix 2021-10-25 15:00:55 -07:00
Jacky Zhao 1835b97a7a better homepage 2021-10-24 23:45:55 -07:00
Jacky Zhao f56642f13c forgot string lol 2021-10-24 23:32:55 -07:00
Jacky Zhao 22a9c0ddfc docs updates, add search to main page, fix redir bug 2021-10-24 23:31:09 -07:00
Jacky Zhao c1c061fbea bump docs 2021-10-24 23:17:20 -07:00
Jacky Zhao 6fd19069de search improvements 2021-10-24 23:17:13 -07:00
Jacky Zhao 299533a4f4 bump hugo-obsidian version 2021-10-24 23:17:00 -07:00
Blake Allen e1366ecb61 fix accidental code 2021-10-22 18:56:26 -07:00
Blake Allen 776ef084c9 fix last commit 2021-10-22 18:32:57 -07:00
Blake Allen fc00ad5bff fix for notes with spaces not linking properly 2021-10-22 14:04:09 -07:00
Jacky Zhao 228f96e74d
Merge pull request #14 from juaoose/hugo
fix product typo in external hosting section
2021-08-31 18:32:14 -04:00
Juan José Rodríguez 071984a12d fix product typo in external hosting section 2021-08-31 16:40:31 -05:00
jackyzha0 ae2f7efde0 update showcase 2021-08-28 20:58:14 -04:00
jackyzha0 cb38667c1d Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2021-08-27 14:08:18 -04:00
Jacky Zhao 27c33f8334
Merge pull request #9 from brechtcs/template
Execute darkmode script before first render
2021-08-13 17:45:32 -04:00
Brecht Savelkoul f9920f6d73 Execute darkmode script before first render 2021-08-13 22:50:02 +02:00
Jacky Zhao 8850976d8d
Merge pull request #8 from SlRvb/patch-1
Add SlRvb Site to Showcase
2021-08-12 23:49:05 -04:00
SlRvb bb6a1e8c34
Add SlRvb Site to Showcase 2021-08-12 20:46:23 -07:00
217 changed files with 17626 additions and 1630 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
github: [jackyzha0]

33
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,33 @@
---
name: Bug report
about: Something about Quartz isn't working the way you expect
title: ""
labels: bug
assignees: ""
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,19 @@
---
name: Feature request
about: Suggest an idea or improvement for Quartz
title: ""
labels: enhancement
assignees: ""
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

53
.github/workflows/ci.yaml vendored Normal file
View File

@ -0,0 +1,53 @@
name: Build and Test
on:
pull_request:
branches:
- v4
push:
branches:
- v4
jobs:
build-and-test:
if: ${{ github.repository == 'jackyzha0/quartz' }}
strategy:
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
permissions:
contents: write
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- run: npm ci
- name: Check types and style
run: npm run check
- name: Test
run: npm test
- name: Ensure Quartz builds, check bundle info
run: npx quartz build --bundleInfo
- name: Create release tag
uses: Klemensas/action-autotag@stable
with:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
tag_prefix: "v"

View File

@ -1,36 +0,0 @@
name: Deploy to GitHub Pages
on:
push:
branches:
- hugo
jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Build Link Index
uses: jackyzha0/hugo-obsidian@v2.3
with:
index: true
input: content
output: data
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.82.0'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
publish_branch: master # deploying branch
cname: quartz.jzhao.xyz

16
.gitignore vendored
View File

@ -1,7 +1,13 @@
.DS_Store .DS_Store
.gitignore
node_modules
public public
resources prof
.idea tsconfig.tsbuildinfo
content/.obsidian .obsidian
data/linkIndex.yaml .quartz-cache
data/contentIndex.yaml private/
.replit
replit.nix
.env
content/

1
.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict=true

3
.prettierignore Normal file
View File

@ -0,0 +1,3 @@
public
node_modules
.quartz-cache

7
.prettierrc Normal file
View File

@ -0,0 +1,7 @@
{
"printWidth": 100,
"quoteProps": "as-needed",
"trailingComma": "all",
"tabWidth": 2,
"semi": false
}

90
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,90 @@
# Citizen Code of Conduct
## 1. Purpose
A primary goal of the Quartz community is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).
This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.
We invite all those who participate in the Quartz community to help us create safe and positive experiences for everyone.
## 2. Open [Source/Culture/Tech] Citizenship
A supplemental goal of this Code of Conduct is to increase open [source/culture/tech] citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community.
Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society.
If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know.
## 3. Expected Behavior
The following behaviors are expected and requested of all community members:
- Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community.
- Exercise consideration and respect in your speech and actions.
- Attempt collaboration before conflict.
- Refrain from demeaning, discriminatory, or harassing behavior and speech.
- Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential.
- Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations.
## 4. Unacceptable Behavior
The following behaviors are considered harassment and are unacceptable within our community:
- Violence, threats of violence or violent language directed against another person.
- Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language.
- Posting or displaying sexually explicit or violent material.
- Posting or threatening to post other people's personally identifying information ("doxing").
- Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability.
- Inappropriate photography or recording.
- Inappropriate physical contact. You should have someone's consent before touching them.
- Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances.
- Deliberate intimidation, stalking or following (online or in person).
- Advocating for, or encouraging, any of the above behavior.
- Sustained disruption of community events, including talks and presentations.
## 5. Weapons Policy
No weapons will be allowed at Quartz community events, community spaces, or in other spaces covered by the scope of this Code of Conduct. Weapons include but are not limited to guns, explosives (including fireworks), and large knives such as those used for hunting or display, as well as any other item used for the purpose of causing injury or harm to others. Anyone seen in possession of one of these items will be asked to leave immediately, and will only be allowed to return without the weapon. Community members are further expected to comply with all state and local laws on this matter.
## 6. Consequences of Unacceptable Behavior
Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated.
Anyone asked to stop unacceptable behavior is expected to comply immediately.
If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event).
## 7. Reporting Guidelines
If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. j.zhao2k19@gmail.com.
Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress.
## 8. Addressing Grievances
If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify @jackyzha0 with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies.
## 9. Scope
We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues--online and in-person--as well as in all one-on-one communications pertaining to community business.
This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members.
## 10. Contact info
j.zhao2k19@gmail.com
## 11. License and attribution
The Citizen Code of Conduct is distributed by [Stumptown Syndicate](http://stumptownsyndicate.org) under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).
Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy).
_Revision 2.3. Posted 6 March 2017._
_Revision 2.2. Posted 4 February 2016._
_Revision 2.1. Posted 23 June 2014._
_Revision 2.0, adopted by the [Stumptown Syndicate](http://stumptownsyndicate.org) board on 10 January 2013. Posted 17 March 2013._

12
Dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM node:20-slim as builder
WORKDIR /usr/src/app
COPY package.json .
COPY package-lock.json* .
RUN npm ci
RUN npm install
FROM node:20-slim
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/ /usr/src/app/
COPY . .
CMD ["npx", "quartz", "build", "--serve"]

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
.DEFAULT_GOAL := help
# Load environment variables from .env file
include .env
help:
@echo "Available targets:"
@echo " publish Restart Docker Compose (or run 'npx quartz build --serve' with local=True)."
@echo " preview Run 'npx quartz build --serve' with specific directories."
# Target-specific variables for the publish target
publish:
@./scripts/publish.sh "$(SOURCE_DIR)" "$(DEST_DIR)"
@if [ "$(local)" = "True" ]; then \
echo "Running npx quartz build --serve"; \
npx quartz build --serve; \
else \
echo "Restarting Docker Compose"; \
docker compose restart; \
fi

View File

@ -1,6 +1,53 @@
# Quartz # Quartz v4
Simple second brain and digital garden.
> “He who works with the door open gets all kinds of interruptions, but he also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming ## Set up
🔗 Get Started: https://quartz.jzhao.xyz/ Set up .env:
```
SOURCE_DIR=<path>
DEST_DIR=<path>
```
Run on local:
```
make publish local=True
```
Run on server:
```
make publish
```
## How this works
- From local obsidian, sync to remote obsidian
- In local I read from local vault and copy to content all that have tag publish=True
- In remote I read from remove vault and copy to content all that have tag publish=True
## Improvements
- scripts/publish.sh:
- [ ] Skip copying files that already exist
- [ ] Resize image to 60% for faster load
- [x] add restart/publish to make
---
> “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming
Quartz is a set of tools that helps you publish your [digital garden](https://jzhao.xyz/posts/networked-thought) and notes as a website for free.
Quartz v4 features a from-the-ground rewrite focusing on end-user extensibility and ease-of-use.
**If you are looking for Quartz v3, you can find it on the [`hugo` branch](https://github.com/jackyzha0/quartz/tree/hugo).**
🔗 Read the documentation and get started: https://quartz.jzhao.xyz/
[Join the Discord Community](https://discord.gg/cRFFHYye7t)
## Sponsors
<p align="center">
<a href="https://github.com/sponsors/jackyzha0">
<img src="https://cdn.jsdelivr.net/gh/jackyzha0/jackyzha0/sponsorkit/sponsors.svg" />
</a>
</p>

View File

@ -1,354 +0,0 @@
:root {
--lt-colours-light: var(--light) !important;
--lt-colours-lightgray: var(--lightgray) !important;
--lt-colours-dark: var(--secondary) !important;
--lt-colours-secondary: var(--tertiary) !important;
--lt-colours-gray: var(--outlinegray) !important;
}
h1, h2, h3, h4, ol, ul, thead {
font-family: Inter;
color: var(--dark)
}
p, ul, text {
font-family: 'Source Sans Pro', sans-serif;
color: var(--gray);
fill: var(--gray);
}
a {
font-family: Inter;
font-weight: 700;
font-size: 1em;
text-decoration: none;
transition: all 0.2s ease;
color: var(--secondary);
&:hover {
color: var(--tertiary) !important;
}
}
#TableOfContents > ol {
counter-reset: section;
margin-left: 0em;
padding-left: 1.5em;
& > li {
counter-increment: section;
& > ol {
counter-reset: subsection;
& > li {
counter-increment: subsection;
&::marker {
content: counter(section) "." counter(subsection) " ";
}
}
}
}
& > li::marker {
content: counter(section) " ";
}
& > li::marker, & > li > ol > li::marker {
font-family: Source Sans Pro;
font-weight: 700;
}
}
footer {
margin-top: 4em;
text-align: center;
}
table {
width: 100%;
}
img {
width: 100%;
border-radius: 3px;
margin: 1em 0;
}
p>img+em {
display: block;
transform: translateY(-1em);
}
sup {
line-height: 0
}
p, tbody, li {
font-family: Source Sans Pro;
color: var(--gray);
line-height: 1.5em;
}
h2 {
opacity: 0.85;
}
h3 {
opacity: 0.75;
}
blockquote {
margin-left: 0em;
border-left: 3px solid var(--secondary);
padding-left: 1em;
transition: border-color 0.2s ease;
&:hover {
border-color: var(--tertiary);
}
}
table {
padding: 1.5em;
}
td, th {
padding: 0.1em 0.5em;
}
.footnotes p {
margin: 0.5em 0;
}
article a {
font-family: Source Sans Pro;
font-weight: 600;
text-decoration: underline;
text-decoration-color: var(--tertiary);
text-decoration-thickness: .15em;
}
sup > a {
text-decoration: none;
padding: 0 0.1em 0 0.2em;
}
pre {
font-family: 'Fira Code';
padding: 0.75em;
border-radius: 3px;
overflow-x: scroll;
}
code {
font-family: 'Fira Code';
font-size: 0.85em;
padding: 0.15em 0.3em;
border-radius: 5px;
background: var(--lightgray);
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
height: 100vh;
width: 100vw;
overflow-x: hidden;
background-color: var(--light);
}
@keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
}
footer {
margin-top: 4em;
& > a {
font-size: 1em;
color: var(--secondary);
padding: 0 0.5em 3em 0.5em;
}
}
hr {
width: 25%;
margin: 4em auto;
height: 2px;
border-radius: 1px;
border-width: 0;
color: var(--dark);
background-color: var(--dark);
}
// internal link
a[href^="/"] {
text-decoration: none;
background-color: #afbfc922;
padding: 0 0.2em;
border-radius: 3px;
}
.singlePage {
margin: 4em 30vw;
@media all and (max-width: 1200px) {
margin: 25px 5vw;
}
}
.page-end {
display: flex;
flex-direction: row;
@media all and (max-width: 780px) {
flex-direction: column;
}
& > * {
flex: 1 0 0;
}
& > .backlinks-container {
& > ul {
list-style: none;
padding-left: 0;
margin-right: 2em;
& > li {
margin: 0.5em 0;
padding: 0.25em 1em;
border: var(--outlinegray) 1px solid;
border-radius: 5px
}
}
}
& #graph-container {
border: var(--outlinegray) 1px solid;
border-radius: 5px
}
}
.centered {
margin-top: 30vh;
}
header {
display: flex;
flex-direction: row;
align-items: center;
& > nav {
@media all and (max-width: 600px) {
display: none;
}
& > a {
margin-left: 2em;
}
}
& > .spacer {
flex: 1 1 auto;
}
& > svg {
cursor: pointer;
width: 18px;
min-width: 18px;
margin: 0 1em;
&:hover .search-path {
stroke: var(--tertiary);
}
.search-path {
stroke: var(--gray);
stroke-width: 2px;
transition: stroke 0.5s ease;
}
}
}
#search-container {
position: fixed;
z-index: 9999;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: none;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
& > div {
width: 50%;
margin-top: 15vh;
margin-left: auto;
margin-right: auto;
@media all and (max-width: 1200px) {
width: 90%;
}
& > * {
width: 100%;
border-radius: 4px;
background: var(--light);
box-shadow: 0 14px 50px rgba(27, 33, 48, 0.12), 0 10px 30px rgba(27, 33, 48, 0.16);
margin-bottom: 2em;
}
& > input {
box-sizing: border-box;
padding: 0.5em 1em;
font-family: Inter, sans-serif;
color: var(--dark);
font-size: 1.1em;
border: 1px solid var(--outlinegray);
&:focus {
outline: none;
}
}
& > #results-container {
& > .result-card {
padding: 1em;
cursor: pointer;
transition: background 0.2s ease;
border: 1px solid var(--outlinegray);
border-bottom: none;
&:hover {
background: rgba(180, 180, 180, 0.15);
}
&:first-of-type {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
&:last-of-type {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
border-bottom: 1px solid var(--outlinegray);
}
& > h3, & > p {
margin: 0;
}
& .search-highlight {
background-color: #afbfc966;
padding: 0.05em 0.2em;
border-radius: 3px;
}
}
}
}
}

View File

@ -1,24 +0,0 @@
// Add your own CSS here!
:root {
--light: #faf8f8;
--dark: #141021;
--secondary: #284b63;
--tertiary: #84a59d;
--visited: #afbfc9;
--primary: #f28482;
--gray: #4e4e4e;
--lightgray: #f0f0f0;
--outlinegray: #dadada;
}
[saved-theme="dark"] {
--light: #1e1e21 !important;
--dark: #fbfffe !important;
--secondary: #5b778a !important;
--visited: #4a575e !important;
--tertiary: #84a59d !important;
--primary: #f58382 !important;
--gray: #d4d4d4 !important;
--lightgray: #292633 !important;
--outlinegray: #343434 !important;
}

View File

@ -1,26 +0,0 @@
// Darkmode toggle
const toggleSwitch = document.querySelector('#darkmode-toggle')
const userPref = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'
const currentTheme = localStorage.getItem('theme') ?? userPref
if (currentTheme) {
document.documentElement.setAttribute('saved-theme', currentTheme);
if (currentTheme === 'dark') {
toggleSwitch.checked = true
}
}
const switchTheme = (e) => {
if (e.target.checked) {
document.documentElement.setAttribute('saved-theme', 'dark')
localStorage.setItem('theme', 'dark')
}
else {
document.documentElement.setAttribute('saved-theme', 'light')
localStorage.setItem('theme', 'light')
}
}
// listen for toggle
toggleSwitch.addEventListener('change', switchTheme, false)

View File

@ -1,99 +0,0 @@
/* Background */ .chroma { color: #f8f8f2; background-color: #282a36 }
/* Other */ .chroma .x { }
/* Error */ .chroma .err { }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; }
/* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #ffffcc }
/* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* Keyword */ .chroma .k { color: #ff79c6 }
/* KeywordConstant */ .chroma .kc { color: #ff79c6 }
/* KeywordDeclaration */ .chroma .kd { color: #8be9fd; font-style: italic }
/* KeywordNamespace */ .chroma .kn { color: #ff79c6 }
/* KeywordPseudo */ .chroma .kp { color: #ff79c6 }
/* KeywordReserved */ .chroma .kr { color: #ff79c6 }
/* KeywordType */ .chroma .kt { color: #8be9fd }
/* Name */ .chroma .n { }
/* NameAttribute */ .chroma .na { color: #50fa7b }
/* NameBuiltin */ .chroma .nb { color: #8be9fd; font-style: italic }
/* NameBuiltinPseudo */ .chroma .bp { }
/* NameClass */ .chroma .nc { color: #50fa7b }
/* NameConstant */ .chroma .no { }
/* NameDecorator */ .chroma .nd { }
/* NameEntity */ .chroma .ni { }
/* NameException */ .chroma .ne { }
/* NameFunction */ .chroma .nf { color: #50fa7b }
/* NameFunctionMagic */ .chroma .fm { }
/* NameLabel */ .chroma .nl { color: #8be9fd; font-style: italic }
/* NameNamespace */ .chroma .nn { }
/* NameOther */ .chroma .nx { }
/* NameProperty */ .chroma .py { }
/* NameTag */ .chroma .nt { color: #ff79c6 }
/* NameVariable */ .chroma .nv { color: #8be9fd; font-style: italic }
/* NameVariableClass */ .chroma .vc { color: #8be9fd; font-style: italic }
/* NameVariableGlobal */ .chroma .vg { color: #8be9fd; font-style: italic }
/* NameVariableInstance */ .chroma .vi { color: #8be9fd; font-style: italic }
/* NameVariableMagic */ .chroma .vm { }
/* Literal */ .chroma .l { }
/* LiteralDate */ .chroma .ld { }
/* LiteralString */ .chroma .s { color: #f1fa8c }
/* LiteralStringAffix */ .chroma .sa { color: #f1fa8c }
/* LiteralStringBacktick */ .chroma .sb { color: #f1fa8c }
/* LiteralStringChar */ .chroma .sc { color: #f1fa8c }
/* LiteralStringDelimiter */ .chroma .dl { color: #f1fa8c }
/* LiteralStringDoc */ .chroma .sd { color: #f1fa8c }
/* LiteralStringDouble */ .chroma .s2 { color: #f1fa8c }
/* LiteralStringEscape */ .chroma .se { color: #f1fa8c }
/* LiteralStringHeredoc */ .chroma .sh { color: #f1fa8c }
/* LiteralStringInterpol */ .chroma .si { color: #f1fa8c }
/* LiteralStringOther */ .chroma .sx { color: #f1fa8c }
/* LiteralStringRegex */ .chroma .sr { color: #f1fa8c }
/* LiteralStringSingle */ .chroma .s1 { color: #f1fa8c }
/* LiteralStringSymbol */ .chroma .ss { color: #f1fa8c }
/* LiteralNumber */ .chroma .m { color: #bd93f9 }
/* LiteralNumberBin */ .chroma .mb { color: #bd93f9 }
/* LiteralNumberFloat */ .chroma .mf { color: #bd93f9 }
/* LiteralNumberHex */ .chroma .mh { color: #bd93f9 }
/* LiteralNumberInteger */ .chroma .mi { color: #bd93f9 }
/* LiteralNumberIntegerLong */ .chroma .il { color: #bd93f9 }
/* LiteralNumberOct */ .chroma .mo { color: #bd93f9 }
/* Operator */ .chroma .o { color: #ff79c6 }
/* OperatorWord */ .chroma .ow { color: #ff79c6 }
/* Punctuation */ .chroma .p { }
/* Comment */ .chroma .c { color: #6272a4 }
/* CommentHashbang */ .chroma .ch { color: #6272a4 }
/* CommentMultiline */ .chroma .cm { color: #6272a4 }
/* CommentSingle */ .chroma .c1 { color: #6272a4 }
/* CommentSpecial */ .chroma .cs { color: #6272a4 }
/* CommentPreproc */ .chroma .cp { color: #ff79c6 }
/* CommentPreprocFile */ .chroma .cpf { color: #ff79c6 }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { color: #8b080b }
/* GenericEmph */ .chroma .ge { text-decoration: underline }
/* GenericError */ .chroma .gr { }
/* GenericHeading */ .chroma .gh { font-weight: bold }
/* GenericInserted */ .chroma .gi { font-weight: bold }
/* GenericOutput */ .chroma .go { color: #44475a }
/* GenericPrompt */ .chroma .gp { }
/* GenericStrong */ .chroma .gs { }
/* GenericSubheading */ .chroma .gu { font-weight: bold }
/* GenericTraceback */ .chroma .gt { }
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
/* TextWhitespace */ .chroma .w { }
.lntd:first-of-type > .chroma {
padding-right: 0;
}
.chroma code {
font-family: 'Fira Code' !important;
font-size: 0.85em;
line-height: 1em;
background: none;
padding: 0;
}
.chroma {
border-radius: 3px;
margin: 0;
}

View File

@ -1,27 +0,0 @@
baseURL = "https://quartz.jzhao.xyz/"
languageCode = "en-us"
googleAnalytics = "G-XYFD95KB4J"
pygmentsUseClasses = true
relativeURLs = true
disablePathToLower = true
ignoreFiles = [
"/content/templates/*",
"/content/private/*",
]
[markup]
[markup.tableOfContents]
endLevel = 3
ordered = true
startLevel = 2
[markup.highlight]
anchorLineNos = false
codeFences = true
guessSyntax = true
hl_Lines = ""
lineAnchors = ""
lineNoStart = 1
lineNos = true
lineNumbersInTable = true
style = "dracula"
tabWidth = 4

View File

@ -1,23 +0,0 @@
# 🌱 Quartz
## v2.0
Simple second brain and [digital garden](https://jzhao.xyz/posts/digital-gardening).
## Why Quartz?
Hosting a public digital garden isn't easy. There are an overwhelming number of tutorials, resources, and guides for tools like [Notion](https://www.notion.so/), [Roam](https://roamresearch.com/), and [Obsidian](https://obsidian.md/), yet none of them have super easy to use *free* tools to publish that garden to the world.
I've personally found that
1. It's nice to access notes from anywhere
2. Having a public digital garden invites open conversations
3. It makes keeping personal notes and knowledge *playful and fun*
> “He who works with the door open gets all kinds of interruptions, but he also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming
I was really inspired by [Bianca](https://garden.bianca.digital/) and [Joel](https://joelhooks.com/digital-garden)'s digital gardens and wanted to try making my own.
**The goal of Quartz is to make hosting your own public digital garden free and simple.** You don't even need your own website. Quartz does all of that for you and gives your own little corner of the internet.
## Get Started
The entire Quartz documentation is fully hosted using Quartz! To get started, let's visit the main directory.
👉 [Directory](moc/directory.md)

View File

@ -1,19 +0,0 @@
---
title: "Quartz Documentation"
---
## Setup
Welcome to Quartz! Whether you're setting up a website and project for the first time or a seasoned digital gardener, I hope that you'll find something useful about this project.
Let's get to business and get you started!
- 📚 [Setup your own digital garden using Quartz](notes/setup.md)
- 🔗 [Linking with an Obsidian Vault](notes/obsidian.md)
- 🎨 [Customizing and Styling Quartz](notes/config.md)
- 🌍 [Hosting Quartz online!](notes/hosting.md)
Not convinced yet? Look at some [community digital gardens](moc/showcase) built with Quartz!
## Troubleshooting
- 🚧 [Troubleshooting and FAQ](notes/troubleshooting.md)
- 🐛 [Submit an Issue](https://github.com/jackyzha0/quartz/issues)

View File

@ -1,14 +0,0 @@
---
title: "Showcase"
---
Want to see what Quartz can do? Here are some cool community gardens :)
- [Quartz Documentation (this site!)](https://quartz.jzhao.xyz/)
- [Strengthening Online Social Bonds: Research Garden](https://communities.digital/)
- [Jacky Zhao's Garden](https://garden.jzhao.xyz/)
- [Anson Yu's Garden](http://garden.ansonyu.me/)
- [Shihyu's PKM](https://shihyuho.github.io/pkm/)
- [Chloe's Garden](https://garden.chloeabrasada.online/)
If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/hugo/content/moc/showcase.md)!

View File

@ -1,45 +0,0 @@
---
title: "Configuration"
---
## Configuration
Quartz is designed to be extremely configurable. You can find the bulk of the configuration scattered throughout the repository depending on how in-depth you'd like to get.
The majority of configuration can be be found under `data/config.yaml`. An annotated example configuration is shown below.
```yaml
name: Your name here! # Shows in the footer
enableToc: true # Whether to show a Table of Contents
description: Page description to show to search engines
page_title: Quartz Example Page # Default Page Title
links: # Links to show in footer
- link_name: Twitter
link: https://twitter.com/_jzhao
- link_name: Github
link: https://github.com/jackyzha0
```
### Graph View
To customize the Interactive Graph view, you can poke around `data/graphConfig.yaml`.
```yaml
enableLegend: false # automatically generate a legend
enableDrag: true # allow dragging nodes in the graph
enableZoom: true # allow zooming and panning the graph
paths: # colour specific nodes path off of their path
- /moc: "#4388cc"
```
## Styling
Want to go even more in-depth? You can add custom CSS styling and change existing colours through editing `assets/custom.scss`. If you'd like to target specific parts of the site, you can add ids and classes to the HTML partials in `/layouts/partials`.
### Partials
Partials are what dictate what actually gets rendered to the page. Want to change how pages are styled and structured? You can edit the appropriate layout in `/layouts`.
For example, the structure of the home page can be edited through `/layouts/index.html`. To customize the footer, you can edit `/layouts/partials/footer.html`
More info about partials on [Hugo's website.](https://gohugo.io/templates/partials/)
Still having problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).

View File

@ -1,57 +0,0 @@
---
title: "Editing Content in Quartz"
---
## Editing
Quartz runs on top of [Hugo](https://gohugo.io/) so all notes are written in [Markdown](https://www.markdownguide.org/getting-started/).
### Obsidian
I *strongly* recommend using [Obsidian](http://obsidian.md/) as a way to edit and grow your digital garden. It comes with a really nice editor and graphical interface to preview all of my local files.
**🔗 [How to link your Obsidian Vault](notes/obsidian.md)**
Of course, all the files are in Markdown so you could just use your favourite text editor of choice.
### Ignoring Files
Only want to publish a subset of all of your notes? Don't worry, Quartz makes this a simple two-step process.
❌ [Excluding pages from being published](notes/ignore-notes.md)
### Folder Structure
Here's a rough overview of what's what.
**All content in your garden can found in the `/content` folder.** To make edits, you can open any of the files and make changes directly and save it. You can organize content into any folder you'd like.
**To edit the main home page, open `/content/_index.md`.** This is the home page which is slightly special. You don't need front matter here!
To create a link between notes in your garden, just create a normal link using Markdown pointing to the document in question. Please note that **all links should be relative to the root `/content` path**.
```markdown
For example, I want to link this current document to `notes/config.md`.
[A link to the config page](notes/config.md)
```
### Front Matter
Hugo is picky when it comes to metadata for files. Ensure that you have a title defined at the top of your file like so:
```markdown
---
title: "Example Title"
---
Rest of your content here...
```
## Previewing Changes
This step is purely optional and mostly for those who want to see the published version of their digital garden locally before opening it up to the internet. This is *highly recommended*.
👀 [Preview Quartz Changes](notes/preview-changes.md)
For those who like to live life more on the edge, viewing the garden through Obsidian gets you pretty close to the real thing.
## Publishing Changes
Now that you know the basics of managing your digital garden using Quartz, you can publish it to the internet!
🌍 [Hosting Quartz online!](notes/hosting.md)
Having problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).

View File

@ -1,6 +0,0 @@
---
title: "External Hosting"
---

View File

@ -1,85 +0,0 @@
---
title: "Deploying Quartz to the Web"
---
## GitHub Pages
Quartz is designed to be effortless to deploy. If you forked and cloned Quartz directly from the repository, everything should already be good to go! You can head to `<YOUR-GITHUB-USERNAME.github.io/quartz` to see it live.
### Enable GitHub Actions
By default, GitHub disables workflows from running automatically on Forked Repostories. Head to the 'Actions' tab of your forked repository and Enable Workflows to setup deploying your Quartz site!
![Enable GitHub Actions](/notes/images/github-actions.png)*Enable GitHub Actions*
### Enable GitHub Pages
Head to the 'Settings' tab of your forked repository and go to the 'Pages' tab.
1. Set the source to deploy from `master` using `/ (root)`
2. Set a custom domain here if you have one!
![Enable GitHub Pages](/notes/images/github-pages.png)*Enable GitHub Pages*
### Pushing Changes
To see your changes on the internet, we need to push it them to GitHub. Quartz is essentially a `git` repository so updating it is the same workflow as you would follow as normal.
```shell
# Navigate to Quartz folder
cd <path-to-quartz>
# Commit all changes
git add .
git commit -m "message describing changes"
# Push to GitHub to update site
git push origin hugo
```
### Setting up the Site
Now let's get this site up and running. Never hosted a site before? No problem. Have a fancy custom domain you already own or want to subdomain your Quartz? That's easy too.
Here, we take advantage of GitHub's free page hosting to deploy our site. Change `baseURL` in `/config.toml`. If you don't have a custom domain to use, you can use `<YOUR-USERNAME>.github.io` (which GitHub gives to you for free!) as your domain.
[Reference.](https://github.com/jackyzha0/quartz/blob/hugo/config.toml)
```toml
baseURL = "https://<YOUR-DOMAIN>/"
```
Change `cname` in `/.github/workflows/deploy.yaml`. Again, if you don't have a custom domain to use, you can use `<YOUR-USERNAME>.github.io`.
[Reference.](https://github.com/jackyzha0/quartz/blob/hugo/.github/workflows/deploy.yaml)
```yaml
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # this can stay as is, GitHub fills this in for us!
publish_dir: ./public
publish_branch: master
cname: <YOUR-DOMAIN>
```
### Registrar
This step is only applicable if you are using a **custom domain**! If you are using `<YOUR-USERNAME>.github.io`, you can skip this step.
For this last bit to take effect, you also need to create a CNAME record with the DNS provider you register your domain with (i.e. NameCheap, Google Domains).
GitHub has some [documentation on this](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site), but the tldr; is to
1. Go to your forked repository (`github.com/<YOUR-GITHUB-USERNAME>/quartz`) settings page and go to the Pages tab. Under "Custom domain", type your custom domain, then click **Save**.
2. Go to your DNS Provider and create a CNAME record that points from your domain to `<YOUR-GITHUB-USERNAME.github.io.` (yes, with the trailing period).
![Example Configuration for Quartz](/notes/images/google-domains.png)*Example Configuration for Quartz*
3. Wait 30 minutes to an hour for the network changes to kick in.
4. Done!
## External Hosting
Don't want to use GitHub Pages? Hugo builds everything for you! Everything is a packaged set of static files ready to deploy in `/public`. You can then upload this folder to a cloud provider to deploy. Alternatively, most providers also give users the option to link a GitHub repository and a folder to deploy. When doing this, ensure you select `/public` folder under the `master` branch.
---
Now that your Quartz is live, let's figure out how to make Quartz really *yours*!
🎨 [Customizing Quarts](notes/config.md)
Having problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).

View File

@ -1,22 +0,0 @@
---
title: "Ignoring Notes"
---
### Quartz Ignore
Edit `ignoreFiles` in `config.toml` to include paths you'd like to exclude from being rendered.
```toml
...
ignoreFiles = [
"/content/templates/*",
"/content/private/*",
"<your path here>"
]
```
`ignoreFiles` supports the use of Regular Expressions (RegEx) so you can ignore patterns as well (e.g. ignoring all `.png`s by doing `\\.png$`).
More details in [Hugo's documentation](https://gohugo.io/getting-started/configuration/#ignore-content-and-data-files-when-rendering).
### Global Ignore
However, just adding to the `ignoreFiles` will only prevent the page from being access through Quartz. If you want to prevent the file from being pushed to GitHub (for example if you have a public repository), you need to also add the path to the `.gitignore` file at the root of the repository.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,26 +0,0 @@
---
title: "Obsidian Vault Integration"
---
## Setup
Obsidian is the preferred way to use Quartz. You can either create a new Obsidian Vault or link one that your already have.
### New Vault
If you don't have an existing Vault, [download Obsidian](https://obsidian.md/) and create a new Vault in the `/content` folder that you created and cloned during the [setup](notes/setup.md).
### Linking an existing Vault
The easiest way to use an existing Vault is to copy all of our files (directory and hierarchies intact) into the `/content` folder.
## Settings
Great, now that you have your Obsidian linked to your Quartz, let's fix some settings so that they play well.
Under Options > Files and Links, set the New link format to always be Absolute Path in Vault and disabled WikiLinks so Obsidian generates regular Markdown links.
![Obsidian Settings](/notes/images/obsidian-settings.png)*Obsidian Settings*
## Templates
Inserting front matter everytime you want to create a new Note gets really annoying really quickly. Luckily, Obsidian supports templates which makes inserting new content really easily.
**If you decide to overwrite the `/content` folder completely, don't remove the `/content/templates` folder!**
Head over to Options > Core Plugins and enable the Templates plugin. Then go to Options > Hotkeys and set a hotkey for 'Insert Template'. That way, when you create a new note, you can just press the hotkey for a new template and be ready to go!

View File

@ -1,34 +0,0 @@
---
title: "Preview Changes"
---
If you'd like to preview what your Quartz site looks like before deploying it to the internet, here's exactly how to do that!
## Install `hugo-obsidian`
This step will generate the list of backlinks for Hugo to parse. Ensure you have [Go](https://golang.org/doc/install) (>= 1.16) installed.
```shell
# Install and link `hugo-obsidian` locally
$ go install github.com/jackyzha0/hugo-obsidian
# Navigate to your local Quartz folder
$ cd <location-of-your-local-quartz>
# Scrape all links in your Quartz folder and generate info for Quartz
$ hugo-obsidian -input=content -output=data -index=true
```
Afterwards, start the Hugo server as shown above and your local backlinks and interactive graph should be populated!
## Installing Hugo
Hugo is the static site generator that powers Quartz. If you'd like to preview your site locally, [install Hugo](https://gohugo.io/getting-started/installing/).
```
# Navigate to your local Quartz folder
$ cd <location-of-your-local-quartz>
# Start local server
$ hugo server
# View your site in a browser at http://localhost:1313/
```

View File

@ -1,29 +0,0 @@
---
title: "Setup"
---
## Making your own Quartz
Setting up Quartz requires a basic understanding of `git`. If you are unfamiliar, [this resource](https://resources.nwplus.io/2-beginner/how-to-git-github.html) is a great place to start!
### Forking
> A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.
Navigate to the GitHub repository for the Quartz project:
📁 [Quartz Repository](https://github.com/jackyzha0/quartz)
Then, Fork the repository into your own GitHub account. If you don't have an account, you can make on for free [here](https://github.com/join). More details about forking a repo can be found on [GitHub's documentation](https://docs.github.com/en/get-started/quickstart/fork-a-repo).
### Cloning
After you've made a fork of the repository, you need to download the files locally onto your machine. Ensure you have `git`, then type the following command replacing `YOUR-USERNAME` with your GitHub username.
```shell
$ git clone https://github.com/YOUR-USERNAME/quartz
```
## Editing
Great! Now you have everything you need to start editing and growing your digital garden. If you're ready to start writing content already, check out the recommended flow for editing notes in Quartz.
✏️ [Editing Notes in Quartz](notes/editing.md)
Having problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).

View File

@ -1,59 +0,0 @@
---
title: "Troubleshooting and FAQ"
---
## Common Pitfalls
### Can I publish only a subset of my pages?
Yes! Quartz makes selective publishing really easy. Heres a guide on [excluding pages from being published](notes/ignore-notes.md).
### Can I host this myself and not on GitHub Pages?
Yes! All built files can be found under `/public` in the `master` branch. More details under [hosting](notes/hosting.md).
### Do I need a website already?
No! Setting up Quartz means you set up a site too :)
### `command not found: hugo-obsidian`
Make sure you set your `GOPATH` correctly! This will allow your terminal to correctly recognize `hugo-obsidian` as an executable.
```shell
# Add the following 2 lines to your ~/.bash_profile
export GOPATH=/Users/$USER/go
export PATH=$GOPATH/bin:$PATH
# In your current terminal, to reload the session
source ~/.bash_profile
```
### How come my notes aren't being rendered?
You probably forgot to include front matter in your Markdown files. You can either setup [Obsidian](notes/obsidian) to do this for you or you need to manually define it. More details in [the 'how to edit' guide](notes/editing.md).
### My custom domain isn't working!
Walk through the steps in [the hosting guide](notes/hosting.md) again. Make sure you wait 30 min to 1 hour for changes to take effect.
### How do I setup Google Analytics?
You can edit it in `config.toml` and either use a V3 (UA-) or V4 (G-) tag.
### How do I change the content on the home page?
To edit the main home page, open `/content/_index.md`.
### How do I change the colours?
You can change the theme by editing `assets/custom.scss`. More details on customization and themeing can be found in the [customization guide](notes/config.md).
### How do I add images?
You can put images anywhere in the `/content` folder. The only caveat is that you should reference them in your Markdown by prefixing it with a `/`.
```markdown
Example image (source is in content/notes/images/example.png)
![Example Image](/content/notes/images/example.png)
```
### My Interactive Graph and Backlinks aren't up to date
By default, the `linkIndex.yaml` (which Quartz needs to generate the Interactive Graph and Backlinks) are not regenerated locally. To set that up, see the guide on [local editing](notes/editing.md)
### Can I use React/Vue/some other framework?
Not out of the box. You could probably make it work by editing `/layouts/_default/single.html` but that's not what Quartz is designed to work with. 99% of things you are trying to do with those frameworks you can accomplish perfectly fine using just vanilla HTML/CSS/JS.
## Still Stuck?
Quartz isn't perfect! If you're still having troubles, file an issue in the GitHub repo with as much information as you can reasonably provide. Alternatively, you can message me on [Twitter](https://twitter.com/_jzhao) and I'll try to get back to you as soon as I can.
🐛 [Submit an Issue](https://github.com/jackyzha0/quartz/issues)

View File

@ -1,5 +0,0 @@
---
title: "Private Stuff"
---
This page doesn't get published!

View File

@ -1,3 +0,0 @@
---
title: "{{title}}"
---

View File

@ -1,12 +0,0 @@
name: Jacky Zhao
enableToc: true
description:
Here is the page description. This is an example Quartz site that details installation,
setup, customization, and troubleshooting for Quartz itself.
page_title:
Quartz Example Page
links:
- link_name: Twitter
link: https://twitter.com/_jzhao
- link_name: Github
link: https://github.com/jackyzha0

View File

@ -1,5 +0,0 @@
enableLegend: false
enableDrag: true
enableZoom: true
paths:
- /moc: "#4388cc"

23
docker-compose.yml Normal file
View File

@ -0,0 +1,23 @@
version: '3'
services:
quartz:
image: node:20-slim
working_dir: /usr/src/app
volumes:
- ./:/usr/src/app
ports:
- "3000:3000"
command: ["npx", "quartz", "build", "--serve", "--port", "3000"]
labels:
- "traefik.enable=true"
- "traefik.http.routers.quartz.rule=Host(`notes.velouria.dev`)"
- "traefik.http.routers.quartz.entrypoints=websecure"
- "traefik.http.routers.quartz.tls.certresolver=myresolver"
- "traefik.http.services.quartz.loadbalancer.server.port=3000"
networks:
- traefik_network
networks:
traefik_network:
external: true

View File

@ -0,0 +1,52 @@
---
title: Architecture
---
Quartz is a static site generator. How does it work?
This question is best answered by tracing what happens when a user (you!) runs `npx quartz build` in the command line:
## On the server
1. After running `npx quartz build`, npm will look at `package.json` to find the `bin` entry for `quartz` which points at `./quartz/bootstrap-cli.mjs`.
2. This file has a [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>) line at the top which tells npm to execute it using Node.
3. `bootstrap-cli.mjs` is responsible for a few things:
1. Parsing the command-line arguments using [yargs](http://yargs.js.org/).
2. Transpiling and bundling the rest of Quartz (which is in Typescript) to regular JavaScript using [esbuild](https://esbuild.github.io/). The `esbuild` configuration here is slightly special as it also handles `.scss` file imports using [esbuild-sass-plugin v2](https://www.npmjs.com/package/esbuild-sass-plugin). Additionally, we bundle 'inline' client-side scripts (any `.inline.ts` file) that components declare using a custom `esbuild` plugin that runs another instance of `esbuild` which bundles for the browser instead of `node`. Modules of both types are imported as plain text.
3. Running the local preview server if `--serve` is set. This starts two servers:
1. A WebSocket server on port 3001 to handle hot-reload signals. This tracks all inbound connections and sends a 'rebuild' message a server-side change is detected (either content or configuration).
2. An HTTP file-server on a user defined port (normally 8080) to serve the actual website files.
4. If the `--serve` flag is set, it also starts a file watcher to detect source-code changes (e.g. anything that is `.ts`, `.tsx`, `.scss`, or packager files). On a change, we rebuild the module (step 2 above) using esbuild's [rebuild API](https://esbuild.github.io/api/#rebuild) which drastically reduces the build times.
5. After transpiling the main Quartz build module (`quartz/build.ts`), we write it to a cache file `.quartz-cache/transpiled-build.mjs` and then dynamically import this using `await import(cacheFile)`. However, we need to be pretty smart about how to bust Node's [import cache](https://github.com/nodejs/modules/issues/307) so we add a random query string to fake Node into thinking it's a new module. This does, however, cause memory leaks so we just hope that the user doesn't hot-reload their configuration too many times in a single session :)) (it leaks about ~350kB memory on each reload). After importing the module, we then invoke it, passing in the command line arguments we parsed earlier along with a callback function to signal the client to refresh.
4. In `build.ts`, we start by installing source map support manually to account for the query string cache busting hack we introduced earlier. Then, we start processing content:
1. Clean the output directory.
2. Recursively glob all files in the `content` folder, respecting the `.gitignore`.
3. Parse the Markdown files.
1. Quartz detects the number of threads available and chooses to spawn worker threads if there are >128 pieces of content to parse (rough heuristic). If it needs to spawn workers, it will invoke esbuild again to transpile the worker script `quartz/worker.ts`. Then, a work-stealing [workerpool](https://www.npmjs.com/package/workerpool) is then created and batches of 128 files are assigned to workers.
2. Each worker (or just the main thread if there is no concurrency) creates a [unified](https://github.com/unifiedjs/unified) parser based off of the plugins defined in the [[configuration]].
3. Parsing has three steps:
1. Read the file into a [vfile](https://github.com/vfile/vfile).
2. Applied plugin-defined text transformations over the content.
3. Slugify the file path and store it in the data for the file. See the page on [[paths]] for more details about how path logic works in Quartz (spoiler: its complicated).
4. Markdown parsing using [remark-parse](https://www.npmjs.com/package/remark-parse) (text to [mdast](https://github.com/syntax-tree/mdast)).
5. Apply plugin-defined Markdown-to-Markdown transformations.
6. Convert Markdown into HTML using [remark-rehype](https://github.com/remarkjs/remark-rehype) ([mdast](https://github.com/syntax-tree/mdast) to [hast](https://github.com/syntax-tree/hast)).
7. Apply plugin-defined HTML-to-HTML transformations.
4. Filter out unwanted content using plugins.
5. Emit files using plugins.
1. Gather all the static resources (e.g. external CSS, JS modules, etc.) each emitter plugin declares.
2. Emitters that emit HTML files do a bit of extra work here as they need to transform the [hast](https://github.com/syntax-tree/hast) produced in the parse step to JSX. This is done using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) with the [Preact](https://preactjs.com/) runtime. Finally, the JSX is rendered to HTML using [preact-render-to-string](https://github.com/preactjs/preact-render-to-string) which statically renders the JSX to HTML (i.e. doesn't care about `useState`, `useEffect`, or any other React/Preact interactive bits). Here, we also do a bunch of fun stuff like assemble the page [[layout]] from `quartz.layout.ts`, assemble all the inline scripts that actually get shipped to the client, and all the transpiled styles. The bulk of this logic can be found in `quartz/components/renderPage.tsx`. Other fun things of note:
1. CSS is minified and transformed using [Lightning CSS](https://github.com/parcel-bundler/lightningcss) to add vendor prefixes and do syntax lowering.
2. Scripts are split into `beforeDOMLoaded` and `afterDOMLoaded` and are inserted in the `<head>` and `<body>` respectively.
3. Finally, each emitter plugin is responsible for emitting and writing it's own emitted files to disk.
6. If the `--serve` flag was detected, we also set up another file watcher to detect content changes (only `.md` files). We keep a content map that tracks the parsed AST and plugin data for each slug and update this on file changes. Newly added or modified paths are rebuilt and added to the content map. Then, all the filters and emitters are run over the resulting content map. This file watcher is debounced with a threshold of 250ms. On success, we send a client refresh signal using the passed in callback function.
## On the client
1. The browser opens a Quartz page and loads the HTML. The `<head>` also links to page styles (emitted to `public/index.css`) and page-critical JS (emitted to `public/prescript.js`)
2. Then, once the body is loaded, the browser loads the non-critical JS (emitted to `public/postscript.js`)
3. Once the page is done loading, the page will then dispatch a custom synthetic browser event `"nav"`. This is used so client-side scripts declared by components can 'setup' anything that requires access to the page DOM.
1. If the [[SPA Routing|enableSPA option]] is enabled in the [[configuration]], this `"nav"` event is also fired on any client-navigation to allow for components to unregister and reregister any event handlers and state.
2. If it's not, we wire up the `"nav"` event to just be fired a single time after page load to allow for consistency across how state is setup across both SPA and non-SPA contexts.
The architecture and design of the plugin system was intentionally left pretty vague here as this is described in much more depth in the guide on [[making plugins|making your own plugin]].

View File

@ -0,0 +1,233 @@
---
title: Creating your own Quartz components
---
> [!warning]
> This guide assumes you have experience writing JavaScript and are familiar with TypeScript.
Normally on the web, we write layout code using HTML which looks something like the following:
```html
<article>
<h1>An article header</h1>
<p>Some content</p>
</article>
```
This piece of HTML represents an article with a leading header that says "An article header" and a paragraph that contains the text "Some content". This is combined with CSS to style the page and JavaScript to add interactivity.
However, HTML doesn't let you create reusable templates. If you wanted to create a new page, you would need to copy and paste the above snippet and edit the header and content yourself. This isn't great if we have a lot of content on our site that shares a lot of similar layout. The smart people who created React also had similar complaints and invented the concept of Components -- JavaScript functions that return JSX -- to solve the code duplication problem.
In effect, components allow you to write a JavaScript function that takes some data and produces HTML as an output. **While Quartz doesn't use React, it uses the same component concept to allow you to easily express layout templates in your Quartz site.**
## An Example Component
### Constructor
Component files are written in `.tsx` files that live in the `quartz/components` folder. These are re-exported in `quartz/components/index.ts` so you can use them in layouts and other components more easily.
Each component file should have a default export that satisfies the `QuartzComponentConstructor` function signature. It's a function that takes in a single optional parameter `opts` and returns a Quartz Component. The type of the parameters `opts` is defined by the interface `Options` which you as the component creator also decide.
In your component, you can use the values from the configuration option to change the rendering behaviour inside of your component. For example, the component in the code snippet below will not render if the `favouriteNumber` option is below 0.
```tsx {11-17}
interface Options {
favouriteNumber: number
}
const defaultOptions: Options = {
favouriteNumber: 42,
}
export default ((userOpts?: Options) => {
const opts = { ...userOpts, ...defaultOpts }
function YourComponent(props: QuartzComponentProps) {
if (opts.favouriteNumber < 0) {
return null
}
return <p>My favourite number is {opts.favouriteNumber}</p>
}
return YourComponent
}) satisfies QuartzComponentConstructor
```
### Props
The Quartz component itself (lines 11-17 highlighted above) looks like a React component. It takes in properties (sometimes called [props](https://react.dev/learn/passing-props-to-a-component)) and returns JSX.
All Quartz components accept the same set of props:
```tsx title="quartz/components/types.ts"
// simplified for sake of demonstration
export type QuartzComponentProps = {
fileData: QuartzPluginData
cfg: GlobalConfiguration
tree: Node<QuartzPluginData>
allFiles: QuartzPluginData[]
displayClass?: "mobile-only" | "desktop-only"
}
```
- `fileData`: Any metadata [[making plugins|plugins]] may have added to the current page.
- `fileData.slug`: slug of the current page.
- `fileData.frontmatter`: any frontmatter parsed.
- `cfg`: The `configuration` field in `quartz.config.ts`.
- `tree`: the resulting [HTML AST](https://github.com/syntax-tree/hast) after processing and transforming the file. This is useful if you'd like to render the content using [hast-util-to-jsx-runtime](https://github.com/syntax-tree/hast-util-to-jsx-runtime) (you can find an example of this in `quartz/components/pages/Content.tsx`).
- `allFiles`: Metadata for all files that have been parsed. Useful for doing page listings or figuring out the overall site structure.
- `displayClass`: a utility class that indicates a preference from the user about how to render it in a mobile or desktop setting. Helpful if you want to conditionally hide a component on mobile or desktop.
### Styling
Quartz components can also define a `.css` property on the actual function component which will get picked up by Quartz. This is expected to be a CSS string which can either be inlined or imported from a `.scss` file.
Note that inlined styles **must** be plain vanilla CSS:
```tsx {6-10} title="quartz/components/YourComponent.tsx"
export default (() => {
function YourComponent() {
return <p class="red-text">Example Component</p>
}
YourComponent.css = `
p.red-text {
color: red;
}
`
return YourComponent
}) satisfies QuartzComponentConstructor
```
Imported styles, however, can be from SCSS files:
```tsx {1-2,9} title="quartz/components/YourComponent.tsx"
// assuming your stylesheet is in quartz/components/styles/YourComponent.scss
import styles from "./styles/YourComponent.scss"
export default (() => {
function YourComponent() {
return <p>Example Component</p>
}
YourComponent.css = styles
return YourComponent
}) satisfies QuartzComponentConstructor
```
> [!warning]
> Quartz does not use CSS modules so any styles you declare here apply _globally_. If you only want it to apply to your component, make sure you use specific class names and selectors.
### Scripts and Interactivity
What about interactivity? Suppose you want to add an-click handler for example. Like the `.css` property on the component, you can also declare `.beforeDOMLoaded` and `.afterDOMLoaded` properties that are strings that contain the script.
```tsx title="quartz/components/YourComponent.tsx"
export default (() => {
function YourComponent() {
return <button id="btn">Click me</button>
}
YourComponent.beforeDOM = `
console.log("hello from before the page loads!")
`
YourComponent.afterDOM = `
document.getElementById('btn').onclick = () => {
alert('button clicked!')
}
`
return YourComponent
}) satisfies QuartzComponentConstructor
```
> [!hint]
> For those coming from React, Quartz components are different from React components in that it only uses JSX for templating and layout. Hooks like `useEffect`, `useState`, etc. are not rendered and other properties that accept functions like `onClick` handlers will not work. Instead, do it using a regular JS script that modifies the DOM element directly.
As the names suggest, the `.beforeDOMLoaded` scripts are executed _before_ the page is done loading so it doesn't have access to any elements on the page. This is mostly used to prefetch any critical data.
The `.afterDOMLoaded` script executes once the page has been completely loaded. This is a good place to setup anything that should last for the duration of a site visit (e.g. getting something saved from local storage).
If you need to create an `afterDOMLoaded` script that depends on _page specific_ elements that may change when navigating to a new page, you can listen for the `"nav"` event that gets fired whenever a page loads (which may happen on navigation if [[SPA Routing]] is enabled).
```ts
document.addEventListener("nav", () => {
// do page specific logic here
// e.g. attach event listeners
const toggleSwitch = document.querySelector("#switch") as HTMLInputElement
toggleSwitch.removeEventListener("change", switchTheme)
toggleSwitch.addEventListener("change", switchTheme)
})
```
It is best practice to also unmount any existing event handlers to prevent memory leaks.
#### Importing Code
Of course, it isn't always practical (nor desired!) to write your code as a string literal in the component.
Quartz supports importing component code through `.inline.ts` files.
```tsx title="quartz/components/YourComponent.tsx"
// @ts-ignore: typescript doesn't know about our inline bundling system
// so we need to silence the error
import script from "./scripts/graph.inline"
export default (() => {
function YourComponent() {
return <button id="btn">Click me</button>
}
YourComponent.afterDOM = script
return YourComponent
}) satisfies QuartzComponentConstructor
```
```ts title="quartz/components/scripts/graph.inline.ts"
// any imports here are bundled for the browser
import * as d3 from "d3"
document.getElementById("btn").onclick = () => {
alert("button clicked!")
}
```
Additionally, like what is shown in the example above, you can import packages in `.inline.ts` files. This will be bundled by Quartz and included in the actual script.
### Using a Component
After creating your custom component, re-export it in `quartz/components/index.ts`:
```ts title="quartz/components/index.ts" {4,10}
import ArticleTitle from "./ArticleTitle"
import Content from "./pages/Content"
import Darkmode from "./Darkmode"
import YourComponent from "./YourComponent"
export { ArticleTitle, Content, Darkmode, YourComponent }
```
Then, you can use it like any other component in `quartz.layout.ts` via `Component.YourComponent()`. See the [[configuration#Layout|layout]] section for more details.
As Quartz components are just functions that return React components, you can compositionally use them in other Quartz components.
```tsx title="quartz/components/AnotherComponent.tsx"
import YourComponent from "./YourComponent"
export default (() => {
function AnotherComponent(props: QuartzComponentProps) {
return (
<div>
<p>It's nested!</p>
<YourComponent {...props} />
</div>
)
}
return AnotherComponent
}) satisfies QuartzComponentConstructor
```
> [!hint]
> Look in `quartz/components` for more examples of components in Quartz as reference for your own components!

3
docs/advanced/index.md Normal file
View File

@ -0,0 +1,3 @@
---
title: "Advanced"
---

View File

@ -0,0 +1,302 @@
---
title: Making your own plugins
---
> [!warning]
> This part of the documentation will assume you have working knowledge in TypeScript and will include code snippets that describe the interface of what Quartz plugins should look like.
Quartz's plugins are a series of transformations over content. This is illustrated in the diagram of the processing pipeline below:
![[quartz transform pipeline.png]]
All plugins are defined as a function that takes in a single parameter for options `type OptionType = object | undefined` and return an object that corresponds to the type of plugin it is.
```ts
type OptionType = object | undefined
type QuartzPlugin<Options extends OptionType = undefined> = (opts?: Options) => QuartzPluginInstance
type QuartzPluginInstance =
| QuartzTransformerPluginInstance
| QuartzFilterPluginInstance
| QuartzEmitterPluginInstance
```
The following sections will go into detail for what methods can be implemented for each plugin type. Before we do that, let's clarify a few more ambiguous types:
- `BuildCtx` is defined in `quartz/ctx.ts`. It consists of
- `argv`: The command line arguments passed to the Quartz [[build]] command
- `cfg`: The full Quartz [[configuration]]
- `allSlugs`: a list of all the valid content slugs (see [[paths]] for more information on what a `ServerSlug` is)
- `StaticResources` is defined in `quartz/resources.tsx`. It consists of
- `css`: a list of URLs for stylesheets that should be loaded
- `js`: a list of scripts that should be loaded. A script is described with the `JSResource` type which is also defined in `quartz/resources.tsx`. It allows you to define a load time (either before or after the DOM has been loaded), whether it should be a module, and either the source URL or the inline content of the script.
## Transformers
Transformers **map** over content, taking a Markdown file and outputting modified content or adding metadata to the file itself.
```ts
export type QuartzTransformerPluginInstance = {
name: string
textTransform?: (ctx: BuildCtx, src: string | Buffer) => string | Buffer
markdownPlugins?: (ctx: BuildCtx) => PluggableList
htmlPlugins?: (ctx: BuildCtx) => PluggableList
externalResources?: (ctx: BuildCtx) => Partial<StaticResources>
}
```
All transformer plugins must define at least a `name` field to register the plugin and a few optional functions that allow you to hook into various parts of transforming a single Markdown file.
- `textTransform` performs a text-to-text transformation _before_ a file is parsed into the [Markdown AST](https://github.com/syntax-tree/mdast).
- `markdownPlugins` defines a list of [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md). `remark` is a tool that transforms Markdown to Markdown in a structured way.
- `htmlPlugins` defines a list of [rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md). Similar to how `remark` works, `rehype` is a tool that transforms HTML to HTML in a structured way.
- `externalResources` defines any external resources the plugin may need to load on the client-side for it to work properly.
Normally for both `remark` and `rehype`, you can find existing plugins that you can use to . If you'd like to create your own `remark` or `rehype` plugin, checkout the [guide to creating a plugin](https://unifiedjs.com/learn/guide/create-a-plugin/) using `unified` (the underlying AST parser and transformer library).
A good example of a transformer plugin that borrows from the `remark` and `rehype` ecosystems is the [[Latex]] plugin:
```ts title="quartz/plugins/transformers/latex.ts"
import remarkMath from "remark-math"
import rehypeKatex from "rehype-katex"
import rehypeMathjax from "rehype-mathjax/svg.js"
import { QuartzTransformerPlugin } from "../types"
interface Options {
renderEngine: "katex" | "mathjax"
}
export const Latex: QuartzTransformerPlugin<Options> = (opts?: Options) => {
const engine = opts?.renderEngine ?? "katex"
return {
name: "Latex",
markdownPlugins() {
return [remarkMath]
},
htmlPlugins() {
if (engine === "katex") {
// if you need to pass options into a plugin, you
// can use a tuple of [plugin, options]
return [[rehypeKatex, { output: "html" }]]
} else {
return [rehypeMathjax]
}
},
externalResources() {
if (engine === "katex") {
return {
css: ["https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css"],
js: [
{
src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js",
loadTime: "afterDOMReady",
contentType: "external",
},
],
}
} else {
return {}
}
},
}
}
```
Another common thing that transformer plugins will do is parse a file and add extra data for that file:
```ts
export const AddWordCount: QuartzTransformerPlugin = () => {
return {
name: "AddWordCount",
markdownPlugins() {
return [
() => {
return (tree, file) => {
// tree is an `mdast` root element
// file is a `vfile`
const text = file.value
const words = text.split(" ").length
file.data.wordcount = words
}
},
]
},
}
}
// tell typescript about our custom data fields we are adding
// other plugins will then also be aware of this data field
declare module "vfile" {
interface DataMap {
wordcount: number
}
}
```
Finally, you can also perform transformations over Markdown or HTML ASTs using the `visit` function from the `unist-util-visit` package or the `findAndReplace` function from the `mdast-util-find-and-replace` package.
```ts
export const TextTransforms: QuartzTransformerPlugin = () => {
return {
name: "TextTransforms",
markdownPlugins() {
return [() => {
return (tree, file) => {
// replace _text_ with the italics version
findAndReplace(tree, /_(.+)_/, (_value: string, ...capture: string[]) => {
// inner is the text inside of the () of the regex
const [inner] = capture
// return an mdast node
// https://github.com/syntax-tree/mdast
return {
type: "emphasis",
children: [{ type: 'text', value: inner }]
}
})
// remove all links (replace with just the link content)
// match by 'type' field on an mdast node
// https://github.com/syntax-tree/mdast#link in this example
visit(tree, "link", (link: Link) => {
return {
type: "paragraph"
children: [{ type: 'text', value: link.title }]
}
})
}
}]
}
}
}
```
All transformer plugins can be found under `quartz/plugins/transformers`. If you decide to write your own transformer plugin, don't forget to re-export it under `quartz/plugins/transformers/index.ts`
A parting word: transformer plugins are quite complex so don't worry if you don't get them right away. Take a look at the built in transformers and see how they operate over content to get a better sense for how to accomplish what you are trying to do.
## Filters
Filters **filter** content, taking the output of all the transformers and determining what files to actually keep and what to discard.
```ts
export type QuartzFilterPlugin<Options extends OptionType = undefined> = (
opts?: Options,
) => QuartzFilterPluginInstance
export type QuartzFilterPluginInstance = {
name: string
shouldPublish(ctx: BuildCtx, content: ProcessedContent): boolean
}
```
A filter plugin must define a `name` field and a `shouldPublish` function that takes in a piece of content that has been processed by all the transformers and returns a `true` or `false` depending on whether it should be passed to the emitter plugins or not.
For example, here is the built-in plugin for removing drafts:
```ts title="quartz/plugins/filters/draft.ts"
import { QuartzFilterPlugin } from "../types"
export const RemoveDrafts: QuartzFilterPlugin<{}> = () => ({
name: "RemoveDrafts",
shouldPublish(_ctx, [_tree, vfile]) {
// uses frontmatter parsed from transformers
const draftFlag: boolean = vfile.data?.frontmatter?.draft ?? false
return !draftFlag
},
})
```
## Emitters
Emitters **reduce** over content, taking in a list of all the transformed and filtered content and creating output files.
```ts
export type QuartzEmitterPlugin<Options extends OptionType = undefined> = (
opts?: Options,
) => QuartzEmitterPluginInstance
export type QuartzEmitterPluginInstance = {
name: string
emit(
ctx: BuildCtx,
content: ProcessedContent[],
resources: StaticResources,
emitCallback: EmitCallback,
): Promise<FilePath[]>
getQuartzComponents(ctx: BuildCtx): QuartzComponent[]
}
```
An emitter plugin must define a `name` field an `emit` function and a `getQuartzComponents` function. `emit` is responsible for looking at all the parsed and filtered content and then appropriately creating files and returning a list of paths to files the plugin created.
Creating new files can be done via regular Node [fs module](https://nodejs.org/api/fs.html) (i.e. `fs.cp` or `fs.writeFile`) or via the `emitCallback` if you are creating files that contain text. The `emitCallback` function is the 4th argument of the emit function. Its interface looks something like this:
```ts
export type EmitCallback = (data: {
// the name of the file to emit (not including the file extension)
slug: ServerSlug
// the file extension
ext: `.${string}` | ""
// the file content to add
content: string
}) => Promise<FilePath>
```
This is a thin wrapper around writing to the appropriate output folder and ensuring that intermediate directories exist. If you choose to use the native Node `fs` APIs, ensure you emit to the `argv.output` folder as well.
If you are creating an emitter plugin that needs to render components, there are three more things to be aware of:
- Your component should use `getQuartzComponents` to declare a list of `QuartzComponents` that it uses to construct the page. See the page on [[creating components]] for more information.
- You can use the `renderPage` function defined in `quartz/components/renderPage.tsx` to render Quartz components into HTML.
- If you need to render an HTML AST to JSX, you can use the `htmlToJsx` function from `quartz/util/jsx.ts`. An example of this can be found in `quartz/components/pages/Content.tsx`.
For example, the following is a simplified version of the content page plugin that renders every single page.
```tsx title="quartz/plugins/emitters/contentPage.tsx"
export const ContentPage: QuartzEmitterPlugin = () => {
// construct the layout
const layout: FullPageLayout = {
...sharedPageComponents,
...defaultContentPageLayout,
pageBody: Content(),
}
const { head, header, beforeBody, pageBody, left, right, footer } = layout
return {
name: "ContentPage",
getQuartzComponents() {
return [head, ...header, ...beforeBody, pageBody, ...left, ...right, footer]
},
async emit(ctx, content, resources, emit): Promise<FilePath[]> {
const cfg = ctx.cfg.configuration
const fps: FilePath[] = []
const allFiles = content.map((c) => c[1].data)
for (const [tree, file] of content) {
const slug = canonicalizeServer(file.data.slug!)
const externalResources = pageResources(slug, resources)
const componentData: QuartzComponentProps = {
fileData: file.data,
externalResources,
cfg,
children: [],
tree,
allFiles,
}
const content = renderPage(slug, componentData, opts, externalResources)
const fp = await emit({
content,
slug: file.data.slug!,
ext: ".html",
})
fps.push(fp)
}
return fps
},
}
}
```
Note that it takes in a `FullPageLayout` as the options. It's made by combining a `SharedLayout` and a `PageLayout` both of which are provided through the `quartz.layout.ts` file.
> [!hint]
> Look in `quartz/plugins` for more examples of plugins in Quartz as reference for your own plugins!

51
docs/advanced/paths.md Normal file
View File

@ -0,0 +1,51 @@
---
title: Paths in Quartz
---
Paths are pretty complex to reason about because, especially for a static site generator, they can come from so many places.
A full file path to a piece of content? Also a path. What about a slug for a piece of content? Yet another path.
It would be silly to type these all as `string` and call it a day as it's pretty common to accidentally mistake one type of path for another. Unfortunately, TypeScript does not have [nominal types](https://en.wikipedia.org/wiki/Nominal_type_system) for type aliases meaning even if you made custom types of a server-side slug or a client-slug slug, you can still accidentally assign one to another and TypeScript wouldn't catch it.
Luckily, we can mimic nominal typing using [brands](https://www.typescriptlang.org/play#example/nominal-typing).
```typescript
// instead of
type FullSlug = string
// we do
type FullSlug = string & { __brand: "full" }
// that way, the following will fail typechecking
const slug: FullSlug = "some random string"
```
While this prevents most typing mistakes _within_ our nominal typing system (e.g. mistaking a server slug for a client slug), it doesn't prevent us from _accidentally_ mistaking a string for a client slug when we forcibly cast it.
Thus, we still need to be careful when casting from a string to one of these nominal types in the 'entrypoints', illustrated with hexagon shapes in the diagram below.
The following diagram draws the relationships between all the path sources, nominal path types, and what functions in `quartz/path.ts` convert between them.
```mermaid
graph LR
Browser{{Browser}} --> Window{{Body}} & LinkElement{{Link Element}}
Window --"getFullSlug()"--> FullSlug[Full Slug]
LinkElement --".href"--> Relative[Relative URL]
FullSlug --"simplifySlug()" --> SimpleSlug[Simple Slug]
SimpleSlug --"pathToRoot()"--> Relative
SimpleSlug --"resolveRelative()" --> Relative
MD{{Markdown File}} --> FilePath{{File Path}} & Links[Markdown links]
Links --"transformLink()"--> Relative
FilePath --"slugifyFilePath()"--> FullSlug[Full Slug]
style FullSlug stroke-width:4px
```
Here are the main types of slugs with a rough description of each type of path:
- `FilePath`: a real file path to a file on disk. Cannot be relative and must have a file extension.
- `FullSlug`: cannot be relative and may not have leading or trailing slashes. It can have `index` as it's last segment. Use this wherever possible is it's the most 'general' interpretation of a slug.
- `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`.

48
docs/authoring content.md Normal file
View File

@ -0,0 +1,48 @@
---
title: Authoring Content
---
All of the content in your Quartz should go in the `/content` folder. The content for the home page of your Quartz lives in `content/index.md`. If you've [[index#🪴 Get Started|setup Quartz]] already, this folder should already be initailized. Any Markdown in this folder will get processed by Quartz.
It is recommended that you use [Obsidian](https://obsidian.md/) as a way to edit and maintain your Quartz. It comes with a nice editor and graphical interface to preview, edit, and link your local files and attachments.
Got everything setup? Let's [[build]] and preview your Quartz locally!
## Syntax
As Quartz uses Markdown files as the main way of writing content, it fully supports Markdown syntax. By default, Quartz also ships with a few syntax extensions like [Github Flavored Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax) (footnotes, strikethrough, tables, tasklists) and [Obsidian Flavored Markdown](https://help.obsidian.md/Editing+and+formatting/Obsidian+Flavored+Markdown) ([[callouts]], [[wikilinks]]).
Additionally, Quartz also allows you to specify additional metadata in your notes called **frontmatter**.
```md title="content/note.md"
---
title: Example Title
draft: false
tags:
- example-tag
---
The rest of your content lives here. You can use **Markdown** here :)
```
Some common frontmatter fields that are natively supported by Quartz:
- `title`: Title of the page. If it isn't provided, Quartz will use the name of the file as the title.
- `aliases`: Other names for this note. This is a list of strings.
- `draft`: Whether to publish the page or not. This is one way to make [[private pages|pages private]] in Quartz.
- `date`: A string representing the day the note was published. Normally uses `YYYY-MM-DD` format.
## Syncing your Content
When your Quartz is at a point you're happy with, you can save your changes to GitHub by doing `npx quartz sync`.
> [!hint] Flags and options
> For full help options, you can run `npx quartz sync --help`.
>
> Most of these have sensible defaults but you can override them if you have a custom setup:
>
> - `-d` or `--directory`: the content folder. This is normally just `content`
> - `-v` or `--verbose`: print out extra logging information
> - `--commit` or `--no-commit`: whether to make a `git` commit for your changes
> - `--push` or `--no-push`: whether to push updates to your GitHub fork of Quartz
> - `--pull` or `--no-pull`: whether to try and pull in any updates from your GitHub fork (i.e. from other devices) before pushing

23
docs/build.md Normal file
View File

@ -0,0 +1,23 @@
---
title: "Building your Quartz"
---
Once you've [[index#🪴 Get Started|initialized]] Quartz, let's see what it looks like locally:
```bash
npx quartz build --serve
```
This will start a local web server to run your Quartz on your computer. Open a web browser and visit `http://localhost:8080/` to view it.
> [!hint] Flags and options
> For full help options, you can run `npx quartz build --help`.
>
> Most of these have sensible defaults but you can override them if you have a custom setup:
>
> - `-d` or `--directory`: the content folder. This is normally just `content`
> - `-v` or `--verbose`: print out extra logging information
> - `-o` or `--output`: the output folder. This is normally just `public`
> - `--serve`: run a local hot-reloading server to preview your Quartz
> - `--port`: what port to run the local preview server on
> - `--concurrency`: how many threads to use to parse notes

82
docs/configuration.md Normal file
View File

@ -0,0 +1,82 @@
---
title: Configuration
---
Quartz is meant to be extremely configurable, even if you don't know any coding. Most of the configuration you should need can be done by just editing `quartz.config.ts` or changing [[layout|the layout]] in `quartz.layout.ts`.
> [!tip]
> If you edit Quartz configuration using a text-editor that has TypeScript language support like VSCode, it will warn you when you you've made an error in your configuration, helping you avoid configuration mistakes!
The configuration of Quartz can be broken down into two main parts:
```ts title="quartz.config.ts"
const config: QuartzConfig = {
configuration: { ... },
plugins: { ... },
}
```
## General Configuration
This part of the configuration concerns anything that can affect the whole site. The following is a list breaking down all the things you can configure:
- `pageTitle`: title of the site. This is also used when generating the [[RSS Feed]] for your site.
- `enableSPA`: whether to enable [[SPA Routing]] on your site.
- `enablePopovers`: whether to enable [[popover previews]] on your site.
- `analytics`: what to use for analytics on your site. Values can be
- `null`: don't use analytics;
- `{ provider: 'plausible' }`: use [Plausible](https://plausible.io/), a privacy-friendly alternative to Google Analytics; or
- `{ provider: 'google', tagId: <your-google-tag> }`: use Google Analytics
- `baseUrl`: this is used for sitemaps and RSS feeds that require an absolute URL to know where the canonical 'home' of your site lives. This is normally the deployed URL of your site (e.g. `quartz.jzhao.xyz` for this site). Do not include the protocol (i.e. `https://`) or any leading or trailing slashes.
- This should also include the subpath if you are [[hosting]] on GitHub pages without a custom domain. For example, if my repository is `jackyzha0/quartz`, GitHub pages would deploy to `https://jackyzha0.github.io/quartz` and the `baseUrl` would be `jackyzha0.github.io/quartz`
- Note that Quartz 4 will avoid using this as much as possible and use relative URLs whenever it can to make sure your site works no matter _where_ you end up actually deploying it.
- `ignorePatterns`: a list of [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details.
- `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings.
- `theme`: configure how the site looks.
- `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here.
- `header`: Font to use for headers
- `code`: Font for inline and block quotes.
- `body`: Font for everything
- `colors`: controls the theming of the site.
- `light`: page background
- `lightgray`: borders
- `gray`: graph links, heavier borders
- `darkgray`: body text
- `dark`: header text and icons
- `secondary`: link colour, current [[graph view|graph]] node
- `tertiary`: hover states and visited [[graph view|graph]] nodes
- `highlight`: internal link background, highlighted text, [[syntax highlighting|highlighted lines of code]]
## Plugins
You can think of Quartz plugins as a series of transformations over content.
![[quartz transform pipeline.png]]
```ts
plugins: {
transformers: [...],
filters: [...],
emitters: [...],
}
```
- [[making plugins#Transformers|Transformers]] **map** over content (e.g. parsing frontmatter, generating a description)
- [[making plugins#Filters|Filters]] **filter** content (e.g. filtering out drafts)
- [[making plugins#Emitters|Emitters]] **reduce** over content (e.g. creating an RSS feed or pages that list all files with a specific tag)
By adding, removing, and reordering plugins from the `tranformers`, `filters`, and `emitters` fields, you can customize the behaviour of Quartz.
> [!note]
> Each node is modified by every transformer _in order_. Some transformers are position-sensitive so you may need to take special note of whether it needs come before or after any other particular plugins.
Additionally, plugins may also have their own configuration settings that you can pass in. For example, the [[Latex]] plugin allows you to pass in a field specifying the `renderEngine` to choose between Katex and MathJax.
```ts
transformers: [
Plugin.FrontMatter(), // uses default options
Plugin.Latex({ renderEngine: "katex" }), // specify some options
]
```
If you'd like to make your own plugins, read the guide on [[making plugins]] for more information.

View File

@ -0,0 +1,7 @@
Quartz comes shipped with a Docker image that will allow you to preview your Quartz locally without installing Node.
You can run the below one-liner to run Quartz in Docker.
```sh
docker run --rm -itp 8080:8080 $(docker build -q .)
```

63
docs/features/Latex.md Normal file
View File

@ -0,0 +1,63 @@
---
tags:
- plugin/transformer
---
Quartz uses [Katex](https://katex.org/) by default to typeset both inline and block math expressions at build time.
## Syntax
### Block Math
Block math can be rendered by delimiting math expression with `$$`.
```
$$
f(x) = \int_{-\infty}^\infty
f\hat(\xi),e^{2 \pi i \xi x}
\,d\xi
$$
```
$$
f(x) = \int_{-\infty}^\infty
f\hat(\xi),e^{2 \pi i \xi x}
\,d\xi
$$
$$
\begin{aligned}
a &= b + c \\ &= e + f \\
\end{aligned}
$$
$$
\begin{bmatrix}
1 & 2 & 3 \\
a & b & c
\end{bmatrix}
$$
### Inline Math
Similarly, inline math can be rendered by delimiting math expression with a single `$`. For example, `$e^{i\pi} = -1$` produces $e^{i\pi} = -1$
### Escaping symbols
There will be cases where you may have more than one `$` in a paragraph at once which may accidentally trigger MathJax/Katex.
To get around this, you can escape the dollar sign by doing `\$` instead.
For example:
- Incorrect: `I have $1 and you have $2` produces I have $1 and you have $2
- Correct: `I have \$1 and you have \$2` produces I have \$1 and you have \$2
## MathJax
In `quartz.config.ts`, you can configure Quartz to use [MathJax SVG rendering](https://docs.mathjax.org/en/latest/output/svg.html) by replacing `Plugin.Latex({ renderEngine: 'katex' })` with `Plugin.Latex({ renderEngine: 'mathjax' })`
## Customization
- Removing Latex support: remove all instances of `Plugin.Latex()` from `quartz.config.ts`.
- Plugin: `quartz/plugins/transformers/latex.ts`

View File

@ -0,0 +1,28 @@
Quartz supports Mermaid which allows you to add diagrams and charts to your notes. Mermaid supports a range of diagrams, such as [flow charts](https://mermaid.js.org/syntax/flowchart.html), [sequence diagrams](https://mermaid.js.org/syntax/sequenceDiagram.html), and [timelines](https://mermaid.js.org/syntax/timeline.html). This is enabled as a part of [[Obsidian compatibility]] and can be configured and enabled/disabled from that plugin.
By default, Quartz will render Mermaid diagrams to match the site theme.
> [!warning]
> Wondering why Mermaid diagrams may not be showing up even if you have them enabled? You may need to reorder your plugins so that `Plugin.ObsidianFlavoredMarkdown()` is _after_ `Plugin.SyntaxHighlighting()`.
## Syntax
To add a Mermaid diagram, create a mermaid code block.
````
```mermaid
sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
```
````
```mermaid
sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
```

View File

@ -0,0 +1,31 @@
---
tags:
- plugin/transformer
---
Quartz was originally designed as a tool to publish Obsidian vaults as websites. Even as the scope of Quartz has widened over time, it hasn't lost the ability to seamlessly interoperate with Obsidian.
By default, Quartz ships with `Plugin.ObsidianFlavoredMarkdown` which is a transformer plugin that adds support for [Obsidian Flavored Markdown](https://help.obsidian.md/Editing+and+formatting/Obsidian+Flavored+Markdown). This includes support for features like [[wikilinks]] and [[Mermaid diagrams]].
It also ships with support for [frontmatter parsing](https://help.obsidian.md/Editing+and+formatting/Properties) with the same fields that Obsidian uses through the `Plugin.FrontMatter` transformer plugin.
Finally, Quartz also provides `Plugin.CrawlLinks` which allows you to customize Quartz's link resolution behaviour to match Obsidian.
## Configuration
- Frontmatter parsing:
- Disabling: remove all instances of `Plugin.FrontMatter()` from `quartz.config.ts`.
- Customize default values for frontmatter: edit `quartz/plugins/transformers/frontmatter.ts`
- Obsidian Flavored Markdown:
- Disabling: remove all instances of `Plugin.ObsidianFlavoredMarkdown()` from `quartz.config.ts`
- Customizing features: `Plugin.ObsidianFlavoredMarkdown` has several other options to toggle on and off:
- `comments`: whether to enable `%%` style Obsidian comments. Defaults to `true`
- `highlight`: whether to enable `==` style highlights. Defaults to `true`
- `wikilinks`: whether to enable turning [[wikilinks]] into regular links. Defaults to `true`
- `callouts`: whether to enable [[callouts]]. Defaults to `true`
- `mermaid`: whether to enable [[Mermaid diagrams]]. Defaults to `true`
- `parseTags`: whether to try and parse tags in the content body. Defaults to `true`
- `enableInHtmlEmbed`: whether to try and parse Obsidian flavoured markdown in raw HTML. Defaults to `false`
- Link resolution behaviour:
- Disabling: remove all instances of `Plugin.CrawlLinks()` from `quartz.config.ts`
- Changing link resolution preference: set `markdownLinkResolution` to one of `absolute`, `relative` or `shortest`

View File

@ -0,0 +1,39 @@
---
tags:
- plugin/transformer
---
[org-roam](https://www.orgroam.com/) is a plain-text personal knowledge management system for [emacs](https://en.wikipedia.org/wiki/Emacs). [ox-hugo](https://github.com/kaushalmodi/ox-hugo) is org exporter backend that exports `org-mode` files to [Hugo](https://gohugo.io/) compatible Markdown.
Because the Markdown generated by ox-hugo is not pure Markdown but Hugo specific, we need to transform it to fit into Quartz. This is done by `Plugin.OxHugoFlavouredMarkdown`. Even though this [[making plugins|plugin]] was written with `ox-hugo` in mind, it should work for any Hugo specific Markdown.
```typescript title="quartz.config.ts"
plugins: {
transformers: [
Plugin.FrontMatter({ delims: "+++", language: "toml" }), // if toml frontmatter
// ...
Plugin.OxHugoFlavouredMarkdown(),
Plugin.GitHubFlavoredMarkdown(),
// ...
],
},
```
## Usage
Quartz by default doesn't understand `org-roam` files as they aren't Markdown. You're responsible for using an external tool like `ox-hugo` to export the `org-roam` files as Markdown content to Quartz and managing the static assets so that they're available in the final output.
## Configuration
- Link resolution
- `wikilinks`: Whether to replace `{{ relref }}` with Quartz [[wikilinks]]
- `removePredefinedAnchor`: Whether to remove [pre-defined anchor set by ox-hugo](https://ox-hugo.scripter.co/doc/anchors/).
- Image handling
- `replaceFigureWithMdImg`: Whether to replace `<figure/>` with `![]()`
- Formatting
- `removeHugoShortcode`: Whether to remove hugo shortcode syntax (`{{}}`)
- `replaceOrgLatex`: Whether to replace org-mode formatting for latex fragments with what `Plugin.Latex` supports.
> [!warning]
>
> While you can use `Plugin.OxHugoFlavoredMarkdown` and `Plugin.ObsidianFlavoredMarkdown` together, it's not recommended because it might mutate the file in unexpected ways. Use with caution.

View File

@ -0,0 +1,7 @@
Quartz creates an RSS feed for all the content on your site by generating an `index.xml` file that RSS readers can subscribe to. Because of the RSS spec, this requires the `baseUrl` property in your [[configuration]] to be set properly for RSS readers to pick it up properly.
## Configuration
- Remove RSS feed: set the `enableRSS` field of `Plugin.ContentIndex` in `quartz.config.ts` to be `false`.
- Change number of entries: set the `rssLimit` field of `Plugin.ContentIndex` to be the desired value. It defaults to latest 10 items.
- Use rich HTML output in RSS: set `rssFullHtml` field of `Plugin.ContentIndex` to be `true`.

View File

@ -0,0 +1,7 @@
Single-page-app style rendering. This prevents flashes of unstyled content and improves the smoothness of Quartz.
Under the hood, this is done by hijacking page navigations and instead fetching the HTML via a `GET` request and then diffing and selectively replacing parts of the page using [micromorph](https://github.com/natemoo-re/micromorph). This allows us to change the content of the page without fully refreshing the page, reducing the amount of content that the browser needs to load.
## Configuration
- Disable SPA Routing: set the `enableSPA` field of the [[configuration]] in `quartz.config.ts` to be `false`.

View File

@ -0,0 +1,14 @@
---
title: Backlinks
tags:
- component
---
A backlink for a note is a link from another note to that note. Links in the backlink pane also feature rich [[popover previews]] if you have that feature enabled.
## Customization
- Removing backlinks: delete all usages of `Component.Backlinks()` from `quartz.layout.ts`.
- Component: `quartz/components/Backlinks.tsx`
- Style: `quartz/components/styles/backlinks.scss`
- Script: `quartz/components/scripts/search.inline.ts`

View File

@ -0,0 +1,35 @@
---
title: "Breadcrumbs"
tags:
- component
---
Breadcrumbs provide a way to navigate a hierarchy of pages within your site using a list of its parent folders.
By default, the element at the very top of your page is the breadcrumb navigation bar (can also be seen at the top on this page!).
## Customization
Most configuration can be done by passing in options to `Component.Breadcrumbs()`.
For example, here's what the default configuration looks like:
```typescript title="quartz.layout.ts"
Component.Breadcrumbs({
spacerSymbol: "", // symbol between crumbs
rootName: "Home", // name of first/root element
resolveFrontmatterTitle: true, // whether to resolve folder names through frontmatter titles
hideOnRoot: true, // whether to hide breadcrumbs on root `index.md` page
})
```
When passing in your own options, you can omit any or all of these fields if you'd like to keep the default value for that field.
You can also adjust where the breadcrumbs will be displayed by adjusting the [[layout]] (moving `Component.Breadcrumbs()` up or down)
Want to customize it even more?
- Removing breadcrumbs: delete all usages of `Component.Breadcrumbs()` from `quartz.layout.ts`.
- Component: `quartz/components/Breadcrumbs.tsx`
- Style: `quartz/components/styles/breadcrumbs.scss`
- Script: inline at `quartz/components/Breadcrumbs.tsx`

86
docs/features/callouts.md Normal file
View File

@ -0,0 +1,86 @@
---
title: Callouts
tags:
- plugin/transformer
---
Quartz supports the same Admonition-callout syntax as Obsidian.
This includes
- 12 Distinct callout types (each with several aliases)
- Collapsable callouts
```
> [!info] Title
> This is a callout!
```
See [documentation on supported types and syntax here](https://help.obsidian.md/Editing+and+formatting/Callouts).
> [!warning]
> Wondering why callouts may not be showing up even if you have them enabled? You may need to reorder your plugins so that `Plugin.ObsidianFlavoredMarkdown()` is _after_ `Plugin.SyntaxHighlighting()`.
## Customization
- Disable callouts: simply pass `callouts: false` to the plugin: `Plugin.ObsidianFlavoredMarkdown({ callouts: false })`
- Editing icons: `quartz/plugins/transformers/ofm.ts`
## Showcase
> [!info]
> Default title
> [!question]+ Can callouts be nested?
>
> > [!todo]- Yes!, they can. And collapsed!
> >
> > > [!example] You can even use multiple layers of nesting.
> [!EXAMPLE] Examples
>
> Aliases: example
> [!note] Notes
>
> Aliases: note
> [!abstract] Summaries
>
> Aliases: abstract, summary, tldr
> [!info] Info
>
> Aliases: info, todo
> [!tip] Hint
>
> Aliases: tip, hint, important
> [!success] Success
>
> Aliases: success, check, done
> [!question] Question
>
> Aliases: question, help, faq
> [!warning] Warning
>
> Aliases: warning, caution, attention
> [!failure] Failure
>
> Aliases: failure, fail, missing
> [!danger] Error
>
> Aliases: danger, error
> [!bug] Bug
>
> Aliases: bug
> [!quote] Quote
>
> Aliases: quote, cite

14
docs/features/darkmode.md Normal file
View File

@ -0,0 +1,14 @@
---
title: "Darkmode"
tags:
- component
---
Quartz supports darkmode out of the box that respects the user's theme preference. Any future manual toggles of the darkmode switch will be saved in the browser's local storage so it can be persisted across future page loads.
## Customization
- Removing darkmode: delete all usages of `Component.Darkmode()` from `quartz.layout.ts`.
- Component: `quartz/components/Darkmode.tsx`
- Style: `quartz/components/styles/darkmode.scss`
- Script: `quartz/components/scripts/darkmode.inline.ts`

245
docs/features/explorer.md Normal file
View File

@ -0,0 +1,245 @@
---
title: "Explorer"
tags:
- component
---
Quartz features an explorer that allows you to navigate all files and folders on your site. It supports nested folders and is highly customizable.
By default, it shows all folders and files on your page. To display the explorer in a different spot, you can edit the [[layout]].
Display names for folders get determined by the `title` frontmatter field in `folder/index.md` (more detail in [[authoring content | Authoring Content]]). If this file does not exist or does not contain frontmatter, the local folder name will be used instead.
> [!info]
> The explorer uses local storage by default to save the state of your explorer. This is done to ensure a smooth experience when navigating to different pages.
>
> To clear/delete the explorer state from local storage, delete the `fileTree` entry (guide on how to delete a key from local storage in chromium based browsers can be found [here](https://docs.devolutions.net/kb/general-knowledge-base/clear-browser-local-storage/clear-chrome-local-storage/)). You can disable this by passing `useSavedState: false` as an argument.
## Customization
Most configuration can be done by passing in options to `Component.Explorer()`.
For example, here's what the default configuration looks like:
```typescript title="quartz.layout.ts"
Component.Explorer({
title: "Explorer", // title of the explorer component
folderClickBehavior: "collapse", // what happens when you click a folder ("link" to navigate to folder page on click or "collapse" to collapse folder on click)
folderDefaultState: "collapsed", // default state of folders ("collapsed" or "open")
useSavedState: true, // wether to use local storage to save "state" (which folders are opened) of explorer
// Sort order: folders first, then files. Sort folders and files alphabetically
sortFn: (a, b) => {
... // default implementation shown later
},
filterFn: filterFn: (node) => node.name !== "tags", // filters out 'tags' folder
mapFn: undefined,
// what order to apply functions in
order: ["filter", "map", "sort"],
})
```
When passing in your own options, you can omit any or all of these fields if you'd like to keep the default value for that field.
Want to customize it even more?
- Removing table of contents: remove `Component.Explorer()` from `quartz.layout.ts`
- (optional): After removing the explorer component, you can move the [[table of contents | Table of Contents]] component back to the `left` part of the layout
- Changing `sort`, `filter` and `map` behavior: explained in [[#Advanced customization]]
- Component:
- Wrapper (Outer component, generates file tree, etc): `quartz/components/Explorer.tsx`
- Explorer node (recursive, either a folder or a file): `quartz/components/ExplorerNode.tsx`
- Style: `quartz/components/styles/explorer.scss`
- Script: `quartz/components/scripts/explorer.inline.ts`
## Advanced customization
This component allows you to fully customize all of its behavior. You can pass a custom `sort`, `filter` and `map` function.
All functions you can pass work with the `FileNode` class, which has the following properties:
```ts title="quartz/components/ExplorerNode.tsx" {2-5}
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
depth: number // depth of current node
... // rest of implementation
}
```
Every function you can pass is optional. By default, only a `sort` function will be used:
```ts title="Default sort function"
// Sort order: folders first, then files. Sort folders and files alphabetically
Component.Explorer({
sortFn: (a, b) => {
if ((!a.file && !b.file) || (a.file && b.file)) {
// sensitivity: "base": Only strings that differ in base letters compare as unequal. Examples: a ≠ b, a = á, a = A
// numeric: true: Whether numeric collation should be used, such that "1" < "2" < "10"
return a.displayName.localeCompare(b.displayName, undefined, {
numeric: true,
sensitivity: "base",
})
}
if (a.file && !b.file) {
return 1
} else {
return -1
}
},
})
```
---
You can pass your own functions for `sortFn`, `filterFn` and `mapFn`. All functions will be executed in the order provided by the `order` option (see [[#Customization]]). These functions behave similarly to their `Array.prototype` counterpart, except they modify the entire `FileNode` tree in place instead of returning a new one.
For more information on how to use `sort`, `filter` and `map`, you can check [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort), [Array.prototype.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) and [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).
Type definitions look like this:
```ts
sortFn: (a: FileNode, b: FileNode) => number
filterFn: (node: FileNode) => boolean
mapFn: (node: FileNode) => void
```
> [!tip]
> You can check if a `FileNode` is a folder or a file like this:
>
> ```ts
> if (node.file) {
> // node is a file
> } else {
> // node is a folder
> }
> ```
## Basic examples
These examples show the basic usage of `sort`, `map` and `filter`.
### Use `sort` to put files first
Using this example, the explorer will alphabetically sort everything, but put all **files** above all **folders**.
```ts title="quartz.layout.ts"
Component.Explorer({
sortFn: (a, b) => {
if ((!a.file && !b.file) || (a.file && b.file)) {
return a.displayName.localeCompare(b.displayName)
}
if (a.file && !b.file) {
return -1
} else {
return 1
}
},
})
```
### Change display names (`map`)
Using this example, the display names of all `FileNodes` (folders + files) will be converted to full upper case.
```ts title="quartz.layout.ts"
Component.Explorer({
mapFn: (node) => {
node.displayName = node.displayName.toUpperCase()
},
})
```
### Remove list of elements (`filter`)
Using this example, you can remove elements from your explorer by providing an array of folders/files using the `omit` set.
```ts title="quartz.layout.ts"
Component.Explorer({
filterFn: (node) => {
// set containing names of everything you want to filter out
const omit = new Set(["authoring content", "tags", "hosting"])
return !omit.has(node.name.toLowerCase())
},
})
```
You can customize this by changing the entries of the `omit` set. Simply add all folder or file names you want to remove.
### 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`.
```ts title="quartz.layout.ts"
Component.Explorer({
filterFn: undefined, // apply no filter function, every file and folder will visible
})
```
## Advanced examples
### Add emoji prefix
To add emoji prefixes (📁 for folders, 📄 for files), you could use a map function like this:
```ts title="quartz.layout.ts"
Component.Explorer({
mapFn: (node) => {
// dont change name of root node
if (node.depth > 0) {
// set emoji for file/folder
if (node.file) {
node.displayName = "📄 " + node.displayName
} else {
node.displayName = "📁 " + node.displayName
}
}
},
})
```
### Putting it all together
In this example, we're going to customize the explorer by using functions from examples above to [[#Add emoji prefix | add emoji prefixes]], [[#remove-list-of-elements-filter| filter out some folders]] and [[#use-sort-to-put-files-first | sort with files above folders]].
```ts title="quartz.layout.ts"
Component.Explorer({
filterFn: sampleFilterFn,
mapFn: sampleMapFn,
sortFn: sampleSortFn,
order: ["filter", "sort", "map"],
})
```
Notice how we customized the `order` array here. This is done because the default order applies the `sort` function last. While this normally works well, it would cause unintended behavior here, since we changed the first characters of all display names. In our example, `sort` would be applied based off the emoji prefix instead of the first _real_ character.
To fix this, we just changed around the order and apply the `sort` function before changing the display names in the `map` function.
> [!tip]
> When writing more complicated functions, the `layout` file can start to look very cramped.
> You can fix this by defining your functions in another file.
>
> ```ts title="functions.ts"
> import { Options } from "./quartz/components/ExplorerNode"
> export const mapFn: Options["mapFn"] = (node) => {
> // implement your function here
> }
> export const filterFn: Options["filterFn"] = (node) => {
> // implement your function here
> }
> export const sortFn: Options["sortFn"] = (a, b) => {
> // implement your function here
> }
> ```
>
> You can then import them like this:
>
> ```ts title="quartz.layout.ts"
> import { mapFn, filterFn, sortFn } from "./functions.ts"
> Component.Explorer({
> mapFn: mapFn,
> filterFn: filterFn,
> sortFn: sortFn,
> })
> ```

View File

@ -0,0 +1,32 @@
---
title: Folder and Tag Listings
tags:
- plugin/emitter
---
Quartz creates listing pages for any folders and tags you have.
## Folder Listings
Quartz will generate an index page for all the pages under that folder. This includes any content that is multiple levels deep.
Additionally, Quartz will also generate pages for subfolders. Say you have a note in a nested folder `content/abc/def/note.md`. Then, Quartz would generate a page for all the notes under `abc` _and_ a page for all the notes under `abc/def`.
By default, Quartz will title the page `Folder: <name of folder>` and no description. You can override this by creating an `index.md` file in the folder with the `title` [[authoring content#Syntax|frontmatter]] field. Any content you write in this file will also be used in the description of the folder.
For example, for the folder `content/posts`, you can add another file `content/posts/index.md` to add a specific description for it.
## Tag Listings
Quartz will also create an index page for each unique tag in your vault and render a list of all notes with that tag.
Quartz also supports tag hierarchies as well (e.g. `plugin/emitter`) and will also render a separate tag page for each layer of the tag hierarchy. It will also create a default global tag index page at `/tags` that displays a list of all the tags in your Quartz.
Like folder listings, you can also provide a description and title for a tag page by creating a file for each tag. For example, if you wanted to create a custom description for the #component tag, you would create a file at `content/tags/component.md` with a title and description.
## Customization
The layout for both the folder and content pages can be customized. By default, they use the `defaultListPageLayout` in `quartz.layouts.ts`. If you'd like to make more involved changes to the layout and don't mind editing some [[creating components|Quartz components]], you can take a look at `quartz/components/pages/FolderContent.tsx` and `quartz/components/pages/TagContent.tsx` respectively.
- Removing folder listings: remove `Plugin.FolderPage()` from `emitters` in `quartz.config.ts`
- Removing tag listings: remove `Plugin.TagPage()` from `emitters` in `quartz.config.ts`

View File

@ -0,0 +1,30 @@
---
title: Full-text Search
tags:
- component
---
Full-text search in Quartz is powered by [Flexsearch](https://github.com/nextapps-de/flexsearch). It's fast enough to return search results in under 10ms for Quartzs as large as half a million words.
It can be opened by either clicking on the search bar or pressing `⌘`/`ctrl` + `K`. The top 5 search results are shown on each query. Matching subterms are highlighted and the most relevant 30 words are excerpted. Clicking on a search result will navigate to that page.
To search content by tags, you can either press `⌘`/`ctrl` + `shift` + `K` or start your query with `#` (e.g. `#components`).
This component is also keyboard accessible: Tab and Shift+Tab will cycle forward and backward through search results and Enter will navigate to the highlighted result (first result by default). You are also able to navigate search results using `ArrowUp` and `ArrowDown`.
> [!info]
> Search requires the `ContentIndex` emitter plugin to be present in the [[configuration]].
### Indexing Behaviour
By default, it indexes every page on the site with **Markdown syntax removed**. This means link URLs for instance are not indexed.
It properly tokenizes Chinese, Korean, and Japenese characters and constructs separate indexes for the title, content and tags, weighing title matches above content matches.
## Customization
- Removing search: delete all usages of `Component.Search()` from `quartz.layout.ts`.
- Component: `quartz/components/Search.tsx`
- Style: `quartz/components/styles/search.scss`
- Script: `quartz/components/scripts/search.inline.ts`
- You can edit `contextWindowWords`, `numSearchResults` or `numTagResults` to suit your needs

View File

@ -0,0 +1,59 @@
---
title: "Graph View"
tags:
- component
---
Quartz features a graph-view that can show both a local graph view and a global graph view.
- The local graph view shows files that either link to the current file or are linked from the current file. In other words, it shows all notes that are _at most_ one hop away.
- The global graph view can be toggled by clicking the graph icon on the top-right of the local graph view. It shows _all_ the notes in your graph and how they connect to each other.
By default, the node radius is proportional to the total number of incoming and outgoing internal links from that file.
Additionally, similar to how browsers highlight visited links a different colour, the graph view will also show nodes that you have visited in a different colour.
> [!info]
> Graph View requires the `ContentIndex` emitter plugin to be present in the [[configuration]].
## Customization
Most configuration can be done by passing in options to `Component.Graph()`.
For example, here's what the default configuration looks like:
```typescript title="quartz.layout.ts"
Component.Graph({
localGraph: {
drag: true, // whether to allow panning the view around
zoom: true, // whether to allow zooming in and out
depth: 1, // how many hops of notes to display
scale: 1.1, // default view scale
repelForce: 0.5, // how much nodes should repel each other
centerForce: 0.3, // how much force to use when trying to center the nodes
linkDistance: 30, // how long should the links be by default?
fontSize: 0.6, // what size should the node labels be?
opacityScale: 1, // how quickly do we fade out the labels when zooming out?
},
globalGraph: {
drag: true,
zoom: true,
depth: -1,
scale: 0.9,
repelForce: 0.5,
centerForce: 0.3,
linkDistance: 30,
fontSize: 0.6,
opacityScale: 1,
},
})
```
When passing in your own options, you can omit any or all of these fields if you'd like to keep the default value for that field.
Want to customize it even more?
- Removing graph view: delete all usages of `Component.Graph()` from `quartz.layout.ts`.
- Component: `quartz/components/Graph.tsx`
- Style: `quartz/components/styles/graph.scss`
- Script: `quartz/components/scripts/graph.inline.ts`

3
docs/features/index.md Normal file
View File

@ -0,0 +1,3 @@
---
title: Feature List
---

View File

@ -0,0 +1,15 @@
---
title: Popover Previews
---
Like Wikipedia, when you hover over a link in Quartz, there is a popup of a page preview that you can scroll to see the entire content. Links to headers will also scroll the popup to show that specific header in view.
By default, Quartz only fetches previews for pages inside your vault due to [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). It does this by selecting all HTML elements with the `popover-hint` class. For most pages, this includes the page title, page metadata like words and time to read, tags, and the actual page content.
When [[creating components|creating your own components]], you can include this `popover-hint` class to also include it in the popover.
## Configuration
- Remove popovers: set the `enablePopovers` field in `quartz.config.ts` to be `false`.
- Style: `quartz/components/styles/popover.scss`
- Script: `quartz/components/scripts/popover.inline.ts`

View File

@ -0,0 +1,35 @@
---
title: Private Pages
tags:
- plugin/filter
---
There may be some notes you want to avoid publishing as a website. Quartz supports this through two mechanisms which can be used in conjunction:
## Filter Plugins
[[making plugins#Filters|Filter plugins]] are plugins that filter out content based off of certain criteria. By default, Quartz uses the `Plugin.RemoveDrafts` plugin which filters out any note that has `draft: true` in the frontmatter.
If you'd like to only publish a select number of notes, you can instead use `Plugin.ExplicitPublish` which will filter out all notes except for any that have `publish: true` in the frontmatter.
> [!warning]
> Regardless of the filter plugin used, **all non-markdown files will be emitted and available publically in the final build.** This includes files such as images, voice recordings, PDFs, etc. One way to prevent this and still be able to embed local images is to create a folder specifically for public media and add the following two patterns to the ignorePatterns array.
>
> `"!(PublicMedia)**/!(*.md)", "!(*.md)"`
## `ignorePatterns`
This is a field in `quartz.config.ts` under the main [[configuration]] which allows you to specify a list of patterns to effectively exclude from parsing all together. Any valid [fast-glob](https://github.com/mrmlnc/fast-glob#pattern-syntax) pattern works here.
> [!note]
> Bash's glob syntax is slightly different from fast-glob's and using bash's syntax may lead to unexpected results.
Common examples include:
- `some/folder`: exclude the entire of `some/folder`
- `*.md`: exclude all files with a `.md` extension
- `!*.md` exclude all files that _don't_ have a `.md` extension
- `**/private`: exclude any files or folders named `private` at any level of nesting
> [!warning]
> Marking something as private via either a plugin or through the `ignorePatterns` pattern will only prevent a page from being included in the final built site. If your GitHub repository is public, also be sure to include an ignore for those in the `.gitignore` of your Quartz. See the `git` [documentation](https://git-scm.com/docs/gitignore#_pattern_format) for more information.

View File

@ -0,0 +1,16 @@
---
title: Recent Notes
tags: component
---
Quartz can generate a list of recent notes for based on some filtering and sorting criteria. Though this component isn't included in any [[layout]] by default, you can add it by using `Component.RecentNotes`.
## Customization
- 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 })`
- 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.
- Component: `quartz/components/RecentNotes.tsx`
- Style: `quartz/components/styles/recentNotes.scss`

View File

@ -0,0 +1,135 @@
---
title: Syntax Highlighting
tags:
- plugin/transformer
---
Syntax highlighting in Quartz is completely done at build-time. This means that Quartz only ships pre-calculated CSS to highlight the right words so there is no heavy client-side bundle that does the syntax highlighting.
And, unlike some client-side highlighters, it has a full TextMate parser grammar instead of using Regexes, allowing for highly accurate code highlighting.
In short, it generates HTML that looks exactly like your code in an editor like VS Code. Under the hood, it's powered by [Rehype Pretty Code](https://rehype-pretty-code.netlify.app/) which uses [Shiki](https://github.com/shikijs/shiki).
> [!warning]
> Syntax highlighting does have an impact on build speed if you have a lot of code snippets in your notes.
## Formatting
Text inside `backticks` on a line will be formatted like code.
````
```ts
export function trimPathSuffix(fp: string): string {
fp = clientSideSlug(fp)
let [cleanPath, anchor] = fp.split("#", 2)
anchor = anchor === undefined ? "" : "#" + anchor
return cleanPath + anchor
}
```
````
```ts
export function trimPathSuffix(fp: string): string {
fp = clientSideSlug(fp)
let [cleanPath, anchor] = fp.split("#", 2)
anchor = anchor === undefined ? "" : "#" + anchor
return cleanPath + anchor
}
```
### Titles
Add a file title to your code block, with text inside double quotes (`""`):
````
```js title="..."
```
````
```ts title="quartz/path.ts"
export function trimPathSuffix(fp: string): string {
fp = clientSideSlug(fp)
let [cleanPath, anchor] = fp.split("#", 2)
anchor = anchor === undefined ? "" : "#" + anchor
return cleanPath + anchor
}
```
### Line highlighting
Place a numeric range inside `{}`.
````
```js {1-3,4}
```
````
```ts {2-3,6}
export function trimPathSuffix(fp: string): string {
fp = clientSideSlug(fp)
let [cleanPath, anchor] = fp.split("#", 2)
anchor = anchor === undefined ? "" : "#" + anchor
return cleanPath + anchor
}
```
### Word highlighting
A series of characters, like a literal regex.
````
```js /useState/
const [age, setAge] = useState(50);
const [name, setName] = useState('Taylor');
```
````
```js /useState/
const [age, setAge] = useState(50)
const [name, setName] = useState("Taylor")
```
### Line numbers
Syntax highlighting has line numbers configured automatically. If you want to start line numbers at a specific number, use `showLineNumbers{number}`:
````
```js showLineNumbers{number}
```
````
```ts showLineNumbers{20}
export function trimPathSuffix(fp: string): string {
fp = clientSideSlug(fp)
let [cleanPath, anchor] = fp.split("#", 2)
anchor = anchor === undefined ? "" : "#" + anchor
return cleanPath + anchor
}
```
### Escaping code blocks
You can format a codeblock inside of a codeblock by wrapping it with another level of backtick fences that has one more backtick than the previous fence.
`````
````
```js /useState/
const [age, setAge] = useState(50);
const [name, setName] = useState('Taylor');
```
````
`````
## Customization
- Removing syntax highlighting: delete all usages of `Plugin.SyntaxHighlighting()` from `quartz.config.ts`.
- Style: By default, Quartz uses derivatives of the GitHub light and dark themes. You can customize the colours in the `quartz/styles/syntax.scss` file.
- Plugin: `quartz/plugins/transformers/syntax.ts`

View File

@ -0,0 +1,26 @@
---
title: "Table of Contents"
tags:
- component
- plugin/transformer
---
Quartz can automatically generate a table of contents from a list of headings on each page. It will also show you your current scroll position on the site by marking headings you've scrolled through with a different colour.
By default, it will show all headers from H1 (`# Title`) all the way to H3 (`### Title`) and will only show the table of contents if there is more than 1 header on the page.
You can also hide the table of contents on a page by adding `enableToc: false` to the frontmatter for that page.
> [!info]
> This feature requires both `Plugin.TableOfContents` in your `quartz.config.ts` and `Component.TableOfContents` in your `quartz.layout.ts` to function correctly.
## Customization
- Removing table of contents: remove all instances of `Plugin.TableOfContents()` from `quartz.config.ts`. and `Component.TableOfContents()` from `quartz.layout.ts`
- Changing the max depth: pass in a parameter to `Plugin.TableOfContents({ maxDepth: 4 })`
- Changing the minimum number of entries in the Table of Contents before it renders: pass in a parameter to `Plugin.TableOfContents({ minEntries: 3 })`
- Collapse the table of content by default: pass in a parameter to `Plugin.TableOfContents({ collapseByDefault: true })`
- Component: `quartz/components/TableOfContents.tsx`
- Style:
- Modern (default): `quartz/components/styles/toc.scss`
- Legacy Quartz 3 style: `quartz/components/styles/legacyToc.scss`
- Script: `quartz/components/scripts/toc.inline.ts`

View File

@ -0,0 +1,23 @@
---
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
- 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

@ -0,0 +1,16 @@
---
title: Wikilinks
---
Wikilinks were pioneered by earlier internet wikis to make it easier to write links across pages without needing to write Markdown or HTML links each time.
Quartz supports Wikilinks by default and these links are resolved by Quartz using `Plugin.CrawlLinks`. See the [Obsidian Help page on Internal Links](https://help.obsidian.md/Linking+notes+and+files/Internal+links) for more information on Wikilink syntax.
This is enabled as a part of [[Obsidian compatibility]] and can be configured and enabled/disabled from that plugin.
## Syntax
- `[[Path to file]]`: produces a link to `Path to file.md` (or `Path-to-file.md`) with the text `Path to file`
- `[[Path to file | Here's the title override]]`: produces a link to `Path to file.md` with the text `Here's the title override`
- `[[Path to file#Anchor]]`: produces a link to the anchor `Anchor` in the file `Path to file.md`
- `[[Path to file#^block-ref]]`: produces a link to the specific block `block-ref` in the file `Path to file.md`

221
docs/hosting.md Normal file
View File

@ -0,0 +1,221 @@
---
title: Hosting
---
Quartz effectively turns your Markdown files and other resources into a bundle of HTML, JS, and CSS files (a website!).
However, if you'd like to publish your site to the world, you need a way to host it online. This guide will detail how to deploy with either GitHub Pages or Cloudflare pages but any service that allows you to deploy static HTML should work as well (e.g. Netlify, Replit, etc.)
> [!hint]
> Some Quartz features (like [[RSS Feed]] and sitemap generation) require `baseUrl` to be configured properly in your [[configuration]] to work properly. Make sure you set this before deploying!
## Cloudflare Pages
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/) and select your account.
2. In Account Home, select **Workers & Pages** > **Create application** > **Pages** > **Connect to Git**.
3. Select the new GitHub repository that you created and, in the **Set up builds and deployments** section, provide the following information:
| Configuration option | Value |
| ---------------------- | ------------------ |
| Production branch | `v4` |
| Framework preset | `None` |
| Build command | `npx quartz build` |
| Build output directory | `public` |
Press "Save and deploy" and Cloudflare should have a deployed version of your site in about a minute. Then, every time you sync your Quartz changes to GitHub, your site should be updated.
To add a custom domain, check out [Cloudflare's documentation](https://developers.cloudflare.com/pages/platform/custom-domains/).
## GitHub Pages
Like Quartz 3, you can deploy the site generated by Quartz 4 via GitHub Pages.
> [!warning]
> Quartz generates files in the format of `file.html` instead of `file/index.html` which means the trailing slashes for _non-folder paths_ are dropped. As GitHub pages does not do this redirect, this may cause existing links to your site that use trailing slashes to break. If not breaking existing links is important to you, consider using [[#Cloudflare Pages]].
In your local Quartz, create a new file `quartz/.github/workflows/deploy.yml`.
```yaml title="quartz/.github/workflows/deploy.yml"
name: Deploy Quartz site to GitHub Pages
on:
push:
branches:
- v4
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch all history for git info
- uses: actions/setup-node@v3
with:
node-version: 18.14
- name: Install Dependencies
run: npm ci
- name: Build Quartz
run: npx quartz build
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: public
deploy:
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
```
Then:
1. Head to "Settings" tab of your forked repository and in the sidebar, click "Pages". Under "Source", select "GitHub Actions".
2. Commit these changes by doing `npx quartz sync`. This should deploy your site to `<github-username>.github.io/<repository-name>`.
> [!hint]
> If you get an error about not being allowed to deploy to `github-pages` due to environment protection rules, make sure you remove any existing GitHub pages environments.
>
> You can do this by going to your Settings page on your GitHub fork and going to the Environments tab and pressing the trash icon. The GitHub action will recreate the environment for you correctly the next time you sync your Quartz.
### Custom Domain
Here's how to add a custom domain to your GitHub pages deployment.
1. Head to the "Settings" tab of your forked repository.
2. In the "Code and automation" section of the sidebar, click "Pages".
3. Under "Custom Domain", type your custom domain and click "Save".
4. This next step depends on whether you are using an apex domain (`example.com`) or a subdomain (`subdomain.example.com`).
- If you are using an apex domain, navigate to your DNS provider and create an `A` record that points your apex domain to GitHub's name servers which have the following IP addresses:
- `185.199.108.153`
- `185.199.109.153`
- `185.199.110.153`
- `185.199.111.153`
- If you are using a subdomain, navigate to your DNS provider and create a `CNAME` record that points your subdomain to the default domain for your site. For example, if you want to use the subdomain `quartz.example.com` for your user site, create a `CNAME` record that points `quartz.example.com` to `<github-username>.github.io`.
![[dns records.png]]_The above shows a screenshot of Google Domains configured for both `jzhao.xyz` (an apex domain) and `quartz.jzhao.xyz` (a subdomain)._
See the [GitHub documentation](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site#configuring-a-subdomain) for more detail about how to setup your own custom domain with GitHub Pages.
> [!question] Why aren't my changes showing up?
> There could be many different reasons why your changes aren't showing up but the most likely reason is that you forgot to push your changes to GitHub.
>
> Make sure you save your changes to Git and sync it to GitHub by doing `npx quartz sync`. This will also make sure to pull any updates you may have made from other devices so you have them locally.
## Vercel
### Fix URLs
Before deploying to Vercel, a `vercel.json` file is required at the root of the project directory. It needs to contain the following configuration so that URLs don't require the `.html` extension:
```json title="vercel.json"
{
"cleanUrls": true
}
```
### Deploy to Vercel
1. Log in to the [Vercel Dashboard](https://vercel.com/dashboard) and click "Add New..." > Project
2. Import the Git repository containing your Quartz project.
3. Give the project a name (lowercase characters and hyphens only)
4. Check that these configuration options are set:
| Configuration option | Value |
| ----------------------------------------- | ------------------ |
| Framework Preset | `Other` |
| Root Directory | `./` |
| Build and Output Settings > Build Command | `npx quartz build` |
5. Press Deploy. Once it's live, you'll have 2 `*.vercel.app` URLs to view the page.
### Custom Domain
> [!note]
> If there is something already hosted on the domain, these steps will not work without replacing the previous content. As a workaround, you could use Next.js rewrites or use the next section to create a subdomain.
1. Update the `baseUrl` in `quartz.config.js` if necessary.
2. Go to the [Domains - Dashboard](https://vercel.com/dashboard/domains) page in Vercel.
3. Connect the domain to Vercel
4. Press "Add" to connect a custom domain to Vercel.
5. Select your Quartz repository and press Continue.
6. Enter the domain you want to connect it to.
7. Follow the instructions to update your DNS records until you see "Valid Configuration"
### Use a Subdomain
Using `docs.example.com` is an example of a subdomain. They're a simple way of connecting multiple deployments to one domain.
1. Update the `baseUrl` in `quartz.config.js` if necessary.
2. Ensure your domain has been added to the [Domains - Dashboard](https://vercel.com/dashboard/domains) page in Vercel.
3. Go to the [Vercel Dashboard](https://vercel.com/dashboard) and select your Quartz project.
4. Go to the Settings tab and then click Domains in the sidebar
5. Enter your subdomain into the field and press Add
## GitLab Pages
You can configure GitLab CI to build and deploy a Quartz 4 project.
In your local Quartz, create a new file `.gitlab-ci.yaml`.
```yaml title=".gitlab-ci.yaml"
stages:
- build
- deploy
variables:
NODE_VERSION: "18.14"
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
script:
- npx prettier --write .
- npm run check
- npx quartz build
artifacts:
paths:
- public
cache:
paths:
- ~/.npm/
key: "${CI_COMMIT_REF_SLUG}-node-${CI_COMMIT_REF_NAME}"
tags:
- docker
pages:
stage: deploy
rules:
- if: '$CI_COMMIT_REF_NAME == "v4"'
script:
- echo "Deploying to GitLab Pages..."
artifacts:
paths:
- public
```
When `.gitlab-ci.yaml` is commited, GitLab will build and deploy the website as a GitLab Page. You can find the url under `Deploy` -> `Pages` in the sidebar.
By default, the page is private and only visible when logged in to a GitLab account with access to the repository but can be opened in the settings under `Deploy` -> `Pages`.

BIN
docs/images/dns records.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

45
docs/index.md Normal file
View File

@ -0,0 +1,45 @@
---
title: Welcome to Quartz 4
---
Quartz is a fast, batteries-included static-site generator that transforms Markdown content into fully functional websites. Thousands of students, developers, and teachers are [[showcase|already using Quartz]] to publish personal notes, wikis, and [digital gardens](https://jzhao.xyz/posts/networked-thought) to the web.
## 🪴 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.
Then, in your terminal of choice, enter the following commands line by line:
```shell
git clone https://github.com/jackyzha0/quartz.git
cd quartz
npm i
npx quartz create
```
This will guide you through initializing your Quartz with content. Once you've done so, see how to:
1. [[authoring content|Author content]] in Quartz
2. [[configuration|Configure]] Quartz's behaviour
3. Change Quartz's [[layout]]
4. [[build|Build and preview]] Quartz
5. [[hosting|Host]] Quartz online
> [!info]
> Coming from Quartz 3? See the [[migrating from Quartz 3|migration guide]] for the differences between Quartz 3 and Quartz 4 and how to migrate.
## 🔧 Features
- [[Obsidian compatibility]], [[full-text search]], [[graph view]], note transclusion, [[wikilinks]], [[backlinks]], [[Latex]], [[syntax highlighting]], [[popover previews]], [[Docker Support]], 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
- Fully-customizable parsing, filtering, and page generation through [[making plugins|plugins]]
For a comprehensive list of features, visit the [features page](/features). You can read more about the _why_ behind these features on the [[philosophy]] page and a technical overview on the [[architecture]] page.
### 🚧 Troubleshooting + Updating
Having trouble with Quartz? Try searching for your issue using the search feature. If you haven't already, [[upgrading|upgrade]] to the newest version of Quartz to see if this fixes your issue.
If you're still having trouble, feel free to [submit an issue](https://github.com/jackyzha0/quartz/issues) if you feel you found a bug or ask for help in our [Discord Community](https://discord.gg/cRFFHYye7t).

42
docs/layout.md Normal file
View File

@ -0,0 +1,42 @@
---
title: Layout
---
Certain emitters may also output [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) files. To enable easy customization, these emitters allow you to fully rearrange the layout of the page. The default page layouts can be found in `quartz.layout.ts`.
Each page is composed of multiple different sections which contain `QuartzComponents`. The following code snippet lists all of the valid sections that you can add components to:
```typescript title="quartz/cfg.ts"
export interface FullPageLayout {
head: QuartzComponent // single component
header: QuartzComponent[] // laid out horizontally
beforeBody: QuartzComponent[] // laid out vertically
pageBody: QuartzComponent // single component
left: QuartzComponent[] // vertical on desktop, horizontal on mobile
right: QuartzComponent[] // vertical on desktop, horizontal on mobile
footer: QuartzComponent // single component
}
```
These correspond to following parts of the page:
![[quartz layout.png|800]]
> [!note]
> There are two additional layout fields that are _not_ shown in the above diagram.
>
> 1. `head` is a single component that renders the `<head>` [tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head) in the HTML. This doesn't appear visually on the page and is only is responsible for metadata about the document like the tab title, scripts, and styles.
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. This enables you to replicate the old Quartz 3 header bar where the title, search bar, and dark mode toggle. By default, Quartz 4 doesn't place any components in the `header`.
Quartz **components**, like plugins, can take in additional properties as configuration options. If you're familiar with React terminology, you can think of them as Higher-order Components.
See [a list of all the components](component.md) for all available components along with their configuration options. You can also checkout the guide on [[creating components]] if you're interested in further customizing the behaviour of Quartz.
### Style
Most meaningful style changes like colour scheme and font can be done simply through the [[configuration#General Configuration|general configuration]] options. However, if you'd like to make more involved style changes, you can do this by writing your own styles. Quartz 4, like Quartz 3, uses [Sass](https://sass-lang.com/guide/) for styling.
You can see the base style sheet in `quartz/styles/base.scss` and write your own in `quartz/styles/custom.scss`.
> [!note]
> Some components may provide their own styling as well! For example, `quartz/components/Darkmode.tsx` imports styles from `quartz/components/styles/darkmode.scss`. If you'd like to customize styling for a specific component, double check the component definition to see how its styles are defined.

View File

@ -0,0 +1,41 @@
---
title: "Migrating from Quartz 3"
---
As you already have Quartz locally, you don't need to fork or clone it again. Simply just checkout the alpha branch, install the dependencies, and import your old vault.
```bash
git fetch
git checkout v4
git pull upstream v4
npm i
npx quartz create
```
If you get an error like `fatal: 'upstream' does not appear to be a git repository`, make sure you add `upstream` as a remote origin:
```shell
git remote add upstream https://github.com/jackyzha0/quartz.git
```
When running `npx quartz create`, you will be prompted as to how to initialize your content folder. Here, you can choose to import or link your previous content folder and Quartz should work just as you expect it to.
> [!note]
> If the existing content folder you'd like to use is at the _same_ path on a different branch, clone the repo again somewhere at a _different_ path in order to use it.
## Key changes
1. **Removing Hugo and `hugo-obsidian`**: Hugo worked well for earlier versions of Quartz but it also made it hard for people outside of the Golang and Hugo communities to fully understand what Quartz was doing under the hood and be able to properly customize it to their needs. Quartz 4 now uses a Node-based static-site generation process which should lead to a much more helpful error messages and an overall smoother user experience.
2. **Full-hot reload**: The many rough edges of how `hugo-obsidian` integrated with Hugo meant that watch mode didn't re-trigger `hugo-obsidian` to update the content index. This lead to a lot of weird cases where the watch mode output wasn't accurate. Quartz 4 now uses a cohesive parse, filter, and emit pipeline which gets run on every change so hot-reloads are always accurate.
3. **Replacing Go template syntax with JSX**: Quartz 3 used [Go templates](https://pkg.go.dev/text/template) to create layouts for pages. However, the syntax isn't great for doing any sort of complex rendering (like [text processing](https://github.com/jackyzha0/quartz/blob/hugo/layouts/partials/textprocessing.html)) and it got very difficult to make any meaningful layout changes to Quartz 3. Quartz 4 uses an extension of JavaScript syntax called JSX which allows you to write layout code that looks like HTML in JavaScript which is significantly easier to understand and maintain.
4. **A new extensible [[configuration]] and [[configuration#Plugins|plugin]] system**: Quartz 3 was hard to configure without technical knowledge of how Hugo's partials worked. Extensions were even hard to make. Quartz 4's configuration and plugin system is designed to be extended by users while making updating to new versions of Quartz easy.
## Things to update
- You will need to update your deploy scripts. See the [[hosting]] guide for more details.
- Ensure that your default branch on GitHub is updated from `hugo` to `v4`.
- [[folder and tag listings|Folder and tag listings]] have also changed.
- Folder descriptions should go under `content/<folder-name>/index.md` where `<folder-name>` is the name of the folder.
- Tag descriptions should go under `content/tags/<tag-name>.md` where `<tag-name>` is the name of the tag.
- Some HTML layout may not be the same between Quartz 3 and Quartz 4. If you depended on a particular HTML hierarchy or class names, you may need to update your custom CSS to reflect these changes.
- If you customized the layout of Quartz 3, you may need to translate these changes from Go templates back to JSX as Quartz 4 no longer uses Hugo. For components, check out the guide on [[creating components]] for more details on this.

28
docs/philosophy.md Normal file
View File

@ -0,0 +1,28 @@
---
title: Philosophy of Quartz
---
## A garden should be a true hypertext
> The garden is the web as topology. Every walk through the garden creates new paths, new meanings, and when we add things to the garden we add them in a way that allows many future, unpredicted relationships.
>
> _(The Garden and the Stream)_
The problem with the file cabinet is that it focuses on efficiency of access and interoperability rather than generativity and creativity. Thinking is not linear, nor is it hierarchical. In fact, not many things are linear or hierarchical at all. Then why is it that most tools and thinking strategies assume a nice chronological or hierarchical order for my thought processes? The ideal tool for thought for me would embrace the messiness of my mind, and organically help insights emerge from chaos instead of forcing an artificial order. A rhizomatic, not arboresecent, form of note taking.
My goal with a digital garden is not purely as an organizing system and information store (though it works nicely for that). I want my digital garden to be a playground for new ways ideas can connect together. As a result, existing formal organizing systems like Zettelkasten or the hierarchical folder structures of Notion dont work well for me. There is way too much upfront friction that by the time Ive thought about how to organize my thought into folders categories, Ive lost it.
Quartz embraces the inherent rhizomatic and web-like nature of our thinking and tries to encourage note-taking in a similar form.
---
## A garden should be shared
The goal of digital gardening should be to tap into your networks collective intelligence to create constructive feedback loops. If done well, I have a shareable representation of my thoughts that I can send out into the world and people can respond. Even for my most half-baked thoughts, this helps me create a feedback cycle to strengthen and fully flesh out that idea.
Quartz is designed first and foremost as a tool for publishing [digital gardens](https://jzhao.xyz/posts/networked-thought) to the web. To me, digital gardening is not just passive knowledge collection. Its a form of expression and sharing.
> “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.”
> — Richard Hamming
**The goal of Quartz is to make sharing your digital garden free and simple.** At its core, Quartz is designed to be easy to use enough for non-technical people to get going but also powerful enough that senior developers can tweak it to work how they'd like it to work.

24
docs/showcase.md Normal file
View File

@ -0,0 +1,24 @@
---
title: "Quartz Showcase"
---
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/)
- [Brandon Boswell's Garden](https://brandonkboswell.com)
- [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/)
- [AWAGMI Intern Notes](https://notes.awagmi.xyz/)
- [Data Dictionary 🧠](https://glossary.airbyte.com/)
- [sspaeti.com's Second Brain](https://brain.sspaeti.com/)
- [oldwinter の数字花园](https://garden.oldwinter.top/)
- [Abhijeet's Math Wiki](https://abhmul.github.io/quartz/Math-Wiki/)
- [Mike's AI Garden 🤖🪴](https://mwalton.me/)
- [Matt Dunn's Second Brain](https://mattdunn.info/)
- [Pelayo Arbues' Notes](https://pelayoarbues.github.io/)
- [Vince Imbat's Talahardin](https://vinceimbat.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/)
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)!

5
docs/tags/component.md Normal file
View File

@ -0,0 +1,5 @@
---
title: Components
---
Want to create your own custom component? Check out the advanced guide on [[creating components]] for more information.

19
docs/upgrading.md Normal file
View File

@ -0,0 +1,19 @@
---
title: "Upgrading Quartz"
---
> [!note]
> This is specifically a guide for upgrading Quartz 4 version to a more recent update. If you are coming from Quartz 3, check out the [[migrating from Quartz 3|migration guide]] for more info.
To fetch the latest Quartz updates, simply run
```bash
npx quartz update
```
As Quartz uses [git](https://git-scm.com/) under the hood for versioning, updating effectively 'pulls' in the updates from the official Quartz GitHub repository. If you have local changes that might conflict with the updates, you may need to resolve these manually yourself (or, pull manually using `git pull origin upstream`).
> [!hint]
> Quartz will try to cache your content before updating to try and prevent merge conflicts. If you get a conflict mid-merge, you can stop the merge and then run `npx quartz restore` to restore your content from the cache.
If you have the [GitHub desktop app](https://desktop.github.com/), this will automatically open to help you resolve the conflicts. Otherwise, you will need to resolve this in a text editor like VSCode. For more help on resolving conflicts manually, check out the [GitHub guide on resolving merge conflicts](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line#competing-line-change-merge-conflicts).

12
globals.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
export declare global {
interface Document {
addEventListener<K extends keyof CustomEventMap>(
type: K,
listener: (this: Document, ev: CustomEventMap[K]) => void,
): void
dispatchEvent<K extends keyof CustomEventMap>(ev: CustomEventMap[K]): void
}
interface Window {
spaNavigate(url: URL, isBack: boolean = false)
}
}

11
index.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
declare module "*.scss" {
const content: string
export = content
}
// dom custom event
interface CustomEventMap {
nav: CustomEvent<{ url: FullSlug }>
}
declare const fetchData: Promise<ContentIndex>

View File

@ -1,22 +0,0 @@
<!DOCTYPE html>
<html lang="en">
{{ partial "head.html" . }}
<body>
<div class="singlePage">
{{partial "darkmode.html" .}}
<div class="centered">
<h1>404.</h1>
<h3>Hey! You look a little lost. This page doesn't exist (or may be private).</h3>
<a href="/">↳ Let's get you home.</a>
</div>
</div>
{{- with resources.Get "darkmode.js" | minify -}}
<script>
{{.Content | safeJS }}
</script>
{{- end -}}
</body>
</html>

View File

@ -1,7 +0,0 @@
{{$trimmed := strings.TrimSuffix ".md" (.Destination | safeURL)}}
{{$external := strings.HasPrefix $trimmed "http" }}
{{ if $external }}
<a href="{{ $trimmed }}" rel="noopener">{{ .Text | safeHTML }}</a>
{{else}}
<a href="{{ if (hasPrefix $trimmed "/") }}{{ $trimmed }}{{ else }}{{ print "/" $trimmed }}{{ end }}" rel="noopener">{{ .Text | safeHTML }}</a>
{{end}}

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
{{ block "head" . }}
{{ end }}
<body>
{{ block "main" . }}
{{ end }}
</body>
</html>

View File

@ -1,35 +0,0 @@
<!DOCTYPE html>
<html lang="en">
{{ partial "head.html" . }}
<body>
{{partial "search.html" .}}
<div class="singlePage">
<!-- Begin actual content -->
<header>
{{if .Title}}<h1>{{ .Title }}</h1>{{end}}
<svg tabindex="0" id="search-icon" aria-labelledby="title desc" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.9 19.7"><title id="title">Search Icon</title><desc id="desc">Icon to open search</desc><g class="search-path" fill="none"><path stroke-linecap="square" d="M18.5 18.3l-5.4-5.4"/><circle cx="8" cy="8" r="7"/></g></svg>
<div class="spacer"></div>
{{partial "darkmode.html" .}}
</header>
<article>
{{if $.Site.Data.config.enableToc}}
<aside class="mainTOC">
<h3>Table of Contents</h3>
{{ .TableOfContents }}
</aside>
{{end}}
{{- .Content -}}
</article>
{{partial "footer.html" .}}
</div>
{{- with resources.Get "darkmode.js" | minify -}}
<script>
{{.Content | safeJS }}
</script>
{{- end -}}
</body>
</html>

View File

@ -1,22 +0,0 @@
{{define "head"}}
{{ partial "head.html" . }}
{{end}}
{{define "main"}}
<!-- Main Page -->
<div class="singlePage">
{{partial "darkmode.html" .}}
{{.Content}}
<!-- Contact Info -->
<div>
{{partial "footer.html" .}}
</div>
</div>
{{- with resources.Get "darkmode.js" | minify -}}
<script>
{{.Content | safeJS }}
</script>
{{- end -}}
{{end}}

View File

@ -1,18 +0,0 @@
<h3>Backlinks</h3>
<ul class="backlinks">
{{$url := urls.Parse .Site.BaseURL }}
{{$host := strings.TrimRight "/" $url.Path }}
{{$curPage := strings.TrimPrefix $host (strings.TrimRight "/" .Page.RelPermalink) }}
{{$inbound := index $.Site.Data.linkIndex.index.backlinks $curPage}}
{{if $inbound}}
{{- range $inbound -}}
<li>
<a href="{{index . "source"}}">{{index . "source"}}</a>
</li>
{{- end -}}
{{else}}
<li>
No backlinks found
</li>
{{end}}
</ul>

View File

@ -1,15 +0,0 @@
<div class='darkmode'>
<input class='toggle' id='darkmode-toggle' type='checkbox' tabindex="-1">
<label id="toggle-label-light" for='darkmode-toggle' tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="dayIcon" x="0px" y="0px" viewBox="0 0 35 35" style="enable-background:new 0 0 35 35;" xml:space="preserve">
<title>Light Mode</title>
<path d="M6,17.5C6,16.672,5.328,16,4.5,16h-3C0.672,16,0,16.672,0,17.5 S0.672,19,1.5,19h3C5.328,19,6,18.328,6,17.5z M7.5,26c-0.414,0-0.789,0.168-1.061,0.439l-2,2C4.168,28.711,4,29.086,4,29.5 C4,30.328,4.671,31,5.5,31c0.414,0,0.789-0.168,1.06-0.44l2-2C8.832,28.289,9,27.914,9,27.5C9,26.672,8.329,26,7.5,26z M17.5,6 C18.329,6,19,5.328,19,4.5v-3C19,0.672,18.329,0,17.5,0S16,0.672,16,1.5v3C16,5.328,16.671,6,17.5,6z M27.5,9 c0.414,0,0.789-0.168,1.06-0.439l2-2C30.832,6.289,31,5.914,31,5.5C31,4.672,30.329,4,29.5,4c-0.414,0-0.789,0.168-1.061,0.44 l-2,2C26.168,6.711,26,7.086,26,7.5C26,8.328,26.671,9,27.5,9z M6.439,8.561C6.711,8.832,7.086,9,7.5,9C8.328,9,9,8.328,9,7.5 c0-0.414-0.168-0.789-0.439-1.061l-2-2C6.289,4.168,5.914,4,5.5,4C4.672,4,4,4.672,4,5.5c0,0.414,0.168,0.789,0.439,1.06 L6.439,8.561z M33.5,16h-3c-0.828,0-1.5,0.672-1.5,1.5s0.672,1.5,1.5,1.5h3c0.828,0,1.5-0.672,1.5-1.5S34.328,16,33.5,16z M28.561,26.439C28.289,26.168,27.914,26,27.5,26c-0.828,0-1.5,0.672-1.5,1.5c0,0.414,0.168,0.789,0.439,1.06l2,2 C28.711,30.832,29.086,31,29.5,31c0.828,0,1.5-0.672,1.5-1.5c0-0.414-0.168-0.789-0.439-1.061L28.561,26.439z M17.5,29 c-0.829,0-1.5,0.672-1.5,1.5v3c0,0.828,0.671,1.5,1.5,1.5s1.5-0.672,1.5-1.5v-3C19,29.672,18.329,29,17.5,29z M17.5,7 C11.71,7,7,11.71,7,17.5S11.71,28,17.5,28S28,23.29,28,17.5S23.29,7,17.5,7z M17.5,25c-4.136,0-7.5-3.364-7.5-7.5 c0-4.136,3.364-7.5,7.5-7.5c4.136,0,7.5,3.364,7.5,7.5C25,21.636,21.636,25,17.5,25z" />
</svg>
</label>
<label id="toggle-label-dark" for='darkmode-toggle' tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="nightIcon" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background='new 0 0 100 100'" xml:space="preserve">
<title>Dark Mode</title>
<path d="M96.76,66.458c-0.853-0.852-2.15-1.064-3.23-0.534c-6.063,2.991-12.858,4.571-19.655,4.571 C62.022,70.495,50.88,65.88,42.5,57.5C29.043,44.043,25.658,23.536,34.076,6.47c0.532-1.08,0.318-2.379-0.534-3.23 c-0.851-0.852-2.15-1.064-3.23-0.534c-4.918,2.427-9.375,5.619-13.246,9.491c-9.447,9.447-14.65,22.008-14.65,35.369 c0,13.36,5.203,25.921,14.65,35.368s22.008,14.65,35.368,14.65c13.361,0,25.921-5.203,35.369-14.65 c3.872-3.871,7.064-8.328,9.491-13.246C97.826,68.608,97.611,67.309,96.76,66.458z" />
</svg>
</label>
</div>

View File

@ -1,22 +0,0 @@
<hr/>
<div class="page-end">
<div class="backlinks-container">
{{partial "backlinks.html" .}}
</div>
<div>
{{partial "graph.html" .}}
</div>
</div>
<!-- Contact Info -->
<div id="contact_buttons">
<footer>
<p>Made by {{ $.Site.Data.config.name }} using <a href="https://github.com/jackyzha0/quartz">Quartz</a>, © {{ dateFormat "2006" now }}</p>
{{ if not .IsHome }}
<a href="/">Home</a>
{{end}}
{{- range $.Site.Data.config.links -}}
<a href="{{.link}}">{{.link_name}}</a>
{{- end -}}
</footer>
</div>

View File

@ -1,219 +0,0 @@
<script src="https://cdn.jsdelivr.net/npm/d3@6"></script>
<h3>Interactive Graph</h3>
<div id="graph-container"></div>
<style>
:root {
--g-node: var(--secondary);
--g-node-active: var(--primary);
--g-node-inactive: var(--visited);
--g-link: var(--outlinegray);
--g-link-active: #5a7282;
}
</style>
<script>
const index = {{$.Site.Data.linkIndex.index}}
const links = {{$.Site.Data.linkIndex.links}}
const curPage = {{ strings.TrimRight "/" .Page.RelPermalink }}
const pathColors = {{$.Site.Data.graphConfig.paths}}
const parseIdsFromLinks = (links) => [...(new Set(links.flatMap(link => ([link.source, link.target]))))]
const data = {
nodes: parseIdsFromLinks(links).map(id => ({id})),
links,
}
const color = (d) => {
if (d.id === curPage || (d.id === "/" && curPage === "")) {
return "var(--g-node-active)"
}
for (const pathColor of pathColors) {
const path = Object.keys(pathColor)[0]
const colour = pathColor[path]
if (d.id.startsWith(path)) {
return colour
}
}
return "var(--g-node)"
}
const drag = simulation => {
function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(1).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(event,d) {
d.fx = event.x;
d.fy = event.y;
}
function dragended(event,d) {
if (!event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
const enableDrag = {{$.Site.Data.graphConfig.enableDrag}}
const noop = () => {}
return d3.drag()
.on("start", enableDrag ? dragstarted : noop)
.on("drag", enableDrag ? dragged : noop)
.on("end", enableDrag ? dragended : noop);
}
const height = 250
const width = document.getElementById("graph-container").offsetWidth
const simulation = d3.forceSimulation(data.nodes)
.force("charge", d3.forceManyBody().strength(-20))
.force("link", d3.forceLink(data.links)
.id(d => d.id)
)
.force("center", d3.forceCenter());
const svg = d3.select('#graph-container')
.append('svg')
.attr('width', width)
.attr('height', height)
.attr("viewBox", [-width / 2, -height / 2, width, height]);
// legend
const enableLegend = {{$.Site.Data.graphConfig.enableLegend}}
if (enableLegend) {
const legend = [
{"Current": "var(--g-node-active)"},
{"Note": "var(--g-node)"},
...pathColors
]
legend.forEach((legendEntry, i) => {
const key = Object.keys(legendEntry)[0]
const colour = legendEntry[key]
svg.append("circle").attr("cx", -width/2 + 20).attr("cy", height/2 - 30 * (i+1)).attr("r", 6).style("fill", colour)
svg.append("text").attr("x", -width/2 + 40).attr("y", height/2 - 30 * (i+1)).text(key).style("font-size", "15px").attr("alignment-baseline","middle")
})
}
// draw links between nodes
const link = svg.append("g")
.selectAll("line")
.data(data.links)
.join("line")
.attr("class", "link")
.attr("stroke", "var(--g-link)")
.attr("stroke-width", 2)
.attr("data-source", d => d.source.id)
.attr("data-target", d => d.target.id)
// svg groups
const graphNode = svg.append("g")
.selectAll("g")
.data(data.nodes)
.enter().append("g")
// draw individual nodes
const node = graphNode.append("circle")
.attr("class", "node")
.attr("id", (d) => d.id)
.attr("r", (d) => {
const numOut = index.links[d.id]?.length || 0
const numIn = index.backlinks[d.id]?.length || 0
return 3 + (numOut + numIn) / 4
})
.attr("fill", color)
.style("cursor", "pointer")
.on("click", (_, d) => {
window.location.href = {{.Site.BaseURL}} + d.id;
})
.on("mouseover", function (_, d) {
d3.selectAll(".node")
.transition()
.duration(100)
.attr("fill", "var(--g-node-inactive)")
const neighbours = parseIdsFromLinks([...(index.links[d.id] || []), ...(index.backlinks[d.id] || [])])
const neighbourNodes = d3.selectAll(".node").filter(d => neighbours.includes(d.id))
const currentId = d.id
const links = d3.selectAll(".link").filter(d => d.source.id === currentId || d.target.id === currentId)
// highlight neighbour nodes
neighbourNodes
.transition()
.duration(200)
.attr("fill", color)
// highlight links
links
.transition()
.duration(200)
.attr("stroke", "var(--g-link-active)")
// show text for self
d3.select(this.parentNode)
.select("text")
.raise()
.transition()
.duration(200)
.style("opacity", 1)
}).on("mouseleave", function (_,d) {
d3.selectAll(".node")
.transition()
.duration(200)
.attr("fill", color)
const currentId = d.id
const links = d3.selectAll(".link").filter(d => d.source.id === currentId || d.target.id === currentId)
links
.transition()
.duration(200)
.attr("stroke", "var(--g-link)")
d3.select(this.parentNode)
.select("text")
.transition()
.duration(200)
.style("opacity", 0)
})
.call(drag(simulation));
// draw labels
const labels = graphNode.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text((d) => d.id)
.style("opacity", 0)
.style("pointer-events", "none")
.call(drag(simulation));
// set panning
const enableZoom = {{$.Site.Data.graphConfig.enableZoom}}
if (enableZoom) {
svg.call(d3.zoom()
.extent([[0, 0], [width, height]])
.scaleExtent([0.25, 4])
.on("zoom", ({transform}) => {
link.attr("transform", transform);
node.attr("transform", transform);
labels.attr("transform", transform);
}));
}
// progress the simulation
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
labels
.attr("x", d => d.x)
.attr("y", d => d.y);
});
</script>

View File

@ -1,21 +0,0 @@
<head>
<!-- Meta tags -->
<meta charset="UTF-8">
<meta name="description" content="{{$.Site.Data.config.description}}">
<title>{{ if .Title }}{{ .Title }}{{ else }}{{ $.Site.Data.config.page_title }}{{ end }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/png" href="/icon.png" />
<!-- CSS Stylesheets and Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&family=Source+Sans+Pro:wght@400;700&family=Fira+Code:wght@400;700&display=swap" rel="stylesheet">
{{ $css := slice "custom.scss" "base.scss" "darkmode.scss" "syntax.scss"}}
{{range $css}}
{{$sass := resources.Get . | resources.ToCSS }}
{{with $sass | minify}}
<style>
{{.Content | safeCSS}}
</style>
{{end}}
{{end}}
</head>
{{ template "_internal/google_analytics.html" . }}

View File

@ -1,208 +0,0 @@
<div id="search-container">
<div>
<input autocomplete="off" id="search-bar" name="search" type="text" aria-label="Search" placeholder="Search for something...">
<div id="results-container">
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@0.7.2/dist/flexsearch.bundle.js"></script>
<script>
// code from https://github.com/danestves/markdown-to-text
const removeMarkdown = (
markdown,
options = {
listUnicodeChar: false,
stripListLeaders: true,
gfm: true,
useImgAltText: false,
preserveLinks: false,
}
) => {
let output = markdown || "";
output = output.replace(/^(-\s*?|\*\s*?|_\s*?){3,}\s*$/gm, "");
try {
if (options.stripListLeaders) {
if (options.listUnicodeChar)
output = output.replace(
/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm,
options.listUnicodeChar + " $1"
);
else output = output.replace(/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm, "$1");
}
if (options.gfm) {
output = output
.replace(/\n={2,}/g, "\n")
.replace(/~{3}.*\n/g, "")
.replace(/~~/g, "")
.replace(/`{3}.*\n/g, "");
}
if(options.preserveLinks) {
output = output.replace(/\[(.*?)\][\[\(](.*?)[\]\)]/g, "$1 ($2)")
}
output = output
.replace(/<[^>]*>/g, "")
.replace(/^[=\-]{2,}\s*$/g, "")
.replace(/\[\^.+?\](\: .*?$)?/g, "")
.replace(/\s{0,2}\[.*?\]: .*?$/g, "")
.replace(/\!\[(.*?)\][\[\(].*?[\]\)]/g, options.useImgAltText ? "$1" : "")
.replace(/\[(.*?)\][\[\(].*?[\]\)]/g, "$1")
.replace(/^\s{0,3}>\s?/g, "")
.replace(/(^|\n)\s{0,3}>\s?/g, "\n\n")
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, "")
.replace(
/^(\n)?\s{0,}#{1,6}\s+| {0,}(\n)?\s{0,}#{0,} {0,}(\n)?\s{0,}$/gm,
"$1$2$3"
)
.replace(/([\*_]{1,3})(\S.*?\S{0,1})\1/g, "$2")
.replace(/([\*_]{1,3})(\S.*?\S{0,1})\1/g, "$2")
.replace(/(`{3,})(.*?)\1/gm, "$2")
.replace(/`(.+?)`/g, "$1")
.replace(/\n{2,}/g, "\n\n");
} catch (e) {
console.error(e);
return markdown;
}
return output;
};
</script>
<script>
const contentIndex = new FlexSearch.Worker({
tokenize: "strict",
charset: "latin:advanced",
context: true,
depth: 3,
cache: 10,
suggest: true,
})
const scrapedContent = {{$.Site.Data.contentIndex}}
for (const [key, value] of Object.entries(scrapedContent)) {
contentIndex.add(key, value.content)
}
const stopwords = ['i','me','my','myself','we','our','ours','ourselves','you','your','yours','yourself','yourselves','he','him','his','himself','she','her','hers','herself','it','its','itself','they','them','their','theirs','themselves','what','which','who','whom','this','that','these','those','am','is','are','was','were','be','been','being','have','has','had','having','do','does','did','doing','a','an','the','and','but','if','or','because','as','until','while','of','at','by','for','with','about','against','between','into','through','during','before','after','above','below','to','from','up','down','in','out','on','off','over','under','again','further','then','once','here','there','when','where','why','how','all','any','both','each','few','more','most','other','some','such','no','nor','not','only','own','same','so','than','too','very','s','t','can','will','just','don','should','now']
const highlight = (content, term) => {
const highlightWindow = 15
const tokenizedTerm = term.split(/\s+/).filter(t => t !== "")
const splitText = content.split(/\s+/).filter(t => t !== "")
const includesCheck = (token) => tokenizedTerm.some(term => token.toLowerCase().includes(term.toLowerCase()))
const occurrencesIndices = splitText
.map(includesCheck)
// calculate best index
let bestSum = 0
let bestIndex = 0
for (let i = 0; i < Math.max(occurrencesIndices.length - highlightWindow, 0); i++) {
const window = occurrencesIndices.slice(i, i + highlightWindow)
const windowSum = window.reduce((total, cur) => total + cur, 0)
if (windowSum > bestSum) {
bestSum = windowSum
bestIndex = i
}
}
const startIndex = Math.max(bestIndex - highlightWindow, 0)
const endIndex = Math.min(startIndex + 2 * highlightWindow, splitText.length)
const mappedText = splitText
.slice(startIndex, endIndex)
.map(token => {
if (includesCheck(token)) {
return `<span class="search-highlight">${token}</span>`
}
return token
})
.join(" ")
.replaceAll('</span> <span class="search-highlight">', " ")
return `${startIndex === 0 ? "" : "..."}${mappedText}${endIndex === splitText.length ? "" : "..."}`
}
const resultToHTML = ({url, title, content, term}) => {
const md = content.split("---")[2]
const text = removeMarkdown(md)
const resultTitle = highlight(title, term)
const resultText = highlight(text, term)
return `<div class="result-card" id="${url}">
<h3>${resultTitle}</h3>
<p>${resultText}</p>
</div>`
}
const source = document.getElementById('search-bar')
const results = document.getElementById("results-container")
source.addEventListener('input', (e) => {
const term = e.target.value
contentIndex.search(term, {
limit: 5,
depth: 3,
suggest: true,
}).then(searchResults => {
const resultIds = [...new Set(searchResults)]
const finalResults = resultIds.map(id => ({
url: id,
title: scrapedContent[id].title,
content: scrapedContent[id].content
}))
// display
if (finalResults.length === 0) {
results.innerHTML = `<div class="result-card">
<p>No results.</p>
</div>`
} else {
results.innerHTML = finalResults
.map(result => resultToHTML({
...result,
term,
}))
.join("\n")
const anchors = document.getElementsByClassName("result-card");
[...anchors].forEach(anchor => {
anchor.onclick = () => {
window.location.href = `${anchor.id}#:~:text=${encodeURIComponent(term)}`
}
})
}
})
})
const searchContainer = document.getElementById("search-container")
function openSearch() {
if (searchContainer.style.display === "none" || searchContainer.style.display === "") {
source.value = ""
results.innerHTML = ""
searchContainer.style.display = "block"
source.focus()
} else {
searchContainer.style.display = "none"
}
}
function closeSearch() {
searchContainer.style.display = "none"
}
document.addEventListener('keydown', (event) => {
if (event.key === "/") {
event.preventDefault()
openSearch()
}
if (event.key === "Escape") {
event.preventDefault()
closeSearch()
}
})
window.addEventListener('DOMContentLoaded', () => {
const searchButton = document.getElementById("search-icon")
searchButton.addEventListener('click', (evt) => {
openSearch()
})
searchButton.addEventListener('keydown', (evt) => {
openSearch()
})
})
</script>

6213
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

109
package.json Normal file
View File

@ -0,0 +1,109 @@
{
"name": "@jackyzha0/quartz",
"description": "🌱 publish your digital garden and notes as a website",
"private": true,
"version": "4.1.1",
"type": "module",
"author": "jackyzha0 <j.zhao2k19@gmail.com>",
"license": "MIT",
"homepage": "https://quartz.jzhao.xyz",
"repository": {
"type": "git",
"url": "https://github.com/jackyzha0/quartz.git"
},
"scripts": {
"docs": "npx quartz build --serve -d docs",
"check": "tsc --noEmit && npx prettier . --check",
"format": "npx prettier . --write",
"test": "tsx ./quartz/util/path.test.ts",
"profile": "0x -D prof ./quartz/bootstrap-cli.mjs build --concurrency=1"
},
"engines": {
"npm": ">=9.3.1",
"node": ">=18.14"
},
"keywords": [
"site generator",
"ssg",
"digital-garden",
"markdown",
"blog",
"quartz"
],
"bin": {
"quartz": "./quartz/bootstrap-cli.mjs"
},
"dependencies": {
"@clack/prompts": "^0.6.3",
"@floating-ui/dom": "^1.4.0",
"@napi-rs/simple-git": "0.1.9",
"async-mutex": "^0.4.0",
"chalk": "^4.1.2",
"chokidar": "^3.5.3",
"cli-spinner": "^0.2.10",
"d3": "^7.8.5",
"esbuild-sass-plugin": "^2.12.0",
"flexsearch": "0.7.21",
"github-slugger": "^2.0.0",
"globby": "^13.1.4",
"gray-matter": "^4.0.3",
"hast-util-to-html": "^8.0.4",
"hast-util-to-jsx-runtime": "^1.2.0",
"hast-util-to-string": "^2.0.0",
"is-absolute-url": "^4.0.1",
"js-yaml": "^4.1.0",
"lightningcss": "1.21.7",
"mdast-util-find-and-replace": "^2.2.2",
"mdast-util-to-hast": "^12.3.0",
"mdast-util-to-string": "^3.2.0",
"micromorph": "^0.4.5",
"plausible-tracker": "^0.3.8",
"preact": "^10.14.1",
"preact-render-to-string": "^6.0.3",
"pretty-bytes": "^6.1.0",
"pretty-time": "^1.1.0",
"reading-time": "^1.5.0",
"rehype-autolink-headings": "^6.1.1",
"rehype-katex": "^6.0.3",
"rehype-mathjax": "^4.0.3",
"rehype-pretty-code": "^0.10.0",
"rehype-raw": "^6.1.1",
"rehype-slug": "^5.1.0",
"remark": "^14.0.2",
"remark-breaks": "^3.0.3",
"remark-frontmatter": "^4.0.1",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"remark-parse": "^10.0.1",
"remark-rehype": "^10.1.0",
"remark-smartypants": "^2.0.0",
"rimraf": "^5.0.1",
"serve-handler": "^6.1.5",
"source-map-support": "^0.5.21",
"to-vfile": "^7.2.4",
"toml": "^3.0.0",
"unified": "^10.1.2",
"unist-util-visit": "^4.1.2",
"vfile": "^5.3.7",
"workerpool": "^6.4.0",
"ws": "^8.13.0",
"yargs": "^17.7.2"
},
"devDependencies": {
"@types/cli-spinner": "^0.2.1",
"@types/d3": "^7.4.0",
"@types/flexsearch": "^0.7.3",
"@types/hast": "^2.3.4",
"@types/js-yaml": "^4.0.5",
"@types/node": "^20.1.2",
"@types/pretty-time": "^1.1.2",
"@types/source-map-support": "^0.5.6",
"@types/workerpool": "^6.4.0",
"@types/ws": "^8.5.5",
"@types/yargs": "^17.0.24",
"esbuild": "0.19.2",
"prettier": "^3.0.0",
"tsx": "^3.12.7",
"typescript": "^5.0.4"
}
}

77
quartz.config.ts Normal file
View File

@ -0,0 +1,77 @@
import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"
const config: QuartzConfig = {
configuration: {
pageTitle: "notes.velouria.dev ",
enableSPA: true,
enablePopovers: true,
analytics: {
provider: "plausible",
},
baseUrl: "notes.velouria.dev",
ignorePatterns: ["private", "templates", ".obsidian"],
defaultDateType: "created",
theme: {
typography: {
header: "Inter",
body: "Shippori Mincho",
code: "IBM Plex Mono",
},
colors: {
lightMode: {
light: "#faf8f8",
lightgray: "#e5e5e5",
gray: "#b8b8b8",
darkgray: "#4e4e4e",
dark: "#2b2b2b",
secondary: "#284b63",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
},
darkMode: {
light: "#161618",
lightgray: "#393639",
gray: "#646464",
darkgray: "#d4d4d4",
dark: "#ebebec",
secondary: "#7b97aa",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
},
},
},
},
plugins: {
transformers: [
Plugin.FrontMatter(),
Plugin.TableOfContents(),
Plugin.CreatedModifiedDate({
priority: ["frontmatter", "filesystem"], // you can add 'git' here for last modified from Git but this makes the build slower
}),
Plugin.SyntaxHighlighting(),
Plugin.ObsidianFlavoredMarkdown({ enableInHtmlEmbed: false }),
Plugin.GitHubFlavoredMarkdown(),
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
Plugin.Latex({ renderEngine: "katex" }),
Plugin.Description(),
],
filters: [Plugin.RemoveDrafts()],
emitters: [
Plugin.AliasRedirects(),
Plugin.ComponentResources({ fontOrigin: "googleFonts" }),
Plugin.ContentPage(),
Plugin.FolderPage(),
Plugin.TagPage(),
Plugin.ContentIndex({
enableSiteMap: true,
enableRSS: true,
}),
Plugin.Assets(),
Plugin.Static(),
Plugin.NotFoundPage(),
],
},
}
export default config

46
quartz.layout.ts Normal file
View File

@ -0,0 +1,46 @@
import { PageLayout, SharedLayout } from "./quartz/cfg"
import * as Component from "./quartz/components"
// components shared across all pages
export const sharedPageComponents: SharedLayout = {
head: Component.Head(),
header: [],
footer: Component.Footer({
links: {
},
}),
}
// components for pages that display a single page (e.g. a single note)
export const defaultContentPageLayout: PageLayout = {
beforeBody: [
Component.Breadcrumbs(),
Component.ArticleTitle(),
Component.ContentMeta(),
Component.TagList(),
],
left: [
Component.PageTitle(),
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
Component.DesktopOnly(Component.Explorer()),
],
right: [
Component.Graph(),
Component.DesktopOnly(Component.TableOfContents()),
Component.Backlinks(),
],
}
// components for pages that display lists of pages (e.g. tags or folders)
export const defaultListPageLayout: PageLayout = {
beforeBody: [Component.ArticleTitle()],
left: [
Component.PageTitle(),
Component.MobileOnly(Component.Spacer()),
Component.Search(),
Component.Darkmode(),
],
right: [],
}

41
quartz/bootstrap-cli.mjs Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/env node
import yargs from "yargs"
import { hideBin } from "yargs/helpers"
import {
handleBuild,
handleCreate,
handleUpdate,
handleRestore,
handleSync,
} from "./cli/handlers.js"
import { CommonArgv, BuildArgv, CreateArgv, SyncArgv } from "./cli/args.js"
import { version } from "./cli/constants.js"
yargs(hideBin(process.argv))
.scriptName("quartz")
.version(version)
.usage("$0 <cmd> [args]")
.command("create", "Initialize Quartz", CreateArgv, async (argv) => {
await handleCreate(argv)
})
.command("update", "Get the latest Quartz updates", CommonArgv, async (argv) => {
await handleUpdate(argv)
})
.command(
"restore",
"Try to restore your content folder from the cache",
CommonArgv,
async (argv) => {
await handleRestore(argv)
},
)
.command("sync", "Sync your Quartz to and from GitHub.", SyncArgv, async (argv) => {
await handleSync(argv)
})
.command("build", "Build Quartz into a bundle of static HTML files", BuildArgv, async (argv) => {
await handleBuild(argv)
})
.showHelpOnFail(false)
.help()
.strict()
.demandCommand().argv

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