From b98e4be66548e452419a1e4138d9d6d1981f891e Mon Sep 17 00:00:00 2001 From: Mara-Li Date: Fri, 15 Mar 2024 23:28:31 +0100 Subject: [PATCH 1/9] feat(i18n): Add French translation for reading time (#998) Signed-off-by: Mara-Li --- quartz/i18n/locales/fr-FR.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/i18n/locales/fr-FR.ts b/quartz/i18n/locales/fr-FR.ts index 88ad5a27e..e1dfa48b7 100644 --- a/quartz/i18n/locales/fr-FR.ts +++ b/quartz/i18n/locales/fr-FR.ts @@ -54,7 +54,7 @@ export default { title: "Table des Matières", }, contentMeta: { - readingTime: ({ minutes }) => `${minutes} min read`, + readingTime: ({ minutes }) => `${minutes} min de lecture`, }, }, pages: { From 47024022e834e1bb6c70f671cb32597f42aabd94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:29:14 -0400 Subject: [PATCH 2/9] chore(deps-dev): bump @types/node from 20.11.24 to 20.11.25 (#990) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.24 to 20.11.25. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c042b2d6..92d41dd90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.24", + "@types/node": "^20.11.25", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.10", @@ -1170,9 +1170,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", - "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" diff --git a/package.json b/package.json index 2395c7dc2..145804871 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "@types/d3": "^7.4.3", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.24", + "@types/node": "^20.11.25", "@types/pretty-time": "^1.1.5", "@types/source-map-support": "^0.5.10", "@types/ws": "^8.5.10", From 7164857f6e32aeba3da80112d604244aa8f557f4 Mon Sep 17 00:00:00 2001 From: Aaron Pham <29749331+aarnphm@users.noreply.github.com> Date: Fri, 15 Mar 2024 21:17:42 -0400 Subject: [PATCH 3/9] chore(ofm): remove unused (#999) Signed-off-by: Aaron <29749331+aarnphm@users.noreply.github.com> --- quartz/plugins/transformers/ofm.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 40919607b..3b76f2533 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -194,9 +194,8 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin return src }, - markdownPlugins(ctx) { + markdownPlugins(_ctx) { const plugins: PluggableList = [] - const cfg = ctx.cfg.configuration // regex replacements plugins.push(() => { From 4691369abf0ccb763112cda10f8208c68814c046 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Sat, 16 Mar 2024 14:23:08 +0100 Subject: [PATCH 4/9] fix(wikilinks): only escape alias in wikilinks inside tables (#1000) --- quartz/plugins/transformers/ofm.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 3b76f2533..50371c87a 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -99,13 +99,15 @@ export const externalLinkRegex = /^https?:\/\//i export const arrowRegex = new RegExp(/(-{1,2}>|={1,2}>|<-{1,2}|<={1,2})/, "g") +// (\|[^\|\[\n]*)? -> optional check if wikilink is inside a table cell // !? -> optional embedding // \[\[ -> open brace // ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) // (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) -// (\|[^\[\]\#]+)? -> \| then one or more non-special characters (alias) +// (\|[^\[\]\#]+)? -> \| then one or more non-special characters (alias) +// ([^\|\n]*\|)? -> optional check if wikilink is inside a table cell export const wikilinkRegex = new RegExp( - /!?\[\[([^\[\]\|\#\\]+)?(#+[^\[\]\|\#\\]+)?(\\?\|[^\[\]\#]+)?\]\]/, + /(\|[^\|\[\n]*)?!?\[\[([^\[\]\|\#\\]+)?(#+[^\[\]\|\#\\]+)?(\\?\|[^\[\]\#]+)?\]\]([^\|\n]*\|)?/, "g", ) const highlightRegex = new RegExp(/==([^=]+)==/, "g") @@ -170,7 +172,8 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin } src = src.replace(wikilinkRegex, (value, ...capture) => { - const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture + const [rawTablePre, rawFp, rawHeader, rawAlias, rawTablePost]: (string | undefined)[] = + capture const fp = rawFp ?? "" const anchor = rawHeader?.trim().replace(/^#+/, "") @@ -183,8 +186,9 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin return `${embedDisplay}[${displayAlias.replace(/^\|/, "")}](${rawFp})` } - //transform `[[note#^block_ref|^block_ref]]` to `[[note#^block_ref\|^block_ref]]`, display correctly in table. - if (displayAlias && displayAlias.startsWith("|")) { + // transform `[[note#^block_ref|^block_ref]]` to `[[note#^block_ref\|^block_ref]]`, + // when the wikilink with alias is inside a table. + if (displayAlias && displayAlias.startsWith("|") && rawTablePre && rawTablePost) { displayAlias = `\\${displayAlias}` } @@ -207,7 +211,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin replacements.push([ wikilinkRegex, (value: string, ...capture: string[]) => { - let [rawFp, rawHeader, rawAlias] = capture + let [_rawTablePre, rawFp, rawHeader, rawAlias, _rawTablePost] = capture const fp = rawFp?.trim() ?? "" const anchor = rawHeader?.trim() ?? "" const alias = rawAlias?.slice(1).trim() From 253497cad45b086aae3cc1c99e483146440ae8c2 Mon Sep 17 00:00:00 2001 From: Denis Bezykornov Date: Sat, 16 Mar 2024 20:16:58 +0300 Subject: [PATCH 5/9] docs: add config for Caddy server (#1002) --- docs/hosting.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/hosting.md b/docs/hosting.md index eeb930849..e5ef9a615 100644 --- a/docs/hosting.md +++ b/docs/hosting.md @@ -250,3 +250,21 @@ server { } } ``` + +### Using Caddy + +Here's and example of how to do this with Caddy: + +```caddy title="Caddyfile" +example.com { + root * /path/to/quartz/public + try_files {path} {path}.html {path}/ =404 + file_server + encode gzip + + handle_errors { + rewrite * /{err.status_code}.html + file_server + } +} +``` From 38d9d5213784ba3250326c66567be5a91d93c415 Mon Sep 17 00:00:00 2001 From: makondratev <69584771+makondratev@users.noreply.github.com> Date: Mon, 18 Mar 2024 03:48:00 +0300 Subject: [PATCH 6/9] feat(search): add search by title/content index and tag at the same time (#978) * feat(search): add search by title/content index and tag at the same time * fix(search): set search type to basic and remove tag from term for proper highlightning and scroll when searched by tag and title/content index * fix(search): use indexOf to find space so it is easier to read * fix(search): trim trailing whitespaces before splitting * fix(search): set limit to 10000 for combined search mode (to make filter by tag more accurate) --- quartz/components/scripts/search.inline.ts | 33 ++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/quartz/components/scripts/search.inline.ts b/quartz/components/scripts/search.inline.ts index a75f4ff46..72be6b8dd 100644 --- a/quartz/components/scripts/search.inline.ts +++ b/quartz/components/scripts/search.inline.ts @@ -21,6 +21,7 @@ let index = new FlexSearch.Document({ encode: encoder, document: { id: "id", + tag: "tags", index: [ { field: "title", @@ -405,11 +406,33 @@ document.addEventListener("nav", async (e: CustomEventMap["nav"]) => { let searchResults: FlexSearch.SimpleDocumentSearchResultSetUnit[] if (searchType === "tags") { - searchResults = await index.searchAsync({ - query: currentSearchTerm.substring(1), - limit: numSearchResults, - index: ["tags"], - }) + currentSearchTerm = currentSearchTerm.substring(1).trim() + const separatorIndex = currentSearchTerm.indexOf(" ") + if (separatorIndex != -1) { + // search by title and content index and then filter by tag (implemented in flexsearch) + const tag = currentSearchTerm.substring(0, separatorIndex) + const query = currentSearchTerm.substring(separatorIndex + 1).trim() + searchResults = await index.searchAsync({ + query: query, + // return at least 10000 documents, so it is enough to filter them by tag (implemented in flexsearch) + limit: Math.max(numSearchResults, 10000), + index: ["title", "content"], + tag: tag, + }) + for (let searchResult of searchResults) { + searchResult.result = searchResult.result.slice(0, numSearchResults) + } + // set search type to basic and remove tag from term for proper highlightning and scroll + searchType = "basic" + currentSearchTerm = query + } else { + // default search by tags index + searchResults = await index.searchAsync({ + query: currentSearchTerm, + limit: numSearchResults, + index: ["tags"], + }) + } } else if (searchType === "basic") { searchResults = await index.searchAsync({ query: currentSearchTerm, From 91f0a2abb2d186801244a0b63b64604ac7505031 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sun, 17 Mar 2024 18:00:04 -0700 Subject: [PATCH 7/9] feat: support rich descriptions in tag listing page (closes #908) --- quartz/components/pages/TagContent.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/quartz/components/pages/TagContent.tsx b/quartz/components/pages/TagContent.tsx index 692585c2b..94061631e 100644 --- a/quartz/components/pages/TagContent.tsx +++ b/quartz/components/pages/TagContent.tsx @@ -52,8 +52,14 @@ const TagContent: QuartzComponent = (props: QuartzComponentProps) => { allFiles: pages, } - const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`)[0] - const content = contentPage?.description + const contentPage = allFiles.filter((file) => file.slug === `tags/${tag}`).at(0) + + const root = contentPage?.htmlAst + const content = + !root || root?.children.length === 0 + ? contentPage?.description + : htmlToJsx(contentPage.filePath!, root) + return (

From daa8796554dea41d6fbf81f4eccea58153a4e850 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Sun, 17 Mar 2024 18:15:42 -0700 Subject: [PATCH 8/9] fix: format --- quartz/components/pages/TagContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/components/pages/TagContent.tsx b/quartz/components/pages/TagContent.tsx index 94061631e..9e04359c1 100644 --- a/quartz/components/pages/TagContent.tsx +++ b/quartz/components/pages/TagContent.tsx @@ -56,7 +56,7 @@ const TagContent: QuartzComponent = (props: QuartzComponentProps) => { const root = contentPage?.htmlAst const content = - !root || root?.children.length === 0 + !root || root?.children.length === 0 ? contentPage?.description : htmlToJsx(contentPage.filePath!, root) From 7e22c38f8eaf8d9e3ae3a5b25f4611a5f4503b26 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Mon, 18 Mar 2024 02:16:04 +0100 Subject: [PATCH 9/9] fix(wikilinks): handle wikilinks inside tables seperately from other wikilinks (#1005) * fix(wikilinks): handle wikilinks inside tables seperately from other wikilinks * Prettier * Cleaned up duplicate code * Remove test logging * Refactored and fixed for non-aliased wikilinks inside table * Updated naming and comments * Updated comment of wikilink regex * Updated regex to match previous formatting * Match table even if EOF is immediately after the table. * Update quartz/plugins/transformers/ofm.ts Co-authored-by: Jacky Zhao * Change table escape replace to non-regex version * Prettier * Prettier --------- Co-authored-by: Jacky Zhao --- quartz/plugins/transformers/ofm.ts | 53 ++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 50371c87a..3ee6480ca 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -99,17 +99,27 @@ export const externalLinkRegex = /^https?:\/\//i export const arrowRegex = new RegExp(/(-{1,2}>|={1,2}>|<-{1,2}|<={1,2})/, "g") -// (\|[^\|\[\n]*)? -> optional check if wikilink is inside a table cell -// !? -> optional embedding -// \[\[ -> open brace -// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) -// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) -// (\|[^\[\]\#]+)? -> \| then one or more non-special characters (alias) -// ([^\|\n]*\|)? -> optional check if wikilink is inside a table cell +// !? -> optional embedding +// \[\[ -> open brace +// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) +// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) +// (\\?\|[^\[\]\#]+)? -> optional escape \ then | then one or more non-special characters (alias) export const wikilinkRegex = new RegExp( - /(\|[^\|\[\n]*)?!?\[\[([^\[\]\|\#\\]+)?(#+[^\[\]\|\#\\]+)?(\\?\|[^\[\]\#]+)?\]\]([^\|\n]*\|)?/, + /!?\[\[([^\[\]\|\#\\]+)?(#+[^\[\]\|\#\\]+)?(\\?\|[^\[\]\#]+)?\]\]/, "g", ) + +// ^\|([^\n])+\|\n(\|) -> matches the header row +// ( ?:?-{3,}:? ?\|)+ -> matches the header row separator +// (\|([^\n])+\|\n)+ -> matches the body rows +export const tableRegex = new RegExp( + /^\|([^\n])+\|\n(\|)( ?:?-{3,}:? ?\|)+\n(\|([^\n])+\|\n?)+/, + "gm", +) + +// matches any wikilink, only used for escaping wikilinks inside tables +export const tableWikilinkRegex = new RegExp(/(!?\[\[[^\]]*?\]\])/, "g") + const highlightRegex = new RegExp(/==([^=]+)==/, "g") const commentRegex = new RegExp(/%%[\s\S]*?%%/, "g") // from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts @@ -171,27 +181,34 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin src = src.toString() } + // replace all wikilinks inside a table first + src = src.replace(tableRegex, (value) => { + // escape all aliases and headers in wikilinks inside a table + return value.replace(tableWikilinkRegex, (value, ...capture) => { + const [raw]: (string | undefined)[] = capture + let escaped = raw ?? "" + escaped = escaped.replace("#", "\\#") + escaped = escaped.replace("|", "\\|") + + return escaped + }) + }) + + // replace all other wikilinks src = src.replace(wikilinkRegex, (value, ...capture) => { - const [rawTablePre, rawFp, rawHeader, rawAlias, rawTablePost]: (string | undefined)[] = - capture + const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture const fp = rawFp ?? "" const anchor = rawHeader?.trim().replace(/^#+/, "") const blockRef = Boolean(anchor?.startsWith("^")) ? "^" : "" const displayAnchor = anchor ? `#${blockRef}${slugAnchor(anchor)}` : "" - let displayAlias = rawAlias ?? rawHeader?.replace("#", "|") ?? "" + const displayAlias = rawAlias ?? rawHeader?.replace("#", "|") ?? "" const embedDisplay = value.startsWith("!") ? "!" : "" if (rawFp?.match(externalLinkRegex)) { return `${embedDisplay}[${displayAlias.replace(/^\|/, "")}](${rawFp})` } - // transform `[[note#^block_ref|^block_ref]]` to `[[note#^block_ref\|^block_ref]]`, - // when the wikilink with alias is inside a table. - if (displayAlias && displayAlias.startsWith("|") && rawTablePre && rawTablePost) { - displayAlias = `\\${displayAlias}` - } - return `${embedDisplay}[[${fp}${displayAnchor}${displayAlias}]]` }) } @@ -211,7 +228,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin replacements.push([ wikilinkRegex, (value: string, ...capture: string[]) => { - let [_rawTablePre, rawFp, rawHeader, rawAlias, _rawTablePost] = capture + let [rawFp, rawHeader, rawAlias] = capture const fp = rawFp?.trim() ?? "" const anchor = rawHeader?.trim() ?? "" const alias = rawAlias?.slice(1).trim()