mirror of
https://github.com/LukeHagar/unicorn-utterances.git
synced 2025-12-06 04:21:55 +00:00
move post content to h3, restructure around "Post contents" heading
This commit is contained in:
@@ -13,10 +13,6 @@ import sitemap from "@astrojs/sitemap";
|
||||
import { EnumChangefreq as ChangeFreq } from "sitemap";
|
||||
import { siteUrl } from "./src/constants/site-config";
|
||||
import vercel from "@astrojs/vercel/static";
|
||||
|
||||
// TODO: Create types
|
||||
import behead from "remark-behead";
|
||||
|
||||
import image from "@astrojs/image";
|
||||
import mdx from "@astrojs/mdx";
|
||||
import symlink from "symlink-dir";
|
||||
@@ -86,7 +82,6 @@ export default defineConfig({
|
||||
// Remove complaining about "div cannot be in p element"
|
||||
remarkUnwrapImages,
|
||||
/* start remark plugins here */
|
||||
[behead, { depth: 1 }],
|
||||
[
|
||||
remarkEmbedder,
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ Sin embargo, sabemos que este es un objetivo ambicioso, y no queremos hacerlo so
|
||||
|
||||
---
|
||||
|
||||
# Dónde encontrarnos
|
||||
## Dónde encontrarnos
|
||||
|
||||
Tenemos varias cuentas en redes sociales donde compartimos actualizaciones y nuevo contenido con amigos! También tenemos un canal de YouTube donde compartimos transmisiones en vivo, charlas grabadas, y mucho contenido educativo adicional sobre temas relacionados a las ciencias de la computación.
|
||||
|
||||
@@ -20,7 +20,7 @@ Como lo mencionamos antes, también tenemos un servidor de Discord donde podemos
|
||||
|
||||
---
|
||||
|
||||
# Sponsors \{#sponsors\}
|
||||
## Sponsors \{#sponsors\}
|
||||
|
||||
<Sponsors />
|
||||
|
||||
@@ -31,7 +31,7 @@ Como lo mencionamos antes, también tenemos un servidor de Discord donde podemos
|
||||
|
||||
---
|
||||
|
||||
# Declaración de Ética \{#ethics\}
|
||||
## Declaración de Ética \{#ethics\}
|
||||
|
||||
Nunca queremos terminar en un lugar en el que nuestro contenido educativo, la experiencia,
|
||||
o la comunidad se vean comprometidos ya sea por influencias financieras o miembros potencialmente
|
||||
|
||||
@@ -10,7 +10,7 @@ C'est certainement un objectif ambitieux, et il sera difficile de l'atteindre se
|
||||
|
||||
---
|
||||
|
||||
# Où Nous Trouver
|
||||
## Où Nous Trouver
|
||||
|
||||
Nous partageons notre contenu avec tout le monde sur les différents réseaux sociaux. Notre chaîne YouTube contient nos émissions vidéos, nos livestreams et beaucoup plus sur le domaine de l’informatique.
|
||||
|
||||
@@ -20,7 +20,7 @@ Et comme nous l’avons déjà cité, on a un serveur Discord ou on parle tech,
|
||||
|
||||
---
|
||||
|
||||
# Sponsors \{#sponsors\}
|
||||
## Sponsors \{#sponsors\}
|
||||
|
||||
<Sponsors />
|
||||
|
||||
@@ -31,7 +31,7 @@ Et comme nous l’avons déjà cité, on a un serveur Discord ou on parle tech,
|
||||
|
||||
---
|
||||
|
||||
# Code d’éthique \{#ethics\}
|
||||
## Code d’éthique \{#ethics\}
|
||||
|
||||
Nous ne voudrions jamais nous retrouver dans un endroit où le contenu ou la communauté sont compromis par des influences financières, ou bien des individus potentiellement nuisibles. Pour cela, nous avons adopté le
|
||||
[“Contributor Covenant”](https://www.contributor-covenant.org/)
|
||||
|
||||
@@ -10,7 +10,7 @@ We know this is a lofty goal, though, and we don't want to do it alone. If you'r
|
||||
|
||||
---
|
||||
|
||||
# Where to find us, you ask?
|
||||
## Where to find us, you ask?
|
||||
|
||||
We have various social media accounts where we share updates and new content with folks! We also have a YouTube channel where we host livestreams, recorded talks, and much more educational content on computer science related topics.
|
||||
|
||||
@@ -20,7 +20,7 @@ As mentioned previously, we also have a Discord where we chat tech, help out wit
|
||||
|
||||
---
|
||||
|
||||
# Sponsors \{#sponsors\}
|
||||
## Sponsors \{#sponsors\}
|
||||
|
||||
<Sponsors />
|
||||
|
||||
@@ -31,7 +31,7 @@ As mentioned previously, we also have a Discord where we chat tech, help out wit
|
||||
|
||||
---
|
||||
|
||||
# Statement of Ethics \{#ethics\}
|
||||
## Statement of Ethics \{#ethics\}
|
||||
|
||||
We never want to end up in a place where our educational content, experience, or community is compromised by either financial sway or potentially harmful members of the community. As such, we've implemented the [Contributor Covenant](https://www.contributor-covenant.org/) as our [code of conduct](https://github.com/unicorn-utterances/unicorn-utterances/blob/master/CODE_OF_CONDUCT.md) to uphold these values.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Mas sabemos que este é um objetivo arrojado, e não o queremos fazer sozinhos.
|
||||
|
||||
---
|
||||
|
||||
# Onde nos podes encontrar?
|
||||
## Onde nos podes encontrar?
|
||||
|
||||
Nós temos diversas redes sociais, onde partilhamos updates e novidades com os membros! Nós também temos um canal do YouTube, onde fazemos algumas livestreams, conversas à solta, e muito mais conteúdo educational ligados à Ciência dos Computadores
|
||||
|
||||
@@ -20,7 +20,7 @@ Como já foi mencionado antes, nós também temos um Discord onde falamos sobre
|
||||
|
||||
---
|
||||
|
||||
# Sponsors \{#sponsors\}
|
||||
## Sponsors \{#sponsors\}
|
||||
|
||||
<Sponsors />
|
||||
|
||||
@@ -31,7 +31,7 @@ Como já foi mencionado antes, nós também temos um Discord onde falamos sobre
|
||||
|
||||
---
|
||||
|
||||
# Princípios de Ética \{#ethics\}
|
||||
## Princípios de Ética \{#ethics\}
|
||||
|
||||
Não queremos acabar num lugar onde o nosso conteúdo educacional, a nossa experiência,
|
||||
ou comunidade está comprometida pelas oscilação das finanças ou potencialmente
|
||||
|
||||
168
package-lock.json
generated
168
package-lock.json
generated
@@ -80,7 +80,6 @@
|
||||
"probe-image-size": "^7.2.3",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"rehype-slug-custom-id": "^1.1.0",
|
||||
"remark-behead": "^3.1.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-shiki-twoslash": "^3.1.3",
|
||||
"remark-unwrap-images": "^3.0.1",
|
||||
@@ -92,6 +91,7 @@
|
||||
"tsx": "^3.12.7",
|
||||
"typescript": "^5.1.6",
|
||||
"unified": "^10.1.2",
|
||||
"unist-util-find": "^3.0.0",
|
||||
"unist-util-find-all-after": "^5.0.0",
|
||||
"unist-util-is": "^6.0.0",
|
||||
"unist-util-replace-all-between": "^0.1.1",
|
||||
@@ -25023,64 +25023,6 @@
|
||||
"@types/unist": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/remark-behead": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/remark-behead/-/remark-behead-3.1.0.tgz",
|
||||
"integrity": "sha512-rKns7st91lgppaD5YaH58O4ECFVXTVnkyYQBuCw4ISRE2TFK/iVySMaKbvV2pVbUVIjAaDciugrTI/tyuPOlWQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"unist-util-find": "^1.0.2",
|
||||
"unist-util-find-all-after": "^4.0.0",
|
||||
"unist-util-find-all-before": "^4.0.0",
|
||||
"unist-util-find-all-between": "^2.1.0",
|
||||
"unist-util-visit": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/remark-behead/node_modules/unist-util-find-all-after": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-4.0.1.tgz",
|
||||
"integrity": "sha512-AO8++e6HJfwNoTrqkV7xSeW65e6uSsLRQST/9LWi8FmFSz1gS7TBd+DkL/CYiElsSZIQgT4J5U54v5/kJX5Nqg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0",
|
||||
"unist-util-is": "^5.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/remark-behead/node_modules/unist-util-is": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
|
||||
"integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/remark-behead/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==",
|
||||
"dev": true,
|
||||
"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-frontmatter": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-4.0.1.tgz",
|
||||
@@ -28461,13 +28403,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-find/-/unist-util-find-1.0.4.tgz",
|
||||
"integrity": "sha512-T5vI7IkhroDj7KxAIy057VbIeGnCXfso4d4GoUsjbAmDLQUkzAeszlBtzx1+KHgdsYYBygaqUBvrbYCfePedZw==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-find/-/unist-util-find-3.0.0.tgz",
|
||||
"integrity": "sha512-T7ZqS7immLjYyC4FCp2hDo3ksZ1v+qcbb+e5+iWxc2jONgHOLXPCpms1L8VV4hVxCXgWTxmBHDztuEZFVwC+Gg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lodash.iteratee": "^4.7.0",
|
||||
"unist-util-visit": "^2.0.0"
|
||||
"@types/unist": "^3.0.0",
|
||||
"lodash.iteratee": "^4.0.0",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find-all-after": {
|
||||
@@ -28490,94 +28437,11 @@
|
||||
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/unist-util-find-all-before": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-find-all-before/-/unist-util-find-all-before-4.0.1.tgz",
|
||||
"integrity": "sha512-xg4UHtZ6VbcjQbfDtmLZch6kQYQFF3nfaW05Ie3+t2UectzeqSx/iqLmh/wWogwU+YDWnD40PjZKK7ORmCma+g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0",
|
||||
"unist-util-is": "^5.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find-all-before/node_modules/unist-util-is": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
|
||||
"integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find-all-between": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-find-all-between/-/unist-util-find-all-between-2.1.0.tgz",
|
||||
"integrity": "sha512-OCCUtDD8UHKeODw3TPXyFDxPCbpgBzbGTTaDpR68nvxkwiVcawBqMVrokfBMvUi7ij2F5q7S4s4Jq5dvkcBt+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"unist-util-find": "^1.0.1",
|
||||
"unist-util-is": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find-all-between/node_modules/unist-util-is": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
|
||||
"integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find/node_modules/unist-util-is": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
|
||||
"integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find/node_modules/unist-util-visit": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
|
||||
"integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0",
|
||||
"unist-util-is": "^4.0.0",
|
||||
"unist-util-visit-parents": "^3.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/unist-util-find/node_modules/unist-util-visit-parents": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz",
|
||||
"integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0",
|
||||
"unist-util-is": "^4.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
"node_modules/unist-util-find/node_modules/@types/unist": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
|
||||
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/unist-util-generated": {
|
||||
"version": "2.0.1",
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
"probe-image-size": "^7.2.3",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"rehype-slug-custom-id": "^1.1.0",
|
||||
"remark-behead": "^3.1.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-shiki-twoslash": "^3.1.3",
|
||||
"remark-unwrap-images": "^3.0.1",
|
||||
@@ -116,6 +115,7 @@
|
||||
"tsx": "^3.12.7",
|
||||
"typescript": "^5.1.6",
|
||||
"unified": "^10.1.2",
|
||||
"unist-util-find": "^3.0.0",
|
||||
"unist-util-find-all-after": "^5.0.0",
|
||||
"unist-util-is": "^6.0.0",
|
||||
"unist-util-replace-all-between": "^0.1.1",
|
||||
|
||||
@@ -5,7 +5,7 @@ import { visit } from "unist-util-visit";
|
||||
|
||||
import { EMBED_MIN_HEIGHT, EMBED_SIZE } from "../constants";
|
||||
import { fromHtml } from "hast-util-from-html";
|
||||
import find from "unist-util-find";
|
||||
import { find } from "unist-util-find";
|
||||
import { getLargestManifestIcon } from "../../get-largest-manifest-icon";
|
||||
import { getPicture } from "../get-picture-hack";
|
||||
import type { GetPictureResult } from "@astrojs/image/dist/lib/get-picture";
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from "./rehype-absolute-paths";
|
||||
import { rehypeFixTwoSlashXHTML } from "./rehype-fix-twoslash-xhtml";
|
||||
import { rehypeHeaderText } from "./rehype-header-text";
|
||||
import { rehypeHeaderClass } from "./rehype-header-class";
|
||||
import { rehypeFileTree } from "./file-tree/rehype-file-tree";
|
||||
import { rehypeTwoslashTabindex } from "./twoslash-tabindex/rehype-transform";
|
||||
|
||||
@@ -26,7 +27,16 @@ type RehypePlugin = Plugin<any[]> | [Plugin<any[]>, any];
|
||||
export function createRehypePlugins(config: MarkdownConfig): RehypePlugin[] {
|
||||
return [
|
||||
...(config.format === "html"
|
||||
? [rehypeUnicornPopulatePost, rehypeUnicornGetSuggestedPosts]
|
||||
? [
|
||||
rehypeUnicornPopulatePost,
|
||||
rehypeUnicornGetSuggestedPosts,
|
||||
[
|
||||
rehypeExcerpt,
|
||||
{
|
||||
maxLength: 150,
|
||||
},
|
||||
] as RehypePlugin,
|
||||
]
|
||||
: []),
|
||||
// This is required to handle unsafe HTML embedded into Markdown
|
||||
[rehypeRaw, { passThrough: [`mdxjsEsm`] }],
|
||||
@@ -48,6 +58,21 @@ export function createRehypePlugins(config: MarkdownConfig): RehypePlugin[] {
|
||||
enableCustomId: true,
|
||||
},
|
||||
],
|
||||
...(config.format === "html"
|
||||
? [
|
||||
rehypeHeaderText,
|
||||
[
|
||||
rehypeHeaderClass,
|
||||
{
|
||||
// the page starts at h3 (under {title} -> "Post content")
|
||||
depth: 2,
|
||||
// visually, headings should start at h2-h6
|
||||
className: (depth: number) =>
|
||||
`text-style-headline-${Math.min(depth + 1, 6)}`,
|
||||
},
|
||||
] as RehypePlugin,
|
||||
]
|
||||
: []),
|
||||
...(config.format === "html"
|
||||
? [
|
||||
/**
|
||||
@@ -60,18 +85,8 @@ export function createRehypePlugins(config: MarkdownConfig): RehypePlugin[] {
|
||||
rehypeUnicornIFrameClickToRun,
|
||||
rehypeUnicornElementMap,
|
||||
rehypeTwoslashTabindex,
|
||||
rehypeFileTree,
|
||||
]
|
||||
: []),
|
||||
...(config.format === "html"
|
||||
? [
|
||||
[
|
||||
rehypeExcerpt,
|
||||
{
|
||||
maxLength: 150,
|
||||
},
|
||||
] as RehypePlugin,
|
||||
]
|
||||
: []),
|
||||
...(config.format === "html" ? [rehypeFileTree, rehypeHeaderText] : []),
|
||||
];
|
||||
}
|
||||
|
||||
58
src/utils/markdown/rehype-header-class.ts
Normal file
58
src/utils/markdown/rehype-header-class.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { headingRank } from "hast-util-heading-rank";
|
||||
import { hasProperty } from "hast-util-has-property";
|
||||
import { toString } from "hast-util-to-string";
|
||||
import { Root, Parent } from "hast";
|
||||
import { visit } from "unist-util-visit";
|
||||
|
||||
interface RehypeHeaderClassOpts {
|
||||
depth: number;
|
||||
className: (depth: number) => string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin to act as "rehype-behead", but add a className to display headings
|
||||
* at the intended visual level.
|
||||
*/
|
||||
export const rehypeHeaderClass = (opts: RehypeHeaderClassOpts) => {
|
||||
return (tree: Root, file) => {
|
||||
// hacky (temporary) fix to exclude the site/about-us*.mdx files, since
|
||||
// those start at a different heading level
|
||||
if (file.data.astro.frontmatter.slug === "site") return;
|
||||
|
||||
// Find the minimum heading rank in the file
|
||||
// (e.g. if it starts at h2, minDepth = 2)
|
||||
let minDepth: number;
|
||||
visit(tree, "element", (node: Parent["children"][number]) => {
|
||||
const nodeHeadingRank = headingRank(node);
|
||||
if (!minDepth || nodeHeadingRank < minDepth) minDepth = nodeHeadingRank;
|
||||
});
|
||||
minDepth ||= 1;
|
||||
|
||||
visit(tree, "element", (node: Parent["children"][number]) => {
|
||||
const nodeHeadingRank = headingRank(node);
|
||||
|
||||
if (
|
||||
nodeHeadingRank &&
|
||||
"properties" in node &&
|
||||
node.properties &&
|
||||
!hasProperty(node, "class") &&
|
||||
!hasProperty(node, "className")
|
||||
) {
|
||||
// indent the heading rank by opts.depth - (1 - minDepth), so that:
|
||||
// - when (minDepth = 5, depth = 2) h5 + 2 - 4 -> h3
|
||||
// - when (minDepth = 1, depth = 2) h1 + 2 + 0 -> h3
|
||||
const tagHeadingRank = Math.min(
|
||||
nodeHeadingRank + opts.depth + (1 - minDepth),
|
||||
6,
|
||||
);
|
||||
const className = opts.className(nodeHeadingRank);
|
||||
|
||||
node.tagName = "h" + tagHeadingRank;
|
||||
node.properties.className = className;
|
||||
|
||||
const headerText = toString(node as never);
|
||||
node.properties["data-header-text"] = headerText;
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -35,7 +35,7 @@ export const rehypeHeaderText = () => {
|
||||
const headingWithID = {
|
||||
value: headerText,
|
||||
depth: headingRank(node)!,
|
||||
slug: node.properties["id"] as string,
|
||||
slug: node.properties["id"]! as string,
|
||||
};
|
||||
|
||||
headingsWithId.push(headingWithID);
|
||||
|
||||
@@ -63,9 +63,8 @@ import style from "./heading-link.module.scss";
|
||||
.querySelector(".post-body")
|
||||
.querySelectorAll<HTMLElement>("h1, h2, h3, h4, h5, h6")
|
||||
.forEach((headingEl) => {
|
||||
// ensure that each heading has an ID, and doesn't have a class attr.
|
||||
// (i.e. it is a markdown heading, not belonging to another component)
|
||||
if (!headingEl.matches("[id]:not([class])")) return;
|
||||
// ensure that each heading has an ID, and doesn't have a "data-no-heading-link" attr
|
||||
if (!headingEl.matches("[id]:not([data-no-heading-link])")) return;
|
||||
|
||||
// add the click listener
|
||||
headingEl.addEventListener("click", handleClick);
|
||||
|
||||
@@ -75,7 +75,14 @@ if (post.collection && post.order) {
|
||||
<BlogPostLayout>
|
||||
<PostTitleHeader slot="header" post={post} />
|
||||
<TableOfContents slot="left" headingsWithId={post.headingsWithId} />
|
||||
<div class="post-body" data-testid="post-body-div">
|
||||
<section
|
||||
class="post-body"
|
||||
data-testid="post-body-div"
|
||||
aria-labelledby="blog-post-contents"
|
||||
>
|
||||
<h2 id="blog-post-contents" class="visually-hidden" data-no-heading-link>
|
||||
Post contents
|
||||
</h2>
|
||||
{
|
||||
post.collection ? (
|
||||
<SeriesToC
|
||||
@@ -96,7 +103,7 @@ if (post.collection && post.order) {
|
||||
<ArticleNav post={post} postSeries={seriesPosts} />
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
<aside slot="right" aria-labelledby="related-posts-heading">
|
||||
<RelatedPosts post={post} headingId="related-posts-heading" />
|
||||
</aside>
|
||||
|
||||
@@ -19,8 +19,10 @@ const editedStr = post.edited && dayjs(post.edited).format("MMMM D, YYYY");
|
||||
const originalLinkStr = post.originalLink && new URL(post.originalLink).host;
|
||||
---
|
||||
|
||||
<section class={style.container}>
|
||||
<h1 class={`text-style-headline-1 ${style.title}`}>{title}</h1>
|
||||
<section class={style.container} aria-labelledby="post-title-header">
|
||||
<h1 id="post-title-header" class={`text-style-headline-1 ${style.title}`}>
|
||||
{title}
|
||||
</h1>
|
||||
|
||||
<div class={style.details}>
|
||||
<div class={style.date}>
|
||||
|
||||
Reference in New Issue
Block a user