rendering, link resolution, asset copying
This commit is contained in:
		
							
								
								
									
										456
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										456
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -9,13 +9,16 @@ | ||||
|       "version": "4.0.3", | ||||
|       "license": "MIT", | ||||
|       "dependencies": { | ||||
|         "@flowershow/remark-wiki-link": "^1.2.0", | ||||
|         "@inquirer/prompts": "^1.0.3", | ||||
|         "@napi-rs/simple-git": "^0.1.8", | ||||
|         "chalk": "^4.1.2", | ||||
|         "cli-spinner": "^0.2.10", | ||||
|         "globby": "^13.1.4", | ||||
|         "gray-matter": "^4.0.3", | ||||
|         "hast-util-to-jsx-runtime": "^1.2.0", | ||||
|         "hast-util-to-string": "^2.0.0", | ||||
|         "is-absolute-url": "^4.0.1", | ||||
|         "preact": "^10.14.1", | ||||
|         "preact-render-to-string": "^6.0.3", | ||||
|         "pretty-time": "^1.1.0", | ||||
| @@ -32,11 +35,11 @@ | ||||
|         "serve-handler": "^6.1.5", | ||||
|         "to-vfile": "^7.2.4", | ||||
|         "unified": "^10.1.2", | ||||
|         "unist-util-visit": "^4.1.2", | ||||
|         "vfile": "^5.3.7", | ||||
|         "yargs": "^17.7.2" | ||||
|       }, | ||||
|       "bin": { | ||||
|         "cycle-detect": "madge --circular --extensions ts .", | ||||
|         "quartz": "quartz/bootstrap.mjs" | ||||
|       }, | ||||
|       "devDependencies": { | ||||
| @@ -64,6 +67,17 @@ | ||||
|         "node": ">=6.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@babel/runtime": { | ||||
|       "version": "7.22.3", | ||||
|       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz", | ||||
|       "integrity": "sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==", | ||||
|       "dependencies": { | ||||
|         "regenerator-runtime": "^0.13.11" | ||||
|       }, | ||||
|       "engines": { | ||||
|         "node": ">=6.9.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@dependents/detective-less": { | ||||
|       "version": "3.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-3.0.2.tgz", | ||||
| @@ -429,6 +443,16 @@ | ||||
|         "node": ">=12" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@flowershow/remark-wiki-link": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/@flowershow/remark-wiki-link/-/remark-wiki-link-1.2.0.tgz", | ||||
|       "integrity": "sha512-CI4+jjoZ0n036tZBjvMX4XyVAzHxU/6hDrl78511VSgwnRAYMEo6Jqxg9suq+mW0FlREz3mSQGpsbXcc92sqhA==", | ||||
|       "dependencies": { | ||||
|         "mdast-util-to-markdown": "^1.5.0", | ||||
|         "mdast-util-wiki-link": "^0.0.2", | ||||
|         "micromark-util-symbol": "^1.0.1" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/@inquirer/checkbox": { | ||||
|       "version": "1.2.8", | ||||
|       "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-1.2.8.tgz", | ||||
| @@ -1309,6 +1333,24 @@ | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/character-entities-legacy": { | ||||
|       "version": "1.1.4", | ||||
|       "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", | ||||
|       "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/character-reference-invalid": { | ||||
|       "version": "1.1.4", | ||||
|       "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", | ||||
|       "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/chardet": { | ||||
|       "version": "0.7.0", | ||||
|       "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", | ||||
| @@ -2343,6 +2385,26 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/hast-util-to-jsx-runtime": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-1.2.0.tgz", | ||||
|       "integrity": "sha512-Y4FB8Dx2k6zJZrwbexkVm6YVRA8Sho2tTwacjDSr/x5c0wioOpc1VIoLyGUSb8+8xkAnQPAtHbdMvzA6bl0F1w==", | ||||
|       "dependencies": { | ||||
|         "@types/hast": "^2.0.0", | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "comma-separated-tokens": "^2.0.0", | ||||
|         "hast-util-whitespace": "^2.0.0", | ||||
|         "property-information": "^6.0.0", | ||||
|         "space-separated-tokens": "^2.0.0", | ||||
|         "style-to-object": "^0.4.1", | ||||
|         "unist-util-position": "^4.0.0", | ||||
|         "vfile-message": "^3.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/hast-util-to-string": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz", | ||||
| @@ -2370,6 +2432,15 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/hast-util-whitespace": { | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", | ||||
|       "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/hastscript": { | ||||
|       "version": "7.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", | ||||
| @@ -2453,6 +2524,44 @@ | ||||
|       "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/inline-style-parser": { | ||||
|       "version": "0.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", | ||||
|       "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" | ||||
|     }, | ||||
|     "node_modules/is-absolute-url": { | ||||
|       "version": "4.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", | ||||
|       "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", | ||||
|       "engines": { | ||||
|         "node": "^12.20.0 || ^14.13.1 || >=16.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "url": "https://github.com/sponsors/sindresorhus" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/is-alphabetical": { | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", | ||||
|       "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/is-alphanumerical": { | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", | ||||
|       "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", | ||||
|       "dependencies": { | ||||
|         "is-alphabetical": "^1.0.0", | ||||
|         "is-decimal": "^1.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/is-buffer": { | ||||
|       "version": "2.0.5", | ||||
|       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", | ||||
| @@ -2487,6 +2596,15 @@ | ||||
|         "url": "https://github.com/sponsors/ljharb" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/is-decimal": { | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", | ||||
|       "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/is-extendable": { | ||||
|       "version": "0.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", | ||||
| @@ -2522,6 +2640,15 @@ | ||||
|         "node": ">=0.10.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/is-hexadecimal": { | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", | ||||
|       "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/is-interactive": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", | ||||
| @@ -2813,33 +2940,6 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | ||||
|       "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0", | ||||
|         "unist-util-visit-parents": "^5.1.1" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-definitions/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-find-and-replace": { | ||||
|       "version": "2.2.2", | ||||
|       "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", | ||||
| @@ -2866,19 +2966,6 @@ | ||||
|         "url": "https://github.com/sponsors/sindresorhus" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-find-and-replace/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-from-markdown": { | ||||
|       "version": "1.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.0.tgz", | ||||
| @@ -3050,33 +3137,6 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | ||||
|       "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0", | ||||
|         "unist-util-visit-parents": "^5.1.1" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-to-markdown": { | ||||
|       "version": "1.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", | ||||
| @@ -3096,33 +3156,6 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | ||||
|       "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0", | ||||
|         "unist-util-visit-parents": "^5.1.1" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-to-string": { | ||||
|       "version": "3.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", | ||||
| @@ -3135,6 +3168,59 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-wiki-link": { | ||||
|       "version": "0.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/mdast-util-wiki-link/-/mdast-util-wiki-link-0.0.2.tgz", | ||||
|       "integrity": "sha512-lSsR10/dPuYIxzjGZIGA4oYzsnEnqcsD6DTXL0pqdbBzNB9teKVZB2aIzZcUsdg31v/NoHOstkVwzbN6VrQLtw==", | ||||
|       "dependencies": { | ||||
|         "@babel/runtime": "^7.12.1", | ||||
|         "mdast-util-to-markdown": "^0.6.5" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-wiki-link/node_modules/longest-streak": { | ||||
|       "version": "2.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", | ||||
|       "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-wiki-link/node_modules/mdast-util-to-markdown": { | ||||
|       "version": "0.6.5", | ||||
|       "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", | ||||
|       "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "longest-streak": "^2.0.0", | ||||
|         "mdast-util-to-string": "^2.0.0", | ||||
|         "parse-entities": "^2.0.0", | ||||
|         "repeat-string": "^1.0.0", | ||||
|         "zwitch": "^1.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-wiki-link/node_modules/mdast-util-to-string": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", | ||||
|       "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/mdast-util-wiki-link/node_modules/zwitch": { | ||||
|       "version": "1.0.5", | ||||
|       "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", | ||||
|       "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/merge2": { | ||||
|       "version": "1.4.1", | ||||
|       "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", | ||||
| @@ -4027,6 +4113,32 @@ | ||||
|         "node": ">=0.10.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/parse-entities": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", | ||||
|       "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", | ||||
|       "dependencies": { | ||||
|         "character-entities": "^1.0.0", | ||||
|         "character-entities-legacy": "^1.0.0", | ||||
|         "character-reference-invalid": "^1.0.0", | ||||
|         "is-alphanumerical": "^1.0.0", | ||||
|         "is-decimal": "^1.0.0", | ||||
|         "is-hexadecimal": "^1.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/parse-entities/node_modules/character-entities": { | ||||
|       "version": "1.2.4", | ||||
|       "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", | ||||
|       "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", | ||||
|       "funding": { | ||||
|         "type": "github", | ||||
|         "url": "https://github.com/sponsors/wooorm" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/parse-latin": { | ||||
|       "version": "5.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-5.0.1.tgz", | ||||
| @@ -4621,6 +4733,11 @@ | ||||
|         "node": ">= 6" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/regenerator-runtime": { | ||||
|       "version": "0.13.11", | ||||
|       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", | ||||
|       "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" | ||||
|     }, | ||||
|     "node_modules/rehype-katex": { | ||||
|       "version": "6.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-6.0.3.tgz", | ||||
| @@ -4638,33 +4755,6 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/rehype-katex/node_modules/unist-util-visit": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | ||||
|       "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0", | ||||
|         "unist-util-visit-parents": "^5.1.1" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/rehype-katex/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/remark": { | ||||
|       "version": "14.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.3.tgz", | ||||
| @@ -4767,33 +4857,6 @@ | ||||
|         "node": "^12.20.0 || ^14.13.1 || >=16.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/remark-smartypants/node_modules/unist-util-visit": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | ||||
|       "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0", | ||||
|         "unist-util-visit-parents": "^5.1.1" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/remark-smartypants/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/remark-stringify": { | ||||
|       "version": "10.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.3.tgz", | ||||
| @@ -4808,6 +4871,14 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/repeat-string": { | ||||
|       "version": "1.6.1", | ||||
|       "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", | ||||
|       "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", | ||||
|       "engines": { | ||||
|         "node": ">=0.10" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/require-directory": { | ||||
|       "version": "2.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", | ||||
| @@ -4940,33 +5011,6 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/retext-smartypants/node_modules/unist-util-visit": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | ||||
|       "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0", | ||||
|         "unist-util-visit-parents": "^5.1.1" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/retext-smartypants/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/retext-stringify": { | ||||
|       "version": "3.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-3.1.0.tgz", | ||||
| @@ -5350,6 +5394,14 @@ | ||||
|         "node": ">=0.10.0" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/style-to-object": { | ||||
|       "version": "0.4.1", | ||||
|       "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz", | ||||
|       "integrity": "sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==", | ||||
|       "dependencies": { | ||||
|         "inline-style-parser": "0.1.1" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/stylus-lookup": { | ||||
|       "version": "3.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-3.0.2.tgz", | ||||
| @@ -5644,7 +5696,19 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/unist-util-remove-position/node_modules/unist-util-visit": { | ||||
|     "node_modules/unist-util-stringify-position": { | ||||
|       "version": "3.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", | ||||
|       "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/unist-util-visit": { | ||||
|       "version": "4.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", | ||||
|       "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", | ||||
| @@ -5658,31 +5722,6 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/unist-util-remove-position/node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/unist-util-stringify-position": { | ||||
|       "version": "3.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", | ||||
|       "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/unist-util-visit-children": { | ||||
|       "version": "2.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-2.0.2.tgz", | ||||
| @@ -5695,6 +5734,19 @@ | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/unist-util-visit-parents": { | ||||
|       "version": "5.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", | ||||
|       "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", | ||||
|       "dependencies": { | ||||
|         "@types/unist": "^2.0.0", | ||||
|         "unist-util-is": "^5.0.0" | ||||
|       }, | ||||
|       "funding": { | ||||
|         "type": "opencollective", | ||||
|         "url": "https://opencollective.com/unified" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/util-deprecate": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", | ||||
|   | ||||
| @@ -25,13 +25,16 @@ | ||||
|     "quartz": "./quartz/bootstrap.mjs" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@flowershow/remark-wiki-link": "^1.2.0", | ||||
|     "@inquirer/prompts": "^1.0.3", | ||||
|     "@napi-rs/simple-git": "^0.1.8", | ||||
|     "chalk": "^4.1.2", | ||||
|     "cli-spinner": "^0.2.10", | ||||
|     "globby": "^13.1.4", | ||||
|     "gray-matter": "^4.0.3", | ||||
|     "hast-util-to-jsx-runtime": "^1.2.0", | ||||
|     "hast-util-to-string": "^2.0.0", | ||||
|     "is-absolute-url": "^4.0.1", | ||||
|     "preact": "^10.14.1", | ||||
|     "preact-render-to-string": "^6.0.3", | ||||
|     "pretty-time": "^1.1.0", | ||||
| @@ -48,6 +51,7 @@ | ||||
|     "serve-handler": "^6.1.5", | ||||
|     "to-vfile": "^7.2.4", | ||||
|     "unified": "^10.1.2", | ||||
|     "unist-util-visit": "^4.1.2", | ||||
|     "vfile": "^5.3.7", | ||||
|     "yargs": "^17.7.2" | ||||
|   }, | ||||
|   | ||||
| @@ -1,14 +1,13 @@ | ||||
| import { buildQuartz } from "./quartz" | ||||
| import Head from "./quartz/components/Head" | ||||
| import { ContentPage, CreatedModifiedDate, Description, FrontMatter, GitHubFlavoredMarkdown, Katex, RemoveDrafts } from "./quartz/plugins" | ||||
| import { LinkProcessing } from "./quartz/plugins/transformers/links" | ||||
|  | ||||
| export default buildQuartz({ | ||||
|   configuration: { | ||||
|     siteTitle: "🪴 Quartz 4.0", | ||||
|     prettyLinks: true, | ||||
|     markdownLinkResolution: 'absolute', | ||||
|     enableLatex: true, | ||||
|     enableSPA: true, | ||||
|     ignorePatterns: [], | ||||
|     ignorePatterns: ["private", "templates"], | ||||
|   }, | ||||
|   plugins: { | ||||
|     transformers: [ | ||||
| @@ -16,13 +15,18 @@ export default buildQuartz({ | ||||
|       new GitHubFlavoredMarkdown(), | ||||
|       new Katex(), | ||||
|       new Description(), | ||||
|       new CreatedModifiedDate() | ||||
|       new CreatedModifiedDate({ | ||||
|         priority: ['frontmatter', 'filesystem'] // you can add 'git' here for last modified from Git but this makes the build slower | ||||
|       }), | ||||
|       new LinkProcessing() | ||||
|     ], | ||||
|     filters: [ | ||||
|       new RemoveDrafts() | ||||
|     ], | ||||
|     emitters: [ | ||||
|       new ContentPage() | ||||
|       new ContentPage({ | ||||
|         Head: Head | ||||
|       }) | ||||
|     ] | ||||
|   }, | ||||
|   theme: { | ||||
|   | ||||
| @@ -53,8 +53,6 @@ yargs(hideBin(process.argv)) | ||||
|     const out = await esbuild.build({ | ||||
|       entryPoints: [fp], | ||||
|       write: false, | ||||
|       minifySyntax: true, | ||||
|       minifyWhitespace: true, | ||||
|       bundle: true, | ||||
|       keepNames: true, | ||||
|       platform: "node", | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { PluginTypes } from "./plugins" | ||||
| import { PluginTypes } from "./plugins/types" | ||||
|  | ||||
| export interface ColorScheme { | ||||
|   light: string, | ||||
| @@ -14,12 +14,6 @@ export interface ColorScheme { | ||||
| export interface QuartzConfig { | ||||
|   configuration: { | ||||
|     siteTitle: string, | ||||
|     /** How to resolve Markdown paths */ | ||||
|     markdownLinkResolution: 'absolute' | 'relative' | ||||
|     /** Strips folders from a link so that it looks nice */ | ||||
|     prettyLinks: boolean | ||||
|     /** Whether to process and render latex (increases bundle size) */ | ||||
|     enableLatex: boolean, | ||||
|     /** Whether to enable single-page-app style rendering. this prevents flashes of unstyled content and improves smoothness of Quartz */ | ||||
|     enableSPA: boolean, | ||||
|     /** Glob patterns to not search */ | ||||
|   | ||||
| @@ -1,18 +1,22 @@ | ||||
| import { resolveToRoot } from "../path" | ||||
| import { StaticResources } from "../resources" | ||||
|  | ||||
| interface Props { | ||||
|   title: string, | ||||
|   description: string, | ||||
|   externalResources: StaticResources, | ||||
|   baseDir: string | ||||
| export interface HeadProps { | ||||
|   title: string | ||||
|   description: string | ||||
|   slug: string | ||||
|   externalResources: StaticResources | ||||
| } | ||||
|  | ||||
| export default function({ title, description, externalResources, baseDir }: Props) { | ||||
| export default function({ title, description, slug, externalResources }: HeadProps) { | ||||
|   const { css, js } = externalResources | ||||
|   const baseDir = resolveToRoot(slug) | ||||
|   const iconPath = baseDir + "/static/icon.png" | ||||
|   const ogImagePath = baseDir + "/static/og-image.png" | ||||
|   return <head> | ||||
|     <title>{title}</title> | ||||
|     <meta charSet="utf-8" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||||
|     <meta property="og:title" content={title} /> | ||||
|     <meta property="og:description" content={title} /> | ||||
|     <meta property="og:image" content={ogImagePath} /> | ||||
| @@ -21,8 +25,16 @@ export default function({ title, description, externalResources, baseDir }: Prop | ||||
|     <link rel="icon" href={iconPath} /> | ||||
|     <meta name="description" content={description} /> | ||||
|     <meta name="generator" content="Quartz" /> | ||||
|     <meta charSet="UTF-8" /> | ||||
|     <base href={slug} /> | ||||
|     {css.map(href => <link key={href} href={href} rel="stylesheet" type="text/css" />)} | ||||
|     {js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource => <script key={resource.src} src={resource.src} />)} | ||||
|   </head> | ||||
| } | ||||
|  | ||||
| export function beforeDOMLoaded() { | ||||
|  | ||||
| } | ||||
|  | ||||
| export function onDOMLoaded() { | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,8 @@ import chalk from "chalk" | ||||
| import http from "http" | ||||
| import serveHandler from "serve-handler" | ||||
| import { createProcessor, parseMarkdown } from "./processors/parse" | ||||
| import { filterContent } from "./processors/filter" | ||||
| import { emitContent } from "./processors/emit" | ||||
|  | ||||
| interface Argv { | ||||
|   directory: string | ||||
| @@ -21,7 +23,16 @@ export function buildQuartz(cfg: QuartzConfig) { | ||||
|   return async (argv: Argv, version: string) => { | ||||
|     console.log(chalk.bgGreen.black(`\n Quartz v${version} \n`)) | ||||
|     const perf = new PerfTimer() | ||||
|     const output = path.join(argv.directory, argv.output) | ||||
|     const output = argv.output | ||||
|  | ||||
|     if (argv.verbose) { | ||||
|       const pluginCount = Object.values(cfg.plugins).flat().length | ||||
|       const pluginNames = (key: 'transformers' | 'filters' | 'emitters') => cfg.plugins[key].map(plugin => plugin.name) | ||||
|       console.log(`Loaded ${pluginCount} plugins`) | ||||
|       console.log(`  Transformers: ${pluginNames('transformers').join(", ")}`) | ||||
|       console.log(`  Filters: ${pluginNames('filters').join(", ")}`) | ||||
|       console.log(`  Emitters: ${pluginNames('emitters').join(", ")}`) | ||||
|     } | ||||
|  | ||||
|     // clean | ||||
|     if (argv.clean) { | ||||
| @@ -36,7 +47,7 @@ export function buildQuartz(cfg: QuartzConfig) { | ||||
|     perf.addEvent('glob') | ||||
|     const fps = await globby('**/*.md', { | ||||
|       cwd: argv.directory, | ||||
|       ignore: [...cfg.configuration.ignorePatterns, 'quartz/**'], | ||||
|       ignore: cfg.configuration.ignorePatterns, | ||||
|       gitignore: true, | ||||
|     }) | ||||
|  | ||||
| @@ -47,8 +58,8 @@ export function buildQuartz(cfg: QuartzConfig) { | ||||
|     const processor = createProcessor(cfg.plugins.transformers) | ||||
|     const filePaths = fps.map(fp => `${argv.directory}${path.sep}${fp}`) | ||||
|     const parsedFiles = await parseMarkdown(processor, argv.directory, filePaths, argv.verbose) | ||||
|     // const filteredContent = filterContent(cfg.plugins.filters, processedContent, argv.verbose) | ||||
|     // await emitContent(argv.directory, output, cfg, filteredContent, argv.verbose) | ||||
|     const filteredContent = filterContent(cfg.plugins.filters, parsedFiles, argv.verbose) | ||||
|     await emitContent(output, cfg, filteredContent, argv.verbose) | ||||
|     console.log(chalk.green(`Done in ${perf.timeSince()}`)) | ||||
|  | ||||
|     if (argv.serve) { | ||||
|   | ||||
| @@ -1,11 +1,20 @@ | ||||
| import path from 'path' | ||||
|  | ||||
| // Replaces all whitespace with dashes and URI encodes the rest | ||||
| export function pathToSlug(fp: string): string { | ||||
|   const { dir, name } = path.parse(fp) | ||||
|   let slug = path.join('/', dir, name) | ||||
|   slug = slug.replace(/\s/g, '-') | ||||
|   return slug | ||||
| function slugSegment(s: string): string { | ||||
|   return s.replace(/\s/g, '-') | ||||
| } | ||||
|  | ||||
| export function slugify(s: string): string { | ||||
|   const [fp, anchor] = s.split("#", 2) | ||||
|   const sluggedAnchor = anchor === undefined ? "" : "#" + slugSegment(anchor) | ||||
|   const withoutFileExt = fp.replace(new RegExp(path.extname(fp) + '$'), '') | ||||
|   const rawSlugSegments = withoutFileExt.split(path.sep) | ||||
|   const slugParts: string = rawSlugSegments | ||||
|     .map((segment) => slugSegment(segment)) | ||||
|     .join(path.posix.sep) | ||||
|     // .replace(/index$/, '') | ||||
|     .replace(/\/$/, '') | ||||
|   return path.normalize(slugParts) + sluggedAnchor | ||||
| } | ||||
|  | ||||
| // resolve /a/b/c to ../../ | ||||
| @@ -15,5 +24,19 @@ export function resolveToRoot(slug: string): string { | ||||
|     fp = fp.slice(0, -"/index".length) | ||||
|   } | ||||
|  | ||||
|   return "./" + path.relative(fp, path.posix.sep) | ||||
|   return fp | ||||
|     .split('/') | ||||
|     .filter(x => x !== '') | ||||
|     .map(_ => '..') | ||||
|     .join('/') | ||||
| } | ||||
|  | ||||
| export function relativeToRoot(slug: string, fp: string): string { | ||||
|   return path.join(resolveToRoot(slug), fp) | ||||
| } | ||||
|  | ||||
| export function relative(src: string, dest: string): string { | ||||
|   return path.relative(src, dest) | ||||
| } | ||||
|  | ||||
| export const QUARTZ = "quartz" | ||||
|   | ||||
| @@ -1,26 +0,0 @@ | ||||
| import { resolveToRoot } from "../../path" | ||||
| import { EmitCallback, QuartzEmitterPlugin } from "../types" | ||||
| import { ProcessedContent } from "../vfile" | ||||
|  | ||||
| export class ContentPage extends QuartzEmitterPlugin { | ||||
|   name = "ContentPage" | ||||
|   async emit(content: ProcessedContent[], emit: EmitCallback): Promise<string[]> { | ||||
|     const fps: string[] = [] | ||||
|     for (const [tree, file] of content) { | ||||
|       const pathToRoot = resolveToRoot(file.data.slug!) | ||||
|  | ||||
|       const fp = file.data.slug + ".html" | ||||
|       await emit({ | ||||
|         title: file.data.frontmatter?.title ?? "Untitled", | ||||
|         description: file.data.description ?? "", | ||||
|         slug: file.data.slug!, | ||||
|         ext: ".html", | ||||
|       }) | ||||
|  | ||||
|       // TODO: process aliases | ||||
|  | ||||
|       fps.push(fp) | ||||
|     } | ||||
|     return fps | ||||
|   } | ||||
| } | ||||
							
								
								
									
										62
									
								
								quartz/plugins/emitters/contentPage.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								quartz/plugins/emitters/contentPage.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| import { toJsxRuntime } from "hast-util-to-jsx-runtime" | ||||
| import { resolveToRoot } from "../../path" | ||||
| import { StaticResources } from "../../resources" | ||||
| import { EmitCallback, QuartzEmitterPlugin } from "../types" | ||||
| import { ProcessedContent } from "../vfile" | ||||
| import { Fragment, jsx, jsxs } from 'preact/jsx-runtime' | ||||
| import { render } from "preact-render-to-string" | ||||
| import { ComponentType } from "preact" | ||||
| import { HeadProps } from "../../components/Head" | ||||
|  | ||||
| interface Options { | ||||
|   Head: ComponentType<HeadProps> | ||||
| } | ||||
|  | ||||
| export class ContentPage extends QuartzEmitterPlugin { | ||||
|   name = "ContentPage" | ||||
|   opts: Options | ||||
|  | ||||
|   constructor(opts: Options) { | ||||
|     super() | ||||
|     this.opts = opts | ||||
|   } | ||||
|  | ||||
|   async emit(content: ProcessedContent[], resources: StaticResources, emit: EmitCallback): Promise<string[]> { | ||||
|     const fps: string[] = [] | ||||
|     for (const [tree, file] of content) { | ||||
|  | ||||
|       // @ts-ignore (preact makes it angry) | ||||
|       const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: 'html' }) | ||||
|  | ||||
|       const { Head } = this.opts | ||||
|       const doc = <html> | ||||
|         <Head | ||||
|           title={file.data.frontmatter?.title ?? "Untitled"} | ||||
|           description={file.data.description ?? "No description provided"} | ||||
|           slug={file.data.slug!} | ||||
|           externalResources={resources} /> | ||||
|         <body> | ||||
|           <div id="quartz-root"> | ||||
|             <header> | ||||
|               <h1>{file.data.frontmatter?.title}</h1> | ||||
|             </header> | ||||
|             <article> | ||||
|               {content} | ||||
|             </article> | ||||
|           </div> | ||||
|         </body> | ||||
|         {resources.js.filter(resource => resource.loadTime === "afterDOMReady").map(resource => <script key={resource.src} src={resource.src} />)} | ||||
|       </html> | ||||
|  | ||||
|       const fp = file.data.slug + ".html" | ||||
|       await emit({ | ||||
|         content: "<!DOCTYPE html>\n" + render(doc), | ||||
|         slug: file.data.slug!, | ||||
|         ext: ".html", | ||||
|       }) | ||||
|  | ||||
|       fps.push(fp) | ||||
|     } | ||||
|     return fps | ||||
|   } | ||||
| } | ||||
| @@ -45,12 +45,11 @@ export class CreatedModifiedDate extends QuartzTransformerPlugin { | ||||
|               modified ||= file.data.frontmatter["last-modified"] | ||||
|               published ||= file.data.frontmatter.publishDate | ||||
|             } else if (source === "git") { | ||||
|               console.log(file) | ||||
|               if (!repo) { | ||||
|                 repo = new Repository(file.cwd) | ||||
|               } | ||||
|  | ||||
|               modified ||= new Date(await repo.getFileLatestModifiedDateAsync(fp)) | ||||
|               modified ||= new Date(await repo.getFileLatestModifiedDateAsync(file.data.filePath!)) | ||||
|             } | ||||
|           } | ||||
|  | ||||
|   | ||||
							
								
								
									
										85
									
								
								quartz/plugins/transformers/links.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								quartz/plugins/transformers/links.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| import { PluggableList } from "unified" | ||||
| import { QuartzTransformerPlugin } from "../types" | ||||
| import { remarkWikiLink } from "@flowershow/remark-wiki-link" | ||||
| import { relative, relativeToRoot, slugify } from "../../path" | ||||
| import path from "path" | ||||
| import { visit } from 'unist-util-visit' | ||||
| import isAbsoluteUrl from "is-absolute-url" | ||||
|  | ||||
| interface Options { | ||||
|   /** How to resolve Markdown paths */ | ||||
|   markdownLinkResolution: 'absolute' | 'relative' | ||||
|   /** Strips folders from a link so that it looks nice */ | ||||
|   prettyLinks: boolean | ||||
| } | ||||
|  | ||||
| const defaultOptions: Options = { | ||||
|   markdownLinkResolution: 'absolute', | ||||
|   prettyLinks: true | ||||
| } | ||||
|  | ||||
| export class LinkProcessing extends QuartzTransformerPlugin { | ||||
|   name = "LinkProcessing" | ||||
|   opts: Options | ||||
|  | ||||
|   constructor(opts?: Options) { | ||||
|     super() | ||||
|     this.opts = { ...defaultOptions, ...opts } | ||||
|   } | ||||
|  | ||||
|   markdownPlugins(): PluggableList { | ||||
|     return [[remarkWikiLink, { | ||||
|       pathFormat: this.opts.markdownLinkResolution === "absolute" ? 'obsidian-absolute' : 'raw' | ||||
|     }]] | ||||
|   } | ||||
|  | ||||
|   htmlPlugins(): PluggableList { | ||||
|     return [() => { | ||||
|       return (tree, file) => { | ||||
|         const curSlug = file.data.slug!  | ||||
|         const transformLink = (target: string) => { | ||||
|           const targetSlug = slugify(decodeURI(target)) | ||||
|           if (this.opts.markdownLinkResolution === 'relative' && !path.isAbsolute(targetSlug)) { | ||||
|             return './' + relative(curSlug, targetSlug) | ||||
|           } else { | ||||
|             return './' + relativeToRoot(curSlug, targetSlug) | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         // rewrite all links | ||||
|         visit(tree, 'element', (node, _index, _parent) => { | ||||
|           if ( | ||||
|             node.tagName === 'a' && | ||||
|             node.properties && | ||||
|             typeof node.properties.href === 'string' | ||||
|           ) { | ||||
|             node.properties.className = isAbsoluteUrl(node.properties.href) ? "external" : "internal" | ||||
|  | ||||
|             // don't process external links or intra-document anchors | ||||
|             if (!(isAbsoluteUrl(node.properties.href) || node.properties.href.startsWith("#"))) { | ||||
|               node.properties.href = transformLink(node.properties.href) | ||||
|             } | ||||
|  | ||||
|             if (this.opts.prettyLinks && node.children.length === 1 && node.children[0].type === 'text') { | ||||
|               node.children[0].value = path.basename(node.children[0].value) | ||||
|             } | ||||
|           } | ||||
|         }) | ||||
|  | ||||
|         // transform all images | ||||
|         visit(tree, 'element', (node, _index, _parent) => { | ||||
|           if ( | ||||
|             node.tagName === 'img' && | ||||
|             node.properties && | ||||
|             typeof node.properties.src === 'string' | ||||
|           ) { | ||||
|             if (!isAbsoluteUrl(node.properties.src)) { | ||||
|               const ext = path.extname(node.properties.src) | ||||
|               node.properties.src = transformLink("/assets/" + node.properties.src) + ext | ||||
|             } | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }] | ||||
|   } | ||||
| } | ||||
| @@ -15,20 +15,15 @@ export abstract class QuartzFilterPlugin { | ||||
| } | ||||
|  | ||||
| export interface EmitOptions { | ||||
|   // meta | ||||
|   title: string | ||||
|   description: string | ||||
|   slug: string | ||||
|   ext: `.${string}` | ||||
|    | ||||
|   // rendering related  | ||||
|   content: string | ||||
| } | ||||
|  | ||||
| export type EmitCallback = (data: EmitOptions) => Promise<void> | ||||
| export type EmitCallback = (data: EmitOptions) => Promise<string> | ||||
| export abstract class QuartzEmitterPlugin { | ||||
|   abstract name: string | ||||
|   abstract emit(content: ProcessedContent[], emitCallback: EmitCallback): Promise<string[]> | ||||
|   abstract emit(content: ProcessedContent[], resources: StaticResources, emitCallback: EmitCallback): Promise<string[]> | ||||
| } | ||||
|  | ||||
| export interface PluginTypes { | ||||
|   | ||||
| @@ -0,0 +1,61 @@ | ||||
| import path from "path" | ||||
| import fs from "fs" | ||||
| import { QuartzConfig } from "../cfg" | ||||
| import { PerfTimer } from "../perf" | ||||
| import { getStaticResourcesFromPlugins } from "../plugins" | ||||
| import { EmitCallback } from "../plugins/types" | ||||
| import { ProcessedContent } from "../plugins/vfile" | ||||
| import { QUARTZ, slugify } from "../path" | ||||
| import { globbyStream } from "globby" | ||||
|  | ||||
| export async function emitContent(output: string, cfg: QuartzConfig, content: ProcessedContent[], verbose: boolean) { | ||||
|   const perf = new PerfTimer() | ||||
|  | ||||
|  | ||||
|   const staticResources = getStaticResourcesFromPlugins(cfg.plugins) | ||||
|   const emit: EmitCallback = async ({ slug, ext, content }) => { | ||||
|     const pathToPage = path.join(output, slug + ext) | ||||
|     const dir = path.dirname(pathToPage) | ||||
|     await fs.promises.mkdir(dir, { recursive: true }) | ||||
|     await fs.promises.writeFile(pathToPage, content) | ||||
|     return pathToPage | ||||
|   } | ||||
|  | ||||
|   let emittedFiles = 0 | ||||
|   for (const emitter of cfg.plugins.emitters) { | ||||
|     const emitted = await emitter.emit(content, staticResources, emit) | ||||
|     emittedFiles += emitted.length | ||||
|  | ||||
|     if (verbose) { | ||||
|       for (const file of emitted) { | ||||
|         console.log(`[emit:${emitter.name}] ${file}`) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   const staticPath = path.join(QUARTZ, "static") | ||||
|   await fs.promises.cp(staticPath, path.join(output, "static"), { recursive: true }) | ||||
|  | ||||
|   // glob all non MD/MDX/HTML files in content folder and copy it over | ||||
|   const assetsPath = path.join("public", "assets") | ||||
|   for await (const fp of globbyStream("**", { | ||||
|     ignore: ["**/*.{md,mdx,html}"], | ||||
|     cwd: "./content", | ||||
|   })) { | ||||
|     const ext = path.extname(fp as string) | ||||
|     const src = path.join("content", fp as string) | ||||
|     const dest = path.join(assetsPath, slugify(fp as string) + ext) | ||||
|     const dir = path.dirname(dest) | ||||
|     await fs.promises.mkdir(dir, { recursive: true }) // ensure dir exists | ||||
|     await fs.promises.copyFile(src, dest) | ||||
|     emittedFiles += 1 | ||||
|     if (verbose) { | ||||
|       console.log(`[emit:Assets] ${dest}`) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (verbose) { | ||||
|     console.log(`[emit:Static] ${path.join(output, "static", "**")}`) | ||||
|     console.log(`Emitted ${emittedFiles} files to \`${output}\` in ${perf.timeSince()}`) | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,16 @@ | ||||
| import { PerfTimer } from "../perf" | ||||
| import { QuartzFilterPlugin } from "../plugins/types" | ||||
| import { ProcessedContent } from "../plugins/vfile" | ||||
|  | ||||
| export function filterContent(plugins: QuartzFilterPlugin[], content: ProcessedContent[], verbose: boolean): ProcessedContent[] { | ||||
|   const perf = new PerfTimer() | ||||
|   const initialLength = content.length | ||||
|   for (const plugin of plugins) { | ||||
|     content = content.filter(plugin.shouldPublish) | ||||
|   } | ||||
|  | ||||
|   if (verbose) { | ||||
|     console.log(`Filtered out ${initialLength - content.length} files in ${perf.timeSince()}`) | ||||
|   } | ||||
|   return content | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import { Root as HTMLRoot } from 'hast' | ||||
| import { ProcessedContent } from '../plugins/vfile' | ||||
| import { PerfTimer } from '../perf' | ||||
| import { read } from 'to-vfile' | ||||
| import { pathToSlug } from '../path' | ||||
| import { slugify } from '../path' | ||||
| import path from 'path' | ||||
| import { QuartzTransformerPlugin } from '../plugins/types' | ||||
|  | ||||
| @@ -39,7 +39,7 @@ export async function parseMarkdown(processor: QuartzProcessor, baseDir: string, | ||||
|     const file = await read(fp) | ||||
|  | ||||
|     // base data properties that plugins may use | ||||
|     file.data.slug = pathToSlug(path.relative(baseDir, file.path)) | ||||
|     file.data.slug = slugify(path.relative(baseDir, file.path)) | ||||
|     file.data.filePath = fp | ||||
|  | ||||
|     const ast = processor.parse(file) | ||||
|   | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user