update packages

This commit is contained in:
2021-01-08 19:32:30 +01:00
parent ce8f24d28a
commit f5649dceab
467 changed files with 26642 additions and 22487 deletions

View File

@@ -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 ![text](file).
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)