Skip to content

Commit

Permalink
feat(highlight): ✨ shiki-twoslash (importantimport#5)
Browse files Browse the repository at this point in the history
βž• add shiki-twoslash, fenceparser
βž– remove shiki
πŸ’„ add twoslash style
  • Loading branch information
kwaa committed Mar 6, 2022
1 parent f734abd commit 47a9aca
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 29 deletions.
14 changes: 9 additions & 5 deletions mdsvex.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import shiki from 'shiki'
import rehypeSlug from 'rehype-slug'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
import rehypeExternalLinks from 'rehype-external-links'
import { escapeSvelte } from 'mdsvex'
import { lex, parse as parseFence } from 'fenceparser'
import { renderCodeToHTML, runTwoSlash, createShikiHighlighter } from 'shiki-twoslash'
import { statSync } from 'fs'
import { parse, join } from 'path'
import { visit } from 'unist-util-visit'
Expand Down Expand Up @@ -59,10 +60,13 @@ export const mdsvexConfig = {
_: './src/lib/components/layout_post.svelte'
},
highlight: {
highlighter: async (code, lang) =>
`{@html \`${escapeSvelte(
await shiki.getHighlighter({ theme: 'material-default' }).then(highlighter => highlighter.codeToHtml(code, { lang }))
)}\` }`
highlighter: async (code, lang, meta) => {
let fence, twoslash
try { fence = parseFence(lex([lang, meta].filter(Boolean).join(' '))) }
catch (error) { throw new Error(`Could not parse the codefence for this code sample \n${code}`) }
if (fence?.twoslash === true) twoslash = runTwoSlash(code, lang)
return `{@html \`${escapeSvelte(renderCodeToHTML(code, lang, fence ?? {}, {}, await createShikiHighlighter({ theme: 'material-default' }), twoslash))}\` }`
}
},
remarkPlugins: [remarkUraraFm, remarkUraraSpoiler],
rehypePlugins: [
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^3.4.1",
"fenceparser": "^2.0.0",
"github-slugger": "^1.4.0",
"mdast-util-to-string": "^3.1.0",
"mdsvex": "^0.9.8",
Expand All @@ -47,7 +48,7 @@
"rehype-external-links": "^1.0.1",
"rehype-slug": "^5.0.1",
"remark": "^14.0.2",
"shiki": "^0.9.15",
"shiki-twoslash": "^3.0.2",
"svelte": "^3.46.4",
"svelte-check": "^2.4.5",
"svelte-preprocess": "^4.10.4",
Expand Down
78 changes: 69 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 72 additions & 14 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,6 @@ html {
@apply !relative;
}

/* .urara-prose pre */

.urara-prose pre {
@apply mockup-code !bg-neutral min-w-0;
}

.urara-prose pre.shiki::before {
@apply sticky -left-5 -ml-5;
}

.urara-prose pre:not(.shiki) {
@apply bg-neutral text-neutral-content;
}

/* .urara-prose a */

.urara-prose :is(p, li) > a {
Expand Down Expand Up @@ -101,4 +87,76 @@ footer a {
@apply shadow-xl transition-shadow ease-in-out hover:shadow-2xl;
}

/* .prose pre */

.prose pre {
@apply mockup-code !bg-neutral min-w-0;
}

.prose pre:not(.shiki) {
@apply bg-neutral text-neutral-content;
}

.prose pre:not(.shiki)::before {
@apply sticky -left-5 -ml-5
}

/* shiki */

pre.shiki {
@apply px-0
}

pre.shiki::before {
@apply sticky;
}

pre.shiki > div.code-title {
@apply absolute -mt-10 ml-20 pt-1.5 pl-1.5 opacity-50
}

pre.shiki .language-id {
@apply hidden
}

pre .code-container {
@apply overflow-auto
}

pre .code-container > code > div.line > span:first-child {
@apply pl-5
}

pre .code-container > code > div.line > span:last-child {
@apply pr-5
}

pre.shiki div.dim {
@apply opacity-50 transition-opacity
}

pre.shiki:hover div.dim {
@apply opacity-100
}

pre.shiki div.highlight {
@apply bg-warning/20
}

pre.twoslash {
@apply shadow-inner
}

pre.twoslash data-lsp {
@apply border-b border-dashed border-transparent transition-all
}

pre.twoslash:hover data-lsp {
@apply border-neutral-content/30
}

pre.twoslash data-lsp:hover::before {
@apply content-[attr(lsp)] absolute rounded translate-y-5 bg-neutral-focus text-neutral-content font-mono whitespace-pre-wrap transition-all px-2 py-1 z-50
}

/* your code here */

0 comments on commit 47a9aca

Please sign in to comment.