Skip to content

Commit

Permalink
✨ feat: Shiki transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuozhiyongde committed Nov 15, 2024
1 parent 5989ef6 commit 86385f9
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 7 deletions.
12 changes: 8 additions & 4 deletions astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import vercel from '@astrojs/vercel/serverless'
import mdx from '@astrojs/mdx'
import sitemap from '@astrojs/sitemap'
import tailwind from '@astrojs/tailwind'
import playformCompress from '@playform/compress'
import icon from 'astro-icon'
// Markdown
import rehypeExternalLinks from 'rehype-external-links'
Expand All @@ -18,8 +17,10 @@ import { remarkAlert } from 'remark-github-blockquote-alert'
import remarkMath from 'remark-math'
import remarkUnwrapImages from 'remark-unwrap-images'
import { siteConfig } from './src/site.config.ts'
import { addCopyButton, addLanguage } from './src/utils/shiki.ts'
import { remarkGithubCards, remarkReadingTime, remarkArxivCards } from './src/utils/remarkParser.ts'


// https://astro.build/config
export default defineConfig({
// Top-Level Options
Expand All @@ -45,8 +46,9 @@ export default defineConfig({
sitemap(),
mdx(),
icon(),
playformCompress({
SVG: false
(await import('@playform/compress')).default({
SVG: false,
Exclude: ['index.*.js']
})
],
// root: './my-project-directory',
Expand All @@ -72,6 +74,7 @@ export default defineConfig({
[
rehypeExternalLinks,
{
...(siteConfig.externalLinkArrow && { content: { type: 'text', value: ' ↗' } }),
target: '_blank',
rel: ['nofollow, noopener, noreferrer']
}
Expand All @@ -86,7 +89,8 @@ export default defineConfig({
themes: {
dark: 'github-dark',
light: 'github-light'
}
},
transformers: [addLanguage(), addCopyButton(2000)]
}
}
})
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"xmldom": "^0.6.0"
},
"devDependencies": {
"@playform/compress": "^0.1.0",
"@playform/compress": "^0.1.6",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/typography": "^0.5.13",
"@types/dompurify": "^3.0.5",
Expand Down
29 changes: 29 additions & 0 deletions public/icons/code.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions public/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,47 @@ body::-webkit-scrollbar {
::-webkit-scrollbar-track {
background: transparent;
}

/* Shiki transformer */
.astro-code:has(code) {
position: relative;
}
.astro-code:has(div.title) pre {
padding-top: 2.25rem;
}
.astro-code button.copy {
& .success::before {
content: 'Copied!';
position: absolute;
right: 100%;
top: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.75rem;
padding: 0.5rem;
margin-right: 0.5rem;
border-radius: 0.25rem;
color: hsl(var(--muted-foreground));
background-color: hsl(var(--primary-foreground));
border: 1px solid hsl(var(--border));
}
&.copied {
& .success {
display: block;
}

& .ready {
display: none;
}
}
}
.astro-code:hover {
button.copy {
opacity: 1;
}
.language {
opacity: 0;
}
}
1 change: 0 additions & 1 deletion src/components/BaseHead.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const titleSeparator = '•'
const siteTitle = `${title} ${titleSeparator} ${siteConfig.title}`
const canonicalURL = new URL(Astro.url.pathname, Astro.site)
const socialImageURL = new URL(ogImage ? ogImage : '/images/social-card.png', Astro.url).href
const { walineServerUrl } = siteConfig
---

<meta charset='utf-8' />
Expand Down
1 change: 0 additions & 1 deletion src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import PostPreview from '@/components/blog/PostPreview.astro'
import Button from '@/components/Button.astro'
import { siteConfig } from '@/site-config'
import { getAllPosts, sortMDByDate } from '@/utils'
import GithubCard from '@/components/GithubCard.astro'
import avatar from '@/assets/avatar.png'
Expand Down
1 change: 1 addition & 0 deletions src/site.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const siteConfig: SiteConfig = {
},
// Customize
pageSize: 8,
externalLinkArrow: true,
registration: {
url: 'https://icp.gov.moe/?keyword=APTX4869',
text: '萌ICP备APTX4869号'
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type SiteConfig = {
options: Intl.DateTimeFormatOptions
}
pageSize: number
externalLinkArrow: boolean
registration?: {
url: string
text: string
Expand Down
1 change: 1 addition & 0 deletions src/utils/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const GITHUB_TOKEN = ''
142 changes: 142 additions & 0 deletions src/utils/shiki.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { h } from 'hastscript'
import type { ShikiTransformer } from 'shiki'

function parseMetaString(str = '') {
return Object.fromEntries(
str.split(' ').reduce((acc: [string, string | true][], cur) => {
const matched = cur.match(/(.+)?=("(.+)"|'(.+)')$/)
if (matched === null) return acc
const key = matched[1]
const value = matched[3] || matched[4] || true
acc = [...acc, [key, value]]
return acc
}, [])
)
}

export const updateStyle = (): ShikiTransformer => {
return {
name: 'shiki-transformer-update-style',
pre(node) {
const container = h(
'pre',
{
class: 'code-container overflow-x-scroll'
},
node.children
)
node.children = [container]
node.tagName = 'div'
}
}
}

export const processMeta = (): ShikiTransformer => {
return {
name: 'shiki-transformer-process-meta',
preprocess() {
if (!this.options.meta) return
const rawMeta = this.options.meta?.__raw
if (!rawMeta) return
const meta = parseMetaString(rawMeta)
Object.assign(this.options.meta, meta)
}
}
}

export const addTitle = (): ShikiTransformer => {
return {
name: 'shiki-transformer-add-title',
pre(node) {
const rawMeta = this.options.meta?.__raw
if (!rawMeta) return
const meta = parseMetaString(rawMeta)
if (this.options.meta) {
Object.assign(this.options.meta, meta)
}
console.log(this.options.meta)

if (!meta.title) return

const div = h(
'div',
{
class:
'title absolute top-2 left-3 text-sm text-foreground px-2 py-0.5 bg-primary-foreground rounded-lg border border-border'
},
meta.title.toString()
)
node.children.unshift(div)
}
}
}

export const addLanguage = (): ShikiTransformer => {
return {
name: 'shiki-transformer-add-language',
pre(node) {
const span = h(
'span',
{
class:
'language transition-opacity duration-300 absolute top-3 right-3 text-sm text-muted-foreground'
},
this.options.lang
)
node.children.push(span)
}
}
}

export const addCopyButton = (timeout?: number): ShikiTransformer => {
const toggleMs = timeout || 3000

return {
name: 'shiki-transformer-copy-button',
pre(node) {
const button = h(
'button',
{
class:
'copy transition-opacity duration-300 opacity-0 absolute top-3 right-3 text-muted-foreground p-1 box-content border border-border rounded bg-primary-foreground',
'data-code': this.source,
onclick: `
navigator.clipboard.writeText(this.dataset.code);
this.classList.add('copied');
setTimeout(() => this.classList.remove('copied'), ${toggleMs})
`
},
[
h('div', { class: 'ready' }, [
h(
'svg',
{
class: 'size-5'
},
[
h('use', {
href: '/icons/code.svg#mingcute-clipboard-line'
})
]
)
]),
h('div', { class: 'success hidden' }, [
h(
'svg',
{
class: 'size-5'
},
[
h('use', {
href: '/icons/code.svg#mingcute-file-check-line'
})
]
)
])
]
)

node.children.push(button)
}
}
}

0 comments on commit 86385f9

Please sign in to comment.