Skip to content

Commit

Permalink
Merge pull request #842 from umanwizard/faster-inline-bold
Browse files Browse the repository at this point in the history
Get rid of some quadratic behavior
  • Loading branch information
syohex authored Aug 20, 2024
2 parents 8a7773f + b1acc05 commit 6d1f08b
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 56 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
- Consider `major-mode-remap-alist` to determine major-mode for code blocks [GH-787][]
- Set marker after footnote reference [GH-793][]
- Improve putting text attribute for indented blocks [GH-794][]
- Some sources of pathological behavior of markdown-match-bold and markdown-match-italic
on large blocks have been mitigated

* Bug fixes:
- Don't override table faces by link faces [GH-716][]
Expand Down
143 changes: 87 additions & 56 deletions markdown-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -2789,8 +2789,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
Expand All @@ -2807,7 +2808,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)))
Expand Down Expand Up @@ -2955,66 +2958,94 @@ 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."
(let* ((is-gfm (derived-mode-p 'gfm-mode))
(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
Expand Down

0 comments on commit 6d1f08b

Please sign in to comment.