User:Khanson/compare2texts.js

// //Скрипт для поиска совпадающих подстрок в двух текстах

//Этот код выполняется в начале. if (wgAction == 'edit' || wgAction == 'submit'){ addOnloadHook(XRomix_Compare2texts_OnLoad) }

///////////////////////////////////////////////////////////////////////////// function XRomix_Compare2texts_OnLoad{ //Этот код выполнится после загрузки страницы var toolbar = document.getElementById('toolbar') var textbox = document.getElementById('wpTextbox1') if (!textbox || !toolbar) return addToolbarButton("Сравнение", XRomix_Compare2texts, 'btnXRomix_Compare2texts', 'Сравнение двух текстов', ""); //Adds a text button to edit toolbar function addToolbarButton(name, onclick, id, tooltip, accesskey){ var toolbar = document.getElementById('toolbar'); if (!toolbar) return; var newBtn = document.createElement('input'); newBtn.type = 'button'; newBtn.style.background = '#adbede'; newBtn.style.height = '22px'; newBtn.style.verticalAlign = 'middle'; if (name) newBtn.value = name; if (onclick) newBtn.onclick = onclick; if (id) newBtn.id = id; if (tooltip) newBtn.title = tooltip; if (accesskey) newBtn.accessKey = accesskey; toolbar.appendChild(newBtn); return newBtn; } } ///////////////////////////////////////////////////////////////////////////// function insertAfter(parent, node, referenceNode) { parent.insertBefore(node, referenceNode.nextSibling); } ///////////////////////////////////////////////////////////////////////////// function XRomix_Compare2texts{ XRomix_CreateNewTextbox; }

///////////////////////////////////////////////////////////////////////////// function XRomix_CreateNewTextbox{ //var input = document.getElementById('wpSummary') var input = document.getElementById('wpTextbox1') if (!input) return var el = document.getElementById('XRomix_wpTextbox2') if (el) { removeElementById('XRomix_wpTextbox2'); return; } var el = document.createElement('span') el.id = 'XRomix_wpTextbox2'; el.style.marginLeft = '3px' input.parentNode.insertBefore(el, input.nextSibling) el.innerHTML = ' Текст в окне ниже не будет сохранён на сервер.\ \ \   \ \  \  '; //Вспомогательные функции function removeChildrenRecursively(node) {         if (!node) return; while (node.hasChildNodes) { removeChildrenRecursively(node.firstChild); node.removeChild(node.firstChild); }     }     function removeElementById(nodeId) { document.getElementById(nodeId).parentNode.removeChild(                                document.getElementById(nodeId)); }  }

///////////////////////////////////////////////////////////////////////////// function XRomix_Compare2texts_Compare(mode){ //////////////////////////////////////	// Переменные для функции var XRomix_maxP1; //позиция максимально совпадающих фрагментов var XRomix_maxP2; var XRomix_max1;//длина максимвльно совпадающих фрагментов var XRomix_max2; var XRomix_len1;//длина текущего соответствия для checkCompareLength var XRomix_len2; var XRomix_s1// тексты для сравнения. в них знаки препинания и прочие различия удалены, но число и позиция символов сохранена var XRomix_s2

