aboutsummaryrefslogtreecommitdiff
path: root/lightroff.el
diff options
context:
space:
mode:
Diffstat (limited to 'lightroff.el')
-rw-r--r--lightroff.el103
1 files changed, 103 insertions, 0 deletions
diff --git a/lightroff.el b/lightroff.el
new file mode 100644
index 0000000..ca49866
--- /dev/null
+++ b/lightroff.el
@@ -0,0 +1,103 @@
+;;; lightroff.el --- major mode for lightroff -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 John Ankarström
+
+;; Author: John Ankarström <john@ankarstrom.se>
+;; Created: 10 Jul 2022
+;; Version: 0.1
+
+;; Keywords: troff groff
+;; URL: http://ankarstrom.se/~john/etc/lightroff
+
+;; This file is not part of GNU Emacs.
+
+;; Permission to use, copy, modify and/or distribute this software for
+;; any purpose with or without fee is hereby granted.
+
+;;; Commentary:
+
+;; Major mode for lightroff, an alternative, XML-like syntax for troff.
+
+;;; Code:
+
+(defvar lightroff--request-regexp
+ (rx "<"
+ (group (+ (or "\\>" (not (in "> ")))))
+ (group (* (or "\\>" (not ?>))))
+ ">"))
+
+(defvar lightroff--single-escape-regexp
+ (rx "\\" any))
+
+(defvar lightroff--identifier-escape-regexp
+ (rx "\\"
+ (any "FfgkmnOsYZ*$")
+ (? (any "+-"))
+ (or (not (any "([+-"))
+ (seq "(" any any)
+ (seq "[" (* (not "]")) "]"))))
+
+(defvar lightroff--parameter-escape-regexp
+ (rx "\\"
+ (any "ABbCDHhLlMNoRSVvwXxz")
+ "'" (* (not "'")) "'"))
+
+(defconst lightroff-font-lock-keywords
+ `(;; Comment.
+ ("<!--.*-->"
+ (0 font-lock-comment-face))
+ ;; Request.
+ (,(concat lightroff--request-regexp)
+ (1 font-lock-keyword-face keep)
+ (2 font-lock-string-face keep))
+ (,(concat "\\\\" lightroff--request-regexp)
+ (1 nil t)
+ (2 nil t))
+ ;; Parameter escape (e.g., \l'...').
+ (,lightroff--parameter-escape-regexp
+ (0 lightroff-escape-face))
+ (,(concat "\\\\" lightroff--parameter-escape-regexp)
+ (0 nil t))
+ ;; Identifier escape (e.g., \n(PI).
+ (,lightroff--identifier-escape-regexp
+ (0 lightroff-escape-face))
+ (,(concat "\\\\" lightroff--identifier-escape-regexp)
+ (0 nil t))
+ ;; Single escape (e.g., \%).
+ (,lightroff--single-escape-regexp
+ (0 lightroff-escape-face))
+ (,(concat "\\\\" lightroff--single-escape-regexp)
+ (0 nil t))
+ ;; Escaped backslash.
+ (,"\\\\\\\\"
+ (0 lightroff-escape-face t))))
+
+(defface lightroff-escape
+ '((t (:foreground "gray")))
+ "`lightroff-mode' face used to highlight backslash escapes."
+ :group 'lightroff)
+(defvar lightroff-escape-face 'lightroff-escape)
+
+;;;###autoload
+(define-derived-mode lightroff-mode text-mode "Lightroff"
+ "Major mode for editing documents with lightroff syntax."
+ ;; A start or end tag by itself on a line separates a paragraph.
+ ;; This is desirable because SGML discards a newline that appears
+ ;; immediately after a start tag or immediately before an end tag.
+ (setq-local paragraph-start "<\\([^>]\\)+>")
+ (setq-local paragraph-separate "$\\|\\]>")
+ (setq-local adaptive-fill-regexp "[ \t]*")
+ ;; (add-hook 'fill-nobreak-predicate 'sgml-fill-nobreak nil t)
+ ;; (setq-local indent-line-function 'sgml-indent-line)
+ (setq-local comment-start "<!-- ")
+ (setq-local comment-end " -->")
+ ;; (setq-local comment-indent-function 'sgml-comment-indent)
+ ;; (setq-local comment-line-break-function 'sgml-comment-indent-new-line)
+ (setq-local font-lock-defaults '((lightroff-font-lock-keywords)))
+ ;; (setq-local font-lock-multiline t)
+ (setq-local comment-start-skip "<!--[ \t]*")
+ (setq-local comment-end-skip "[ \t]*--[ \t\n]*>")
+ (visual-line-mode 1))
+
+(provide 'lightroff)
+;;; lightroff.el ends here