diff options
| author | Simeon Simeonov | 2021-01-12 20:11:30 +0100 |
|---|---|---|
| committer | Simeon Simeonov | 2021-01-12 20:11:30 +0100 |
| commit | 97d084eb0846f3c2edbb199fed7226370471cd5a (patch) | |
| tree | ef941986ce4f9037cf527a1164e0e54140726402 | |
| parent | 4996a6403108a226d4ff1d73b880207cc80284bd (diff) | |
Update markdown-mode
| -rw-r--r-- | .emacs.d/lisp/markdown-mode.el | 198 |
1 files changed, 111 insertions, 87 deletions
diff --git a/.emacs.d/lisp/markdown-mode.el b/.emacs.d/lisp/markdown-mode.el index 2e47247..542de4e 100644 --- a/.emacs.d/lisp/markdown-mode.el +++ b/.emacs.d/lisp/markdown-mode.el | |||
| @@ -116,7 +116,8 @@ arguments." | |||
| 116 | :type '(choice file function (const :tag "None" nil))) | 116 | :type '(choice file function (const :tag "None" nil))) |
| 117 | 117 | ||
| 118 | (defcustom markdown-open-image-command nil | 118 | (defcustom markdown-open-image-command nil |
| 119 | "Command used for opening image files directly at `markdown-follow-link-at-point'." | 119 | "Command used for opening image files directly. |
| 120 | This is used at `markdown-follow-link-at-point'." | ||
| 120 | :group 'markdown | 121 | :group 'markdown |
| 121 | :type '(choice file function (const :tag "None" nil))) | 122 | :type '(choice file function (const :tag "None" nil))) |
| 122 | 123 | ||
| @@ -1667,7 +1668,7 @@ region of a YAML metadata block as propertized by | |||
| 1667 | markdown--syntax-properties) | 1668 | markdown--syntax-properties) |
| 1668 | (put-text-property comment-begin comment-end | 1669 | (put-text-property comment-begin comment-end |
| 1669 | 'markdown-comment (list comment-begin comment-end)) | 1670 | 'markdown-comment (list comment-begin comment-end)) |
| 1670 | (goto-char (min (1+ comment-end) end (point-max))))) | 1671 | (goto-char (min comment-end end (point-max))))) |
| 1671 | ;; Nothing found | 1672 | ;; Nothing found |
| 1672 | (t (setq finish t))))) | 1673 | (t (setq finish t))))) |
| 1673 | nil)) | 1674 | nil)) |
| @@ -2140,7 +2141,7 @@ Depending on your font, some reasonable choices are: | |||
| 2140 | 2141 | ||
| 2141 | (defconst markdown-footnote-chars | 2142 | (defconst markdown-footnote-chars |
| 2142 | "[[:alnum:]-]" | 2143 | "[[:alnum:]-]" |
| 2143 | "Regular expression matching any character that is allowed in a footnote identifier.") | 2144 | "Regular expression matching any character for a footnote identifier.") |
| 2144 | 2145 | ||
| 2145 | (defconst markdown-regex-footnote-definition | 2146 | (defconst markdown-regex-footnote-definition |
| 2146 | (concat "^ \\{0,3\\}\\[\\(\\^" markdown-footnote-chars "*?\\)\\]:\\(?:[ \t]+\\|$\\)") | 2147 | (concat "^ \\{0,3\\}\\[\\(\\^" markdown-footnote-chars "*?\\)\\]:\\(?:[ \t]+\\|$\\)") |
| @@ -4301,6 +4302,11 @@ opening code fence and an info string." | |||
| 4301 | :safe #'natnump | 4302 | :safe #'natnump |
| 4302 | :package-version '(markdown-mode . "2.3")) | 4303 | :package-version '(markdown-mode . "2.3")) |
| 4303 | 4304 | ||
| 4305 | (defcustom markdown-code-block-braces nil | ||
| 4306 | "When non-nil, automatically insert braces for GFM code blocks." | ||
| 4307 | :group 'markdown | ||
| 4308 | :type 'boolean) | ||
| 4309 | |||
| 4304 | (defun markdown-insert-gfm-code-block (&optional lang edit) | 4310 | (defun markdown-insert-gfm-code-block (&optional lang edit) |
| 4305 | "Insert GFM code block for language LANG. | 4311 | "Insert GFM code block for language LANG. |
| 4306 | If LANG is nil, the language will be queried from user. If a | 4312 | If LANG is nil, the language will be queried from user. If a |
| @@ -4321,45 +4327,49 @@ code block in an indirect buffer after insertion." | |||
| 4321 | (quit ""))) | 4327 | (quit ""))) |
| 4322 | current-prefix-arg)) | 4328 | current-prefix-arg)) |
| 4323 | (unless (string= lang "") (markdown-gfm-add-used-language lang)) | 4329 | (unless (string= lang "") (markdown-gfm-add-used-language lang)) |
| 4324 | (when (> (length lang) 0) | 4330 | (when (and (> (length lang) 0) |
| 4331 | (not markdown-code-block-braces)) | ||
| 4325 | (setq lang (concat (make-string markdown-spaces-after-code-fence ?\s) | 4332 | (setq lang (concat (make-string markdown-spaces-after-code-fence ?\s) |
| 4326 | lang))) | 4333 | lang))) |
| 4327 | (if (use-region-p) | 4334 | (let ((gfm-open-brace (if markdown-code-block-braces "{" "")) |
| 4328 | (let* ((b (region-beginning)) (e (region-end)) end | 4335 | (gfm-close-brace (if markdown-code-block-braces "}" ""))) |
| 4329 | (indent (progn (goto-char b) (current-indentation)))) | 4336 | (if (use-region-p) |
| 4330 | (goto-char e) | 4337 | (let* ((b (region-beginning)) (e (region-end)) end |
| 4331 | ;; if we're on a blank line, don't newline, otherwise the ``` | 4338 | (indent (progn (goto-char b) (current-indentation)))) |
| 4332 | ;; should go on its own line | 4339 | (goto-char e) |
| 4333 | (unless (looking-back "\n" nil) | 4340 | ;; if we're on a blank line, don't newline, otherwise the ``` |
| 4334 | (newline)) | 4341 | ;; should go on its own line |
| 4342 | (unless (looking-back "\n" nil) | ||
| 4343 | (newline)) | ||
| 4344 | (indent-to indent) | ||
| 4345 | (insert "```") | ||
| 4346 | (markdown-ensure-blank-line-after) | ||
| 4347 | (setq end (point)) | ||
| 4348 | (goto-char b) | ||
| 4349 | ;; if we're on a blank line, insert the quotes here, otherwise | ||
| 4350 | ;; add a new line first | ||
| 4351 | (unless (looking-at-p "\n") | ||
| 4352 | (newline) | ||
| 4353 | (forward-line -1)) | ||
| 4354 | (markdown-ensure-blank-line-before) | ||
| 4355 | (indent-to indent) | ||
| 4356 | (insert "```" gfm-open-brace lang gfm-close-brace) | ||
| 4357 | (markdown-syntax-propertize-fenced-block-constructs (point-at-bol) end)) | ||
| 4358 | (let ((indent (current-indentation)) | ||
| 4359 | start-bol) | ||
| 4360 | (delete-horizontal-space :backward-only) | ||
| 4361 | (markdown-ensure-blank-line-before) | ||
| 4362 | (indent-to indent) | ||
| 4363 | (setq start-bol (point-at-bol)) | ||
| 4364 | (insert "```" gfm-open-brace lang gfm-close-brace "\n") | ||
| 4365 | (indent-to indent) | ||
| 4366 | (unless edit (insert ?\n)) | ||
| 4335 | (indent-to indent) | 4367 | (indent-to indent) |
| 4336 | (insert "```") | 4368 | (insert "```") |
| 4337 | (markdown-ensure-blank-line-after) | 4369 | (markdown-ensure-blank-line-after) |
| 4338 | (setq end (point)) | 4370 | (markdown-syntax-propertize-fenced-block-constructs start-bol (point))) |
| 4339 | (goto-char b) | 4371 | (end-of-line 0) |
| 4340 | ;; if we're on a blank line, insert the quotes here, otherwise | 4372 | (when edit (markdown-edit-code-block))))) |
| 4341 | ;; add a new line first | ||
| 4342 | (unless (looking-at-p "\n") | ||
| 4343 | (newline) | ||
| 4344 | (forward-line -1)) | ||
| 4345 | (markdown-ensure-blank-line-before) | ||
| 4346 | (indent-to indent) | ||
| 4347 | (insert "```" lang) | ||
| 4348 | (markdown-syntax-propertize-fenced-block-constructs (point-at-bol) end)) | ||
| 4349 | (let ((indent (current-indentation)) start-bol) | ||
| 4350 | (delete-horizontal-space :backward-only) | ||
| 4351 | (markdown-ensure-blank-line-before) | ||
| 4352 | (indent-to indent) | ||
| 4353 | (setq start-bol (point-at-bol)) | ||
| 4354 | (insert "```" lang "\n") | ||
| 4355 | (indent-to indent) | ||
| 4356 | (unless edit (insert ?\n)) | ||
| 4357 | (indent-to indent) | ||
| 4358 | (insert "```") | ||
| 4359 | (markdown-ensure-blank-line-after) | ||
| 4360 | (markdown-syntax-propertize-fenced-block-constructs start-bol (point))) | ||
| 4361 | (end-of-line 0) | ||
| 4362 | (when edit (markdown-edit-code-block)))) | ||
| 4363 | 4373 | ||
| 4364 | (defun markdown-code-block-lang (&optional pos-prop) | 4374 | (defun markdown-code-block-lang (&optional pos-prop) |
| 4365 | "Return the language name for a GFM or tilde fenced code block. | 4375 | "Return the language name for a GFM or tilde fenced code block. |
| @@ -5533,52 +5543,61 @@ See also `markdown-mode-map'.") | |||
| 5533 | "Create and return a nested imenu index alist for the current buffer. | 5543 | "Create and return a nested imenu index alist for the current buffer. |
| 5534 | See `imenu-create-index-function' and `imenu--index-alist' for details." | 5544 | See `imenu-create-index-function' and `imenu--index-alist' for details." |
| 5535 | (let* ((root '(nil . nil)) | 5545 | (let* ((root '(nil . nil)) |
| 5536 | cur-alist | 5546 | (min-level 9999) |
| 5537 | (cur-level 0) | 5547 | hashes headers) |
| 5538 | (empty-heading "-") | ||
| 5539 | (self-heading ".") | ||
| 5540 | hashes pos level heading) | ||
| 5541 | (save-excursion | 5548 | (save-excursion |
| 5542 | ;; Headings | 5549 | ;; Headings |
| 5543 | (goto-char (point-min)) | 5550 | (goto-char (point-min)) |
| 5544 | (while (re-search-forward markdown-regex-header (point-max) t) | 5551 | (while (re-search-forward markdown-regex-header (point-max) t) |
| 5545 | (unless (markdown-code-block-at-point-p) | 5552 | (unless (or (markdown-code-block-at-point-p) |
| 5553 | (and (match-beginning 3) | ||
| 5554 | (get-text-property (match-beginning 3) 'markdown-yaml-metadata-end))) | ||
| 5546 | (cond | 5555 | (cond |
| 5547 | ((match-string-no-properties 2) ;; level 1 setext | 5556 | ((match-string-no-properties 2) ;; level 1 setext |
| 5548 | (setq heading (match-string-no-properties 1)) | 5557 | (setq min-level 1) |
| 5549 | (setq pos (match-beginning 1) | 5558 | (push (list :heading (match-string-no-properties 1) |
| 5550 | level 1)) | 5559 | :point (match-beginning 1) |
| 5560 | :level 1) headers)) | ||
| 5551 | ((match-string-no-properties 3) ;; level 2 setext | 5561 | ((match-string-no-properties 3) ;; level 2 setext |
| 5552 | (setq heading (match-string-no-properties 1)) | 5562 | (setq min-level (min min-level 2)) |
| 5553 | (setq pos (match-beginning 1) | 5563 | (push (list :heading (match-string-no-properties 1) |
| 5554 | level 2)) | 5564 | :point (match-beginning 1) |
| 5565 | :level (- 2 (1- min-level))) headers)) | ||
| 5555 | ((setq hashes (markdown-trim-whitespace | 5566 | ((setq hashes (markdown-trim-whitespace |
| 5556 | (match-string-no-properties 4))) | 5567 | (match-string-no-properties 4))) |
| 5557 | (setq heading (match-string-no-properties 5) | 5568 | (setq min-level (min min-level (length hashes))) |
| 5558 | pos (match-beginning 4) | 5569 | (push (list :heading (match-string-no-properties 5) |
| 5559 | level (length hashes)))) | 5570 | :point (match-beginning 4) |
| 5560 | (let ((alist (list (cons heading pos)))) | 5571 | :level (- (length hashes) (1- min-level))) headers))))) |
| 5561 | (cond | 5572 | (cl-loop with cur-level = 0 |
| 5562 | ((= cur-level level) ; new sibling | 5573 | with cur-alist = nil |
| 5563 | (setcdr cur-alist alist) | 5574 | with empty-heading = "-" |
| 5564 | (setq cur-alist alist)) | 5575 | with self-heading = "." |
| 5565 | ((< cur-level level) ; first child | 5576 | for header in (reverse headers) |
| 5566 | (dotimes (_ (- level cur-level 1)) | 5577 | for level = (plist-get header :level) |
| 5567 | (setq alist (list (cons empty-heading alist)))) | 5578 | do |
| 5568 | (if cur-alist | 5579 | (let ((alist (list (cons (plist-get header :heading) (plist-get header :point))))) |
| 5569 | (let* ((parent (car cur-alist)) | 5580 | (cond |
| 5570 | (self-pos (cdr parent))) | 5581 | ((= cur-level level) ; new sibling |
| 5571 | (setcdr parent (cons (cons self-heading self-pos) alist))) | 5582 | (setcdr cur-alist alist) |
| 5572 | (setcdr root alist)) ; primogenitor | 5583 | (setq cur-alist alist)) |
| 5573 | (setq cur-alist alist) | 5584 | ((< cur-level level) ; first child |
| 5574 | (setq cur-level level)) | 5585 | (dotimes (_ (- level cur-level 1)) |
| 5575 | (t ; new sibling of an ancestor | 5586 | (setq alist (list (cons empty-heading alist)))) |
| 5576 | (let ((sibling-alist (last (cdr root)))) | 5587 | (if cur-alist |
| 5577 | (dotimes (_ (1- level)) | 5588 | (let* ((parent (car cur-alist)) |
| 5578 | (setq sibling-alist (last (cdar sibling-alist)))) | 5589 | (self-pos (cdr parent))) |
| 5579 | (setcdr sibling-alist alist) | 5590 | (setcdr parent (cons (cons self-heading self-pos) alist))) |
| 5580 | (setq cur-alist alist)) | 5591 | (setcdr root alist)) ; primogenitor |
| 5581 | (setq cur-level level)))))) | 5592 | (setq cur-alist alist) |
| 5593 | (setq cur-level level)) | ||
| 5594 | (t ; new sibling of an ancestor | ||
| 5595 | (let ((sibling-alist (last (cdr root)))) | ||
| 5596 | (dotimes (_ (1- level)) | ||
| 5597 | (setq sibling-alist (last (cdar sibling-alist)))) | ||
| 5598 | (setcdr sibling-alist alist) | ||
| 5599 | (setq cur-alist alist)) | ||
| 5600 | (setq cur-level level))))) | ||
| 5582 | ;; Footnotes | 5601 | ;; Footnotes |
| 5583 | (let ((fn (markdown-get-defined-footnotes))) | 5602 | (let ((fn (markdown-get-defined-footnotes))) |
| 5584 | (if (or (zerop (length fn)) | 5603 | (if (or (zerop (length fn)) |
| @@ -8398,13 +8417,14 @@ or \\[markdown-toggle-inline-images]." | |||
| 8398 | (widen) | 8417 | (widen) |
| 8399 | (goto-char (point-min)) | 8418 | (goto-char (point-min)) |
| 8400 | (while (re-search-forward markdown-regex-link-inline nil t) | 8419 | (while (re-search-forward markdown-regex-link-inline nil t) |
| 8401 | (let ((start (match-beginning 0)) | 8420 | (let* ((start (match-beginning 0)) |
| 8402 | (imagep (match-beginning 1)) | 8421 | (imagep (match-beginning 1)) |
| 8403 | (end (match-end 0)) | 8422 | (end (match-end 0)) |
| 8404 | (file (match-string-no-properties 6))) | 8423 | (file (match-string-no-properties 6)) |
| 8424 | (unhex_file (url-unhex-string file))) | ||
| 8405 | (when (and imagep | 8425 | (when (and imagep |
| 8406 | (not (zerop (length file)))) | 8426 | (not (zerop (length file)))) |
| 8407 | (unless (file-exists-p file) | 8427 | (unless (file-exists-p unhex_file) |
| 8408 | (let* ((download-file (funcall markdown-translate-filename-function file)) | 8428 | (let* ((download-file (funcall markdown-translate-filename-function file)) |
| 8409 | (valid-url (ignore-errors | 8429 | (valid-url (ignore-errors |
| 8410 | (member (downcase (url-type (url-generic-parse-url download-file))) | 8430 | (member (downcase (url-type (url-generic-parse-url download-file))) |
| @@ -8414,18 +8434,22 @@ or \\[markdown-toggle-inline-images]." | |||
| 8414 | (when (not valid-url) | 8434 | (when (not valid-url) |
| 8415 | ;; strip query parameter | 8435 | ;; strip query parameter |
| 8416 | (setq file (replace-regexp-in-string "?.+\\'" "" file)))))) | 8436 | (setq file (replace-regexp-in-string "?.+\\'" "" file)))))) |
| 8417 | (when (file-exists-p file) | 8437 | (when (file-exists-p unhex_file) |
| 8418 | (let* ((abspath (if (file-name-absolute-p file) | 8438 | (let* ((abspath (if (file-name-absolute-p unhex_file) |
| 8419 | file | 8439 | unhex_file |
| 8420 | (concat default-directory file))) | 8440 | (concat default-directory unhex_file))) |
| 8421 | (image | 8441 | (image |
| 8422 | (if (and markdown-max-image-size | 8442 | (cond ((and markdown-max-image-size |
| 8423 | (image-type-available-p 'imagemagick)) | 8443 | (image-type-available-p 'imagemagick)) |
| 8424 | (create-image | 8444 | (create-image |
| 8425 | abspath 'imagemagick nil | 8445 | abspath 'imagemagick nil |
| 8426 | :max-width (car markdown-max-image-size) | 8446 | :max-width (car markdown-max-image-size) |
| 8427 | :max-height (cdr markdown-max-image-size)) | 8447 | :max-height (cdr markdown-max-image-size))) |
| 8428 | (create-image abspath)))) | 8448 | (markdown-max-image-size |
| 8449 | (create-image abspath nil nil | ||
| 8450 | :max-width (car markdown-max-image-size) | ||
| 8451 | :max-height (cdr markdown-max-image-size))) | ||
| 8452 | (t (create-image abspath))))) | ||
| 8429 | (when image | 8453 | (when image |
| 8430 | (let ((ov (make-overlay start end))) | 8454 | (let ((ov (make-overlay start end))) |
| 8431 | (overlay-put ov 'display image) | 8455 | (overlay-put ov 'display image) |
