Skip to content

Commit

Permalink
feat: support for :link directive to automatically add npm icon via…
Browse files Browse the repository at this point in the history
… `style=npm` & properly embed the icon
  • Loading branch information
lin-stephanie committed Nov 24, 2024
1 parent d565bbd commit 19a6fc4
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 51 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![jsDocs.io][jsdocs-src]][jsdocs-href]

A [remark](https://github.com/remarkjs/remark) plugin built on remark-directive, providing predefined directives for image captions, video embedding, styled GitHub links, badge markers, and more.
A [remark](https://github.com/remarkjs/remark) plugin built on remark-directive, providing predefined directives for image captions, video embedding, styled GitHub links, badges, and more.

## Usage

Expand Down
52 changes: 35 additions & 17 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
githubUsernameRegex,
linkStyle,
tabOrgRegex,
iconSvgPath,
validBadges,
videoPlatforms,
imageRegex,
Expand All @@ -29,13 +30,17 @@ import type { Plugin } from 'unified'
import type { UserOptions } from './types.js'

/**
* A remark plugin for supporting regular
* {@link https://github.com/remarkjs/remark-directive?tab=readme-ov-file#use remark-directive usage},
* along with the following predefined directives:
* - `::video`: enable consistent video embedding.
* - `:link`: link to GitHub users/repositories or other external URLs in Markdown/MDX.
* (Inspired by: https://github.com/antfu/markdown-it-magic-link)
* - `:badge`/`:badge-*`: customizable badge-like markers.
* A remark plugin based on {@link https://github.com/remarkjs/remark-directive remark-directive},
* offering the following predefined directives:
*
* - `:::image-figure`: creates a block with an image, figcaption, and optional styling, much like a figure in academic papers.
* - `:::image-a`: wraps an image inside a link, making it clickable.
* - `:::image-[validTagsForImg]`: wraps an image inside any valid HTML tags.
* - `::video`: allows for consistent video embedding across different platforms (youtobe, bilibili, vimeo).
* - `:link`: creates styled links to GitHub repositories, users/organizations, or any external URLs. (Inspired by: {@link https://github.com/antfu/markdown-it-magic-link markdown-it-magic-link})
* - `:badge`/`:badge-*`: customizable badges to improve document visuals.
*
* @remark Supports regular {@link https://github.com/remarkjs/remark-directive?tab=readme-ov-file#use remark-directive usage}.
*
* @param options
* Optional options to configure the output.
Expand All @@ -44,7 +49,6 @@ import type { UserOptions } from './types.js'
*/

const remarkDirectiveSugar: Plugin<[UserOptions?], Root> = (options) => {
// get config
const config = getConfig(options)
const { classPrefix, image, link, video, badge } = config

Expand Down Expand Up @@ -126,13 +130,10 @@ const remarkDirectiveSugar: Plugin<[UserOptions?], Root> = (options) => {
data.hName = 'a'
const defaultAttributes = { target: '_blank' }
data.hProperties = { ...defaultAttributes, ...attributes }
} else if (imageRegex.test(node.name)) {
} else {
/* image-* */
const match = node.name.match(imageRegex)
if (match && validTagsForImg.has(match[1])) {
/* const data = node.data || (node.data = {})
const attributes = node.attributes || {} */

data.hName = match[1]
data.hProperties = attributes
} else {
Expand Down Expand Up @@ -329,25 +330,42 @@ const remarkDirectiveSugar: Plugin<[UserOptions?], Root> = (options) => {
value: resolvedText,
},
]
} else if (resolvedStyle === 'github') {
} else if (
resolvedStyle === 'github' ||
resolvedStyle === 'npm'
) {
data.hName = 'span'
data.hProperties = {
style: 'white-space: nowrap',
}
data.hChildren = [
{
type: 'element',
tagName: 'span',
tagName: 'svg',
properties: {
class: 'i-carbon-logo-github',
xmlns: 'http://www.w3.org/2000/svg',
width: '1.2em',
height: '1.2em',
viewBox: '0 0 32 32',
ariaHidden: 'true',
},
children: [],
children: [
{
type: 'element',
tagName: 'path',
properties: {
fill: 'currentColor',
d: iconSvgPath[resolvedStyle],
},
children: [],
},
],
},
{
type: 'element',
tagName: 'a',
properties: {
class: `${classPrefix}-link-github`,
class: `${classPrefix}-link-${resolvedStyle}`,
href: resolvedLink,
},
children: [{ type: 'text', value: resolvedText }],
Expand Down
10 changes: 8 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const githubUsernameRegex = /^@[a-zA-Z\d](?!.*--)[\w-]{0,37}[a-zA-Z\d]$/
export const githubRepoRegex =
/^@?([a-zA-Z\d](?!.*--)[\w-]{0,37}[a-zA-Z\d])\/.*$/

export const linkStyle = ['square', 'rounded', 'github'] as const
export const linkStyle = ['square', 'rounded', 'github', 'npm'] as const

export const tabOrgRegex = /^org-(\w+)$/

Expand All @@ -50,6 +50,12 @@ export const githubTab = [
'org-people',
]

export const iconSvgPath = {
github:
'M16 2a14 14 0 0 0-4.43 27.28c.7.13 1-.3 1-.67v-2.38c-3.89.84-4.71-1.88-4.71-1.88a3.7 3.7 0 0 0-1.62-2.05c-1.27-.86.1-.85.1-.85a2.94 2.94 0 0 1 2.14 1.45a3 3 0 0 0 4.08 1.16a2.93 2.93 0 0 1 .88-1.87c-3.1-.36-6.37-1.56-6.37-6.92a5.4 5.4 0 0 1 1.44-3.76a5 5 0 0 1 .14-3.7s1.17-.38 3.85 1.43a13.3 13.3 0 0 1 7 0c2.67-1.81 3.84-1.43 3.84-1.43a5 5 0 0 1 .14 3.7a5.4 5.4 0 0 1 1.44 3.76c0 5.38-3.27 6.56-6.39 6.91a3.33 3.33 0 0 1 .95 2.59v3.84c0 .46.25.81 1 .67A14 14 0 0 0 16 2',
npm: 'M4 28V4h24v24zM8.5 8.5v15H16v-12h4.5v12h3v-15z',
}

/* badge */
export const badgesPreset: BadgesPreset = {
a: { text: 'ARTICLE', color: '#e9d66b|#fbf8cc' },
Expand All @@ -65,7 +71,7 @@ export const badgeRegex = /^badge-(.*)/

export const validBadges = new Set(Object.keys(badgesPreset))

/* default */
/* Default Config */
export const configOptions: ConfigOptions = {
classPrefix: 'directive-sugar',
image: {
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/badge/input.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The `:badge` directive allows you to add customizable markers to improve document visuals.

There are built-in markers that automatically apply predefined labels and colors based on the configuration:
There are built-in badges that automatically apply predefined labels and colors based on the configuration:

- `badge-a`: :badge-a
- `badge-v`: :badge-v
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/badge/output.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
improve document visuals.
</p>
<p>
There are built-in markers that automatically apply predefined labels and
There are built-in badges that automatically apply predefined labels and
colors based on the configuration:
</p>
<ul>
Expand Down
6 changes: 5 additions & 1 deletion test/fixtures/link/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

:link{#lin-stephanie/astro-antfustyle-theme style=github}

**Example 10**: `:link[send a little encouragement my way ❤️]{link=https://github.com/sponsors/lin-stephanie imageUrl=https://github.githubassets.com/assets/mona-e50f14d05e4b.png}` fully customizes a link.
**Example 10**: `:link[remark-directive-sugar]{link=https://www.npmjs.com/package/remark-directive-sugar style=npm}` creates a npm-styled link like:

:link[remark-directive-sugar]{link=https://www.npmjs.com/package/remark-directive-sugar style=npm}

**Example 11**: `:link[send a little encouragement my way ❤️]{link=https://github.com/sponsors/lin-stephanie imageUrl=https://github.githubassets.com/assets/mona-e50f14d05e4b.png}` fully customizes a link.

Thanks for making it this far! Writing is no easy task --- maybe you'd like to :link[send a little encouragement my way ❤️]{link=https://github.com/sponsors/lin-stephanie imageUrl=https://github.githubassets.com/assets/mona-e50f14d05e4b.png}.
63 changes: 35 additions & 28 deletions test/fixtures/link/output.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<p>
<strong>Example 1</strong>: <code>:link[Astro]{#withastro/astro}</code> or
<code>:link[Astro]{id=withastro/astro}</code> creates a link to
<a
class="sugar-link-square"
href="https://github.com/withastro/astro"
<a class="sugar-link-square" href="https://github.com/withastro/astro"
><span
class="sugar-link-image"
style="background-image: url(https://github.com/withastro.png)"
Expand All @@ -16,9 +14,7 @@
<strong>Example 2</strong>:
<code>:link[Stephanie Lin]{#@lin-stephanie}</code> links to the GitHub profile
of the project maintainer,
<a
class="sugar-link-rounded"
href="https://github.com/lin-stephanie?tab="
<a class="sugar-link-rounded" href="https://github.com/lin-stephanie?tab="
><span
class="sugar-link-image"
style="background-image: url(https://github.com/lin-stephanie.png)"
Expand All @@ -29,9 +25,7 @@
<p>
<strong>Example 3</strong>: <code>:link[Vite]{id=@vitejs}</code> links to the
GitHub profile of the
<a
class="sugar-link-rounded"
href="https://github.com/vitejs?tab="
<a class="sugar-link-rounded" href="https://github.com/vitejs?tab="
><span
class="sugar-link-image"
style="background-image: url(https://github.com/vitejs.png)"
Expand Down Expand Up @@ -61,9 +55,7 @@
<p>
<strong>Example 5</strong>: <code>:link{#@vitejs tab=org-people}</code> links
directly to the people section of a GitHub organization, like
<a
class="sugar-link-rounded"
href="https://github.com/orgs/vitejs/people"
<a class="sugar-link-rounded" href="https://github.com/orgs/vitejs/people"
><span
class="sugar-link-image"
style="background-image: url(https://github.com/vitejs.png)"
Expand All @@ -80,9 +72,7 @@
<strong>Example 6</strong>:
<code>:link[Google]{link=https://www.google.com/}</code> creates an external
link to the
<a
class="sugar-link-square"
href="https://www.google.com/"
<a class="sugar-link-square" href="https://www.google.com/"
><span
class="sugar-link-image"
style="background-image: url(https://favicon.yandex.net/favicon/www.google.com)"
Expand All @@ -94,9 +84,7 @@
<strong>Example 7</strong>:
<code>:link[Astro]{#withastro/astro style=rounded}</code> creates a rounded
button like
<a
class="sugar-link-rounded"
href="https://github.com/withastro/astro"
<a class="sugar-link-rounded" href="https://github.com/withastro/astro"
><span
class="sugar-link-image"
style="background-image: url(https://github.com/withastro.png)"
Expand All @@ -107,9 +95,7 @@
<p>
<strong>Example 8</strong>:
<code>:link[Vite]{id=@vitejs style=square}</code> creates a square button like
<a
class="sugar-link-square"
href="https://github.com/vitejs?tab="
<a class="sugar-link-square" href="https://github.com/vitejs?tab="
><span
class="sugar-link-image"
style="background-image: url(https://github.com/vitejs.png)"
Expand All @@ -119,13 +105,22 @@
</p>
<p>
<strong>Example 9</strong>:
<code>:link{#lin-stephanie/astro-antfustyle-theme style=github}</code> creates
a GitHub-styled link like:
<code>:link{#lin-stephanie/astro-antfustyle-theme style=github}</code> creates a GitHub-styled link like:
</p>
<p>
<span style="white-space: nowrap"
><span class="i-carbon-logo-github"></span
><a
><svg
xmlns="http://www.w3.org/2000/svg"
width="1.2em"
height="1.2em"
viewBox="0 0 32 32"
aria-hidden="true"
>
<path
fill="currentColor"
d="M16 2a14 14 0 0 0-4.43 27.28c.7.13 1-.3 1-.67v-2.38c-3.89.84-4.71-1.88-4.71-1.88a3.7 3.7 0 0 0-1.62-2.05c-1.27-.86.1-.85.1-.85a2.94 2.94 0 0 1 2.14 1.45a3 3 0 0 0 4.08 1.16a2.93 2.93 0 0 1 .88-1.87c-3.1-.36-6.37-1.56-6.37-6.92a5.4 5.4 0 0 1 1.44-3.76a5 5 0 0 1 .14-3.7s1.17-.38 3.85 1.43a13.3 13.3 0 0 1 7 0c2.67-1.81 3.84-1.43 3.84-1.43a5 5 0 0 1 .14 3.7a5.4 5.4 0 0 1 1.44 3.76c0 5.38-3.27 6.56-6.39 6.91a3.33 3.33 0 0 1 .95 2.59v3.84c0 .46.25.81 1 .67A14 14 0 0 0 16 2"
></path>
</svg><a
class="sugar-link-github"
href="https://github.com/lin-stephanie/astro-antfustyle-theme"
>lin-stephanie/astro-antfustyle-theme</a
Expand All @@ -134,6 +129,20 @@
</p>
<p>
<strong>Example 10</strong>:
<code>:link[remark-directive-sugar]{link=https://www.npmjs.com/package/remark-directive-sugar style=npm}</code>
creates a npm-styled link like:
</p>
<p>
<span style="white-space: nowrap">
<svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 32 32" aria-hidden="true">
<path fill="currentColor" d="M4 28V4h24v24zM8.5 8.5v15H16v-12h4.5v12h3v-15z"></path>
</svg><a class="sugar-link-npm" href="https://www.npmjs.com/package/remark-directive-sugar"
>remark-directive-sugar
</a>
</span>
</p>
<p>
<strong>Example 11</strong>:
<code
>:link[send a little encouragement my way
❤️]{link=https://github.com/sponsors/lin-stephanie
Expand All @@ -143,9 +152,7 @@
</p>
<p>
Thanks for making it this far! Writing is no easy task --- maybe you'd like to
<a
class="sugar-link-square"
href="https://github.com/sponsors/lin-stephanie"
<a class="sugar-link-square" href="https://github.com/sponsors/lin-stephanie"
><span
class="sugar-link-image"
style="background-image: url(https://github.githubassets.com/assets/mona-e50f14d05e4b.png)"
Expand Down

0 comments on commit 19a6fc4

Please sign in to comment.