Function: markdown-match-generic-links

markdown-match-generic-links is a byte-compiled function defined in markdown-mode.el.

Signature

(markdown-match-generic-links LAST REF)

Documentation

Match inline links from point to LAST.

When REF is non-nil, match reference links instead of standard links with URLs. This function should only be used during font-lock, as it determines syntax based on the presence of faces for previously processed elements.

Source Code

;; Defined in ~/.emacs.d/elpa/markdown-mode-20260321.143/markdown-mode.el
(defun markdown-match-generic-links (last ref)
  "Match inline links from point to LAST.
When REF is non-nil, match reference links instead of standard
links with URLs.
This function should only be used during font-lock, as it
determines syntax based on the presence of faces for previously
processed elements."
  ;; Search for the next potential link (not in a code block).
  (let ((prohibited-faces '(markdown-pre-face
                            markdown-code-face
                            markdown-inline-code-face
                            markdown-comment-face))
        found)
    (while
        (and (not found) (< (point) last)
             (progn
               ;; Clear match data to test for a match after functions returns.
               (set-match-data nil)
               ;; Preliminary regular expression search so we can return
               ;; quickly upon failure.  This doesn't handle malformed links
               ;; or nested square brackets well, so if it passes we back up
               ;; continue with a more precise search.
               (re-search-forward
                (if ref
                    markdown-regex-link-reference
                  markdown-regex-link-inline)
                last 'limit)))
      ;; Keep searching if this is in a code block, inline code, or a
      ;; comment, or if it is include syntax. The link text portion
      ;; (group 3) may contain inline code or comments, but the
      ;; markup, URL, and title should not be part of such elements.
      (if (or (markdown-range-property-any
               (match-beginning 0) (match-end 2) 'face prohibited-faces)
              (markdown-range-property-any
               (match-beginning 4) (match-end 0) 'face prohibited-faces)
              (and (char-equal (char-after (line-beginning-position)) ?<)
                   (char-equal (char-after (1+ (line-beginning-position))) ?<)))
          (set-match-data nil)
        (setq found t))))
  ;; Match opening exclamation point (optional) and left bracket.
  (when (match-beginning 2)
    (let* ((bang (match-beginning 1))
           (first-begin (match-beginning 2))
           ;; Find end of block to prevent matching across blocks.
           (end-of-block (save-excursion
                           (progn
                             (goto-char (match-beginning 2))
                             (markdown-end-of-text-block)
                             (point))))
           ;; Move over balanced expressions to closing right bracket.
           ;; Catch unbalanced expression errors, then try to search right bracket manually.
           (first-end (condition-case nil
                          (and (goto-char first-begin)
                               (scan-sexps (point) 1))
                        (error
                         (save-match-data
                           (let ((last (match-end 4))
                                 ok end-pos)
                             (while (and (not ok) (search-forward "]" last t))
                               (unless (= (char-before (1- (point))) ?\\)
                                 (setq ok t end-pos (point))))
                             end-pos)))))
           ;; Continue with point at CONT-POINT upon failure.
           (cont-point (min (1+ first-begin) last))
           second-begin second-end url-begin url-end
           title-begin title-end)
      ;; When bracket found, in range, and followed by a left paren/bracket...
      (when (and first-end (< first-end end-of-block) (goto-char first-end)
                 (char-equal (char-after (point)) (if ref ?\[ ?\()))
        ;; Scan across balanced expressions for closing parenthesis/bracket.
        (setq second-begin (point)
              second-end (condition-case nil
                             (scan-sexps (point) 1)
                           (error nil)))
        ;; Check that closing parenthesis/bracket is in range.
        (if (and second-end (<= second-end end-of-block) (<= second-end last))
            (progn
              ;; Search for (optional) title inside closing parenthesis
              (when (and (not ref) (search-forward "\"" second-end t))
                (setq title-begin (1- (point))
                      title-end (and (goto-char second-end)
                                     (search-backward "\"" (1+ title-begin) t))
                      title-end (and title-end (1+ title-end))))
              ;; Store URL/reference range
              (setq url-begin (1+ second-begin)
                    url-end (1- (or title-begin second-end)))
              ;; Set match data, move point beyond link, and return
              (set-match-data
               (list (or bang first-begin) second-end  ; 0 - all
                     bang (and bang (1+ bang))         ; 1 - bang
                     first-begin (1+ first-begin)      ; 2 - markup
                     (1+ first-begin) (1- first-end)   ; 3 - link text
                     (1- first-end) first-end          ; 4 - markup
                     second-begin (1+ second-begin)    ; 5 - markup
                     url-begin url-end                 ; 6 - url/reference
                     title-begin title-end             ; 7 - title
                     (1- second-end) second-end))      ; 8 - markup
              ;; Nullify cont-point and leave point at end and
              (setq cont-point nil)
              (goto-char second-end))
          ;; If no closing parenthesis in range, update continuation point
          (setq cont-point (min end-of-block second-begin))))
      (cond
       ;; On failure, continue searching at cont-point
       ((and cont-point (< cont-point last))
        (goto-char cont-point)
        (markdown-match-generic-links last ref))
       ;; No more text, return nil
       ((and cont-point (= cont-point last))
        nil)
       ;; Return t if a match occurred
       (t t)))))