aboutsummaryrefslogtreecommitdiff
path: root/wiki-markup.el
diff options
context:
space:
mode:
authorYuchen Pei <id@ypei.org>2023-07-09 10:34:03 +1000
committerYuchen Pei <id@ypei.org>2023-07-09 10:34:03 +1000
commitd2549f5ea26f55d98c9106448002adfc023793d7 (patch)
tree7f3fea423f1477a58ccae30ea5fe0ab03900a3af /wiki-markup.el
first commit
Diffstat (limited to 'wiki-markup.el')
-rw-r--r--wiki-markup.el121
1 files changed, 121 insertions, 0 deletions
diff --git a/wiki-markup.el b/wiki-markup.el
new file mode 100644
index 0000000..45bc740
--- /dev/null
+++ b/wiki-markup.el
@@ -0,0 +1,121 @@
+;;; wiki-markup.el -- A wikitext mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of wiki-markup.el.
+
+;; wiki-markup.el is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; wiki-markup.el 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 Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with wiki-markup.el. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A wikitext mode for wiki-markup
+
+;;; Code:
+(require 'wiki-faces)
+
+(defvar wiki-url-regexp "https?://[^ ]+")
+
+(defvar wiki-external-link-re
+ (rx (seq "[["
+ (group (seq "http"
+ (opt "s")
+ "://"
+ (+ (not " "))))
+ (opt (seq " " (group (+? anything))))
+ "]]")))
+
+(defvar wiki-internal-link-re
+ (rx (seq "[["
+ ;; Target
+ (group
+ (one-or-more
+ (not (any "[|]"))))
+ ;; Label (optional)
+ (opt (seq "|" (group (+? anything))))
+ "]]"))
+ )
+
+(defvar wiki-font-lock-keywords
+ (list
+ (cons "^======.*======\\ *$" 'wiki-level-6)
+ (cons "^=====.*=====\\ *$" 'wiki-level-5)
+ (cons "^====.*====\\ *$" 'wiki-level-4)
+ (cons "^===.*===\\ *$" 'wiki-level-3)
+ (cons "^==.*==\\ *$" 'wiki-level-2)
+ (cons "^=.*=\\ *$" 'wiki-level-1)
+ (cons "^----+\\ *$" 'wiki-hr-face)
+ (cons "'''''[^ \t\n].*?[^ \t\n]'''''" 'wiki-bold-italic)
+ (cons "'''[^ \t\n'].*?[^ \t\n']'''" 'wiki-bold)
+ (cons "''[^ \t\n'].*?[^ \t\n']''" 'wiki-italic)
+ (cons "^ .*$" 'wiki-pre-face)
+ '(wiki-activate-external-links)
+ '(wiki-activate-internal-links)
+ ))
+
+(defvar wiki-outline-regexp "=+.*=+\ *$")
+
+(defun wiki-outline-level ()
+ (when (looking-at "\\(=+\\).*\\(=+\\)\ *$")
+ (min (length (match-string 1))
+ (length (match-string 2))
+ 6)))
+
+;; Like `org-activate-links'
+(defun wiki-activate-links (link-re limit)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward link-re limit t)
+ (let ((start (match-beginning 0))
+ (end (match-end 0))
+ (visible-start (or (match-beginning 2) (match-beginning 1)))
+ (visible-end (or (match-end 2) (match-end 1)))
+ )
+ (put-text-property start visible-start 'invisible t)
+ (put-text-property start end 'font-lock-face 'wiki-link)
+ (put-text-property visible-end end 'invisible t)
+ (add-text-properties (1- visible-start) visible-start
+ '(rear-nonsticky (invisible)))
+ (add-text-properties (1- visible-end) visible-end
+ '(rear-nonsticky (invisible)))
+ ))))
+
+(defun wiki-activate-internal-links (limit)
+ (wiki-activate-links wiki-internal-link-re limit))
+
+(defun wiki-activate-external-links (limit)
+ (wiki-activate-links wiki-external-link-re limit))
+
+(define-derived-mode wiki-mode outline-mode "Wiki"
+ "A wikitext mode."
+
+ (setq-local comment-start "<!--")
+ (setq-local comment-end "-->")
+
+ ;; FIXME: this should not be necessary in outline mode
+ (setq-local font-lock-defaults
+ '(wiki-font-lock-keywords
+ t
+ nil
+ nil
+ (font-lock-extra-managed-props invisible font-lock-face)))
+ (setq-local outline-regexp wiki-outline-regexp)
+ (setq-local outline-level 'wiki-outline-level)
+ )
+
+(provide 'wiki-markup)
+;;; wiki-markup.el ends here
+