;;; wiki.el -- A wikitext mode -*- lexical-binding: t -*- ;; Copyright (C) 2023 Free Software Foundation. ;; Author: Yuchen Pei ;; Package-Requires: ((emacs "28.2")) ;; This file is part of dotted. ;; dotted 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. ;; dotted 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 dotted. If not, see . ;;; Commentary: ;; A wikitext mode. ;;; Code: (require 'wiki-faces) (defvar wiki-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) ;; FIXME: not working, need to do something like `org-activate-links' (cons "\\(\\[\\[\\)\\([^][|]+\\)\\(|\\)\\([^][|]+\\)\\(\\]\\]\\)" '((1 invisible) (2 invisible) (3 invisible) (4 wiki-link) (5 invisible))) )) (defvar wiki-font-lock-keywords nil) (defvar wiki-outline-regexp "=+.*=+\ *$") (defun wiki-outline-level () (when (looking-at "\\(=+\\).*\\(=+\\)\ *$") (min (length (match-string 1)) (length (match-string 2)) 6))) ;; `org-activate-links' (defun wiki-activate-links () (save-excursion (goto-char (point-min)) (while (re-search-forward wiki-link-re nil 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 visible-start visible-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-start) visible-start '(rear-nonsticky invisible)) )))) (define-derived-mode wiki-mode outline-mode "Wiki" "A wikitext mode." (setq-local comment-start "") ;; FIXME: this should not be necessary in outline mode (setq-local font-lock-defaults '(wiki-font-lock-keywords t nil nil nil)) (setq-local outline-regexp wiki-outline-regexp) (setq-local outline-level 'wiki-outline-level) (wiki-activate-links)) (provide 'wiki) ;;; wiki.el ends here