/*
 * Typograph
 *
 * Copyright (c) 2009 Andrew Gromoff <andrew@gromoff.net>, http://gromoff.net/digraph
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * $Version: 09.12.17 alfa
 */


/*
Всё (или почти всё) о пробеле
	http://habrahabr.ru/blogs/typography/23250/
Непустое место: Cложные случаи употребления пробела в русском языке
	http://gramota.ru/biblio/public/32_8
Буквенные аббревиатуры, сложносокращенные слова и графические сокращения
	http://www.gramota.ru/spravka/rules/?rub=sokr

Цифры, числа и числительные
	http://scrype.ru/blog/articles/2008/05/cifry-chisla-i-chislitelnye.html
	http://habrahabr.ru/blogs/typography/24544/

* Latin-1 Entities
* Symbols and Greek Letters
* Other Special Characters
	http://www.htmlhelp.com/reference/html40/entities/

UTF-8 encoding table and Unicode characters
	http://www.utf8-chartable.de/unicode-utf8-table.pl
	http://ivanov.in/upbar/symbols8.php

пробел
	http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B1%D0%B5%D0%BB
минус
	http://ru.wikipedia.org/wiki/%D0%9C%D0%B8%D0%BD%D1%83%D1%81
тире
	http://ru.wikipedia.org/wiki/%D0%A2%D0%B8%D1%80%D0%B5 
дефис
	http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D1%84%D0%B8%D1%81 
кавычки
	http://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%B2%D1%8B%D1%87%D0%BA%D0%B8

Написания слитные и через дефис (черточку)
	VI. Предлоги, союзы, частицы, междометия
		http://gramota.ru/spravka/rules/?rub=def&text=19_23


Знаки валют
	http://ru.wikipedia.org/wiki/%D0%97%D0%BD%D0%B0%D0%BA%D0%B8_%D0%B2%D0%B0%D0%BB%D1%8E%D1%82
	http://www.w3.org/TR/html4/sgml/entities.html

*/

DiGraphPlugin.push('initTypograph'); // инициализация плагина

DiGraph.prototype.initTypograph = function()
	{
	this.TERRORS = [];

	var ar=[];
	var i;
	var L;

	var ISO_Latin_1 = ["nbsp","iexcl", "cent", "pound", "curren", "yen", "brvbar", "sect", "uml", "copy", "ordf", "laquo", "not", "shy", "reg", "macr", "deg", "plusmn", "sup2", "sup3", "acute", "micro", "para", "middot", "cedil", "sup1", "ordm", "raquo", "frac14", "frac12", "frac34", "iquest", "Agrave", "Aacute", "Acirc", "Atilde", "Auml", "Aring", "AElig", "Ccedil", "Egrave", "Eacute", "Ecirc", "Euml", "Igrave", "Iacute", "Icirc", "Iuml", "ETH", "Ntilde", "Ograve", "Oacute", "Ocirc", "Otilde", "Ouml", "times", "Oslash", "Ugrave", "Uacute", "Ucirc", "Uuml", "Yacute", "THORN", "szlig", "agrave", "aacute", "acirc", "atilde", "auml", "aring", "aelig", "ccedil", "egrave", "eacute", "ecirc", "euml", "igrave", "iacute", "icirc", "iuml", "eth", "ntilde", "ograve", "oacute", "ocirc", "otilde", "ouml", "divide", "oslash", "ugrave", "uacute", "ucirc", "uuml", "yacute", "thorn", "yuml"];
	// http://www.w3.org/TR/html401/sgml/entities.html
	// Special Entities
	var SE = {34:'quot',38:'amp',60:'lt',62:'gt',338:'OElig',339:'oelig',352:'Scaron',353:'scaron',376:'Yuml',710:'circ',732:'tilde',8194:'ensp',8195:'emsp',8201:'thinsp',8211:'ndash',8212:'mdash',8216:'lsquo',8217:'rsquo',8218:'sbquo',8220:'ldquo',8221:'rdquo',8222:'bdquo',8224:'dagger',8225:'Dagger',8240:'permil',8249:'lsaquo',8250:'rsaquo',8364:'euro',8722:'minus'};

	this.ISON = {"&nbsp;":160,"&#160;":160};

	
	ar.push('&nbsp;|&#160;');
	
	
	for (i = 161; i<= 255; i++) // 255
		{
		this.ISON['&'+ISO_Latin_1[(i-160)]+';'] = i;
		this.ISON['&#'+i+';'] = i;

		ar.push('|&'+ISO_Latin_1[(i-160)]+';|&#'+i+';');
		}

	for(i in SE)
		{
		this.ISON['&'+SE[i]+';'] = i;
		this.ISON['&#'+i+';'] = i;

		ar.push('|&'+SE[i]+';|&#'+i+';');
		}

	this.rISO =  new RegExp(ar.join(''), "gm");

	// почтовые сокращения 
	var PS= new Array('а/п','ал.','б/о','б/п','б-р','вол\\.','высел\\.','г\\.','гк','д\\.','д/о','д/интер','дд','дор\\.','дп','дск','ж/д','ж\\.д\\.','жт','жилмас','заим\\.','заст\\.','з-д','зо',	
'и/з','кв-л','клх','кл-ще','км\\.','кп','лесн-во','м\\.','м/с','мкр','мо','наб\\.','нп','общ\\.','отд\\.','п\\.','п/л','п/о','п/р','п/свх','п/ст','п/станок','панс\\.','пгт','пер\\.','пз','пит\\.',
'пл\\.','платф\\.','пл-ка','п-ов','подст\\.','пр\\.','промзона','пр-кт','проф\\.','пх','рембаза','респ\\.','рзд','р-н','рп','ряды','с\\.','сан\\.','сан-проф\\.','свх','сдт','сл\\.','сооруж\\.','ст\\.','стр\\.',
'ст-ца','т/б','тер\\.','туп\\.','у\\.','ул\\.','ур-ще','уч-к','учхоз','х\\.','х-во','цо','цу','цу пх','цу свх','цу ТОО','ш\\.');
	this.rPS =  new RegExp('(^|\\s|\\(|{|\\[|"|>)('+PS.join('|')+')\\s?(?="?[А-ЯA-Z])', "gm");

	// географические сокращения
	var GS	= new Array('арх\\.','бл\\.-п\\.','бр\\.','вдхр\\.','в\\.д\\.','впд\\.','влк\\.','гсп\\.','з\\.д\\.','запов\\.','зим\\.','ист\\.','кам\\.','кл\\.','маш\\.','низм\\.','н\\.у\\.м\\.','о\\.','о-ва','обл\\.','оз\\.','плск\\.','пос\\.','пещ\\.','пл\\.','р\\.','с\\.ш\\.','тун\\.','ур\\.','хр\\.','шах\\.','шл\\.','шк\\.','ю\\.ш\\.');
	this.rGS	=  new RegExp('(^|\\s|\\(|{|\\[|"|>)('+GS.join('|')+')\\s?(?="?[А-ЯA-Z])', "gm");

	// прочие сокращения
	var OS = new Array('акад\\.','асс\\.','доц\\.','др\\.','гос\\.','гос-во','гр\\.','гр-ка','гр-н','гр-не','ж\\.','жен\\.','заруб\\.','изд-во','им\\.','ин\\.','иностр\\.','ин-т','инст\\.','напр\\.','проф\\.','тов\\.');
	this.rOS =  new RegExp('(^|\\s|\\(|{|\\[|"|>)('+OS.join('|')+')\\s?(?="?[А-ЯA-Z])', "gmi");

	// союзы, короткие слова
	var SO= new Array(
'а','аль',
'без','безо','бы','будто',
'в','вне','во',
'да','дабы','для','до',
'едва','ежели','если','еще','ещё',
'же',
'за','зато',
'и','ибо','из','из-за','из-под','изо','или','иль','их',
'к','как','ко','кое','когда','коли','коль',
'либо','лишь',
'меж','между',
'на','над','надо','не','ни','ни-ни','но',
'о','об','обо','однако','около','от','ото','оттого',
'перед','передо','по','по-над','под','пока','подо','потому','пред','предо','при','про','пусть',
'раз',
'с','со','сквозь','словно',
'так','там','тем','то','то-то','того','точно',
'у','уж',
'через',
'хотя','хоть',
'что','чтобы','я');

	this.rSO =  new RegExp('(^|\\s|\\(|{|\\[|"|<)('+SO.join('|')+')(\\s)', "gmi"); // \u00A0
	this.rSO2 =  new RegExp('(\\s)('+SO.join('|')+')(\\s)', "gm");
	}










