Installation
Quick Take
Idea
As you know, straight apostrophes are not always typographically-correct: John's
should be John’s
, with right single quote instead of apostrophe.
This program converts all cases of single and double apostrophes, plus primes.
Sources used in rules logic and unit tests:
- Oxford A-Z of Grammar and Punctuation 2nd Ed., 2009, ISBN 978-0199564675
- Butterick’s Practical Typography 2nd Ed., “Apostrophes” chapter
API — convertAll()
The main function convertAll()
is imported like this:
It’s a function which takes two input arguments:
Input argument | Type | Obligatory | Description |
---|---|---|---|
str Type: String Obligatory: yes | |||
str | String | yes | String to process. |
opts Type: Plain object Obligatory: no | |||
opts | Plain object | no | Optional Options Object. |
The Optional Options Object has the following shape:
Key | Type | Default | Obligatory | Description |
---|---|---|---|---|
convertEntities Type: Boolean Default: false Obligatory: no | ||||
convertEntities | Boolean | false | no | Should we HTML-encode the characters? |
convertApostrophes Type: Boolean Default: true Obligatory: no | ||||
convertApostrophes | Boolean | true | no | A killswitch. If it’s false , the program does nothing. |
Here are all defaults in one place for copying:
The function will return a plain object:
Returned object’s key | Type | Description |
---|---|---|
result Type: String | ||
result | String | Processed string, with all ranges applied |
ranges Type: Ranges: null or array of arrays | ||
ranges | Ranges: null or array of arrays | Ranges that were gathered and applied to produce the result |
API — convertOne()
The main function convertOne()
is imported like this:
It’s a function which takes two input arguments:
Input argument | Type | Obligatory | Description |
---|---|---|---|
str Type: String Obligatory: yes | |||
str | String | yes | A string to process |
opts Type: Plain object Obligatory: yes | |||
opts | Plain object | yes | Obligatory Options Object. |
The Obligatory Options Object has the following shape:
Key | Type | Default | Obligatory | Description |
---|---|---|---|---|
from Type: Natural number, string index Default: undefined Obligatory: yes | ||||
from | Natural number, string index | undefined | yes | Where does the character we need to process start in a given index? |
to Type: Natural number, string index Default: from + 1 Obligatory: no | ||||
to | Natural number, string index | from + 1 | no | Where does the character we need to process end in a given index? |
value Type: String Default: undefined Obligatory: no | ||||
value | String | undefined | no | Override the value of a string value, present at str.slice(from, to) |
convertEntities Type: Boolean Default: false Obligatory: no | ||||
convertEntities | Boolean | false | no | Should we HTML-encode the characters? |
convertApostrophes Type: Boolean Default: true Obligatory: no | ||||
convertApostrophes | Boolean | true | no | Killswitch. If it’s false , the program does nothing. |
offsetBy Type: Function Default: undefined Obligatory: no | ||||
offsetBy | Function | undefined | no | If you provide a function, it will be called with a natural number input argument, meaning how much characters to skip next. |
opts.from
is obligatory — that’s how you tell the program which characters to process.
The function returns ranges: an array of range arrays or null
. Later you can use them in ranges-apply
to process a string using those ranges (in other words, “to apply those ranges”).
opts.offsetBy
Offset is needed to bypass characters we already fixed — it happens for example, with nested quotes — we’d fix many in one go, and we need to skip the further processing; otherwise, those characters would get processed multiple times.
For example, here’s how the convertAll()
index is bumped using offsetBy
, in a callback-fashion:
function convertAll(str, opts) {
let ranges = [];
const preppedOpts = Object.assign({}, opts);
// loop through the given string
for (let i = 0, len = str.length; i < len; i++) {
// define starting index:
preppedOpts.from = i;
// offset function:
preppedOpts.offsetBy = (idx) => {
i = i + idx;
};
// calculate the result:
const res = convertOne(str, preppedOpts);
if (Array.isArray(res) && res.length) {
ranges = ranges.concat(res);
}
}
return {
result: rangesApply(str, ranges),
ranges,
};
}
The inner function convertOne()
bumps outer’s convertAll()
index.
opts.value
Consider string Your's
with HTML-escaped apostrophe:
Your's
There are various other cases of apostrophes and quotes where we have a sentence, and all apostrophes/quotes are there, and we know where just different character(s) represent them. Values are not '
and "
.
We are not going to code up all those cases!
Instead, use convertOne()
, process each “symbol” one-by-one and instruct the program from where (from
) to where (to
) is a particular character (value
).
For example,
import { convertOne, convertAll } from "string-apostrophes";
const res = convertOne(`test's`, {
from: 4,
to: 10,
value: "'", // <-------- we insist to program that it's an apostrophe between indexes 4 and 10
convertEntities: 0,
});
console.log(JSON.stringify(res, null, 0));
// => [[4, 10, "’"]]
In the example above, the program evaluates surroundings of '
as if it was a “normal” apostrophe and suggests a replacement.
In practice, that’s how detergent
uses this package.
API — defaults
You can import defaults
:
It's a plain object:
The main function calculates the options to be used by merging the options you passed with these defaults.
These defaults are appllicable for both convertOne()
and convertAll()
functions.
API — version
You can import version
:
Compared to Others
📦 This program, string-apostrophes | straight-to-curly-quotes | smartquotes | typographic-quotes | |
---|---|---|---|---|
Returns processed string | ||||
Returns processed string | ✅ | ✅ | ✅ | ✅ |
Additionally returns index ranges allowing to compose string operations | ||||
Additionally returns index ranges allowing to compose string operations | ✅ | ❌ | ❌ | ❌ |
Replaces quotes in DOM, on a web page, where you put a script in | ||||
Replaces quotes in DOM, on a web page, where you put a script in | ❌ | ❌ | ✅ | ❌ |
Not regex-based | ||||
Not regex-based | ✅ | ❌ | ❌ | ❌ |
Can output HTML-encoded content upon request | ||||
Can output HTML-encoded content upon request | ✅ | ❌ | ❌ | ❌ |
A killswitch to bypass processing | ||||
A killswitch to bypass processing | ✅ | ❌ | ❌ | ❌ |
Allows to process any part of string as if it were single or double quote | ||||
Allows to process any part of string as if it were single or double quote | ✅ | ❌ | ❌ | ❌ |
Serves other languages besides English | ||||
Serves other languages besides English | ❌ | ❌ | ❌ | ✅ |