Skip to content

richie-south/javascript-rich-string-parser

Repository files navigation

rich-string-parser

Finds rich text in strings, ex: links, mentions, emails, your own parser, in an non overlapping way to prevent dubble matching.

Example

import {richStringParser} from 'rich-string-parser'
import {emailParser} from 'rich-string-parser/lib/parsers/email-parser'
import {linkParser} from 'rich-string-parser/lib/parsers/link-parser'

const result = richStringParser(
  'https://www.typescriptlang.org/ text example@example.com more text',
  [emailParser(), linkParser()],
)

// log result
/* [
  {
    type: 'LinkParser',
    match: 'https://www.typescriptlang.org/',
    index: 0,
    subIndex: 0
  },
  ' text ',
  {
    type: 'EmailParser',
    match: 'example@example.com',
    index: 37,
    subIndex: 37
  },
  ' more text'
] */

Parser result

required parameters

{
  "type": "", // uniq for each parser
  "match": "", // result from parser
  "index": 0, // where match is found based on whole string
  "subIndex": 0 // where match is found based on parsed substring
}

Built in parsers

MentionParser

Matches on @(number|string), @(9712|John)

Result:

Without mention type:

{
  type: 'MentionParser',
  match: '@(9712|John)',
  id: 9712,
  name: 'John',
  index: 0,
  subIndex: 0,
  target: undefined
}

With mention type provided:

{
  type: 'MentionParser',
  match: '@(0|Testgroupchatroom|group)',
  id: 0,
  name: 'Testgroupchatroom',
  index: 0,
  subIndex: 0,
  target: 'group'
}

EmailParser

Matches on example@example.com,

Result:

{
  type: 'EmailParser',
  match: 'example@example.com',
  index: 0,
  subIndex: 0,
}

LinkParser

Matches on https://example.com,

Result:

{
  type: 'LinkParser',
  match: 'https://example.com',
  index: 0,
  subIndex: 0,
}

Create your own parser

Create a function that retrurns a Parser interface with a custom string in generic type, example Parser<'HashtagParser'>. Implemente the required return object function parse.

Example

function hashtagParser(): Parser<'HashtagParser'> {
  const regex: RegExp = /(#[a-z\d-]+)/gi

  return {
    parse: (text, index) => {
      const result = regex.exec(text)
      if (result === null) return null

      return {
        type: 'HashtagParser',
        match: result[0],
        index: index + result.index, // don't forget to add the global index
        subIndex: result.index,
      }
    },
  }
}