Replace all n/m dashes, curly quotes with their simpler equivalents

§ Quick Take

import { strict as assert } from "assert";
import unfancy from "string-unfancy";

// U+2019
const rightSingleQuote = "\u2019";


// works with encoded HTML:
assert.equal(unfancy("someone’s"), "someone's");

§ Idea

Convert typographically-correct characters (like curly quotes or m-dashes) to their basic counterparts (like apostrophes or hyphens).

It's the opposite of detergent and string-apostrophes.

It's used in ASCII-restricted places where encoding is too unwieldy, for example, image alt attribute values in email templates.



Caveat: if the input is not a string it will throw.

Function returns a string.

§ Example - Gulp streams

If you are using Gulp to build email templates, you can tap the stream, apply a function to it, then within that function, replace opens in a new tab all instances of alt="..." with their unfancied versions.

First, you need to require gulp-tap opens in a new tab and string-unfancy:

const tap = require("gulp-tap");
const unfancy = require("string-unfancy");

Then, tap your main build task's stream, probably towards the end of the pipeline:

.pipe(tap((file) => {
file.contents = Buffer.from(unfancy(file.contents.toString()))
.pipe(gulp.dest('dist')) // that's the final write happening, yours might be different

Then, declare a function somewhere within your gulpfile.js:

function unfancy(input) {
input = input.replace(/alt="[^"]*"/g, (el) => {
return unfancy(el);
return input;

As you see above, we're running an inline function opens in a new tab upon all regex-matched characters.

And that's it! All image alt attributes will lose their HTML encoding and will have their fancy special characters converted to simple ASCII letter equivalents.

§ Can we use lodash.deburr instead?

No. It won't even convert opens in a new tab a single m-dash! It's a different tool for a different purpose.

§ Licence

MIT opens in a new tab

Copyright © 2010–2020 Roy Revelt and other contributors

Related packages:

📦 detergent 5.11.7
Extracts, cleans and encodes text
📦 html-img-alt 1.4.64
Adds missing alt attributes to img tags. Non-parsing.
📦 string-remove-widows 1.6.17
Helps to prevent widow words in a text
📦 string-trim-spaces-only 2.8.23
Like String.trim() but you can choose granularly what to trim
📦 string-remove-thousand-separators 3.0.72
Detects and removes thousand separators (dot/comma/quote/space) from string-type digits
📦 string-split-by-whitespace 1.6.72
Split string into array by chunks of whitespace
📦 string-range-expander 1.11.11
Expands string index ranges within whitespace boundaries until letters are met