Add basic support for callouts
This commit is contained in:
parent
b280b29df6
commit
5687f3b02b
5 changed files with 265 additions and 4 deletions
10
bun.lock
10
bun.lock
|
@ -6,7 +6,7 @@
|
|||
"dependencies": {
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@endeavorance/emdy": "^1.0.0",
|
||||
"marked": "^15.0.12",
|
||||
"rehype-callouts": "^2.1.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
|
@ -90,10 +90,14 @@
|
|||
|
||||
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
|
||||
|
||||
"hast-util-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", "hast-util-from-parse5": "^8.0.0", "parse5": "^7.0.0", "vfile": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="],
|
||||
|
||||
"hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="],
|
||||
|
||||
"hast-util-heading-rank": ["hast-util-heading-rank@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA=="],
|
||||
|
||||
"hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="],
|
||||
|
||||
"hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="],
|
||||
|
||||
"hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="],
|
||||
|
@ -116,8 +120,6 @@
|
|||
|
||||
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
|
||||
|
||||
"marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="],
|
||||
|
||||
"mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="],
|
||||
|
||||
"mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="],
|
||||
|
@ -204,6 +206,8 @@
|
|||
|
||||
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
||||
|
||||
"rehype-callouts": ["rehype-callouts@2.1.0", "", { "dependencies": { "@types/hast": "^3.0.4", "hast-util-from-html": "^2.0.3", "hast-util-is-element": "^3.0.0", "hastscript": "^9.0.1", "unist-util-visit": "^5.0.0" } }, "sha512-Als/wlYpXg2Rs0p/yofrkSH6IQzn1xh6cvBC5BHy5JVT3lGlzUvVT8wOyVqCEgf8Eun6cQ3f47rLLoaiyLkP0w=="],
|
||||
|
||||
"rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="],
|
||||
|
||||
"rehype-slug": ["rehype-slug@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "github-slugger": "^2.0.0", "hast-util-heading-rank": "^3.0.0", "hast-util-to-string": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A=="],
|
||||
|
|
|
@ -8,3 +8,12 @@ It has a list!
|
|||
|
||||
- See?
|
||||
- Fancy!
|
||||
|
||||
How about a callout?
|
||||
|
||||
> [!info] This is an info callout
|
||||
> Here's some more info
|
||||
> etc
|
||||
|
||||
> [!warning]- This is collapsible
|
||||
> And how!
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest"
|
||||
},
|
||||
|
@ -13,6 +13,7 @@
|
|||
"dependencies": {
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@endeavorance/emdy": "^1.0.0",
|
||||
"rehype-callouts": "^2.1.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
|
|
|
@ -113,3 +113,248 @@ th {
|
|||
background: var(--color-bg);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Callout styles, from https://raw.githubusercontent.com/lin-stephanie/rehype-callouts/refs/heads/main/src/themes/obsidian/index.css */
|
||||
|
||||
[data-callout="note"] {
|
||||
--rc-color-light: var(--callout-note-color-light, rgb(8, 109, 221));
|
||||
--rc-color-dark: var(--callout-note-color-dark, rgb(2, 122, 255));
|
||||
}
|
||||
|
||||
[data-callout="abstract"] {
|
||||
--rc-color-light: var(--callout-abstract-color-light, rgb(0, 191, 188));
|
||||
--rc-color-dark: var(--callout-abstract-color-dark, rgb(83, 223, 221));
|
||||
}
|
||||
|
||||
[data-callout="summary"] {
|
||||
--rc-color-light: var(--callout-summary-color-light, rgb(0, 191, 188));
|
||||
--rc-color-dark: var(--callout-summary-color-dark, rgb(83, 223, 221));
|
||||
}
|
||||
|
||||
[data-callout="tldr"] {
|
||||
--rc-color-light: var(--callout-tldr-color-light, rgb(0, 191, 188));
|
||||
--rc-color-dark: var(--callout-tldr-color-dark, rgb(83, 223, 221));
|
||||
}
|
||||
|
||||
[data-callout="info"] {
|
||||
--rc-color-light: var(--callout-info-color-light, rgb(8, 109, 221));
|
||||
--rc-color-dark: var(--callout-info-color-dark, rgb(2, 122, 255));
|
||||
}
|
||||
|
||||
[data-callout="todo"] {
|
||||
--rc-color-light: var(--callout-todo-color-light, rgb(8, 109, 221));
|
||||
--rc-color-dark: var(--callout-todo-color-dark, rgb(2, 122, 255));
|
||||
}
|
||||
|
||||
[data-callout="tip"] {
|
||||
--rc-color-light: var(--callout-tip-color-light, rgb(0, 191, 188));
|
||||
--rc-color-dark: var(--callout-tip-color-dark, rgb(83, 223, 221));
|
||||
}
|
||||
|
||||
[data-callout="hint"] {
|
||||
--rc-color-light: var(--callout-hint-color-light, rgb(0, 191, 188));
|
||||
--rc-color-dark: var(--callout-hint-color-dark, rgb(83, 223, 221));
|
||||
}
|
||||
|
||||
[data-callout="important"] {
|
||||
--rc-color-light: var(--callout-important-color-light, rgb(0, 191, 188));
|
||||
--rc-color-dark: var(--callout-important-color-dark, rgb(83, 223, 221));
|
||||
}
|
||||
|
||||
[data-callout="success"] {
|
||||
--rc-color-light: var(--callout-success-color-light, rgb(8, 185, 78));
|
||||
--rc-color-dark: var(--callout-success-color-dark, rgb(68, 207, 110));
|
||||
}
|
||||
|
||||
[data-callout="check"] {
|
||||
--rc-color-light: var(--callout-check-color-light, rgb(8, 185, 78));
|
||||
--rc-color-dark: var(--callout-check-color-dark, rgb(68, 207, 110));
|
||||
}
|
||||
|
||||
[data-callout="done"] {
|
||||
--rc-color-light: var(--callout-done-color-light, rgb(8, 185, 78));
|
||||
--rc-color-dark: var(--callout-done-color-dark, rgb(68, 207, 110));
|
||||
}
|
||||
|
||||
[data-callout="question"] {
|
||||
--rc-color-light: var(--callout-question-color-light, rgb(236, 117, 0));
|
||||
--rc-color-dark: var(--callout-question-color-dark, rgb(233, 151, 63));
|
||||
}
|
||||
|
||||
[data-callout="help"] {
|
||||
--rc-color-light: var(--callout-help-color-light, rgb(236, 117, 0));
|
||||
--rc-color-dark: var(--callout-help-color-dark, rgb(233, 151, 63));
|
||||
}
|
||||
|
||||
[data-callout="faq"] {
|
||||
--rc-color-light: var(--callout-faq-color-light, rgb(236, 117, 0));
|
||||
--rc-color-dark: var(--callout-faq-color-dark, rgb(233, 151, 63));
|
||||
}
|
||||
|
||||
[data-callout="warning"] {
|
||||
--rc-color-light: var(--callout-warning-color-light, rgb(236, 117, 0));
|
||||
--rc-color-dark: var(--callout-warning-color-dark, rgb(233, 151, 63));
|
||||
}
|
||||
|
||||
[data-callout="attention"] {
|
||||
--rc-color-light: var(--callout-attention-color-light, rgb(236, 117, 0));
|
||||
--rc-color-dark: var(--callout-attention-color-dark, rgb(233, 151, 63));
|
||||
}
|
||||
|
||||
[data-callout="caution"] {
|
||||
--rc-color-light: var(--callout-caution-color-light, rgb(236, 117, 0));
|
||||
--rc-color-dark: var(--callout-caution-color-dark, rgb(233, 151, 63));
|
||||
}
|
||||
|
||||
[data-callout="failure"] {
|
||||
--rc-color-light: var(--callout-failure-color-light, rgb(233, 49, 71));
|
||||
--rc-color-dark: var(--callout-failure-color-dark, rgb(251, 70, 76));
|
||||
}
|
||||
|
||||
[data-callout="missing"] {
|
||||
--rc-color-light: var(--callout-missing-color-light, rgb(233, 49, 71));
|
||||
--rc-color-dark: var(--callout-missing-color-dark, rgb(251, 70, 76));
|
||||
}
|
||||
|
||||
[data-callout="fail"] {
|
||||
--rc-color-light: var(--callout-fail-color-light, rgb(233, 49, 71));
|
||||
--rc-color-dark: var(--callout-fail-color-dark, rgb(251, 70, 76));
|
||||
}
|
||||
|
||||
[data-callout="danger"] {
|
||||
--rc-color-light: var(--callout-danger-color-light, rgb(233, 49, 71));
|
||||
--rc-color-dark: var(--callout-danger-color-dark, rgb(251, 70, 76));
|
||||
}
|
||||
|
||||
[data-callout="error"] {
|
||||
--rc-color-light: var(--callout-error-color-light, rgb(233, 49, 71));
|
||||
--rc-color-dark: var(--callout-error-color-dark, rgb(251, 70, 76));
|
||||
}
|
||||
|
||||
[data-callout="bug"] {
|
||||
--rc-color-light: var(--callout-bug-color-light, rgb(233, 49, 71));
|
||||
--rc-color-dark: var(--callout-bug-color-dark, rgb(251, 70, 76));
|
||||
}
|
||||
|
||||
[data-callout="example"] {
|
||||
--rc-color-light: var(--callout-example-color-light, rgb(120, 82, 238));
|
||||
--rc-color-dark: var(--callout-example-color-dark, rgb(168, 130, 255));
|
||||
}
|
||||
|
||||
[data-callout="quote"] {
|
||||
--rc-color-light: var(--callout-quote-color-light, rgb(158, 158, 158));
|
||||
--rc-color-dark: var(--callout-quote-color-dark, rgb(158, 158, 158));
|
||||
}
|
||||
|
||||
[data-callout="cite"] {
|
||||
--rc-color-light: var(--callout-cite-color-light, rgb(158, 158, 158));
|
||||
--rc-color-dark: var(--callout-cite-color-dark, rgb(158, 158, 158));
|
||||
}
|
||||
|
||||
.callout {
|
||||
--rc-color-default: #888;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
width: 100%;
|
||||
padding: 12px 12px 12px 24px;
|
||||
border-radius: 4px;
|
||||
margin: 1em 0;
|
||||
|
||||
line-height: 1.3;
|
||||
|
||||
mix-blend-mode: darken;
|
||||
background-color: rgb(
|
||||
from var(--rc-color-light, var(--rc-color-default)) r g b /
|
||||
0.1
|
||||
);
|
||||
}
|
||||
|
||||
.dark .callout {
|
||||
mix-blend-mode: lighten;
|
||||
background-color: rgb(
|
||||
from var(--rc-color-dark, var(--rc-color-default)) r g b /
|
||||
0.1
|
||||
);
|
||||
}
|
||||
|
||||
.callout-title {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
|
||||
color: var(--rc-color-light, var(--rc-color-default));
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.dark .callout-title {
|
||||
color: var(--rc-color-dark, var(--rc-color-default));
|
||||
}
|
||||
|
||||
.callout-title::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.callout-title-icon {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.callout-title-text {
|
||||
color: inherit;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.callout-content {
|
||||
overflow-x: auto;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.callout[data-collapsible="true"] .callout-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.callout[data-collapsible="true"] .callout-fold-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-inline-end: 8px;
|
||||
}
|
||||
|
||||
.callout[data-collapsible="true"] > .callout-title .callout-fold-icon svg {
|
||||
transform: rotate(-90deg);
|
||||
transition: transform 100ms ease-in-out;
|
||||
}
|
||||
|
||||
.callout[data-collapsible="true"][open]
|
||||
> .callout-title
|
||||
.callout-fold-icon
|
||||
svg {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.callout-title-icon::after,
|
||||
.callout-fold-icon::after {
|
||||
content: "\200B";
|
||||
}
|
||||
|
||||
.callout-title-icon svg,
|
||||
.callout-fold-icon svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.callout {
|
||||
mix-blend-mode: lighten;
|
||||
background-color: rgb(
|
||||
from var(--rc-color-dark, var(--rc-color-default)) r g b /
|
||||
0.1
|
||||
);
|
||||
}
|
||||
|
||||
.callout-title {
|
||||
color: var(--rc-color-dark, var(--rc-color-default));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import remarkParse from "remark-parse";
|
|||
import remarkRehype from "remark-rehype";
|
||||
import rehypeSlug from "rehype-slug";
|
||||
import { unified } from "unified";
|
||||
import rehypeCallouts from "rehype-callouts";
|
||||
|
||||
export async function parseMarkdown(markdown: string): Promise<string> {
|
||||
const file = await unified()
|
||||
|
@ -13,6 +14,7 @@ export async function parseMarkdown(markdown: string): Promise<string> {
|
|||
.use(remarkRehype, { allowDangerousHtml: true })
|
||||
.use(rehypeRaw)
|
||||
.use(rehypeSlug)
|
||||
.use(rehypeCallouts)
|
||||
.use(rehypeStringify)
|
||||
.process(markdown);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue