123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- 'use strict';
- // Expose to the world
- module.exports.parseHeader = parseHeader;
- module.exports.generateHeader = generateHeader;
- module.exports.formatCharset = formatCharset;
- module.exports.foldLine = foldLine;
- /**
- * Parses a header string into an object of key-value pairs
- *
- * @param {String} str Header string
- * @return {Object} An object of key-value pairs
- */
- function parseHeader (str) {
- var lines = (str || '').split('\n');
- var headers = {};
- lines.forEach(function (line) {
- var parts = line.trim().split(':');
- var key = (parts.shift() || '').trim().toLowerCase();
- var value = parts.join(':').trim();
- if (!key) {
- return;
- }
- headers[key] = value;
- });
- return headers;
- }
- /**
- * Convert first letters after - to uppercase, other lowercase
- *
- * @param {String} str String to be updated
- * @return {String} A string with uppercase words
- */
- function upperCaseWords (str) {
- return (str || '')
- .toLowerCase()
- .trim()
- .replace(/^(MIME|POT?(?=-)|[a-z])|-[a-z]/gi, function (str) {
- return str.toUpperCase();
- });
- }
- /**
- * Joins a header object of key value pairs into a header string
- *
- * @param {Object} header Object of key value pairs
- * @return {String} Header string
- */
- function generateHeader (header) {
- var lines = [];
- Object.keys(header || {}).forEach(function (key) {
- if (key) {
- lines.push(upperCaseWords(key) + ': ' + (header[key] || '').trim());
- }
- });
- return lines.join('\n') + (lines.length ? '\n' : '');
- }
- /**
- * Normalizes charset name. Converts utf8 to utf-8, WIN1257 to windows-1257 etc.
- *
- * @param {String} charset Charset name
- * @return {String} Normalized charset name
- */
- function formatCharset (charset, defaultCharset) {
- return (charset || 'iso-8859-1').toString().toLowerCase()
- .replace(/^utf[-_]?(\d+)$/, 'utf-$1')
- .replace(/^win(?:dows)?[-_]?(\d+)$/, 'windows-$1')
- .replace(/^latin[-_]?(\d+)$/, 'iso-8859-$1')
- .replace(/^(us[-_]?)?ascii$/, 'ascii')
- .replace(/^charset$/, defaultCharset || 'iso-8859-1')
- .trim();
- }
- /**
- * Folds long lines according to PO format
- *
- * @param {String} str PO formatted string to be folded
- * @param {Number} [maxLen=76] Maximum allowed length for folded lines
- * @return {Array} An array of lines
- */
- function foldLine (str, maxLen) {
- maxLen = maxLen || 76;
- var lines = [];
- var curLine = '';
- var pos = 0;
- var len = str.length;
- var match;
- while (pos < len) {
- curLine = str.substr(pos, maxLen);
- // ensure that the line never ends with a partial escaping
- // make longer lines if needed
- while (curLine.substr(-1) === '\\' && pos + curLine.length < len) {
- curLine += str.charAt(pos + curLine.length);
- }
- // ensure that if possible, line breaks are done at reasonable places
- if ((match = /.*?\\n/.exec(curLine))) {
- // use everything before and including the first line break
- curLine = match[0];
- } else if (pos + curLine.length < len) {
- // if we're not at the end
- if ((match = /.*\s+/.exec(curLine)) && /[^\s]/.test(match[0])) {
- // use everything before and including the last white space character (if anything)
- curLine = match[0];
- } else if ((match = /.*[\x21-\x2f0-9\x5b-\x60\x7b-\x7e]+/.exec(curLine)) && /[^\x21-\x2f0-9\x5b-\x60\x7b-\x7e]/.test(match[0])) {
- // use everything before and including the last "special" character (if anything)
- curLine = match[0];
- }
- }
- lines.push(curLine);
- pos += curLine.length;
- }
- return lines;
- }
|