Skip to content

Latest commit

 

History

History

remark-ping

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

remark-ping Build Status Coverage Status

This plugin parses custom Markdown syntax such as @someone or @**nick with spaces** to create links such as /member/profile/someone to the corresponding user page if this user exists in your system.

Default Syntax

@username
@**nick with spaces**

AST (see mdast specification)

Ping (Parent) represents a reference to a user.

interface Ping <: Parent {
  type: "ping";
  url: "member profile url";
  username: "username";
}

rehype

This plugin is compatible with rehype. Ping mdast nodes will become HTML links pointing to a customizable target, usually used to link to a user profile.

@foo

gives:

<a href="/custom/link/foo/" rel="nofollow" class="ping ping-link">
  @<span class="ping-username">foo</span>
</a>

Pings are handled a bit differently if they are already inside of a link:

[@foo](http://example.com)

gives:

<a href="http://example.com">
  <span class="ping ping-in-link">
    @<span class="ping-username">foo</span>
  </span>
</a>

Installation

npm:

npm install remark-ping

Usage

Dependencies:

const unified = require('unified')
const remarkParse = require('remark-parse')
const stringify = require('rehype-stringify')
const remark2rehype = require('remark-rehype')

const remarkPing = require('remark-ping')

Usage:

unified()
  .use(remarkParse)
  .use(remarkPing, {
      pingUsername: (username) => true,
      userURL: (username) => `https://your.website.com/path/to/${username}`
  })
  .use(remark2rehype)
  .use(stringify)

as you can see, remark-ping takes two mandatory options :

  • pingUsername is a function taking username as parameter and returning true if the user exists or should be pinged
    • If you want to parse any username without checking whether they exist or (like GitHub does), use a function always returning true (() => true)
    • When pingUsername(username) doesn't return true, the ping syntax is simply ignored and no AST Ping node gets created for this username
  • userUrl is a function taking username as parameter and returning a path or URL to this user profile or member page

You can override the default parsing regexp, for example if you don't want to include @**username with space** by setting up the usernameRegex option:

  .use(remarkPing, {
      pingUsername: (username) => true,
      userURL: (username) => `https://your.website.com/path/to/${username}`,
      usernameRegex: /[\s'"(,:<]?@(\w+)/,
  })

Retrieving the usernames to ping

Once the Markdown has been processed by this plugin, the output vfile contains a ping array in the data property.

This array contains every username that should be ping, should you want your backend to generate notifications for these.

unified()
  .use(reParse)
  .use(plugin, {pingUsername, userURL})
  .use(remark2rehype)
  .use(rehypeStringify)
  .process('@foo @bar')
  .then((vfile) => {
    console.log(vfile.data.ping.length === 2) // true
    console.log(vfile.data.ping[0] === 'foo') // true
    console.log(vfile.data.ping[1] === 'bar') // true
    return vfile
  })

License

MIT © Zeste de Savoir