Я опишу простой основной режим для выделения <style>
(CSS) и <script>
(JavaScript и т. Д.) Блоков. Чтобы получить многострочный замок шрифта работает достаточно хорошо, вы должны сначала включить его, установив font-lock-multiline
в t
и написать функцию, чтобы добавить к font-lock-extend-region-functions
, который будет распространяться соответствующий область поиска, чтобы содержать большие блоки текста. Затем вам нужно будет написать многострочные совпадения - либо регулярные выражения или функции - и добавить их в font-lock-defaults
.
Вот основное главным определение режима, что имена шрифты блокировки списка ключевых слов (здесь, test-font-lock-keywords
), позволяет многострочного замка шрифта, и добавляет функцию расширения области test-font-lock-extend-region
.
(define-derived-mode test-mode html-mode "Test"
"Major mode for highlighting JavaScript and CSS blocks."
;; Basic font lock
(set (make-local-variable 'font-lock-defaults)
'(test-font-lock-keywords))
;; Multiline font lock
(set (make-local-variable 'font-lock-multiline) t)
(add-hook 'font-lock-extend-region-functions
'test-font-lock-extend-region))
Область функция расширения должна выглядеть примерно так:
(defun test-font-lock-extend-region()
"Extend the search region to include an entire block of text."
;; Avoid compiler warnings about these global variables from font-lock.el.
;; See the documentation for variable `font-lock-extend-region-functions'.
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
(save-excursion
(goto-char font-lock-beg)
(let ((found (or (re-search-backward "\n\n" nil t) (point-min))))
(goto-char font-lock-end)
(when (re-search-forward "\n\n" nil t)
(beginning-of-line)
(setq font-lock-end (point)))
(setq font-lock-beg found))))
Эта функция смотрит на глобальные переменные font-lock-beg
и font-lock-end
, которые содержат начальную и конечную позиции области поиска, и расширяет область, чтобы содержать весь блок текста (разделенный пустыми строками, или "\n\n"
).
Теперь, когда Emacs будет искать совпадения в более крупных регионах, нам необходимо установить test-font-lock-keywords
. Есть два разумно хороших способов согласования многострочных конструкций: - регулярное выражение, которое будет соответствовать по строкам и соответствует функции . Я приведу примеры того и другого. Этот список ключевых слов содержит регулярного выражения для сопоставления <style>
блоков и функция для согласования <script>
блоков:
(defvar test-font-lock-keywords
(list
(cons test-style-block-regexp 'font-lock-string-face)
(cons 'test-match-script-blocks '((0 font-lock-keyword-face)))
)
"Font lock keywords for inline JavaScript and CSS blocks.")
Первый элемент в списке прост: регулярное выражение и лицо для выделения матчей, что регулярного выражение. Второй выглядит немного более сложным, но может быть обобщен , чтобы указать разные грани для разных групп, определенных в данных соответствия , заданных функцией. Здесь мы просто выделяем группу ноль (весь матч), используя font-lock-keyword-face
. (Соответствующая документация для этих matchers находится в Search-based fontification разделе учебное пособие Emacs.)
Основное регулярное выражение для сопоставления <style>
блоков будет:
(defconst test-style-block-regexp
"<style>\\(.\\|\n\\)*</style>"
"Regular expression for matching inline CSS blocks.")
Обратите внимание, что мы должны поставить \n
во внутренней группе, потому что .
не соответствие новой строки.
Функция соответствия, с другой стороны, нужно искать первый <script>
блока в области от точки к одной заданной аргумента, last
:
(defun test-match-script-blocks (last)
"Match JavaScript blocks from the point to LAST."
(cond ((search-forward "<script" last t)
(let ((beg (match-beginning 0)))
(cond ((search-forward-regexp "</script>" last t)
(set-match-data (list beg (point)))
t)
(t nil))))
(t nil)))
Эта функция устанавливает данные соответствия , который представляет собой список форм begin-0 end-0 begin-1 end-1 ...
, дающий начало и конец нулевой группы , первой группы и т. д. Здесь мы ограничиваем только весь блок, который был сопоставлен, но вы могли бы сделать что-то более сложнее, например, установить разные грани для тегов и содержимое .
Если объединить весь этот код в один файл и запустить M-x test-mode
, он должен работать для выделения этих двух типов блоков. Хотя я считаю, что это делает работу, если есть более эффективный или правильный способ обойти это, мне также будет любопытно знать .
В этой [нить] (http://lists.gnu.org/archive/html/help-gnu-emacs/2004-09/msg00534.html) Стефан Моннье говорит, что функция font-lock-multi-line подходит для вещей, которые обычно однострочные, но иногда многострочные. Комментарии? –
Ну, Stefan Monnier является окончательной ссылкой, когда дело доходит до любого связанного с шрифтом-замком, поэтому любые советы от него заслуживают внимания. Использование синтаксической системы, как он предлагает, является одним из способов сделать это. Другим является использование «функции соответствия», а не регулярного выражения, которое может соответствовать всему блоку. Вы должны увидеть мои ответы как прямой ответ на вопрос (укажите пример многострочной функции блокировки шрифтов) и, возможно, не ответ на лучший способ выполнить то, о чем спрашивали оригинальные плакаты. – Lindydancer