Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update string.js with changes mentioned below #248

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 17 additions & 56 deletions src/string.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,68 +11,29 @@
*/

const { pipe } = require('./functional');
const { size } = require('./stdtraits');
const { filter, map, count, foldl, join } = require('./sequence');
const { count, filter, foldl, join, map } = require('./sequence');

/**
* Helpers for working with strings.
*/

/**
* This is a helper for declaring multiline strings.
*
* ```
* const { strictEqual: assertIs } = require('assert');
* const { multiline } = require('ferrum');
*
* assertIs(
* multiline(`
* Foo
* Bar
* Baz
*
* Hello
*
* Bang
*
* `),
* 'Foo\nBar\nBaz\n\n Hello\n\nBang\n');
*
* assertIs(
* multiline(`Foo\nBar`),
* 'Foo\nBar');
* ```
*
* The function basically just takes a string and then
* strips the first & last lines if they are empty.
*
* In order to remove indentation, we determine the common
* whitespace prefix length (number of space 0x20 characters
* at the start of the line). This prefix is simply removed
* from each line...
*
* @function
*/
const multiline = (str) => {
// Discard the leading & trailing line
const lines = str.split('\n');
if (!str.trim()) return ''; // Handle empty or whitespace-only strings early

// Strip the first and the last line
if (lines[0].match(/^\s*$/)) {
lines.shift();
}
if (size(lines) > 0 && lines[size(lines) - 1].match(/^\s*$/)) {
lines.pop();
}
const lines = str.trim().split('\n'); // Use trim to avoid shift/pop

// Find the prefix length
const prefixLen = pipe(
lines,
filter((l) => !l.match(/^\s*$/)), // Disregarding empty lines
map((l) => l.match(/^ */)[0]), // Extract prefixes
map(count), // calculate length
foldl(Infinity, (a, b) => Math.min(a, b)),
); // minimum
filter(l => l.trim()), // Ignore empty lines
map(l => l.match(/^ */)[0].length), // Calculate prefix lengths
foldl(Infinity, Math.min) // Find minimum prefix length
);

return pipe(
lines,
map(l => l.slice(prefixLen)), // Remove the common prefix
join('\n')
);
};

module.exports = { multiline };


return pipe(
lines,
Expand Down