Skip to content

Commit

Permalink
Ability to toggle wiki link support
Browse files Browse the repository at this point in the history
Added a new custom variable markdown-enable-wiki-links.
This may be set in a file local variable.
Also added function markdown-toggle-wiki-links.
Updated tests to reflect new variables and behavior.
  • Loading branch information
jrblevin committed Feb 22, 2016
1 parent 385ab7b commit f8fd642
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 73 deletions.
120 changes: 81 additions & 39 deletions markdown-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,11 @@
;; automatically indent new lines when the enter key is pressed
;; (default: `t')
;;
;; * `markdown-enable-wiki-links' - syntax highlighting for wiki
;; links (default: `nil'). Set this to a non-nil value to turn on
;; wiki link support by default. Wiki link support can be toggled
;; later using the function `markdown-toggle-wiki-links'."
;;
;; * `markdown-wiki-link-alias-first' - set to a non-nil value to
;; treat aliased wiki links like `[[link text|PageName]]`
;; (default: `t'). When set to nil, they will be treated as
Expand Down Expand Up @@ -616,9 +621,10 @@

;;; Extensions:

;; Besides supporting the basic Markdown syntax, markdown-mode also
;; includes syntax highlighting for `[[Wiki Links]]` by default. Wiki
;; links may be followed by pressing `C-c C-o` when the point
;; Besides supporting the basic Markdown syntax, Markdown Mode also
;; includes syntax highlighting for `[[Wiki Links]]`. This can be
;; enabled by setting `markdown-enable-wiki-links' to a non-nil value.
;; Wiki links may be followed by pressing `C-c C-o` when the point
;; is at a wiki link. Use `M-p` and `M-n` to quickly jump to the
;; previous and next links (including links of other types).
;; Aliased or piped wiki links of the form `[[link text|PageName]]`
Expand Down Expand Up @@ -983,6 +989,15 @@ auto-indentation by pressing \\[newline-and-indent]."
:group 'markdown
:type 'boolean)

(defcustom markdown-enable-wiki-links nil
"Syntax highlighting for wiki links.
Set this to a non-nil value to turn on wiki link support by default.
Support can be toggled later using the `markdown-toggle-wiki-links'
function or \\[markdown-toggle-wiki-links]."
:group 'markdown
:type 'boolean
:safe 'booleanp)

(defcustom markdown-wiki-link-alias-first t
"When non-nil, treat aliased wiki links like [[alias text|PageName]].
Otherwise, they will be treated as [[PageName|alias text]]."
Expand Down Expand Up @@ -1347,12 +1362,13 @@ Group 6 matches the closing square brackets.")
"<\\(\\(\\sw\\|\\s_\\|\\s.\\)+@\\(\\sw\\|\\s_\\|\\s.\\)+\\)>"
"Regular expression for matching inline email addresses.")

(defconst markdown-regex-link-generic
(concat "\\(?:" markdown-regex-wiki-link
"\\|" markdown-regex-link-inline
(defsubst markdown-make-regex-link-generic ()
"Make regular expression for matching any recognized link."
(concat "\\(?:" markdown-regex-link-inline
(when markdown-enable-wiki-links
(concat "\\|" markdown-regex-wiki-link))
"\\|" markdown-regex-link-reference
"\\|" markdown-regex-angle-uri "\\)")
"Regular expression for matching any recognized link.")
"\\|" markdown-regex-angle-uri "\\)"))

(defconst markdown-regex-gfm-checkbox
" \\(\\[[ xX]\\]\\) "
Expand Down Expand Up @@ -4076,7 +4092,8 @@ text to kill ring), and list items."
(kill-new (match-string 1))
(delete-region (match-beginning 0) (match-end 0)))
;; Wiki link (add alias text to kill ring)
((thing-at-point-looking-at markdown-regex-wiki-link)
((and markdown-enable-wiki-links
(thing-at-point-looking-at markdown-regex-wiki-link))
(kill-new (markdown-wiki-link-alias))
(delete-region (match-beginning 1) (match-end 1)))
;; Bold
Expand Down Expand Up @@ -5281,7 +5298,7 @@ See `markdown-wiki-link-p' and `markdown-previous-wiki-link'."
;; At a link already, move past it.
(goto-char (+ (match-end 0) 1)))
;; Search for the next wiki link and move to the beginning.
(while (and (re-search-forward markdown-regex-link-generic nil t)
(while (and (re-search-forward (markdown-make-regex-link-generic) nil t)
(markdown-code-block-at-point)
(< (point) (point-max))))
(if (and (not (eq (point) opoint))
Expand All @@ -5298,7 +5315,7 @@ If successful, return point. Otherwise, return nil.
See `markdown-wiki-link-p' and `markdown-next-wiki-link'."
(interactive)
(let ((opoint (point)))
(while (and (re-search-backward markdown-regex-link-generic nil t)
(while (and (re-search-backward (markdown-make-regex-link-generic) nil t)
(markdown-code-block-at-point)
(> (point) (point-min))))
(if (and (not (eq (point) opoint))
Expand Down Expand Up @@ -6011,18 +6028,19 @@ not at a link or the link reference is not defined returns nil."
;;; WikiLink Following/Markup =================================================

(defun markdown-wiki-link-p ()
"Return non-nil when `point' is at a true wiki link.
A true wiki link name matches `markdown-regex-wiki-link' but does not
match the current file name after conversion. This modifies the data
returned by `match-data'. Note that the potential wiki link name must
be available via `match-string'."
(let ((case-fold-search nil))
(and (thing-at-point-looking-at markdown-regex-wiki-link)
(not (markdown-code-block-at-point))
(or (not buffer-file-name)
(not (string-equal (buffer-file-name)
(markdown-convert-wiki-link-to-filename
(markdown-wiki-link-link))))))))
"Return non-nil when wiki links are enabled and `point' is at a true wiki link.
A true wiki link name matches `markdown-regex-wiki-link' but does
not match the current file name after conversion. This modifies
the data returned by `match-data'. Note that the potential wiki
link name must be available via `match-string'."
(when markdown-enable-wiki-links
(let ((case-fold-search nil))
(and (thing-at-point-looking-at markdown-regex-wiki-link)
(not (markdown-code-block-at-point))
(or (not buffer-file-name)
(not (string-equal (buffer-file-name)
(markdown-convert-wiki-link-to-filename
(markdown-wiki-link-link)))))))))

(defun markdown-wiki-link-link ()
"Return the link part of the wiki link using current match data.
Expand Down Expand Up @@ -6285,7 +6303,7 @@ This is an exact copy of `line-number-at-pos' for use in emacs21."
;;; Extension Framework =======================================================

(defun markdown-reload-extensions ()
"Check settings, update font-lock keywords, and re-fontify buffer."
"Check settings, update font-lock keywords and hooks, and re-fontify buffer."
(interactive)
(when (eq major-mode 'markdown-mode)
;; Update font lock keywords with extensions
Expand All @@ -6298,17 +6316,54 @@ This is an exact copy of `line-number-at-pos' for use in emacs21."
'(markdown-mode-font-lock-keywords
nil nil nil nil
(font-lock-syntactic-face-function . markdown-syntactic-face)))
;; Add or remove hooks related to extensions
(markdown-setup-wiki-link-hooks)
;; Refontify buffer
(when (fboundp 'font-lock-refresh-defaults) (font-lock-refresh-defaults))))
(when (fboundp 'font-lock-refresh-defaults) (font-lock-refresh-defaults))
(when markdown-enable-wiki-links (markdown-fontify-buffer-wiki-links))))

(defun markdown-handle-local-variables ()
"Runs as a `hack-local-variables-hook' to update font lock rules.
Checks to see if there is actually a markdown-mode file local variable
before regenerating font-lock rules for extensions."
(when (and (boundp 'file-local-variables-alist)
(assoc 'markdown-enable-wiki-links file-local-variables-alist)
(assoc 'markdown-enable-math file-local-variables-alist))
(markdown-reload-extensions)))

;;; Wiki Links ================================================================

(defun markdown-toggle-wiki-links (&optional arg)
"Toggle support for wiki links.
With a prefix argument ARG, enable wiki link support if ARG is positive,
and disable it otherwise."
(interactive (list (or current-prefix-arg 'toggle)))
(setq markdown-enable-wiki-links
(if (eq arg 'toggle)
(not markdown-enable-wiki-links)
(> (prefix-numeric-value arg) 0)))
(if markdown-enable-wiki-links
(message "markdown-mode wiki link support enabled")
(message "markdown-mode wiki link support disabled"))
(markdown-reload-extensions))

(defun markdown-setup-wiki-link-hooks ()
"Add or remove hooks for fontifying wiki links."
;; Anytime text changes make sure it gets fontified correctly
(if markdown-enable-wiki-links
(add-hook 'after-change-functions
'markdown-check-change-for-wiki-link-after-change t t)
(remove-hook 'after-change-functions
'markdown-check-change-for-wiki-link-after-change t))
;; If we left the buffer there is a really good chance we were
;; creating one of the wiki link documents. Make sure we get
;; refontified when we come back.
(if markdown-enable-wiki-links
(add-hook 'window-configuration-change-hook
'markdown-fontify-buffer-wiki-links t t)
(remove-hook 'window-configuration-change-hook
'markdown-fontify-buffer-wiki-links t)))

;;; Math Support ==============================================================

(make-obsolete 'markdown-enable-math 'markdown-toggle-math "v2.1")
Expand Down Expand Up @@ -6501,27 +6556,14 @@ if ARG is omitted or nil."
(make-local-hook 'font-lock-extend-region-functions)
(make-local-hook 'window-configuration-change-hook))

;; Anytime text changes make sure it gets fontified correctly
(add-hook 'after-change-functions
'markdown-check-change-for-wiki-link-after-change t t)

;; Make checkboxes buttons
(when markdown-make-gfm-checkboxes-buttons
(markdown-make-gfm-checkboxes-buttons (point-min) (point-max))
(add-hook 'after-change-functions 'markdown-gfm-checkbox-after-change-function t t))

;; If we left the buffer there is a really good chance we were
;; creating one of the wiki link documents. Make sure we get
;; refontified when we come back.
(add-hook 'window-configuration-change-hook
'markdown-fontify-buffer-wiki-links t t)

;; add live preview export hook
(add-hook 'after-save-hook #'markdown-live-preview-if-markdown t t)
(add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t)

;; do the initial link fontification
(markdown-fontify-buffer-wiki-links))
(add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t))

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
Expand Down
91 changes: 57 additions & 34 deletions tests/markdown-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -1354,8 +1354,6 @@ the opening bracket of [^2], and then subsequent functions would kill [^2])."
'("![foo][bar]" . "foo")
'("<http://foo.com/>" . "http://foo.com/")
'("<foo@bar.com>" . "foo@bar.com")
'("[[foo]]" . "foo")
'("[[foo|bar]]" . "foo")
'("**foo**" . "foo")
'("__foo__" . "foo")
'("*foo*" . "foo")
Expand Down Expand Up @@ -3244,47 +3242,57 @@ like statement. Detail: https://github.com/jrblevin/markdown-mode/issues/75"

;;; Wiki link tests:

(ert-deftest test-markdown-wiki-link/file-local-variabls ()
"Test enabling wiki links via file-local variables."
(markdown-test-file "wiki-links.text"
(should-not markdown-enable-wiki-links)
(hack-local-variables)
(should markdown-enable-wiki-links)))

(ert-deftest test-markdown-wiki-link/aliasing ()
"Test filename extraction for aliased wiki links."
(markdown-test-file "wiki-links.text"
;; Confirm location of first wiki link
(should (eq (markdown-next-link) 8))
;; Confirm location of second wiki link
(should (eq (markdown-next-link) 73))
;; Test predicate function
(should (markdown-wiki-link-p))
;; Test alias-first filename extraction
(setq markdown-wiki-link-alias-first t)
(should (string-equal (markdown-wiki-link-link) "second"))
;; Test alias-second filename extraction
(setq markdown-wiki-link-alias-first nil)
(should (string-equal (markdown-wiki-link-link) "first"))))
(let ((markdown-enable-wiki-links t))
(markdown-test-file "wiki-links.text"
;; Confirm location of first wiki link
(should (eq (markdown-next-link) 8))
;; Confirm location of second wiki link
(should (eq (markdown-next-link) 73))
;; Test predicate function
(should (markdown-wiki-link-p))
;; Test alias-first filename extraction
(setq markdown-wiki-link-alias-first t)
(should (string-equal (markdown-wiki-link-link) "second"))
;; Test alias-second filename extraction
(setq markdown-wiki-link-alias-first nil)
(should (string-equal (markdown-wiki-link-link) "first")))))

(ert-deftest test-markdown-wiki-link/navigation ()
"Test wiki link navigation."
(markdown-test-file "wiki-links.text"
;; Advance to first link
(should (eq (markdown-next-link) 8))
;; Advance to second link
(should (eq (markdown-next-link) 73))
;; Avance to final link
(should (eq (markdown-next-link) 155))
;; Return nil and don't advance point
(should (eq (markdown-next-link) nil))
(should (eq (point) 155))
;; Move back to second link
(should (eq (markdown-previous-link) 73))
;; Move back to first link
(should (eq (markdown-previous-link) 8))
;; Return nil and don't move point
(should (eq (markdown-previous-link) nil))
(should (eq (point) 8))))
(let ((markdown-enable-wiki-links t))
(markdown-test-file "wiki-links.text"
;; Advance to first link
(should (eq (markdown-next-link) 8))
;; Advance to second link
(should (eq (markdown-next-link) 73))
;; Avance to final link
(should (eq (markdown-next-link) 155))
;; Return nil and don't advance point
(should (eq (markdown-next-link) nil))
(should (eq (point) 155))
;; Move back to second link
(should (eq (markdown-previous-link) 73))
;; Move back to first link
(should (eq (markdown-previous-link) 8))
;; Return nil and don't move point
(should (eq (markdown-previous-link) nil))
(should (eq (point) 8)))))

(ert-deftest test-markdown-wiki-link/font-lock ()
"Test font lock faces for wiki links."
(markdown-test-temp-file "wiki-links.text"
(let* ((fn (concat (file-name-directory buffer-file-name)
"inline.text")))
"inline.text"))
(markdown-enable-wiki-links t))
;; Create inline.text in the same temp directory, refontify
(write-region "" nil fn nil 1)
(markdown-fontify-buffer-wiki-links)
Expand All @@ -3305,6 +3313,20 @@ like statement. Detail: https://github.com/jrblevin/markdown-mode/issues/75"
(delete-file fn)
)))

(ert-deftest test-markdown-wiki-link/kill ()
"Simple tests for `markdown-kill-thing-at-point' for wiki links."
(let ((kill-ring nil)
(markdown-enable-wiki-links t)
(tests (list '("[[foo]]" . "foo")
'("[[foo|bar]]" . "bar"))))
(dolist (test tests)
;; Load test string (the car), move to end of first line, kill
;; thing at point, and then verify that the kill ring contains cdr.
(markdown-test-string (car test)
(end-of-line)
(call-interactively 'markdown-kill-thing-at-point)
(should (string-equal (current-kill 0) (cdr test)))))))

;;; Filling tests:

(ert-deftest test-markdown-filling/blockquote ()
Expand Down Expand Up @@ -3713,7 +3735,8 @@ Detail: https://github.com/jrblevin/markdown-mode/issues/79"
(should (string-equal (buffer-string) " #. abc\n def\n"))))

(ert-deftest test-markdown-ext/ikiwiki ()
(let ((markdown-wiki-link-search-parent-directories t))
(let ((markdown-enable-wiki-links t)
(markdown-wiki-link-search-parent-directories t))
(progn
(find-file "ikiwiki/root")
(unwind-protect
Expand Down
4 changes: 4 additions & 0 deletions tests/wiki-links.text
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ links:
}
}
```

<!-- Local Variables: -->
<!-- markdown-enable-wiki-links: t -->
<!-- End: -->

0 comments on commit f8fd642

Please sign in to comment.