From 82b8ca280905ea284730f228ae082c42c348e818 Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Thu, 17 Mar 2011 11:36:56 +0100 Subject: Big emacs cleanup, must be lighter --- emacs.d/elisp/muse/muse-colors.el | 1022 ------------------------------------- 1 file changed, 1022 deletions(-) delete mode 100644 emacs.d/elisp/muse/muse-colors.el (limited to 'emacs.d/elisp/muse/muse-colors.el') 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 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 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 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 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 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 tags in #title after other 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 - 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 -- cgit v1.2.3-54-g00ecf