Compare commits

...

833 Commits
v4.1.0 ... main

Author SHA1 Message Date
Gal 971c16f3b8
Change font 2025-03-18 09:29:35 +01:00
Gal 71b8147a05
fix: image path 2025-02-24 07:48:15 +01:00
Gal 8e5e121f29
fix: modify publish symbolic link 2025-02-23 23:50:26 +01:00
Gal 98d4db67ea
fix: load env 2025-02-22 11:25:55 +01:00
Gal 00b048f177
refactor: update publish script 2025-02-22 11:23:22 +01:00
Gal 9300e1a362
Hide metadata 2025-02-12 00:15:18 +01:00
Gal 56c2d0455b
Change name 2024-04-11 08:19:57 +02:00
Gal ad3d5754e7
Change name 2024-04-11 08:12:30 +02:00
Gal 7459f2b158
🐛 Replace file if content is different 2024-03-24 18:51:37 +01:00
Gal ddb3af1f46
Unpublish posts 2024-03-02 09:15:33 +01:00
Gal 3e162637f5
Add diagram of current setup 2024-03-02 08:58:14 +01:00
Gal 6bdb536366
🐛 Fix links to broken images 2024-03-02 08:50:28 +01:00
Gal 5ffd94d9ca
Add clean function 2024-02-15 00:15:16 +01:00
Gal c91fe60268
🐛 Debug 2024-02-14 23:06:31 +01:00
Gal e46cf2e130
🐛 Fix quote bug 2024-02-14 22:59:42 +01:00
Gal aae3847a46
🔨 Keep DEST_DIR and SOURCE_DIR in sync 2024-02-14 22:42:14 +01:00
Gal 1c2996acc4
🔨 Keep DEST_DIR and SOURCE_DIR in sync 2024-02-14 22:27:27 +01:00
Gal 685f214d16
🔨 Keep DEST_DIR and SOURCE_DIR in sync 2024-02-14 22:11:33 +01:00
Gal fcccfaff3c
Add ignorepatterns 2024-02-14 22:00:04 +01:00
Gal 7822c38e99
Add try catch 2024-02-14 21:58:24 +01:00
Gal e35a9119a9
Add logging 2024-02-13 23:33:25 +01:00
Gal baebdbd22f
🐛 Make strict all deps 2024-02-13 23:06:21 +01:00
Gal 1514870931
🐛 Remove package-lock 2024-02-13 22:54:13 +01:00
Gal dcdcb0e8a8
Remove excessive logging and skip copy if file already exists 2024-02-13 22:31:09 +01:00
Gal 5357fbb572
Remove excessive logging 2024-02-13 22:25:35 +01:00
Gal b4fb95ffe6
Skip if file already exists 2024-02-13 22:23:39 +01:00
Gal 8a1964be84
🐛 Fix image compression 2024-02-13 22:02:24 +01:00
Gal 1fe0f662f0
Trying to make image compression work istg 2024-02-13 21:02:37 +01:00
Gal b66cc4b418
Compress image 2024-02-11 20:35:21 +01:00
Gal dece24b2bf Remove /content directory 2024-02-11 15:58:48 +01:00
Gal c636f79a9d Initial commit 2024-02-11 15:52:45 +01:00
Gal 77483a9fff Update 2024-01-21 21:56:22 +07:00
Gal 3337586250 test 2023-12-30 00:01:03 +01:00
Gal 5eb77f075d test 2023-12-29 22:41:52 +01:00
Gal 49b9d894b1 test 2023-12-29 22:40:22 +01:00
Gal b3d908132f test 2023-12-29 22:38:22 +01:00
Gal cae20f340d test 2023-12-29 22:36:31 +01:00
Gal 6bca301b22 test 2023-12-29 18:26:41 +01:00
Gal 5f990ab9fb test 2023-12-29 18:18:45 +01:00
Gal 3c15cf0eba Change config 2023-12-29 18:13:23 +01:00
Gal 04d7bd7b41 add network 2023-12-28 22:55:02 +01:00
Gal 32a0b781ad remove network 2023-12-27 23:53:57 +01:00
Gal f918b1b21c change port 2023-12-27 23:47:43 +01:00
Gal 8391e482c6 change port 2023-12-27 23:43:03 +01:00
Gal 11e5964cda change port 2023-12-27 23:42:38 +01:00
Gal 5abe832c9c change port 2023-12-27 23:41:25 +01:00
Gal 86753b4b52 Add traefik 2023-12-27 23:28:24 +01:00
Gal accc315672 Update 2023-12-27 22:11:25 +01:00
Gal 50c481541c update readme 2023-12-27 22:09:22 +01:00
Gal 4a9e82becb Add env 2023-12-27 22:06:00 +01:00
Gal 7c45eec14c Add script 2023-12-27 22:04:30 +01:00
Gal 8c4963ba93 Update makefile 2023-12-27 22:04:12 +01:00
Gal ee6bbaa156 Update makefile 2023-12-27 21:38:36 +01:00
Gal 54a8284d02 Update makefile 2023-12-27 21:38:12 +01:00
Gal cb4a2823be Add scripts 2023-12-27 21:35:10 +01:00
Gal d3eacb10af change port 2023-12-27 00:58:43 +01:00
Gal bfed71a040 change port 2023-12-27 00:30:20 +01:00
Gal d741508721 test change 2023-12-26 14:25:27 +01:00
Gal 7beed09824 update 2023-12-26 14:22:56 +01:00
Gal 5d78628ab0 Add npm install 2023-12-26 13:57:39 +01:00
Gal e8bb94211e change port 2023-12-26 13:49:23 +01:00
Gal 0c8ab1e82d Add dc 2023-12-26 13:48:48 +01:00
Gal 372563d053 Add website 2023-12-12 00:49:06 +01:00
Gal 979260ac92 Add website 2023-12-12 00:44:33 +01:00
Gal 146c505b65 Quartz sync: Dec 9, 2023, 5:36 PM 2023-12-09 17:36:33 +01:00
Jacky Zhao 22fc06fb31 fix: spa shouldn't use popover script directly 2023-11-18 18:46:58 -08:00
Jacky Zhao 69a996c5d6 fix: explicit undefined check in header transclude 2023-11-18 18:27:44 -08:00
Jacky Zhao 91def71ed1 fix: bad transform in wikilink pre-transform (closes #598) 2023-11-17 14:00:49 -08:00
Jacky Zhao 68b5cca6ec fix: check content-type before applying spa patch (closes #597) 2023-11-17 10:46:23 -08:00
Jacky Zhao 8a6c576264 fix: dont run explorer scripts on non-explorer pages (closes #596) 2023-11-17 10:29:24 -08:00
Matt Vogel feb8899b6e feat: add class `alias` to aliases (#585) 2023-11-17 10:23:39 -08:00
Zijing Zhang 630d1de011 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 516a083506 fix: include anchor when normalizing urls for spa/popovers 2023-11-15 20:35:45 -08:00
Jacky Zhao 3304b8924a feat: scrub link formatting from toc entries 2023-11-15 20:13:28 -08:00
Jacky Zhao 4e3e894be2 fix: format 2023-11-15 19:32:25 -08:00
Jacky Zhao 99f33a9cee 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 fb7dca854c feat: support repeated anchor tag (closes #592) 2023-11-15 19:27:54 -08:00
Jacky Zhao c8b7ccc108 feat: deref symlinks when copying static assets (closes #588) 2023-11-15 09:43:30 -08:00
Jacky Zhao f03148be3a fix: set htmlAst after walking tree in ofm (closes #589) 2023-11-14 20:01:48 -08:00
Jacky Zhao 0d7dd0ae4a versioning: bump to v4.1.1 2023-11-13 22:57:05 -08:00
Jacky Zhao ced51864fc feat: header and full-page transcludes (closes #557) 2023-11-13 22:51:40 -08:00
Jacky Zhao a24f625379 fix: make :has img selector direct 2023-11-12 14:33:19 -08:00
Jacky Zhao ce2468705b feat: option to specify npx quartz sync message (closes #583) 2023-11-12 14:27:53 -08:00
Jacky Zhao b4f5c0b837 fix(style): dont internal-link highlight when image (closes #581) 2023-11-11 21:13:10 -08:00
Jacky Zhao f97aee238b perf: compute mapping of folder name to file data for faster breadcrumbs 2023-11-11 21:06:37 -08:00
Jacky Zhao cee53ca69d fix: check if popover exists after fetching and before inserting 2023-11-11 20:46:57 -08:00
Jacky Zhao f99e83267e style + cfg: resolve breadcrumb titles by default and change arrow character 2023-11-11 20:46:29 -08:00
Jacky Zhao 5c20fb7310 fix: .date.getTime() based sort 2023-11-11 20:28:26 -08:00
Jacky Zhao cf32895001 fix: sort rss feed by date 2023-11-11 12:08:54 -08:00
Jacky Zhao 6659182eef lint: format 2023-11-11 12:02:34 -08:00
Jacky Zhao 564e761acd fix: normalize relative urls (closes #569) 2023-11-11 11:59:05 -08:00
Jacky Zhao 9389e5f91d types: cast in jsx.tsx to avoid @ts-ignore 2023-11-11 11:41:44 -08:00
Jacky Zhao 5da1be1b18 style: scrollable tables 2023-11-11 11:39:56 -08:00
Jacky Zhao 14f8287257 fix: anchors links shouldnt cause reload (closes #574) 2023-11-11 10:11:31 -08:00
Jacky Zhao 87a3503f57 fix: trailing slash aliases (closes #577) 2023-11-11 09:56:30 -08:00
Yes365 151326c0aa fix: adapt vercel cleanurls (#487)
Co-authored-by: Harrison <Harrison@fanruan.com>
2023-11-09 19:44:16 -08:00
Niklas Schröder 130dc98446 docs: fix property name for ToC toggle (#573) 2023-11-07 09:16:48 -08:00
Mau Camargo f5cda601da docs: Add Mau Camargo's Notkesto to showcase (#570) 2023-11-05 11:30:10 -08:00
Anson Yu 1cef8dcf2d docs: Update making plugins.md (#567)
:)
2023-11-04 14:20:16 -07:00
Jacky Zhao 72bd595fa9 feat: add collapseByDefault option to TableOfContents (closes #566) 2023-11-04 12:11:42 -07:00
Emil Rofors 3cabf21c55 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 2a97177a5d feat: auto-tag releases (closes #560) 2023-11-01 10:04:41 -07:00
Florence e193e76b63 docs: remove dead link (#561) 2023-11-01 09:57:32 -07:00
Blue Rose 38ebb34a4e 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 09a1b59a6a fix: disable semi-broken flexsearch cache 2023-10-25 09:40:43 -07:00
Jacky Zhao 8d15ed26d8 feat: openLinksInNewTab option for link transformer 2023-10-22 09:54:12 -07:00
Jacky Zhao 5e44004415 fix: styling for nested popover tag in page list 2023-10-21 21:12:11 -07:00
Jacky Zhao 735315a01b fix: catch html to jsx errors (closes #547) 2023-10-21 21:06:02 -07:00
Jacky Zhao 14a5196822 fix(style): tag float orientation for long tags on page listing 2023-10-21 21:06:02 -07:00
Jacky Zhao b0220f5d25 fix(style): prioritize base and custom scss over component css 2023-10-21 21:06:02 -07:00
freenandes 77b512e381 docs: Update showcase.md (#540)
changed URL
2023-10-17 19:43:41 -07:00
Thomas 085035249c docs(explorer): Fixed small typo with extra } in explorer.md (#541) 2023-10-17 19:43:20 -07:00
freenandes bb1c5f6af7 Update showcase.md (#539) 2023-10-17 08:58:28 -07:00
Jacky Zhao 1857c17d5c fix(css): import base from custom instead of the other way around (#536) 2023-10-14 13:45:56 -07:00
Jacky Zhao 61a45e25de feat: docker support for v4 (closes #530) 2023-10-08 09:59:18 -07:00
Jacky Zhao 38db1fd55d fix: ctrl+click with spa enabled 2023-10-08 09:15:06 -07:00
Jacky Zhao 6c8e7e5bb0 css: make article relative 2023-10-05 13:48:52 -07:00
Jacky Zhao 0d500da752 style: styling for codeblocks without langs (#527) 2023-10-05 13:30:06 -07:00
Ben Schlegel 99deff9a6e 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 282acb6bb8 specify minimum npm version 2023-10-04 09:23:56 -07:00
Luca Salvarani 08ee858830 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 8c1c1c78d7 Fix: RSS title escaping (#521)
* Fix title escaping

* npm run format
2023-10-01 09:47:22 -07:00
Hrishikesh Barman b38d9322b1 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 22b559b31b 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 e4e54f52d5 docs: fix typo in breadcrumbs documentation (#513) 2023-09-29 08:19:10 -07:00
Ben Schlegel 12664ae596 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 482b7f4439 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 37d59b994e fix: coerce title to string 2023-09-25 18:15:55 -07:00
Jacky Zhao 2443791d33 fix: treat the 0 time as invalid too 2023-09-24 14:47:30 -07:00
Jacky Zhao 242b37034e fix: mermaid copy source position 2023-09-24 10:31:54 -07:00
Chad Lee 44b8f446ef add site to showcase (#504) 2023-09-24 10:27:42 -07:00
Vince Imbat cb7b7c3869 docs: Adds Vince Imbat to showcase (#501) 2023-09-22 19:39:02 -07:00
Jacky Zhao 5f0a7a5d35 feat: add warning for invalid date format 2023-09-22 10:04:50 -07:00
Jacky Zhao 3c8cff48a3 feat: add warning for missing home page 2023-09-22 10:04:50 -07:00
Ben Schlegel d23c80cfad docs(showcase): fix pull request redirect link (#500) 2023-09-22 08:20:19 -07:00
Ben Schlegel e3de59f265 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 476ae69e9d 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 f1fdbd3452 docs(explorer): update default config + new example (#493) 2023-09-21 18:53:19 +02:00
Jacky Zhao 42cb4efb33 perf: memoize filetree computation (#490)
* perf: memoize filetree computation

* format

* var -> let
2023-09-20 16:09:18 -07:00
Jacky Zhao 96abbf63d3 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 31d6601a0d 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 9738b95e1b 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 7652bdff7e Revert "docs: wording changes for offline support"
This reverts commit 52a172d1a4.
2023-09-20 13:52:29 -07:00
Jacky Zhao 186ca72a9f docs: document enableToc 2023-09-20 11:58:52 -07:00
Jacky Zhao 2a552cd92b docs: wording changes for offline support 2023-09-20 11:40:36 -07:00
Adam Brangenberg 9c322802fa 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 ae57715822 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 aa4f788123 fix(nit): make defaultOptions on explorer not a function 2023-09-19 10:22:39 -07:00
David Fischer ee0c958b72 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 1a572d77ef docs: fix explorer example (#483) 2023-09-18 14:32:00 -07:00
Ben Schlegel f030418822 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 a9cdd5ff27 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 a1f2551c16 docs: fix examples 2023-09-17 21:32:23 +02:00
Ben Schlegel b672a4c827 docs: fix intra page links 2023-09-17 21:20:09 +02:00
Christian Gill e173414d12 fix(slug): Handle question mark (#481) 2023-09-17 11:02:00 -07:00
Ben Schlegel d889775951 fix: darkmode scroll bars (#480) 2023-09-17 10:29:20 -07:00
Ben Schlegel 27f99713d8 docs(explorer): write docs for new features 2023-09-17 16:41:23 +02:00
Ben Schlegel c2ac5dcfd0 fix(explorer): filter function in `ExplorerNode` 2023-09-17 15:51:08 +02:00
Ben Schlegel b8fbb64cad fix: display name for file nodes 2023-09-17 12:41:06 +02:00
Ben Schlegel e3306cc475 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 e112fdad2b fix: create deep copy of file passed into tree 2023-09-16 19:45:21 +02:00
Ben Schlegel 0ed17307cf 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 4ba45f9577 feat(explorer): integrate filter option 2023-09-16 19:18:59 +02:00
Ben Schlegel 9ad51c46d0 fix: use correct import for `QuartzPluginData` 2023-09-16 17:47:44 +02:00
Ben Schlegel 3ea0d50293 feat: implement filter function for explorer 2023-09-16 17:28:58 +02:00
Ben Schlegel 5d9d681152 feat(explorer): add config to support custom sort fn 2023-09-16 12:40:19 +02:00
Yuto Nagata a0a98bcf4f fix: umami analytics date attribute (#477) 2023-09-15 19:17:20 -07:00
Jacky Zhao bf89e38a40 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 9bfdc24161 fix: use git dates by default, @napi/git is fast enough 2023-09-15 09:46:06 -07:00
Ben Schlegel 515ac8d9a1 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 4b177ed03e 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 0a6e9c3f86 feat: note transclusion (#475)
* basic transclude

* feat: note transclusion
2023-09-13 11:28:53 -07:00
Jacky Zhao bfabedc5f7 fix dont show html in search when rssFullHtml is true (closes #474) 2023-09-13 09:43:30 -07:00
Jacky Zhao 3844a911e5 feat: resolve block references in obsidian markdown 2023-09-12 22:55:50 -07:00
Jacky Zhao 64d6db3b3f feat: rich html rss (closes #460) 2023-09-12 21:44:03 -07:00
Jacky Zhao 4387044cc7 fix: 404 page styling for nested pages (closes #458) 2023-09-12 21:29:57 -07:00
Jacky Zhao 5e02b3fed1 feat: rss limit (closes #459) 2023-09-12 19:18:44 -07:00
hcplantern 1562d2d9ad fix: callout parsing (#469) 2023-09-11 23:00:21 -07:00
Oskar Manhart 4b37976c29 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 17e5fbc0e6 ci: print bundleInfo 2023-09-10 23:07:17 -07:00
Jacky Zhao fde8608927 fix: more lenient date parsing for templates 2023-09-08 09:29:57 -07:00
Stefano Cecere 49470d641a typo (it's draft, not drafts) (#456) 2023-09-07 08:13:41 -07:00
Jacky Zhao 425592d09a fix: links to index not showing in graph (closes #450) 2023-09-06 22:24:15 -07:00
Jacky Zhao 32b65cd1f7 fix: escape encoding for titles in rss 2023-09-06 21:47:59 -07:00
Jacky Zhao 86ccdccde1 fix: encodeuri for slugs in rss 2023-09-06 21:31:01 -07:00
Jacky Zhao b668b4c1a3 docs: correct field for ignorePatterns 2023-09-06 21:08:08 -07:00
Jacky Zhao c9ddec07aa feat: 404 page emitter 2023-09-06 21:02:21 -07:00
Jacky Zhao 7e1be1d5b2 fix: dont transform external links 2023-09-06 20:25:50 -07:00
Ben Schlegel 25541d2e35 docs: update `full-text-search.md` (#447) 2023-09-03 22:36:30 -07:00
Dr Kim Foale b3bd6f7c01 docs: Make it clearer that wikilinks go to paths not page titles (#448) 2023-09-03 21:29:58 -07:00
Adam Brangenberg 49d5d56bf4 feat(analytics): Support for Umami (#449) 2023-09-03 21:28:57 -07:00
Ben Schlegel 50da33ea4d 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 f257e2a948 fix: clipboard button visible in search (#445) 2023-09-03 09:06:05 -07:00
Jacky Zhao c7cd941e5f feat: pluralize things in lists 2023-09-02 18:07:26 -07:00
Ben Schlegel 53dd86727b fix(search): matches getting highlighted in title (#440) 2023-09-01 14:12:32 -07:00
Ben Schlegel fa0629716f 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 b9be4e470c Adds Pelayo Arbues to showcase (#435) 2023-08-31 12:12:06 -07:00
Ben Schlegel f06440806f 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 67451fa0fd fix: aliasredirects not using full path, add permalink support 2023-08-29 10:37:00 -07:00
Jeffrey Fabian 683c40a0ac 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 e815256517 fix: correct graph labels for `index.md` nodes (#431) 2023-08-28 10:00:49 -07:00
Jeremy Press 43eeb8f4e7 Fix typo :) (#430) 2023-08-27 20:57:19 -07:00
Jeremy Press ef762f28cd 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 78eb93eb85 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 d4187034c2 fix: slugify tag on page before adding (closes #411) 2023-08-27 12:27:55 -07:00
Ben Schlegel 3233d5b08a Fix search bar after navigate (#424) 2023-08-26 17:19:45 -07:00
Ben Schlegel 0688a2415f 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 29c4087dea style: fix mulitline callout styling 2023-08-26 10:48:34 -07:00
Jacky Zhao 6e8de47b7e docs: simplify oxhugo page 2023-08-26 10:42:55 -07:00
Hrishikesh Barman 1de352dc11 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 da64b9be3a 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 6bcae12f6d feat(consistency): Add `.obsidian` to ignorePatterns (#420) 2023-08-25 09:03:49 -07:00
Jacky Zhao 477922e5f0 format, ensure ci runs on prs 2023-08-24 12:31:15 -07:00
Ben Schlegel 818fa95f0f style: integrate tertiary color to text-select (#413) 2023-08-24 12:28:06 -07:00
Zero King d75cf0b354 feat: reproducible build (#412)
for sitemap, RSS and contentIndex.json.
2023-08-24 11:41:20 -07:00
Jacky Zhao 9707aadf11 format 2023-08-24 10:03:14 -07:00
Jacky Zhao 9973f77c5b fix: ensure recentnotes uses proper date 2023-08-24 09:38:00 -07:00
Jacky Zhao 7e537a83cb fix: add better warning when defaultDateType is not set due to upgrade 2023-08-24 09:17:43 -07:00
Jacky Zhao 84d4636b07 version bump to 4.0.10 2023-08-24 09:05:19 -07:00
Jacky Zhao ca718fa3d7 feat: add defaultDateType config 2023-08-24 08:56:40 -07:00
Jacky Zhao 9ff82b4983 fix: lock to never read when site is building 2023-08-24 08:31:12 -07:00
Ben Schlegel 09e7672211 docs: fix typo in `authoring content.md` (#408) 2023-08-24 08:14:52 -07:00
bfahrenfort ae729cc28b Revert contentIndex to RSS 2.0 (#407) 2023-08-23 22:57:49 -07:00
Jacky Zhao ce8f150883 format 2023-08-23 15:16:04 -07:00
Zane Helton 2c38375975 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 2b4320332e fix: text wrap in popover 2023-08-23 13:10:23 -07:00
Jacky Zhao 7104a15d30 docs: make incompability of trailing slashes clear 2023-08-23 12:23:49 -07:00
Jacky Zhao da2e87d655 fix: use proper full base for links.ts 2023-08-23 12:18:50 -07:00
Jacky Zhao c816ad023b docs: whitespace 2023-08-23 12:11:24 -07:00
kanpov 39a290c48f Fix #403 by moving documentation to separate directory to avoid merge conflicts (#405) 2023-08-23 12:09:04 -07:00
Jacky Zhao 107c8d413a fix: builds should no accumulate on repeated changes (closes #404) 2023-08-23 11:36:34 -07:00
Jacky Zhao a25bc8a5e4 deps: native addons for lightningcss 2023-08-23 09:19:00 -07:00
Jacky Zhao c84e823ec7 deps: install exact 2023-08-23 09:16:44 -07:00
Jacky Zhao bdc4ce1700 deps: esbuild and esbuild-sass-plugin 2023-08-23 09:10:30 -07:00
Aaron Pham fb2b228b29 fix(esbuild): conflict with esbuild-sass-plugin (#402) 2023-08-23 09:05:01 -07:00
Jacky Zhao 2a5cfa011f version bump to 4.0.9 2023-08-22 23:37:02 -07:00
Jacky Zhao 2ecc650d42 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 709ad94180 fix: toc for cyrillic and other non-latin alphabets (closes #396) 2023-08-22 22:41:50 -07:00
Jacky Zhao 300aff4125 fix: properly lock across source and content refresh by sharing a mutex 2023-08-22 22:27:41 -07:00
Jacky Zhao 460879df31 fix: tag support for non-latin alphabets (fixes #398) 2023-08-22 22:14:16 -07:00
Jacky Zhao a8272d4a9c fix: spa hijacks back button (closes #400) 2023-08-22 21:30:31 -07:00
松浦 知也 Matsuura Tomoya a23f127c13 fixed broken CJK links (#390) 2023-08-22 09:16:55 -07:00
Ikko Eltociear Ashimine fc58b10ab3 fix: typo in bootstrap-cli.mjs (#394) 2023-08-22 09:16:21 -07:00
Jacky Zhao 520ed4368d fix: server-handler crash from filename (closes #386) 2023-08-21 17:01:18 -07:00
Jacky Zhao e0bcc8815e fix: async-mutex not exclusively locking correectly 2023-08-21 16:43:32 -07:00
Jacky Zhao 72963752b6 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 a920416db2 format, update default sidepanel width 2023-08-21 09:00:13 -07:00
松浦 知也 Matsuura Tomoya dcaf09b658 fix: opts being overriden in graph option (#384) 2023-08-21 08:45:47 -07:00
Jacky Zhao c2c976a56c docs: fix links to networked thought 2023-08-20 23:50:29 -07:00
Jacky Zhao 57e9297173 format 2023-08-20 20:48:35 -07:00
Jacky Zhao 61d67c9057 fix: ctrl + k breaking after page nav 2023-08-20 20:47:07 -07:00
Jacky Zhao 504e6f67ee move wss server start after http 2023-08-20 18:41:37 -07:00
Jacky Zhao 487e0c8473 fix: nav event with spa off, anchor nav refresh page 2023-08-20 18:08:44 -07:00
Jacky Zhao 95b9358c0d fix: jump to anchor on deployed site triggering spa refresh 2023-08-20 17:50:56 -07:00
Jacky Zhao 1d5d088c86 remove checkout step from instructions as v4 is the default branch 2023-08-20 16:59:25 -07:00
Jacky Zhao 3b9ed2ab7b fix: ensure code exists inside pre before adding clipboard 2023-08-20 15:38:37 -07:00
Jacky Zhao 3eba87a512 fix: dont show index page for folder in its own listing 2023-08-20 15:02:24 -07:00
Jacky Zhao 4aa80e0426 fix: ci runs on v4 2023-08-20 14:34:00 -07:00
Jacky Zhao 3ad0b250bb fix: add async-mutex to builds on large vaults 2023-08-20 14:27:44 -07:00
Jacky Zhao efd0c1a443 recent notes css fixes 2023-08-20 14:05:37 -07:00
Jacky Zhao 4c72472f5f add docs for recent notes 2023-08-20 13:00:33 -07:00
Jacky Zhao 987d72d67f css fixes, add recent notes, more robust quartz update 2023-08-20 12:46:37 -07:00
Jacky Zhao 992e4e9704 add engines field 2023-08-20 08:57:56 -07:00
Jacky Zhao 76bc9f49b4 fix description not being used in folder and tag listings 2023-08-20 01:08:18 -07:00
Jacky Zhao c5d90e9214 update plausible url 2023-08-20 00:54:13 -07:00
Jacky Zhao cacdb200b0 docs: update notes for tag and folder listings 2023-08-20 00:52:49 -07:00
Jacky Zhao 65c60e9103 docs: note about updating default branch 2023-08-20 00:02:41 -07:00
Jacky Zhao 2f2c4ff4fb docs: make setting upstream more clear, docs on npx quartz restore 2023-08-19 22:19:49 -07:00
Jacky Zhao e39eef402b fix: put quotations around font 2023-08-19 22:04:29 -07:00
Jacky Zhao 740f20f8ca readme fix 2023-08-19 21:59:20 -07:00
Jacky Zhao 6edcfc0a9c fix: string for aliases being treated as array of chars 2023-08-19 21:59:01 -07:00
Jacky Zhao 604fc3be04 css: fix scrollbars on windows 2023-08-19 21:55:09 -07:00
Jacky Zhao 3d7a7c8790 add git fetch to migration instructions 2023-08-19 21:38:10 -07:00
Jacky Zhao 1a7e4cf90e Merge branch 'v4' of https://github.com/jackyzha0/quartz into v4 2023-08-19 21:16:31 -07:00
Jacky Zhao 3549020750 add sponsors 2023-08-19 21:16:24 -07:00
Matt Dunn de537aba1b Adding to Showcase page (#367) 2023-08-19 19:15:14 -07:00
Jacky Zhao f9a08bc0f4 update docs 2023-08-19 18:56:45 -07:00
Jacky Zhao 34dbddbd61 impl baseDir option for quartz build --serve for local testing 2023-08-19 18:04:17 -07:00
Jacky Zhao 5d225f1206 fix trailing slash causing folder listing to not fetch content correctly 2023-08-19 16:55:36 -07:00
Jacky Zhao 9e2fbabc20 avoid 404 on icon for spa navigations with anchors 2023-08-19 16:40:02 -07:00
Jacky Zhao f7c2fc36f3 improve path resolution stability 2023-08-19 16:28:44 -07:00
Jacky Zhao 303a867d60 base path refactor to better support subpath hosting 2023-08-19 15:52:25 -07:00
Jacky Zhao a3703cbe0b v4-alpha -> v4 2023-08-18 18:24:09 -07:00
Jacky Zhao 2c4ea82e86 update docs on github pages and syncing 2023-08-18 18:22:38 -07:00
Jacky Zhao d14a81014b fix typo in docs 2023-08-17 23:39:15 -07:00
Jacky Zhao 0320da77d0 format 2023-08-17 21:54:42 -07:00
Jacky Zhao f56c5c3939 ensure sync includes untracked files 2023-08-17 21:49:58 -07:00
Jacky Zhao f88e15c719 ensure contentfolder is passed to popContentFolder 2023-08-17 21:24:41 -07:00
Jacky Zhao 3031c599b1 fix when symlink targ is calculated and added npx quartz restore 2023-08-17 21:20:15 -07:00
Jacky Zhao 94a45c6efe format 2023-08-17 21:08:26 -07:00
Jacky Zhao 3990894cfe deref symlink on quartz sync 2023-08-17 21:07:40 -07:00
Jacky Zhao 6ab90d093c fix rebuild debouncing 2023-08-17 01:58:11 -07:00
Jacky Zhao a3cba52362 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 c65451519e format 2023-08-17 00:55:52 -07:00
Jacky Zhao cdaec963ed various path fixes for links to extensions, fix relative paths in links 2023-08-17 00:55:28 -07:00
Jacky Zhao 94dbdec8d0 fix import paths 2023-08-16 22:09:11 -07:00
Jacky Zhao b5ab38cb7e fix relative path resolution in router and link crawling 2023-08-16 22:04:15 -07:00
Sohaib 53732b901d Update hosting.md (#371) 2023-08-14 17:59:47 -07:00
Jacky Zhao e0d63776cd fix: add trailing slash to local serving 2023-08-13 17:47:18 -07:00
vintro a8604d84f4 docs: note about existing content at same path on different branches 2023-08-13 17:19:50 -07:00
Jacky Zhao d7a133d579 format docs 2023-08-12 21:18:51 -07:00
Jacky Zhao b6a3fa4f62 fix relative path resolution logic, add more path tests 2023-08-12 21:16:43 -07:00
Jacky Zhao e5869624bd 404 page styling on local 2023-08-12 21:16:43 -07:00
Jacky Zhao d256e359b8 fix nested callout folding 2023-08-12 21:16:43 -07:00
Sohaib 58c7a9b6f4 Update hosting.md (#368) 2023-08-12 13:52:16 -07:00
Jacky Zhao cdc8a4b7fe fmt 2023-08-12 10:17:07 -07:00
Jacky Zhao fc5c8b4a94 enable rich text in callout title 2023-08-12 10:16:55 -07:00
Jacky Zhao 7b9e986f2e include home page in search 2023-08-12 00:24:30 -07:00
Jacky Zhao b62827a782 format, make search async 2023-08-12 00:03:11 -07:00
Jacky Zhao 5e7865d7e9 fix wikilinks to anchors in the same document 2023-08-11 23:55:17 -07:00
Jacky Zhao 85bb91d998 fix scanning for tags in content 2023-08-11 23:40:06 -07:00
Jacky Zhao 7d9d4becd7 fix broken tag listing links to tags 2023-08-11 23:27:59 -07:00
Jacky Zhao 6093c863a6 fix emit filepaths, tag emit being overriden by content 2023-08-11 23:25:44 -07:00
Jacky Zhao d4d6ffac64 feature docs 2023-08-11 22:47:50 -07:00
Jacky Zhao 41f7de75a9 more documentation 2023-08-11 00:31:44 -07:00
Jacky Zhao b3635a0c5a spacing fix 2023-08-10 21:32:11 -07:00
Jacky Zhao 5bd341a462 run prettier 2023-08-10 21:29:11 -07:00
Jacky Zhao cf730e31fb docs on making plugins 2023-08-10 21:16:07 -07:00
Jacky Zhao 99ce8dcd72 format 2023-08-09 09:18:44 -07:00
Jacky Zhao 3918ad7a75 update npx quartz update script 2023-08-09 09:10:40 -07:00
Jacky Zhao 1b37945b13 profiling, better concurrency heuristics 2023-08-09 00:26:33 -07:00
Jacky Zhao 486bd9358c format 2023-08-08 22:53:01 -07:00
Jacky Zhao b79e889d87 better concurrency debugging, --concurrency flag for npx quartz build 2023-08-08 22:52:49 -07:00
Jacky Zhao cd2ac7f9c7 fix getFileExtension missing numeric extensions (e.g. mp4) 2023-08-08 21:31:36 -07:00
Jacky Zhao 3f8329207b change reading time to content meta 2023-08-08 21:28:09 -07:00
Jacky Zhao e9eebd1c87 fix head.tsx 2023-08-08 20:36:24 -07:00
Jacky Zhao 9ad6f49c15 guide to creating components 2023-08-08 20:18:31 -07:00
Jacky Zhao 6fe77cd16c fix notes 2023-08-07 23:57:24 -07:00
Jacky Zhao 964e033655 most of creating components, increase legibility of bold in article and callouts 2023-08-07 23:56:50 -07:00
Jacky Zhao a6904be6f1 format 2023-08-07 21:51:23 -07:00
Jacky Zhao a026ddad33 fix regression in code block font-size boosting on safari mobile 2023-08-07 21:51:06 -07:00
Jacky Zhao 4e97695eee various css fixes, fix new image loading bug when previewing, path docs 2023-08-07 21:41:18 -07:00
Jacky Zhao 15be857598 architecture, fix vendor prefixing 2023-08-07 17:34:38 -07:00
Jacky Zhao 7639abf0eb format 2023-08-06 22:07:33 -07:00
Jacky Zhao 60f95f1ed7 fix css transforms for mobile 2023-08-06 22:07:08 -07:00
Jacky Zhao 66e8afb008 fix shortest path for non-md files, mobile fix 2023-08-06 20:52:17 -07:00
Jacky Zhao 22d2d344f2 note formatting 2023-08-06 19:54:11 -07:00
Jacky Zhao b4f4eec3f5 docs upgrade, ci changes 2023-08-06 19:52:30 -07:00
Jacky Zhao a58458a99e mobile fixes, fix bug when linking to anchor on home, docs 2023-08-06 17:09:29 -07:00
Jacky Zhao d38837c15d format, remove markdown from being procesed 2023-08-05 18:00:52 -07:00
Jacky Zhao cf18b99937 reverse query param hack to re-add sourcemap support 2023-08-05 17:53:29 -07:00
Jacky Zhao 6d2291bbf1 non-admonition callout fix 2023-08-05 16:43:50 -07:00
Jacky Zhao 12ec0a77a0 improve hot reload robustness 2023-08-05 15:34:10 -07:00
Jacky Zhao 9868c09f58 more robust error handling, config hotreload 2023-08-05 11:28:09 -07:00
Jacky Zhao c307dce3a4 fix mermaid initialization 2023-08-04 22:35:21 -07:00
Jacky Zhao 34641d758f bump mathjax version 2023-08-03 23:36:00 -07:00
Jacky Zhao 718f15dd4e fix execsync 2023-08-03 23:28:34 -07:00
Jacky Zhao 3a7f382cbb fix fetch flags 2023-08-03 23:24:34 -07:00
Jacky Zhao ced82d2e09 format, add upstream 2023-08-03 23:08:04 -07:00
Jacky Zhao a660922136 update pull strategy 2023-08-03 22:29:46 -07:00
Jacky Zhao a01301fb70 fix callout aliases not being used properly 2023-08-03 00:08:13 -07:00
Jacky Zhao 503166063d readme fixes, force 2023-08-02 23:42:49 -07:00
Jacky Zhao e1970ed24c use checkout for pulling updates 2023-08-02 23:29:28 -07:00
Jacky Zhao 744955bc94 use posix style paths for all path ops 2023-08-02 23:04:26 -07:00
Jacky Zhao 4f7c51cd84 format 2023-08-02 22:16:46 -07:00
Jacky Zhao 0a217c1bcc use autostash and pull 2023-08-02 22:16:32 -07:00
Jacky Zhao 94e0088c01 format 2023-08-02 22:11:46 -07:00
Jacky Zhao 159bf972c3 make path and globbing more platform invariant 2023-08-02 22:10:13 -07:00
Jacky Zhao 53344e4dfa add gitattributes for windows 2023-08-02 20:59:56 -07:00
Jacky Zhao 8f2ccfb910 fix test matrix for ci 2023-08-02 20:56:31 -07:00
Jacky Zhao 2caebeaed4 make ci also run on windows, re-add css minification 2023-08-02 20:53:13 -07:00
Jacky Zhao 990ef3a317 windows patches 2023-08-02 00:07:41 -07:00
Jacky Zhao 5e0b397a5f change default strategy to be rebase 2023-08-01 23:29:58 -07:00
Jacky Zhao 4f35300e96 Merge branch 'v4-alpha' of https://github.com/jackyzha0/quartz into v4-alpha 2023-08-01 22:48:32 -07:00
Jacky Zhao 0b46a69a53 flag to allow ofm replace in html embed 2023-08-01 22:47:16 -07:00
Adam Brangenberg 75aca63349 Removing redundant properties (#356) 2023-07-30 21:08:32 -07:00
Jacky Zhao 31e99c669a make layouts simpler to think about 2023-07-25 23:37:24 -07:00
Jacky Zhao 828a474fa9 fix checkbox/tasklist styling 2023-07-25 22:27:59 -07:00
Jacky Zhao 3f7c8d1917 fix formatting 2023-07-25 21:11:06 -07:00
Jacky Zhao dfee2f3b6e nested tag support and tag index page 2023-07-25 21:10:37 -07:00
Jacky Zhao 1ee77893ac font loading options, optimize css 2023-07-24 21:54:47 -07:00
Jacky Zhao 74089b3057 actually add processed tag to frontmatter 2023-07-24 00:07:58 -07:00
Jacky Zhao c60f17d101 fix watch-mode batching 2023-07-24 00:04:01 -07:00
Jacky Zhao 145e57d4fc npm i on quartz update 2023-07-23 21:53:34 -07:00
Jacky Zhao 2df818c624 styling fixes for stacking order and overflow 2023-07-23 21:41:09 -07:00
Jacky Zhao 4c0ad3e361 make component resources a proper emitter 2023-07-23 18:20:43 -07:00
Jacky Zhao eaa54b02dd version bump, update doc 2023-07-23 17:59:44 -07:00
Jacky Zhao 0b769e854b bundleinfo flag, minify scripts 2023-07-23 17:58:35 -07:00
Jacky Zhao 480948a78f support attachments folder 2023-07-23 17:42:00 -07:00
Jacky Zhao dfac1d6e44 format 2023-07-23 17:09:12 -07:00
Jacky Zhao a1985bfd28 refactor static and asset emission to be actual emitter plugins 2023-07-23 17:07:19 -07:00
Jacky Zhao 340e5e1472 update feature list 2023-07-23 15:37:06 -07:00
Jacky Zhao 6c5dc18fae feat: process tags in content 2023-07-23 14:02:57 -07:00
Jacky Zhao 5d8b034af1 improve error handling while serving 2023-07-23 11:49:26 -07:00
Jacky Zhao 88e040c290 style fixes for search bar and title on mobile 2023-07-23 11:19:15 -07:00
Jacky Zhao 3e08318c65 fix styles 2023-07-23 11:04:20 -07:00
Jacky Zhao 560196860f various typography and styling fixes 2023-07-23 11:02:45 -07:00
Jacky Zhao 59a1feac39 oops actually use npm run check 2023-07-22 17:42:13 -07:00
Jacky Zhao a796b593bc run prettier on ci 2023-07-22 17:39:10 -07:00
Jacky Zhao 617ea80db1 run prettier 2023-07-22 17:27:41 -07:00
Jacky Zhao 6b99b8abc7 configure prettier 2023-07-22 17:26:03 -07:00
Jacky Zhao 7f571846bb hot content reload 2023-07-22 16:06:36 -07:00
Jacky Zhao a7603fcca8 update features list 2023-07-20 21:51:55 -07:00
Jacky Zhao fcaec298e9 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 c2048517cb rename github action 2023-07-19 22:00:44 -07:00
Jacky Zhao 265079bf76 add custom.scss 2023-07-19 21:59:48 -07:00
Jacky Zhao 177c6d97f6 quartz update and quartz sync 2023-07-19 21:59:39 -07:00
Jacky Zhao 0b5fc92b90 add link resolution prompt to quartz create 2023-07-16 10:39:35 -07:00
Jacky Zhao 0c5ca34c4b treat _index as index 2023-07-15 23:33:06 -07:00
Jacky Zhao 361c5c9ffb fix ci, disable strict path type checks by default 2023-07-15 23:05:17 -07:00
Jacky Zhao 2c0f21a97d finish path refactoring, add sourcemap + better trace support 2023-07-15 23:02:12 -07:00
Jacky Zhao ffb2c9ba57 base path refactor, more docs 2023-07-13 00:19:35 -07:00
Jacky Zhao 33c8c9c5f6 docs + various polish 2023-07-09 19:32:24 -07:00
Jacky Zhao b06cf9bdac polish 2023-07-08 14:36:02 -07:00
Jacky Zhao e0b91a193f fix styling for bullet points 2023-07-06 19:18:18 -07:00
Jacky Zhao 8f76cc5768 handle dates as tags 2023-07-06 18:45:38 -07:00
Jacky Zhao 27bf450955 handle string tags 2023-07-06 18:32:48 -07:00
Jacky Zhao 32018d9f83 fix path parsing 2023-07-06 16:56:30 -07:00
Jacky Zhao 3fc81b705f basic docs, remove publish, add quartz create 2023-07-05 00:16:06 -07:00
Jacky Zhao 70dcf6acc2 fix default callout state 2023-07-04 18:26:11 -07:00
Jacky Zhao 7e901087d0 update package 2023-07-04 18:08:36 -07:00
Jacky Zhao f8b2275b43 folder and tag descriptions, re-enable relative pathing 2023-07-04 18:02:59 -07:00
Jacky Zhao 7e3781c6d0 fix popover zindex 2023-07-04 17:14:15 -07:00
Jacky Zhao a90142ba2d more visual polish, adjust colours and spacing 2023-07-04 16:48:36 -07:00
Jacky Zhao 1547c8af0d fix indexing causing main thread freeze, various polish 2023-07-04 10:08:32 -07:00
Jacky Zhao 20b2d88a06 various polish 2023-07-02 13:08:29 -07:00
Jacky Zhao bcebc20808 rss + sitemap 2023-07-01 13:35:27 -07:00
Jacky Zhao 3e0e06025c tag and folder pages 2023-07-01 00:03:01 -07:00
Jacky Zhao fc03f3dcec fix: parsing wikilinks that have codeblock anchors, scroll to anchor 2023-06-19 22:50:25 -07:00
Jacky Zhao 1c7b5c88d8 basic search implementation 2023-06-19 20:37:45 -07:00
Jacky Zhao 2a9ed21823 local and global graph 2023-06-18 10:47:07 -07:00
Jacky Zhao d5b51a8e29 popovers 2023-06-17 16:05:46 -07:00
Jacky Zhao f078f20c08 basic left,right layout 2023-06-17 14:36:06 -07:00
Jacky Zhao 23624105fb collapsible callout 2023-06-17 13:08:06 -07:00
Jacky Zhao 5162c3c977 collapsible toc 2023-06-17 12:07:40 -07:00
Jacky Zhao 09b5f4b10a modern toc tweaks 2023-06-16 19:41:59 -07:00
Jacky Zhao 9c6046a1f8 taglist, mermaid 2023-06-12 22:41:42 -07:00
Jacky Zhao 397f4f7d3a add config to components 2023-06-11 23:46:38 -07:00
Jacky Zhao 9a1f0b48b4 refactor plugins to be functions instead of classes 2023-06-11 23:26:43 -07:00
Jacky Zhao 8c5dd2287a toc 2023-06-09 23:06:02 -07:00
Jacky Zhao b3cbcaf0f5 add custom spa solution 2023-06-09 19:58:58 -07:00
Jacky Zhao 8e36d2a677 add flamethrower router 2023-06-07 22:38:45 -07:00
Jacky Zhao cc10ff2487 generic quartz component for layout 2023-06-07 22:27:32 -07:00
Jacky Zhao d4878f62db update gh actions 2023-06-07 10:52:53 -07:00
Jacky Zhao e16cc9be37 codeblock copy 2023-06-06 21:19:00 -07:00
Jacky Zhao 4c94432a8f fix darkmode script load 2023-06-06 20:58:26 -07:00
Jacky Zhao 229f615790 darkmode scripts 2023-06-06 19:48:37 -07:00
Jacky Zhao dace837cd5 embeds 2023-06-06 00:00:38 -07:00
Jacky Zhao 69679df121 callouts 2023-06-05 22:14:17 -07:00
Jacky Zhao 4f2a91da13 update spinners 2023-06-04 13:37:43 -04:00
Jacky Zhao 060dcce93e multi-core builds 2023-06-04 12:35:45 -04:00
Jacky Zhao 7b5df46f1c inline scripts 2023-06-03 15:07:19 -04:00
Jacky Zhao 894c7ff4e7 heading linking 2023-06-01 19:48:38 -04:00
Jacky Zhao 428833aeec syntax higlighting 2023-06-01 19:05:14 -04:00
Jacky Zhao 51e26ecb4e scss support 2023-06-01 17:35:31 -04:00
Jacky Zhao 5154dbca4e obsidian flavored markdown support 2023-06-01 12:33:20 -04:00
Jacky Zhao e5f95504e1 link processing 2023-05-31 17:41:44 -04:00
Jacky Zhao 2d3b816c44 rendering, link resolution, asset copying 2023-05-31 17:01:23 -04:00
Jacky Zhao 62d0c4bd1a plugin integration round 2 2023-05-30 08:02:20 -07:00
Jacky Zhao 70a05fccd5 base setup 2023-05-28 17:44:08 -07:00
BSD-Yassin 0183bbcb10 i18n: Update fr.toml (#313) 2023-04-27 11:12:56 -07:00
Jacky Zhao aa52b7a540 fix: graph and tooltip sometimes not showing 2023-04-06 15:06:01 -07:00
Mattia Ippoliti d73301ae11 fix: padding for empty title callouts (#308) 2023-04-01 13:50:08 -07:00
Md Jawad Noor Asif 61c2501fbb fix: search highlight not showing because for trailing slash (#306) 2023-03-30 07:14:06 -04:00
Mike Walton de7eff3ce5 adding myself to the showcase (#301) 2023-03-23 00:56:20 -05:00
Daniel Lazaro aed2983b7b docs: Update link to callouts documentation (#300) 2023-03-18 09:20:56 -07:00
Jacky Zhao 8070695459 deps: bump hugo-obsidian 2023-03-16 10:33:01 -07:00
Jacky Zhao 24f8ae76cb docs: update to account for github changes 2023-03-02 09:14:29 -08:00
Jacky Zhao aea60cc08b deps: bump hugo-obsidian 2023-02-25 13:04:15 -08:00
Jacky Zhao 26001fb683 fix: recent notes partial sorting 2023-02-12 16:46:11 -08:00
Dev Uni 36539c6b7b fix: Bad UI due to head.html (#284) 2023-02-07 08:38:20 -08:00
Simon Späti 623e15d296 feat: Adding Twitter and Social image preview including description (#207) 2023-02-07 00:16:15 -08:00
Jacky Zhao 965e568c6f feat: max-width for large screens 2023-02-06 12:58:34 -08:00
Jacky Zhao 71c8d549ab fix: fix duplicate link click tracking 2023-02-05 12:01:49 -08:00
Jacky Zhao 0fb84029ec feat: add more plausible events 2023-02-05 11:34:39 -08:00
Jacky Zhao cc41f19aad feat: switch from GA to Plausible for analytics 2023-02-05 10:39:58 -08:00
Adam Brangenberg 981b6465d8 feat: Remove leading slash of folders in graph view (#282) 2023-02-01 12:34:18 -08:00
Jacky Zhao 3b0d4629d3 docs: remove broken links from showcase 2023-01-31 11:00:28 -08:00
Olivér Falvai 71691ed423 docs: Clarify Obsidian settings (#280) 2023-01-31 10:48:20 -08:00
herrwinfried f9e4c73b84 feat: Added Turkish translation (#275) 2023-01-29 12:14:11 -08:00
Apoorv Khandelwal c7e1291321 feat: Embedding multimodal assets (#274) 2023-01-21 10:01:05 -08:00
Quadrubo e68fa7910a added the liveReloadPort as an option for docker (#272) 2023-01-18 08:25:01 -08:00
chaosarium 361b884181 Fix callout behaviour inconsistent with Obsidian (closes #168) (#268) 2023-01-09 14:14:11 -08:00
Md Jawad Noor Asif 6de66f98c9 feat: Added Bangla translations (#266) 2023-01-09 14:12:52 -08:00
Md Jawad Noor Asif 56f56e7d8f fix: fix unicode broken tags (#261) 2023-01-03 22:10:25 -05:00
Adam Brangenberg cfe923a1fd refactor: General performance/style improvements (#262) 2022-12-29 10:43:41 -05:00
chaosarium 144660372b fix edge cases link processing (#258)
Fixes https://github.com/jackyzha0/quartz/issues/176
2022-12-24 12:10:59 -05:00
toof 186aa450fd fix: fix misspelling (#259) 2022-12-24 10:38:49 -05:00
chaosarium 19750d2c7c feat: Added simplified Chinese translations (#257) 2022-12-22 10:34:21 -08:00
Jacky Zhao 1088441458 feat: latex in search results 2022-12-03 21:03:12 -08:00
Jacky Zhao caa966de8a fix: text highlighting 2022-11-30 18:00:12 -08:00
Apoorv Khandelwal 5676d90d56 fix: Replacing "internal-link broken" with link to asset (#232) 2022-11-30 17:41:05 -08:00
Jon Erling Hustadnes 2e152a5dfc feat: Added Norwegian localization (#242) 2022-11-27 10:55:43 -08:00
Filippo Andrea Sighinolfi 472ee3ea97 feat: Added italian localization in i18n/it.toml (#239) 2022-11-27 10:55:13 -08:00
Brendan Ang 523f4e67ae feat: add support for mermaid diagrams (#244) 2022-11-27 10:53:52 -08:00
Jacky Zhao f8d2495582 fix: only run docker publish on main repository 2022-11-23 08:34:19 -08:00
Jacky Zhao b9d9ec44af fix: jump to search for operand 2022-11-21 23:36:27 -08:00
SafEight e6733b5e9d 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 fec8fd9a09 fix: Semantic Search: Use Operand Beta API (#235) 2022-11-21 08:54:45 -08:00
Jacky Zhao 514670b55f update config for search 2022-11-20 15:14:48 -08:00
Jacky Zhao 37bd59d5ad feat: docker docs, semantic search alpha 2022-11-20 15:09:58 -08:00
Apoorv Khandelwal 9d6cad7621 feat: Dockerfile and automated container build (#230) 2022-11-20 14:03:53 -08:00
SafEight 64c3e75651 feat: Replace == with <mark> (#234)
Co-authored-by: SAF <saf@saf.saf>
2022-11-19 13:17:55 -08:00
Jacky Zhao 5c8bed5c6a feat: allow enableToc to override default no TOC on a per-page basis 2022-11-19 11:18:57 -08:00
jet457 f687f108e2 docs: add Abhijeet's math-wiki to the showcase (#228) 2022-11-19 11:10:41 -08:00
saucecoat ade87d7f13 Added German translation (#223) 2022-10-29 23:08:44 -07:00
Conor aae283fa00 feat: Add French translation (#221) 2022-10-26 09:12:35 -07:00
Jacky Zhao d84946c556 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-10-25 13:14:13 -07:00
Jacky Zhao 774c4e2d58 deps: bump ubuntu version (closes #218) 2022-10-25 13:14:06 -07:00
Evan Cater 44a2184731 fix euler's identity (#220) 2022-10-24 09:13:35 -07:00
Javier Zaleta Martínez 8f1c4b401f feat: Add Spanish translation (#217) 2022-10-18 17:25:55 -07:00
Charles Chamberlain 483190d244 fix: Apply monospace style to all meta in a popover (#216) 2022-10-16 09:43:43 -07:00
Pavol Komlos bc81bd7e65 Decode the heading id from split link (#214) 2022-10-12 08:21:28 -07:00
Seth fb963b8db9 Add SethMB Work (#203) 2022-10-03 11:45:54 -07:00
Jacky Zhao 976f2461ef Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-09-23 10:17:34 -07:00
Jacky Zhao 391918e7fc feat: hide TOC when no headers (closes #204) 2022-09-23 10:17:28 -07:00
Simon Späti 052b1c798b Adding reference projects (#196)
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2022-09-14 10:05:51 -07:00
DongDong Chen 3bf99ddc11 add my showcase : oldwinterの数字花园 (#192) 2022-09-14 10:05:20 -07:00
Jacky Zhao b19135cab2 fix: make latex rendering size more simialr to obsidian 2022-09-12 11:08:07 -07:00
Jacky Zhao f879a2e0ac fix: latex rendering bugs + patch for #195 2022-09-11 18:03:55 -07:00
Nikola Georgiev 8a0514bb40 feat: Hide full path to file in Wikilinks by default (#195) 2022-09-11 17:05:14 -07:00
Jacky Zhao 95365231ff Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-08-29 14:23:19 -04:00
Jacky Zhao 6e3157c0a7 Update Quartz version in documentation 2022-08-29 14:23:04 -04:00
Andrii Yefremov a103539d9e Add Ukrainian translation (#191) 2022-08-29 14:15:18 -04:00
Jacky Zhao 1c405c79dc deps: bump hugo-obsidian version 2022-08-28 01:09:52 -04:00
Jacky Zhao 0862dc7751 fix: tag list styling 2022-08-24 00:45:08 -04:00
Youssif Shaaban Alsager bd65d242be feat: Add internationalization (i18n) support (#182) 2022-08-23 23:32:40 -04:00
Vincent Huang 9bc0849280 Popover preview should show relevant heading (#180) 2022-08-20 21:31:06 -04:00
Jacky Zhao a9fdaf9787 feat: link previews to page-list (closes #173) 2022-08-11 11:42:16 -07:00
Jacky Zhao ad5905128d fix: make callout detection case-insensitive (closes #171) 2022-08-05 11:08:52 -07:00
Jacky Zhao d315e75b91 feat: better graph scaling (closes #170) 2022-08-05 11:04:01 -07:00
Jacky Zhao ff4872e8a3 style: _callouts.scss simplification (#169) 2022-08-04 14:50:24 -07:00
Jacky Zhao 07ccc23f6f fix: CJK search (closes #163) 2022-08-03 23:46:55 -07:00
Jacky Zhao d35cb82ef7 fix: highlights being stripped in non-semantic search mode 2022-08-01 07:59:49 -07:00
Jacky Zhao e64b2c378a docs: update, re-added debounce 2022-07-31 18:21:17 -07:00
Jacky Zhao 16f571fcf9 docs: add documentation for Operand Search, remove debounce 2022-07-31 18:02:06 -07:00
Jacky Zhao c30c823253 fix: title not being selected properly, bump hugo-obsidian for uri fix 2022-07-31 16:55:25 -07:00
Jacky Zhao 9dfd79474f 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 75c1cac0c8 deps: bump hugo-obsidian to properly copy linkmap 2022-07-31 12:24:53 -07:00
Jacky Zhao bcc3196abd feat: add support for semantic search using operand 2022-07-31 12:16:36 -07:00
Jacky Zhao 71488dec88 refactor: move search utils to util.js 2022-07-31 10:54:23 -07:00
Jacky Zhao 2d4a986bd7 deps: bump hugo-obsidian version 2022-07-31 10:14:36 -07:00
Jacky Zhao 4cafc64eb9 docs: improve scss structure and admonition styling, update docs 2022-07-30 18:46:19 -07:00
Emile Bangma ee33b49d89 Support Admonition callouts (#166) (closes #88) 2022-07-30 17:29:26 -07:00
Jacky Zhao 32c2a034bb Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-07-19 09:03:26 -07:00
Jacky Zhao 847094f3ca docs: copy edits 2022-07-19 09:03:19 -07:00
Pranav M 09474da51b 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 c73bac4a3d fix: give precedence to date created over last modified if defined (#101) 2022-07-15 14:26:31 -07:00
Jacky Zhao 50c3b5ab0a style: improve header anchor styling 2022-07-14 13:09:21 -07:00
Jacky Zhao a0da04d298 feat: add description section to section/term/taxonomies, fix header margin 2022-07-14 12:02:54 -07:00
Jacky Zhao 216ceb9a34 fix: styling on page-list for smaller screens 2022-07-14 11:49:47 -07:00
Jacky Zhao 5352c38b01 fix: make section-li scss more generic 2022-07-14 10:38:34 -07:00
Jacky Zhao b5d964364b feat: improve styling for lists, fix anchor offset 2022-07-14 10:30:07 -07:00
Jacky Zhao 9cad2af01f feat: css typography improvements 2022-07-13 23:51:33 -07:00
Jacky Zhao 4db93bf384 feat: css refactor for easy font change 2022-07-13 23:37:54 -07:00
Jacky Zhao e235f00fd1 fix: change / to use base url 2022-07-13 22:27:13 -07:00
y1450 5a784fc8f4 fix: remove console log (#159) 2022-07-13 15:02:11 -07:00
Jacky Zhao 9cb48adf29 feat: use floating-ui for better popover positioning 2022-07-13 15:01:50 -07:00
Jacky Zhao dc58887a92 feat: restyle search icon 2022-07-13 14:32:32 -07:00
Jacky Zhao c00d4014f7 fix: tabsize not being respected 2022-07-12 14:37:10 -07:00
Jacky Zhao d9c87a5727 docs + fix: broken partial and description of enableGitHubEdit 2022-07-05 15:42:57 -07:00
rphla d279c1c805 Add GitHub "edit" button (#157) 2022-07-05 15:39:29 -07:00
Jacky Zhao 1d5530e22f fix: copy code block logic for non code pages 2022-07-03 11:50:13 -07:00
Geoffrey Garrett a47218d28c 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 白宇彤 4f088e1312 Fix `width: auto` for SPA routing (#156) 2022-07-02 19:40:18 -07:00
Jacky Zhao 541eac9497 fix: adjust weird colours for err highlighting 2022-07-02 17:14:17 -07:00
Jacky Zhao 9279fa6d97 fix: image scaling for md-style links (closes #155) 2022-07-01 11:27:50 -07:00
Geoffrey Garrett c67ffb76ef Added optional rendering of code block titles (#148) 2022-07-01 11:03:52 -07:00
Jacky Zhao 3912c98dad fix: non-SPA fn defs (closes #154) 2022-07-01 11:03:04 -07:00
Jacky Zhao 3cc761ea2d docs: remove test image from hosting 2022-06-29 17:35:29 -07:00
Jacky Zhao 96fd6a5d1e feat: image scaling (closes #131) 2022-06-29 17:34:05 -07:00
Jacky Zhao 37bd26bc86 fix: anchor formatting (closes #141) 2022-06-29 17:17:53 -07:00
Jacky Zhao 7d80b81cf8 docs: fix page weight 2022-06-29 17:03:41 -07:00
Jacky Zhao 8f277f9f2e docs: polish and update 2022-06-29 16:57:36 -07:00
Jacky Zhao f603dcf3e7 feat: enable raw html by default (fixes #143) 2022-06-29 16:16:06 -07:00
Jacky Zhao 0a744d4451 fix: prefix images with base url for non-root quartz 2022-06-29 16:15:40 -07:00
Jacky Zhao a3623dbb2a Merge pull request #150 from aidenybai/bump-million 2022-06-28 23:21:25 -07:00
Aiden Bai f3ddbe8860 Bump million to 1.11.3 2022-06-28 21:43:28 -07:00
Jacky Zhao 5caa93cd5e Merge pull request #146 from geoffreygarrett/hugo 2022-06-27 16:27:57 -07:00
Geoffrey Garrett 87e01d32a0 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 28495292af docs(config.md): Fixed multi-favicon examples and general favicon explanation throughout 2022-06-28 01:15:33 +02:00
Geoffrey Garrett d3075c02bb docs(config.md): Added short explainer on favicons 2022-06-28 00:45:48 +02:00
Geoffrey Garrett 33958c09f7 docs(content/notes/config.md): Adds documentation for the new favicon support 2022-06-27 22:05:35 +02:00
Geoffrey Garrett e42fd64f86 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 4faa0205a7 Merge pull request #140 from DhammaCharts/hugo 2022-06-07 08:43:52 -07:00
DhammaCharts 74eacf732c change enableGlobalGraph to false 2022-06-06 16:49:01 +01:00
DhammaCharts 32354d4d9d minor adjustment 2022-06-06 16:48:16 +01:00
DhammaCharts dcbce2bece Update layouts/partials/head.html
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
2022-06-06 16:42:53 +01:00
DhammaCharts ca6a6f67fa Merge branch 'hugo' into hugo 2022-06-06 12:56:47 +01:00
Jacky Zhao faa472db04 Merge pull request #139 from aidenybai/prerender-latex 2022-06-03 10:59:18 -07:00
DhammaCharts 4bdfbcfbfb better font behaviour 2022-06-02 08:35:28 +01:00
DhammaCharts e9d9a6cfb9 change to object destructuring for drawGraph() arguments 2022-06-02 08:16:02 +01:00
DhammaCharts 2726835ea0 remove unnecessary ternary 2022-06-02 07:49:09 +01:00
DhammaCharts 49e2072633 change baseURL back to original 2022-06-02 07:45:44 +01:00
DhammaCharts a61b57f827 uncomment window.Million 2022-06-01 21:30:40 +01:00
DhammaCharts 077f3a0d11 increase scale 2022-06-01 21:22:31 +01:00
DhammaCharts e63463a981 add www. 2022-06-01 21:19:03 +01:00
DhammaCharts 5c405ac0c8 change baseURL 2022-06-01 20:15:44 +01:00
DhammaCharts 47dae8a6d4 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 4c291a7d87 Prerender latex 2022-05-29 20:40:44 -07:00
Jacky Zhao eb62163549 Merge pull request #138 from aidenybai/add-footer-config 2022-05-28 23:27:54 -07:00
Aiden Bai fcfb6bf008 Add option to toggle footer 2022-05-28 22:52:18 -07:00
Jacky Zhao c73b6552a2 Merge pull request #137 from aidenybai/fix-non-spa-routing 2022-05-27 19:21:05 -07:00
Aiden Bai 4eaa753e32 Fix formatting 2022-05-27 18:45:42 -07:00
Aiden Bai ed17d678f6 Fix non-spa fallback 2022-05-27 18:42:01 -07:00
Jacky Zhao 8dafd4f1fe Merge pull request #136 from aidenybai/custom-progress-bar-color 2022-05-27 18:32:49 -07:00
Aiden Bai 0da10b77a5 Remove redundant CSS rule 2022-05-27 18:31:36 -07:00
Jacky Zhao b3da25a8f2 Merge pull request #135 from aidenybai/bump-million 2022-05-27 17:14:55 -07:00
Aiden Bai 9c459c0aeb Bump to 1.9.6 2022-05-27 16:14:17 -07:00
Aiden Bai ad94850f82 Add support for progress bar 2022-05-27 13:27:13 -07:00
Aiden Bai f4fb941de7 Bump million to 1.9.5 2022-05-27 13:19:19 -07:00
Jacky Zhao a5942130db Merge pull request #134 from aidenybai/add-prefetching-within-graph 2022-05-27 11:01:20 -07:00
Aiden Bai c5247d4df8 Bump million to 1.9.4 2022-05-27 09:49:28 -07:00
Aiden Bai aff7855269 Bump milliomn to 1.9.3 2022-05-27 09:02:01 -07:00
Aiden Bai c1b8d1965b Add prefetch to graph 2022-05-27 08:40:00 -07:00
Aiden Bai 0978df58f7 Bump million to 1.9.2 2022-05-27 08:39:44 -07:00
Jacky Zhao 0e454790e9 feat: recent posts section/partial 2022-05-23 22:25:13 -07:00
Jacky Zhao b719568b2c fix: js not executing if spa disabled 2022-05-20 16:50:56 -04:00
Jacky Zhao 597d514480 fix: tag boxes overlapping for content with many tags (closes #130) 2022-05-14 16:47:50 -04:00
Jacky Zhao 13cc826cf3 fix inline link highlighting, safer latex render 2022-05-05 21:11:23 -04:00
Jacky Zhao 63a14e205b fix: more generic style to match bad nesting generated by popover interp 2022-05-05 20:35:32 -04:00
Jacky Zhao dd6440e153 fix: clean wikilinks and render latex in popover 2022-05-05 20:30:55 -04:00
Jacky Zhao b61392bea6 fix: merge conf 2022-05-05 01:03:09 -04:00
Jacky Zhao 81f30fea4e feat: contextual backlinks (closes #106) 2022-05-05 00:58:50 -04:00
Jacky Zhao 9d5777b934 Merge pull request #125 from aidenybai/fix-latex 2022-05-04 11:40:38 -04:00
Aiden Bai b3182f5d3f Remove pnpm debug log 2022-05-04 08:39:25 -07:00
Aiden Bai 15f4fe4306 Fix latex 2022-05-04 08:10:59 -07:00
Jacky Zhao 5f089f57f7 Merge pull request #124 from aidenybai/hugo 2022-05-03 13:59:02 -04:00
Aiden Bai 5c7d7eb5f8 Remove redundant URL construction 2022-05-03 10:55:45 -07:00
Aiden Bai b146d410d9 Support /path root sites 2022-05-03 10:54:39 -07:00
Aiden Bai b5bf2152ac Support active node with other data at end of url 2022-05-03 10:38:41 -07:00
Jacky Zhao 3ac4226fee Merge pull request #123 from aidenybai/fix-popover 2022-05-03 13:21:32 -04:00
Aiden Bai 00dfceceac Merge 2022-05-03 10:18:41 -07:00
Aiden Bai b218ce4c56 Rename API and generalize router API 2022-05-03 10:16:09 -07:00
Aiden Bai 8bfd982d4c Merge 2022-05-03 10:07:38 -07:00
Aiden Bai 3eb7297eaf Add future note about init function 2022-05-03 09:34:27 -07:00
Aiden Bai 白宇彤 fb867fedcf Merge branch 'hugo' into fix-popover 2022-05-03 09:33:00 -07:00
Jacky Zhao 7dd40f88ac Merge pull request #122 from aidenybai/fix-active-graph-node 2022-05-03 12:29:26 -04:00
Aiden Bai 055422cc17 Use explicit regex for trailing slash trim 2022-05-03 09:27:25 -07:00
Aiden Bai 018c55bd99 Remove unnecessary 'url' argument in graph.html 2022-05-03 09:22:51 -07:00
Aiden Bai 322643335b Remove unnecessary 'url' argument in graph.html 2022-05-03 09:21:44 -07:00
Aiden Bai 8d105ce68f Remove unnecessary 'url' param in drawGraph 2022-05-03 09:20:01 -07:00
Aiden Bai c3d49818bc Peg router version 2022-05-03 09:04:15 -07:00
Aiden Bai 7a80cc0510 Fix active node on graph 2022-05-03 08:53:18 -07:00
Aiden Bai 6f002d5f5b Enable config for testing 2022-05-03 08:48:35 -07:00
Aiden Bai 4525576341 Fix popover 2022-05-03 08:47:42 -07:00
Jacky Zhao a1d03a044e fix: trim trailing slash when calculating popover 2022-05-03 10:57:20 -04:00
Jacky Zhao b78c02c6f3 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-05-03 10:44:56 -04:00
Jacky Zhao 516eeca853 cfg: make SPA optional 2022-05-03 10:43:22 -04:00
Jacky Zhao ebe627c5fd Merge pull request #121 from benbohmer/patch-1 2022-05-03 09:48:50 -04:00
Jacky Zhao d758e6b4a3 Merge pull request #120 from straightupjac/fix/github-info 2022-05-03 09:47:48 -04:00
benbohmer c9af35742b 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 c20da99a98 fix github info 2022-05-03 01:51:15 -04:00
Jacky Zhao 7653fc0eac fix: broken semi and graph min-height 2022-05-02 13:00:41 -04:00
Jacky Zhao c3eaa9ea86 fmt: remove semis for good 2022-05-02 12:56:44 -04:00
Jacky Zhao 8934617ca0 Merge pull request #118 from aidenybai/add-router 2022-05-02 12:19:26 -04:00
Jacky Zhao 24f70ec244 fmt: remove semis :) 2022-05-02 12:14:51 -04:00
Aiden Bai 81f9e295e4 Fix clarification comment 2022-05-02 09:10:40 -07:00
Jacky Zhao 621ba6465e Merge pull request #119 from aidenybai/add-prettier
Add prettier config
2022-05-02 12:06:57 -04:00
Aiden Bai 17b3039d64 Expand template 2022-05-02 09:05:02 -07:00
Aiden Bai 3f60ab4bbf Add clarification comments 2022-05-02 09:04:36 -07:00
Aiden Bai 7cc9974f93 Use semi: false for prettier config 2022-05-02 08:57:25 -07:00
Aiden Bai 42cb28afb8 Add prettier config 2022-05-01 22:08:14 -07:00
Aiden Bai b4675a9282 Add router 2022-05-01 22:06:33 -07:00
Jacky Zhao e72fc0b62b fix: add update for local hugo-obsidian on make update 2022-04-30 13:13:30 -07:00
Jacky Zhao 5ef8a0c26f feat: copyable header anchors (fixes #86) 2022-04-30 13:10:12 -07:00
Jacky Zhao dcb701721c Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-28 15:53:57 -07:00
Jacky Zhao 92d5e5bd3b feat: show graph titles on zoom (fixes #92) 2022-04-28 15:49:16 -07:00
Jacky Zhao b09df08e07 fix: always hide popover on mobile (fixes #104) 2022-04-28 13:45:29 -07:00
Jacky Zhao 5451e16dd8 fix: append trailing slash, fixes #111 2022-04-28 10:48:31 -07:00
Jacky Zhao 4c8b916197 Merge pull request #108 from exu3/patch-1 2022-04-20 09:20:21 -07:00
Ella 15c046410d Fix another typo 2022-04-17 02:11:17 -07:00
Ella 05d1b12c7f Fix typo: recomment -> recommend 2022-04-17 01:33:16 -07:00
Jacky Zhao 9daef8557b fix: add dropshadow to popover, cleanup animation 2022-04-05 23:19:33 -07:00
Jacky Zhao 493ba0513d fix: popover selection wrongly including line breaks 2022-04-05 22:43:11 -07:00
Jacky Zhao bde1fe5f6a deps: bump hugo -> v0.96.0 2022-04-05 21:40:59 -07:00
Jacky Zhao c92332681a fix: check for src before attempting to add popover 2022-04-05 20:44:39 -07:00
Jacky Zhao b3e699bbf6 fix: missing whitespace chomp in link render hook 2022-04-05 18:07:40 -07:00
Jacky Zhao 396efaadaa fix: wikilink patch not applying to transformed text like apostrophes 2022-04-05 14:14:19 -07:00
Jacky Zhao 23ecd06eef fix: wikilink image relURL for images with spaces 2022-04-05 14:08:36 -07:00
Jacky Zhao cc9050b284 fix: wikilink-like text in code fences #95, #97 2022-04-05 13:47:24 -07:00
Jacky Zhao d07d6ceec1 feat: wikilink img support 2022-04-05 12:47:28 -07:00
Jacky Zhao a443796539 fix: align footer links 2022-04-05 09:41:13 -07:00
Jacky Zhao 9e298dd25d docs: make update command and clarify update steps/potential danger 2022-04-05 00:09:56 -07:00
Jacky Zhao 9e5e2d3d44 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-05 00:02:48 -07:00
Jacky Zhao 26e6ec1cb8 add update target to Makefile 2022-04-05 00:02:37 -07:00
Jacky Zhao 4fd224efed Merge pull request #93 from meleu/patch-3 2022-04-04 23:56:28 -07:00
Jacky Zhao 093da40cdf update screenshot 2022-04-04 23:30:28 -07:00
Jacky Zhao 3bcfa8936a feat: hide toc for short notes 2022-04-04 23:25:24 -07:00
Jacky Zhao 0c0a755162 Merge pull request #94 from meleu/patch-4 2022-04-04 23:20:43 -07:00
meleu 864048f360 link to home goes to baseURL 2022-04-04 20:15:40 -03:00
meleu 4cd43aabc9 docs: warn about possible lost of customization 2022-04-04 17:30:23 -03:00
Jacky Zhao a69f0f4faa Merge pull request #91 from meleu/patch-2 2022-04-04 13:08:42 -07:00
meleu 4c58f1fd32 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 03fd0aea23 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-04 09:45:05 -07:00
Jacky Zhao 3d2e563d2a re-add obsidian file 2022-04-04 09:44:58 -07:00
meleu 89b9abc04e Merge branch 'jackyzha0:hugo' into patch-2 2022-04-03 22:14:12 -03:00
meleu fc342fe8a3 add a collapsible ToC 2022-04-03 22:12:55 -03:00
Jacky Zhao 76c695af0e Merge pull request #88 from meleu/patch-2 2022-04-03 17:57:46 -07:00
Jacky Zhao 3ec8145d74 fix: favicon not showing on non-root domain #89 2022-04-03 17:43:37 -07:00
meleu 99e4fb786d use "enableToc: false" 2022-04-03 16:31:29 -03:00
meleu 8c1bf40202 disable ToC if frontmatter has "enableToc: false" 2022-04-03 16:29:10 -03:00
meleu 4ea7d0c32d disable ToC if enableToc: false 2022-04-03 16:22:32 -03:00
Jacky Zhao 320a377262 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-03 11:44:39 -07:00
Jacky Zhao ad9f2e502f fix: multiline code block #87 2022-04-03 11:44:33 -07:00
Jacky Zhao c3c39c2d08 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 3af6e4e680 duplicated file 2022-04-03 11:19:21 -03:00
Jacky Zhao 948cbdfc07 README update 2022-04-02 21:04:20 -07:00
Jacky Zhao 52fdfc111f bump hugo version v0.82 -> v0.92.2 2022-04-02 20:37:42 -07:00
Jacky Zhao 2dd7171d0e fix latex misrendering 2022-04-02 20:34:55 -07:00
Jacky Zhao ef89dfaac8 bump hugo obsidian, fix backlinks for subpathed quartz, update homepage 2022-04-02 20:21:16 -07:00
Jacky Zhao e247835d15 feat: wikilinks implementation 2022-04-02 20:06:31 -07:00
Jacky Zhao 0f98d65f4c fix: cjk support + demo page 2022-04-02 17:38:39 -07:00
Jacky Zhao 2d48e11a78 feat: basic latex support 2022-04-02 17:00:14 -07:00
Jacky Zhao e02b804523 Merge pull request #83 from meleu/patch-2 2022-04-02 14:53:05 -07:00
meleu 84b36d2534 cleanup 2022-04-02 18:51:45 -03:00
meleu aabcdea76f separate contact links semantically 2022-04-02 18:50:58 -03:00
Jacky Zhao 129d13743b feat: grey out broken links 2022-04-02 13:34:26 -07:00
Jacky Zhao 960de47cad Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-04-02 12:59:47 -07:00
Jacky Zhao 39794d4d69 fix: non-unicode character in popover and search #67, #68 2022-04-02 12:59:38 -07:00
meleu aff7b38826 separate links with &ZeroWidthSpace; 2022-04-02 13:37:12 -03:00
Jacky Zhao 6f2e0db24c Merge pull request #82 from meleu/patch-1 2022-04-01 14:17:35 -07:00
meleu 5aef637877 fix custom.scss path 2022-04-01 18:13:49 -03:00
Jacky Zhao e30e4e12f9 fix pagination styling 2022-04-01 10:13:01 -07:00
Jacky Zhao 27ecf74b4f Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-03-31 23:16:00 -07:00
Jacky Zhao ea0686f032 more troubleshooting, backlinks reference private page fix 2022-03-31 23:15:54 -07:00
Jacky Zhao 6315dd8dba Merge pull request #71 from siyangsun/patch-1 2022-03-21 09:15:35 -07:00
Siyang 4826a21604 add to showcase and fix link to file 2022-03-20 22:37:05 -07:00
Jacky Zhao d040ffdb27 patch image 2022-03-18 10:53:39 -07:00
Jacky Zhao 1fcd21fdcb add update 2022-03-16 17:54:24 -07:00
Jacky Zhao 3c6e446678 fix: bump hugo-obsidian version to account for contentIndex paths on windows 2022-03-15 01:12:08 -07:00
Jacky Zhao 4592bde30d feat: better titles for empty pages #61 2022-03-15 00:37:56 -07:00
Jacky Zhao c51dcaaaf1 Merge pull request #65 from claudio4/fix-text 2022-03-09 10:11:36 -08:00
Claudio Yanes b89fffe959 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 4dcb8c62fd Merge pull request #62 from claudio4/hugo 2022-03-07 10:45:07 -08:00
Claudio Yanes 620d4ae8f7 Merge branch 'jackyzha0-hugo' into hugo 2022-03-07 18:28:14 +00:00
Claudio Yanes 5de94e0d14 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into jackyzha0-hugo 2022-03-07 18:27:45 +00:00
Claudio Yanes 29e2934dc2 Format JS 2022-03-07 18:25:02 +00:00
Jacky Zhao e7d299fa61 fix: hide popover on mobile to prevent overflow 2022-03-04 23:55:07 -08:00
Claudio Yanes 30a6697c5b 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 06a83a1825 Add .gitkeep to assets/indices 2022-03-04 04:14:42 +00:00
Claudio Yanes 4e1e39bff4 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 58b2d1dda9 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 1929b466c0 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 a1c6b89740 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 6846d314d6 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 4b257252ac fix backlinks not using baseurl 2022-02-28 08:24:29 -08:00
Jacky Zhao 58332d0b30 bump hugo-obsidian to support root 2022-02-28 07:30:59 -08:00
Jacky Zhao 03a276a00a fix: explicitly set root as current directory to fix ignore files 2022-02-28 07:14:55 -08:00
Jacky Zhao 3ca62f9ab0 add screenshot to readme 2022-02-23 12:28:25 -05:00
Jacky Zhao 3b998a320b fix: relink search button (move outside content load listener) 2022-02-22 13:36:08 -05:00
Jacky Zhao 15ff24a483 fix links being broken for pages with spaces 2022-02-20 21:40:10 -05:00
Jacky Zhao 85dea2ed79 rtl docs 2022-02-17 10:49:41 -05:00
Jacky Zhao c49adb26d6 docs updates 2022-02-17 10:44:39 -05:00
Jacky Zhao ce4c95b8ab fix #54: root all image urls 2022-02-15 23:03:02 -05:00
Jacky Zhao cf4e921ca4 fix relative pathing for dynamic fetch 2022-02-15 22:54:20 -05:00
Jacky Zhao 6b680a43bb change output to static instead of data 2022-02-15 19:42:45 -05:00
Jacky Zhao fdf1d9bbe3 feat: dynamically fetch indices 2022-02-15 19:39:14 -05:00
Jacky Zhao 556d6799f2 feat: add rtl support as part of #47 2022-02-15 17:12:08 -05:00
Jacky Zhao a74c540ccc Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-02-15 16:52:49 -05:00
Jacky Zhao dc9038792e fix: #50, change css load order 2022-02-15 16:52:32 -05:00
Jacky Zhao 4fd71221f9 Merge pull request #51 from brandonkboswell/patch-1 2022-02-15 14:51:29 -05:00
Jacky Zhao 687edcb902 Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2022-02-15 14:50:34 -05:00
Jacky Zhao 4dcf573fc5 visibility fix 2022-02-15 14:50:25 -05:00
Brandon Boswell 1e027f9ede Added to the Showcase 2022-02-12 22:35:03 -05:00
Jacky Zhao 8d10bdb5df Merge pull request #48 from earnestma/earne/configurable-page-toc 2022-02-11 17:24:54 -05:00
earnest ma 3ea23a0d1c Add disableToc parameter to not show TOC on a page 2022-02-11 17:15:28 -05:00
Jacky Zhao c867a6f0af Merge pull request #46 from adube/patch-1 2022-01-31 12:28:40 -08:00
Alexandre Dubé ef6dce93da 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 18ec469e1f link fixing 2022-01-27 09:38:28 -08:00
Jacky Zhao f268b9728f underscore fix, fix relative path being weird for graph 2022-01-10 13:08:50 -08:00
Jacky Zhao 9106a1605f fix popover regex 2022-01-10 09:00:45 -08:00
Jacky Zhao 1f3cad2afa revert baseurl fix 2022-01-10 08:51:00 -08:00
Jacky Zhao 2caba8f250 various path fixes 2022-01-10 08:49:29 -08:00
Jacky Zhao 3de584c78c set relativeUrls to true 2022-01-05 19:42:13 -05:00
Jacky Zhao fc5748ffa4 docs update 2022-01-04 11:39:22 -05:00
Jacky Zhao 06c7923ad3 update featurelist 2022-01-03 16:37:24 -05:00
Jacky Zhao d39691e43a fix copy selection 2022-01-03 15:36:58 -05:00
Jacky Zhao e8327048bd made link preview optional 2022-01-03 13:22:04 -05:00
Jacky Zhao 671fe795b2 popover implementation 2022-01-03 13:18:31 -05:00
Jacky Zhao 51308b20a0 fix flex gap 2022-01-02 20:02:47 -05:00
Jacky Zhao 470cce1866 fix search styling 2022-01-02 19:49:41 -05:00
Jacky Zhao 5359ffe35f fix render link for apostrophe 2021-12-28 14:28:08 -05:00
Jacky Zhao fac4950315 bump hugo-obsidian 2021-12-27 20:52:30 -05:00
Jacky Zhao 722a8c645b add pagination to section, fix graph linking 2021-12-27 20:16:21 -05:00
Jacky Zhao bc218f3d61 remove console.log 2021-12-27 19:43:01 -05:00
Jacky Zhao 05bee3c878 add taxonomy and term lists 2021-12-27 19:35:42 -05:00
Jacky Zhao f664d5e49e fix last modified not working for capitalized pages 2021-12-27 17:53:33 -05:00
Jacky Zhao 22830be78a fix capitalization 2021-12-27 17:44:39 -05:00
Jacky Zhao ab192437dc fix casing 2021-12-27 17:43:27 -05:00
Jacky Zhao 2e7801d20b modify obsidian 2021-12-27 17:34:53 -05:00
Jacky Zhao 8b1cc8ffc1 enable last modified info 2021-12-27 17:28:53 -05:00
Jacky Zhao 64596c3742 content section 2021-12-27 15:59:19 -05:00
Jacky Zhao 6b5baa4f61 dedupe backlinks 2021-12-27 13:15:10 -05:00
Jacky Zhao 000611b2ea add graph depth config 2021-12-27 13:06:58 -05:00
Jacky Zhao 8fd011ac31 base tags 2021-12-26 21:13:21 -05:00
Jacky Zhao 3891f13e9e various font and colour fixes 2021-12-26 00:09:15 -05:00
Jacky Zhao 42a11e3f39 add makefile, fix link padding, test capitalization 2021-12-25 23:45:30 -05:00
Jacky Zhao c9400d06fa fix untitled #36 2021-12-24 15:51:37 -05:00
Jacky Zhao 7858bc70cf Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2021-12-24 09:48:41 -05:00
Jacky Zhao b5643bf747 add toLowerCase to id 2021-12-24 09:48:22 -05:00
Jacky Zhao c6412ea6e4 fix config setting, fix font size for h1 in article 2021-12-23 14:40:59 -08:00
Jacky Zhao 74e1092b44 actually display site title 2021-12-23 14:32:47 -08:00
Jacky Zhao ed93fc8b7b update subdomain docs 2021-12-23 14:21:39 -08:00
Jacky Zhao cca56fbd2b 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 1ccfb6e8d3 Create CODE_OF_CONDUCT.md 2021-12-23 13:37:29 -08:00
Jacky Zhao 9e54be2403 Update issue templates 2021-12-23 13:22:22 -08:00
Jacky Zhao 9aa78a6c98 Create FUNDING.yml 2021-12-23 13:18:03 -08:00
Jacky Zhao f36f9b11dd Merge pull request #28 from juaoose/overflow 2021-12-02 20:06:18 -08:00
Juaoose b63d9c1abd remove horizontal scrollbar 2021-12-02 22:58:34 -05:00
Jacky Zhao e332d5f9a6 remove bad wikilink 2021-11-20 22:55:53 -08:00
Jacky Zhao ab17ca5816 better search, fix spacing support, bump hugo-obsidian 2021-11-20 22:53:26 -08:00
Jacky Zhao b80562bc37 search styling 2021-11-15 15:54:18 -08:00
Jacky Zhao e55361d476 search patch 2021-10-31 09:59:38 -07:00
Jacky Zhao 555f293801 more search improvements 2021-10-30 23:27:33 -07:00
Jacky Zhao 7f9444c0e8 css fixes 2021-10-27 20:10:04 -07:00
Jacky Zhao a7669d317f update graph redir 2021-10-26 17:06:00 -07:00
Jacky Zhao d4a7456fd6 Merge pull request #23 from bur3ku/hugo 2021-10-26 17:03:07 -07:00
Blake Allen 657e3b6380 Merge branch 'hugo' of https://github.com/bur3ku/quartz into hugo 2021-10-26 16:58:37 -07:00
Blake Allen c457f0af60 remove unnecessary regex, use encodeuri for label instead of replace 2021-10-26 16:58:08 -07:00
Blake Allen 8f2e5f1bdb Merge branch 'hugo' into hugo 2021-10-26 12:46:03 -07:00
Blake Allen 7f9f9dca8a fix conflict fix 2021-10-26 12:44:25 -07:00
Blake Allen 4e2f8eb96a fix conflict 2021-10-26 12:43:55 -07:00
Blake Allen 786d5d84f2 change %20 in node labels to whitespace, change %20 in node hrefs to hyphen 2021-10-26 12:36:20 -07:00
Jacky Zhao a805f19f38 normalize search styling 2021-10-25 15:06:29 -07:00
Jacky Zhao 8c74061ea2 search fix 2021-10-25 15:00:55 -07:00
Jacky Zhao 5c4b6046b2 better homepage 2021-10-24 23:45:55 -07:00
Jacky Zhao afaf25ba45 forgot string lol 2021-10-24 23:32:55 -07:00
Jacky Zhao 8e27c78c1f docs updates, add search to main page, fix redir bug 2021-10-24 23:31:09 -07:00
Jacky Zhao 1150feb378 bump docs 2021-10-24 23:17:20 -07:00
Jacky Zhao bbfbe2ed90 search improvements 2021-10-24 23:17:13 -07:00
Jacky Zhao 5577b46db3 bump hugo-obsidian version 2021-10-24 23:17:00 -07:00
Blake Allen a50c87d1cd fix accidental code 2021-10-22 18:56:26 -07:00
Blake Allen b1b2913834 fix last commit 2021-10-22 18:32:57 -07:00
Blake Allen c942c5e09d fix for notes with spaces not linking properly 2021-10-22 14:04:09 -07:00
Jacky Zhao 40fef3fe61 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 84b4ee9119 fix product typo in external hosting section 2021-08-31 16:40:31 -05:00
jackyzha0 7d34dfd501 update showcase 2021-08-28 20:58:14 -04:00
jackyzha0 efe3932bfb Merge branch 'hugo' of https://github.com/jackyzha0/quartz into hugo 2021-08-27 14:08:18 -04:00
Jacky Zhao 943858ded5 Merge pull request #9 from brechtcs/template
Execute darkmode script before first render
2021-08-13 17:45:32 -04:00
Brecht Savelkoul 9d47dc942e Execute darkmode script before first render 2021-08-13 22:50:02 +02:00
Jacky Zhao b5ed5aa14b Merge pull request #8 from SlRvb/patch-1
Add SlRvb Site to Showcase
2021-08-12 23:49:05 -04:00
SlRvb 1d1ac23ff8 Add SlRvb Site to Showcase 2021-08-12 20:46:23 -07:00
218 changed files with 17060 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
.gitignore
node_modules
public
resources
.idea
content/.obsidian
data/linkIndex.yaml
data/contentIndex.yaml
prof
tsconfig.tsbuildinfo
.obsidian
.quartz-cache
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._

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM node:20-slim as builder
WORKDIR /usr/src/app
COPY package.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"]

24
Makefile Normal file
View File

@ -0,0 +1,24 @@
.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:
@if [ "$(clean)" = "True" ]; then \
./scripts/publish.py clean; \
else \
./scripts/publish.py; \
fi
@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,56 @@
# Quartz
Simple second brain and digital garden.
# Quartz v4
> “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 remote vault and copy to content all that have tag publish=True
Current set up:
![Diagram](flow.png)
## Improvements
- scripts/publish.sh:
- [x] Skip copying files that already exist
- [x] Resize image to 60% for faster load
- [x] Keep source and destination dirs in sync
- [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:
notes:
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.notes.rule=Host(`notes.velouria.dev`)"
- "traefik.http.routers.notes.entrypoints=websecure"
- "traefik.http.routers.notes.tls.certresolver=myresolver"
- "traefik.http.services.notes.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).

BIN
flow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

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>

5418
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

110
package.json Normal file
View File

@ -0,0 +1,110 @@
{
"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",
"sharp": "0.33.2",
"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: "DM Sans",
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

44
quartz.layout.ts Normal file
View File

@ -0,0 +1,44 @@
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.DesktopOnly(Component.TableOfContents()),
],
}
// 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: [],
}

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