Spec-Zone.ru › Elisp

Функции поиска текстовых свойств

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

Вот функции, которые можно использовать для этого. Для сравнения значений свойств они используют eq. Во всех случаях значение object по умолчанию — текущий буфер.

Для хорошей производительности очень важно использовать аргумент limit этих функций, особенно функций, выполняющих поиск по одному свойству: в противном случае они могут долго сканировать буфер до конца, если интересующее вас свойство не меняется.

Эти функции не перемещают точку; вместо этого они возвращают позицию (или nil). Помните, что позиция всегда находится между двумя символами; позиция, возвращаемая этими функциями, находится между символами с различными свойствами.

Функция: next-property-change pos &optional object limit

Функция сканирует текст в строке или буфере object вперёд, начиная с позиции pos, пока не обнаружит изменение какого-либо текстового свойства, после чего возвращает позицию этого изменения. Иными словами, она возвращает позицию первого символа после pos, свойства которого не идентичны свойствам символа сразу после pos.

Если limit не равен nil, сканирование заканчивается на позиции limit. Если до этой позиции изменений свойств нет, функция возвращает limit.

Значение равно nil, если свойства остаются неизменными до конца object и limit равен nil. Если значение не равно nil, оно представляет собой позицию, большую или равную pos. Значение равно pos только в том случае, если limit равен pos.

Вот пример сканирования буфера по фрагментам текста, в пределах которых все свойства постоянны:

(while (not (eobp))
  (let ((plist (text-properties-at (point)))
        (next-change
         (or (next-property-change (point) (current-buffer))
             (point-max))))
    Process text from point to next-change...
    (goto-char next-change)))
Функция: previous-property-change pos &optional object limit

Эта функция аналогична next-property-change, но сканирует текст назад от pos, а не вперёд. Если значение не равно nil, оно представляет собой позицию, меньшую или равную pos; оно равно pos только в том случае, если limit равен pos.

Функция: next-single-property-change pos prop &optional object limit

Функция сканирует текст в поисках изменения свойства prop, после чего возвращает позицию этого изменения. Сканирование идёт вперёд от позиции pos в строке или буфере object. Иными словами, эта функция возвращает позицию первого символа после pos, свойство prop которого отличается от свойства символа сразу после pos.

Если limit не равен nil, сканирование заканчивается на позиции limit. Если до этой позиции изменений свойства нет, next-single-property-change возвращает limit.

Значение равно nil, если свойство остаётся неизменным до конца object и limit равен nil. Если значение не равно nil, оно представляет собой позицию, большую или равную pos; оно равно pos только в том случае, если limit равен pos.

Функция: previous-single-property-change pos prop &optional object limit

Эта функция аналогична next-single-property-change, но сканирует текст назад от pos, а не вперёд. Если значение не равно nil, оно представляет собой позицию, меньшую или равную pos; оно равно pos только в том случае, если limit равен pos.

Функция: next-char-property-change pos &optional limit

Эта функция аналогична next-property-change, за исключением того, что она учитывает как свойства оверлеев, так и текстовые свойства и, если до конца буфера изменения не найдены, возвращает максимальную позицию буфера, а не nil (в этом смысле она похожа на соответствующую функцию для оверлеев next-overlay-change, а не на next-property-change). Аргумента object нет, поскольку эта функция работает только с текущим буфером. Она возвращает следующий адрес, в котором изменяется свойство любого из этих типов.

Функция: previous-char-property-change pos &optional limit

Эта функция аналогична next-char-property-change, но сканирует текст назад от pos, а не вперёд, и возвращает минимальную позицию буфера, если изменение не найдено.

Функция: next-single-char-property-change pos prop &optional object limit

Эта функция аналогична next-single-property-change, за исключением того, что она учитывает как свойства оверлеев, так и текстовые свойства и, если до конца object изменения не найдены, возвращает максимальную допустимую позицию в object, а не nil. В отличие от next-char-property-change, эта функция имеет аргумент object; если object не является буфером, учитываются только текстовые свойства.

