-
Notifications
You must be signed in to change notification settings - Fork 1
/
foldline.js
100 lines (82 loc) · 2.36 KB
/
foldline.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const CRLF = '\r\n'
const SP = ' '
/**
* Maximum line length (excluding <CR><LF>)
* There are two limits that RFC 5322 places on the number of
* characters in a line. Each line of characters MUST be
* no more than 998 characters, and SHOULD be no more
* than 78 characters, excluding the <CR><LF>.
* @type {Number}
* @constant
*/
const MAX_LINE_LENGTH = 998
/**
* Default maximum line length (excluding <CR><LF>)
* @type {Number}
* @constant
*/
const DEFAULT_LINE_LENGTH = 78
/**
* Minimum `maxLength` that can be used
* @type {Number}
* @constant
*/
const MIN_LINE_LENGTH = 2
/**
* Folds a long line according to RFC 5322
* @see http://tools.ietf.org/html/rfc5322#section-2.1.1
*
* @param {String} input - input string
* @param {Number} maxLength - maximum line length (excluding CRLF)
* @param {Boolean} hardWrap - whether to insert a hard break at `maxLength`
* @returns {String}
*/
function foldLine( input, maxLength, hardWrap ) {
if( maxLength != null && maxLength < MIN_LINE_LENGTH ) {
throw new Error( 'Maximum length must not be less than ' + MIN_LINE_LENGTH )
}
if( maxLength != null && maxLength > MAX_LINE_LENGTH ) {
throw new Error( 'Maximum length must not exceed ' + MAX_LINE_LENGTH )
}
// RFC compliant default line length
maxLength = maxLength || DEFAULT_LINE_LENGTH
input = input.replace( /[\r\n]+/g, '' )
// We really don't need to fold this
if( input.length <= maxLength ) {
return input
}
var output = ''
var index = 0
var nextIndex = 0
var length = input.length
var line = 0
var trim = 0
while( index < length ) {
if( !hardWrap && ~( nextIndex = input.lastIndexOf( SP, index + maxLength ) ) ) {
if( nextIndex > index ) {
output += input.slice( index, nextIndex ) + CRLF + SP
index = nextIndex
} else {
output += input.slice( index, index + maxLength - trim ) + CRLF + SP
index = index + maxLength - trim
hardWrap = true
}
} else {
output += input.slice( index, index + maxLength - trim ) + CRLF + SP
index = index + maxLength - trim
}
if( ( length - index ) < maxLength ) {
output += input.slice( index )
break
}
if( line === 0 ) {
trim = 1
}
line++
}
return output
}
foldLine.unfold = function unfold( input ) {
return input.replace( /\r\n\s/gm, '' )
}
module.exports = foldLine