var wpTextbox1=document.getElementById('wpTextbox1'); if(!wpTextbox1) return; if(mode=="first"){ var s= wpTextbox1.value; XRomix_s1=prepareText(s, true); //см. ниже }else if (mode=="next"){ var h1=document.getElementById('XRomix_h1'); XRomix_s1 = h1.value; }	var wpTextbox2=document.getElementById('XRomix_Textbox2'); if(!wpTextbox2) return; if(mode=="first"){ var s= wpTextbox2.value; XRomix_s2=prepareText(s, false); //см. ниже }else if (mode=="next"){ var h2=document.getElementById('XRomix_h2'); XRomix_s2 = h2.value; }		getMaxSameText; //см.ниже //alert("Совпадение1: "+wpTextbox1.value.substr(XRomix_maxP1, XRomix_max1)) //alert("Совпадение2: "+wpTextbox2.value.substr(XRomix_maxP2, XRomix_max2))

var sovp1=wpTextbox1.value.substr(XRomix_maxP1, XRomix_max1); var sovp2=wpTextbox2.value.substr(XRomix_maxP2, XRomix_max2); if(XRomix_max2>3){ selectInTextArea(wpTextbox1, sovp1); selectInTextArea(wpTextbox2, sovp2); setSelectionRange(wpTextbox1, XRomix_maxP1, XRomix_maxP1+XRomix_max1); setSelectionRange(wpTextbox2, XRomix_maxP2, XRomix_maxP2+XRomix_max2); wpTextbox1.focus; var label = document.getElementById('XRomix_ComparedText'); label.innerHTML=""+sovp2+" "; }else{ var label = document.getElementById('XRomix_ComparedText'); label.innerHTML="Совпадений не найдено "; //alert("Совпадений не найдено"); }	var s=XRomix_s1; var left=s.substr(0, XRomix_maxP1); var right=s.substr(XRomix_maxP1+XRomix_max1); var sp=generateSpaces(XRomix_max1); var XRomix_s1=left+sp+right; if(s.length!=XRomix_s1.length){ alert("Длина строк не совпадает"); }	var h1=document.getElementById('XRomix_h1'); h1.value=XRomix_s1; var h2=document.getElementById('XRomix_h2'); h2.value=XRomix_s2; //////////////////////////////////////	//Выполняет замену подстроки s1 на s2 в строке s. Сама строка s при этом не изменяется function replace(s, s1, s2){ var p=s.indexOf(s1); if (p<0) return; var left=s.substr(0, p); var right=s.substr(p+s1.length); return left+s2+right; }	//////////////////////////////////////	//генерирует строку из пробелов указанной длины function generateSpaces(len){ var s1=""; for(var i=0; i=0){ //если найдена конструкция "){					flagSpace=0;					c=" ";				}				if(flagSpace==1){					c=" ";				}				s1+=c;			}			s=s1;		}		s=s.replace(/\[\[/, " "); //[[ на два пробела		s=s.replace(/\]\]/, ""); //[[ на пустую строку, т.к. надо отработать еще слова наподобие  [[году		s=s+"  ";//добавляем два пробела в конец, чтобы скомпенсировать длину		return s;	}

//////////////////////////////////////	//Подготавливает текст function prepareText(s, delQuoutes){ //Заменяем знаки препинания на пробелы s=s.replace(/[\.\,\;\?\!\(\)\—\-\:\=\*]/g, " "); //Заменим викификацию var arr=s.match(/\[\[.*?\]\]([^\s])*/g); if(arr){ for(var i=0; i'+w1); s=replace(s, w, w1); }		}

//Убираем закавыченное, если передан такой параметр if(delQuoutes){ var arr=s.match(/«.*?»/g); if(arr){ for(var i=0; i<arr.length; i++){ var w=arr[i]; var w1=generateSpaces(w.length); //см. ниже s=replace(s, w, w1); }			}		}

//Убираем то что внутри [квадратных скобок] var arr=s.match(/\[.*?\]/g); if(arr){ for(var i=0; i<arr.length; i++){ var w=arr[i]; var w1=generateSpaces(w.length); //см. ниже s=replace(s, w, w1); }		}		//Убираем символы кавычек и апострофов s=s.replace(/[«»„“\"\']/g, " ");		//Убираем Википедии		var arr=s.match(/\{\{.*?\}\}/g);		if(arr){			for(var i=0; i<arr.length; i++){				var w=arr[i];				var w1=generateSpaces(w.length); //см. ниже				s=replace(s, w, w1);			}		}

//Переводим строку в нижний регистр s=s.toLocaleLowerCase; //Заменяем ё для целей сравнения s=s.replace(/ё/g, "е"); //Заменяем различные пробельные символы на пробел s=s.replace(/\s/g, " "); return s 	}

//////////////////////////////////////	//Измеряет длину совпадения в символах для строк XRomix_s1 и XRomix_s2 начиная с указанных позиций p1 и p2	function checkCompareLength(p1, p2){ var c1=XRomix_s1.charAt(p1); var c2=XRomix_s2.charAt(p2); if(c1!=c2){ XRomix_len1=0; // XRomix_len2=0; return false; }

var len1=XRomix_s1.length; var len2=XRomix_s2.length; var p1_=p1; //сохраняем позиции для вычисления длины var p2_=p2; var p1_nosp=-1; //позиция последнего совпадающего непробельного символа var p2_nosp=-1; for{ if(p1>=len1) break; if(p2>=len2) break; c1=XRomix_s1.charAt(p1); c2=XRomix_s2.charAt(p2); if((c1==" ") && (c2==" ")){ //отыскиваем первый непробельный символ для p1	    while(c1==" "){ p1++; c1=XRomix_s1.charAt(p1); if(p1>=len1) break; }		 //отыскиваем первый непробельный символ для p2	    while(c2==" "){ p2++; c2=XRomix_s2.charAt(p2); if(p2>=len2) break; }	  }

//Пропускаем мягкий перенос с кодом 173 (дес) или 0xAD if(c1=="\xAD"){ p1++; continue; }	 if(c2=="\xAD"){ p2++; continue; }	 //Пропускаем символ ударения if(c1=="́"){ p1++; continue; }	 if(c2=="́"){ p2++; continue; }	 if(c1==c2){ if(c1!=" ") p1_nosp=p1; if(c2!=" ") p2_nosp=p2; p1++; p2++; continue; }	 break; }		if(p1_nosp==-1){ //не совпал ни один символ XRomix_len1=0; // XRomix_len2=0; }else{ XRomix_len1=p1_nosp-p1_+1; // XRomix_len2=p2_nosp-p2_+1; }	 return true; }

////////////////////////////////////////////////////////////////////////////	//Отыскивает максимально совпадающий текст между XRomix_s1 и XRomix_s2 //Помещет его начальные указатели в XRomix_maxP1 и XRomix_maxP1, и длины в XRomix_max1 и XRomix_max1 function getMaxSameText{ XRomix_maxP1=0; XRomix_maxP2=0; XRomix_max1=0; XRomix_max2=0; var arr1 = new Array; //массивы позиций начала слова для ускорения поиска var arr2 = new Array; //Заполняем массив позициями начала слова var c=" "; var wasSp=1; //признак наличия пробела до текущего символа for(var i=0; i<XRomix_s1.length; i++){ c=XRomix_s1.charAt(i); if(c<=" "){ wasSp=1; continue; }else{ if(wasSp==0) continue; //пропускаем не первые буквы каждого слова wasSp=0; arr1.push(i); }		 }	  //Для второй строки делаем то же самое var wasSp=1; //признак наличия пробела до текущего символа for(var i=0; iXRomix_max2){ //сравниваем по второму тексту, т.к. там нет викификации XRomix_max1=XRomix_len1; XRomix_max2=XRomix_len2; XRomix_maxP1=p1; XRomix_maxP2=p2; }			}		}	 }	}

/////////////////////////////////////////////////////////////////////////////

function selectInTextArea(txtarea, text1){ //Обрезаем многострочный текст до одной строки - иначе поиск не срабатывает var arr=text1.split(/[\n\r]/); var max=""; //найдем максимальную по длине строку из многострочного фрагмента for(var i=0; i<arr.length; i++){ if (max.length<arr[i].length){ max=arr[i]} }		text=max; if (txtarea.setSelectionRange) {//Mozilla/Opera var selPos = txtarea.value.indexOf(text) if (selPos < 0) return txtarea.focus txtarea.setSelectionRange(0, 0);//перейдем в начало

//http://www.dynamicdrive.com/dynamicindex11/findpage.htm var caseSensitive = true // is search case sensitive? var backwards = false //should we also search backwards? var wrapAround = true // should we wrap the search? try{ self.find(text, caseSensitive, backwards, wrapAround); }catch(e){ }		}else if (txtarea.createTextRange){ //IE var oRange = txtarea.createTextRange if (oRange.findText(text)) oRange.select }	}

//подсчитывает концы строк в фрагменте текста function countCrlf(str){ var cnt=0; for(var i=0; i 20031000 || is_safari)) { //Mozilla/Opera/Safari3 input.setSelectionRange(start, end); }else if (document.selection && document.selection.createRange) { //Internet Explorer var range = input.createTextRange; range.collapse(true); range.moveStart("character", start - countCrlf(input.value.substring(0, start))); range.moveEnd("character", end - start - countCrlf(input.value.substring(start, end))); range.select; }	 	};

}//function

///////////////////////////////////////////////////////////////////////////// function XRomix_btnCompare2texts_Compare{ XRomix_Compare2texts_Compare("first"); var wpSummary = document.getElementById('wpSummary') if(wpSummary){ var temp=wpSummary.value; temp=temp.replace(/\/\*.*?\*\//, ""); //комментарии temp=temp.replace(/[\s]*/, ""); //пробелы if (temp==""){ var s=wpSummary.value; s+=" compare2texts.js - поиск совпадений"; if (s.length<200) wpSummary.value=s; }	} }

//////////////////////////////////////////////////////////////////////////// function XRomix_btnCompare2texts_CompareNext{ XRomix_Compare2texts_Compare("next"); } //