Функция: previous-single-char-property-change pos prop &optional object limit

Эта функция аналогична next-single-char-property-change, но сканирует текст назад от pos, а не вперёд, и возвращает минимальную допустимую позицию в object, если изменение не найдено.

Функция: text-property-any start end prop value &optional object

Эта функция возвращает значение, не равное nil, если хотя бы один символ между start и end имеет свойство prop со значением value. Точнее, она возвращает позицию первого такого символа. В противном случае она возвращает nil.

Необязательный пятый аргумент, object, задаёт строку или буфер для сканирования. Позиции отсчитываются относительно object. По умолчанию object — текущий буфер.

Функция: text-property-not-all start end prop value &optional object

Эта функция возвращает значение, не равное nil, если хотя бы один символ между start и end не имеет свойства prop со значением value. Точнее, она возвращает позицию первого такого символа. В противном случае она возвращает nil.

Необязательный пятый аргумент, object, задаёт строку или буфер для сканирования. Позиции отсчитываются относительно object. По умолчанию object — текущий буфер.

Функция: text-property-search-forward prop &optional value predicate not-current

Выполняет поиск следующего участка текста, свойство prop которого соответствует value (по умолчанию nil) согласно predicate.

Эта функция устроена по образцу search-forward (см. раздел Поиск строк) и связанных с ней функций: она перемещает точку, но также возвращает структуру с описанием совпадения, а не возвращает его в match-beginning и связанных с ней функциях.

Если текстовое свойство с подходящим значением найти не удаётся, функция возвращает nil. Если оно найдено, точка устанавливается в конец участка с этим текстовым свойством, а функция возвращает структуру prop-match с информацией о совпадении.

predicate может быть равен t (синоним equal), nil (означает «не равно») или предикатом, который вызывается с двумя аргументами: value и значением текстового свойства prop в позиции буфера, проверяемой на совпадение. При совпадении функция должна возвращать значение, не равное nil, а в противном случае — nil.

Если not-current не равен nil, а точка уже находится в участке с совпадающим свойством, функция пропускает этот участок и ищет следующий.

Структура prop-match имеет следующие функции доступа: prop-match-beginning (начало совпадения), prop-match-end (конец совпадения) и prop-match-value (значение property в начале совпадения).

В примерах ниже используется буфер со следующим содержимым:

This is a bold and here’s bolditalic and this is the end.

То есть слова, выделенные «жирным шрифтом», используют начертание bold, а слово, выделенное «курсивом», — начертание italic.

Если точка находится в начале:

(while (setq match (text-property-search-forward 'face 'bold t))
  (push (buffer-substring (prop-match-beginning match)
                          (prop-match-end match))
        words))

Этот пример выберет все слова, использующие начертание bold.

(while (setq match (text-property-search-forward 'face nil t))
  (push (buffer-substring (prop-match-beginning match)
                          (prop-match-end match))
        words))

Этот пример выберет все фрагменты без свойств начертания, в результате чего получится список ‘("This is a " "and here's " "and this is the end")’ (только в обратном порядке, поскольку мы использовали push; см. раздел Изменение переменных-списков).

(while (setq match (text-property-search-forward 'face nil nil))
  (push (buffer-substring (prop-match-beginning match)
                          (prop-match-end match))
        words))

Этот пример выберет все участки, в которых для face задано какое-либо значение. Однако результат будет разделён в местах изменения свойств, поэтому в данном случае получится список ‘("bold" "bold" "italic")’.

Для более реалистичного примера применения представьте, что у вас есть буфер, в котором некоторые участки представляют URL-адреса и помечены свойством shr-url.

(while (setq match (text-property-search-forward 'shr-url nil nil))
  (push (prop-match-value match) urls))

В результате вы получите список всех этих URL-адресов.

Функция: text-property-search-backward prop &optional value predicate not-current

Эта функция аналогична text-property-search-forward, но выполняет поиск назад и, если совпадение найдено, устанавливает точку в начало найденного участка, а не в конец.

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Search.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API