Skip to content

Commit

Permalink
feat: add legacyTitle option.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Mar 16, 2024
1 parent 3b389ec commit 70c5ffb
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 10 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,31 @@ The output HTML will be:
</div>
```

## Modify the title

Change the expression `[!NOTE]` to `[!NOTE/笔记]`

```js
let markdown = `# Alert \n> [!NOTE/笔记] \n> test`;

const htmlStr = remark()
.use(remarkParse)
.use(remarkAlert, { legacyTitle: true })
.use(remarkRehype)
.use(rehypeStringify)
.processSync(markdown).toString()
```

The output HTML will be:

```html
<h1>笔记</h1>
<div class="markdown-alert markdown-alert-note" dir="auto">
<p class="markdown-alert-title" dir="auto"><svg class="octicon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="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"></path></svg>NOTE</p>
<p>Useful information that users should know, even when skimming content.</p>
</div>
```

## Styling

Add the following styles to your css to mimic GitHub's styling of alerts:
Expand Down
33 changes: 23 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,43 @@ 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 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
}

/**
* 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<[], Root> = () => {
export const remarkAlert: Plugin<[Option?], Root> = ({ legacyTitle = false } = {}) => {
return (tree) => {
visit(tree, "blockquote", (node, index, parent) => {
let alertNode = '';
let alertType = '';
let title = '';
let isNext = true;
let child = node.children.map((item) => {
if (isNext && item.type === "paragraph") {
const firstNode = item.children[0];
const text = firstNode.type === 'text' ? firstNode.value : '';
const match = text.match(alertRegex);
const reg = legacyTitle ? alertLegacyRegex : alertRegex;
const match = text.match(reg);
if (match) {
isNext = false;
alertNode = match[1].toLocaleLowerCase();
alertType = match[1].toLocaleLowerCase();
title = legacyTitle ? match[2] || alertType.toLocaleUpperCase() : alertType.toLocaleUpperCase();
if (text.includes('\n')) {
item.children[0] = {
type: 'text',
value: text.replace(alertRegex, '').replace(/^\n+/, ''),
value: text.replace(reg, '').replace(/^\n+/, ''),
};
}

Expand All @@ -45,21 +58,21 @@ export const remarkAlert: Plugin<[], Root> = () => {
return item;
})

if (!!alertNode) {
if (!!alertType) {
node.data = {
hName: "div",
hProperties: {
class: `markdown-alert markdown-alert-${alertNode}`,
class: `markdown-alert markdown-alert-${alertType}`,
dir: 'auto'
},
}
child.unshift({
type: "paragraph",
children: [
getAlertIcon(alertNode as IconType),
getAlertIcon(alertType as IconType),
{
type: "text",
value: alertNode.toLocaleUpperCase()
value: title.replace(/^\//, ''),
}
],
data: {
Expand Down
42 changes: 42 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,46 @@ it('Alert `CAUTION` space and line break test case 1', async () => {
</div>`;
const htmlStr = remark().use(remarkParse).use(remarkAlert).use(remarkRehype).use(rehypeStringify).processSync(markdown).toString()
expect(htmlStr).toEqual(html);
});

// Legacy title

it('Alert `legacyTitle` test case 1', async () => {
const markdown = `> [!CAUTION/警告] \n> Urgent info that needs immediate user attention to avoid problems.`;
const html = `<div class="markdown-alert markdown-alert-caution" dir="auto">
<p class="markdown-alert-title" dir="auto"><svg class="octicon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="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"></path></svg>警告</p>
<p>Urgent info that needs immediate user attention to avoid problems.</p>
</div>`;
const htmlStr = remark().use(remarkParse).use(remarkAlert, { legacyTitle: true }).use(remarkRehype).use(rehypeStringify).processSync(markdown).toString()
expect(htmlStr).toEqual(html);
});

it('Alert `legacyTitle` test case 2', async () => {
const markdown = `> [!CAUTION警告] \n> Urgent info that needs immediate user attention to avoid problems.`;
const html = `<blockquote>
<p>[!CAUTION警告]
Urgent info that needs immediate user attention to avoid problems.</p>
</blockquote>`;
const htmlStr = remark().use(remarkParse).use(remarkAlert, { legacyTitle: true }).use(remarkRehype).use(rehypeStringify).processSync(markdown).toString();
expect(htmlStr).toEqual(html);
});

it('Alert `legacyTitle` test case 3', async () => {
const markdown = `> [!CAUTION警告] \n> Urgent info that needs immediate user attention to avoid problems.`;
const html = `<blockquote>
<p>[!CAUTION警告]
Urgent info that needs immediate user attention to avoid problems.</p>
</blockquote>`;
const htmlStr = remark().use(remarkParse).use(remarkAlert, { legacyTitle: false }).use(remarkRehype).use(rehypeStringify).processSync(markdown).toString();
expect(htmlStr).toEqual(html);
});

it('Alert `legacyTitle` test case 3', async () => {
const markdown = `> [!CAUTION/警告] \n> Urgent info that needs immediate user attention to avoid problems.`;
const html = `<blockquote>
<p>[!CAUTION/警告]
Urgent info that needs immediate user attention to avoid problems.</p>
</blockquote>`;
const htmlStr = remark().use(remarkParse).use(remarkAlert).use(remarkRehype).use(rehypeStringify).processSync(markdown).toString();
expect(htmlStr).toEqual(html);
});

0 comments on commit 70c5ffb

Please sign in to comment.