moji
Version:
半角全角変換・特定文字抽出など日本語を便利に扱うJavaScriptライブラリ。
224 lines (197 loc) • 5.31 kB
JavaScript
'use strict';
/**
* @constructor
* @param {object} mojisyu
* @param {string} str
*/
function Moji(mojisyu, str) {
this.origin = str;
this._result = this.origin;
this._mojisyu = mojisyu;
}
Moji.prototype.toString = function () {
return this._result;
};
/**
* convert
* 変換の実行
*
* @param {string} from_syumei 変換前の文字種名
* @param {string} to_syumei 変化後の文字種名
* @returns {Moji}
*/
Moji.prototype.convert = function convert(from_syumei, to_syumei) {
var from_mojisyu_body = this._mojisyu[from_syumei];
var to_mojisyu_body = this._mojisyu[to_syumei];
if (this._mojisyuType(from_mojisyu_body) === 'range' && this._mojisyuType(to_mojisyu_body) === 'range') {
this._result = this._rangeConvert(from_mojisyu_body, to_mojisyu_body);
return this;
}
if (this._mojisyuType(from_mojisyu_body) === 'regexp' && this._mojisyuType(to_mojisyu_body) === 'regexp') {
this._result = this._regexpConvert(from_mojisyu_body, to_mojisyu_body);
return this;
}
};
/**
* _rangeConvert
* @param {object} from_syu
* @param {object} to_syu
* @return {string}
* @private
*/
Moji.prototype._rangeConvert = function _rangeConvert(from_syu, to_syu) {
var distance = to_syu.start - from_syu.start;
return this._rangeMap(from_syu, function (moji, is_match, code) {
if (is_match) {
return String.fromCharCode(code + distance);
}
return moji;
}).join('');
};
/**
* _regexpConvert
* @param from_syu
* @param to_syu
* @return {string}
* @private
*/
Moji.prototype._regexpConvert = function _regexpConvert(from_syu, to_syu) {
return this._regexpMap(from_syu, function (moji, is_match, index) {
if (!is_match) {
return moji;
}
return to_syu.list[index];
});
};
/**
* filter
* 文字種のみに絞込
* @param {string} mojisyu_name 絞り込まれる文字種
* @returns {Moji}
*/
Moji.prototype.filter = function filter(mojisyu_name) {
var mojisyu_body = this._mojisyu[mojisyu_name];
if (this._mojisyuType(mojisyu_body) === 'range') {
this._result = this._rangeFilter(mojisyu_body);
return this;
}
if (this._mojisyuType(mojisyu_body) === 'regexp') {
this._result = this._regexpFilter(mojisyu_body);
return this;
}
};
/**
* _rangeFilter
* @param mojisyu
* @return {string}
* @private
*/
Moji.prototype._rangeFilter = function _rangeFilter(mojisyu) {
return this._rangeMap(mojisyu, function (moji, is_range) {
if (is_range) {
return moji;
}
return '';
}).join('');
};
/**
* _regexpFilter
* @param mojisyu
* @return {string}
* @private
*/
Moji.prototype._regexpFilter = function _regexpFilter(mojisyu) {
var match_mojis = [];
this._regexpMap(mojisyu, function (moji, is_match) {
if (is_match) {
match_mojis.push(moji);
}
});
return match_mojis.join('');
};
/**
* reject
* 文字種は排除
* @param {string} mojisyu_name 排除される文字種
* @returns {Moji}
*/
Moji.prototype.reject = function reject(mojisyu_name) {
var mojisyu_body = this._mojisyu[mojisyu_name];
if (this._mojisyuType(mojisyu_body) === 'range') {
this._result = this._rangeReject(mojisyu_body);
return this;
}
if (this._mojisyuType(mojisyu_body) === 'regexp') {
this._result = this._regexpReject(mojisyu_body);
return this;
}
};
/**
* _rangeReject
* @param mojisyu
* @return {string}
* @private
*/
Moji.prototype._rangeReject = function _rangeReject(mojisyu) {
return this._rangeMap(mojisyu, function (moji, is_range) {
if (!is_range) {
return moji;
}
return '';
}).join('');
};
/**
* _regexpReject
* @param mojisyu
* @return {string}
* @private
*/
Moji.prototype._regexpReject = function _regexpReject(mojisyu) {
var reject_moji = this._regexpFilter(mojisyu);
return this._result.replace(reject_moji, '');
};
/**
* _mojisyuType
* 文字種のタイプを判別
* range || regexp
* @param {mojisyu} mojisyu 文字種
* @return {string}
*/
Moji.prototype._mojisyuType = function _mojisyuType(mojisyu) {
if (mojisyu.start && mojisyu.end) {
return 'range';
}
if (mojisyu.regexp && mojisyu.list) {
return 'regexp';
}
return '';
};
/**
* _rangeMap
* @param {object} mojisyu - 文字種オブジェクト
* @param {function} callback
* @return {Array}
* @private
*/
Moji.prototype._rangeMap = function _rangeMap(mojisyu, callback) {
return this._result.split('').map(function (moji) {
var code = moji.charCodeAt(0);
var is_match = (code >= mojisyu.start && code <= mojisyu.end);
return callback.call(this, moji, is_match, code);
});
};
/**
* _regexpMap
* @param {object} mojisyu - 文字種オブジェクト
* @param callback
* @return {string}
* @private
*/
Moji.prototype._regexpMap = function _regexpMap(mojisyu, callback) {
return this._result.replace(mojisyu.regexp, function (moji) {
var index = mojisyu.list.indexOf(moji);
var is_match = index >= 0;
return callback.call(this, moji, is_match, index);
});
};
module.exports = Moji;