Skip to content

Instantly share code, notes, and snippets.

@sapegin
Created February 24, 2012 14:53
Show Gist options
  • Select an option

  • Save sapegin/1901433 to your computer and use it in GitHub Desktop.

Select an option

Save sapegin/1901433 to your computer and use it in GitHub Desktop.
JS Typographer Draft
(function(global) {
////////////////////////////////////////////////////////
var symbols = {
nbsp: ' '
}
var common = {
spaces: function(text) {
return _replace(text, this._spaces);
}
};
var rules = {};
rules.ru = _extend(common, {
// Предлоги и союзы
_prepos: /а|ай|в|вы|во|да|до|ее|её|ей|за|и|из|их|к|ко|мы|на|не|ни|но|ну|о|об|ой|он|от|по|с|со|то|ты|у|уж|я/,
// Частицы
_particles: /б|бы|ж|же|ли|ль/,
// Месяцы
_months: /января|февраля|марта|апреля|мая|июня|июля|августа|сентября|ноября|декабря/,
_spaces: [
// Неразрывные пробелы
[/№\s/g, '№' + symbols.nbsp], // номер
[/§\s/g, '§' + symbols.nbsp], // параграф
// Инициалы
[/((?:[А-ЯЁ]\.\s){1,2}[А-ЯЁ][а-яё]+)/g, '<nobr>$1</nobr>'],
// Слова через дефис
[/([^а-яёА-ЯЁ]|^)((?:[а-яёА-ЯЁ]{1,2}(?:\-[а-яёА-ЯЁ]+))|(?:[а-яёА-ЯЁ]+(?:\-[а-яёА-ЯЁ]{1,2})))(?![-а-яёА-ЯЁ])/g, '$1<nobr>$2</nobr>'],
/*# Предлоги и союзы
{"pat": ur'(?<![-а-яё])(%s)\s' % prepos, "rep": ur'\1%s' % sym['nbsp'], "mod": re.I|re.U},
# Частицы
{"pat": ur'\s(%s)(?![-а-яё])' % particles, "rep": ur'%s\1' % sym['nbsp'], "mod": re.I|re.U},
# Короткие слова в начале предложения
{"pat": ur'(?<=[\?\.\!%s]\s)([А-ЯЁ][а-яё]{1,2})\s' % sym['hellip'], "rep": ur'\1%s' % sym['nbsp'], "mod": re.I|re.U},
# Валюты
# TODO: знак рубля
{"pat": ur'(\d)\s(\$|р\.|руб\.)', "rep": ur'\1%s\2' % sym['nbsp'], "mod": re.I|re.U},
# Год (1917 г.)
(ur'(?<!\d)(\d{4})\s(гг?\.)', ur'\1%s\2' % sym['nbsp']),
# Даты (25 февраля)
(ur'(\d)\s(%s)' % months, ur'\1%s\2' % sym['nbsp']),*/
]
});
rules.en = {
};
////////////////////////////////////////////////////////
var richtypo = {
symbols: symbols
},
_lang = 'ru';
richtypo.lang = function(lang) {
if (lang !== undefined) {
_lang = lang;
}
else {
return _lang;
}
};
richtypo.rich = function(text, lang) {
return _process(text, lang, ['spaces']);
};
function _process(text, lang, ruleset) {
var rulesets = typeof ruleset === 'string' ? [ruleset] : ruleset;
lang = lang || richtypo.lang();
if (!rules[lang]) return text;
var langRules = rules[lang];
for (var setIdx = 0; setIdx < rulesets.length; setIdx++) {
var rulesetId = rulesets[setIdx];
if (!langRules[rulesetId]) continue;
text = langRules[rulesetId](text);
}
return text;
}
function _replace(text, rules) {
for (var ruleIdx = 0; ruleIdx < rules.length; ruleIdx++) {
var rule = rules[ruleIdx];
text = text.replace(rule[0], rule[1]);
}
return text;
}
function _extend(from, to) {
for (var key in from) {
if (!from.hasOwnProperty(key)) continue;
to[key] = from[key];
}
return to;
}
// Support both Node and browser environments
if (typeof module !== 'undefined' && module.exports) {
module.exports = richtypo;
}
else {
global.richtypo = richtypo;
}
})(this);
describe('RichTypo', function() {
var rt = require('../richtypo');
function _symb(s) {
return s.replace(/_/g, rt.symbols.nbsp);
}
it('has API functions', function() {
expect(rt.lang).toBeDefined();
expect(rt.rich).toBeDefined();
});
it('spaces', function() {
//expect(rt.rich('Это было в 1927 г. до нашей эры. А точнее — 25 февраля.'))
// .toBe('Это было в%s1927%sг. до%sнашей эры. А%sточнее%s— 25%sфевраля.'.replace(/%s/g, '_'));
expect(rt.rich('Прочитай § 13 в журнале «Такса» № 27 — там про тлонов, тутликов и табачек.'))
.toBe(_symb('Прочитай §_13 в журнале «Такса» №_27 — там про тлонов, тутликов и табачек.'));
// тлонов, тутликов, табачек и т. п. и т. п.
expect(rt.rich('Приснился однажды В. И. Ленин В. Путину.'))
.toBe(_symb('Приснился однажды <nobr>В. И. Ленин</nobr> <nobr>В. Путину</nobr>.'));
expect(rt.rich('Из-за чего-то всё-таки это как-то очень странно.'))
.toBe(_symb('<nobr>Из-за</nobr> <nobr>чего-то</nobr> всё-таки это <nobr>как-то</nobr> очень странно.'));
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment