time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

pad.js (4824B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 'use strict';
     20 
     21 // MODULES //
     22 
     23 var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive;
     24 var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
     25 var repeat = require( './../../repeat' );
     26 var format = require( './../../format' );
     27 var floor = require( '@stdlib/math/base/special/floor' );
     28 var ceil = require( '@stdlib/math/base/special/ceil' );
     29 var lpad = require( './../../left-pad' );
     30 var rpad = require( './../../right-pad' );
     31 var abs = require( '@stdlib/math/base/special/abs' );
     32 var FLOAT64_MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' );
     33 var validate = require( './validate.js' );
     34 
     35 
     36 // MAIN //
     37 
     38 /**
     39 * Pads a string such that the padded string has a length of `len`.
     40 *
     41 * @param {string} str - string to pad
     42 * @param {NonNegativeInteger} len - string length
     43 * @param {Options} [options] - function options
     44 * @param {string} [options.lpad=''] - string used to left pad
     45 * @param {string} [options.rpad=' '] - string used to right pad
     46 * @param {boolean} [options.centerRight=false] - boolean indicating whether to center right in the event of a tie
     47 * @throws {TypeError} first argument must be a string
     48 * @throws {TypeError} second argument must be a nonnegative integer
     49 * @throws {TypeError} options argument must be an object
     50 * @throws {TypeError} must provide valid options
     51 * @throws {RangeError} at least one padding must have a length greater than `0`
     52 * @returns {string} padded string
     53 *
     54 * @example
     55 * var str = pad( 'a', 5 );
     56 * // returns 'a    '
     57 *
     58 * @example
     59 * var str = pad( 'a', 10, {
     60 *     'lpad': 'b'
     61 * });
     62 * // returns 'bbbbbbbbba'
     63 *
     64 * @example
     65 * var str = pad( 'a', 12, {
     66 *     'rpad': 'b'
     67 * });
     68 * // returns 'abbbbbbbbbbb'
     69 *
     70 * @example
     71 * var opts = {
     72 *     'lpad': 'a',
     73 *     'rpad': 'c'
     74 * };
     75 * var str = pad( 'b', 10, opts );
     76 * // returns 'aaaabccccc'
     77 *
     78 * @example
     79 * var opts = {
     80 *     'lpad': 'a',
     81 *     'rpad': 'c',
     82 *     'centerRight': true
     83 * };
     84 * var str = pad( 'b', 10, opts );
     85 * // returns 'aaaaabcccc'
     86 */
     87 function pad( str, len, options ) {
     88 	var nright;
     89 	var nleft;
     90 	var isodd;
     91 	var right;
     92 	var left;
     93 	var opts;
     94 	var err;
     95 	var tmp;
     96 	var n;
     97 	if ( !isString( str ) ) {
     98 		throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', str ) );
     99 	}
    100 	if ( !isNonNegativeInteger( len ) ) {
    101 		throw new TypeError( format( 'invalid argument. Second argument must be a nonnegative integer. Value: `%s`.', len ) );
    102 	}
    103 	if ( len > FLOAT64_MAX_SAFE_INTEGER ) {
    104 		throw new RangeError( format( 'invalid argument. Output string length exceeds maximum allowed string length. Value: `%u`.', len ) );
    105 	}
    106 	opts = {};
    107 	if ( arguments.length > 2 ) {
    108 		err = validate( opts, options );
    109 		if ( err ) {
    110 			throw err;
    111 		}
    112 	}
    113 	if ( opts.lpad && opts.rpad ) {
    114 		n = ( len-str.length ) / 2;
    115 		if ( n === 0 ) {
    116 			return str;
    117 		}
    118 		tmp = floor( n );
    119 		if ( tmp !== n ) {
    120 			isodd = true;
    121 		}
    122 		if ( n < 0 ) {
    123 			n = floor( abs( n ) );
    124 			nleft = n;
    125 			nright = str.length - n;
    126 
    127 			// If |len-str.length| is an odd number, take away an additional character from one side...
    128 			if ( isodd ) {
    129 				if ( opts.centerRight ) {
    130 					nright -= 1;
    131 				} else {
    132 					nleft += 1;
    133 				}
    134 			}
    135 			return str.substring( nleft, nright );
    136 		}
    137 		nleft = ceil( n / opts.lpad.length );
    138 		left = repeat( opts.lpad, nleft );
    139 
    140 		nright = ceil( n / opts.rpad.length );
    141 		right = repeat( opts.rpad, nright );
    142 
    143 		// If (len-str.length) is an odd number, give one side one extra character...
    144 		n = tmp;
    145 		nleft = n;
    146 		nright = n;
    147 		if ( isodd ) {
    148 			if ( opts.centerRight ) {
    149 				nleft += 1;
    150 			} else {
    151 				nright += 1;
    152 			}
    153 		}
    154 		left = left.substring( 0, nleft );
    155 		right = right.substring( 0, nright );
    156 		return left + str + right;
    157 	}
    158 	if ( opts.lpad ) {
    159 		tmp = lpad( str, len, opts.lpad );
    160 		return tmp.substring( tmp.length-len );
    161 	}
    162 	if ( opts.rpad ) {
    163 		return ( rpad( str, len, opts.rpad ) ).substring( 0, len );
    164 	}
    165 	if ( opts.rpad === void 0 ) {
    166 		return ( rpad( str, len, ' ' ) ).substring( 0, len );
    167 	}
    168 	throw new RangeError( format( 'invalid argument. At least one padding option must have a length greater than 0. Left padding: `%s`. Right padding: `%s`.', opts.lpad, opts.rpad ) );
    169 }
    170 
    171 
    172 // EXPORTS //
    173 
    174 module.exports = pad;