From 52e6c037309a752741f79264afb3e83cd75feabc Mon Sep 17 00:00:00 2001 From: ikorihn <16367098+ikorihn@users.noreply.github.com> Date: Sun, 14 Jan 2024 02:08:21 +0900 Subject: [PATCH 01/98] fix: broken RSS item's link, which were set to `https:/${base}`. (#687) --- quartz/plugins/emitters/contentIndex.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/quartz/plugins/emitters/contentIndex.ts b/quartz/plugins/emitters/contentIndex.ts index bc4c6c325..47a84270a 100644 --- a/quartz/plugins/emitters/contentIndex.ts +++ b/quartz/plugins/emitters/contentIndex.ts @@ -48,12 +48,11 @@ function generateSiteMap(cfg: GlobalConfiguration, idx: ContentIndex): string { function generateRSSFeed(cfg: GlobalConfiguration, idx: ContentIndex, limit?: number): string { const base = cfg.baseUrl ?? "" - const root = `https://${base}` const createURLEntry = (slug: SimpleSlug, content: ContentDetails): string => ` ${escapeHTML(content.title)} - ${joinSegments(root, encodeURI(slug))} - ${joinSegments(root, encodeURI(slug))} + https://${joinSegments(base, encodeURI(slug))} + https://${joinSegments(base, encodeURI(slug))} ${content.richContent ?? content.description} ${content.date?.toUTCString()} ` @@ -78,7 +77,7 @@ function generateRSSFeed(cfg: GlobalConfiguration, idx: ContentIndex, limit?: nu ${escapeHTML(cfg.pageTitle)} - ${root} + https://${base} ${!!limit ? `Last ${limit} notes` : "Recent notes"} on ${escapeHTML( cfg.pageTitle, )} From 0a8c38dc21eeb9aba16154f09e523b2ce762dab2 Mon Sep 17 00:00:00 2001 From: ikorihn <16367098+ikorihn@users.noreply.github.com> Date: Sun, 14 Jan 2024 02:09:41 +0900 Subject: [PATCH 02/98] fix: small typos (#686) --- docs/authoring content.md | 2 +- docs/features/breadcrumbs.md | 2 +- docs/features/explorer.md | 2 +- docs/hosting.md | 2 +- quartz/cli/handlers.js | 4 ++-- quartz/components/Breadcrumbs.tsx | 6 +++--- quartz/components/scripts/search.inline.ts | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/authoring content.md b/docs/authoring content.md index fa6eea258..248214037 100644 --- a/docs/authoring content.md +++ b/docs/authoring content.md @@ -2,7 +2,7 @@ title: Authoring Content --- -All of the content in your Quartz should go in the `/content` folder. The content for the home page of your Quartz lives in `content/index.md`. If you've [[index#🪴 Get Started|setup Quartz]] already, this folder should already be initailized. Any Markdown in this folder will get processed by Quartz. +All of the content in your Quartz should go in the `/content` folder. The content for the home page of your Quartz lives in `content/index.md`. If you've [[index#🪴 Get Started|setup Quartz]] already, this folder should already be initialized. Any Markdown in this folder will get processed by Quartz. It is recommended that you use [Obsidian](https://obsidian.md/) as a way to edit and maintain your Quartz. It comes with a nice editor and graphical interface to preview, edit, and link your local files and attachments. diff --git a/docs/features/breadcrumbs.md b/docs/features/breadcrumbs.md index a241aac41..a70185836 100644 --- a/docs/features/breadcrumbs.md +++ b/docs/features/breadcrumbs.md @@ -20,7 +20,7 @@ Component.Breadcrumbs({ rootName: "Home", // name of first/root element resolveFrontmatterTitle: true, // whether to resolve folder names through frontmatter titles hideOnRoot: true, // whether to hide breadcrumbs on root `index.md` page - showCurrentPage: true, // wether to display the current page in the breadcrumbs + showCurrentPage: true, // whether to display the current page in the breadcrumbs }) ``` diff --git a/docs/features/explorer.md b/docs/features/explorer.md index f4d54faaf..b5fd379a7 100644 --- a/docs/features/explorer.md +++ b/docs/features/explorer.md @@ -26,7 +26,7 @@ Component.Explorer({ title: "Explorer", // title of the explorer component folderClickBehavior: "collapse", // what happens when you click a folder ("link" to navigate to folder page on click or "collapse" to collapse folder on click) folderDefaultState: "collapsed", // default state of folders ("collapsed" or "open") - useSavedState: true, // wether to use local storage to save "state" (which folders are opened) of explorer + useSavedState: true, // whether to use local storage to save "state" (which folders are opened) of explorer // Sort order: folders first, then files. Sort folders and files alphabetically sortFn: (a, b) => { ... // default implementation shown later diff --git a/docs/hosting.md b/docs/hosting.md index 9761e5b45..e6340d293 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -225,6 +225,6 @@ pages: - 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. +When `.gitlab-ci.yaml` is committed, 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`. diff --git a/quartz/cli/handlers.js b/quartz/cli/handlers.js index 37762a4fb..6f8aad1ab 100644 --- a/quartz/cli/handlers.js +++ b/quartz/cli/handlers.js @@ -450,7 +450,7 @@ export async function handleUpdate(argv) { try { gitPull(UPSTREAM_NAME, QUARTZ_SOURCE_BRANCH) } catch { - console.log(chalk.red("An error occured above while pulling updates.")) + console.log(chalk.red("An error occurred above while pulling updates.")) await popContentFolder(contentFolder) return } @@ -522,7 +522,7 @@ export async function handleSync(argv) { try { gitPull(ORIGIN_NAME, QUARTZ_SOURCE_BRANCH) } catch { - console.log(chalk.red("An error occured above while pulling updates.")) + console.log(chalk.red("An error occurred above while pulling updates.")) await popContentFolder(contentFolder) return } diff --git a/quartz/components/Breadcrumbs.tsx b/quartz/components/Breadcrumbs.tsx index 175f6f39d..0497b6458 100644 --- a/quartz/components/Breadcrumbs.tsx +++ b/quartz/components/Breadcrumbs.tsx @@ -18,15 +18,15 @@ interface BreadcrumbOptions { */ rootName: string /** - * wether to look up frontmatter title for folders (could cause performance problems with big vaults) + * Whether to look up frontmatter title for folders (could cause performance problems with big vaults) */ resolveFrontmatterTitle: boolean /** - * Wether to display breadcrumbs on root `index.md` + * Whether to display breadcrumbs on root `index.md` */ hideOnRoot: boolean /** - * Wether to display the current page in the breadcrumbs. + * Whether to display the current page in the breadcrumbs. */ showCurrentPage: boolean } diff --git a/quartz/components/scripts/search.inline.ts b/quartz/components/scripts/search.inline.ts index eff4eb1b9..2858e0fd1 100644 --- a/quartz/components/scripts/search.inline.ts +++ b/quartz/components/scripts/search.inline.ts @@ -35,12 +35,12 @@ function highlight(searchTerm: string, text: string, trim?: boolean) { if (trim) { const includesCheck = (tok: string) => tokenizedTerms.some((term) => tok.toLowerCase().startsWith(term.toLowerCase())) - const occurencesIndices = tokenizedText.map(includesCheck) + const occurrencesIndices = tokenizedText.map(includesCheck) let bestSum = 0 let bestIndex = 0 for (let i = 0; i < Math.max(tokenizedText.length - contextWindowWords, 0); i++) { - const window = occurencesIndices.slice(i, i + contextWindowWords) + const window = occurrencesIndices.slice(i, i + contextWindowWords) const windowSum = window.reduce((total, cur) => total + (cur ? 1 : 0), 0) if (windowSum >= bestSum) { bestSum = windowSum @@ -196,7 +196,7 @@ document.addEventListener("nav", async (e: unknown) => { const termLower = term.toLowerCase() let matching = tags.filter((str) => str.includes(termLower)) - // Substract matching from original tags, then push difference + // Subtract matching from original tags, then push difference if (matching.length > 0) { let difference = tags.filter((x) => !matching.includes(x)) From 6babb788edbdeaf532d406d6daa4d046e5223c7b Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 13 Jan 2024 09:22:27 -0800 Subject: [PATCH 03/98] fix: sluggify pound (closes #681) --- quartz/util/path.test.ts | 2 ++ quartz/util/path.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/quartz/util/path.test.ts b/quartz/util/path.test.ts index 18edc9407..16e0311db 100644 --- a/quartz/util/path.test.ts +++ b/quartz/util/path.test.ts @@ -105,6 +105,8 @@ describe("transforms", () => { ["index.md", "index"], ["test.mp4", "test.mp4"], ["note with spaces.md", "note-with-spaces"], + ["test/special chars?.md", "test/special-chars-q"], + ["test/special chars #3.md", "test/special-chars-3"], ], path.slugifyFilePath, path.isFilePath, diff --git a/quartz/util/path.ts b/quartz/util/path.ts index 6cedffdb6..95acf119d 100644 --- a/quartz/util/path.ts +++ b/quartz/util/path.ts @@ -50,7 +50,9 @@ export function getFullSlug(window: Window): FullSlug { function sluggify(s: string): string { return s .split("/") - .map((segment) => segment.replace(/\s/g, "-").replace(/%/g, "-percent").replace(/\?/g, "-q")) // slugify all segments + .map((segment) => + segment.replace(/\s/g, "-").replace(/%/g, "-percent").replace(/\?/g, "-q").replace(/#/g, ""), + ) // slugify all segments .join("/") // always use / as sep .replace(/\/$/, "") } From 4014c4d6d60f64d64798ce860423513536bb0d98 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 13 Jan 2024 09:27:00 -0800 Subject: [PATCH 04/98] fix: add another test for notes with dots --- quartz/util/path.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/util/path.test.ts b/quartz/util/path.test.ts index 16e0311db..6a8aa3d1d 100644 --- a/quartz/util/path.test.ts +++ b/quartz/util/path.test.ts @@ -105,6 +105,7 @@ describe("transforms", () => { ["index.md", "index"], ["test.mp4", "test.mp4"], ["note with spaces.md", "note-with-spaces"], + ["notes.with.dots.md", "notes.with.dots"], ["test/special chars?.md", "test/special-chars-q"], ["test/special chars #3.md", "test/special-chars-3"], ], From 783b9b219c90fcf929513171867c1054b3ccb1f4 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 13 Jan 2024 09:29:43 -0800 Subject: [PATCH 05/98] fix: dont hijack handlers when search is not focused (closes #680) --- quartz/components/scripts/search.inline.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/components/scripts/search.inline.ts b/quartz/components/scripts/search.inline.ts index 2858e0fd1..de3de2be3 100644 --- a/quartz/components/scripts/search.inline.ts +++ b/quartz/components/scripts/search.inline.ts @@ -110,6 +110,7 @@ document.addEventListener("nav", async (e: unknown) => { } function shortcutHandler(e: HTMLElementEventMap["keydown"]) { + if (!container?.classList.contains("active")) return if (e.key === "k" && (e.ctrlKey || e.metaKey) && !e.shiftKey) { e.preventDefault() const searchBarOpen = container?.classList.contains("active") From 4e82b0d8ce805ca832e08bafcfe5144e352c2d05 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 13 Jan 2024 09:37:24 -0800 Subject: [PATCH 06/98] docs: add sidneys artist handbook to showcase --- docs/showcase.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/showcase.md b/docs/showcase.md index ca5737b78..16235e46a 100644 --- a/docs/showcase.md +++ b/docs/showcase.md @@ -23,5 +23,6 @@ Want to see what Quartz can do? Here are some cool community gardens: - [Caicai's Novels](https://imoko.cc/blog/caicai/) - [🌊 Collapsed Wave](https://collapsedwave.com/) - [Aaron Pham's Garden](https://aarnphm.xyz/) +- [Sideny's 3D Artist's Handbook](https://sidney-eliot.github.io/3d-artists-handbook/) 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)! From e70312320f77e8ee362fd12c5dc5597cfb3cb1ae Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 13 Jan 2024 09:47:56 -0800 Subject: [PATCH 07/98] feat: improve default layout --- quartz.layout.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quartz.layout.ts b/quartz.layout.ts index 4e8a85ff4..b5a1639eb 100644 --- a/quartz.layout.ts +++ b/quartz.layout.ts @@ -37,12 +37,13 @@ export const defaultContentPageLayout: PageLayout = { // components for pages that display lists of pages (e.g. tags or folders) export const defaultListPageLayout: PageLayout = { - beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle()], + beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta()], left: [ Component.PageTitle(), Component.MobileOnly(Component.Spacer()), Component.Search(), Component.Darkmode(), + Component.DesktopOnly(Component.Explorer()), ], right: [], } From a40dbd55a43bfdb24a959bf5be64460438f220d5 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 13 Jan 2024 13:56:03 -0800 Subject: [PATCH 08/98] fix: unbork search shortcut --- quartz/components/scripts/search.inline.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/quartz/components/scripts/search.inline.ts b/quartz/components/scripts/search.inline.ts index de3de2be3..11e1c0da8 100644 --- a/quartz/components/scripts/search.inline.ts +++ b/quartz/components/scripts/search.inline.ts @@ -110,7 +110,6 @@ document.addEventListener("nav", async (e: unknown) => { } function shortcutHandler(e: HTMLElementEventMap["keydown"]) { - if (!container?.classList.contains("active")) return if (e.key === "k" && (e.ctrlKey || e.metaKey) && !e.shiftKey) { e.preventDefault() const searchBarOpen = container?.classList.contains("active") @@ -123,7 +122,10 @@ document.addEventListener("nav", async (e: unknown) => { // add "#" prefix for tag search if (searchBar) searchBar.value = "#" - } else if (e.key === "Enter") { + } + + if (!container?.classList.contains("active")) return + else if (e.key === "Enter") { // If result has focus, navigate to that one, otherwise pick first result if (results?.contains(document.activeElement)) { const active = document.activeElement as HTMLInputElement From f36376503a20f8b0697d72cf1e41dcf402020891 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sat, 13 Jan 2024 14:47:39 -0800 Subject: [PATCH 09/98] fix: allow transcludes of notes with dots (closes #682) --- quartz/plugins/transformers/ofm.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index be3344aa4..35257cc06 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -150,7 +150,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin src = src.toString() } - src = src.replaceAll(calloutLineRegex, (value) => { + src = src.replace(calloutLineRegex, (value) => { // force newline after title of callout return value + "\n> " }) @@ -162,7 +162,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin src = src.toString() } - src = src.replaceAll(wikilinkRegex, (value, ...capture) => { + src = src.replace(wikilinkRegex, (value, ...capture) => { const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture const fp = rawFp ?? "" @@ -236,7 +236,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin type: "html", value: ``, } - } else if (ext === "") { + } else { const block = anchor return { type: "html", @@ -330,7 +330,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin if (typeof replace === "string") { node.value = node.value.replace(regex, replace) } else { - node.value = node.value.replaceAll(regex, (substring: string, ...args) => { + node.value = node.value.replace(regex, (substring: string, ...args) => { const replaceValue = replace(substring, ...args) if (typeof replaceValue === "string") { return replaceValue From 8eec47c340d48d9b45970a88da0aaff4e216a7e2 Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:39:16 +0000 Subject: [PATCH 10/98] fix: rebuild errors on windows (#692) --- quartz/build.ts | 6 +++--- quartz/cli/handlers.js | 4 ++-- quartz/cli/helpers.js | 9 +++++++++ quartz/util/fs.ts | 13 +++++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 quartz/util/fs.ts diff --git a/quartz/build.ts b/quartz/build.ts index 24f049882..6bb3b50ad 100644 --- a/quartz/build.ts +++ b/quartz/build.ts @@ -2,7 +2,6 @@ import sourceMapSupport from "source-map-support" sourceMapSupport.install(options) import path from "path" import { PerfTimer } from "./util/perf" -import { rimraf } from "rimraf" import { isGitIgnored } from "globby" import chalk from "chalk" import { parseMarkdown } from "./processors/parse" @@ -13,6 +12,7 @@ import { FilePath, joinSegments, slugifyFilePath } from "./util/path" import chokidar from "chokidar" import { ProcessedContent } from "./plugins/vfile" import { Argv, BuildCtx } from "./util/ctx" +import { rmrf } from "./util/fs" import { glob, toPosixPath } from "./util/glob" import { trace } from "./util/trace" import { options } from "./util/sourcemap" @@ -40,7 +40,7 @@ async function buildQuartz(argv: Argv, mut: Mutex, clientRefresh: () => void) { const release = await mut.acquire() perf.addEvent("clean") - await rimraf(output) + await rmrf(output) console.log(`Cleaned output directory \`${output}\` in ${perf.timeSince("clean")}`) perf.addEvent("glob") @@ -145,7 +145,7 @@ async function startServing( // TODO: we can probably traverse the link graph to figure out what's safe to delete here // instead of just deleting everything - await rimraf(argv.output) + await rmrf(argv.output) await emitContent(ctx, filteredContent) console.log(chalk.green(`Done rebuilding in ${perf.timeSince()}`)) } catch (err) { diff --git a/quartz/cli/handlers.js b/quartz/cli/handlers.js index 6f8aad1ab..8460dad39 100644 --- a/quartz/cli/handlers.js +++ b/quartz/cli/handlers.js @@ -5,7 +5,6 @@ import chalk from "chalk" import { sassPlugin } from "esbuild-sass-plugin" import fs from "fs" import { intro, outro, select, text } from "@clack/prompts" -import { rimraf } from "rimraf" import chokidar from "chokidar" import prettyBytes from "pretty-bytes" import { execSync, spawnSync } from "child_process" @@ -21,6 +20,7 @@ import { gitPull, popContentFolder, stashContentFolder, + rmrf, } from "./helpers.js" import { UPSTREAM_NAME, @@ -109,7 +109,7 @@ export async function handleCreate(argv) { if (contentStat.isSymbolicLink()) { await fs.promises.unlink(contentFolder) } else { - await rimraf(contentFolder) + await rmrf(contentFolder) } } diff --git a/quartz/cli/helpers.js b/quartz/cli/helpers.js index 702a1b71d..1bb9b23d7 100644 --- a/quartz/cli/helpers.js +++ b/quartz/cli/helpers.js @@ -3,6 +3,7 @@ import chalk from "chalk" import { contentCacheFolder } from "./constants.js" import { spawnSync } from "child_process" import fs from "fs" +import { rimraf } from "rimraf" export function escapePath(fp) { return fp @@ -52,3 +53,11 @@ export async function popContentFolder(contentFolder) { }) await fs.promises.rm(contentCacheFolder, { force: true, recursive: true }) } + +export async function rmrf(path) { + if (os.platform() == "win32") { + return rimraf.windows(path) + } else { + return rimraf(path) + } +} diff --git a/quartz/util/fs.ts b/quartz/util/fs.ts new file mode 100644 index 000000000..ef15fc055 --- /dev/null +++ b/quartz/util/fs.ts @@ -0,0 +1,13 @@ +import os from "os" +import { rimraf, RimrafAsyncOptions } from "rimraf" + +export async function rmrf( + path: string | string[], + opt?: RimrafAsyncOptions | undefined, +): Promise { + if (os.platform() == "win32") { + return rimraf.windows(path, opt) + } else { + return rimraf(path, opt) + } +} From 30640e3441f9273dfdb9f8cf6ea0a29f0bec04a0 Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Mon, 15 Jan 2024 19:51:46 +0000 Subject: [PATCH 11/98] Revert "fix: rebuild errors on windows (#692)" (#695) This reverts commit 8eec47c340d48d9b45970a88da0aaff4e216a7e2. --- quartz/build.ts | 6 +++--- quartz/cli/handlers.js | 4 ++-- quartz/cli/helpers.js | 9 --------- quartz/util/fs.ts | 13 ------------- 4 files changed, 5 insertions(+), 27 deletions(-) delete mode 100644 quartz/util/fs.ts diff --git a/quartz/build.ts b/quartz/build.ts index 6bb3b50ad..24f049882 100644 --- a/quartz/build.ts +++ b/quartz/build.ts @@ -2,6 +2,7 @@ import sourceMapSupport from "source-map-support" sourceMapSupport.install(options) import path from "path" import { PerfTimer } from "./util/perf" +import { rimraf } from "rimraf" import { isGitIgnored } from "globby" import chalk from "chalk" import { parseMarkdown } from "./processors/parse" @@ -12,7 +13,6 @@ import { FilePath, joinSegments, slugifyFilePath } from "./util/path" import chokidar from "chokidar" import { ProcessedContent } from "./plugins/vfile" import { Argv, BuildCtx } from "./util/ctx" -import { rmrf } from "./util/fs" import { glob, toPosixPath } from "./util/glob" import { trace } from "./util/trace" import { options } from "./util/sourcemap" @@ -40,7 +40,7 @@ async function buildQuartz(argv: Argv, mut: Mutex, clientRefresh: () => void) { const release = await mut.acquire() perf.addEvent("clean") - await rmrf(output) + await rimraf(output) console.log(`Cleaned output directory \`${output}\` in ${perf.timeSince("clean")}`) perf.addEvent("glob") @@ -145,7 +145,7 @@ async function startServing( // TODO: we can probably traverse the link graph to figure out what's safe to delete here // instead of just deleting everything - await rmrf(argv.output) + await rimraf(argv.output) await emitContent(ctx, filteredContent) console.log(chalk.green(`Done rebuilding in ${perf.timeSince()}`)) } catch (err) { diff --git a/quartz/cli/handlers.js b/quartz/cli/handlers.js index 8460dad39..6f8aad1ab 100644 --- a/quartz/cli/handlers.js +++ b/quartz/cli/handlers.js @@ -5,6 +5,7 @@ import chalk from "chalk" import { sassPlugin } from "esbuild-sass-plugin" import fs from "fs" import { intro, outro, select, text } from "@clack/prompts" +import { rimraf } from "rimraf" import chokidar from "chokidar" import prettyBytes from "pretty-bytes" import { execSync, spawnSync } from "child_process" @@ -20,7 +21,6 @@ import { gitPull, popContentFolder, stashContentFolder, - rmrf, } from "./helpers.js" import { UPSTREAM_NAME, @@ -109,7 +109,7 @@ export async function handleCreate(argv) { if (contentStat.isSymbolicLink()) { await fs.promises.unlink(contentFolder) } else { - await rmrf(contentFolder) + await rimraf(contentFolder) } } diff --git a/quartz/cli/helpers.js b/quartz/cli/helpers.js index 1bb9b23d7..702a1b71d 100644 --- a/quartz/cli/helpers.js +++ b/quartz/cli/helpers.js @@ -3,7 +3,6 @@ import chalk from "chalk" import { contentCacheFolder } from "./constants.js" import { spawnSync } from "child_process" import fs from "fs" -import { rimraf } from "rimraf" export function escapePath(fp) { return fp @@ -53,11 +52,3 @@ export async function popContentFolder(contentFolder) { }) await fs.promises.rm(contentCacheFolder, { force: true, recursive: true }) } - -export async function rmrf(path) { - if (os.platform() == "win32") { - return rimraf.windows(path) - } else { - return rimraf(path) - } -} diff --git a/quartz/util/fs.ts b/quartz/util/fs.ts deleted file mode 100644 index ef15fc055..000000000 --- a/quartz/util/fs.ts +++ /dev/null @@ -1,13 +0,0 @@ -import os from "os" -import { rimraf, RimrafAsyncOptions } from "rimraf" - -export async function rmrf( - path: string | string[], - opt?: RimrafAsyncOptions | undefined, -): Promise { - if (os.platform() == "win32") { - return rimraf.windows(path, opt) - } else { - return rimraf(path, opt) - } -} From f31cabbbf9b0d438710618a3edd2a4eaaae09d7d Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Mon, 15 Jan 2024 12:37:50 -0800 Subject: [PATCH 12/98] fix: dont use default callout title if theres additional title children left (closes #693) --- quartz/plugins/transformers/ofm.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 35257cc06..6688059dd 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -366,7 +366,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin } const text = firstChild.children[0].value - const restChildren = firstChild.children.slice(1) + const restOfTitle = firstChild.children.slice(1) const [firstLine, ...remainingLines] = text.split("\n") const remainingText = remainingLines.join("\n") @@ -382,7 +382,10 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin match.input.slice(calloutDirective.length).trim() || capitalize(calloutType) const titleNode: Paragraph = { type: "paragraph", - children: [{ type: "text", value: titleContent + " " }, ...restChildren], + children: + restOfTitle.length === 0 + ? [{ type: "text", value: titleContent + " " }] + : restOfTitle, } const title = mdastToHtml(titleNode) From fa7d139ce5a0216ca3f6e63c78f818e9c028a3ab Mon Sep 17 00:00:00 2001 From: sean <146651411+tuta-amb@users.noreply.github.com> Date: Tue, 16 Jan 2024 02:55:32 -0500 Subject: [PATCH 13/98] feat: External link icons (#697) --- quartz/plugins/transformers/links.ts | 26 +++++++++++++++++++++++++- quartz/styles/base.scss | 11 +++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/links.ts b/quartz/plugins/transformers/links.ts index 50d2d1a0a..1ba0c8e58 100644 --- a/quartz/plugins/transformers/links.ts +++ b/quartz/plugins/transformers/links.ts @@ -21,6 +21,7 @@ interface Options { prettyLinks: boolean openLinksInNewTab: boolean lazyLoad: boolean + externalLinkIcon: boolean } const defaultOptions: Options = { @@ -28,6 +29,7 @@ const defaultOptions: Options = { prettyLinks: true, openLinksInNewTab: false, lazyLoad: false, + externalLinkIcon: true, } export const CrawlLinks: QuartzTransformerPlugin | undefined> = (userOpts) => { @@ -55,7 +57,29 @@ export const CrawlLinks: QuartzTransformerPlugin | undefined> = ) { let dest = node.properties.href as RelativeURL const classes = (node.properties.className ?? []) as string[] - classes.push(isAbsoluteUrl(dest) ? "external" : "internal") + const isExternal = isAbsoluteUrl(dest) + classes.push(isExternal ? "external" : "internal") + + if (isExternal && opts.externalLinkIcon) { + node.children.push({ + type: "element", + tagName: "svg", + properties: { + class: "external-icon", + viewBox: "0 0 512 512", + }, + children: [ + { + type: "element", + tagName: "path", + properties: { + d: "M320 0H288V64h32 82.7L201.4 265.4 178.7 288 224 333.3l22.6-22.6L448 109.3V192v32h64V192 32 0H480 320zM32 32H0V64 480v32H32 456h32V480 352 320H424v32 96H64V96h96 32V32H160 32z", + }, + children: [], + }, + ], + }) + } // Check if the link has alias text if ( diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index 607749aa1..16a96122e 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -59,6 +59,7 @@ a { text-decoration: none; transition: color 0.2s ease; color: var(--secondary); + display: inline-block; &:hover { color: var(--tertiary) !important; @@ -76,6 +77,16 @@ a { padding: 0; } } + + &.external .external-icon { + vertical-align: bottom; + height: 1ex; + margin: 0 0.15em; + + > path { + fill: var(--dark); + } + } } .desktop-only { From 107d9b8dff59de34a2ebef4b7be942b12f435e3a Mon Sep 17 00:00:00 2001 From: sean <146651411+tuta-amb@users.noreply.github.com> Date: Tue, 16 Jan 2024 11:18:55 -0500 Subject: [PATCH 14/98] fix: external link icon shouldn't be vertical aligned (#699) --- quartz/styles/base.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/quartz/styles/base.scss b/quartz/styles/base.scss index 16a96122e..68ee11136 100644 --- a/quartz/styles/base.scss +++ b/quartz/styles/base.scss @@ -79,7 +79,6 @@ a { } &.external .external-icon { - vertical-align: bottom; height: 1ex; margin: 0 0.15em; From e17ff202449635af29ef0056886e472a2615708b Mon Sep 17 00:00:00 2001 From: kabirgh <15871468+kabirgh@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:24:01 +0000 Subject: [PATCH 15/98] fix: use joinSegments for `contentIndex.json` file path (#702) --- quartz/plugins/emitters/contentIndex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/plugins/emitters/contentIndex.ts b/quartz/plugins/emitters/contentIndex.ts index 47a84270a..fa8c2c9d4 100644 --- a/quartz/plugins/emitters/contentIndex.ts +++ b/quartz/plugins/emitters/contentIndex.ts @@ -133,7 +133,7 @@ export const ContentIndex: QuartzEmitterPlugin> = (opts) => { ) } - const fp = path.join("static", "contentIndex") as FullSlug + const fp = joinSegments("static", "contentIndex") as FullSlug const simplifiedIndex = Object.fromEntries( Array.from(linkIndex).map(([slug, content]) => { // remove description and from content index as nothing downstream From f6299da1823b51917792905ca71257e55f706ed6 Mon Sep 17 00:00:00 2001 From: Matthew Bailin Date: Thu, 18 Jan 2024 00:32:02 +0700 Subject: [PATCH 16/98] feat: add ofm option to transform `` tags with video exts into `