|
@@ -1,82 +1,82 @@
|
|
|
<script lang="ts" context="module">
|
|
|
import { marked, type Token } from 'marked';
|
|
|
|
|
|
- type AlertType = "NOTE" | "TIP" | "IMPORTANT" | "WARNING" | "CAUTION";
|
|
|
-
|
|
|
- interface AlertTheme {
|
|
|
- border: string;
|
|
|
- text: string;
|
|
|
- icon: ComponentType;
|
|
|
- }
|
|
|
-
|
|
|
- export interface AlertData {
|
|
|
- type: AlertType;
|
|
|
- text: string;
|
|
|
- tokens: Token[];
|
|
|
- }
|
|
|
-
|
|
|
- const alertStyles: Record<AlertType, AlertTheme> = {
|
|
|
- "NOTE": {
|
|
|
- border: "border-sky-500",
|
|
|
- text: "text-sky-500",
|
|
|
- icon: Info
|
|
|
- },
|
|
|
- "TIP": {
|
|
|
- border: "border-emerald-500",
|
|
|
- text: "text-emerald-500",
|
|
|
- icon: LightBlub
|
|
|
- },
|
|
|
- "IMPORTANT": {
|
|
|
- border: "border-purple-500",
|
|
|
- text: "text-purple-500",
|
|
|
- icon: Star
|
|
|
- },
|
|
|
- "WARNING": {
|
|
|
- border: "border-yellow-500",
|
|
|
- text: "text-yellow-500",
|
|
|
- icon: ArrowRightCircle
|
|
|
- },
|
|
|
- "CAUTION": {
|
|
|
- border: "border-rose-500",
|
|
|
- text: "text-rose-500",
|
|
|
- icon: Bolt
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- export function alertComponent(token: Token): AlertData | false {
|
|
|
- const regExpStr = `^(?:\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\])\\s*?\n*`;
|
|
|
- const regExp = new RegExp(regExpStr);
|
|
|
- const matches = token.text?.match(regExp);
|
|
|
-
|
|
|
- if (matches && matches.length) {
|
|
|
- const alertType = matches[1] as AlertType;
|
|
|
- const newText = token.text.replace(regExp, '');
|
|
|
- const newTokens = marked.lexer(newText);
|
|
|
- return {
|
|
|
- type: alertType,
|
|
|
- text: newText,
|
|
|
- tokens: newTokens
|
|
|
- };
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
+ type AlertType = 'NOTE' | 'TIP' | 'IMPORTANT' | 'WARNING' | 'CAUTION';
|
|
|
+
|
|
|
+ interface AlertTheme {
|
|
|
+ border: string;
|
|
|
+ text: string;
|
|
|
+ icon: ComponentType;
|
|
|
+ }
|
|
|
+
|
|
|
+ export interface AlertData {
|
|
|
+ type: AlertType;
|
|
|
+ text: string;
|
|
|
+ tokens: Token[];
|
|
|
+ }
|
|
|
+
|
|
|
+ const alertStyles: Record<AlertType, AlertTheme> = {
|
|
|
+ NOTE: {
|
|
|
+ border: 'border-sky-500',
|
|
|
+ text: 'text-sky-500',
|
|
|
+ icon: Info
|
|
|
+ },
|
|
|
+ TIP: {
|
|
|
+ border: 'border-emerald-500',
|
|
|
+ text: 'text-emerald-500',
|
|
|
+ icon: LightBlub
|
|
|
+ },
|
|
|
+ IMPORTANT: {
|
|
|
+ border: 'border-purple-500',
|
|
|
+ text: 'text-purple-500',
|
|
|
+ icon: Star
|
|
|
+ },
|
|
|
+ WARNING: {
|
|
|
+ border: 'border-yellow-500',
|
|
|
+ text: 'text-yellow-500',
|
|
|
+ icon: ArrowRightCircle
|
|
|
+ },
|
|
|
+ CAUTION: {
|
|
|
+ border: 'border-rose-500',
|
|
|
+ text: 'text-rose-500',
|
|
|
+ icon: Bolt
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ export function alertComponent(token: Token): AlertData | false {
|
|
|
+ const regExpStr = `^(?:\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\])\\s*?\n*`;
|
|
|
+ const regExp = new RegExp(regExpStr);
|
|
|
+ const matches = token.text?.match(regExp);
|
|
|
+
|
|
|
+ if (matches && matches.length) {
|
|
|
+ const alertType = matches[1] as AlertType;
|
|
|
+ const newText = token.text.replace(regExp, '');
|
|
|
+ const newTokens = marked.lexer(newText);
|
|
|
+ return {
|
|
|
+ type: alertType,
|
|
|
+ text: newText,
|
|
|
+ tokens: newTokens
|
|
|
+ };
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
</script>
|
|
|
|
|
|
<script lang="ts">
|
|
|
- import Info from '$lib/components/icons/Info.svelte';
|
|
|
- import Star from '$lib/components/icons/Star.svelte';
|
|
|
- import LightBlub from '$lib/components/icons/LightBlub.svelte';
|
|
|
- import Bolt from '$lib/components/icons/Bolt.svelte';
|
|
|
- import ArrowRightCircle from '$lib/components/icons/ArrowRightCircle.svelte';
|
|
|
- import MarkdownTokens from './MarkdownTokens.svelte';
|
|
|
- import type { ComponentType } from 'svelte';
|
|
|
-
|
|
|
- export let token: Token;
|
|
|
- export let alert: AlertData;
|
|
|
- export let id = '';
|
|
|
- export let tokenIdx = 0;
|
|
|
- export let onTaskClick: ((event: MouseEvent) => void) | undefined = undefined;
|
|
|
- export let onSourceClick: ((event: MouseEvent) => void) | undefined = undefined;
|
|
|
+ import Info from '$lib/components/icons/Info.svelte';
|
|
|
+ import Star from '$lib/components/icons/Star.svelte';
|
|
|
+ import LightBlub from '$lib/components/icons/LightBlub.svelte';
|
|
|
+ import Bolt from '$lib/components/icons/Bolt.svelte';
|
|
|
+ import ArrowRightCircle from '$lib/components/icons/ArrowRightCircle.svelte';
|
|
|
+ import MarkdownTokens from './MarkdownTokens.svelte';
|
|
|
+ import type { ComponentType } from 'svelte';
|
|
|
+
|
|
|
+ export let token: Token;
|
|
|
+ export let alert: AlertData;
|
|
|
+ export let id = '';
|
|
|
+ export let tokenIdx = 0;
|
|
|
+ export let onTaskClick: ((event: MouseEvent) => void) | undefined = undefined;
|
|
|
+ export let onSourceClick: ((event: MouseEvent) => void) | undefined = undefined;
|
|
|
</script>
|
|
|
|
|
|
<!--
|
|
@@ -100,17 +100,9 @@ Renders the following Markdown as alerts:
|
|
|
|
|
|
-->
|
|
|
<div class={`border-l-2 pl-2 ${alertStyles[alert.type].border}`}>
|
|
|
- <p class={alertStyles[alert.type].text}>
|
|
|
- <svelte:component
|
|
|
- this={alertStyles[alert.type].icon}
|
|
|
- className="inline-block size-4"
|
|
|
- />
|
|
|
- <b>{alert.type}</b>
|
|
|
- </p>
|
|
|
- <MarkdownTokens
|
|
|
- id={`${id}-${tokenIdx}`}
|
|
|
- tokens={alert.tokens}
|
|
|
- {onTaskClick}
|
|
|
- {onSourceClick}
|
|
|
- />
|
|
|
+ <p class={alertStyles[alert.type].text}>
|
|
|
+ <svelte:component this={alertStyles[alert.type].icon} className="inline-block size-4" />
|
|
|
+ <b>{alert.type}</b>
|
|
|
+ </p>
|
|
|
+ <MarkdownTokens id={`${id}-${tokenIdx}`} tokens={alert.tokens} {onTaskClick} {onSourceClick} />
|
|
|
</div>
|