§ Quick Take

import { strict as assert } from "assert";
import { extract } from "string-extract-class-names";

// extracts classes and/or id's
const str = "div#brambles.nushes#croodles";
const { res, ranges } = extract(str);
assert.deepEqual(res, [
  "#brambles",
  ".nushes",
  "#croodles",
]);
assert.deepEqual(ranges, [
  [3, 12],
  [12, 19],
  [19, 28],
]);

// `res` can be produced by slicing `ranges`:
assert.deepEqual(
  res,
  ranges.map(([from, to]) => str.slice(from, to))
);

§ Examples

§ API

extract(str)

In other words, it's a function which takes one input, a string.

§ API - Input

Input argumentTypeObligatory?Description
inputStringStringyesA string to process

§ API - Output

It returns a plain object.

Key in a returned objectKey value's typeDescription
resStringArray of extracted classes/id's
rangesArray of one or more arrays or null (compatible with Ranges libraries)Locations of extracted strings

for example, here's how the output could look like:

{
res: "Lorem ipsum dolor sit amet",
ranges: [
[21, 27, " "]
],
log: {
timeTakenInMiliseconds: 42
},
whatWasDone: {
removeWidows: true,
convertEntities: false
}
}

§ The Use

We use string-extract-class-names to extract all the CSS class and id names from HTML/CSS in the library email-comb which detects and deletes the unused CSS styles.

§ Bracket notation

Normally, classes or id's in css include dots/hashes, for example, div.first-class.second-class. Those dots and hashes end up covered by indexes under ranges key:

import { extract } from "string-extract-class-names";
const res = extract("div.first-class.second-class");
console.log(res);
// => {
// res: [".first-class", ".second-class"],
// ranges: [
// [3, 15],
// [15, 28],
// ],
// }

Dots above are at indexes 3 and 15.

However, this program also supports the bracket notation - instead of td.croodles one can say td[class="croodles"]. It used to be the way how email templates were setting CSS because of Yahoo opens in a new tab. Not any more, but this program still supports bracket notation:

import { extract } from "string-extract-class-names";
const str = `td[id=" abc-def "]`
const res = extract(str);
console.log(res);
// => {
// res: ["#abc-def"],
// ranges: [[8, 15]],
// }

// however

console.log(str.slice(8, 15));
// => "abc-def"
// notice there's no hash if you slice the source
// because it didn't exist at the first place

In "normal" CSS where dots and hashes do exist, the res output will match what could be mapped against String.prototype.slice() (as seen in examples):

assert.deepEqual(
res,
ranges.map(([from, to]) => str.slice(from, to))
);

§ Changelog

See it in the monorepo opens in a new tab, on GitHub.

§ Contributing

To report bugs or request features or assistance, raise an issue on GitHub opens in a new tab.

Any code contributions welcome! All Pull Requests will be dealt promptly.

§ Licence

MIT opens in a new tab

Copyright © 2010–2021 Roy Revelt and other contributors

Related packages:

📦 detergent 7.0.14
Extracts, cleans and encodes text
📦 string-apostrophes 1.4.14
Comprehensive, HTML-entities-aware tool to typographically-correct the apostrophes and single/double quotes
📦 string-collapse-white-space 9.0.14
Replace chunks of whitespace with a single spaces
📦 string-extract-sass-vars 2.0.14
Parse SASS variables file into a plain object of CSS key-value pairs
📦 string-convert-indexes 4.0.14
Convert between native JS string character indexes and grapheme-count-based indexes
📦 string-remove-widows 2.0.14
Helps to prevent widow words in a text
📦 string-remove-duplicate-heads-tails 5.0.14
Detect and (recursively) remove head and tail wrappings around the input string