DiGraph.prototype.TypographPost = function(text,result)	//function(_self, error, text)
	{
	if (result === true)
		{
		this.e.value = text;
		}
	
	$("#digraph-wait").overlay().close();
	
	var _self = this;
	window.setTimeout(function(){_self.LoadState();},10);

	$(".ui-state-active").removeClass("ui-state-active");

	if (this.TERRORS.length > 0)
		{
		$("#digraph-message").html(this.TERRORS.join(''));
		$(_self.rid+"-validatorbox").show(0);		
		this.TERRORS = [];
		}
	}

// словари: http://www.lebed.com/slovo.html
//

DiGraph.prototype.TypoRules = function(v)
	{
	var _self	= this;
	var save	= [];

	/* убираем теги */
	v =  v.replace(/(<\/?[^>]*\/?>)/gm,function(s)
		{
		save.push(s);
		return String.fromCharCode(save.length+bbIndex); 
		});

	/* убираем ссылки */
	v = v.replace(/(((file|gopher|news|nntp|telnet|http|ftp|https|ftps|sftp):\/\/)|(www\.))+(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(\/[a-zA-Z0-9\&amp;%_\.\/-~-]*)?/gm, function(s)
		{
		save.push(s);
		return String.fromCharCode(save.length+bbIndex); // Пользовательская зона":"E000,F8FF", 
		});

	/* e-mail адреса */
	v = v.replace(/(?:[a-zA-Z0-9_'^&amp;\/+-])+(?:\.(?:[a-zA-Z0-9_'^&amp;\/+-])+)*@(?:(?:\[?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\]?)|(?:[a-zA-Z0-9-]+\.)+(?:[a-zA-Z]){2,}\.?)/gm, function(s)
		{
		save.push(s);
		return String.fromCharCode(save.length+bbIndex);
		});

	var re;

	// http://xpoint.ru/forums/programming/PHP/thread/39384.xhtml

	// конвертация строк типа &Auml;&Egrave;&Igrave; согласно
	// http://www.w3.org/TR/html401/sgml/entities.html		Character Entities for ISO Latin-1

	// http://www.htmlhelp.com/reference/html40/entities/latin1.html

	v = v.replace(this.rISO, function(s){return String.fromCharCode(_self.ISON[s])});  

	// сущности в Юникод (которые остались)
	v = v.replace(/&#(\d+);/gm, function(str){return String.fromCharCode(str)});

	/* ЗАМЕНА ПРОБЕЛОВ		http://habrahabr.ru/blogs/typography/23250/ */

	/* !!! надо будет подробно проработать тему : http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B1%D0%B5%D0%BB */
	
	// Межсловный пробел,				U+0020, &#32;
	// Неразрывный межсловный пробел	U+00A0, &nbsp;
	// Полукруглая шпация				U+2002, 			&ensp;
	// Круглая шпация					U+2003, 			&emsp;
	// Третная шпация					U+2004, &#8196;
	// Четвертная шпация					U+2005, &#8197;
	// Одна шестая круглой				U+2006, &#8198;
	// Тонкая шпация						U+2009, 			&thinsp; 
	// Волосяная шпация					U+200A, &#8202;

	v = v.replace(/\n+/gm,'');

	v = v.replace(/(\u0020|\t|\u00A0|\u2002\u2003|\u2005|\u2005|\u2006|\u2009|\u200A)+/gm,'\u0020');

	//v = v.replace(/\s+/gm,'\u0020');

	/* IE6 НЕКОРРЕКТНО ОТОБРАЖАЕТ ТОНКУЮ ШПАНАЦИЮ */

	var thinsp = '\u2009';

	//if (($.browser.msie) && ($.browser.version == '6.0'))
	//	{
	//	thinsp = '\u00A0';
	//	}	
		

	/* минус, тире, дефис */

	/* минус	http://ru.wikipedia.org/wiki/%D0%9C%D0%B8%D0%BD%D1%83%D1%81 */
	// Унарный минус не отбивается от последующего числа. Бинарный минус одинаково отбивается с обеих сторон. 
	// При разрыве строк унарный минус не должен отбиваться от своего аргумента, а в случае с бинарным минусом возможен разрыв формулы по нему 
	// (в отечественной типографике — с повторением минуса до и после разрыва).

	// По начертанию минус должен иметь те же пропорции (в ширину), и его центр должен быть на той же высоте, как у знака равенства и у плюса (-7+5=-2).\, 
	// В традиционных отечественных шрифтах минус часто был тождествен с тире, но в новых шрифтах он обычно ставится несколько выше и имеет меньший размер.

	// Минус в компьютерном наборе

	// Исторически, знак дефиса использовался в компьютерном наборе вместо минуса и тире ввиду отсутствия отдельных клавиш для последних.
	// В программировании эти символы по‑прежнему не различаются (так как обычно для служебных целей используются только символы ASCII),
	// но при качественном наборе текстов следует различать дефис (‐), минус (−) и тире (—).

	// MINUS										\u2212 	8722 	− 	&minus;

	/* тире		http://ru.wikipedia.org/wiki/%D0%A2%D0%B8%D1%80%D0%B5 */

	// Длинное тире			EM DASH 				\u2014 	8212 	— 	&mdash; (черта длиной в заглавную букву М)
	//	* для указания внезапной остановки повествования;
	//	* выделения вводного предложения;
	//	* обозначения открытого диапазона (John Smith, 1981—);
	//	* может использоваться в тех же случаях, что и знак двоеточия.

	// Среднее тире 			EN DASH 				\u2013 	8211 	– 	&ndash; (черта длиной в заглавную букву N)
	//	* Используется для обозначения диапазонов и интервалов (June–July 1967, For ages 3–5, New York–London flight) 
	//	и для соединения сложных слов, содержащих дефисы (high-priority–high-pressure tasks).

	// Цифровое тире 		FIGURE DASH 			\u2012 	8210 	‒ 	отсутствует
	//	* Используется в качестве разделителя в цифровых выражениях, напр., в телефонных номерах (123‒45‒67). По ширине равно цифре.

	/* дефис	http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D1%84%D0%B8%D1%81 */
	
	// дефис				HYPHEN					\u2010	8208	‐	отсутствует
	// неразрывный дефис 	NON-BREAKING HYPHEN 	\u2011 	8209 	‑ 	отсутствует
	// дефис-минус			HYPHEN-MINUS 			\u002D 	45 	-



	
	//	* для присоединения частиц (кто-либо, где-то);
	//	* для присоединения префиксов (во-первых, по-русски);
	//	* для разделения сложных слов (физико-математический, иссиня-черный);
	//	* в качестве знака сокращения (физ-ра);
	//	* в словосочетаниях (бизнес-ланч, интернет-кафе);
	//	* в качестве знака переноса (в интернете сегодня практически не встречается) и т. д.

	// приводим для удобства типографирования всё к: дефис-минус
	v = v.replace(/\u2010|\u2011|\u2012|\u2013|\u2014|\u2212/gm,'\u002D');

	// многоточие
	v = v.replace(/(\.){3,}/gm,"…");

	//Заменяет двойные знаки препинания и тире на одинарные
	v = v.replace(/,{2,}/gm,",");
	v = v.replace(/-{2,}/gm,"-");
	v = v.replace(/\.{2,}/gm,".");

	var DR = {};
	//if ($.browser.msie)
	//	{
		DR= {'1/4':'\u00BC','1/2':'\u00BD','3/4':'\u00BE','1/3':'\u2153','2/3':'\u2154','1/8':'\u215b','3/8':'\u215c','5/8':'\u215d','7/8':'\u215e'};
	//	}
	//else	{
	//	DR= {'1/4':'\u00BC','1/2':'\u00BD','3/4':'\u00BE','1/3':'\u2153','2/3':'\u2154','1/5':'\u2155','2/5':'\u2156','3/5':'\u2157','4/5':'\u2158','1/6':'\u2159','5/6':'\u215a','1/8':'\u215b','3/8':'\u215c','5/8':'\u215d','7/8':'\u215e'};
	//	}

	var stt='';

	for(var m in DR)
		{
		if (!stt)
			{stt+=m}
		else	{stt+='|'+m}
		}

	re =  new RegExp('(^|[^\\d])('+stt+')(?=[^\\d\\/])', "gm");
	v = v.replace(re, function(s,s1,s2,s3){return s1+DR[s2]});

	v = v.replace(/\(c\)|\(с\)/gim,"©");
	v = v.replace(/([^\+]|^)\+-/gm,"$1±");

	// точки в англоязычных наименованиях

	v = v.replace(/([A-Za-z])\.([A-Za-z])/gm,"$1\u2024$2");	// \u2024	&#8228;
	v = v.replace(/(\d)\.([A-Za-z])/gm,"$1\u2024$2");
	v = v.replace(/([A-Za-z])\.(\d)/gm,"$1\u2024$2");

	v = v.replace(/([^\+]|^)\+-/gm,"$1±");

	/* КАВЫЧКИ http://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%B2%D1%8B%D1%87%D0%BA%D0%B8 */

	//			RUS				ING
	// «	Открывающая 		—			LEFT-POINTING DOUBLE ANGLE QUOTATION MARK		00AB 	171 	&laquo;
	// ‹		Открывающая[1] 	—			SINGLE LEFT-POINTING ANGLE QUOTATION MARK		2039 	8249 	&lsaquo;
	// »	Закрывающая 		—			RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK	00BB 	187 	&raquo;
	// ›		Закрывающая[1] 		—			SINGLE RIGHT-POINTING ANGLE QUOTATION MARK	203A 	8250 	&rsaquo;
	// „		Открывающая 		—			DOUBLE LOW-9 QUOTATION MARK					201E 	8222 	&bdquo;
	// ‚		Открывающая[1] 	—			SINGLE LOW-9 QUOTATION MARK					201A 	8218 	&sbquo;
	// “		Закрывающая	Открывающая 	LEFT DOUBLE QUOTATION MARK					201C 	8220 	&ldquo;
	// ‟		— 			Открывающая [1]DOUBLE HIGH-REVERSED-9 QUOTATION MARK			201F 	8223 	&#8223;
	// ‘		Закрывающая [1]	Открывающая 	LEFT SINGLE QUOTATION MARK						2018 	8216 	&lsquo;
	// ‛			— 			Открывающая [1]SINGLE HIGH-REVERSED-9 QUOTATION MARK			201B 	8219 	&#8219;
	// ”			— 			Закрывающая 	RIGHT DOUBLE QUOTATION MARK					201D 	8221 	&rdquo;
	// ’			— 			Закрывающая 	RIGHT SINGLE QUOTATION MARK					2019 	8217 	&rsquo;
	// "		Универсальная[2]				QUOTATION MARK								0022 	0034 	&quot;

//alert('1 '+v);
	// обрабатываем англоязычный порядок кавычек
	v = v.replace(/([^A-Za-zА-Яа-я])[“|\u201F|‘|‛]([^”]*)[”|’]([^A-Za-zА-Яа-я])/gm,'$1"$2"$3'); // 
//return v;
		// убираем пробельные символы поcле открывающихся кавычек
		
		// RUS
		v = v.replace(/(«|‹|„|‚)\s?/gm,'$1'); // ' $1'
//alert('2 '+v);
		// убираем пробельные символы перед
		v = v.replace(/\s?(»|›|“|‘)/gm,'$1');
//alert('3 '+v);
		// Унифицируем кавычки
		//v = v.replace(/«|‹|„|‚|\u201F|‛|»|›|“|‘|”|’/gm,'"')
		v = v.replace(/\u00AB|\u00BB|[\u2018-\u201F]|\u2039|\u203A/gm,'"')

	/*неразрывный пробел перед латинскими символами, могущими обозначать римские цифры, пример: «Fuzzi Logic II», «Николай II», «Людовиг XVI» */

	v = v.replace(/([A-Za-zА-Яа-я]) ([IVXLCDM]+)(\s|\.|,|:|\?|!|;|\)|\}|\]|>|")/gm,"$1\u00A0$2$3");

	/* Знаки препинания http://habrahabr.ru/blogs/typography/23250/ */

	//	1.	Точка, запятая, двоеточие, вопросительный и восклицательный знаки, точка с запятой 
	//			1а	не отбиваются пробелом от предшествующего слова,
	//			1б	и отбиваются пробелом от последующего: Ха, ха. Ха? Ха!
			//1а
			//v = v.replace(/\s(\.|,|:|\?|!|;|\)|\}|\]|>)/gm,'$1');
			//1б
			//v = v.replace(/(\.|,|:|\?|!|;|\)|\}|\]|>)([A-Za-zА-Яа-я])/gm,'$1 $2');

			// см. ниже

	//	+8.	отсутствие пробела после запятой
			//v = v.replace(/([A-Za-zА-Яа-я]),([A-Za-zА-Яа-я])/gm,'$1, $2'); 
			//v = v.replace(/(\d),([A-Za-zА-Яа-я])/gm,'$1, $2');
			//v = v.replace(/([A-Za-zА-Яа-я]),(\d)/gm,'$1, $2');

	//	+9.	если точки и далее заглавная буква - разделить пробелом
			//v = v.replace(/\.([А-Я])/gm,". $1");
			//Убирает пробельные символы перед . , : ? ! ; ) } ] > » “ ”
			//v = v.replace(/\s(\.|,|:|\?|!|;|\)|\}|\]|>|»|“|”)/gm,'$1');

	

	// 	2.	Многоточие не отбивается от предшествующего слова, если оно стоит в конце предложения или части предложения, 
	//		и от последующего — если оно стоит в начале предложения: Ого… Что? …Ничего.
	//		примеры: http://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%BE%D0%B3%D0%BE%D1%82%D0%BE%D1%87%D0%B8%D0%B5
			
			// Ого… Что?
			v = v.replace(/([\dа-я])\s…\s([\dA-ZА-Я])/gm,'$1… $2');
			// Что? …Ничего.
			v = v.replace(/([^а-я])\s…\s([\dA-ZА-Я])/gm,'$1 …$2');
			// А поэзия… должна быть глуповата
			v = v.replace(/([а-я])\s?…\s?(.)/gm,'$1… $2');	// частично перекрывает первый вариант
			// " … Нашёл || " … нашёл
			//v = v.replace(/("…)\s/gm,'$1'); см. после расстановок кавычек
			v = v.replace(/… "/gm,'…"');
	//	1. 
			v = v.replace(/\s(\.|,|:|\?|!|;|\)|\}|\]|>)/gm,'$1');
			//1б
			v = v.replace(/(\.|,|:|\?|!|;|\)|\}|\]|>)([A-Za-zА-Яа-я])/gm,'$1 $2');

			// отрываем кавычку от ," :" )" }" ]" >" 

			//v = v.replace(/(,|:|\)|\}|\]|>)"/gm,'$1AAA"');
			v = v.replace(/(:|\)|\}|\]|>)"/gm,'$1 "'); // «,»

