This commit is contained in:
semanticdata 2024-02-23 10:46:43 -06:00
commit a3b270e55b
21 changed files with 83 additions and 54 deletions

View File

@ -42,7 +42,7 @@ When passing in your own options, you can omit any or all of these fields if you
Want to customize it even more?
- Removing table of contents: remove `Component.Explorer()` from `quartz.layout.ts`
- Removing explorer: remove `Component.Explorer()` from `quartz.layout.ts`
- (optional): After removing the explorer component, you can move the [[table of contents | Table of Contents]] component back to the `left` part of the layout
- Changing `sort`, `filter` and `map` behavior: explained in [[#Advanced customization]]
- Component:

View File

@ -25,5 +25,6 @@ Want to see what Quartz can do? Here are some cool community gardens:
- [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/)
- [Data Dictionary 🧠](https://glossary.airbyte.com/)
- [sspaeti.com's Second Brain](https://brain.sspaeti.com/)
- [🪴Aster's notebook](https://notes.asterhu.com)
If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/v4/docs/showcase.md)!

34
package-lock.json generated
View File

@ -40,7 +40,7 @@
"rehype-autolink-headings": "^7.1.0",
"rehype-katex": "^7.0.0",
"rehype-mathjax": "^6.0.0",
"rehype-pretty-code": "^0.12.6",
"rehype-pretty-code": "^0.13.0",
"rehype-raw": "^7.0.0",
"rehype-slug": "^6.0.0",
"remark": "^15.0.1",
@ -54,7 +54,7 @@
"rfdc": "^1.3.1",
"rimraf": "^5.0.5",
"serve-handler": "^6.1.5",
"shikiji": "^0.10.2",
"shiki": "^1.1.6",
"source-map-support": "^0.5.21",
"to-vfile": "^8.0.0",
"toml": "^3.0.0",
@ -742,6 +742,11 @@
"node": ">=14"
}
},
"node_modules/@shikijs/core": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.6.tgz",
"integrity": "sha512-kt9hhvrWTm0EPtRDIsoAZnSsFlIDBVBBI5CQewpA/NZCPin+MOKRXg+JiWc4y+8fZ/v0HzfDhu/UC+OTZGMt7A=="
},
"node_modules/@sindresorhus/merge-streams": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
@ -4708,11 +4713,11 @@
}
},
"node_modules/rehype-pretty-code": {
"version": "0.12.6",
"resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.12.6.tgz",
"integrity": "sha512-AW18s4eXwnb4PGwL0Y8BoUzBJr23epWNXndCKaZ52S4kl/4tsgM+406oCp5NdtPZsB0ItpaY+hCMv3kw58DLrA==",
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/rehype-pretty-code/-/rehype-pretty-code-0.13.0.tgz",
"integrity": "sha512-+22dz1StXlF7dlMyOySNaVxgcGhMI4BCxq0JxJJPWYGiKsI6cu5jyuIKGHXHvH18D8sv1rdKtvsY9UEfN3++SQ==",
"dependencies": {
"@types/hast": "^3.0.3",
"@types/hast": "^3.0.4",
"hast-util-to-string": "^3.0.0",
"parse-numeric-range": "^1.3.0",
"rehype-parse": "^9.0.0",
@ -4723,7 +4728,7 @@
"node": ">=18"
},
"peerDependencies": {
"shikiji": "^0.7.0 || ^0.8.0 || ^0.9.0 || ^0.10.0"
"shiki": "^1.0.0"
}
},
"node_modules/rehype-raw": {
@ -5321,19 +5326,14 @@
"node": ">=8"
}
},
"node_modules/shikiji": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/shikiji/-/shikiji-0.10.2.tgz",
"integrity": "sha512-wtZg3T0vtYV2PnqusWQs3mDaJBdCPWxFDrBM/SE5LfrX92gjUvfEMlc+vJnoKY6Z/S44OWaCRzNIsdBRWcTAiw==",
"node_modules/shiki": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.6.tgz",
"integrity": "sha512-j4pcpvaQWHb42cHeV+W6P+X/VcK7Y2ctvEham6zB8wsuRQroT6cEMIkiUmBU2Nqg2qnHZDH6ZyRdVldcy0l6xw==",
"dependencies": {
"shikiji-core": "0.10.2"
"@shikijs/core": "1.1.6"
}
},
"node_modules/shikiji-core": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/shikiji-core/-/shikiji-core-0.10.2.tgz",
"integrity": "sha512-9Of8HMlF96usXJHmCL3Gd0Fcf0EcyJUF9m8EoAKKd98mHXi0La2AZl1h6PegSFGtiYcBDK/fLuKbDa1l16r1fA=="
},
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",

View File

@ -70,7 +70,7 @@
"rehype-autolink-headings": "^7.1.0",
"rehype-katex": "^7.0.0",
"rehype-mathjax": "^6.0.0",
"rehype-pretty-code": "^0.12.6",
"rehype-pretty-code": "^0.13.0",
"rehype-raw": "^7.0.0",
"rehype-slug": "^6.0.0",
"remark": "^15.0.1",
@ -84,7 +84,7 @@
"rfdc": "^1.3.1",
"rimraf": "^5.0.5",
"serve-handler": "^6.1.5",
"shikiji": "^0.10.2",
"shiki": "^1.1.6",
"source-map-support": "^0.5.21",
"to-vfile": "^8.0.0",
"toml": "^3.0.0",

