update packages
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
;; Maintainer: Jason R. Blevins <jblevins@xbeta.org>
|
||||
;; Created: May 24, 2007
|
||||
;; Version: 2.5-dev
|
||||
;; Package-Version: 20200622.20
|
||||
;; Package-Commit: 399df42755ccf31cecb61c9f5d8ad72bc30d7e4b
|
||||
;; Package-Version: 20210107.101
|
||||
;; Package-Commit: 6d64f9e96203b1e76e3f0adfd2f545b5b02f5ffb
|
||||
;; Package-Requires: ((emacs "25.1"))
|
||||
;; Keywords: Markdown, GitHub Flavored Markdown, itex
|
||||
;; URL: https://jblevins.org/projects/markdown-mode/
|
||||
@@ -118,7 +118,8 @@ arguments."
|
||||
:type '(choice file function (const :tag "None" nil)))
|
||||
|
||||
(defcustom markdown-open-image-command nil
|
||||
"Command used for opening image files directly at `markdown-follow-link-at-point'."
|
||||
"Command used for opening image files directly.
|
||||
This is used at `markdown-follow-link-at-point'."
|
||||
:group 'markdown
|
||||
:type '(choice file function (const :tag "None" nil)))
|
||||
|
||||
@@ -643,7 +644,7 @@ This variant of `rx' supports common Markdown named REGEXPS."
|
||||
"Regular expression matches HTML comment closing.")
|
||||
|
||||
(defconst markdown-regex-link-inline
|
||||
"\\(?1:!\\)?\\(?2:\\[\\)\\(?3:\\^?\\(?:\\\\\\]\\|[^]]\\)*\\|\\)\\(?4:\\]\\)\\(?5:(\\)\\(?6:[^)]*?\\)\\(?:\\s-+\\(?7:\"[^\"]*\"\\)\\)?\\(?8:)\\)"
|
||||
"\\(?1:!\\)?\\(?2:\\[\\)\\(?3:\\^?\\(?:\\\\\\]\\|[^]]\\)*\\|\\)\\(?4:\\]\\)\\(?5:(\\)\\s-*\\(?6:[^)]*?\\)\\(?:\\s-+\\(?7:\"[^\"]*\"\\)\\)?\\s-*\\(?8:)\\)"
|
||||
"Regular expression for a [text](file) or an image link .
|
||||
Group 1 matches the leading exclamation point (optional).
|
||||
Group 2 matches the opening square bracket.
|
||||
@@ -791,7 +792,7 @@ Groups 3 and 5 matches the opening and closing delimiters.
|
||||
Group 4 matches the text inside the delimiters.")
|
||||
|
||||
(defconst markdown-regex-gfm-italic
|
||||
"\\(?:^\\|[^\\]\\)\\(?1:\\(?2:[*_]\\)\\(?3:[^ \\]\\2\\|[^ ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(?4:\\2\\)\\)"
|
||||
"\\(?:^\\|[^\\]\\)\\(?1:\\(?2:[*_]\\)\\(?3:[^ \\]\\2\\|[^ ]\\(?:.\\|\n[^\n]\\)*?\\)\\(?4:\\2\\)\\)"
|
||||
"Regular expression for matching italic text in GitHub Flavored Markdown.
|
||||
Underscores in words are not treated as special.
|
||||
Group 1 matches the entire expression, including delimiters.
|
||||
@@ -907,7 +908,7 @@ Group 5 matches the closing brace (optional) and any surrounding whitespace.
|
||||
Groups need to agree with `markdown-regex-gfm-code-block-open'.")
|
||||
|
||||
(defconst markdown-regex-declarative-metadata
|
||||
"^\\([[:alpha:]][[:alpha:] _-]*?\\)\\([:=][ \t]*\\)\\(.*\\)$"
|
||||
"^[ \t]*\\(?:-[ \t]*\\)?\\([[:alpha:]][[:alpha:] _-]*?\\)\\([:=][ \t]*\\)\\(.*\\)$"
|
||||
"Regular expression for matching declarative metadata statements.
|
||||
This matches MultiMarkdown metadata as well as YAML and TOML
|
||||
assignments such as the following:
|
||||
@@ -1156,7 +1157,8 @@ this property is a list with elements of the form (begin . end)
|
||||
giving the bounds of the current and parent list items."
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(let (bounds level pre-regexp)
|
||||
(let ((prev-list-line -100)
|
||||
bounds level pre-regexp)
|
||||
;; Find a baseline point with zero list indentation
|
||||
(markdown-search-backward-baseline)
|
||||
;; Search for all list items between baseline and END
|
||||
@@ -1173,7 +1175,9 @@ giving the bounds of the current and parent list items."
|
||||
((markdown-new-baseline)
|
||||
(setq bounds nil))
|
||||
;; Make sure this is not a line from a pre block
|
||||
((looking-at-p pre-regexp))
|
||||
((and (looking-at-p pre-regexp)
|
||||
;; too indented line is also treated as list if previous line is list
|
||||
(>= (- (line-number-at-pos) prev-list-line) 2)))
|
||||
;; If not, then update levels and propertize list item when in range.
|
||||
(t
|
||||
(let* ((indent (current-indentation))
|
||||
@@ -1184,6 +1188,7 @@ giving the bounds of the current and parent list items."
|
||||
(setq bounds (markdown--append-list-item-bounds
|
||||
marker indent cur-bounds bounds))
|
||||
(when (and (<= start (point)) (<= (point) end))
|
||||
(setq prev-list-line (line-number-at-pos first))
|
||||
(put-text-property first last 'markdown-list-item bounds)))))
|
||||
(end-of-line)))))
|
||||
|
||||
@@ -1191,50 +1196,54 @@ giving the bounds of the current and parent list items."
|
||||
"Match preformatted text blocks from START to END."
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(let ((levels (markdown-calculate-list-levels))
|
||||
indent pre-regexp close-regexp open close)
|
||||
(while (and (< (point) end) (not close))
|
||||
;; Search for a region with sufficient indentation
|
||||
(if (null levels)
|
||||
(setq indent 1)
|
||||
(setq indent (1+ (length levels))))
|
||||
(setq pre-regexp (format "^\\( \\|\t\\)\\{%d\\}" indent))
|
||||
(setq close-regexp (format "^\\( \\|\t\\)\\{0,%d\\}\\([^ \t]\\)" (1- indent)))
|
||||
(let (finish)
|
||||
;; Use loop for avoiding too many recursive calls
|
||||
;; https://github.com/jrblevin/markdown-mode/issues/512
|
||||
(while (not finish)
|
||||
(let ((levels (markdown-calculate-list-levels))
|
||||
indent pre-regexp close-regexp open close)
|
||||
(while (and (< (point) end) (not close))
|
||||
;; Search for a region with sufficient indentation
|
||||
(if (null levels)
|
||||
(setq indent 1)
|
||||
(setq indent (1+ (length levels))))
|
||||
(setq pre-regexp (format "^\\( \\|\t\\)\\{%d\\}" indent))
|
||||
(setq close-regexp (format "^\\( \\|\t\\)\\{0,%d\\}\\([^ \t]\\)" (1- indent)))
|
||||
|
||||
(cond
|
||||
;; If not at the beginning of a line, move forward
|
||||
((not (bolp)) (forward-line))
|
||||
;; Move past blank lines
|
||||
((markdown-cur-line-blank-p) (forward-line))
|
||||
;; At headers and horizontal rules, reset levels
|
||||
((markdown-new-baseline) (forward-line) (setq levels nil))
|
||||
;; If the current line has sufficient indentation, mark out pre block
|
||||
;; The opening should be preceded by a blank line.
|
||||
((and (markdown-prev-line-blank) (looking-at pre-regexp))
|
||||
(setq open (match-beginning 0))
|
||||
(while (and (or (looking-at-p pre-regexp) (markdown-cur-line-blank-p))
|
||||
(not (eobp)))
|
||||
(forward-line))
|
||||
(skip-syntax-backward "-")
|
||||
(setq close (point)))
|
||||
;; If current line has a list marker, update levels, move to end of block
|
||||
((looking-at markdown-regex-list)
|
||||
(setq levels (markdown-update-list-levels
|
||||
(match-string 2) (current-indentation) levels))
|
||||
(markdown-end-of-text-block))
|
||||
;; If this is the end of the indentation level, adjust levels accordingly.
|
||||
;; Only match end of indentation level if levels is not the empty list.
|
||||
((and (car levels) (looking-at-p close-regexp))
|
||||
(setq levels (markdown-update-list-levels
|
||||
nil (current-indentation) levels))
|
||||
(markdown-end-of-text-block))
|
||||
(t (markdown-end-of-text-block))))
|
||||
(cond
|
||||
;; If not at the beginning of a line, move forward
|
||||
((not (bolp)) (forward-line))
|
||||
;; Move past blank lines
|
||||
((markdown-cur-line-blank-p) (forward-line))
|
||||
;; At headers and horizontal rules, reset levels
|
||||
((markdown-new-baseline) (forward-line) (setq levels nil))
|
||||
;; If the current line has sufficient indentation, mark out pre block
|
||||
;; The opening should be preceded by a blank line.
|
||||
((and (markdown-prev-line-blank) (looking-at pre-regexp))
|
||||
(setq open (match-beginning 0))
|
||||
(while (and (or (looking-at-p pre-regexp) (markdown-cur-line-blank-p))
|
||||
(not (eobp)))
|
||||
(forward-line))
|
||||
(skip-syntax-backward "-")
|
||||
(setq close (point)))
|
||||
;; If current line has a list marker, update levels, move to end of block
|
||||
((looking-at markdown-regex-list)
|
||||
(setq levels (markdown-update-list-levels
|
||||
(match-string 2) (current-indentation) levels))
|
||||
(markdown-end-of-text-block))
|
||||
;; If this is the end of the indentation level, adjust levels accordingly.
|
||||
;; Only match end of indentation level if levels is not the empty list.
|
||||
((and (car levels) (looking-at-p close-regexp))
|
||||
(setq levels (markdown-update-list-levels
|
||||
nil (current-indentation) levels))
|
||||
(markdown-end-of-text-block))
|
||||
(t (markdown-end-of-text-block))))
|
||||
|
||||
(when (and open close)
|
||||
;; Set text property data
|
||||
(put-text-property open close 'markdown-pre (list open close))
|
||||
;; Recursively search again
|
||||
(markdown-syntax-propertize-pre-blocks (point) end)))))
|
||||
(if (and open close)
|
||||
;; Set text property data and continue to search
|
||||
(put-text-property open close 'markdown-pre (list open close))
|
||||
(setq finish t))))
|
||||
nil)))
|
||||
|
||||
(defconst markdown-fenced-block-pairs
|
||||
`(((,markdown-regex-tilde-fence-begin markdown-tilde-fence-begin)
|
||||
@@ -1632,35 +1641,39 @@ region of a YAML metadata block as propertized by
|
||||
|
||||
(defun markdown-syntax-propertize-comments (start end)
|
||||
"Match HTML comments from the START to END."
|
||||
(let* ((in-comment (nth 4 (syntax-ppss)))
|
||||
(comment-begin (nth 8 (syntax-ppss))))
|
||||
;; Implement by loop instead of recursive call for avoiding
|
||||
;; exceed max-lisp-eval-depth issue
|
||||
;; https://github.com/jrblevin/markdown-mode/issues/536
|
||||
(let (finish)
|
||||
(goto-char start)
|
||||
(cond
|
||||
;; Comment start
|
||||
((and (not in-comment)
|
||||
(re-search-forward markdown-regex-comment-start end t)
|
||||
(not (markdown-inline-code-at-point-p))
|
||||
(not (markdown-code-block-at-point-p)))
|
||||
(let ((open-beg (match-beginning 0)))
|
||||
(put-text-property open-beg (1+ open-beg)
|
||||
'syntax-table (string-to-syntax "<"))
|
||||
(markdown-syntax-propertize-comments
|
||||
(min (1+ (match-end 0)) end (point-max)) end)))
|
||||
;; Comment end
|
||||
((and in-comment comment-begin
|
||||
(re-search-forward markdown-regex-comment-end end t))
|
||||
(let ((comment-end (match-end 0)))
|
||||
(put-text-property (1- comment-end) comment-end
|
||||
'syntax-table (string-to-syntax ">"))
|
||||
;; Remove any other text properties inside the comment
|
||||
(remove-text-properties comment-begin comment-end
|
||||
markdown--syntax-properties)
|
||||
(put-text-property comment-begin comment-end
|
||||
'markdown-comment (list comment-begin comment-end))
|
||||
(markdown-syntax-propertize-comments
|
||||
(min (1+ comment-end) end (point-max)) end)))
|
||||
;; Nothing found
|
||||
(t nil))))
|
||||
(while (not finish)
|
||||
(let* ((in-comment (nth 4 (syntax-ppss)))
|
||||
(comment-begin (nth 8 (syntax-ppss))))
|
||||
(cond
|
||||
;; Comment start
|
||||
((and (not in-comment)
|
||||
(re-search-forward markdown-regex-comment-start end t)
|
||||
(not (markdown-inline-code-at-point-p))
|
||||
(not (markdown-code-block-at-point-p)))
|
||||
(let ((open-beg (match-beginning 0)))
|
||||
(put-text-property open-beg (1+ open-beg)
|
||||
'syntax-table (string-to-syntax "<"))
|
||||
(goto-char (min (1+ (match-end 0)) end (point-max)))))
|
||||
;; Comment end
|
||||
((and in-comment comment-begin
|
||||
(re-search-forward markdown-regex-comment-end end t))
|
||||
(let ((comment-end (match-end 0)))
|
||||
(put-text-property (1- comment-end) comment-end
|
||||
'syntax-table (string-to-syntax ">"))
|
||||
;; Remove any other text properties inside the comment
|
||||
(remove-text-properties comment-begin comment-end
|
||||
markdown--syntax-properties)
|
||||
(put-text-property comment-begin comment-end
|
||||
'markdown-comment (list comment-begin comment-end))
|
||||
(goto-char (min (1+ comment-end) end (point-max)))))
|
||||
;; Nothing found
|
||||
(t (setq finish t)))))
|
||||
nil))
|
||||
|
||||
(defun markdown-syntax-propertize (start end)
|
||||
"Function used as `syntax-propertize-function'.
|
||||
@@ -2130,7 +2143,7 @@ Depending on your font, some reasonable choices are:
|
||||
|
||||
(defconst markdown-footnote-chars
|
||||
"[[:alnum:]-]"
|
||||
"Regular expression matching any character that is allowed in a footnote identifier.")
|
||||
"Regular expression matching any character for a footnote identifier.")
|
||||
|
||||
(defconst markdown-regex-footnote-definition
|
||||
(concat "^ \\{0,3\\}\\[\\(\\^" markdown-footnote-chars "*?\\)\\]:\\(?:[ \t]+\\|$\\)")
|
||||
@@ -2144,7 +2157,10 @@ Depending on your font, some reasonable choices are:
|
||||
Used for `flyspell-generic-check-word-predicate'."
|
||||
(save-excursion
|
||||
(goto-char (1- (point)))
|
||||
(if (or (markdown-code-block-at-point-p)
|
||||
;; https://github.com/jrblevin/markdown-mode/issues/560
|
||||
;; enable spell check YAML meta data
|
||||
(if (or (and (markdown-code-block-at-point-p)
|
||||
(not (markdown-text-property-at-point 'markdown-yaml-metadata-section)))
|
||||
(markdown-inline-code-at-point-p)
|
||||
(markdown-in-comment-p)
|
||||
(markdown--face-p (point) '(markdown-reference-face
|
||||
@@ -2629,9 +2645,10 @@ Group 3 matches the closing backquotes."
|
||||
(while (and (markdown-match-code end-of-block)
|
||||
(setq found t)
|
||||
(< (match-end 0) old-point)))
|
||||
(and found ; matched something
|
||||
(<= (match-beginning 0) old-point) ; match contains old-point
|
||||
(> (match-end 0) old-point)))))
|
||||
(let ((match-group (if (eq (char-after (match-beginning 0)) ?`) 0 1)))
|
||||
(and found ; matched something
|
||||
(<= (match-beginning match-group) old-point) ; match contains old-point
|
||||
(> (match-end 0) old-point))))))
|
||||
|
||||
(defun markdown-inline-code-at-pos-p (pos)
|
||||
"Return non-nil if there is an inline code fragment at POS.
|
||||
@@ -2758,10 +2775,23 @@ When FACELESS is non-nil, do not return matches where faces have been applied."
|
||||
(goto-char (min (1+ (match-end 0)) last (point-max)))
|
||||
t))
|
||||
|
||||
(defun markdown--gfm-markup-underscore-p (begin end)
|
||||
(let ((is-underscore (eql (char-after begin) ?_)))
|
||||
(if (not is-underscore)
|
||||
t
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(goto-char begin)
|
||||
(and (looking-back "\\(?:^\\|[[:blank:][:punct:]]\\)" (1- begin))
|
||||
(progn
|
||||
(goto-char end)
|
||||
(looking-at-p "\\(?:[[:blank:][:punct:]]\\|$\\)"))))))))
|
||||
|
||||
(defun markdown-match-bold (last)
|
||||
"Match inline bold from the point to LAST."
|
||||
(when (markdown-match-inline-generic markdown-regex-bold last)
|
||||
(let ((begin (match-beginning 2))
|
||||
(let ((is-gfm (derived-mode-p 'gfm-mode))
|
||||
(begin (match-beginning 2))
|
||||
(end (match-end 2)))
|
||||
(if (or (markdown-inline-code-at-pos-p begin)
|
||||
(markdown-inline-code-at-pos-p end)
|
||||
@@ -2771,7 +2801,8 @@ When FACELESS is non-nil, do not return matches where faces have been applied."
|
||||
markdown-plain-url-face))
|
||||
(markdown-range-property-any
|
||||
begin end 'face '(markdown-hr-face
|
||||
markdown-math-face)))
|
||||
markdown-math-face))
|
||||
(and is-gfm (not (markdown--gfm-markup-underscore-p begin end))))
|
||||
(progn (goto-char (min (1+ begin) last))
|
||||
(when (< (point) last)
|
||||
(markdown-match-bold last)))
|
||||
@@ -2781,21 +2812,9 @@ When FACELESS is non-nil, do not return matches where faces have been applied."
|
||||
(match-beginning 5) (match-end 5)))
|
||||
t))))
|
||||
|
||||
(defun markdown--gfm-italic-p (begin end)
|
||||
(let ((is-underscore (eql (char-after begin) ?_)))
|
||||
(if (not is-underscore)
|
||||
t
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(goto-char begin)
|
||||
(and (looking-back "\\(?:^\\|[[:blank:]]\\)" (1- begin))
|
||||
(progn
|
||||
(goto-char end)
|
||||
(looking-at-p "\\(?:[[:blank:]]\\|$\\)"))))))))
|
||||
|
||||
(defun markdown-match-italic (last)
|
||||
"Match inline italics from the point to LAST."
|
||||
(let* ((is-gfm (memq major-mode '(gfm-mode gfm-view-mode)))
|
||||
(let* ((is-gfm (derived-mode-p 'gfm-mode))
|
||||
(regex (if is-gfm
|
||||
markdown-regex-gfm-italic
|
||||
markdown-regex-italic)))
|
||||
@@ -2808,7 +2827,7 @@ When FACELESS is non-nil, do not return matches where faces have been applied."
|
||||
(close-end (match-end 4)))
|
||||
(if (or (eql (char-before begin) (char-after begin))
|
||||
(markdown-inline-code-at-pos-p begin)
|
||||
(markdown-inline-code-at-pos-p end)
|
||||
(markdown-inline-code-at-pos-p (1- end))
|
||||
(markdown-in-comment-p)
|
||||
(markdown-range-property-any
|
||||
begin begin 'face '(markdown-url-face
|
||||
@@ -2818,7 +2837,9 @@ When FACELESS is non-nil, do not return matches where faces have been applied."
|
||||
markdown-list-face
|
||||
markdown-hr-face
|
||||
markdown-math-face))
|
||||
(and is-gfm (not (markdown--gfm-italic-p begin close-end))))
|
||||
(and is-gfm
|
||||
(or (char-equal (char-after begin) (char-after (1+ begin))) ;; check bold case
|
||||
(not (markdown--gfm-markup-underscore-p begin close-end)))))
|
||||
(progn (goto-char (min (1+ begin) last))
|
||||
(when (< (point) last)
|
||||
(markdown-match-italic last)))
|
||||
@@ -3713,6 +3734,28 @@ be used to populate the title attribute when converted to XHTML."
|
||||
"Reference [%s] was defined, press \\[markdown-do] to jump there")
|
||||
label))))
|
||||
|
||||
(defcustom markdown-link-make-text-function nil
|
||||
"Function that automatically generates a link text for a URL.
|
||||
|
||||
If non-nil, this function will be called by
|
||||
`markdown--insert-link-or-image' and the result will be the
|
||||
default link text. The function should receive exactly one
|
||||
argument that corresponds to the link URL."
|
||||
:group 'markdown
|
||||
:type 'function
|
||||
:package-version '(markdown-mode . "2.5"))
|
||||
|
||||
(defcustom markdown-disable-tooltip-prompt nil
|
||||
"Disable prompt for tooltip when inserting a link or image.
|
||||
|
||||
If non-nil, `markdown-insert-link' and `markdown-insert-link'
|
||||
will not prompt the user to insert a tooltip text for the given
|
||||
link or image."
|
||||
:group 'markdown
|
||||
:type 'boolean
|
||||
:safe 'booleanp
|
||||
:package-version '(markdown-mode . "2.5"))
|
||||
|
||||
(defun markdown--insert-link-or-image (image)
|
||||
"Interactively insert new or update an existing link or image.
|
||||
When IMAGE is non-nil, insert an image. Otherwise, insert a link.
|
||||
@@ -3750,6 +3793,8 @@ This is an internal function called by
|
||||
(if ref
|
||||
"Link text: "
|
||||
"Link text (blank for plain URL): ")))
|
||||
(text (or text (and markdown-link-make-text-function uri
|
||||
(funcall markdown-link-make-text-function uri))))
|
||||
(text (completing-read text-prompt defined-refs nil nil text))
|
||||
(text (if (= (length text) 0) nil text))
|
||||
(plainp (and uri (not text)))
|
||||
@@ -3758,7 +3803,7 @@ This is an internal function called by
|
||||
(definedp (and ref (markdown-reference-definition ref)))
|
||||
(ref-url (unless (or uri definedp)
|
||||
(completing-read "Reference URL: " used-uris)))
|
||||
(title (unless (or plainp definedp)
|
||||
(title (unless (or plainp definedp markdown-disable-tooltip-prompt)
|
||||
(read-string "Title (tooltip text, optional): " title)))
|
||||
(title (if (= (length title) 0) nil title)))
|
||||
(when (and image implicitp)
|
||||
@@ -3801,7 +3846,12 @@ it seems to be a URL, or link text value otherwise.
|
||||
If a given reference is not defined, this function will
|
||||
additionally prompt for the URL and optional title. In this case,
|
||||
the reference definition is placed at the location determined by
|
||||
`markdown-reference-location'.
|
||||
`markdown-reference-location'. In addition, it is possible to
|
||||
have the `markdown-link-make-text-function' function, if non-nil,
|
||||
define the default link text before prompting the user for it.
|
||||
|
||||
If `markdown-disable-tooltip-prompt' is non-nil, the user will
|
||||
not be prompted to add or modify a tooltip text.
|
||||
|
||||
Through updating the link, this function can be used to convert a
|
||||
link of one type (inline, reference, or plain) to another type by
|
||||
@@ -4254,6 +4304,11 @@ opening code fence and an info string."
|
||||
:safe #'natnump
|
||||
:package-version '(markdown-mode . "2.3"))
|
||||
|
||||
(defcustom markdown-code-block-braces nil
|
||||
"When non-nil, automatically insert braces for GFM code blocks."
|
||||
:group 'markdown
|
||||
:type 'boolean)
|
||||
|
||||
(defun markdown-insert-gfm-code-block (&optional lang edit)
|
||||
"Insert GFM code block for language LANG.
|
||||
If LANG is nil, the language will be queried from user. If a
|
||||
@@ -4274,45 +4329,49 @@ code block in an indirect buffer after insertion."
|
||||
(quit "")))
|
||||
current-prefix-arg))
|
||||
(unless (string= lang "") (markdown-gfm-add-used-language lang))
|
||||
(when (> (length lang) 0)
|
||||
(when (and (> (length lang) 0)
|
||||
(not markdown-code-block-braces))
|
||||
(setq lang (concat (make-string markdown-spaces-after-code-fence ?\s)
|
||||
lang)))
|
||||
(if (use-region-p)
|
||||
(let* ((b (region-beginning)) (e (region-end)) end
|
||||
(indent (progn (goto-char b) (current-indentation))))
|
||||
(goto-char e)
|
||||
;; if we're on a blank line, don't newline, otherwise the ```
|
||||
;; should go on its own line
|
||||
(unless (looking-back "\n" nil)
|
||||
(newline))
|
||||
(let ((gfm-open-brace (if markdown-code-block-braces "{" ""))
|
||||
(gfm-close-brace (if markdown-code-block-braces "}" "")))
|
||||
(if (use-region-p)
|
||||
(let* ((b (region-beginning)) (e (region-end)) end
|
||||
(indent (progn (goto-char b) (current-indentation))))
|
||||
(goto-char e)
|
||||
;; if we're on a blank line, don't newline, otherwise the ```
|
||||
;; should go on its own line
|
||||
(unless (looking-back "\n" nil)
|
||||
(newline))
|
||||
(indent-to indent)
|
||||
(insert "```")
|
||||
(markdown-ensure-blank-line-after)
|
||||
(setq end (point))
|
||||
(goto-char b)
|
||||
;; if we're on a blank line, insert the quotes here, otherwise
|
||||
;; add a new line first
|
||||
(unless (looking-at-p "\n")
|
||||
(newline)
|
||||
(forward-line -1))
|
||||
(markdown-ensure-blank-line-before)
|
||||
(indent-to indent)
|
||||
(insert "```" gfm-open-brace lang gfm-close-brace)
|
||||
(markdown-syntax-propertize-fenced-block-constructs (point-at-bol) end))
|
||||
(let ((indent (current-indentation))
|
||||
start-bol)
|
||||
(delete-horizontal-space :backward-only)
|
||||
(markdown-ensure-blank-line-before)
|
||||
(indent-to indent)
|
||||
(setq start-bol (point-at-bol))
|
||||
(insert "```" gfm-open-brace lang gfm-close-brace "\n")
|
||||
(indent-to indent)
|
||||
(unless edit (insert ?\n))
|
||||
(indent-to indent)
|
||||
(insert "```")
|
||||
(markdown-ensure-blank-line-after)
|
||||
(setq end (point))
|
||||
(goto-char b)
|
||||
;; if we're on a blank line, insert the quotes here, otherwise
|
||||
;; add a new line first
|
||||
(unless (looking-at-p "\n")
|
||||
(newline)
|
||||
(forward-line -1))
|
||||
(markdown-ensure-blank-line-before)
|
||||
(indent-to indent)
|
||||
(insert "```" lang)
|
||||
(markdown-syntax-propertize-fenced-block-constructs (point-at-bol) end))
|
||||
(let ((indent (current-indentation)) start-bol)
|
||||
(delete-horizontal-space :backward-only)
|
||||
(markdown-ensure-blank-line-before)
|
||||
(indent-to indent)
|
||||
(setq start-bol (point-at-bol))
|
||||
(insert "```" lang "\n")
|
||||
(indent-to indent)
|
||||
(unless edit (insert ?\n))
|
||||
(indent-to indent)
|
||||
(insert "```")
|
||||
(markdown-ensure-blank-line-after)
|
||||
(markdown-syntax-propertize-fenced-block-constructs start-bol (point)))
|
||||
(end-of-line 0)
|
||||
(when edit (markdown-edit-code-block))))
|
||||
(markdown-syntax-propertize-fenced-block-constructs start-bol (point)))
|
||||
(end-of-line 0)
|
||||
(when edit (markdown-edit-code-block)))))
|
||||
|
||||
(defun markdown-code-block-lang (&optional pos-prop)
|
||||
"Return the language name for a GFM or tilde fenced code block.
|
||||
@@ -5486,52 +5545,61 @@ See also `markdown-mode-map'.")
|
||||
"Create and return a nested imenu index alist for the current buffer.
|
||||
See `imenu-create-index-function' and `imenu--index-alist' for details."
|
||||
(let* ((root '(nil . nil))
|
||||
cur-alist
|
||||
(cur-level 0)
|
||||
(empty-heading "-")
|
||||
(self-heading ".")
|
||||
hashes pos level heading)
|
||||
(min-level 9999)
|
||||
hashes headers)
|
||||
(save-excursion
|
||||
;; Headings
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward markdown-regex-header (point-max) t)
|
||||
(unless (markdown-code-block-at-point-p)
|
||||
(unless (or (markdown-code-block-at-point-p)
|
||||
(and (match-beginning 3)
|
||||
(get-text-property (match-beginning 3) 'markdown-yaml-metadata-end)))
|
||||
(cond
|
||||
((match-string-no-properties 2) ;; level 1 setext
|
||||
(setq heading (match-string-no-properties 1))
|
||||
(setq pos (match-beginning 1)
|
||||
level 1))
|
||||
(setq min-level 1)
|
||||
(push (list :heading (match-string-no-properties 1)
|
||||
:point (match-beginning 1)
|
||||
:level 1) headers))
|
||||
((match-string-no-properties 3) ;; level 2 setext
|
||||
(setq heading (match-string-no-properties 1))
|
||||
(setq pos (match-beginning 1)
|
||||
level 2))
|
||||
(setq min-level (min min-level 2))
|
||||
(push (list :heading (match-string-no-properties 1)
|
||||
:point (match-beginning 1)
|
||||
:level (- 2 (1- min-level))) headers))
|
||||
((setq hashes (markdown-trim-whitespace
|
||||
(match-string-no-properties 4)))
|
||||
(setq heading (match-string-no-properties 5)
|
||||
pos (match-beginning 4)
|
||||
level (length hashes))))
|
||||
(let ((alist (list (cons heading pos))))
|
||||
(cond
|
||||
((= cur-level level) ; new sibling
|
||||
(setcdr cur-alist alist)
|
||||
(setq cur-alist alist))
|
||||
((< cur-level level) ; first child
|
||||
(dotimes (_ (- level cur-level 1))
|
||||
(setq alist (list (cons empty-heading alist))))
|
||||
(if cur-alist
|
||||
(let* ((parent (car cur-alist))
|
||||
(self-pos (cdr parent)))
|
||||
(setcdr parent (cons (cons self-heading self-pos) alist)))
|
||||
(setcdr root alist)) ; primogenitor
|
||||
(setq cur-alist alist)
|
||||
(setq cur-level level))
|
||||
(t ; new sibling of an ancestor
|
||||
(let ((sibling-alist (last (cdr root))))
|
||||
(dotimes (_ (1- level))
|
||||
(setq sibling-alist (last (cdar sibling-alist))))
|
||||
(setcdr sibling-alist alist)
|
||||
(setq cur-alist alist))
|
||||
(setq cur-level level))))))
|
||||
(setq min-level (min min-level (length hashes)))
|
||||
(push (list :heading (match-string-no-properties 5)
|
||||
:point (match-beginning 4)
|
||||
:level (- (length hashes) (1- min-level))) headers)))))
|
||||
(cl-loop with cur-level = 0
|
||||
with cur-alist = nil
|
||||
with empty-heading = "-"
|
||||
with self-heading = "."
|
||||
for header in (reverse headers)
|
||||
for level = (plist-get header :level)
|
||||
do
|
||||
(let ((alist (list (cons (plist-get header :heading) (plist-get header :point)))))
|
||||
(cond
|
||||
((= cur-level level) ; new sibling
|
||||
(setcdr cur-alist alist)
|
||||
(setq cur-alist alist))
|
||||
((< cur-level level) ; first child
|
||||
(dotimes (_ (- level cur-level 1))
|
||||
(setq alist (list (cons empty-heading alist))))
|
||||
(if cur-alist
|
||||
(let* ((parent (car cur-alist))
|
||||
(self-pos (cdr parent)))
|
||||
(setcdr parent (cons (cons self-heading self-pos) alist)))
|
||||
(setcdr root alist)) ; primogenitor
|
||||
(setq cur-alist alist)
|
||||
(setq cur-level level))
|
||||
(t ; new sibling of an ancestor
|
||||
(let ((sibling-alist (last (cdr root))))
|
||||
(dotimes (_ (1- level))
|
||||
(setq sibling-alist (last (cdar sibling-alist))))
|
||||
(setcdr sibling-alist alist)
|
||||
(setq cur-alist alist))
|
||||
(setq cur-level level)))))
|
||||
;; Footnotes
|
||||
(let ((fn (markdown-get-defined-footnotes)))
|
||||
(if (or (zerop (length fn))
|
||||
@@ -5849,7 +5917,7 @@ CHECKER-FUNCTION."
|
||||
"\n\nIf SILENT is non-nil, do not message anything when no
|
||||
such references found.")
|
||||
(interactive "P")
|
||||
(when (not (memq major-mode '(markdown-mode gfm-mode)))
|
||||
(unless (derived-mode-p 'markdown-mode)
|
||||
(user-error "Not available in current mode"))
|
||||
(let ((oldbuf (current-buffer))
|
||||
(refs (,checker-function))
|
||||
@@ -6683,15 +6751,15 @@ setext header, but should not be folded."
|
||||
;; This function was originally derived from `org-cycle' from org.el.
|
||||
(defun markdown-cycle (&optional arg)
|
||||
"Visibility cycling for Markdown mode.
|
||||
If ARG is t, perform global visibility cycling. If the point is
|
||||
at an atx-style header, cycle visibility of the corresponding
|
||||
subtree. Otherwise, indent the current line or insert a tab,
|
||||
as appropriate, by calling `indent-for-tab-command'."
|
||||
This function is called with a `\\[universal-argument]' or if ARG is t, perform
|
||||
global visibility cycling. If the point is at an atx-style header, cycle
|
||||
visibility of the corresponding subtree. Otherwise, indent the current line
|
||||
or insert a tab, as appropriate, by calling `indent-for-tab-command'."
|
||||
(interactive "P")
|
||||
(cond
|
||||
|
||||
;; Global cycling
|
||||
((eq arg t)
|
||||
(arg
|
||||
(cond
|
||||
;; Move from overview to contents
|
||||
((and (eq last-command this-command)
|
||||
@@ -7765,7 +7833,7 @@ in parent directories if
|
||||
`markdown-wiki-link-search-parent-directories' is non-nil."
|
||||
(let* ((basename (replace-regexp-in-string
|
||||
"[[:space:]\n]" markdown-link-space-sub-char name))
|
||||
(basename (if (memq major-mode '(gfm-mode gfm-view-mode))
|
||||
(basename (if (derived-mode-p 'gfm-mode)
|
||||
(concat (upcase (substring basename 0 1))
|
||||
(downcase (substring basename 1 nil)))
|
||||
basename))
|
||||
@@ -7806,7 +7874,7 @@ window when OTHER is non-nil."
|
||||
(when other (other-window 1))
|
||||
(let ((default-directory wp))
|
||||
(find-file filename)))
|
||||
(unless (memq major-mode '(markdown-mode gfm-mode))
|
||||
(unless (derived-mode-p 'markdown-mode)
|
||||
(markdown-mode))))
|
||||
|
||||
(defun markdown-follow-wiki-link-at-point (&optional arg)
|
||||
@@ -8131,8 +8199,7 @@ or span."
|
||||
(defun markdown-reload-extensions ()
|
||||
"Check settings, update font-lock keywords and hooks, and re-fontify buffer."
|
||||
(interactive)
|
||||
(when (member major-mode
|
||||
'(markdown-mode markdown-view-mode gfm-mode gfm-view-mode))
|
||||
(when (derived-mode-p 'markdown-mode)
|
||||
;; Refontify buffer
|
||||
(font-lock-flush)
|
||||
;; Add or remove hooks related to extensions
|
||||
@@ -8352,31 +8419,39 @@ or \\[markdown-toggle-inline-images]."
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward markdown-regex-link-inline nil t)
|
||||
(let ((start (match-beginning 0))
|
||||
(let* ((start (match-beginning 0))
|
||||
(imagep (match-beginning 1))
|
||||
(end (match-end 0))
|
||||
(file (match-string-no-properties 6)))
|
||||
(file (match-string-no-properties 6))
|
||||
(unhex_file (url-unhex-string file)))
|
||||
(when (and imagep
|
||||
(not (zerop (length file))))
|
||||
(unless (file-exists-p file)
|
||||
(unless (file-exists-p unhex_file)
|
||||
(let* ((download-file (funcall markdown-translate-filename-function file))
|
||||
(valid-url (ignore-errors
|
||||
(member (downcase (url-type (url-generic-parse-url download-file)))
|
||||
markdown-remote-image-protocols))))
|
||||
(when (and markdown-display-remote-images valid-url)
|
||||
(setq file (markdown--get-remote-image download-file)))))
|
||||
(when (file-exists-p file)
|
||||
(let* ((abspath (if (file-name-absolute-p file)
|
||||
file
|
||||
(concat default-directory file)))
|
||||
(if (and markdown-display-remote-images valid-url)
|
||||
(setq file (markdown--get-remote-image download-file))
|
||||
(when (not valid-url)
|
||||
;; strip query parameter
|
||||
(setq file (replace-regexp-in-string "?.+\\'" "" file))))))
|
||||
(when (file-exists-p unhex_file)
|
||||
(let* ((abspath (if (file-name-absolute-p unhex_file)
|
||||
unhex_file
|
||||
(concat default-directory unhex_file)))
|
||||
(image
|
||||
(if (and markdown-max-image-size
|
||||
(cond ((and markdown-max-image-size
|
||||
(image-type-available-p 'imagemagick))
|
||||
(create-image
|
||||
abspath 'imagemagick nil
|
||||
:max-width (car markdown-max-image-size)
|
||||
:max-height (cdr markdown-max-image-size))
|
||||
(create-image abspath))))
|
||||
(create-image
|
||||
abspath 'imagemagick nil
|
||||
:max-width (car markdown-max-image-size)
|
||||
:max-height (cdr markdown-max-image-size)))
|
||||
(markdown-max-image-size
|
||||
(create-image abspath nil nil
|
||||
:max-width (car markdown-max-image-size)
|
||||
:max-height (cdr markdown-max-image-size)))
|
||||
(t (create-image abspath)))))
|
||||
(when image
|
||||
(let ((ov (make-overlay start end)))
|
||||
(overlay-put ov 'display image)
|
||||
@@ -8533,11 +8608,19 @@ position."
|
||||
(defvar edit-indirect-guess-mode-function)
|
||||
(defvar edit-indirect-after-commit-functions)
|
||||
|
||||
(defun markdown--edit-indirect-after-commit-function (_beg end)
|
||||
"Ensure trailing newlines at the END of code blocks."
|
||||
(defun markdown--edit-indirect-after-commit-function (beg end)
|
||||
"Corrective logic run on code block content from lines BEG to END.
|
||||
Restores code block indentation from BEG to END, and ensures trailing newlines
|
||||
at the END of code blocks."
|
||||
;; ensure trailing newlines
|
||||
(goto-char end)
|
||||
(unless (eq (char-before) ?\n)
|
||||
(insert "\n")))
|
||||
(insert "\n"))
|
||||
;; restore code block indentation
|
||||
(goto-char (- beg 1))
|
||||
(let ((block-indentation (current-indentation)))
|
||||
(when (> block-indentation 0)
|
||||
(indent-rigidly beg end block-indentation))))
|
||||
|
||||
(defun markdown-edit-code-block ()
|
||||
"Edit Markdown code block in an indirect buffer."
|
||||
@@ -8548,13 +8631,17 @@ position."
|
||||
(begin (and bounds (goto-char (nth 0 bounds)) (point-at-bol 2)))
|
||||
(end (and bounds (goto-char (nth 1 bounds)) (point-at-bol 1))))
|
||||
(if (and begin end)
|
||||
(let* ((lang (markdown-code-block-lang))
|
||||
(let* ((indentation (and (goto-char (nth 0 bounds)) (current-indentation)))
|
||||
(lang (markdown-code-block-lang))
|
||||
(mode (or (and lang (markdown-get-lang-mode lang))
|
||||
markdown-edit-code-block-default-mode))
|
||||
(edit-indirect-guess-mode-function
|
||||
(lambda (_parent-buffer _beg _end)
|
||||
(funcall mode))))
|
||||
(edit-indirect-region begin end 'display-buffer))
|
||||
(funcall mode)))
|
||||
(indirect-buf (edit-indirect-region begin end 'display-buffer)))
|
||||
(when (> indentation 0) ;; un-indent in edit-indirect buffer
|
||||
(with-current-buffer indirect-buf
|
||||
(indent-rigidly (point-min) (point-max) (- indentation)))))
|
||||
(user-error "Not inside a GFM or tilde fenced code block")))
|
||||
(when (y-or-n-p "Package edit-indirect needed to edit code blocks. Install it now? ")
|
||||
(progn (package-refresh-contents)
|
||||
@@ -9090,7 +9177,7 @@ Create new table lines if required."
|
||||
(progn
|
||||
(re-search-forward "\\(?:^\\|[^\\]\\)|" end)
|
||||
(when (looking-at "[ \t]*$")
|
||||
(re-search-forward "\\(?^|[^\\]:\\)|" end))
|
||||
(re-search-forward "\\(?:^\\|[^\\]:\\)|" end))
|
||||
(when (and (looking-at "[-:]")
|
||||
(re-search-forward "^\\(?:[ \t]*\\|[^\\]\\)|\\([^-:]\\)" end t))
|
||||
(goto-char (match-beginning 1)))
|
||||
@@ -9391,6 +9478,8 @@ rows and columns and the column alignment."
|
||||
(setq-local comment-column 0)
|
||||
(setq-local comment-auto-fill-only-comments nil)
|
||||
(setq-local comment-use-syntax t)
|
||||
;; Sentence
|
||||
(setq-local sentence-end-base "[.?!…‽][]\"'”’)}»›*_`~]*")
|
||||
;; Syntax
|
||||
(add-hook 'syntax-propertize-extend-region-functions
|
||||
#'markdown-syntax-propertize-extend-region)
|
||||
|
||||
Reference in New Issue
Block a user