Skip to content

Commit

Permalink
Французкие кавычки отбиваем тонким пробелом
Browse files Browse the repository at this point in the history
- Французкие кавычки отбиваем тонким пробелом.
- В правилах можно запускать метод .execute().
  • Loading branch information
hcodes committed Apr 22, 2017
1 parent 3a4405e commit f1b1114
Show file tree
Hide file tree
Showing 47 changed files with 307 additions and 295 deletions.
23 changes: 0 additions & 23 deletions src/data.js
Expand Up @@ -30,26 +30,3 @@ Typograf._mix(Typograf, {
},
_data: {}
});

/**
* Get data for use in rules.
*
* @param {string} key
*
* @returns {*}
*/
Typograf.prototype.getData = function(key) {
var locale = this._sessionPrefs ? this._sessionPrefs.locale : this._prefs.locale;

if (key.search('/') === -1) {
if (key === 'char') {
return locale.map(function(item) {
return Typograf.getData(item + '/' + key);
}).join('');
} else {
return Typograf.getData(locale[0] + '/' + key);
}
} else {
return Typograf.getData(key);
}
};
5 changes: 3 additions & 2 deletions src/data/fr/quote.js
@@ -1,4 +1,5 @@
Typograf.setData('fr/quote', {
left: '«“',
right: '»”'
left: '«‹',
right: '»›',
spacing: true
});
30 changes: 13 additions & 17 deletions src/html-entities.js
Expand Up @@ -276,21 +276,20 @@ Typograf.HtmlEntities = {
/**
* Entities as name or digit to UTF-8.
*
* @param {string} text
* @return {string}
* @param {Object} context
*/
toUtf: function(text) {
if (text.search(/&#/) !== -1) {
text = this.decHexToUtf(text);
toUtf: function(context) {
if (context.text.search(/&#/) !== -1) {
context.text = this.decHexToUtf(context.text);
}

if (text.search(/&[a-z]/i) !== -1) {
if (context.text.search(/&[a-z]/i) !== -1) {
this._entities.forEach(function(entity) {
text = text.replace(entity.reName, entity.utf);
context.text = context.text.replace(entity.reName, entity.utf);
});
}

return text.replace(/"/g, '"');
context.text = context.text.replace(/"/g, '"');
},
/**
* Entities in decimal or hexadecimal form to UTF-8.
Expand All @@ -310,12 +309,11 @@ Typograf.HtmlEntities = {
/**
* Restore HTML entities in text.
*
* @param {string} text
* @param {HtmlEntity} params
* @returns {string}
* @param {Object} context
*/
restore: function(text, params) {
var type = params.type,
restore: function(context) {
var params = context.prefs.htmlEntity,
type = params.type,
entities = this._entities;

if (type === 'name' || type === 'digit') {
Expand All @@ -331,14 +329,12 @@ Typograf.HtmlEntities = {
}
}

text = this._restoreEntitiesByIndex(
text,
context.text = this._restoreEntitiesByIndex(
context.text,
type + 'Entity',
entities
);
}

return text;
},
/**
* Get a entity by utf using the type.
Expand Down
106 changes: 49 additions & 57 deletions src/main.js
Expand Up @@ -188,12 +188,27 @@
if (!text) { return ''; }

prefs = prefs || {};
this._sessionPrefs = Typograf.deepCopy(this._prefs);
this._sessionPrefs.htmlEntity = prefs.htmlEntity || this._prefs.htmlEntity || {};
this._sessionPrefs.locale = Typograf._prepareLocale(prefs.locale, this._prefs.locale);
this._sessionPrefs.lineEnding = prefs.lineEnding || this._prefs.lineEnding;

var locale = this._sessionPrefs.locale;
var context = {
text: text,
prefs: Typograf.deepCopy(this._prefs),
getData: function(key) {
if (key === 'char') {
return this.prefs.locale.map(function(item) {
return Typograf.getData(item + '/' + key);
}).join('');
} else {
return Typograf.getData(this.prefs.locale[0] + '/' + key);
}
}
};

context.prefs.htmlEntity = prefs.htmlEntity || this._prefs.htmlEntity || {};
context.prefs.locale = Typograf._prepareLocale(prefs.locale, this._prefs.locale);
context.prefs.lineEnding = prefs.lineEnding || this._prefs.lineEnding;
context.prefs.ruleFilter = prefs.ruleFilter || this._prefs.ruleFilter;

var locale = context.prefs.locale;
if (!locale.length || !locale[0]) {
throw Error('Not defined the property "locale".');
}
Expand All @@ -202,42 +217,37 @@
throw Error('"' + locale[0] + '" is not supported locale.');
}

text = this._removeCR(text);
context.text = this._removeCR(context.text);

this._isHTML = text.search(/(<\/?[a-z]|<!|&[lg]t;)/i) !== -1;
context.isHTML = context.text.search(/(<\/?[a-z]|<!|&[lg]t;)/i) !== -1;

text = this._executeRules(text, 'start');
this._executeRules(context, 'start');

text = this._safeTags.hide(text, this._isHTML, function(t, group) {
return that._executeRules(t, 'hide-safe-tags-' + group);
this._safeTags.hide(context, function(c, group) {
that._executeRules(c, 'hide-safe-tags-' + group);
});

text = this._executeRules(text, 'hide-safe-tags');
this._executeRules(context, 'hide-safe-tags');

text = Typograf.HtmlEntities.toUtf(text);
Typograf.HtmlEntities.toUtf(context);

if (this._prefs.live) { text = Typograf._replaceNbsp(text); }
if (this._prefs.live) { context.text = Typograf._replaceNbsp(context.text); }

text = this._executeRules(text, 'utf');
this._executeRules(context, 'utf');

text = this._executeRules(text);
this._executeRules(context);

text = Typograf.HtmlEntities.restore(text, this._sessionPrefs.htmlEntity);
Typograf.HtmlEntities.restore(context);

text = this._executeRules(text, 'html-entities');
this._executeRules(context, 'html-entities');

text = this._safeTags.show(text, function(t, group) {
return that._executeRules(t, 'show-safe-tags-' + group);
this._safeTags.show(context, function(c, group) {
that._executeRules(c, 'show-safe-tags-' + group);
});

text = this._executeRules(text, 'end');

text = this._fixLineEnding(text, this._sessionPrefs.lineEnding);

this._isHTML = null;
this._sessionPrefs = null;
this._executeRules(context, 'end');

return text;
return this._fixLineEnding(context.text, context.prefs.lineEnding);
},
/**
* Get a setting.
Expand Down Expand Up @@ -327,55 +337,37 @@

return this;
},
_cloneInstance: function(ruleFilter) {
var tp = new Typograf(this._sessionPrefs || this._prefs);
this._rules.forEach(function(rule) {
var ruleName = rule.name;
if (ruleFilter && !ruleFilter(rule)) {
tp.disableRule(ruleName);
return;
}

if (this.isEnabledRule(ruleName)) {
tp.enableRule(ruleName);
} else {
tp.disableRule(ruleName);
}
}, this);

return tp;
},
_executeRules: function(text, queue) {
_executeRules: function(context, queue) {
queue = queue || 'default';

var rules = this._rulesByQueues[queue],
innerRules = this._innerRulesByQueues[queue];

innerRules && innerRules.forEach(function(rule) {
text = this._ruleIterator(text, rule);
this._ruleIterator(context, rule);
}, this);

rules && rules.forEach(function(rule) {
text = this._ruleIterator(text, rule);
this._ruleIterator(context, rule);
}, this);

return text;
},
_ruleIterator: function(text, rule) {
_ruleIterator: function(context, rule) {
var rlocale = rule._locale,
live = this._prefs.live;

if ((live === true && rule.live === false) || (live === false && rule.live === true)) {
return text;
return;
}

if ((rlocale === 'common' || rlocale === this._sessionPrefs.locale[0]) && this.isEnabledRule(rule.name)) {
this._onBeforeRule && this._onBeforeRule(rule.name, text);
text = rule.handler.call(this, text, this._settings[rule.name]);
this._onAfterRule && this._onAfterRule(rule.name, text);
}
if ((rlocale === 'common' || rlocale === context.prefs.locale[0]) && this.isEnabledRule(rule.name)) {
if (context.prefs.ruleFilter && !context.prefs.ruleFilter(rule)) {
return;
}

return text;
this._onBeforeRule && this._onBeforeRule(rule.name, context.text, context);
context.text = rule.handler.call(this, context.text, this._settings[rule.name], context);
this._onAfterRule && this._onAfterRule(rule.name, context.text, context);
}
},
_removeCR: function(text) {
return text.replace(/\r\n?/g, '\n');
Expand Down
4 changes: 2 additions & 2 deletions src/rules/common/html/e-mail.js
@@ -1,8 +1,8 @@
Typograf.addRule({
name: 'common/html/e-mail',
queue: 'end',
handler: function(text) {
return this._isHTML ? text : text.replace(
handler: function(text, settings, context) {
return context.isHTML ? text : text.replace(
/(^|[\s;(])([\w\-.]{2,})@([\w\-.]{2,})\.([a-z]{2,6})([)\s.,!?]|$)/gi,
'$1<a href="mailto:$2@$3.$4">$2@$3.$4</a>$5'
);
Expand Down
20 changes: 10 additions & 10 deletions src/rules/common/html/processingAttrs.js
@@ -1,25 +1,25 @@
Typograf.addRule({
name: 'common/html/processingAttrs',
queue: 'hide-safe-tags-own', // After "hide-safe-tags-own", before "hide-safe-tags-html".
handler: function(text, settings) {
handler: function(text, settings, context) {
var that = this,
tp = null,
reAttrs = new RegExp('(^|\\s)(' + settings.attrs.join('|') + ')=("[^"]*?"|\'[^\']*?\')', 'gi');
reAttrs = new RegExp('(^|\\s)(' + settings.attrs.join('|') + ')=("[^"]*?"|\'[^\']*?\')', 'gi'),
prefs = Typograf.deepCopy(context.prefs);

return text.replace(/(<[-\w]+\s)([^>]+?)>/g, function(match, tagName, attrs) {
var resultAttrs = attrs.replace(reAttrs, function(submatch, space, attrName, attrValue) {
tp = tp || that._cloneInstance(function(rule) {
return rule.htmlAttrs !== false;
});
prefs.ruleFilter = function(rule) {
return rule.htmlAttrs !== false;
};

return text.replace(/(<[-\w]+\s)([^>]+?)(?=>)/g, function(match, tagName, attrs) {
var resultAttrs = attrs.replace(reAttrs, function(submatch, space, attrName, attrValue) {
var lquote = attrValue[0],
rquote = attrValue[attrValue.length - 1],
value = attrValue.slice(1, -1);

return space + attrName + '=' + lquote + tp.execute(value) + rquote;
return space + attrName + '=' + lquote + that.execute(value, prefs) + rquote;
});

return tagName + resultAttrs + '>';
return tagName + resultAttrs;
});
},
settings: {
Expand Down
4 changes: 2 additions & 2 deletions src/rules/common/html/url.js
@@ -1,8 +1,8 @@
Typograf.addRule({
name: 'common/html/url',
queue: 'end',
handler: function(text) {
return this._isHTML ? text : text.replace(Typograf._reUrl, function($0, protocol, path) {
handler: function(text, settings, context) {
return context.isHTML ? text : text.replace(Typograf._reUrl, function($0, protocol, path) {
path = path
.replace(/([^\/]+\/?)(\?|#)$/, '$1') // Remove ending ? and #
.replace(/^([^\/]+)\/$/, '$1'); // Remove ending /
Expand Down
3 changes: 2 additions & 1 deletion src/rules/common/html/url.spec.js
Expand Up @@ -20,5 +20,6 @@ tests.push(['common/html/url', [
['Ссылка http://www.example.com:443', 'Ссылка <a href="http://www.example.com:443">example.com:443</a>'],
['Ссылка https://www.example.com:443/?', 'Ссылка <a href="https://www.example.com">https://example.com</a>'],
['Ссылка https://www.example.com:443/?query=hello', 'Ссылка <a href="https://www.example.com/?query=hello">https://example.com/?query=hello</a>'],
['Ссылка https://www.example.com:4434/?query=hello', 'Ссылка <a href="https://www.example.com:4434/?query=hello">https://example.com:4434/?query=hello</a>']
['Ссылка https://www.example.com:4434/?query=hello', 'Ссылка <a href="https://www.example.com:4434/?query=hello">https://example.com:4434/?query=hello</a>'],
['<a href="https://www.example.com">https://www.example.com</a>', '<a href="https://www.example.com">https://www.example.com</a>']
]]);
4 changes: 2 additions & 2 deletions src/rules/common/nbsp/afterNumber.js
@@ -1,8 +1,8 @@
Typograf.addRule({
name: 'common/nbsp/afterNumber',
handler: function(text) {
handler: function(text, settings, context) {
var re = '(^|\\D)(\\d{1,5}) ([' +
this.getData('char') +
context.getData('char') +
']{2,})';

return text.replace(new RegExp(re, 'gi'), '$1$2\u00A0$3');
Expand Down
6 changes: 3 additions & 3 deletions src/rules/common/nbsp/afterShortWord.js
@@ -1,9 +1,9 @@
Typograf.addRule({
name: 'common/nbsp/afterShortWord',
handler: function(text, settings) {
handler: function(text, settings, context) {
var len = settings.lengthShortWord,
before = ' \u00A0(' + Typograf._privateLabel + this.getData('common/quote'),
subStr = '(^|[' + before + '])([' + this.getData('char') + ']{1,' + len + '}) ',
before = ' \u00A0(' + Typograf._privateLabel + Typograf.getData('common/quote'),
subStr = '(^|[' + before + '])([' + context.getData('char') + ']{1,' + len + '}) ',
newSubStr = '$1$2\u00A0',
re = new RegExp(subStr, 'gim');

Expand Down
6 changes: 3 additions & 3 deletions src/rules/common/nbsp/beforeShortLastNumber.js
@@ -1,11 +1,11 @@
Typograf.addRule({
name: 'common/nbsp/beforeShortLastNumber',
handler: function(text, settings) {
var ch = this.getData('char'),
handler: function(text, settings, context) {
var ch = context.getData('char'),
CH = ch.toUpperCase(),
re = new RegExp('([' + ch + CH +
']) (?=\\d{1,' + settings.lengthLastNumber +
'}[-+−%\'"' + this.getData('quote').right + ']?([.!?…]( [' +
'}[-+−%\'"' + context.getData('quote').right + ']?([.!?…]( [' +
CH + ']|$)|$))', 'gm');

return text.replace(re, '$1\u00A0');
Expand Down
4 changes: 2 additions & 2 deletions src/rules/common/nbsp/beforeShortLastWord.js
@@ -1,7 +1,7 @@
Typograf.addRule({
name: 'common/nbsp/beforeShortLastWord',
handler: function(text, settings) {
var ch = this.getData('char'),
handler: function(text, settings, context) {
var ch = context.getData('char'),
CH = ch.toUpperCase(),
re = new RegExp('([' + ch + '\\d]) ([' +
ch + CH + ']{1,' + settings.lengthLastWord +
Expand Down
6 changes: 3 additions & 3 deletions src/rules/common/other/repeatWord.js
@@ -1,9 +1,9 @@
Typograf.addRule({
name: 'common/other/repeatWord',
handler: function(text, settings) {
var punc = '[;:,.?! \n' + this.getData('common/quote') + ']';
handler: function(text, settings, context) {
var punc = '[;:,.?! \n' + Typograf.getData('common/quote') + ']';
var re = new RegExp('(' + punc + '|^)' +
'([' + this.getData('char') + ']{' + settings.min + ',}) ' +
'([' + context.getData('char') + ']{' + settings.min + ',}) ' +
'\\2(' + punc + '|$)', 'gi');

return text.replace(re, '$1$2$3');
Expand Down
4 changes: 2 additions & 2 deletions src/rules/common/punctuation/apostrophe.js
@@ -1,7 +1,7 @@
Typograf.addRule({
name: 'common/punctuation/apostrophe',
handler: function(text) {
var letters = '([' + this.getData('char') + '])',
handler: function(text, settings, context) {
var letters = '([' + context.getData('char') + '])',
re = new RegExp(letters + '\'' + letters, 'gi');

return text.replace(re, '$1’$2');
Expand Down

0 comments on commit f1b1114

Please sign in to comment.