diff --git a/astro.config.ts b/astro.config.ts index 31974d7..b7193cf 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -24,7 +24,7 @@ export default defineConfig({ site: 'https://astro-erudite.vercel.app', integrations: [ expressiveCode({ - themes: ['min-light', 'min-dark'], + themes: ['github-light', 'github-dark'], plugins: [pluginCollapsibleSections(), pluginLineNumbers()], useDarkModeMediaQuery: false, themeCssSelector: (theme) => `.${theme.name.split('-')[1]}`, @@ -44,6 +44,7 @@ export default defineConfig({ codeBackground: 'color-mix(in oklab, var(--secondary) 25%, transparent)', frames: { + editorActiveTabForeground: 'var(--muted-foreground)', editorActiveTabBackground: 'color-mix(in oklab, var(--secondary) 25%, transparent)', editorActiveTabIndicatorBottomColor: 'transparent', @@ -95,8 +96,8 @@ export default defineConfig({ rehypePrettyCode, { theme: { - light: 'min-light', - dark: 'min-dark', + light: 'github-light', + dark: 'github-dark', }, }, ], diff --git a/src/components/BlogCard.astro b/src/components/BlogCard.astro index eb1ac7d..cc7101f 100644 --- a/src/components/BlogCard.astro +++ b/src/components/BlogCard.astro @@ -4,9 +4,9 @@ import { Badge } from '@/components/ui/badge' import { Separator } from '@/components/ui/separator' import { parseAuthors } from '@/lib/server-utils' import { formatDate, readingTime } from '@/lib/utils' +import { Icon } from 'astro-icon/components' import { Image } from 'astro:assets' import type { CollectionEntry } from 'astro:content' -import { Icon } from 'astro-icon/components' import Link from './Link.astro' type Props = { diff --git a/src/components/PostNavigation.astro b/src/components/PostNavigation.astro index 8bfafea..a735ca9 100644 --- a/src/components/PostNavigation.astro +++ b/src/components/PostNavigation.astro @@ -7,7 +7,7 @@ import { Icon } from 'astro-icon/components' const { prevPost, nextPost } = Astro.props --- -
+
{project.data.tags.map((tag: string) => ( - - {tag} - + {tag} ))}
) diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx index 7513c87..ad0d40c 100644 --- a/src/components/ui/pagination.tsx +++ b/src/components/ui/pagination.tsx @@ -140,7 +140,7 @@ const PaginationComponent: React.FC = ({ - 1 ? getPageUrl(currentPage - 1) : undefined} isDisabled={currentPage === 1} /> @@ -148,7 +148,7 @@ const PaginationComponent: React.FC = ({ {pages.map((page) => ( - @@ -165,7 +165,9 @@ const PaginationComponent: React.FC = ({ @@ -182,7 +184,6 @@ interface PaginationProps { export default PaginationComponent - export { Pagination, PaginationContent, diff --git a/src/content/blog/2022-post/2022.png b/src/content/blog/2022-post/2022.png deleted file mode 100644 index 3872e8d..0000000 Binary files a/src/content/blog/2022-post/2022.png and /dev/null differ diff --git a/src/content/blog/2022-post/index.mdx b/src/content/blog/2022-post/index.mdx deleted file mode 100644 index b9e364a..0000000 --- a/src/content/blog/2022-post/index.mdx +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: '2022 Post' -description: 'This a dummy post written in the year 2022.' -date: 2022-06-01 -tags: ['dummy', 'placeholder'] -image: './2022.png' ---- - -This is a dummy post written in the year 2022. diff --git a/src/content/blog/2023-post/index.mdx b/src/content/blog/2023-post/index.mdx index cc33ffc..62907dd 100644 --- a/src/content/blog/2023-post/index.mdx +++ b/src/content/blog/2023-post/index.mdx @@ -2,7 +2,7 @@ title: '2023 Post' description: 'This a dummy post written in the year 2023.' date: 2023-06-01 -tags: ['dummy', 'placeholder'] +tags: ['v1.0.0'] image: './2023.png' authors: ['enscribe'] --- diff --git a/src/content/blog/2024-post/index.mdx b/src/content/blog/2024-post/index.mdx index bf21d0c..34615c6 100644 --- a/src/content/blog/2024-post/index.mdx +++ b/src/content/blog/2024-post/index.mdx @@ -2,7 +2,7 @@ title: '2024 Post' description: 'This a dummy post written in the year 2024 (with multiple authors).' date: 2024-06-01 -tags: ['dummy', 'placeholder'] +tags: ['v1.0.0'] image: './2024.png' authors: ['enscribe', 'jktrn'] --- diff --git a/src/content/blog/rehype-patch/1200x630.png b/src/content/blog/rehype-patch/1200x630.png new file mode 100644 index 0000000..933b94b Binary files /dev/null and b/src/content/blog/rehype-patch/1200x630.png differ diff --git a/src/content/blog/rehype-patch/index.mdx b/src/content/blog/rehype-patch/index.mdx new file mode 100644 index 0000000..908d9be --- /dev/null +++ b/src/content/blog/rehype-patch/index.mdx @@ -0,0 +1,89 @@ +--- +title: 'v1.3.0: “Patches in Production”' +description: 'Whenever you depend on Node packages with missing maintainers, patching becomes a necessary evil.' +date: 2025-03-21 +tags: ['v1.3.0'] +image: './1200x630.png' +authors: ['enscribe'] +--- + +## A problem (about dead maintainers) + +This post talks about changes I've made to astro-erudite in v1.3.0! + +I recently found myself caught between two syntax highlighting packages that I absolutely needed for astro-erudite. On one hand, the current template uses [rehype-pretty-code](https://rehype-pretty.pages.dev/) as its main syntax highlighting solution, but due to issues with its inherent implementation and missing features that I needed, I had created a bunch of custom transformers to make it do what I wanted, and the whole setup was getting unwieldy. I then discovered [Expressive Code](https://expressive-code.com/), which had everything I wanted out of the box—collapsible code sections, terminal and editor frames, gutter comments—it was perfect! Well, almost perfect. + +The primary issue was that Expressive Code doesn't support inline syntax highlighting, which is non-negotiable for me since I need my inline code snippets to look as good as my code blocks (so I could do stuff like `console.log("Hello, world!".split('').reverse().join('')){:js}`). So I opened a feature request at [expressive-code/expressive-code#250](https://github.com/expressive-code/expressive-code/issues/250) and the maintainer seemed interested, saying they'd get around to it eventually. Implementing this feature is a lot easier said than done though, and I summarized it well in another thread: + +> [@jktrn](https://github.com/rehype-pretty/rehype-pretty-code/issues/247#issuecomment-2619869436): [...] expressive-code is already interested in implementing inline code support, but it would be a bit nuanced to add since it has to: +> +> - allow existing plugins to continue working normally with block-level code (without breaking changes), +> - enable new plugins to explicitly declare support for inline code, +> - and provide ways for plugins to distinguish between inline and block-level code processing. + +However, I needed a solution immediately. My first thought was to use both packages together—Expressive Code for block code and rehype-pretty-code for inline code. However, importing both at the same time caused everything to break spectacularly. + +## The hunt for a solution + +Digging into the rehype-pretty-code docs, I noticed they had a `bypassInlineCode{:js}` option that lets you skip inline code highlighting (it was actually added in a really recent update). But what I needed was the opposite, which would be a way to make it only handle inline code and bypass blocks entirely. + +So I opened a feature request at [rehype-pretty/rehype-pretty-code#247](https://github.com/rehype-pretty/rehype-pretty-code/issues/247) for a theoretical `bypassBlockCode{:js}` option. I got no response, since the repository seemed unmaintained for a bit since it seems like the maintainer has moved onto other projects. + +Fast forward a few months, and user [@kelvindecosta](https://github.com/kelvindecosta) comments on my issue: + +> [[@kelvindecosta]](https://github.com/rehype-pretty/rehype-pretty-code/issues/247#issuecomment-2610536000): Hey [@jktrn](https://github.com/jktrn), did you figure out a workaround for this? I'm interested in setting this up alongside expressive-code. + +After I replied that I hadn't figured out a workaround yet, they sent me a brilliantly hacky solution a couple days later: + +> [[@kelvindecosta]](https://github.com/rehype-pretty/rehype-pretty-code/issues/247#issuecomment-2619666231): Hey again @jktrn, I have found an unconventional way to achieve this. +> +> If you're using pnpm or bun, you can use their patch functionality to customize the contents of the `node_modules/rehype-pretty-code` package. +> +> I only recently learned about this feature, and it is a good workaround for the time being. Here are the steps: +> +> 1. Run `pnpm patch rehype-pretty-code`. This will instruct you to edit the files in a certain directory. +> 2. Patch out the `isBlockCode{:js}` function to always return `false{:js}`. This will instruct the plugin to not process any block code elements. +> 3. Run `pnpm patch-commit `. This will create a nice patches folder with the right changes. + +## Performing surgery on node_modules + +This happened to be exactly what I needed! I went into my `node_modules` directory and made the changes manually: + +```js title="node_modules > rehype-pretty-code > dist > index.js" startLineNumber=18 ins={9} del={8} +function isInlineCode(element, parent, bypass = false) { + if (bypass) { + return false; + } + return element.tagName === "code" && isElement(parent) && parent.tagName !== "pre" || element.tagName === "inlineCode"; +} +function isBlockCode(element) { + return element.tagName === "pre" && Array.isArray(element.children) && element.children.length === 1 && isElement(element.children[0]) && element.children[0].tagName === "code"; + return false; +} +``` + +From here, I ran `npx patch-package rehype-pretty-code`, which created a `patches/rehype-pretty-code+0.14.1.patch` file with the changes I made: + +```diff title="patches > rehype-pretty-code+0.14.1.patch" +--- a/node_modules/rehype-pretty-code/dist/index.js ++++ b/node_modules/rehype-pretty-code/dist/index.js +@@ -22,7 +22,7 @@ function isInlineCode(element, parent, bypass = false) { + return element.tagName === "code" && isElement(parent) && parent.tagName !== "pre" || element.tagName === "inlineCode"; + } + function isBlockCode(element) { +- return element.tagName === "pre" && Array.isArray(element.children) && element.children.length === 1 && isElement(element.children[0]) && element.children[0].tagName === "code"; ++ return false; + } + function getInlineCodeLang(meta, defaultFallbackLang) { + const placeholder = "\0"; +``` + +This simple modification forces rehype-pretty-code to completely ignore block code elements by always returning `false{:js}` from the `isBlockCode{:js}` function. Now Expressive Code handles all block code formatting, while rehype-pretty-code still beautifully handles my inline code. And just like that, they're working in perfect harmony! + +## Please don't perform surgery on your node_modules + +Absolutely do not do this for production sites (your personal blog does not count = ̄ω ̄=). Directly patching node modules is generally discouraged because patches can break with updates and create maintenance headaches down the road. + +But sometimes, when you're working at the bleeding edge of web development, temporary solutions like this become necessary. The better approach would be to just wait for Expressive Code to implement inline syntax highlighting. But, since it'll take a while for reasons aforementioned, I'll stick with my janky solution. This patch buys me time until either rehype-pretty-code gets maintained again and implements the feature properly, or Expressive Code adds inline code support. + +In the meantime, astro-erudite now has both beautiful code blocks and inline syntax highlighting. And now it's available for all of you to use! \ No newline at end of file diff --git a/src/content/blog/the-state-of-static-blogs/index.mdx b/src/content/blog/the-state-of-static-blogs/index.mdx index 612a973..e33897b 100644 --- a/src/content/blog/the-state-of-static-blogs/index.mdx +++ b/src/content/blog/the-state-of-static-blogs/index.mdx @@ -2,7 +2,7 @@ title: 'The State of Static Blogs in 2024' description: 'There should not be a single reason why you would need a command palette search bar to find a blog post on your own site.' date: 2024-07-25 -tags: ['webdev', 'opinion'] +tags: ['v1.0.0'] image: './1200x630.png' authors: ['enscribe'] --- @@ -123,7 +123,7 @@ This is a non-exhaustive list of features I believe are essential for a friction - The `cn(){:js}` function is a utility function which combines [clsx](https://www.npmjs.com/package/clsx) and [tailwind-merge](https://www.npmjs.com/package/tailwind-merge), two packages which allow painless conditional class addition and concatenation: - ```tsx title="src/lib/utils.ts" caption="A utility function for class name concatenation" showLineNumbers + ```tsx title="src > lib > utils.ts" caption="A utility function for class name concatenation" showLineNumbers import { type ClassValue, clsx } from 'clsx' import { twMerge } from 'tailwind-merge' @@ -134,7 +134,7 @@ This is a non-exhaustive list of features I believe are essential for a friction This needs to be in every single template. This is an example of it being used in my `{:html}` component: - ```astro showLineNumbers title="src/components/Link.astro" caption="A custom Link component with tailwind-merge and clsx" {10-15} "cn" + ```astro showLineNumbers title="src > components > Link.astro" caption="A custom Link component with tailwind-merge and clsx" {10-15} "cn" --- import { cn } from '@/lib/utils' diff --git a/src/pages/404.astro b/src/pages/404.astro index 6ba66f8..2007b55 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -17,9 +17,7 @@ import { cn } from '@/lib/utils' >

404: Page not found

-

- Oops! The page you're looking for doesn't exist. -

+

Oops! The page you're looking for doesn't exist.

0 && } -
+
diff --git a/src/pages/index.astro b/src/pages/index.astro index 5053282..87ba6db 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -18,8 +18,10 @@ const blog = (await getCollection('blog'))
-

er·u·dite

-

/ˈer(y)əˌdīt/ • adjective

+

er·u·dite

+

+ /ˈer(y)əˌdīt/ • adjective +

diff --git a/src/styles/global.css b/src/styles/global.css index 269f525..573fcb2 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -47,7 +47,7 @@ @font-face { font-family: 'Geist Mono'; src: url('/fonts/GeistMonoVF.woff2') format('woff2-variations'); - font-weight: 100 500; + font-weight: 100 600; font-style: normal; font-display: swap; } diff --git a/src/styles/typography.css b/src/styles/typography.css index e39564b..d574410 100644 --- a/src/styles/typography.css +++ b/src/styles/typography.css @@ -5,7 +5,7 @@ @apply text-foreground text-base leading-8 [&>*]:first:mt-0 [&>*]:last:mb-0; p { - @apply text-foreground/80 my-5 leading-7 [&:not(:first-child)]:mt-5; + @apply text-foreground/80 my-5 leading-7 not-first:mt-5; } h1 { @@ -41,11 +41,11 @@ } ul { - @apply marker:text-foreground/30 my-5 ml-6 list-disc [&>li]:mt-4; + @apply marker:text-foreground/30 my-5 ml-6 list-disc [&>li]:mt-2; } ol { - @apply marker:text-foreground/30 my-5 ml-6 list-decimal [&>li]:mt-4; + @apply marker:text-foreground/30 my-5 ml-6 list-decimal [&>li]:mt-2; @apply [&[type='A']]:list-[upper-alpha] [&[type='I']]:list-[upper-roman] [&[type='a']]:list-[lower-alpha] [&[type='i']]:list-[lower-roman]; } @@ -66,11 +66,11 @@ } .expressive-code { - @apply my-6; + @apply my-6 [&_.title]:font-medium!; } blockquote { - @apply my-6 border-l-2 pl-6 text-sm; + @apply [&_*]:text-muted-foreground my-6 border-l-2 pl-6; } hr {