simov/slugify

How to remove `<` and `>` characters

theetrain opened this issue · 5 comments

Thanks for maintaining slugify.

I want to strip < and > characters from strings, but for some reason they always convert to less and greater respectively. Is there a way to do this?

Here's my input, expected result, and actual result:

slugify('Hello <world>', {
    replacement: '',
    remove: /[=_'\-+,<>.()[\]]/g,
    lower: true,
    strict: true
  })

// expected: `helloworld`
// actual: `hellolessworldgreater`

Here is my workaround:

slugify('Hello <world>'.replace(/[<>]/g, ''), {
    replacement: '',
    remove: /[=_'\-+,<>.()[\]]/g,
    lower: true,
    strict: true
  })

// output: `helloworld`
simov commented

Maybe you can use the extend method to override the defaults as {'<':'', '>':''}.

Trott commented

I'm curious about your use case. There are a lot of options but what is best may depend on what you're trying to do. (To give an extreme example, if you want to get rid of all characters that aren't in the Latin alphabet, you don't need slugify at all.)

slugify has a lot of "magic" characters beyond < and >:

  "$": "dollar",
  "%": "percent",
  "&": "and",
  "<": "less",
  ">": "greater",
  "|": "or",
  "¢": "cent",
  "£": "pound",
  "¤": "currency",
  "¥": "yen",
  "©": "(c)",

If you're looking to avoid all of those, you might consider choosing slug instead of slugify as it does not have any of that kind of stuff.

const slug = require('slug')
console.log(slug('Hello <world>')) // hello-world

If sticking with slugify makes sense, then there are a few options. extend() is probably the best:

const slugify = require('slugify')
slugify.extend({'<': '', '>': ''})
console.log(slugify('Hello <world>')) // Hello-world

@Trott thanks for the help, I think I misunderstood how to use extend() but I got it now.

My use case is to automatically create safe and legible user handles based on a name such as "Super Company©" becoming super-company, and that also becomes an email handle such has supercompanyguest@email.com, which means I'd have to employ two slug rules; one for the handle, and one for the email.

Trott commented

@theetrain In that case, you might want to use slug instead of slugify. Assuming you want only Latin alphabet characters, by default slug will only produce those. slugify will preserve many special characters. Given the input 'We Got Symbols Like ~!@*()_+', slugify will output 'We-Got-Symbols-Like-~!@*()_+' by default, while slug will output 'we-got-symbols-like' by default.

I also probably wouldn't use two slug rules. Unless there's an important reason, I'd suggest using slug() to create the user handle, and then using String.prototype.replaceAll() create the email handle.

const slug = require('slug')

function makeHandles(name) {
  const userHandle = slug(name)
  const emailHandle = userHandle.replaceAll('-', '')
  return ({ userHandle, emailHandle })
}

console.log(makeHandles('John Doe'))
console.log(makeHandles('Super Company©'))
console.log(makeHandles('Super Company™'))
console.log(makeHandles('We Got Symbols Like ~!@*()_+'))

Output:

{ userHandle: 'john-doe', emailHandle: 'johndoe' }
{ userHandle: 'super-company', emailHandle: 'supercompany' }
{ userHandle: 'super-company', emailHandle: 'supercompany' }
{ userHandle: 'we-got-symbols-like', emailHandle: 'wegotsymbolslike' }
Trott commented

(Closing because I think you have your answer, but if not, feel free to re-open and/or comment.)