/** * @author Titus Wormer * @copyright 2015 Titus Wormer * @license MIT * @module remark:parse:util:remove-indentation * @fileoverview Remove indentation. */ 'use strict'; /* Dependencies. */ var trim = require('trim'); var repeat = require('repeat-string'); var getIndent = require('./get-indentation'); /* Expose. */ module.exports = indentation; /* Characters. */ var C_SPACE = ' '; var C_NEWLINE = '\n'; var C_TAB = '\t'; /** * Remove the minimum indent from every line in `value`. * Supports both tab, spaced, and mixed indentation (as * well as possible). * * @example * removeIndentation(' foo'); // 'foo' * removeIndentation(' foo', 2); // ' foo' * removeIndentation('\tfoo', 2); // ' foo' * removeIndentation(' foo\n bar'); // ' foo\n bar' * * @param {string} value - Value to trim. * @param {number?} [maximum] - Maximum indentation * to remove. * @return {string} - Unindented `value`. */ function indentation(value, maximum) { var values = value.split(C_NEWLINE); var position = values.length + 1; var minIndent = Infinity; var matrix = []; var index; var indentation; var stops; var padding; values.unshift(repeat(C_SPACE, maximum) + '!'); while (position--) { indentation = getIndent(values[position]); matrix[position] = indentation.stops; if (trim(values[position]).length === 0) { continue; } if (indentation.indent) { if (indentation.indent > 0 && indentation.indent < minIndent) { minIndent = indentation.indent; } } else { minIndent = Infinity; break; } } if (minIndent !== Infinity) { position = values.length; while (position--) { stops = matrix[position]; index = minIndent; while (index && !(index in stops)) { index--; } if ( trim(values[position]).length !== 0 && minIndent && index !== minIndent ) { padding = C_TAB; } else { padding = ''; } values[position] = padding + values[position].slice( index in stops ? stops[index] + 1 : 0 ); } } values.shift(); return values.join(C_NEWLINE); }