org: syntax-highlight the HOA outputs
* elisp/hoa-mode.el, elisp/Makefile.am, elisp/README: New files. * debian/copyright, configure.ac, README, Makefile.am: Adjust. * doc/org/init.el.in: Adjust to load hoa-mode.el. * doc/org/spot.css: Add entries for HOA mode. * doc/org/hoa.org, doc/org/ltldo.org, doc/org/oaut.org, doc/org/tut20.org, doc/org/tut21.org, doc/org/tut22.org, doc/org/tut30.org: Make the HOA outputs as HOA.
This commit is contained in:
parent
d46da963d5
commit
5aba246ff0
16 changed files with 449 additions and 132 deletions
27
elisp/Makefile.am
Normal file
27
elisp/Makefile.am
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
## l'Epita (LRDE).
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
## Spot is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
## License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
EXTRA_DIST = hoa-mode.el
|
||||
|
||||
GIT = https://gitlab.lrde.epita.fr/spot/emacs-modes/raw/master/
|
||||
|
||||
.PHONY: update-el
|
||||
update-el:
|
||||
wget $(GIT)/hoa-mode.el -O $(srcdir)/hoa-mode.el
|
||||
chmod a-w $(srcdir)/hoa-mode.el
|
||||
3
elisp/README
Normal file
3
elisp/README
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
hoa-mode.el is used when building the documentation for syntax
|
||||
highlighting the HOA files displayed in the examples. But you may
|
||||
also want to use it for editing and displaying HOA files.
|
||||
249
elisp/hoa-mode.el
Normal file
249
elisp/hoa-mode.el
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
;;; hoa-mode.el --- Major mode for the Hanoi Omega Automata format
|
||||
|
||||
;; Copyright (C) 2015 Alexandre Duret-Lutz
|
||||
|
||||
;; Author: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||
;; Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||
;; URL: https://gitlab.lrde.epita.fr/spot/emacs-modes
|
||||
;; Keywords: major-mode, automata, convenience
|
||||
;; Created: 2015-11-13
|
||||
|
||||
;;; License:
|
||||
|
||||
;; This package is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; This package is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Major mode for editing files in the Hanoi Omega Automata format.
|
||||
;; (See URL `http://adl.github.io/hoaf/' for that format.) This
|
||||
;; provides rules for syntax highlighting, some navigation functions,
|
||||
;; and a convenient way to display the automata in Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.hoa\\'" . hoa-mode))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'magic-mode-alist '("\\<HOA:\\s-*v" . hoa-mode))
|
||||
|
||||
(defgroup hoa-mode nil
|
||||
"Major mode for editing Hanoi Omega Automata files."
|
||||
:group 'data)
|
||||
|
||||
(defgroup hoa-mode-faces nil
|
||||
"Faces used by `hoa-mode'."
|
||||
:group 'hoa-mode
|
||||
:group 'faces)
|
||||
|
||||
(defface hoa-header-uppercase-face
|
||||
'((t :inherit font-lock-type-face :weight bold))
|
||||
"Face for headers with an uppercase initial."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-header-lowercase-face
|
||||
'((t :inherit font-lock-type-face :weight normal))
|
||||
"Face for headers with a lowercase initial."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-keyword-face
|
||||
'((t :inherit font-lock-keyword-face))
|
||||
"Face used for --BODY--, --END--, and --ABORT--."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-builtin-face
|
||||
'((t :inherit font-lock-builtin-face))
|
||||
"Face used for Inf, Fin, t, and f."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-acceptance-set-face
|
||||
'((t :inherit font-lock-constant-face :weight bold))
|
||||
"Face used for acceptance sets."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-alias-face
|
||||
'((t :inherit font-lock-variable-name-face))
|
||||
"Face used for aliases."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-ap-number-face
|
||||
'((t :inherit font-lock-constant-face))
|
||||
"Face used for numbers that denote atomic propositions."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defconst hoa-alias-regex
|
||||
"@[a-zA-Z0-9_-]*\\_>"
|
||||
"Regex for matching aliases.")
|
||||
|
||||
(defvar hoa-font-lock-keywords
|
||||
(list
|
||||
'("\\_<[A-Z][a-zA-Z0-9_-]*:" . 'hoa-header-uppercase-face)
|
||||
'("\\_<[a-z][a-zA-Z0-9_-]*:" . 'hoa-header-lowercase-face)
|
||||
`(,hoa-alias-regex . 'hoa-alias-face)
|
||||
'("\\_<--\\(BODY\\|END\\|ABORT\\)--" . 'hoa-keyword-face)
|
||||
'("\\_<\\(Inf\\|Fin\\|t\\|f\\)\\_>" . 'hoa-builtin-face)
|
||||
'("(\\s-*\\([0-9]+\\)\\s-*)" 1 'hoa-acceptance-set-face)
|
||||
'("{\\(\\([0-9]\\|\\s-\\)+\\)}" 1 'hoa-acceptance-set-face)
|
||||
;; numbers between brackets denote atomic propositions.
|
||||
'("\\["
|
||||
("\\_<[0-9]+\\_>"
|
||||
(save-excursion (search-forward "]" nil t))
|
||||
nil
|
||||
(0 'hoa-ap-number-face)))
|
||||
;; likewise for numbers following an Alias: definition
|
||||
`(,(concat "Alias:\\s-*" hoa-alias-regex)
|
||||
("\\_<[0-9]+\\_>"
|
||||
(save-excursion
|
||||
(re-search-forward
|
||||
(concat "\\(" hoa-alias-regex "\\|[0-9|&!]\\|\\s-\\)+") nil t))
|
||||
nil
|
||||
(0 'hoa-ap-number-face))))
|
||||
"Hilighting rules for `hoa-mode'.")
|
||||
|
||||
(defvar hoa-mode-syntax-table
|
||||
(let ((st (make-syntax-table)))
|
||||
(modify-syntax-entry ?< "." st)
|
||||
(modify-syntax-entry ?> "." st)
|
||||
(modify-syntax-entry ?| "." st)
|
||||
(modify-syntax-entry ?_ "_" st)
|
||||
(modify-syntax-entry ?- "_" st)
|
||||
(modify-syntax-entry ?$ "." st)
|
||||
(modify-syntax-entry ?& "." st)
|
||||
(modify-syntax-entry ?+ "." st)
|
||||
(modify-syntax-entry ?/ ". 14bn" st)
|
||||
(modify-syntax-entry ?* ". 23bn" st)
|
||||
st)
|
||||
"Syntax table for `hoa-mode'.")
|
||||
|
||||
(defun hoa-start-of-automaton ()
|
||||
"Move to the start of the automaton at point."
|
||||
(interactive)
|
||||
(search-backward "HOA:"))
|
||||
|
||||
(defun hoa-end-of-automaton ()
|
||||
"Move to the end of the automaton at point."
|
||||
(interactive)
|
||||
; if we are pointing inside something that looks like --END-- or
|
||||
; --ABORT--, back out a bit.
|
||||
(if (looking-at "[ENDABORT-]*-")
|
||||
(backward-word))
|
||||
(re-search-forward "--\\(END\\|ABORT\\)--\n?"))
|
||||
|
||||
(defun hoa-mark-automaton-at-point ()
|
||||
"Mark the automaton at point."
|
||||
(interactive)
|
||||
(hoa-end-of-automaton)
|
||||
(set-mark (point))
|
||||
(hoa-start-of-automaton))
|
||||
|
||||
(defcustom hoa-display-error-buffer "*hoa-dot-error*"
|
||||
"The name of the buffer to display errors from `hoa-display-command'."
|
||||
:group 'hoa-mode
|
||||
:type 'string)
|
||||
|
||||
(defcustom hoa-display-buffer "*hoa-display*"
|
||||
"The name of the buffer to display automata."
|
||||
:group 'hoa-mode
|
||||
:type 'string)
|
||||
|
||||
(defcustom hoa-display-command "autfilt --dot='barf(Lato)' | dot -Tpng"
|
||||
"Command used to display HOA files.
|
||||
|
||||
The command is expected to take the automaton in HOA format on
|
||||
its standard input, and output an image in PNG format on its
|
||||
standard output.
|
||||
|
||||
The default value uses the tools autfilt (part of the Spot
|
||||
package, see URL `https://spot.lrde.epita.fr/') and dot (part of
|
||||
the GraphViz package, see URL `http://www.graphviz.org/')."
|
||||
:group 'hoa-mode
|
||||
:type 'string)
|
||||
|
||||
(defun hoa-display-automaton-at-point ()
|
||||
"Display the automaton-at-point.
|
||||
|
||||
This uses the command in `hoa-display-command' to convert HOA
|
||||
into PNG, and then display the result in `hoa-display-buffer'.
|
||||
If the command terminates with an error, its standard error is
|
||||
put in `hoa-display-error-buffer' and shown."
|
||||
(interactive)
|
||||
(let ((b (save-excursion (if (not (looking-at "HOA:"))
|
||||
(hoa-start-of-automaton)
|
||||
(point))))
|
||||
(e (save-excursion (hoa-end-of-automaton) (point)))
|
||||
(dotbuf (generate-new-buffer "*hoa-dot-output*"))
|
||||
(errfile (make-temp-file
|
||||
(expand-file-name "hoadot" temporary-file-directory)))
|
||||
(coding-system-for-read 'no-conversion))
|
||||
(with-current-buffer dotbuf
|
||||
(set-buffer-multibyte nil))
|
||||
(let ((exit-status
|
||||
(call-process-region b e shell-file-name nil (list dotbuf errfile)
|
||||
nil shell-command-switch hoa-display-command)))
|
||||
(when (equal 0 exit-status)
|
||||
(let ((hoa-img (create-image (with-current-buffer dotbuf (buffer-string))
|
||||
'png t)))
|
||||
(with-current-buffer (get-buffer-create hoa-display-buffer)
|
||||
(erase-buffer)
|
||||
(insert-image hoa-img)
|
||||
(display-buffer (current-buffer)))))
|
||||
(when (file-exists-p errfile)
|
||||
(when (< 0 (nth 7 (file-attributes errfile)))
|
||||
(with-current-buffer (get-buffer-create hoa-display-error-buffer)
|
||||
(setq buffer-read-only nil)
|
||||
(erase-buffer)
|
||||
(format-insert-file errfile nil)
|
||||
(display-buffer (current-buffer))))
|
||||
(delete-file errfile))
|
||||
(kill-buffer dotbuf))))
|
||||
|
||||
(defvar hoa-mode-map
|
||||
(let ((map (make-keymap)))
|
||||
(define-key map "\M-e" 'hoa-end-of-automaton)
|
||||
(define-key map "\M-a" 'hoa-start-of-automaton)
|
||||
(define-key map "\C-\M-h" 'hoa-mark-automaton-at-point)
|
||||
(define-key map "\C-c\C-c" 'hoa-display-automaton-at-point)
|
||||
map)
|
||||
"Keymap for `hoa-mode'.")
|
||||
|
||||
(defcustom hoa-mode-hook nil
|
||||
"Hook run whenever `hoa-mode' is activated."
|
||||
:group 'hoa-mode
|
||||
:type 'hook)
|
||||
|
||||
;;;### autoload
|
||||
(defun hoa-mode ()
|
||||
"Major mode for editing files in the Hanoi Omega Automata format.
|
||||
|
||||
See URL `http://adl.github.io/hoaf/' for a definition of that format.
|
||||
|
||||
The following key bindings are installed in hoa-mode:
|
||||
|
||||
\\{hoa-mode-map}
|
||||
|
||||
By default the `hoa-display-automaton-at-point' function requires
|
||||
extra software (Spot and GraphViz), but can be configured to use
|
||||
other tools. See that function for details."
|
||||
(interactive)
|
||||
(kill-all-local-variables)
|
||||
(set-syntax-table hoa-mode-syntax-table)
|
||||
(set (make-local-variable 'font-lock-defaults) '(hoa-font-lock-keywords))
|
||||
(use-local-map hoa-mode-map)
|
||||
(setq major-mode 'hoa-mode)
|
||||
(setq mode-name "HOA")
|
||||
(run-hooks 'hoa-mode-hook))
|
||||
|
||||
(provide 'hoa-mode)
|
||||
|
||||
;;; hoa-mode.el ends here
|
||||
Loading…
Add table
Add a link
Reference in a new issue