//	1a	унарный минус и унарный плюс в диапазонах : − 5 … + 10 ° C . − 25 … − 30 градусов
			v = v.replace(/(…)(\s?)-\s?(\d+)/gm,'$1$2\u2212$3');	// &minus; , но не 1799–1837 гг.,
			v = v.replace(/(\s?)-\s?(\d+)\s?…/gm,'$1\u2212$2…');	// &minus; , но не 1799–1837 гг.,
			v = v.replace(/(…)(\s?)\+\s?(\d+)/gm,'$1$2+$3');			// +
			v = v.replace(/(\s?)\+\s?(\d+)\s?…/gm,'$1+$2…');

			// 5 … 10; −5 … +10 ° C. −25 … −30 градусов
			v = v.replace(/(\d)\s?…\s?(\+|\u2212)?(\d)/gm,'$1…$2$3');


	/* последовательность перенесена из-за обработки … */
	//	3.	Кавычки не отбиваются пробелами от заключённого в них текста: броненосец «Потёмкин».

			//Убирает пробельные символы поcле ({[<
			v = v.replace(/(\(|\{|\[|<)\s+/gm,'$1');

	//	4.	Скобки не отбиваются пробелами 
	//			4а	от заключённого в них текста, 
	//			4б	и отбиваются пробелами снаружи 
	//		(кроме того случая, когда закрывающая скобка соседствует с знаком препинания справа):  слово( раз )слово слово{ два }слово слово[ три ]слово ,( раз ) ,слово{ два } ,слово[ три ] .

			// 4а - см. 3
			// 4б
			v = v.replace(/([^\s\(\{\[])(\(|\{|\[)/gm,'$1 $2');

	//	5.	Тире отбивается от предыдущего слова неразрывным пробелом, а от следующего — обычным пробелом 
	//		(в том числе и в случае, если интервал указан в словесной, а не цифровой форме).
	//		Витенька&nbsp;— молодец!
	//		нам подойдёт только огурец длиной пятнадцать&nbsp;— двадцать сантиметров
	//		пакт Молотова&nbsp;— Риббентропа.
			/* будет реализованно после интервалов */
	//	6.	Если два числа в словесной форме не образуют интервал, а означают «то ли одно число, то ли другое», 
	//		то между ними ставится дефис, который не отбивается пробелами: выпил рюмки две-три.
			/* будет реализованно после интервалов */

	//	+7.	запятые перед: а, но
			v = v.replace(/([^,])\s(а|но)\s/gm,'$1, $2 ');

	// 	+8   после точки, перед кавычкой - пробел
	//		v = v.replace(/\."/gm,'. "'); НЕВЕРНО !!! исправить при разборе кавычек

	/* § 86. Пишутся через дефис: (http://gramota.ru/spravka/rules/?rub=def&text=19_23) */
	// 1. Сложные предлоги из за, из под, по над, по за.
	v = v.replace(/(^|[^А-Яа-я])(из)\s?-?\s?(за)([^А-Яа-я])/gim,"$1$2\u2011$3$4"); // неразрывный дефис
	v = v.replace(/(^|[^А-Яа-я])(из)\s?-?\s?(под)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	v = v.replace(/(^|[^А-Яа-я])(по)\s?-?\s?(над)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	v = v.replace(/(^|[^А-Яа-я])(по)\s?-?\s?(за)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	// 2. Сложные междометия и звукоподражания, например: ей богу, ей же ей, о го го, ха ха ха, ой ой oй, цып цып, динь динь динь.
	v = v.replace(/(^|[^А-Яа-я])(ей)\s?-?\s?(богу)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	v = v.replace(/(^|[^А-Яа-я])(ей)\s?-?\s?(же) ?-? ?(ей)([^А-Яа-я])/gim,"$1$2\u2011$3\u2011$4$5");
	v = v.replace(/(^|[^А-Яа-я])(о)\s?-?\s?(го)\s?-?\s?(го)([^А-Яа-я])/gim,"$1$2\u2011$3\u2011$4$5");
	v = v.replace(/(^|[^А-Яа-я])(ха)\s?-?\s?(ха)\s?-?\s?(ха)([^А-Яа-я])/gim,"$1$2\u2011$3\u2011$4$5");
	v = v.replace(/(^|[^А-Яа-я])(ой)\s?-?\s?(ой)\s?-?\s?(ой)([^А-Яа-я])/gim,"$1$2\u2011$3\u2011$4$5");
	v = v.replace(/(^|[^А-Яа-я])(цып)\s?-?\s?(цып)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	v = v.replace(/(^|[^А-Яа-я])(динь)\s?-?\s?(динь)\s?-?\s?(динь)([^А-Яа-я])/gim,"$1$2\u2011$3\u2011$4$5");
	// 3. 3. Слова с частицей кое-, кой-, -ка, -либо, -нибудь, -то, -тка, -с, -де, 
	// например: кое-что, кое-кто, кое-какой, кой-куда, кто-нибудь, кто-либо, кто-то, давай-ка, как-нибудь, как-либо, как-то, ну-тка, да-с. 
	v = v.replace(/(^|[^А-Яа-я])(кое|кой) /gim,"$1$2\u2011");
	v = v.replace(/(^|[^А-Яа-я])(кто|как)\s?-?\s?(нибудь)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	v = v.replace(/(^|[^А-Яа-я])(кто|как)\s?-?\s?(либо)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	v = v.replace(/(^|[^А-Яа-я])(кто|как|какие|где|когда|почему|что|чем)\s?-?\s?(то)/gim,"$1$2\u2011$3");
	v = v.replace(/(^|[^А-Яа-я])(да)\s(с)([^А-Яа-я])/gim,"$1$2\u2011$3$4");
	v = v.replace(/([а-я]+)\s(де|ка|тка|кась)([^А-Яа-я])/gm,"$1\u2011$2$3");
	// Примечание 1. Местоимения кое-кто и кое-что при сочетании с предлогами пишутся раздельно (в три слова), например:
	// кое у кого, кое в чем. Местоимение кое-какой при сочетании с предлогом пишется в три слова: кое с какими, или в два: с кое-какими. 
	v = v.replace(/(^|[^А-Яа-я])(кое|кой)\s?\u2011?\s?(у|в|с|от|на)\s/gim,"$1$2 $3 ");
	// Примечание 2. Частица таки пишется через дефис в составе слов все-таки и так-таки, а также в тех случаях, когда она следует за глаголом, 
	/* когда она следует за глаголом - это не реализованно */
	// например: Узнал-таки меня? Во всех остальных случаях частица таки пишется отдельно, например: Я таки думаю кое-что (М. Горький). 
	// И все ж таки я тебя не понимаю. 
	v = v.replace(/(^|[^А-Яа-я])(всё|все|так)\s?-?\s?(таки)([^А-Яа-я])/gim,"$1$2\u2011$3$4");

	/* http://habrahabr.ru/blogs/typography/23250/ ==============================================================*/

	/* НЕРАЗРЫВНЫЕ ПРОБЕЛЫ */

	// http://gramota.ru/biblio/public/32_8
	// Пробелы ставятся:

	// 1) В сокращениях типа: и т. д. (и так далее), и т. п. (и тому подобное), до н. э. (до нашей эры), н. э. (нашей эры), т. к. (так как),
	// т. е. (то есть), т. н. (так называемый), т. о. (таким образом), мн. ч. (множественное число), ед. ч. (единственное число),  им. п. (именительный падеж), 
	// ср. р. (средний род), ст. 14 (статья 14), п. 6 (пункт 6), пп. 3 (подпункт 3), 150 руб. (рублей), 300 стр. (страниц), вт. (вторник).
	// все элементы сокращения отделяются неразрывным пробелом:

	// т.#д.,  т.#п., т.#к., т.#е., т.#н., т.#о., мн.#ч., ед.#ч.,  н. э., 

	// http://www.gramota.ru/spravka/rules/?rub=sokr

	/* в целом, можно считать что все конструкции типа: ([а-я]{1,2}\.) ?([а-я]{1,2}\.|\d) попадают под правило $1 $2 */

	//v = v.replace(/(^|\s|\(|{|\[|"|>)([а-я]{1,2}\.)\s?(?=[а-я]{1,3}\.?|\d)/gm,"$1$2\u00A0"); // \u00A0
	// трех составные
	//v = v.replace(/\s([а-я]{1,2}\.)\s?([а-я]{1,2}\.|\d)/gm,"\u00A0{$1}\u00A0($2)"); // \u00A0

	//v = v.replace(/(?= )(?=( [а-я]{1,2}\.)+(?!([а-я]{1,2}\.)))/gm, "@"); //thinsp

	//v = v.replace(/( [а-я]{1,2}\.) ?([а-я]{1,2}\.) ?([а-я]{1,2}\.)?/gm, "$1@$2@$3"); //thinsp

	v = v.replace(/( [а-я]{1,2}\.) ?([а-я]{1,2}\.) ?([а-я]{1,2}\.)?/gm, function(s,s1,s2,s3)
		{
		if (s3)
			return s1+'\u00A0'+s2+'\u00A0'+s3;
		else	return s1+'\u00A0'+s2+' ';
		}); 

	// после сокращения {1,4} идут цифры
	v = v.replace(/(^|\s|\(|{|\[|"|>)([а-я]{1,4}\.|№|§)\s?(\d|[IVXLCDM])/gm,"$1$2\u00A0$3"); // \u00A0

	v = v.replace(/([\d]+) ?(ам|г|кг|б|кб|ккал|мб|гб|dpi|px|км|м|дм|см|мм|мкм|мк|нм|пм|фм|ам|V)([^а-я\d_-])/gm,"$1"+thinsp+"$2$3"); // thinsp

	// кубические, квадратные метры
	v = v.replace(/([\d]+)\s?(км|м|дм|см|мм)3([^\d]|$)/gm,"$1"+thinsp+"$2³$3");
	v = v.replace(/([\d]+)\s?(кб\.?)\s?(км|м|дм|см|мм)([^\d]|$)/gm,"$1"+thinsp+"$3³$4");
	v = v.replace(/([\d]+)\s?(км|м|дм|см|мм)2([^\d]|$)/gm,"$1"+thinsp+"$2²$3");
	v = v.replace(/([\d]+)\s?(кв\.?)\s?(км|м|дм|см|мм)([^\d]|$)/gm,"$1"+thinsp+"$3²$4");

	// после цифры сокращение
	v = v.replace(/(\d|[IVXLCDM]) ?([а-я]{1,3}\.|%[^-])/gm,"$1\u00A0$2"); // 20^% (но: 20%-ный) см. п. 6

	// 2. Инициалы отбиваются друг от друга и от фамилии неразрывным пробелом.
	// А.^С.^Пушкин Дж.^Р.^Р.^Толкиен В.^Путин Сидоров А.^П.
	v = v.replace(/([А-ЯA-Z][а-яa-z]?\.) ?(?=[А-ЯA-Z])/gm,"$1\u00A0");
	// Путин^В.В.
	v = v.replace(/([А-ЯA-Z][а-яa-z]+) (?=[А-ЯA-Z]\.)/gm,"$1\u00A0");

	// 3. Перед единицами измерения: 20 м, 220 V, 15 см, 7 мм, 10 кг, 699 ккал, 33 кв. м, +3 °C.

		// Заменяет С и F в конструкциях градусов на неразрывной пробел, °C и °F соответственно
		v = v.replace(/(([-+±])(\s?))?([\d]+)([.,]?)\s?([\d]*)?\s?(\u00B0|\u00BA)?\s?(C|F)\b/gm,"$2$4$5$6"+thinsp+"\u00B0$8"); // thinsp
		//v = v.replace(/([-+])?([\d]+)([.,]?)\s?([\d]*)?(\s)?(\u00B0)?(F)\b/gm,"$1$2$3$4^°F");

	// 4. Сокращённое слово отбивается от имени собственного неразрывным пробелом.
	// ул.^Щорса г.^Москва метрополитен им.^Ленина & гл.^IV
	// 4а) В сочетаниях «сокращенное родовое название + топоним»: г. Москва, ул. Акад. Королева, д. 13, корп. 2, респ. Татарстан, ст. м. «Выхино», пос. Егоровка.


	// почтовые сокращения 
	v = v.replace(this.rPS, "$1$2\u00A0");  

	// географические сокращения
	v = v.replace(this.rGS, "$1$2\u00A0");  

	// 5) В сокращенных названиях должностей и ученых званий: к. ю. н. (кандидат юридических наук), д. т. н. (доктор технических наук), асс. Борменталь, проф. Преображенский.

	// прочие сокращения
	v = v.replace(this.rOS, "$1$2\u00A0");  

	// 6) Между числом и символом: № 38, 20 % (но: 20%-ный), 4 х 4. 3 + 2.
	v = v.replace(/([0-9]+)\s?(x|х)\s?(?=[0-9]+)/gm,"$1\u00A0×\u00A0");
	v = v.replace(/([0-9]+)\s?\+\s?(?=[0-9]+)/gm,"$1\u00A0+\u00A0");

	// 7) При обозначение даты (перед словом «год»/«года»): 01.01.2008 г.
	//???

	// 8) В многозначных целых числах при разделении на группы (по три цифры справа налево): 55 000, 1 995 650, 9 000.
	// Все, окончательное решение найдено. Регулярное выражение для разделения числа на разряды выглядит так:
	//		http://m-ivanov.livejournal.com/6653.html

	// см. ниже

	// 9) Перед скобками при обозначении мужского/женского пола, дополнения/исключения, перед скобками с восклицательным знаком: уважаемый (ая); и (или); доход (заработная плата); 100 тыс. руб. (!). 
	// ???

	// 10) [4]	Число и соответствующее ему счётное слово отбиваются неразрывным пробелом.
	//			12^млрд рублей гл.^IV пп.^3—6 рис.^42 XX^в. 1941—1945^гг. палата №^6 §^22 25^% 97,5^? 16^¢

	// Денежные суммы, расставляя пробелы в нужных местах.
	v = v.replace(/(\d)\s?(млрд|млн|тыс\.)/g,"$1\u00A0$2");
	v = v.replace(/(\d)\s?(руб\.|долл\.|евро|у\.е\.|уе|ye|€|¢|\$)/g,"$1\u00A0$2");

	// 11) [5]	Знаки градуса, минуты и секунды отбиваются тонкой шпацией от последующих цифр. 59°57′00″ — 59°&thinsp;57′&thinsp;00″
	v = v.replace(/([\d]+)(\u00B0|\u00BA)\s?([\d]+)(′|')\s?([\d]+)(″|")/gm,"$1°"+thinsp+"$3′"+thinsp+"$5″"); // thinsp

	// 12
	//Делает неразрывными названия организаций и аббревиатуру формы собственности
	v = v.replace(/(АООТ|АОЗТ|ГП|ИП|ИЧП|ОАО|ЗАО|МП|НПО|ОО|ООО|СП|ТОО|ЧП|НПФ|НИИ|в\/ч)\s+(?=.*)/gm,"$1\u00A0");

	/* Пробел не ставится (так как нет нового слова): */
	// 1) Перед многоточием: Весна – это…
	// 2) Перед обозначением дома с буквой: д. 25а.
	// исправляем
	v = v.replace(/(д\.\s\d+)\s/gm,"$1");
	// 3) При обозначении формата бумаги: А4, А6, А5.
	// 4) В датах между цифровым обозначением дня, месяца и года: 01.01.2008 г.
	// 5) В сочетании с дефисом пробел не ставится никогда: «Оскар-2008», Мышка-норушка.
	// ???

	/* О собого внимания заслуживает вопрос постановки пробелов в сочетании с тире. Здесь существуют четкие правила: */

	// 1) Тире без пробелов при цифровом обозначении интервала или диапазона: 1799–1837 гг., 10:00–18:00.

		// цифровые диапазоны
		v = v.replace(/(\d+)\s?-\s?(?=[\d]+)/gm,"$1\u2012");

		// добиваем телефоны
		v = v.replace(/(\d{3}) |\u2012(\d{3}\u2012\d{2}\u2012\d{2})/gm,"$1\u00A0$2");
		v = v.replace(/(\+7|8) (\(?\d{2,3}\)?)/gm,"$1\u00A0$2");
	
		// ПЕРИОДЫ
		// года
		v = v.replace(/([\d]{4})\s?\u2012\s?([\d]{4})\s?([г\.\s]+)(,?)(\s+|$)/gm,"$1\u2013$2\u00A0гг.$4$5"); //Среднее тире EN DASH 
		// коррекция года
		v = v.replace(/([\d]{2}\.[\d]{2}\.([\d]{2}|\d{4}))\sг./gm,"$1\u00A0г."); 
		// коррекция года 2
		v = v.replace(/(\d{4})\sгод/gm,"$1\u00A0год"); 
		
		//
		// века
		v = v.replace(/([IVXLCDM]+)\s?-\s?([IVXLCDM]+)\s?([в\.\s]+)(,?)(\s+|$)/gm,"$1\u2013$2\u00A0вв.$4$5");

		// время
		// сначала корректируем
		v = v.replace(/([\d]{1,2})\s?:\s?([\d]{2})/gm,"$1:$2");
		v = v.replace(/([\d]{1,2}:[\d]{2}) ?\u2012 ?([\d]{1,2}:[\d]{2})/gm,"$1\u2013$2");
		

	// 2) Тире с пробелами при словесном обозначении интервала или диапазона: июнь – август, Москва – Владивосток.

		v = v.replace(/(январь|февраль|март|апрель|июнь|июль|август|сентябрь|октябрь|ноябрь|декабрь)\s?-\s?(январь|февраль|март|апрель|июнь|июль|август|сентябрь|октябрь|ноябрь|декабрь)/gim,"$1 \u2013 $2");				
		v = v.replace(/(понедельник|вторник|среда|четверг|пятница|суббота|воскресенье)\s?-\s?(понедельник|вторник|среда|четверг|пятница|суббота|воскресенье)/gim,"$1 \u2013 $2");

	// 3) Тире с пробелами при обозначении двойного авторства: пакт Риббентропа – Молотова, закон Бойля – Мариотта.
		// см. выше
	// 4) Тире с пробелами при обозначении объекта или события, если его характеристика – это словосочетание: «Мужчина года – 2007», Бычок – смоляной бочок.
		v = v.replace(/([А-Яа-я ]+)\s-\s?(.)/gm,"$1 \u2013 $2"); // соответственное второй пункт можно не выполнять

	//	5.	Тире отбивается от предыдущего слова неразрывным пробелом, а от следующего — обычным пробелом 
	//		(в том числе и в случае, если интервал указан в словесной, а не цифровой форме).
	//		Витенька&nbsp;— молодец!
	//		нам подойдёт только огурец длиной пятнадцать&nbsp;— двадцать сантиметров
	//		пакт Молотова&nbsp;— Риббентропа.

			/* не со всем я здесь согласен…, далее это правило будет скорректированно */

			v = v.replace(/(\s)(\-|\u2013)(\s)/gm,'\u00A0\u2013 ');
	//	6.	Если два числа в словесной форме не образуют интервал, а означают «то ли одно число, то ли другое», 
	//		то между ними ставится дефис, который не отбивается пробелами: выпил рюмки две-три.
	//			Санкт-Петербург , Ростов-на-Дону
			v = v.replace(/([А-Яа-я])\-(?=[А-Яа-я])/gm,'$1\u2011'); // неразрывный

	/* Числа и интервалы, по материалам: http://habrahabr.ru/blogs/typography/23250/ */
	// 1. Дробная и целая части числа не отбиваются пробелом от запятой:
	//		0,62, 345,5. - это лежит на человеческой совести
	// 2. Разряды числа отбиваются друг от друга тонкой шпацией, кроме дат, номеров (например, документов), обозначений машин и механизмов.
	//		25 563,42 — 25^563,42; 1 652 — 1^652; 1 298 300 — 1^298^300; 
	//		но 1999 год, ГОСТ 20283, вх. № 982364 (здесь у нас будет NBSP)
	// 3. При численном обозначении интервалов тире не отбивается от границ интервала.
	//		50—100 м — 50—100^м; 1 500—2 000 — 1^500—2^000; 1,5—2 тыс. — 1,5—2^тыс. 15—20 % — 15—20^%
	// 4. Унарные знаки плюс, минус и плюс-минус не отбиваются от следующего за ним числа:
	//		+20^°C, −42, ±0,1.
	// 5. Бинарные знаки математических операций и соотношений отбиваются с обеих сторон на тонкую шпацию.
	//		2 + 3 = 5 — 2^+^3^=^5

	// ставим разделители сотен, если это не год или атрибут или диапазон
//	v = v.replace(/(^| |\(|\{|\[|\>)(\d{4,}[^\u00A0\u2012\u2013"])/gm, function(s, s1, s2)
//		{
//		return s1+s2.replace(/(?=\d)(?=(\d{3})+(?!\d))/gm, thinsp); //thinsp
//		}); 
	//v = v.replace(/(?=\d)(?=(\d{3})+(?![\d\u2013\u00A0"]))/gm, thinsp); //thinsp


	// Последовательность символов пробел-дефис-пробел в большинстве случаев означает, что здесь должно стоять тире. 
	// Поскольку тире не должно отрываться от предшествующего текста и появляться на следующей строке, перед ним необходимо 
	// поставить неразрывный пробел. Таким образом, шаблон-замена принимает указанный вид.
	
	/* ПРЯМАЯ РЕЧЬ */
	// http://www.gramota.ru/spravka/rules/?rub=znapr
	// § 195
	v = v.replace(/^-\s/gm,"\u2014"+thinsp);
	// § 196 в) разрыв прямой речи на две части; 
		/* это мы реализовать не сможем */
		// скорей всего то ж - прямая, НЕТ ! прямую речь надо начинать с новой строки, иначе не отловить
		//v = v.replace(/\. - ([А-ЯA-Z])/gm,". \u2014"+thinsp+"$1");
	//§ 197
		/* сложно реализовать полностью и правильно */

	/* ПРОЧИЕ ТИРЕ */ 
	v = v.replace(/\s-$/gm,"\u00A0\u2013");

	/* НЕ ОТРАБОТАННЫЕ ДЕФИСЫ */ 
	v = v.replace(/-/gm,"\u2011"); // неразрывный дефис  Оскар^‑^2008 Coca^‑^Cola UTF^‑^8 e^‑^mail
	// коррекция
	v = v.replace(/(\s)\u2011(\d)/gm,"$1\u2212$2"); 
	/* Нежелательные переносы */

	// 1. Короткие слова и союзы (а, и, но, я, ты, и так далее) лучше отбивать от последующего слова неразрывным пробелом, 
	// так как висящее на конце строки короткое слово ухудшает читаемость. 
	// В том числе очень желательно не допускать переноса строки между частицей не и следующим за ней глаголом.

	// СОЮЗЫ
	// http://studysphere.ru/work.php?id=322
	// Сочинительные союзы: и, а, но, да, или, либо, ни–ни, то–то, зато, однако, же; то ли – то ли, не то – не то.
	// Подчинительные союзы: что, чтобы, когда, как, как только, между тем как, лишь, лишь только, едва, едва лишь, пока и др.;
	// ибо, потому что, оттого что, так как, из-за того что и др.;
	// чтобы, дабы и др.;
	// если, если бы, ежели, ежели бы, коли (коль), когда, когда бы, раз и др.;
	// хотя (хоть), хотя бы, пусть, даром что и др.;
	// как, как бы, как будто, будто, будто бы, словно, словно как, точно и др.;
	// так что. 

	v = v.replace(this.rSO, "$1$2\u00A0");
	v = v.replace(this.rSO2, "$1$2\u00A0");  

	//	2.	Частицы же, бы, ли желательно отбивать от предыдущего слова неразрывным пробелом: то^же, сказал^бы, думал^ли я.

	re = new RegExp(" (бы|ли|же|б|ль|ж)( |\\.|,|!|\\?|:|;)", "ig");
	v = v.replace(re,"\u00A0$1$2");

	/* телефонные номера http://www.artlebedev.ru/kovodstvo/sections/91/ */

	var op = 0, pop = 0;



	v = v.replace(/([^"\s]*)(["\s]?)/gm,function(s,s1,s2)
		{
//DD.push('>'+s+'< >'+s1+'< >'+s2+'<');
		if (s2 == '"')
			{
			switch(op)
				{
				case 0:	pop=op; op = 1;
						if ((s1.length) && (s1.substring(s1.length-1) == '.'))
							return s1+" «";
						else	return s1+"«";
						break;

				case 1:	

//DD.push(s1);
//DD.push(pop);
						if ((s1) || (pop==2))
							{
							pop=op; op = 0;
							return s1+"»";
							}
						else	{
							pop=op; op = 2;
							return s1+"„";
							}
						break;

				case 2:	if (s1)
							{
							pop=op; op = 1;
							return s1+"“";
							}
						else	{
							_self.TERRORS.push('<ul><li><div><span class="error e1"><strong>ТИПОГРАФ: </strong></span>ошибка при расстановки кавычек: '+v+'</div></li></ul>');
							return s;
							}
						break;
				}
			}
		pop=op;
		return s;
		});

	if (op > 0)
		{_self.TERRORS.push('<ul><li><div><span class="error e1"><strong>ТИПОГРАФ: </strong></span>пропущена кавычка ['+v+']</div></li></ul>')}

	v = v.replace(/\u2024/gm,".");

	v = v.replace(/(«…)\s/gm,'$1');
	v = v.replace(/(»…)\s?/gm,'$1 ');

	v = v.replace(/&/gm,'&amp;');
	v = v.replace(/</gm,'&lt;');
	v = v.replace(/>/gm,'&gt;');
	// ушоб не зацепило :)
	v = v.replace(/\s?\(r\)/gim,"<sup><small>®</small></sup>");
	v = v.replace(/\s?\(tm\)|\(тм\)/gim,"<sup>™</sup>");

	/* возвращаем теги, ссылки, e-mail */
	while(save.length > 0)
		{
		re = new RegExp(String.fromCharCode(save.length+bbIndex)); // Пользовательская зона":"E000,F8FF"
		v = v.replace(re, save.pop());
		}

	return v;
	}


DiGraph.prototype.noTypoRules = function(v) // для расстановки тегов
	{
	//alert('|'+v+'|');
	//return v.replace(/\s+/gm,'\u0020');
	return v;
	}
DiGraph.prototype.TypographRun = function()
	{
	
	// НИКОГДА !!! не проводить обработку строк непостредственно в textarea, т.е. this.e.value, IE & Opera делают преобразование "на лету": \n -> \r\n !!!

	var _self = this;
	var result = true;
	
	HTMLParser(this.e.value, this);

	if(this.TERRORS.length){result = false}	

	for(var i = 0, L=ParserIndex.length; i < L; i++)
		{
		ParserTags[ParserIndex[i]] = this.TR(ParserTags[ParserIndex[i]]);
		}

	// bbCode
	ParserTags = ParserTags.join('');
	for(var i in bbCode)	
		{
		re = new RegExp(String.fromCharCode(i)); // Пользовательская зона":"E000,F8FF"
		ParserTags = ParserTags.replace(re, bbCode[i]);
		}
	
	window.setTimeout(function(){_self.TypographPost(ParserTags, result)}, 50);
	}

DiGraph.prototype.responseAjax = function(_self, error, text)
	{
	var result = true;

	if (error)
		{
		_self.TERRORS.push('<ul><li><div><span class="error e1"><strong>...</strong></span>'+error+'</div></li></ul>');
		result = false;
		}
	if (!text)
		{
		_self.TERRORS.push('<ul><li><div><span class="error e1"><strong>...</strong></span>сервис вернул "пустой" результат...</div></li></ul>');
		result = false;
		text = _self.e.value;
		}
	if (text == 'Ошибка: текст больше 30 килобайт')
		{
		_self.TERRORS.push('<ul><li><div><span class="error e1"><strong>...</strong></span>'+text+'</div></li></ul>');
		result = false;
		text = _self.e.value;
		}

	window.setTimeout(function(){_self.TypographPost(text, result)}, 50);
	}


DiGraph.prototype.Typograph = function(b)
	{
	var button = DiGraphRunTime[b.id];

	$(this.rid+"-validatorbox").hide(0);
	this.SaveState();

	$("#digraph-wait-title").html(button.title);
	$("#digraph-wait").overlay().load();		

	var _self = this;

	switch (button.mode)
		{
		case 'typograph':
				this.TR = this.TypoRules; 
				window.setTimeout(function(){_self.TypographRun()}, 50);	
				break;

		case 'parsing':
				this.TR = this.noTypoRules; 
				window.setTimeout(function(){_self.TypographRun()}, 50);	
				break;

		case 'typograf.ru':
				$.ajax(
					{
					url: this.path+'php/typograf.php'
					,type: "POST"
					,data: {text: _self.e.value, skey: _self.skey}
					,dataType: "json"
					,error: function (xhr, desc, exceptionobj){_self.responseAjax(_self, xhr.responseText)}
					,success : function (json){_self.responseAjax(_self, json.error, json.text)}
					});	
				break;

		case 'artlebedev.ru':
				$.ajax(
					{
					url: this.path+'php/artlebedev.php'
					,type: "POST"
					,data: {text: _self.e.value, skey: _self.skey}
					,dataType: "json"
					,error: function (xhr, desc, exceptionobj){_self.responseAjax(_self, xhr.responseText)}
					,success : function (json){_self.responseAjax(_self, json.error, json.text)}
					});	
				break;

		}
	}