View File

@ -66,9 +66,12 @@ function TagContent(props: QuartzComponentProps) {
<p>
{i18n(cfg.locale).pages.tagContent.itemsUnderTag({ count: pages.length })}
{pages.length > numPages && (
<span>
{i18n(cfg.locale).pages.tagContent.showingFirst({ count: numPages })}
</span>
<>
{" "}
<span>
{i18n(cfg.locale).pages.tagContent.showingFirst({ count: numPages })}
</span>
</>
)}
</p>
<PageList limit={numPages} {...listProps} />

View File

@ -47,8 +47,8 @@ async function mouseEnterHandler(
}
if (!response) return
const contentType = response.headers.get("Content-Type")
const contentTypeCategory = contentType?.split("/")[0] ?? "text"
const [contentType] = response.headers.get("Content-Type")!.split(";")
const [contentTypeCategory, typeInfo] = contentType.split("/")
const popoverElement = document.createElement("div")
popoverElement.classList.add("popover")
@ -56,19 +56,27 @@ async function mouseEnterHandler(
popoverInner.classList.add("popover-inner")
popoverElement.appendChild(popoverInner)
popoverInner.dataset.contentType = contentTypeCategory
popoverInner.dataset.contentType = contentType ?? undefined
switch (contentTypeCategory) {
case "image":
const img = document.createElement("img")
response.blob().then((blob) => {
img.src = URL.createObjectURL(blob)
})
img.src = targetUrl.toString()
img.alt = targetUrl.pathname
popoverInner.appendChild(img)
break
case "application":
switch (typeInfo) {
case "pdf":
const pdf = document.createElement("iframe")
pdf.src = targetUrl.toString()
popoverInner.appendChild(pdf)
break
default:
break
}
break
default:
const contents = await response.text()
const html = p.parseFromString(contents, "text/html")

View File

@ -38,14 +38,25 @@
white-space: normal;
}
& > .popover-inner[data-content-type="image"] {
padding: 0;
max-height: 100%;
& > .popover-inner[data-content-type] {
&[data-content-type*="pdf"],
&[data-content-type*="image"] {
padding: 0;
max-height: 100%;
}
img {
margin: 0;
border-radius: 0;
display: block;
&[data-content-type*="image"] {
img {
margin: 0;
border-radius: 0;
display: block;
}
}
&[data-content-type*="pdf"] {
iframe {
width: 100%;
}
}
}

View File

@ -3,8 +3,10 @@ import { StaticResources } from "../util/resources"
import { QuartzPluginData } from "../plugins/vfile"
import { GlobalConfiguration } from "../cfg"
import { Node } from "hast"
import { BuildCtx } from "../util/ctx"
export type QuartzComponentProps = {
ctx: BuildCtx
externalResources: StaticResources
fileData: QuartzPluginData
cfg: GlobalConfiguration

View File

@ -69,13 +69,13 @@ export default {
folderContent: {
folder: "Ordner",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 Datei in diesem Ordner" : `${count} Dateien in diesem Ordner.`,
count === 1 ? "1 Datei in diesem Ordner." : `${count} Dateien in diesem Ordner.`,
},
tagContent: {
tag: "Tag",
tagIndex: "Tag-Übersicht",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 Datei mit diesem Tag" : `${count} Dateien mit diesem Tag.`,
count === 1 ? "1 Datei mit diesem Tag." : `${count} Dateien mit diesem Tag.`,
showingFirst: ({ count }) => `Die ersten ${count} Tags werden angezeigt.`,
totalTags: ({ count }) => `${count} Tags insgesamt.`,
},

View File

@ -69,13 +69,13 @@ export default {
folderContent: {
folder: "Folder",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 item under this folder" : `${count} items under this folder.`,
count === 1 ? "1 item under this folder." : `${count} items under this folder.`,
},
tagContent: {
tag: "Tag",
tagIndex: "Tag Index",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 item with this tag" : `${count} items with this tag.`,
count === 1 ? "1 item with this tag." : `${count} items with this tag.`,
showingFirst: ({ count }) => `Showing first ${count} tags.`,
totalTags: ({ count }) => `Found ${count} total tags.`,
},

View File

@ -69,13 +69,13 @@ export default {
folderContent: {
folder: "Carpeta",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 artículo en esta carpeta" : `${count} artículos en esta carpeta.`,
count === 1 ? "1 artículo en esta carpeta." : `${count} artículos en esta carpeta.`,
},
tagContent: {
tag: "Etiqueta",
tagIndex: "Índice de Etiquetas",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 artículo con esta etiqueta" : `${count} artículos con esta etiqueta.`,
count === 1 ? "1 artículo con esta etiqueta." : `${count} artículos con esta etiqueta.`,
showingFirst: ({ count }) => `Mostrando las primeras ${count} etiquetas.`,
totalTags: ({ count }) => `Se encontraron ${count} etiquetas en total.`,
},

View File

@ -69,13 +69,13 @@ export default {
folderContent: {
folder: "Dossier",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 élément sous ce dossier" : `${count} éléments sous ce dossier.`,
count === 1 ? "1 élément sous ce dossier." : `${count} éléments sous ce dossier.`,
},
tagContent: {
tag: "Étiquette",
tagIndex: "Index des étiquettes",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 élément avec cette étiquette" : `${count} éléments avec cette étiquette.`,
count === 1 ? "1 élément avec cette étiquette." : `${count} éléments avec cette étiquette.`,
showingFirst: ({ count }) => `Affichage des premières ${count} étiquettes.`,
totalTags: ({ count }) => `Trouvé ${count} étiquettes au total.`,
},

View File

@ -69,13 +69,13 @@ export default {
folderContent: {
folder: "Cartella",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 oggetto in questa cartella" : `${count} oggetti in questa cartella.`,
count === 1 ? "1 oggetto in questa cartella." : `${count} oggetti in questa cartella.`,
},
tagContent: {
tag: "Etichetta",
tagIndex: "Indice etichette",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 oggetto con questa etichetta" : `${count} oggetti con questa etichetta.`,
count === 1 ? "1 oggetto con questa etichetta." : `${count} oggetti con questa etichetta.`,
showingFirst: ({ count }) => `Prime ${count} etichette.`,
totalTags: ({ count }) => `Trovate ${count} etichette totali.`,
},

View File

@ -68,12 +68,12 @@ export default {
},
folderContent: {
folder: "폴더",
itemsUnderFolder: ({ count }) => `${count}건의 페이지`,
itemsUnderFolder: ({ count }) => `${count}건의 항목`,
},
tagContent: {
tag: "태그",
tagIndex: "태그 목록",
itemsUnderTag: ({ count }) => `${count}건의 페이지`,
itemsUnderTag: ({ count }) => `${count}건의 항목`,
showingFirst: ({ count }) => `처음 ${count}개의 태그`,
totalTags: ({ count }) => `${count}개의 태그를 찾았습니다.`,
},

View File

@ -70,7 +70,7 @@ export default {
folderContent: {
folder: "Map",
itemsUnderFolder: ({ count }) =>
count === 1 ? "1 item in deze map" : `${count} items in deze map.`,
count === 1 ? "1 item in deze map." : `${count} items in deze map.`,
},
tagContent: {
tag: "Label",

View File

@ -69,13 +69,13 @@ export default {
folderContent: {
folder: "Папка",
itemsUnderFolder: ({ count }) =>
count === 1 ? "У цій папці 1 елемент" : `Елементів у цій папці: ${count}.`,
count === 1 ? "У цій папці 1 елемент." : `Елементів у цій папці: ${count}.`,
},
tagContent: {
tag: "Тег",
tagIndex: "Індекс тегу",
itemsUnderTag: ({ count }) =>
count === 1 ? "1 елемент з цим тегом" : `Елементів з цим тегом: ${count}.`,
count === 1 ? "1 елемент з цим тегом." : `Елементів з цим тегом: ${count}.`,
showingFirst: ({ count }) => `Показ перших ${count} тегів.`,
totalTags: ({ count }) => `Всього знайдено тегів: ${count}.`,
},

View File

@ -46,6 +46,7 @@ export const NotFoundPage: QuartzEmitterPlugin = () => {
frontmatter: { title: notFound, tags: [] },
})
const componentData: QuartzComponentProps = {
ctx,
fileData: vfile.data,
externalResources,
cfg,

View File

@ -97,6 +97,7 @@ export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOp
const externalResources = pageResources(pathToRoot(slug), resources)
const componentData: QuartzComponentProps = {
ctx,
fileData: file.data,
externalResources,
cfg,

View File

@ -95,6 +95,7 @@ export const FolderPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOpt
const externalResources = pageResources(pathToRoot(slug), resources)
const [tree, file] = folderDescriptions[folder]
const componentData: QuartzComponentProps = {
ctx,
fileData: file.data,
externalResources,
cfg,

View File

@ -99,6 +99,7 @@ export const TagPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOpts)
const externalResources = pageResources(pathToRoot(slug), resources)
const [tree, file] = tagDescriptions[tag]
const componentData: QuartzComponentProps = {
ctx,
fileData: file.data,
externalResources,
cfg,

View File

@ -6,7 +6,7 @@ import Slugger from "github-slugger"
export interface Options {
maxDepth: 1 | 2 | 3 | 4 | 5 | 6
minEntries: 1
minEntries: number
showByDefault: boolean
collapseByDefault: boolean
}
@ -52,7 +52,7 @@ export const TableOfContents: QuartzTransformerPlugin<Partial<Options> | undefin
}
})
if (toc.length > opts.minEntries) {
if (toc.length > 0 && toc.length > opts.minEntries) {
file.data.toc = toc.map((entry) => ({
...entry,
depth: entry.depth - highestDepth,