Выделите символы с диакритическими знаками

Я использую подключаемый модуль jquery.highlight: http://code.google.com/p/gce-empire/source/browse/trunk/jquery.highlight.js?r=2

Когда я ищу слово с акцентом, например. "кафе", он не будет выделять совпадения "кафе"... Однако с "кафе" все работает нормально.. Итак, я хочу иметь возможность выделять слова с акцентом... Любая идея о том, как это сделать с этим плагин?

Спасибо!

EDIT Хорошо, это работает, но мне пришлось добавить пробел между первым "(" и последним ")" в переменных "pattern" и "patternNoAccents", потому что если бы был акцентированный символ в начале или в конце слова, это не сработает (например, «кафе»)

Проблема в том, что он выделяет слово И пробел до и после. Есть ли другое решение?

jQuery.extend({
            highlight: function (node, re, nodeName, className) {
                if (node.nodeType === 3) {
                    var match = node.data.match(re);
                    if (match) {
                        var highlight = document.createElement(nodeName || 'span');
                        highlight.className = className || 'highlight';
                        var wordNode = node.splitText(match.index);
                        wordNode.splitText(match[0].length);
                        var wordClone = wordNode.cloneNode(true);
                        highlight.appendChild(wordClone);
                        wordNode.parentNode.replaceChild(highlight, wordNode);
                        return 1; //skip added node in parent
                    }
                } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
                        !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
                        !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
                    for (var i = 0; i < node.childNodes.length; i++) {
                        i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
                    }
                }
                return 0;
            }
        });

        jQuery.fn.unhighlight = function (options) {
            var settings = { className: 'highlight', element: 'span' };
            jQuery.extend(settings, options);

            return this.find(settings.element + "." + settings.className).each(function () {
                var parent = this.parentNode;
                parent.replaceChild(this.firstChild, this);
                parent.normalize();
            }).end();
        };

        function stripAccents(str) { 
                var rExps=[ 
                {re:/[\xC0-\xC6]/g, ch:'A'}, 
                {re:/[\xE0-\xE6]/g, ch:'a'}, 
                {re:/[\xC8-\xCB]/g, ch:'E'}, 
                {re:/[\xE8-\xEB]/g, ch:'e'}, 
                {re:/[\xCC-\xCF]/g, ch:'I'}, 
                {re:/[\xEC-\xEF]/g, ch:'i'}, 
                {re:/[\xD2-\xD6]/g, ch:'O'}, 
                {re:/[\xF2-\xF6]/g, ch:'o'}, 
                {re:/[\xD9-\xDC]/g, ch:'U'}, 
                {re:/[\xF9-\xFC]/g, ch:'u'}, 
                {re:/[\xD1]/g, ch:'N'}, 
                {re:/[\xF1]/g, ch:'n'} ]; 
                for(var i=0, len=rExps.length; i<len; i++) 
                        str=str.replace(rExps[i].re, rExps[i].ch); 
                return str; 
        };

        jQuery.fn.highlight = function (words, options) {
            var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
            jQuery.extend(settings, options);

            if (words.constructor === String) {
                words = [words];
            }
            words = jQuery.grep(words, function(word, i){
              return word != '';
            });
            words = jQuery.map(words, function(word, i) {
              return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
            });
            wordsNoAccents = jQuery.map(words, function(word, i) {
              return stripAccents(word);
            });

            if (words.length == 0) { return this; };

            var flag = settings.caseSensitive ? "" : "i";
            var pattern = "( " + words.join("|") + " )";

            if (settings.wordsOnly) {
                pattern = "\\b" + pattern + "\\b";
            }

            var patternNoAccents = "( " + wordsNoAccents.join("|") + " )";

            if (settings.wordsOnly) {
                patternNoAccents = "\\b" + patternNoAccents + "\\b";
            }

            var re = new RegExp(pattern, flag);
            var reNA = new RegExp(patternNoAccents, flag);

            console.log(re);
                console.log(reNA);
            return this.each(function () {
                jQuery.highlight(this, re, settings.element, settings.className);
                jQuery.highlight(this, reNA, settings.element, settings.className);
            });
        };

person Santiago    schedule 23.05.2011    source источник


Ответы (3)


Посмотрите этот пример. http://jsfiddle.net/bNPjQ/ Если вы пройдете мимо Café, будут выделены как Cafe, так и Café. Не уверен, что это нужная функция, но я могу помочь вам, если вы хотите, чтобы она выделяла только кафе.

Я начал с оригинального плагина, добавил вашу функцию stripAccents, изменил одну строку и добавил вызов stripAccents в функцию выделения. Все, что я изменил, я отметил комментарием.

Когда вы запустите его, он сделает подсветку без слов, а затем через 2 секунды отменит выделение и сделает еще одно выделение с помощью слов.

person nemophrost    schedule 23.05.2011
comment
Кажется, кто-то вставил весь highlight.js в часть JavaScript - person Hardik Sondagar; 02.04.2014

Вы должны поместить специальный код символа HTML в тело текста.

Например:

Caf&eacute;

Затем в селекторе для примера плагина выделения ниже:

<a href="javascript:void($('#highlight-plugin').removeHighlight().highlight('Caf&eacute;'));">highlight</a>

Только что протестировал его, и он выделяет все экземпляры Caf в документе.

person ectype    schedule 23.05.2011
comment
Проблема в том, что я использую его для выделения результатов поиска, я отображаю результаты в UTF-8 с символами, как в кафе. - person Santiago; 23.05.2011
comment
Вы пытались вставить .highlight('Café')? - person ectype; 23.05.2011
comment
@ectype, только что попробовал запрограммированную функцию .highlight('café'); и не работал. С .highlight('кафе'); работает просто отлично. Это должно быть что-то о плагине jquery.highlight, когда он ищет DOM, чтобы добавить класс выделения или что-то в этом роде. - person Santiago; 23.05.2011
comment
Хорошо, это странно. Оно работает! Но когда ударение стоит в середине слова. Я имею в виду, если это в начале или в конце, это не работает! Кафе не сработает, а ресиен сработает. Я думаю, что это связано с настройкой wordsOnly, которая разделяет термины с помощью \\b - person Santiago; 23.05.2011
comment
Ну, это проблема. Если я изменю эту строку: var pattern = ( + words.join(|) + ); и добавьте пробел перед закрытием), это работает. Проблема в том, что он выделяет слово и пространство тоже... - person Santiago; 23.05.2011

Используйте http://highlightjs.org/ Прост в использовании и имеет множество вариантов выделения

person Hardik Sondagar    schedule 02.04.2014