Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 1x 1x 1x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 13x 13x 13x 13x 8x 13x 5x 5x 15x 10x 5x 5x 5x 16x 16x 13x 20x 13x 16x 13x 13x 1x | import { visit } from 'unist-util-visit';
import type { Plugin } from 'unified';
import type { Root, PhrasingContent } from "mdast";
const alertRegex = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]/i;
const alertLegacyRegex = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)(\/.*)?\]/i;
type Option = {
/**
* Use the legacy title format, which includes a slash and a title after the alert type.
*
* Enabling legacyTitle allows modifying the title, but this is not GitHub standard.
*/
legacyTitle?: boolean;
/**
* The tag name of the alert container. default is `div`.
* or you can use `blockquote` for semantic HTML.
*/
tagName?: string;
/**
* Custom class names for the alert container appending to the end.
*/
classNames?: string;
}
/**
* Alerts are a Markdown extension based on the blockquote syntax that you can use to emphasize critical information.
* On GitHub, they are displayed with distinctive colors and icons to indicate the significance of the content.
* https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
*/
export const remarkAlert: Plugin<[Option?], Root> = ({ legacyTitle = false, tagName = "div", classNames = "" } = {}) => {
return (tree) => {
visit(tree, "blockquote", (node, index, parent) => {
let alertType = '';
let title = '';
let isNext = true;
let child = node.children.map((item) => {
Eif (isNext && item.type === "paragraph") {
const firstNode = item.children[0];
const text = firstNode.type === 'text' ? firstNode.value : '';
const reg = legacyTitle ? alertLegacyRegex : alertRegex;
const match = text.match(reg);
if (match) {
isNext = false;
alertType = match[1].toLocaleLowerCase();
title = legacyTitle ? match[2] || alertType.toLocaleUpperCase() : alertType.toLocaleUpperCase();
if (text.includes('\n')) {
item.children[0] = {
type: 'text',
value: text.replace(reg, '').replace(/^\n+/, ''),
};
}
if (!text.includes('\n')) {
const itemChild: Array<PhrasingContent> = [];
item.children.forEach((item, idx) => {
if (idx == 0) return;
if (idx == 1 && item.type === 'break') {
return;
}
itemChild.push(item);
});
item.children = [...itemChild];
}
}
}
return item;
})
if (!!alertType) {
node.data = {
hName: tagName,
hProperties: {
className: ["markdown-alert", `markdown-alert-${alertType}`, ...classNames.split(" ").filter((s) => s.length)],
dir: 'auto'
},
}
child.unshift({
type: "paragraph",
children: [
getAlertIcon(alertType as IconType),
{
type: "text",
value: title.replace(/^\//, ''),
}
],
data: {
hProperties: {
className: "markdown-alert-title",
dir: "auto"
}
}
})
}
node.children = [...child];
});
};
};
export default remarkAlert;
export function getAlertIcon(type: IconType): PhrasingContent {
let pathD = pathData[type] ?? '';
return {
type: "emphasis",
data: {
hName: "svg",
hProperties: {
className: ["octicon"],
viewBox: '0 0 16 16',
width: '16',
height: '16',
ariaHidden: 'true',
},
},
children: [
{
type: "emphasis",
data: {
hName: "path",
hProperties: {
d: pathD
}
},
children: []
}
]
}
}
type IconType = 'note' | 'tip' | 'important' | 'warning' | 'caution';
const pathData: Record<IconType, string> = {
note: 'M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z',
tip: 'M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z',
important:
'M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z',
warning:
'M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z',
caution:
'M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z',
};
|