From fce4ab59d5afa980fff07083d285886f648d1eb6 Mon Sep 17 00:00:00 2001 From: Andreas Gerler Date: Sun, 22 Dec 2024 13:09:08 +0100 Subject: [PATCH] update markdown-mode Signed-off-by: Andreas Gerler --- .../markdown-mode-pkg.el | 14 - .../markdown-mode-autoloads.el | 57 +- .../markdown-mode-pkg.el | 10 + .../markdown-mode.el | 822 ++++++++++++------ elpa/markdown-mode-readme.txt | 1 - 5 files changed, 615 insertions(+), 289 deletions(-) delete mode 100644 elpa/markdown-mode-20230716.1308/markdown-mode-pkg.el rename elpa/{markdown-mode-20230716.1308 => markdown-mode-20241117.1510}/markdown-mode-autoloads.el (62%) create mode 100644 elpa/markdown-mode-20241117.1510/markdown-mode-pkg.el rename elpa/{markdown-mode-20230716.1308 => markdown-mode-20241117.1510}/markdown-mode.el (93%) delete mode 100644 elpa/markdown-mode-readme.txt diff --git a/elpa/markdown-mode-20230716.1308/markdown-mode-pkg.el b/elpa/markdown-mode-20230716.1308/markdown-mode-pkg.el deleted file mode 100644 index 77171c28..00000000 --- a/elpa/markdown-mode-20230716.1308/markdown-mode-pkg.el +++ /dev/null @@ -1,14 +0,0 @@ -(define-package "markdown-mode" "20230716.1308" "Major mode for Markdown-formatted text" - '((emacs "26.1")) - :commit "0a7404a1c7b1916ca6e8408a6c8bad9125c846d2" :authors - '(("Jason R. Blevins" . "jblevins@xbeta.org")) - :maintainers - '(("Jason R. Blevins" . "jblevins@xbeta.org")) - :maintainer - '("Jason R. Blevins" . "jblevins@xbeta.org") - :keywords - '("markdown" "github flavored markdown" "itex") - :url "https://jblevins.org/projects/markdown-mode/") -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/markdown-mode-20230716.1308/markdown-mode-autoloads.el b/elpa/markdown-mode-20241117.1510/markdown-mode-autoloads.el similarity index 62% rename from elpa/markdown-mode-20230716.1308/markdown-mode-autoloads.el rename to elpa/markdown-mode-20241117.1510/markdown-mode-autoloads.el index d23959a7..133298d5 100644 --- a/elpa/markdown-mode-20230716.1308/markdown-mode-autoloads.el +++ b/elpa/markdown-mode-20241117.1510/markdown-mode-autoloads.el @@ -1,68 +1,63 @@ -;;; markdown-mode-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*- -;; +;;; markdown-mode-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*- +;; Generated by the `loaddefs-generate' function. + +;; This file is part of GNU Emacs. + ;;; Code: -(add-to-list 'load-path (directory-file-name - (or (file-name-directory #$) (car load-path)))) +(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path))) + -;;;### (autoloads nil "markdown-mode" "markdown-mode.el" (0 0 0 0)) ;;; Generated autoloads from markdown-mode.el (autoload 'markdown-mode "markdown-mode" "\ Major mode for editing Markdown files. -\(fn)" t nil) - +(fn)" t) (add-to-list 'auto-mode-alist '("\\.\\(?:md\\|markdown\\|mkd\\|mdown\\|mkdn\\|mdwn\\)\\'" . markdown-mode)) - (autoload 'gfm-mode "markdown-mode" "\ Major mode for editing GitHub Flavored Markdown files. -\(fn)" t nil) - +(fn)" t) (autoload 'markdown-view-mode "markdown-mode" "\ Major mode for viewing Markdown content. -\(fn)" t nil) - +(fn)" t) (autoload 'gfm-view-mode "markdown-mode" "\ Major mode for viewing GitHub Flavored Markdown content. -\(fn)" t nil) - +(fn)" t) (autoload 'markdown-live-preview-mode "markdown-mode" "\ Toggle native previewing on save for a specific markdown file. This is a minor mode. If called interactively, toggle the -`Markdown-Live-Preview mode' mode. If the prefix argument is -positive, enable the mode, and if it is zero or negative, disable -the mode. +`Markdown-Live-Preview mode' mode. If the prefix argument is positive, +enable the mode, and if it is zero or negative, disable the mode. -If called from Lisp, toggle the mode if ARG is `toggle'. Enable -the mode if ARG is nil, omitted, or is a positive number. -Disable the mode if ARG is a negative number. +If called from Lisp, toggle the mode if ARG is `toggle'. Enable the +mode if ARG is nil, omitted, or is a positive number. Disable the mode +if ARG is a negative number. To check whether the minor mode is enabled in the current buffer, -evaluate `markdown-live-preview-mode'. - -The mode's hook is called both when the mode is enabled and when -it is disabled. +evaluate the variable `markdown-live-preview-mode'. -\(fn &optional ARG)" t nil) +The mode's hook is called both when the mode is enabled and when it is +disabled. +(fn &optional ARG)" t) (register-definition-prefixes "markdown-mode" '("defun-markdown-" "gfm-" "markdown")) - -;;;*** -;;;### (autoloads nil nil ("markdown-mode-pkg.el") (0 0 0 0)) +;;; End of scraped data + +(provide 'markdown-mode-autoloads) -;;;*** - ;; Local Variables: ;; version-control: never ;; no-byte-compile: t ;; no-update-autoloads: t -;; coding: utf-8 +;; no-native-compile: t +;; coding: utf-8-emacs-unix ;; End: + ;;; markdown-mode-autoloads.el ends here diff --git a/elpa/markdown-mode-20241117.1510/markdown-mode-pkg.el b/elpa/markdown-mode-20241117.1510/markdown-mode-pkg.el new file mode 100644 index 00000000..c91c3c46 --- /dev/null +++ b/elpa/markdown-mode-20241117.1510/markdown-mode-pkg.el @@ -0,0 +1,10 @@ +;; -*- no-byte-compile: t; lexical-binding: nil -*- +(define-package "markdown-mode" "20241117.1510" + "Major mode for Markdown-formatted text." + '((emacs "27.1")) + :url "https://github.com/jrblevin/markdown-mode" + :commit "b8637bae075231d70fe7f845305eaba2c0240d89" + :revdesc "b8637bae0752" + :keywords '("markdown" "github flavored markdown" "itex") + :authors '(("Jason R. Blevins" . "jblevins@xbeta.org")) + :maintainers '(("Jason R. Blevins" . "jblevins@xbeta.org"))) diff --git a/elpa/markdown-mode-20230716.1308/markdown-mode.el b/elpa/markdown-mode-20241117.1510/markdown-mode.el similarity index 93% rename from elpa/markdown-mode-20230716.1308/markdown-mode.el rename to elpa/markdown-mode-20241117.1510/markdown-mode.el index 521e191a..8cfa90b1 100644 --- a/elpa/markdown-mode-20230716.1308/markdown-mode.el +++ b/elpa/markdown-mode-20241117.1510/markdown-mode.el @@ -1,13 +1,14 @@ ;;; markdown-mode.el --- Major mode for Markdown-formatted text -*- lexical-binding: t; -*- -;; Copyright (C) 2007-2022 Jason R. Blevins and markdown-mode +;; Copyright (C) 2007-2023 Jason R. Blevins and markdown-mode ;; contributors (see the commit log for details). ;; Author: Jason R. Blevins ;; Maintainer: Jason R. Blevins ;; Created: May 24, 2007 -;; Version: 2.6-alpha -;; Package-Requires: ((emacs "26.1")) +;; Package-Version: 20241117.1510 +;; Package-Revision: b8637bae0752 +;; Package-Requires: ((emacs "27.1")) ;; Keywords: Markdown, GitHub Flavored Markdown, itex ;; URL: https://jblevins.org/projects/markdown-mode/ @@ -51,11 +52,18 @@ (declare-function project-roots "project") (declare-function sh-set-shell "sh-script") +(declare-function mailcap-file-name-to-mime-type "mailcap") +(declare-function dnd-get-local-file-name "dnd") + +;; for older emacs<29 +(declare-function mailcap-mime-type-to-extension "mailcap") +(declare-function file-name-with-extension "files") +(declare-function yank-media-handler "yank-media") ;;; Constants ================================================================= -(defconst markdown-mode-version "2.6-alpha" +(defconst markdown-mode-version "2.7-alpha" "Markdown mode version number.") (defconst markdown-output-buffer-name "*markdown-output*" @@ -73,6 +81,13 @@ (defvar markdown-gfm-language-history nil "History list of languages used in the current buffer in GFM code blocks.") +(defvar markdown-follow-link-functions nil + "Functions used to follow a link. +Each function is called with one argument, the link's URL. It +should return non-nil if it followed the link, or nil if not. +Functions are called in order until one of them returns non-nil; +otherwise the default link-following function is used.") + ;;; Customizable Variables ==================================================== @@ -168,7 +183,7 @@ defined by Markdown and HTML. Increasing this produces extra whitespace on the left. Decreasing it may be preferred when fewer than six nested heading levels are used." :group 'markdown - :type 'natnump + :type 'integer :safe 'natnump :package-version '(markdown-mode . "2.4")) @@ -301,7 +316,6 @@ be used." This may be a single string or a list of string. In case of a list, the first one that satisfies `char-displayable-p' will be used." - :type 'string :type '(choice (string :tag "Single blockquote display string") (repeat :tag "List of possible blockquote display strings" string)) @@ -357,6 +371,7 @@ Math support can be enabled, disabled, or toggled later using (defcustom markdown-css-paths nil "List of URLs of CSS files to link to in the output XHTML." :group 'markdown + :safe (lambda (x) (and (listp x) (cl-every #'stringp x))) :type '(repeat (string :tag "CSS File Path"))) (defcustom markdown-content-type "text/html" @@ -646,39 +661,61 @@ markdown-header-face-* faces." :safe 'booleanp :package-version '(markdown-mode . "2.5")) +(defcustom markdown-special-ctrl-a/e nil + "Non-nil means `C-a' and `C-e' behave specially in headlines and items. + +When t, `C-a' will bring back the cursor to the beginning of the +headline text. In an item, this will be the position after bullet +and check-box, if any. When the cursor is already at that +position, another `C-a' will bring it to the beginning of the +line. + +`C-e' will jump to the end of the headline, ignoring the presence +of closing tags in the headline. A second `C-e' will then jump to +the true end of the line, after closing tags. This also means +that, when this variable is non-nil, `C-e' also will never jump +beyond the end of the heading of a folded section, i.e. not after +the ellipses. + +When set to the symbol `reversed', the first `C-a' or `C-e' works +normally, going to the true line boundary first. Only a directly +following, identical keypress will bring the cursor to the +special positions. + +This may also be a cons cell where the behavior for `C-a' and +`C-e' is set separately." + :group 'markdown + :type '(choice + (const :tag "off" nil) + (const :tag "on: after hashes/bullet and before closing tags first" t) + (const :tag "reversed: true line boundary first" reversed) + (cons :tag "Set C-a and C-e separately" + (choice :tag "Special C-a" + (const :tag "off" nil) + (const :tag "on: after hashes/bullet first" t) + (const :tag "reversed: before hashes/bullet first" reversed)) + (choice :tag "Special C-e" + (const :tag "off" nil) + (const :tag "on: before closing tags first" t) + (const :tag "reversed: after closing tags first" reversed)))) + :package-version '(markdown-mode . "2.7")) ;;; Markdown-Specific `rx' Macro ============================================== ;; Based on python-rx from python.el. -(eval-and-compile - (defconst markdown-rx-constituents - `((newline . ,(rx "\n")) - ;; Note: #405 not consider markdown-list-indent-width however this is never used - (indent . ,(rx (or (repeat 4 " ") "\t"))) - (block-end . ,(rx (and (or (one-or-more (zero-or-more blank) "\n") line-end)))) - (numeral . ,(rx (and (one-or-more (any "0-9#")) "."))) - (bullet . ,(rx (any "*+:-"))) - (list-marker . ,(rx (or (and (one-or-more (any "0-9#")) ".") - (any "*+:-")))) - (checkbox . ,(rx "[" (any " xX") "]"))) - "Markdown-specific sexps for `markdown-rx'") - - (defun markdown-rx-to-string (form &optional no-group) - "Markdown mode specialized `rx-to-string' function. -This variant supports named Markdown expressions in FORM. -NO-GROUP non-nil means don't put shy groups around the result." - (let ((rx-constituents (append markdown-rx-constituents rx-constituents))) - (rx-to-string form no-group))) - - (defmacro markdown-rx (&rest regexps) - "Markdown mode specialized rx macro. +(defmacro markdown-rx (&rest regexps) + "Markdown mode specialized rx macro. This variant of `rx' supports common Markdown named REGEXPS." - (cond ((null regexps) - (error "No regexp")) - ((cdr regexps) - (markdown-rx-to-string `(and ,@regexps) t)) - (t - (markdown-rx-to-string (car regexps) t))))) + `(rx-let ((newline "\n") + ;; Note: #405 not consider markdown-list-indent-width however this is never used + (indent (or (repeat 4 " ") "\t")) + (block-end (and (or (one-or-more (zero-or-more blank) "\n") line-end))) + (numeral (and (one-or-more (any "0-9#")) ".")) + (bullet (any "*+:-")) + (list-marker (or (and (one-or-more (any "0-9#")) ".") + (any "*+:-"))) + (checkbox (seq "[" (any " xX") "]"))) + (rx ,@regexps))) ;;; Regular Expressions ======================================================= @@ -732,7 +769,7 @@ Group 2 matches only the label, without the surrounding markup. Group 3 matches the closing square bracket.") (defconst markdown-regex-header - "^\\(?:\\(?1:[^\r\n\t -].*\\)\n\\(?:\\(?2:=+\\)\\|\\(?3:-+\\)\\)\\|\\(?4:#+[ \t]+\\)\\(?5:.*?\\)\\(?6:[ \t]*#*\\)\\)$" + "^\\(?:\\(?1:[^\r\n\t -].*\\)\n\\(?:\\(?2:=+\\)\\|\\(?3:-+\\)\\)\\|\\(?4:#+[ \t]+\\)\\(?5:.*?\\)\\(?6:[ \t]+#+\\)?\\)$" "Regexp identifying Markdown headings. Group 1 matches the text of a setext heading. Group 2 matches the underline of a level-1 setext heading. @@ -1106,7 +1143,8 @@ Group 4 matches the text inside the delimiters.") "Property list of all Markdown syntactic properties.") (defvar markdown-literal-faces - '(markdown-inline-code-face + '(markdown-code-face + markdown-inline-code-face markdown-pre-face markdown-math-face markdown-url-face @@ -1141,6 +1179,10 @@ If POS is not given, use point instead." thereis (memq face faces)) (memq face-prop faces)))) +(defsubst markdown--math-block-p (&optional pos) + (when markdown-enable-math + (markdown--face-p (or pos (point)) '(markdown-math-face)))) + (defun markdown-syntax-propertize-extend-region (start end) "Extend START to END region to include an entire block of text. This helps improve syntax analysis for block constructs. @@ -1317,6 +1359,7 @@ giving the bounds of the current and parent list items." (not (eobp))) (forward-line)) (skip-syntax-backward "-") + (forward-line) (setq close (point))) ;; If current line has a list marker, update levels, move to end of block ((looking-at markdown-regex-list) @@ -1799,6 +1842,10 @@ START and END delimit region to propertize." '(face markdown-markup-face invisible markdown-markup) "List of properties and values to apply to markup.") +(defconst markdown-line-break-properties + '(face markdown-line-break-face invisible markdown-markup) + "List of properties and values to apply to line break markup.") + (defconst markdown-language-keyword-properties '(face markdown-language-keyword-face invisible markdown-markup) "List of properties and values to apply to code block language names.") @@ -1845,10 +1892,10 @@ See `markdown-hide-markup' for additional details." (not markdown-hide-markup) (> (prefix-numeric-value arg) 0))) (if markdown-hide-markup - (progn (add-to-invisibility-spec 'markdown-markup) - (message "markdown-mode markup hiding enabled")) - (progn (remove-from-invisibility-spec 'markdown-markup) - (message "markdown-mode markup hiding disabled"))) + (add-to-invisibility-spec 'markdown-markup) + (remove-from-invisibility-spec 'markdown-markup)) + (when (called-interactively-p 'interactive) + (message "markdown-mode markup hiding %s" (if markdown-hide-markup "enabled" "disabled"))) (markdown-reload-extensions)) @@ -2065,7 +2112,7 @@ headers of levels one through six respectively." '(2.0 1.7 1.4 1.1 1.0 1.0) "List of scaling values for headers of level one through six. Used when `markdown-header-scaling' is non-nil." - :type 'list + :type '(repeat float) :initialize #'custom-initialize-default :set (lambda (symbol value) (set-default symbol value) @@ -2242,7 +2289,7 @@ Depending on your font, some reasonable choices are: (markdown--match-highlighting . ((3 markdown-markup-properties) (4 'markdown-highlighting-face) (5 markdown-markup-properties))) - (,markdown-regex-line-break . (1 'markdown-line-break-face prepend)) + (,markdown-regex-line-break . (1 markdown-line-break-properties prepend)) (markdown-match-escape . ((1 markdown-markup-properties prepend))) (markdown-fontify-sub-superscripts) (markdown-match-inline-attributes . ((0 markdown-markup-properties prepend))) @@ -2744,8 +2791,9 @@ They does not include square brackets)." uris :test #'equal))) (reverse uris)))) -(defun markdown-inline-code-at-pos (pos) - "Return non-nil if there is an inline code fragment at POS. +(defun markdown-inline-code-at-pos (pos &optional from) + "Return non-nil if there is an inline code fragment at POS starting at FROM. +Uses the beginning of the block if FROM is nil. Return nil otherwise. Set match data according to `markdown-match-code' upon success. This function searches the block for a code fragment that @@ -2762,7 +2810,9 @@ Group 3 matches the closing backquotes." (let ((old-point (point)) (end-of-block (progn (markdown-end-of-text-block) (point))) found) - (markdown-beginning-of-text-block) + (if from + (goto-char from) + (markdown-beginning-of-text-block)) (while (and (markdown-match-code end-of-block) (setq found t) (< (match-end 0) old-point))) @@ -2910,28 +2960,42 @@ When FACELESS is non-nil, do not return matches where faces have been applied." (defun markdown-match-bold (last) "Match inline bold from the point to LAST." - (when (markdown-match-inline-generic markdown-regex-bold last) - (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) - (markdown-in-comment-p) - (markdown-range-property-any - begin begin 'face '(markdown-url-face - markdown-plain-url-face)) - (markdown-range-property-any - begin end 'face '(markdown-hr-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))) - (set-match-data (list (match-beginning 2) (match-end 2) - (match-beginning 3) (match-end 3) - (match-beginning 4) (match-end 4) - (match-beginning 5) (match-end 5))) - t)))) + (let (done + retval + last-inline-code) + (while (not done) + (if (markdown-match-inline-generic markdown-regex-bold last) + (let ((is-gfm (derived-mode-p 'gfm-mode)) + (begin (match-beginning 2)) + (end (match-end 2))) + (if (or + (and last-inline-code + (>= begin (car last-inline-code)) + (< begin (cdr last-inline-code))) + (save-match-data + (when (markdown-inline-code-at-pos begin (cdr last-inline-code)) + (setq last-inline-code `(,(match-beginning 0) . ,(match-end 0))))) + (markdown-inline-code-at-pos-p end) + (markdown-in-comment-p) + (markdown-range-property-any + begin begin 'face '(markdown-url-face + markdown-plain-url-face)) + (markdown-range-property-any + begin end 'face '(markdown-hr-face + markdown-math-face)) + (and is-gfm (not (markdown--gfm-markup-underscore-p begin end)))) + (progn (goto-char (min (1+ begin) last)) + (unless (< (point) last) + (setq + done t))) + (set-match-data (list (match-beginning 2) (match-end 2) + (match-beginning 3) (match-end 3) + (match-beginning 4) (match-end 4) + (match-beginning 5) (match-end 5))) + (setq done t + retval t))) + (setq done t))) + retval)) (defun markdown-match-italic (last) "Match inline italics from the point to LAST." @@ -2939,37 +3003,51 @@ When FACELESS is non-nil, do not return matches where faces have been applied." (regex (if is-gfm markdown-regex-gfm-italic markdown-regex-italic))) - (when (and (markdown-match-inline-generic regex last) - (not (markdown--face-p - (match-beginning 1) - '(markdown-html-attr-name-face markdown-html-attr-value-face)))) - (let ((begin (match-beginning 1)) - (end (match-end 1)) - (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 (1- end)) - (markdown-in-comment-p) - (markdown-range-property-any - begin begin 'face '(markdown-url-face - markdown-plain-url-face - markdown-markup-face)) - (markdown-range-property-any - begin end 'face '(markdown-bold-face - markdown-list-face - markdown-hr-face - markdown-math-face)) - (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))) - (set-match-data (list (match-beginning 1) (match-end 1) - (match-beginning 2) (match-end 2) - (match-beginning 3) (match-end 3) - (match-beginning 4) (match-end 4))) - t))))) + (let (done + retval + last-inline-code) + (while (not done) + (if (and (markdown-match-inline-generic regex last) + (not (markdown--face-p + (match-beginning 1) + '(markdown-html-attr-name-face markdown-html-attr-value-face)))) + (let ((begin (match-beginning 1)) + (end (match-end 1)) + (close-end (match-end 4))) + (if (or (eql (char-before begin) (char-after begin)) + (and last-inline-code + (>= begin (car last-inline-code)) + (< begin (cdr last-inline-code))) + (save-match-data + (when (markdown-inline-code-at-pos begin (cdr last-inline-code)) + (setq last-inline-code `(,(match-beginning 0) . ,(match-end 0))))) + + (markdown-inline-code-at-pos-p (1- end)) + (markdown-in-comment-p) + (markdown-range-property-any + begin begin 'face '(markdown-url-face + markdown-plain-url-face + markdown-markup-face)) + (markdown-range-property-any + begin end 'face '(markdown-bold-face + markdown-list-face + markdown-hr-face + markdown-math-face)) + (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)) + (unless (< (point) last) + (setq + done t))) + (set-match-data (list (match-beginning 1) (match-end 1) + (match-beginning 2) (match-end 2) + (match-beginning 3) (match-end 3) + (match-beginning 4) (match-end 4))) + (setq done t + retval t))) + (setq done t))) + retval))) (defun markdown--match-highlighting (last) (when markdown-enable-highlighting-syntax @@ -3483,17 +3561,25 @@ SEQ may be an atom or a sequence." (add-text-properties (match-beginning 3) (match-end 3) rule-props))) ;; atx heading - (if markdown-fontify-whole-heading-line - (let ((header-end (min (point-max) (1+ (match-end 0))))) - (add-text-properties - (match-beginning 0) header-end heading-props)) + (let ((fontified-start + (if (or markdown-hide-markup (not markdown-fontify-whole-heading-line)) + (match-beginning 5) + (match-beginning 0))) + (fontified-end + (if markdown-fontify-whole-heading-line + (min (point-max) (1+ (match-end 0))) + (match-end 5)))) (add-text-properties (match-beginning 4) (match-end 4) left-markup-props) - (add-text-properties - (match-beginning 5) (match-end 5) heading-props) - (when (match-end 6) - (add-text-properties - (match-beginning 6) (match-end 6) right-markup-props))))) + + ;; If closing tag is present + (if (match-end 6) + (progn + (add-text-properties fontified-start fontified-end heading-props) + (when (or markdown-hide-markup (not markdown-fontify-whole-heading-line)) + (add-text-properties (match-beginning 6) (match-end 6) right-markup-props))) + ;; If closing tag is not present + (add-text-properties fontified-start fontified-end heading-props))))) t)) (defun markdown-fontify-tables (last) @@ -3575,7 +3661,8 @@ SEQ may be an atom or a sequence." (when (markdown-search-until-condition (lambda () (and (not (markdown-code-block-at-point-p)) (not (markdown-inline-code-at-point-p)) - (not (markdown-in-comment-p)))) + (not (markdown-in-comment-p)) + (not (markdown--math-block-p)))) markdown-regex-sub-superscript last t) (let* ((subscript-p (string= (match-string 2) "~")) (props @@ -3738,12 +3825,12 @@ prefixed with an integer from 1 to the length of (when (and beg skip-space) (save-excursion (goto-char beg) - (skip-chars-forward "[ \t]") + (skip-chars-forward " \t") (setq beg (point)))) (when (and end skip-space) (save-excursion (goto-char end) - (skip-chars-backward "[ \t]") + (skip-chars-backward " \t") (setq end (point)))) (markdown-wrap-or-insert start-delim end-delim nil beg end)) (if (markdown--face-p (point) (list face)) @@ -4358,87 +4445,131 @@ if three backquotes inserted at the beginning of line." ;; scripts/get-recognized-gfm-languages.el. that produces a single long sexp, ;; but with appropriate use of a keyboard macro, indenting and filling it ;; properly is pretty fast. - '("1C-Enterprise" "4D" "ABAP" "ABNF" "AGS-Script" "AMPL" "ANTLR" - "API-Blueprint" "APL" "ASN.1" "ASP" "ATS" "ActionScript" "Ada" + '("1C-Enterprise" "2-Dimensional-Array" "4D" "ABAP" "ABAP-CDS" "ABNF" + "AGS-Script" "AIDL" "AL" "AMPL" "ANTLR" "API-Blueprint" "APL" "ASL" + "ASN.1" "ASP.NET" "ATS" "ActionScript" "Ada" "Adblock-Filter-List" "Adobe-Font-Metrics" "Agda" "Alloy" "Alpine-Abuild" "Altium-Designer" - "AngelScript" "Ant-Build-System" "ApacheConf" "Apex" - "Apollo-Guidance-Computer" "AppleScript" "Arc" "AsciiDoc" "AspectJ" "Assembly" - "Asymptote" "Augeas" "AutoHotkey" "AutoIt" "Awk" "Ballerina" "Batchfile" - "Befunge" "BibTeX" "Bison" "BitBake" "Blade" "BlitzBasic" "BlitzMax" - "Bluespec" "Boo" "Brainfuck" "Brightscript" "C#" "C++" "C-ObjDump" - "C2hs-Haskell" "CLIPS" "CMake" "COBOL" "COLLADA" "CSON" "CSS" "CSV" "CWeb" - "Cabal-Config" "Cap'n-Proto" "CartoCSS" "Ceylon" "Chapel" "Charity" "ChucK" - "Cirru" "Clarion" "Clean" "Click" "Clojure" "Closure-Templates" - "Cloud-Firestore-Security-Rules" "CoNLL-U" "CodeQL" "CoffeeScript" - "ColdFusion" "ColdFusion-CFC" "Common-Lisp" "Common-Workflow-Language" - "Component-Pascal" "Cool" "Coq" "Cpp-ObjDump" "Creole" "Crystal" "Csound" - "Csound-Document" "Csound-Score" "Cuda" "Cycript" "Cython" "D-ObjDump" - "DIGITAL-Command-Language" "DM" "DNS-Zone" "DTrace" "Dafny" "Darcs-Patch" - "Dart" "DataWeave" "Dhall" "Diff" "DirectX-3D-File" "Dockerfile" "Dogescript" - "Dylan" "EBNF" "ECL" "ECLiPSe" "EJS" "EML" "EQ" "Eagle" "Easybuild" - "Ecere-Projects" "EditorConfig" "Edje-Data-Collection" "Eiffel" "Elixir" "Elm" - "Emacs-Lisp" "EmberScript" "Erlang" "F#" "F*" "FIGlet-Font" "FLUX" "Factor" - "Fancy" "Fantom" "Faust" "Filebench-WML" "Filterscript" "Formatted" "Forth" - "Fortran" "Fortran-Free-Form" "FreeMarker" "Frege" "G-code" "GAML" "GAMS" - "GAP" "GCC-Machine-Description" "GDB" "GDScript" "GEDCOM" "GLSL" "GN" - "Game-Maker-Language" "Genie" "Genshi" "Gentoo-Ebuild" "Gentoo-Eclass" - "Gerber-Image" "Gettext-Catalog" "Gherkin" "Git-Attributes" "Git-Config" - "Glyph" "Glyph-Bitmap-Distribution-Format" "Gnuplot" "Go" "Golo" "Gosu" - "Grace" "Gradle" "Grammatical-Framework" "Graph-Modeling-Language" "GraphQL" - "Graphviz-(DOT)" "Groovy" "Groovy-Server-Pages" "HAProxy" "HCL" "HLSL" "HTML" - "HTML+Django" "HTML+ECR" "HTML+EEX" "HTML+ERB" "HTML+PHP" "HTML+Razor" "HTTP" - "HXML" "Hack" "Haml" "Handlebars" "Harbour" "Haskell" "Haxe" "HiveQL" "HolyC" - "Hy" "HyPhy" "IDL" "IGOR-Pro" "INI" "IRC-log" "Idris" "Ignore-List" "Inform-7" - "Inno-Setup" "Io" "Ioke" "Isabelle" "Isabelle-ROOT" "JFlex" "JSON" - "JSON-with-Comments" "JSON5" "JSONLD" "JSONiq" "JSX" "Jasmin" "Java" - "Java-Properties" "Java-Server-Pages" "JavaScript" "JavaScript+ERB" "Jison" - "Jison-Lex" "Jolie" "Jsonnet" "Julia" "Jupyter-Notebook" "KRL" "KiCad-Layout" - "KiCad-Legacy-Layout" "KiCad-Schematic" "Kit" "Kotlin" "LFE" "LLVM" "LOLCODE" - "LSL" "LTspice-Symbol" "LabVIEW" "Lasso" "Latte" "Lean" "Less" "Lex" - "LilyPond" "Limbo" "Linker-Script" "Linux-Kernel-Module" "Liquid" - "Literate-Agda" "Literate-CoffeeScript" "Literate-Haskell" "LiveScript" - "Logos" "Logtalk" "LookML" "LoomScript" "Lua" "M4" "M4Sugar" "MATLAB" - "MAXScript" "MLIR" "MQL4" "MQL5" "MTML" "MUF" "Macaulay2" "Makefile" "Mako" - "Markdown" "Marko" "Mask" "Mathematica" "Maven-POM" "Max" "MediaWiki" - "Mercury" "Meson" "Metal" "Microsoft-Developer-Studio-Project" "MiniD" "Mirah" - "Modelica" "Modula-2" "Modula-3" "Module-Management-System" "Monkey" "Moocode" - "MoonScript" "Motorola-68K-Assembly" "Muse" "Myghty" "NASL" "NCL" "NEON" "NL" - "NPM-Config" "NSIS" "Nearley" "Nemerle" "NetLinx" "NetLinx+ERB" "NetLogo" - "NewLisp" "Nextflow" "Nginx" "Nim" "Ninja" "Nit" "Nix" "Nu" "NumPy" "OCaml" - "ObjDump" "Object-Data-Instance-Notation" "ObjectScript" "Objective-C" - "Objective-C++" "Objective-J" "Odin" "Omgrofl" "Opa" "Opal" - "Open-Policy-Agent" "OpenCL" "OpenEdge-ABL" "OpenQASM" "OpenRC-runscript" - "OpenSCAD" "OpenStep-Property-List" "OpenType-Feature-File" "Org" "Ox" - "Oxygene" "Oz" "P4" "PHP" "PLSQL" "PLpgSQL" "POV-Ray-SDL" "Pan" "Papyrus" - "Parrot" "Parrot-Assembly" "Parrot-Internal-Representation" "Pascal" "Pawn" - "Pep8" "Perl" "Pic" "Pickle" "PicoLisp" "PigLatin" "Pike" "PlantUML" "Pod" - "Pod-6" "PogoScript" "Pony" "PostCSS" "PostScript" "PowerBuilder" "PowerShell" - "Prisma" "Processing" "Proguard" "Prolog" "Propeller-Spin" "Protocol-Buffer" - "Public-Key" "Pug" "Puppet" "Pure-Data" "PureBasic" "PureScript" "Python" - "Python-console" "Python-traceback" "QML" "QMake" "Quake" "RAML" "RDoc" - "REALbasic" "REXX" "RHTML" "RMarkdown" "RPC" "RPM-Spec" "RUNOFF" "Racket" - "Ragel" "Raku" "Rascal" "Raw-token-data" "Readline-Config" "Reason" "Rebol" - "Red" "Redcode" "Regular-Expression" "Ren'Py" "RenderScript" - "Rich-Text-Format" "Ring" "Riot" "RobotFramework" "Roff" "Roff-Manpage" - "Rouge" "Ruby" "Rust" "SAS" "SCSS" "SMT" "SPARQL" "SQF" "SQL" "SQLPL" - "SRecode-Template" "SSH-Config" "STON" "SVG" "SWIG" "Sage" "SaltStack" "Sass" - "Scala" "Scaml" "Scheme" "Scilab" "Self" "ShaderLab" "Shell" "ShellSession" - "Shen" "Slash" "Slice" "Slim" "SmPL" "Smali" "Smalltalk" "Smarty" "Solidity" - "SourcePawn" "Spline-Font-Database" "Squirrel" "Stan" "Standard-ML" "Starlark" - "Stata" "Stylus" "SubRip-Text" "SugarSS" "SuperCollider" "Svelte" "Swift" - "SystemVerilog" "TI-Program" "TLA" "TOML" "TSQL" "TSX" "TXL" "Tcl" "Tcsh" - "TeX" "Tea" "Terra" "Texinfo" "Text" "Textile" "Thrift" "Turing" "Turtle" - "Twig" "Type-Language" "TypeScript" "Unified-Parallel-C" "Unity3D-Asset" - "Unix-Assembly" "Uno" "UnrealScript" "UrWeb" "VBA" "VBScript" "VCL" "VHDL" - "Vala" "Verilog" "Vim-Snippet" "Vim-script" "Visual-Basic-.NET" "Volt" "Vue" - "Wavefront-Material" "Wavefront-Object" "Web-Ontology-Language" "WebAssembly" - "WebIDL" "WebVTT" "Wget-Config" "Windows-Registry-Entries" "Wollok" - "World-of-Warcraft-Addon-Data" "X-BitMap" "X-Font-Directory-Index" "X-PixMap" - "X10" "XC" "XCompose" "XML" "XML-Property-List" "XPages" "XProc" "XQuery" "XS" - "XSLT" "Xojo" "Xtend" "YAML" "YANG" "YARA" "YASnippet" "Yacc" "ZAP" "ZIL" - "Zeek" "ZenScript" "Zephir" "Zig" "Zimpl" "cURL-Config" "desktop" "dircolors" - "eC" "edn" "fish" "mIRC-Script" "mcfunction" "mupad" "nanorc" "nesC" "ooc" - "reStructuredText" "sed" "wdl" "wisp" "xBase") + "AngelScript" "Ant-Build-System" "Antlers" "ApacheConf" "Apex" + "Apollo-Guidance-Computer" "AppleScript" "Arc" "AsciiDoc" "AspectJ" + "Assembly" "Astro" "Asymptote" "Augeas" "AutoHotkey" "AutoIt" + "Avro-IDL" "Awk" "BASIC" "Ballerina" "Batchfile" "Beef" "Befunge" + "Berry" "BibTeX" "Bicep" "Bikeshed" "Bison" "BitBake" "Blade" + "BlitzBasic" "BlitzMax" "Bluespec" "Bluespec-BH" "Boo" "Boogie" + "Brainfuck" "BrighterScript" "Brightscript" "Browserslist" "C" "C#" + "C++" "C-ObjDump" "C2hs-Haskell" "CAP-CDS" "CIL" "CLIPS" "CMake" + "COBOL" "CODEOWNERS" "COLLADA" "CSON" "CSS" "CSV" "CUE" "CWeb" + "Cabal-Config" "Cadence" "Cairo" "CameLIGO" "Cap'n-Proto" "CartoCSS" + "Ceylon" "Chapel" "Charity" "Checksums" "ChucK" "Circom" "Cirru" + "Clarion" "Clarity" "Classic-ASP" "Clean" "Click" "Clojure" + "Closure-Templates" "Cloud-Firestore-Security-Rules" "CoNLL-U" + "CodeQL" "CoffeeScript" "ColdFusion" "ColdFusion-CFC" "Common-Lisp" + "Common-Workflow-Language" "Component-Pascal" "Cool" "Coq" + "Cpp-ObjDump" "Creole" "Crystal" "Csound" "Csound-Document" + "Csound-Score" "Cuda" "Cue-Sheet" "Curry" "Cycript" "Cypher" "Cython" + "D" "D-ObjDump" "D2" "DIGITAL-Command-Language" "DM" "DNS-Zone" + "DTrace" "Dafny" "Darcs-Patch" "Dart" "DataWeave" + "Debian-Package-Control-File" "DenizenScript" "Dhall" "Diff" + "DirectX-3D-File" "Dockerfile" "Dogescript" "Dotenv" "Dylan" "E" + "E-mail" "EBNF" "ECL" "ECLiPSe" "EJS" "EQ" "Eagle" "Earthly" + "Easybuild" "Ecere-Projects" "Ecmarkup" "Edge" "EdgeQL" + "EditorConfig" "Edje-Data-Collection" "Eiffel" "Elixir" "Elm" + "Elvish" "Elvish-Transcript" "Emacs-Lisp" "EmberScript" "Erlang" + "Euphoria" "F#" "F*" "FIGlet-Font" "FLUX" "Factor" "Fancy" "Fantom" + "Faust" "Fennel" "Filebench-WML" "Filterscript" "Fluent" "Formatted" + "Forth" "Fortran" "Fortran-Free-Form" "FreeBasic" "FreeMarker" + "Frege" "Futhark" "G-code" "GAML" "GAMS" "GAP" + "GCC-Machine-Description" "GDB" "GDScript" "GEDCOM" "GLSL" "GN" "GSC" + "Game-Maker-Language" "Gemfile.lock" "Gemini" "Genero-4gl" + "Genero-per" "Genie" "Genshi" "Gentoo-Ebuild" "Gentoo-Eclass" + "Gerber-Image" "Gettext-Catalog" "Gherkin" "Git-Attributes" + "Git-Config" "Git-Revision-List" "Gleam" "Glimmer-JS" "Glimmer-TS" + "Glyph" "Glyph-Bitmap-Distribution-Format" "Gnuplot" "Go" + "Go-Checksums" "Go-Module" "Go-Workspace" "Godot-Resource" "Golo" + "Gosu" "Grace" "Gradle" "Gradle-Kotlin-DSL" "Grammatical-Framework" + "Graph-Modeling-Language" "GraphQL" "Graphviz-(DOT)" "Groovy" + "Groovy-Server-Pages" "HAProxy" "HCL" "HLSL" "HOCON" "HTML" + "HTML+ECR" "HTML+EEX" "HTML+ERB" "HTML+PHP" "HTML+Razor" "HTTP" + "HXML" "Hack" "Haml" "Handlebars" "Harbour" "Haskell" "Haxe" "HiveQL" + "HolyC" "Hosts-File" "Hy" "HyPhy" "IDL" "IGOR-Pro" "INI" "IRC-log" + "Idris" "Ignore-List" "ImageJ-Macro" "Imba" "Inform-7" "Ink" + "Inno-Setup" "Io" "Ioke" "Isabelle" "Isabelle-ROOT" "J" + "JAR-Manifest" "JCL" "JFlex" "JSON" "JSON-with-Comments" "JSON5" + "JSONLD" "JSONiq" "Janet" "Jasmin" "Java" "Java-Properties" + "Java-Server-Pages" "JavaScript" "JavaScript+ERB" "Jest-Snapshot" + "JetBrains-MPS" "Jinja" "Jison" "Jison-Lex" "Jolie" "Jsonnet" "Julia" + "Jupyter-Notebook" "Just" "KRL" "Kaitai-Struct" "KakouneScript" + "KerboScript" "KiCad-Layout" "KiCad-Legacy-Layout" "KiCad-Schematic" + "Kickstart" "Kit" "Kotlin" "Kusto" "LFE" "LLVM" "LOLCODE" "LSL" + "LTspice-Symbol" "LabVIEW" "Lark" "Lasso" "Latte" "Lean" "Lean-4" + "Less" "Lex" "LigoLANG" "LilyPond" "Limbo" "Linker-Script" + "Linux-Kernel-Module" "Liquid" "Literate-Agda" + "Literate-CoffeeScript" "Literate-Haskell" "LiveScript" "Logos" + "Logtalk" "LookML" "LoomScript" "Lua" "M" "M4" "M4Sugar" "MATLAB" + "MAXScript" "MDX" "MLIR" "MQL4" "MQL5" "MTML" "MUF" "Macaulay2" + "Makefile" "Mako" "Markdown" "Marko" "Mask" "Mathematica" "Maven-POM" + "Max" "Mercury" "Mermaid" "Meson" "Metal" + "Microsoft-Developer-Studio-Project" + "Microsoft-Visual-Studio-Solution" "MiniD" "MiniYAML" "Mint" "Mirah" + "Modelica" "Modula-2" "Modula-3" "Module-Management-System" "Mojo" + "Monkey" "Monkey-C" "Moocode" "MoonScript" "Motoko" + "Motorola-68K-Assembly" "Move" "Muse" "Mustache" "Myghty" "NASL" + "NCL" "NEON" "NL" "NPM-Config" "NSIS" "NWScript" "Nasal" "Nearley" + "Nemerle" "NetLinx" "NetLinx+ERB" "NetLogo" "NewLisp" "Nextflow" + "Nginx" "Nim" "Ninja" "Nit" "Nix" "Nu" "NumPy" "Nunjucks" "Nushell" + "OASv2-json" "OASv2-yaml" "OASv3-json" "OASv3-yaml" "OCaml" "Oberon" + "ObjDump" "Object-Data-Instance-Notation" "ObjectScript" + "Objective-C" "Objective-C++" "Objective-J" "Odin" "Omgrofl" "Opa" + "Opal" "Open-Policy-Agent" "OpenAPI-Specification-v2" + "OpenAPI-Specification-v3" "OpenCL" "OpenEdge-ABL" "OpenQASM" + "OpenRC-runscript" "OpenSCAD" "OpenStep-Property-List" + "OpenType-Feature-File" "Option-List" "Org" "Ox" "Oxygene" "Oz" "P4" + "PDDL" "PEG.js" "PHP" "PLSQL" "PLpgSQL" "POV-Ray-SDL" "Pact" "Pan" + "Papyrus" "Parrot" "Parrot-Assembly" "Parrot-Internal-Representation" + "Pascal" "Pawn" "Pep8" "Perl" "Pic" "Pickle" "PicoLisp" "PigLatin" + "Pike" "Pip-Requirements" "PlantUML" "Pod" "Pod-6" "PogoScript" + "Polar" "Pony" "Portugol" "PostCSS" "PostScript" "PowerBuilder" + "PowerShell" "Praat" "Prisma" "Processing" "Procfile" "Proguard" + "Prolog" "Promela" "Propeller-Spin" "Protocol-Buffer" + "Protocol-Buffer-Text-Format" "Public-Key" "Pug" "Puppet" "Pure-Data" + "PureBasic" "PureScript" "Pyret" "Python" "Python-console" + "Python-traceback" "Q#" "QML" "QMake" "Qt-Script" "Quake" "R" "RAML" + "RBS" "RDoc" "REALbasic" "REXX" "RMarkdown" "RPC" "RPGLE" "RPM-Spec" + "RUNOFF" "Racket" "Ragel" "Raku" "Rascal" "Raw-token-data" "ReScript" + "Readline-Config" "Reason" "ReasonLIGO" "Rebol" "Record-Jar" "Red" + "Redcode" "Redirect-Rules" "Regular-Expression" "Ren'Py" + "RenderScript" "Rez" "Rich-Text-Format" "Ring" "Riot" + "RobotFramework" "Roc" "Roff" "Roff-Manpage" "Rouge" + "RouterOS-Script" "Ruby" "Rust" "SAS" "SCSS" "SELinux-Policy" "SMT" + "SPARQL" "SQF" "SQL" "SQLPL" "SRecode-Template" "SSH-Config" "STAR" + "STL" "STON" "SVG" "SWIG" "Sage" "SaltStack" "Sass" "Scala" "Scaml" + "Scenic" "Scheme" "Scilab" "Self" "ShaderLab" "Shell" + "ShellCheck-Config" "ShellSession" "Shen" "Sieve" + "Simple-File-Verification" "Singularity" "Slash" "Slice" "Slim" + "Slint" "SmPL" "Smali" "Smalltalk" "Smarty" "Smithy" "Snakemake" + "Solidity" "Soong" "SourcePawn" "Spline-Font-Database" "Squirrel" + "Stan" "Standard-ML" "Starlark" "Stata" "StringTemplate" "Stylus" + "SubRip-Text" "SugarSS" "SuperCollider" "Svelte" "Sway" "Sweave" + "Swift" "SystemVerilog" "TI-Program" "TL-Verilog" "TLA" "TOML" "TSQL" + "TSV" "TSX" "TXL" "Talon" "Tcl" "Tcsh" "TeX" "Tea" "Terra" + "Terraform-Template" "Texinfo" "Text" "TextGrid" + "TextMate-Properties" "Textile" "Thrift" "Toit" "Turing" "Turtle" + "Twig" "Type-Language" "TypeScript" "Typst" "Unified-Parallel-C" + "Unity3D-Asset" "Unix-Assembly" "Uno" "UnrealScript" "UrWeb" "V" + "VBA" "VBScript" "VCL" "VHDL" "Vala" "Valve-Data-Format" + "Velocity-Template-Language" "Verilog" "Vim-Help-File" "Vim-Script" + "Vim-Snippet" "Visual-Basic-.NET" "Visual-Basic-6.0" "Volt" "Vue" + "Vyper" "WDL" "WGSL" "Wavefront-Material" "Wavefront-Object" + "Web-Ontology-Language" "WebAssembly" "WebAssembly-Interface-Type" + "WebIDL" "WebVTT" "Wget-Config" "Whiley" "Wikitext" + "Win32-Message-File" "Windows-Registry-Entries" "Witcher-Script" + "Wollok" "World-of-Warcraft-Addon-Data" "Wren" "X-BitMap" + "X-Font-Directory-Index" "X-PixMap" "X10" "XC" "XCompose" "XML" + "XML-Property-List" "XPages" "XProc" "XQuery" "XS" "XSLT" "Xojo" + "Xonsh" "Xtend" "YAML" "YANG" "YARA" "YASnippet" "Yacc" "Yul" "ZAP" + "ZIL" "Zeek" "ZenScript" "Zephir" "Zig" "Zimpl" "cURL-Config" + "desktop" "dircolors" "eC" "edn" "fish" "hoon" "jq" "kvlang" + "mIRC-Script" "mcfunction" "mupad" "nanorc" "nesC" "ooc" "q" + "reStructuredText" "robots.txt" "sed" "wisp" "xBase") "Language specifiers recognized by GitHub's syntax highlighting features.") (defvar-local markdown-gfm-used-languages nil @@ -4652,6 +4783,7 @@ element. More details here https://developer.mozilla.org/en-US/docs/Web/HTML/Ele (interactive) (let ((fn (markdown-footnote-counter-inc))) (insert (format "[^%d]" fn)) + (push-mark (point) t) (markdown-footnote-text-find-new-location) (markdown-ensure-blank-line-before) (unless (markdown-cur-line-blank-p) @@ -4775,7 +4907,7 @@ footnote text is found, NIL is returned." (save-excursion (goto-char (point-min)) (when (re-search-forward (concat "^ \\{0,3\\}\\[" id "\\]:") nil t) - (skip-chars-forward "[ \t]") + (skip-chars-forward " \t") (point)))) (defun markdown-footnote-marker-positions () @@ -5053,9 +5185,10 @@ list simply adds a blank line)." (setq bounds (markdown-cur-list-item-bounds))) (let ((beg (cl-first bounds)) (end (cl-second bounds)) - (length (cl-fourth bounds))) + (nonlist-indent (cl-fourth bounds)) + (checkbox (cl-sixth bounds))) ;; Point is in a list item - (if (= (- end beg) length) + (if (= (- end beg) (+ nonlist-indent (length checkbox))) ;; Delete blank list (progn (delete-region beg end) @@ -5497,6 +5630,9 @@ Assumes match data is available for `markdown-regex-italic'." (define-key map (kbd "C-x n s") 'markdown-narrow-to-subtree) (define-key map (kbd "M-RET") 'markdown-insert-list-item) (define-key map (kbd "C-c C-j") 'markdown-insert-list-item) + ;; Lines + (define-key map [remap move-beginning-of-line] 'markdown-beginning-of-line) + (define-key map [remap move-end-of-line] 'markdown-end-of-line) ;; Paragraphs (Markdown context aware) (define-key map [remap backward-paragraph] 'markdown-backward-paragraph) (define-key map [remap forward-paragraph] 'markdown-forward-paragraph) @@ -6440,6 +6576,130 @@ a list." ;;; Movement ================================================================== +;; This function was originally derived from `org-beginning-of-line' from org.el. +(defun markdown-beginning-of-line (&optional n) + "Go to the beginning of the current visible line. + +If this is a headline, and `markdown-special-ctrl-a/e' is not nil +or symbol `reversed', on the first attempt move to where the +headline text hashes, and only move to beginning of line when the +cursor is already before the hashes of the text of the headline. + +If `markdown-special-ctrl-a/e' is symbol `reversed' then go to +the hashes of the text on the second attempt. + +With argument N not nil or 1, move forward N - 1 lines first." + (interactive "^p") + (let ((origin (point)) + (special (pcase markdown-special-ctrl-a/e + (`(,C-a . ,_) C-a) (_ markdown-special-ctrl-a/e))) + deactivate-mark) + ;; First move to a visible line. + (if visual-line-mode + (beginning-of-visual-line n) + (move-beginning-of-line n) + ;; `move-beginning-of-line' may leave point after invisible + ;; characters if line starts with such of these (e.g., with + ;; a link at column 0). Really move to the beginning of the + ;; current visible line. + (forward-line 0)) + (cond + ;; No special behavior. Point is already at the beginning of + ;; a line, logical or visual. + ((not special)) + ;; `beginning-of-visual-line' left point before logical beginning + ;; of line: point is at the beginning of a visual line. Bail + ;; out. + ((and visual-line-mode (not (bolp)))) + ((looking-at markdown-regex-header-atx) + ;; At a header, special position is before the title. + (let ((refpos (match-beginning 2)) + (bol (point))) + (if (eq special 'reversed) + (when (and (= origin bol) (eq last-command this-command)) + (goto-char refpos)) + (when (or (> origin refpos) (<= origin bol)) + (goto-char refpos))) + ;; Prevent automatic cursor movement caused by the command loop. + ;; Enable disable-point-adjustment to avoid unintended cursor repositioning. + (when (and markdown-hide-markup + (equal (get-char-property (point) 'display) "")) + (setq disable-point-adjustment t)))) + ((looking-at markdown-regex-list) + ;; At a list item, special position is after the list marker or checkbox. + (let ((refpos (or (match-end 4) (match-end 3)))) + (if (eq special 'reversed) + (when (and (= (point) origin) (eq last-command this-command)) + (goto-char refpos)) + (when (or (> origin refpos) (<= origin (line-beginning-position))) + (goto-char refpos))))) + ;; No special case, already at beginning of line. + (t nil)))) + +;; This function was originally derived from `org-end-of-line' from org.el. +(defun markdown-end-of-line (&optional n) + "Go to the end of the line, but before ellipsis, if any. + +If this is a headline, and `markdown-special-ctrl-a/e' is not nil +or symbol `reversed', ignore closing tags on the first attempt, +and only move to after the closing tags when the cursor is +already beyond the end of the headline. + +If `markdown-special-ctrl-a/e' is symbol `reversed' then ignore +closing tags on the second attempt. + +With argument N not nil or 1, move forward N - 1 lines first." + (interactive "^p") + (let ((origin (point)) + (special (pcase markdown-special-ctrl-a/e + (`(,_ . ,C-e) C-e) (_ markdown-special-ctrl-a/e))) + deactivate-mark) + ;; First move to a visible line. + (if visual-line-mode + (beginning-of-visual-line n) + (move-beginning-of-line n)) + (cond + ;; At a headline, with closing tags. + ((save-excursion + (forward-line 0) + (and (looking-at markdown-regex-header-atx) (match-end 3))) + (let ((refpos (match-end 2)) + (visual-end (and visual-line-mode + (save-excursion + (end-of-visual-line) + (point))))) + ;; If `end-of-visual-line' brings us before end of line or even closing + ;; tags, i.e., the headline spans over multiple visual lines, move + ;; there. + (cond ((and visual-end + (< visual-end refpos) + (<= origin visual-end)) + (goto-char visual-end)) + ((not special) (end-of-line)) + ((eq special 'reversed) + (if (and (= origin (line-end-position)) + (eq this-command last-command)) + (goto-char refpos) + (end-of-line))) + (t + (if (or (< origin refpos) (>= origin (line-end-position))) + (goto-char refpos) + (end-of-line)))) + ;; Prevent automatic cursor movement caused by the command loop. + ;; Enable disable-point-adjustment to avoid unintended cursor repositioning. + (when (and markdown-hide-markup + (equal (get-char-property (point) 'display) "")) + (setq disable-point-adjustment t)))) + (visual-line-mode + (let ((bol (line-beginning-position))) + (end-of-visual-line) + ;; If `end-of-visual-line' gets us past the ellipsis at the + ;; end of a line, backtrack and use `end-of-line' instead. + (when (/= bol (line-beginning-position)) + (goto-char bol) + (end-of-line)))) + (t (end-of-line))))) + (defun markdown-beginning-of-defun (&optional arg) "`beginning-of-defun-function' for Markdown. This is used to find the beginning of the defun and should behave @@ -7445,12 +7705,14 @@ Return the name of the output buffer used." Insert the output in the buffer named OUTPUT-BUFFER-NAME." (interactive) (setq output-buffer-name (markdown output-buffer-name)) - (with-current-buffer output-buffer-name - (set-buffer output-buffer-name) - (unless (markdown-output-standalone-p) - (markdown-add-xhtml-header-and-footer output-buffer-name)) - (goto-char (point-min)) - (html-mode)) + (let ((css-path markdown-css-paths)) + (with-current-buffer output-buffer-name + (set-buffer output-buffer-name) + (setq-local markdown-css-paths css-path) + (unless (markdown-output-standalone-p) + (markdown-add-xhtml-header-and-footer output-buffer-name)) + (goto-char (point-min)) + (html-mode))) output-buffer-name) (defun markdown-other-window (&optional output-buffer-name) @@ -7475,9 +7737,7 @@ Standalone XHTML output is identified by an occurrence of (defun markdown-stylesheet-link-string (stylesheet-path) (concat "")) (defun markdown-escape-title (title) @@ -7840,10 +8100,14 @@ Value is a list of elements describing the link: (let* ((close-pos (scan-sexps (match-beginning 5) 1)) (destination-part (string-trim (buffer-substring-no-properties (1+ (match-beginning 5)) (1- close-pos))))) (setq end close-pos) - (if (string-match "\\([^ ]+\\)\\s-+\\(.+\\)" destination-part) - (setq url (match-string-no-properties 1 destination-part) - title (substring (match-string-no-properties 2 destination-part) 1 -1)) - (setq url destination-part)))) + ;; A link can contain spaces if it is wrapped with angle brackets + (cond ((string-match "\\`<\\(.+\\)>\\'" destination-part) + (setq url (match-string-no-properties 1 destination-part))) + ((string-match "\\([^ ]+\\)\\s-+\\(.+\\)" destination-part) + (setq url (match-string-no-properties 1 destination-part) + title (substring (match-string-no-properties 2 destination-part) 1 -1))) + (t (setq url destination-part))) + (setq url (url-unhex-string url)))) ;; Reference link at point. ((thing-at-point-looking-at markdown-regex-link-reference) (setq bang (match-string-no-properties 1) @@ -7899,11 +8163,11 @@ If the link is a complete URL, open in browser with `browse-url'. Otherwise, open with `find-file' after stripping anchor and/or query string. Translate filenames using `markdown-filename-translate-function'." (interactive (list last-command-event)) - (save-excursion - (if event (posn-set-point (event-start event))) - (if (markdown-link-p) - (markdown--browse-url (markdown-link-url)) - (user-error "Point is not at a Markdown link or URL")))) + (if event (posn-set-point (event-start event))) + (if (markdown-link-p) + (or (run-hook-with-args-until-success 'markdown-follow-link-functions (markdown-link-url)) + (markdown--browse-url (markdown-link-url))) + (user-error "Point is not at a Markdown link or URL"))) (defun markdown-fontify-inline-links (last) "Add text properties to next inline link from point to LAST." @@ -8035,9 +8299,8 @@ and disable it otherwise." (if (eq arg 'toggle) (not markdown-hide-urls) (> (prefix-numeric-value arg) 0))) - (if markdown-hide-urls - (message "markdown-mode URL hiding enabled") - (message "markdown-mode URL hiding disabled")) + (when (called-interactively-p 'interactive) + (message "markdown-mode URL hiding %s" (if markdown-hide-urls "enabled" "disabled"))) (markdown-reload-extensions)) @@ -8273,9 +8536,8 @@ and disable it otherwise." (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")) + (when (called-interactively-p 'interactive) + (message "markdown-mode wiki link support %s" (if markdown-enable-wiki-links "enabled" "disabled"))) (markdown-reload-extensions)) (defun markdown-setup-wiki-link-hooks () @@ -8313,7 +8575,7 @@ See `markdown-follow-link-at-point' and `markdown-follow-wiki-link-at-point'." (interactive "P") (cond ((markdown-link-p) - (markdown--browse-url (markdown-link-url))) + (markdown-follow-link-at-point)) ((markdown-wiki-link-p) (markdown-follow-wiki-link-at-point arg)) (t @@ -8528,13 +8790,12 @@ if ARG is omitted or nil." (not markdown-enable-math) (> (prefix-numeric-value arg) 0))) (if markdown-enable-math - (progn - (font-lock-add-keywords - 'markdown-mode markdown-mode-font-lock-keywords-math) - (message "markdown-mode math support enabled")) + (font-lock-add-keywords + 'markdown-mode markdown-mode-font-lock-keywords-math) (font-lock-remove-keywords - 'markdown-mode markdown-mode-font-lock-keywords-math) - (message "markdown-mode math support disabled")) + 'markdown-mode markdown-mode-font-lock-keywords-math)) + (when (called-interactively-p 'interactive) + (message "markdown-mode math support %s" (if markdown-enable-math "enabled" "disabled"))) (markdown-reload-extensions)) @@ -8785,9 +9046,9 @@ and disable otherwise." (if (eq arg 'toggle) (not markdown-fontify-code-blocks-natively) (> (prefix-numeric-value arg) 0))) - (if markdown-fontify-code-blocks-natively - (message "markdown-mode native code block fontification enabled") - (message "markdown-mode native code block fontification disabled")) + (when (called-interactively-p 'interactive) + (message "markdown-mode native code block fontification %s" + (if markdown-fontify-code-blocks-natively "enabled" "disabled"))) (markdown-reload-extensions)) ;; This is based on `org-src-lang-modes' from org-src.el @@ -8829,10 +9090,16 @@ LANG is a string, and the returned major mode is a symbol." (defun markdown--lang-mode-predicate (mode) (and mode (fboundp mode) - ;; https://github.com/jrblevin/markdown-mode/issues/761 - (cl-loop for pair in auto-mode-alist - for func = (cdr pair) - thereis (and (atom func) (eq mode func))))) + (or + ;; https://github.com/jrblevin/markdown-mode/issues/787 + ;; major-mode-remap-alist was introduced at Emacs 29.1 + (cl-loop for pair in (bound-and-true-p major-mode-remap-alist) + for func = (cdr pair) + thereis (and (atom func) (eq mode func))) + ;; https://github.com/jrblevin/markdown-mode/issues/761 + (cl-loop for pair in auto-mode-alist + for func = (cdr pair) + thereis (and (atom func) (eq mode func)))))) (defun markdown-fontify-code-blocks-generic (matcher last) "Add text properties to next code block from point to LAST. @@ -8885,7 +9152,7 @@ position." (remove-text-properties start end '(face nil)) (with-current-buffer (get-buffer-create - (concat " markdown-code-fontification:" (symbol-name lang-mode))) + (format " *markdown-code-fontification:%s*" (symbol-name lang-mode))) ;; Make sure that modification hooks are not inhibited in ;; the org-src-fontification buffer in case we're called ;; from `jit-lock-function' (Bug#25132). @@ -9256,16 +9523,17 @@ This function assumes point is on a table." (goto-char (point-min)) (let ((cur (point)) ret) - (while (re-search-forward "\\s-*\\(|\\)\\s-*" nil t) - (if (markdown--first-column-p (match-beginning 1)) - (setq cur (match-end 0)) - (cond ((eql (char-before (match-beginning 1)) ?\\) - ;; keep spaces - (goto-char (match-end 1))) - ((markdown--thing-at-wiki-link (match-beginning 1))) ;; do nothing - (t - (push (buffer-substring-no-properties cur (match-beginning 0)) ret) - (setq cur (match-end 0)))))) + (while (and (re-search-forward "\\s-*\\(|\\)\\s-*" nil t)) + (when (not (markdown--face-p (match-beginning 1) '(markdown-inline-code-face))) + (if (markdown--first-column-p (match-beginning 1)) + (setq cur (match-end 0)) + (cond ((eql (char-before (match-beginning 1)) ?\\) + ;; keep spaces + (goto-char (match-end 1))) + ((markdown--thing-at-wiki-link (match-beginning 1))) ;; do nothing + (t + (push (buffer-substring-no-properties cur (match-beginning 0)) ret) + (setq cur (match-end 0))))))) (when (< cur (length line)) (push (buffer-substring-no-properties cur (point-max)) ret)) (nreverse ret)))) @@ -9799,6 +10067,48 @@ rows and columns and the column alignment." (markdown--substitute-command-keys "\\[markdown-toggle-markup-hiding]")))))) +(defun markdown--image-media-handler (mimetype data) + (let* ((ext (symbol-name (mailcap-mime-type-to-extension mimetype))) + (filename (read-string "Insert filename for image: ")) + (link-text (read-string "Link text: ")) + (filepath (file-name-with-extension filename ext)) + (dir (file-name-directory filepath))) + (when (and dir (not (file-directory-p dir))) + (make-directory dir t)) + (with-temp-file filepath + (insert data)) + (when (string-match-p "\\s-" filepath) + (setq filepath (concat "<" filepath ">"))) + (markdown-insert-inline-image link-text filepath))) + +(defun markdown--file-media-handler (_mimetype data) + (let* ((data (split-string data "[\0\r\n]" t "^file://")) + (files (cdr data))) + (while (not (null files)) + (let* ((file (url-unhex-string (car files))) + (file (file-relative-name file)) + (prompt (format "Link text(%s): " (file-name-nondirectory file))) + (link-text (read-string prompt))) + (when (string-match-p "\\s-" file) + (setq file (concat "<" file ">"))) + (markdown-insert-inline-image link-text file) + (when (not (null (cdr files))) + (insert " ")) + (setq files (cdr files)))))) + +(defun markdown--dnd-local-file-handler (url _action) + (require 'mailcap) + (require 'dnd) + (let* ((filename (dnd-get-local-file-name url)) + (mimetype (mailcap-file-name-to-mime-type filename)) + (file (file-relative-name filename)) + (link-text "link text")) + (when (string-match-p "\\s-" file) + (setq file (concat "<" file ">"))) + (if (string-prefix-p "image/" mimetype) + (markdown-insert-inline-image link-text file) + (markdown-insert-inline-link link-text file)))) + ;;; Mode Definition ========================================================== @@ -9927,6 +10237,16 @@ rows and columns and the column alignment." (add-hook 'electric-quote-inhibit-functions #'markdown--inhibit-electric-quote nil :local) + ;; drag and drop handler + (setq-local dnd-protocol-alist (cons '("^file:///" . markdown--dnd-local-file-handler) + dnd-protocol-alist)) + + ;; media handler + (when (version< "29" emacs-version) + (yank-media-handler "image/.*" #'markdown--image-media-handler) + ;; TODO support other than GNOME, like KDE etc + (yank-media-handler "x-special/gnome-copied-files" #'markdown--file-media-handler)) + ;; Make checkboxes buttons (when markdown-make-gfm-checkboxes-buttons (markdown-make-gfm-checkboxes-buttons (point-min) (point-max)) @@ -9945,7 +10265,18 @@ rows and columns and the column alignment." ;; 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)) + (add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t) + + ;; Add a custom keymap for `visual-line-mode' so that activating + ;; this minor mode does not override markdown-mode's keybindings. + ;; FIXME: Probably `visual-line-mode' should take care of this. + (let ((oldmap (cdr (assoc 'visual-line-mode minor-mode-map-alist))) + (newmap (make-sparse-keymap))) + (set-keymap-parent newmap oldmap) + (define-key newmap [remap move-beginning-of-line] nil) + (define-key newmap [remap move-end-of-line] nil) + (make-local-variable 'minor-mode-overriding-map-alist) + (push `(visual-line-mode . ,newmap) minor-mode-overriding-map-alist))) ;;;###autoload (add-to-list 'auto-mode-alist @@ -9974,6 +10305,11 @@ rows and columns and the column alignment." (setq markdown-link-space-sub-char "-") (setq markdown-wiki-link-search-subdirectories t) (setq-local markdown-table-at-point-p-function #'gfm--table-at-point-p) + (setq-local paragraph-separate + (concat paragraph-separate + "\\|" + ;; GFM alert syntax + "^>\s-*\\[!\\(?:NOTE\\|TIP\\|IMPORTANT\\|WARNING\\|CAUTION\\)\\]")) (add-hook 'post-self-insert-hook #'gfm--electric-pair-fence-code-block 'append t) (markdown-gfm-parse-buffer-for-languages)) diff --git a/elpa/markdown-mode-readme.txt b/elpa/markdown-mode-readme.txt deleted file mode 100644 index 378a0562..00000000 --- a/elpa/markdown-mode-readme.txt +++ /dev/null @@ -1 +0,0 @@ -See the README.md file for details. -- 2.47.3