summaryrefslogtreecommitdiffstats
path: root/emacs.d/elisp/muse/muse-colors.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs.d/elisp/muse/muse-colors.el')
-rw-r--r--emacs.d/elisp/muse/muse-colors.el1022
1 files changed, 0 insertions, 1022 deletions
diff --git a/emacs.d/elisp/muse/muse-colors.el b/emacs.d/elisp/muse/muse-colors.el
deleted file mode 100644
index fb76ac5..0000000
--- a/emacs.d/elisp/muse/muse-colors.el
+++ /dev/null
@@ -1,1022 +0,0 @@
-;;; muse-colors.el --- coloring and highlighting used by Muse
-
-;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;; Free Software Foundation, Inc.
-
-;; Author: John Wiegley (johnw AT gnu DOT org)
-;; Keywords: hypermedia
-;; Date: Thu 11-Mar-2004
-
-;; This file is part of Emacs Muse. It is not part of GNU Emacs.
-
-;; Emacs Muse 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.
-
-;; Emacs Muse 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 Emacs Muse; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;; Commentary:
-
-;;; Contributors:
-
-;; Lan Yufeng (nlany DOT web AT gmail DOT com) found an error where
-;; headings were being given the wrong face, contributing a patch to
-;; fix this.
-
-;; Sergey Vlasov (vsu AT altlinux DOT ru) fixed an issue with coloring
-;; links that are in consecutive lines.
-
-;; Jim Ottaway ported the <lisp> tag from emacs-wiki.
-
-;; Per B. Sederberg (per AT med DOT upenn DOT edu) contributed the
-;; viewing of inline images.
-
-;;; Code:
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Emacs Muse Highlighting
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(require 'muse-mode)
-(require 'muse-regexps)
-(require 'font-lock)
-
-(defgroup muse-colors nil
- "Options controlling the behavior of Emacs Muse highlighting.
-See `muse-colors-buffer' for more information."
- :group 'muse-mode)
-
-(defcustom muse-colors-autogen-headings t
- "Specify whether the heading faces should be auto-generated.
-The default is to scale them.
-
-Choosing 'outline will copy the colors from the outline-mode
-headings.
-
-If you want to customize each of the headings individually, set
-this to nil."
- :type '(choice (const :tag "Default (scaled) headings" t)
- (const :tag "Use outline-mode headings" outline)
- (const :tag "Don't touch the headings" nil))
- :group 'muse-colors)
-
-(defcustom muse-colors-evaluate-lisp-tags t
- "Specify whether to evaluate the contents of <lisp> tags at
-display time. If nil, don't evaluate them. If non-nil, evaluate
-them.
-
-The actual contents of the buffer are not changed, only the
-displayed text."
- :type 'boolean
- :group 'muse-colors)
-
-(defcustom muse-colors-inline-images t
- "Specify whether to inline images inside the Emacs buffer. If
-nil, don't inline them. If non-nil, an image link will be
-replaced by the image.
-
-The actual contents of the buffer are not changed, only whether
-an image is displayed."
- :type 'boolean
- :group 'muse-colors)
-
-(defcustom muse-colors-inline-image-method 'default-directory
- "Determine how to locate inline images.
-Setting this to 'default-directory uses the current directory of
-the current Muse buffer.
-
-Setting this to a function calls that function with the filename
-of the image to be inlined. The value that is returned will be
-used as the filename of the image."
- :type '(choice (const :tag "Current directory" default-directory)
- (const :tag "Publishing directory"
- muse-colors-use-publishing-directory)
- (function :tag "Custom function"))
- :group 'muse-colors)
-
-(defvar muse-colors-region-end nil
- "Indicate the end of the region that is currently being font-locked.")
-(make-variable-buffer-local 'muse-colors-region-end)
-
-;;;###autoload
-(defun muse-colors-toggle-inline-images ()
- "Toggle display of inlined images on/off."
- (interactive)
- ;; toggle the custom setting
- (if (not muse-colors-inline-images)
- (setq muse-colors-inline-images t)
- (setq muse-colors-inline-images nil))
- ;; reprocess the buffer
- (muse-colors-buffer)
- ;; display informative message
- (if muse-colors-inline-images
- (message "Images are now displayed inline")
- (message "Images are now displayed as links")))
-
-(defvar muse-colors-outline-faces-list
- (if (facep 'outline-1)
- '(outline-1 outline-2 outline-3 outline-4 outline-5)
- ;; these are equivalent in coloring to the outline faces
- '(font-lock-function-name-face
- font-lock-variable-name-face
- font-lock-keyword-face
- font-lock-builtin-face
- font-lock-comment-face))
- "Outline faces to use when assigning Muse header faces.")
-
-(defun muse-make-faces-default (&optional later)
- "Generate the default face definitions for headers."
- (dolist (num '(1 2 3 4 5))
- (let ((newsym (intern (concat "muse-header-" (int-to-string num))))
- (docstring (concat
- "Muse header face. See "
- "`muse-colors-autogen-headings' before changing it.")))
- ;; put in the proper group and give documentation
- (if later
- (unless (featurep 'xemacs)
- (muse-copy-face 'variable-pitch newsym)
- (set-face-attribute newsym nil :height (1+ (* 0.1 (- 5 num)))
- :weight 'bold))
- (if (featurep 'xemacs)
- (eval `(defface ,newsym
- '((t (:size
- ,(nth (1- num)
- '("24pt" "18pt" "14pt" "12pt" "11pt"))
- :bold t)))
- ,docstring
- :group 'muse-colors))
- (eval `(defface ,newsym
- '((t (:height ,(1+ (* 0.1 (- 5 num)))
- :inherit variable-pitch
- :weight bold)))
- ,docstring
- :group 'muse-colors)))))))
-
-(progn (muse-make-faces-default))
-
-(defun muse-make-faces (&optional frame)
- "Generate face definitions for headers based the user's preferences."
- (cond
- ((not muse-colors-autogen-headings)
- nil)
- ((eq muse-colors-autogen-headings t)
- (muse-make-faces-default t))
- (t
- (dolist (num '(1 2 3 4 5))
- (let ((newsym (intern (concat "muse-header-" (int-to-string num)))))
- ;; copy the desired face definition
- (muse-copy-face (nth (1- num) muse-colors-outline-faces-list)
- newsym))))))
-
-;; after displaying the Emacs splash screen, the faces are wiped out,
-;; so recover from that
-(add-hook 'window-setup-hook #'muse-make-faces)
-;; ditto for when a new frame is created
-(when (boundp 'after-make-frame-functions)
- (add-hook 'after-make-frame-functions #'muse-make-faces))
-
-(defface muse-link
- '((((class color) (background light))
- (:foreground "blue" :underline "blue" :bold t))
- (((class color) (background dark))
- (:foreground "cyan" :underline "cyan" :bold t))
- (t (:bold t)))
- "Face for Muse cross-references."
- :group 'muse-colors)
-
-(defface muse-bad-link
- '((((class color) (background light))
- (:foreground "red" :underline "red" :bold t))
- (((class color) (background dark))
- (:foreground "coral" :underline "coral" :bold t))
- (t (:bold t)))
- "Face for bad Muse cross-references."
- :group 'muse-colors)
-
-(defface muse-verbatim
- '((((class color) (background light))
- (:foreground "slate gray"))
- (((class color) (background dark))
- (:foreground "gray")))
- "Face for verbatim text."
- :group 'muse-colors)
-
-(defface muse-emphasis-1
- '((t (:italic t)))
- "Face for italic emphasized text."
- :group 'muse-colors)
-
-(defface muse-emphasis-2
- '((t (:bold t)))
- "Face for bold emphasized text."
- :group 'muse-colors)
-
-(defface muse-emphasis-3
- '((t (:bold t :italic t)))
- "Face for bold italic emphasized text."
- :group 'muse-colors)
-
-(muse-copy-face 'italic 'muse-emphasis-1)
-(muse-copy-face 'bold 'muse-emphasis-2)
-(muse-copy-face 'bold-italic 'muse-emphasis-3)
-
-(defcustom muse-colors-buffer-hook nil
- "A hook run after a region is highlighted.
-Each function receives three arguments: BEG END VERBOSE.
-BEG and END mark the range being highlighted, and VERBOSE specifies
-whether progress messages should be displayed to the user."
- :type 'hook
- :group 'muse-colors)
-
-(defvar muse-colors-highlighting-registry nil
- "The rules for highlighting Muse and Muse-derived buffers.
-This is automatically generated when using font-lock in Muse buffers.
-
-This an alist of major-mode symbols to `muse-colors-rule' objects.")
-
-(defun muse-colors-make-highlighting-struct ()
- (list nil nil nil))
-(defconst muse-colors-highlighting.regexp 0
- "Regexp matching each car of the markup of the current rule.")
-(defconst muse-colors-highlighting.vector 1
- "Vector of all characters that are part of the markup of the current rule.
-This is composed of the 2nd element of each markup entry.")
-(defconst muse-colors-highlighting.remaining 2
- "Expressions for highlighting a buffer which have no corresponding
-entry in the vector.")
-
-(defsubst muse-colors-highlighting-entry (mode)
- "Return the highlighting rules for MODE."
- (assq mode muse-colors-highlighting-registry))
-
-(defun muse-colors-find-highlighting (mode)
- "Return the highlighting rules to be used for MODE.
-If MODE does not have highlighting rules, check its parent modes."
- (let ((seen nil))
- (catch 'rules
- (while (and mode (not (memq mode seen)))
- (let ((entry (muse-colors-highlighting-entry mode)))
- (when entry (throw 'rules (cdr entry))))
- (setq seen (cons mode seen))
- (setq mode (get mode 'derived-mode-parent)))
- nil)))
-
-(defun muse-colors-define-highlighting (mode markup)
- "Create or update the markup rules for MODE, using MARKUP.
-
-See `muse-colors-markup' for an explanation of the format that MARKUP
-should take."
- (unless (and (symbolp mode) mode (consp markup))
- (error "Invalid arguments"))
- (let* ((highlighting-entry (muse-colors-highlighting-entry mode))
- (struct (cdr highlighting-entry))
- (regexp nil)
- (vector nil)
- (remaining nil))
- ;; Initialize struct
- (if struct
- (setq vector (nth muse-colors-highlighting.vector struct))
- (setq struct (muse-colors-make-highlighting-struct)))
- ;; Initialize vector
- (if vector
- (let ((i 0))
- (while (< i 128)
- (aset vector i nil)
- (setq i (1+ i))))
- (setq vector (make-vector 128 nil)))
- ;; Determine vector, regexp, remaining
- (let ((regexps nil)
- (rules nil))
- (dolist (rule markup)
- (let ((value (cond ((symbolp (car rule))
- (symbol-value (car rule)))
- ((stringp (car rule))
- (car rule))
- (t nil))))
- (when value
- (setq rules (cons rule rules))
- (setq regexps (cons value regexps)))))
- (setq regexps (nreverse regexps))
- (setq regexp (concat "\\(" (mapconcat #'identity regexps "\\|") "\\)"))
- (dolist (rule rules)
- (if (eq (nth 1 rule) t)
- (setq remaining (cons (cons (nth 0 rule) (nth 2 rule))
- remaining))
- (aset vector (nth 1 rule)
- (cons (cons (nth 0 rule) (nth 2 rule))
- (aref vector (nth 1 rule)))))))
- ;; Update the struct
- (setcar (nthcdr muse-colors-highlighting.regexp struct) regexp)
- (setcar (nthcdr muse-colors-highlighting.vector struct) vector)
- (setcar (nthcdr muse-colors-highlighting.remaining struct) remaining)
- ;; Update entry for mode in muse-colors-highlighting-registry
- (if highlighting-entry
- (setcdr highlighting-entry struct)
- (setq muse-colors-highlighting-registry
- (cons (cons mode struct)
- muse-colors-highlighting-registry)))))
-
-(defun muse-configure-highlighting (sym val)
- "Extract color markup information from VAL and set to SYM.
-This is usually called with `muse-colors-markup' as both arguments."
- (muse-colors-define-highlighting 'muse-mode val)
- (set sym val))
-
-(defun muse-colors-emphasized ()
- "Color emphasized text and headings."
- ;; Here we need to check four different points - the start and end
- ;; of the leading *s, and the start and end of the trailing *s. We
- ;; allow the outsides to be surrounded by whitespace or punctuation,
- ;; but no word characters, and the insides must not be surrounded by
- ;; whitespace or punctuation. Thus the following are valid:
- ;;
- ;; " *foo bar* "
- ;; "**foo**,"
- ;; and the following is invalid:
- ;; "** testing **"
- (let* ((beg (match-beginning 0))
- (e1 (match-end 0))
- (leader (- e1 beg))
- b2 e2 multiline)
- (unless (or (eq (get-text-property beg 'invisible) 'muse)
- (get-text-property beg 'muse-comment)
- (get-text-property beg 'muse-directive))
- ;; check if it's a header
- (if (eq (char-after e1) ?\ )
- (when (or (= beg (point-min))
- (eq (char-before beg) ?\n))
- (add-text-properties
- (muse-line-beginning-position) (muse-line-end-position)
- (list 'face (intern (concat "muse-header-"
- (int-to-string leader))))))
- ;; beginning of line or space or symbol
- (when (or (= beg (point-min))
- (eq (char-syntax (char-before beg)) ?\ )
- (memq (char-before beg)
- '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n)))
- (save-excursion
- (skip-chars-forward "^*<>\n" muse-colors-region-end)
- (when (eq (char-after) ?\n)
- (setq multiline t)
- (skip-chars-forward "^*<>" muse-colors-region-end))
- (setq b2 (point))
- (skip-chars-forward "*" muse-colors-region-end)
- (setq e2 (point))
- ;; Abort if space exists just before end
- ;; or bad leader
- ;; or no '*' at end
- ;; or word constituent follows
- (unless (or (> leader 5)
- (not (eq leader (- e2 b2)))
- (eq (char-syntax (char-before b2)) ?\ )
- (not (eq (char-after b2) ?*))
- (and (not (eobp))
- (eq (char-syntax (char-after (1+ b2))) ?w)))
- (add-text-properties beg e1 '(invisible muse))
- (add-text-properties
- e1 b2 (list 'face (cond ((= leader 1) 'muse-emphasis-1)
- ((= leader 2) 'muse-emphasis-2)
- ((= leader 3) 'muse-emphasis-3))))
- (add-text-properties b2 e2 '(invisible muse))
- (when multiline
- (add-text-properties
- beg e2 '(font-lock-multiline t))))))))))
-
-(defun muse-colors-underlined ()
- "Color underlined text."
- (let ((start (match-beginning 0))
- multiline)
- (unless (or (eq (get-text-property start 'invisible) 'muse)
- (get-text-property start 'muse-comment)
- (get-text-property start 'muse-directive))
- ;; beginning of line or space or symbol
- (when (or (= start (point-min))
- (eq (char-syntax (char-before start)) ?\ )
- (memq (char-before start)
- '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n)))
- (save-excursion
- (skip-chars-forward "^_<>\n" muse-colors-region-end)
- (when (eq (char-after) ?\n)
- (setq multiline t)
- (skip-chars-forward "^_<>" muse-colors-region-end))
- ;; Abort if space exists just before end
- ;; or no '_' at end
- ;; or word constituent follows
- (unless (or (eq (char-syntax (char-before (point))) ?\ )
- (not (eq (char-after (point)) ?_))
- (and (not (eobp))
- (eq (char-syntax (char-after (1+ (point)))) ?w)))
- (add-text-properties start (1+ start) '(invisible muse))
- (add-text-properties (1+ start) (point) '(face underline))
- (add-text-properties (point)
- (min (1+ (point)) (point-max))
- '(invisible muse))
- (when multiline
- (add-text-properties
- start (min (1+ (point)) (point-max))
- '(font-lock-multiline t)))))))))
-
-(defun muse-colors-verbatim ()
- "Render in teletype and suppress further parsing."
- (let ((start (match-beginning 0))
- multiline)
- (unless (or (eq (get-text-property start 'invisible) 'muse)
- (get-text-property start 'muse-comment)
- (get-text-property start 'muse-directive))
- ;; beginning of line or space or symbol
- (when (or (= start (point-min))
- (eq (char-syntax (char-before start)) ?\ )
- (memq (char-before start)
- '(?\- ?\[ ?\< ?\( ?\' ?\` ?\" ?\n)))
- (let ((pos (point)))
- (skip-chars-forward "^=\n" muse-colors-region-end)
- (when (eq (char-after) ?\n)
- (setq multiline t)
- (skip-chars-forward "^=" muse-colors-region-end))
- ;; Abort if space exists just before end
- ;; or no '=' at end
- ;; or word constituent follows
- (unless (or (eq (char-syntax (char-before (point))) ?\ )
- (not (eq (char-after (point)) ?=))
- (and (not (eobp))
- (eq (char-syntax (char-after (1+ (point)))) ?w)))
- (setq pos (min (1+ (point)) (point-max)))
- (add-text-properties start (1+ start) '(invisible muse))
- (add-text-properties (1+ start) (point) '(face muse-verbatim))
- (add-text-properties (point)
- (min (1+ (point)) (point-max))
- '(invisible muse))
- (when multiline
- (add-text-properties
- start (min (1+ (point)) (point-max))
- '(font-lock-multiline t))))
- (goto-char pos))))))
-
-(defcustom muse-colors-markup
- `(;; make emphasized text appear emphasized
- ("\\*\\{1,5\\}" ?* muse-colors-emphasized)
-
- ;; make underlined text appear underlined
- (,(concat "_[^" muse-regexp-blank "_\n]")
- ?_ muse-colors-underlined)
-
- ("^#title " ?\# muse-colors-title)
-
- (muse-explicit-link-regexp ?\[ muse-colors-explicit-link)
-
- ;; render in teletype and suppress further parsing
- (,(concat "=[^" muse-regexp-blank "=\n]") ?= muse-colors-verbatim)
-
- ;; highlight any markup tags encountered
- (muse-tag-regexp ?\< muse-colors-custom-tags)
-
- ;; display comments
- (,(concat "^;[" muse-regexp-blank "]") ?\; muse-colors-comment)
-
- ;; this has to come later since it doesn't have a special
- ;; character in the second cell
- (muse-url-regexp t muse-colors-implicit-link)
- )
- "Expressions to highlight an Emacs Muse buffer.
-These are arranged in a rather special fashion, so as to be as quick as
-possible.
-
-Each element of the list is itself a list, of the form:
-
- (LOCATE-REGEXP TEST-CHAR MATCH-FUNCTION)
-
-LOCATE-REGEXP is a partial regexp, and should be the smallest possible
-regexp to differentiate this rule from other rules. It may also be a
-symbol containing such a regexp. The buffer region is scanned only
-once, and LOCATE-REGEXP indicates where the scanner should stop to
-look for highlighting possibilities.
-
-TEST-CHAR is a char or t. The character should match the beginning
-text matched by LOCATE-REGEXP. These chars are used to build a vector
-for fast MATCH-FUNCTION calling.
-
-MATCH-FUNCTION is the function called when a region has been
-identified. It is responsible for adding the appropriate text
-properties to change the appearance of the buffer.
-
-This markup is used to modify the appearance of the original text to
-make it look more like the published HTML would look (like making some
-markup text invisible, inlining images, etc).
-
-font-lock is used to apply the markup rules, so that they can happen
-on a deferred basis. They are not always accurate, but you can use
-\\[font-lock-fontifty-block] near the point of error to force
-fontification in that area."
- :type '(repeat
- (list :tag "Highlight rule"
- (choice (regexp :tag "Locate regexp")
- (symbol :tag "Regexp symbol"))
- (choice (character :tag "Confirm character")
- (const :tag "Default rule" t))
- function))
- :set 'muse-configure-highlighting
- :group 'muse-colors)
-
-;; XEmacs users don't have `font-lock-multiline'.
-(unless (boundp 'font-lock-multiline)
- (defvar font-lock-multiline nil))
-
-(defun muse-use-font-lock ()
- "Set up font-locking for Muse."
- (muse-add-to-invisibility-spec 'muse)
- (set (make-local-variable 'font-lock-multiline) 'undecided)
- (set (make-local-variable 'font-lock-defaults)
- `(nil t nil nil beginning-of-line
- (font-lock-fontify-region-function . muse-colors-region)
- (font-lock-unfontify-region-function
- . muse-unhighlight-region)))
- (set (make-local-variable 'font-lock-fontify-region-function)
- 'muse-colors-region)
- (set (make-local-variable 'font-lock-unfontify-region-function)
- 'muse-unhighlight-region)
- (muse-make-faces)
- (muse-colors-define-highlighting 'muse-mode muse-colors-markup)
- (font-lock-mode t))
-
-(defun muse-colors-buffer ()
- "Re-highlight the entire Muse buffer."
- (interactive)
- (muse-colors-region (point-min) (point-max) t))
-
-(defvar muse-colors-fontifying-p nil
- "Indicate whether Muse is fontifying the current buffer.")
-(make-variable-buffer-local 'muse-colors-fontifying-p)
-
-(defvar muse-colors-delayed-commands nil
- "Commands to be run immediately after highlighting a region.
-
-This is meant to accommodate highlighting <lisp> in #title
-directives after everything else.
-
-It may be modified by Muse functions during highlighting, but not
-the user.")
-(make-variable-buffer-local 'muse-colors-delayed-commands)
-
-(defun muse-colors-region (beg end &optional verbose)
- "Apply highlighting according to `muse-colors-markup'.
-Note that this function should NOT change the buffer, nor should any
-of the functions listed in `muse-colors-markup'."
- (let ((buffer-undo-list t)
- (inhibit-read-only t)
- (inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- (modified-p (buffer-modified-p))
- (muse-colors-fontifying-p t)
- (muse-colors-region-end (muse-line-end-position end))
- (muse-colors-delayed-commands nil)
- (highlighting (muse-colors-find-highlighting major-mode))
- regexp vector remaining
- deactivate-mark)
- (unless highlighting
- (error "No highlighting found for this mode"))
- (setq regexp (nth muse-colors-highlighting.regexp highlighting)
- vector (nth muse-colors-highlighting.vector highlighting)
- remaining (nth muse-colors-highlighting.remaining highlighting))
- (unwind-protect
- (save-excursion
- (save-restriction
- (widen)
- ;; check to see if we should expand the beg/end area for
- ;; proper multiline matches
- (when (and font-lock-multiline
- (> beg (point-min))
- (get-text-property (1- beg) 'font-lock-multiline))
- ;; We are just after or in a multiline match.
- (setq beg (or (previous-single-property-change
- beg 'font-lock-multiline)
- (point-min)))
- (goto-char beg)
- (setq beg (muse-line-beginning-position)))
- (when font-lock-multiline
- (setq end (or (text-property-any end (point-max)
- 'font-lock-multiline nil)
- (point-max))))
- (goto-char end)
- (setq end (muse-line-beginning-position 2))
- ;; Undo any fontification in the area.
- (font-lock-unfontify-region beg end)
- ;; And apply fontification based on `muse-colors-markup'
- (let ((len (float (- end beg)))
- (case-fold-search nil)
- markup-list)
- (goto-char beg)
- (while (and (< (point) end)
- (re-search-forward regexp end t))
- (if verbose
- (message "Highlighting buffer...%d%%"
- (* (/ (float (- (point) beg)) len) 100)))
- (let ((ch (char-after (match-beginning 0))))
- (when (< ch 128)
- (setq markup-list (aref vector ch))))
- (unless markup-list
- (setq markup-list remaining))
- (let ((prev (point)))
- ;; backtrack and figure out which rule matched
- (goto-char (match-beginning 0))
- (catch 'done
- (dolist (entry markup-list)
- (let ((value (cond ((symbolp (car entry))
- (symbol-value (car entry)))
- ((stringp (car entry))
- (car entry))
- (t nil))))
- (when (and (stringp value) (looking-at value))
- (goto-char (match-end 0))
- (when (cdr entry)
- (funcall (cdr entry)))
- (throw 'done t))))
- ;; if no rule matched, which should never happen,
- ;; return to previous position so that forward
- ;; progress is ensured
- (goto-char prev))))
- (dolist (command muse-colors-delayed-commands)
- (apply (car command) (cdr command)))
- (run-hook-with-args 'muse-colors-buffer-hook
- beg end verbose)
- (if verbose (message "Highlighting buffer...done")))))
- (set-buffer-modified-p modified-p))))
-
-(defcustom muse-colors-tags
- '(("example" t nil nil muse-colors-example-tag)
- ("code" t nil nil muse-colors-example-tag)
- ("verbatim" t nil nil muse-colors-literal-tag)
- ("lisp" t t nil muse-colors-lisp-tag)
- ("literal" t nil nil muse-colors-literal-tag))
- "A list of tag specifications for specially highlighting text.
-XML-style tags are the best way to add custom highlighting to Muse.
-This is easily accomplished by customizing this list of markup tags.
-
-For each entry, the name of the tag is given, whether it expects
-a closing tag and/or an optional set of attributes, whether it is
-nestable, and a function that performs whatever action is desired
-within the delimited region.
-
-The function is called with three arguments, the beginning and
-end of the region surrounded by the tags. If properties are
-allowed, they are passed as a third argument in the form of an
-alist. The `end' argument to the function is the last character
-of the enclosed tag or region.
-
-Functions should not modify the contents of the buffer."
- :type '(repeat (list (string :tag "Markup tag")
- (boolean :tag "Expect closing tag" :value t)
- (boolean :tag "Parse attributes" :value nil)
- (boolean :tag "Nestable" :value nil)
- function))
- :group 'muse-colors)
-
-(defvar muse-colors-inhibit-tags-in-directives t
- "If non-nil, don't allow tags to be interpreted in directives.
-This is used to delay highlighting of <lisp> tags in #title until later.")
-(make-variable-buffer-local 'muse-colors-inhibit-tags-in-directives)
-
-(defsubst muse-colors-tag-info (tagname &rest args)
- "Get tag info associated with TAGNAME, ignoring ARGS."
- (assoc tagname muse-colors-tags))
-
-(defun muse-colors-custom-tags ()
- "Highlight `muse-colors-tags'."
- (let ((tag-info (muse-colors-tag-info (match-string 1))))
- (unless (or (not tag-info)
- (get-text-property (match-beginning 0) 'muse-comment)
- (and muse-colors-inhibit-tags-in-directives
- (get-text-property (match-beginning 0) 'muse-directive)))
- (let ((closed-tag (match-string 3))
- (start (match-beginning 0))
- end attrs)
- (when (nth 2 tag-info)
- (let ((attrstr (match-string 2)))
- (while (and attrstr
- (string-match (concat "\\([^"
- muse-regexp-blank
- "=\n]+\\)\\(=\""
- "\\([^\"]+\\)\"\\)?")
- attrstr))
- (let ((attr (cons (downcase
- (muse-match-string-no-properties 1 attrstr))
- (muse-match-string-no-properties 3 attrstr))))
- (setq attrstr (replace-match "" t t attrstr))
- (if attrs
- (nconc attrs (list attr))
- (setq attrs (list attr)))))))
- (if (and (cadr tag-info) (not closed-tag))
- (if (muse-goto-tag-end (car tag-info) (nth 3 tag-info))
- (setq end (match-end 0))
- (setq tag-info nil)))
- (when tag-info
- (let ((args (list start end)))
- (if (nth 2 tag-info)
- (nconc args (list attrs)))
- (apply (nth 4 tag-info) args)))))))
-
-(defun muse-unhighlight-region (begin end &optional verbose)
- "Remove all visual highlights in the buffer (except font-lock)."
- (let ((buffer-undo-list t)
- (inhibit-read-only t)
- (inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- (modified-p (buffer-modified-p))
- deactivate-mark)
- (unwind-protect
- (remove-text-properties
- begin end '(face nil font-lock-multiline nil end-glyph nil
- invisible nil intangible nil display nil
- mouse-face nil keymap nil help-echo nil
- muse-link nil muse-directive nil muse-comment nil
- muse-no-implicit-link nil muse-no-flyspell nil))
- (set-buffer-modified-p modified-p))))
-
-(defun muse-colors-example-tag (beg end)
- "Strip properties and colorize with `muse-verbatim'."
- (muse-unhighlight-region beg end)
- (let ((multi (save-excursion
- (goto-char beg)
- (forward-line 1)
- (> end (point)))))
- (add-text-properties beg end `(face muse-verbatim
- font-lock-multiline ,multi))))
-
-(defun muse-colors-literal-tag (beg end)
- "Strip properties and mark as literal."
- (muse-unhighlight-region beg end)
- (let ((multi (save-excursion
- (goto-char beg)
- (forward-line 1)
- (> end (point)))))
- (add-text-properties beg end `(font-lock-multiline ,multi))))
-
-(defun muse-colors-lisp-tag (beg end attrs)
- "Color the region enclosed by a <lisp> tag."
- (if (not muse-colors-evaluate-lisp-tags)
- (muse-colors-literal-tag beg end)
- (muse-unhighlight-region beg end)
- (let (beg-lisp end-lisp)
- (save-match-data
- (goto-char beg)
- (setq beg-lisp (and (looking-at "<[^>]+>")
- (match-end 0)))
- (goto-char end)
- (setq end-lisp (and (muse-looking-back "</[^>]+>")
- (match-beginning 0))))
- (add-text-properties
- beg end
- (list 'font-lock-multiline t
- 'display (muse-eval-lisp
- (concat
- "(progn "
- (buffer-substring-no-properties beg-lisp end-lisp)
- ")"))
- 'intangible t)))))
-
-(defvar muse-mode-local-map
- (let ((map (make-sparse-keymap)))
- (define-key map [return] 'muse-follow-name-at-point)
- (define-key map [(control ?m)] 'muse-follow-name-at-point)
- (define-key map [(shift return)] 'muse-follow-name-at-point-other-window)
- (if (featurep 'xemacs)
- (progn
- (define-key map [(button2)] 'muse-follow-name-at-mouse)
- (define-key map [(shift button2)]
- 'muse-follow-name-at-mouse-other-window))
- (define-key map [(shift control ?m)]
- 'muse-follow-name-at-point-other-window)
- (define-key map [mouse-2] 'muse-follow-name-at-mouse)
- (define-key map [(shift mouse-2)]
- 'muse-follow-name-at-mouse-other-window)
- (unless (eq emacs-major-version 21)
- (set-keymap-parent map muse-mode-map)))
- map)
- "Local keymap used by Muse while on a link.")
-
-(defvar muse-keymap-property
- (if (or (featurep 'xemacs)
- (>= emacs-major-version 21))
- 'keymap
- 'local-map)
- "The name of the keymap or local-map property.")
-
-(defsubst muse-link-properties (help-str &optional face)
- "Determine text properties to use for a link."
- (append (if face
- (list 'face face 'mouse-face 'highlight 'muse-link t)
- (list 'invisible 'muse 'intangible t))
- (list 'help-echo help-str 'rear-nonsticky t
- muse-keymap-property muse-mode-local-map)))
-
-(defun muse-link-face (link-name &optional explicit)
- "Return the type of LINK-NAME as a face symbol.
-For EXPLICIT links, this is either a normal link or a bad-link
-face. For implicit links, it is either colored normally or
-ignored."
- (save-match-data
- (let ((link (if explicit
- (muse-handle-explicit-link link-name)
- (muse-handle-implicit-link link-name))))
- (when link
- (cond ((string-match muse-url-regexp link)
- 'muse-link)
- ((muse-file-remote-p link)
- 'muse-link)
- ((string-match muse-file-regexp link)
- (when (string-match "/[^/]+#[^#./]+\\'" link)
- ;; strip anchor from the end of a path
- (setq link (substring link 0 (match-beginning 0))))
- (if (file-exists-p link)
- 'muse-link
- 'muse-bad-link))
- ((not (featurep 'muse-project))
- 'muse-link)
- (t
- (if (string-match "#" link)
- (setq link (substring link 0 (match-beginning 0))))
- (if (or (and (muse-project-of-file)
- (muse-project-page-file
- link muse-current-project t))
- (file-exists-p link))
- 'muse-link
- 'muse-bad-link)))))))
-
-(defun muse-colors-use-publishing-directory (link)
- "Make LINK relative to the directory where we will publish the
-current file."
- (let ((style (car (muse-project-applicable-styles
- link (cddr (muse-project)))))
- path)
- (when (and style
- (setq path (muse-style-element :path style)))
- (expand-file-name link path))))
-
-(defun muse-colors-resolve-image-file (link)
- "Determine if we can create images and see if the link is an image
-file."
- (save-match-data
- (and (or (fboundp 'create-image)
- (fboundp 'make-glyph))
- (not (string-match "\\`[uU][rR][lL]:" link))
- (string-match muse-image-regexp link))))
-
-(defun muse-make-file-glyph (filename)
- "Given a file name, return a newly-created image glyph.
-This is a hack for supporting inline images in XEmacs."
- (let ((case-fold-search nil))
- ;; Scan filename to determine image type
- (when (fboundp 'make-glyph)
- (save-match-data
- (cond ((string-match "jpe?g" filename)
- (make-glyph (vector 'jpeg :file filename) 'buffer))
- ((string-match "gif" filename)
- (make-glyph (vector 'gif :file filename) 'buffer))
- ((string-match "png" filename)
- (make-glyph (vector 'png :file filename) 'buffer)))))))
-
-(defun muse-colors-insert-image (link beg end invis-props)
- "Create an image using create-image or make-glyph and insert it
-in place of an image link defined by BEG and END."
- (setq link (expand-file-name link))
- (let ((image-file (cond
- ((eq muse-colors-inline-image-method 'default-directory)
- link)
- ((functionp muse-colors-inline-image-method)
- (funcall muse-colors-inline-image-method link))))
- glyph)
- (when (stringp image-file)
- (if (fboundp 'create-image)
- ;; use create-image and display property
- (let ((display-stuff (condition-case nil
- (create-image image-file)
- (error nil))))
- (when display-stuff
- (add-text-properties beg end (list 'display display-stuff))))
- ;; use make-glyph and invisible property
- (and (setq glyph (muse-make-file-glyph image-file))
- (progn
- (add-text-properties beg end invis-props)
- (add-text-properties beg end (list
- 'end-glyph glyph
- 'help-echo link))))))))
-
-(defun muse-colors-explicit-link ()
- "Color explicit links."
- (when (and (eq ?\[ (char-after (match-beginning 0)))
- (not (get-text-property (match-beginning 0) 'muse-comment))
- (not (get-text-property (match-beginning 0) 'muse-directive)))
- ;; remove flyspell overlays
- (when (fboundp 'flyspell-unhighlight-at)
- (let ((cur (match-beginning 0)))
- (while (> (match-end 0) cur)
- (flyspell-unhighlight-at cur)
- (setq cur (1+ cur)))))
- (let* ((unesc-link (muse-get-link))
- (unesc-desc (muse-get-link-desc))
- (link (muse-link-unescape unesc-link))
- (desc (muse-link-unescape unesc-desc))
- (props (muse-link-properties desc (muse-link-face link t)))
- (invis-props (append props (muse-link-properties desc))))
- ;; see if we should try and inline an image
- (if (and muse-colors-inline-images
- (or (muse-colors-resolve-image-file link)
- (and desc
- (muse-colors-resolve-image-file desc)
- (setq link desc))))
- ;; we found an image, so inline it
- (muse-colors-insert-image
- link
- (match-beginning 0) (match-end 0) invis-props)
- (if desc
- (progn
- ;; we put the normal face properties on the invisible
- ;; portion too, since emacs sometimes will position
- ;; the cursor on an intangible character
- (add-text-properties (match-beginning 0)
- (match-beginning 2) invis-props)
- (add-text-properties (match-beginning 2) (match-end 2) props)
- (add-text-properties (match-end 2) (match-end 0) invis-props)
- ;; in case specials were escaped, cause the unescaped
- ;; text to be displayed
- (unless (string= desc unesc-desc)
- (add-text-properties (match-beginning 2) (match-end 2)
- (list 'display desc))))
- (add-text-properties (match-beginning 0)
- (match-beginning 1) invis-props)
- (add-text-properties (match-beginning 1) (match-end 0) props)
- (add-text-properties (match-end 1) (match-end 0) invis-props)
- (unless (string= link unesc-link)
- (add-text-properties (match-beginning 1) (match-end 1)
- (list 'display link))))
- (goto-char (match-end 0))
- (add-text-properties
- (match-beginning 0) (match-end 0)
- (muse-link-properties (muse-match-string-no-properties 0)
- (muse-link-face link t)))))))
-
-(defun muse-colors-implicit-link ()
- "Color implicit links."
- (unless (or (eq (get-text-property (match-beginning 0) 'invisible) 'muse)
- (get-text-property (match-beginning 0) 'muse-comment)
- (get-text-property (match-beginning 0) 'muse-directive)
- (get-text-property (match-beginning 0) 'muse-no-implicit-link)
- (eq (char-before (match-beginning 0)) ?\")
- (eq (char-after (match-end 0)) ?\"))
- ;; remove flyspell overlays
- (when (fboundp 'flyspell-unhighlight-at)
- (let ((cur (match-beginning 0)))
- (while (> (match-end 0) cur)
- (flyspell-unhighlight-at cur)
- (setq cur (1+ cur)))))
- ;; colorize link
- (let ((link (muse-match-string-no-properties 0))
- (face (muse-link-face (match-string 0))))
- (when face
- (add-text-properties (match-beginning 0) (match-end 0)
- (muse-link-properties
- (muse-match-string-no-properties 0) face))))))
-
-(defun muse-colors-title ()
- "Color #title directives."
- (let ((beg (+ 7 (match-beginning 0))))
- (add-text-properties beg (muse-line-end-position) '(muse-directive t))
- ;; colorize <lisp> tags in #title after other <lisp> tags have had a
- ;; chance to run, so that we can have behavior that is consistent
- ;; with how the document is published
- (setq muse-colors-delayed-commands
- (cons (list 'muse-colors-title-lisp beg (muse-line-end-position))
- muse-colors-delayed-commands))))
-
-(defun muse-colors-title-lisp (beg end)
- "Called after other highlighting is done for a region in order to handle
-<lisp> tags that exist in #title directives."
- (save-restriction
- (narrow-to-region beg end)
- (goto-char (point-min))
- (let ((muse-colors-inhibit-tags-in-directives nil)
- (muse-colors-tags '(("lisp" t t nil muse-colors-lisp-tag))))
- (while (re-search-forward muse-tag-regexp nil t)
- (muse-colors-custom-tags))))
- (add-text-properties beg end '(face muse-header-1)))
-
-(defun muse-colors-comment ()
- "Color comments."
- (add-text-properties (match-beginning 0) (muse-line-end-position)
- (list 'face 'font-lock-comment-face
- 'muse-comment t)))
-
-
-(provide 'muse-colors)
-
-;;; muse-colors.el ends here