Skip to content

Commit

Permalink
feat: support gfm alerts
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <[email protected]>
  • Loading branch information
Innei committed Oct 29, 2023
1 parent fe01bb5 commit 1f3d95c
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 19 deletions.
26 changes: 8 additions & 18 deletions src/components/icons/status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,16 @@ export function ClaritySuccessLine(props: SVGProps<SVGSVGElement>) {

export function IonInformation(props: SVGProps<SVGSVGElement>) {
return (
<svg width="1em" height="1em" viewBox="0 0 512 512" {...props}>
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="40"
d="M196 220h64v172"
/>
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeMiterlimit="10"
strokeWidth="40"
d="M187 396h138"
/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 256 256"
{...props}
>
<path
fill="currentColor"
d="M256 160a32 32 0 1 1 32-32a32 32 0 0 1-32 32Z"
d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24Zm0 192a88 88 0 1 1 88-88a88.1 88.1 0 0 1-88 88Zm16-40a8 8 0 0 1-8 8a16 16 0 0 1-16-16v-40a8 8 0 0 1 0-16a16 16 0 0 1 16 16v40a8 8 0 0 1 8 8Zm-32-92a12 12 0 1 1 12 12a12 12 0 0 1-12-12Z"
/>
</svg>
)
Expand Down
1 change: 0 additions & 1 deletion src/components/ui/link/MLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ export const MLink: FC<{

const showRichLink = !!parsedType && !!parsedName

console.log(text || parsedName, 'text || parsedName')
return (
<FloatPopover
as="span"
Expand Down
2 changes: 2 additions & 0 deletions src/components/ui/markdown/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Gallery } from '../gallery'
import { LinkCard } from '../link-card'
import { MLink } from '../link/MLink'
import styles from './markdown.module.css'
import { AlertsRule } from './parsers/alert'
import { ContainerRule } from './parsers/container'
import { InsertRule } from './parsers/ins'
import { KateXRule } from './parsers/katex'
Expand Down Expand Up @@ -249,6 +250,7 @@ export const Markdown: FC<MdProps & MarkdownToJSX.Options & PropsWithChildren> =
ins: InsertRule,
kateX: KateXRule,
container: ContainerRule,
alerts: AlertsRule,

...additionalParserRules,
},
Expand Down
11 changes: 11 additions & 0 deletions src/components/ui/markdown/customize.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,14 @@ Inline https://github.com/Innei
```

[Innei 太菜了]{GH@Innei}

## Alerts

> [!NOTE]
> Highlights information that users should take into account, even when skimming.
> [!IMPORTANT]
> Crucial information necessary for users to succeed.
> [!WARNING]
> Critical content demanding immediate user attention due to potential risks.
92 changes: 92 additions & 0 deletions src/components/ui/markdown/parsers/alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import clsx from 'clsx'
import { blockRegex, Priority } from 'markdown-to-jsx'
import type { MarkdownToJSX } from 'markdown-to-jsx'

import {
FluentShieldError20Regular,
FluentWarning28Regular,
IonInformation,
} from '~/components/icons/status'

import { Markdown } from '../Markdown'

const textColorMap = {
NOTE: 'text-always-blue-500 dark:text-always-blue-400',
IMPORTANT: 'text-accent',
WARNING: 'text-amber-500 dark:text-amber-400',
} as any

const borderColorMap = {
NOTE: 'border-always-blue-500 dark:border-always-blue-400',
IMPORTANT: 'border-accent',
WARNING: 'border-amber-500 dark:border-amber-400',
} as any

const typedIconMap = {
NOTE: IonInformation,
IMPORTANT: FluentWarning28Regular,
WARNING: FluentShieldError20Regular,
} as any

/**
*
* > [!NOTE]
* > Highlights information that users should take into account, even when skimming.
*/
const ALERT_BLOCKQUOTE_R =
// /^( *> *\[!(NOTE|IMPORTANT|WARNING)\] *\n(?: *>.*(?:\n|$))+)/m
// /^( *> *\[!(?:(?<type>NOTE|IMPORTANT|WARNING))\](?<body>.*(\n *>.*?)*))(?=\n *> *\[(NOTE|IMPORTANT|WARNING)\]|$)/
// /^(> *\[!(?<type>NOTE|IMPORTANT|WARNING)\](?<body>(?:\n?.*?)*))((?:\n{2,})|$)/
// /^*> *\[!(?<type>NOTE|IMPORTANT|WARNING)\](?<body>(?:\n? *>.*?)*?)(?=\n{2,}|$)/
// /^( *> *\[!(?<type>NOTE|IMPORTANT|WARNING)\].*?(?:\n(?! *> *\[(NOTE|IMPORTANT|WARNING)\]).*?)*)/

// /^(> \[!(?<type>NOTE|IMPORTANT|WARNING)\])(?<body>(?:\n? *>.*?(?!\n *> *\[(?:NOTE|IMPORTANT|WARNING)\]))*)/
/^(> \[!(?<type>NOTE|IMPORTANT|WARNING)\].*?)(?<body>(?:\n *>.*?)*)(?=\n{2,}|$)/

export const AlertsRule: MarkdownToJSX.Rule = {
match: blockRegex(ALERT_BLOCKQUOTE_R),
order: Priority.HIGH,
parse(capture) {
return {
raw: capture[0],
parsed: {
...capture.groups,
},
}
},
react(node, output, state) {
const { type, body } = node.parsed
const bodyClean = body.replace(/^> */gm, '')

const typePrefix = type[0] + type.toLowerCase().slice(1)

const Icon = typedIconMap[type] || typedIconMap.info
return (
<blockquote className={clsx(borderColorMap[type], 'not-italic')}>
<span
className={clsx(
'text-semibold mb-1 inline-flex items-center',
textColorMap[type],
)}
>
<Icon
className={clsx(
`flex-shrink-0 text-3xl md:mr-2 md:self-start md:text-left`,
typedIconMap[type] || typedIconMap.info,
)}
/>

{typePrefix}
</span>
<br />

<Markdown
allowsScript
className="not-prose w-full [&>p:first-child]:mt-0"
>
{bodyClean}
</Markdown>
</blockquote>
)
},
}
1 change: 1 addition & 0 deletions src/components/ui/markdown/parsers/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const shouldCatchContainerName = [
'warning',
'note',
].join('|')

export const ContainerRule: MarkdownToJSX.Rule = {
match: blockRegex(
new RegExp(
Expand Down

1 comment on commit 1f3d95c

@vercel
Copy link

@vercel vercel bot commented on 1f3d95c Oct 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

shiro – ./

shiro-innei.vercel.app
springtide.vercel.app
shiro-git-main-innei.vercel.app
innei.in

Please sign in to comment.