;; -*- coding: utf-8; lexical-binding: t; -*-
(defunxahhtml-show-duplicate-links ()
"Highlight and print any duplicate links in current html file.
Also, push mark at each of the duplicate link position, so you can `universal-argument' `set-mark-command' to jump to it.
Created: 2024-07-22
Version: 2025-06-03"
(interactive)
(let (xbegxendxlink
(xlinksTable (make-hash-table:test 'equal)))
(seq-setq (xbegxend)
(if (region-active-p)
(vector (region-beginning) (region-end))
(vector (point-min) (point-max))))
(save-restriction
(narrow-to-regionxbegxend)
;; algorithm
;; first, built hashtable.
;; Find each link, then for each, extract the link, if it is local, then expand to file absolute path.
;; this is the key for hashtable.
;; add that to hashtable.
;; if already exist, add to the value of that key.
;; the value of hashtable is a list of vectors [pos-beg pos-end]
;; where the position is the href value
;; now, find the duplicate. algo.
;; go thru hashtable
;; if a value has a list of length more than 1, it means that link is repeated.
;; for each of those, hight them. by the begin end positions in the value.
(save-excursion
(goto-char (point-min))
(while (search-forward"href=\""nilt)
(let (xfpath-begxfpath-endxhrefval)
(let ((xboundary (bounds-of-thing-at-point 'filename)))
(seq-setq (xfpath-begxfpath-end) (list (carxboundary) (cdrxboundary))))
(setqxhrefval (buffer-substring-no-propertiesxfpath-begxfpath-end))
(setqxlink
(if (string-match"\\`http"xhrefval)
xhrefval
(expand-file-namexhrefvaldefault-directory)))
(let ((xresult (gethashxlinkxlinksTable)))
(ifxresult
(progn
(puthashxlink
(cons (vectorxfpath-begxfpath-end) xresult)
xlinksTable))
(progn
(puthashxlink (list (vectorxfpath-begxfpath-end)) xlinksTable)))))))
;; now go thru hashtable
;; if a key's value has length 2 or more
;; highlight it in buffer
(maphash
(lambda (_ xv)
(if (eq (lengthxv) 1)
nil
(let ((xsorted (sortxv:key (lambda (xx) (arefxx 0)))))
;; color first occurances
(let ((xfirst (popxsorted)))
(overlay-put (make-overlay (arefxfirst 0) (arefxfirst 1)) 'face 'hi-yellow))
;; color rest occurances
(mapc
(lambda (x)
(overlay-put (make-overlay (arefx 0) (arefx 1)) 'face 'hi-green))
xsorted))))
xlinksTable)
;; (message "result is [%s]" xlinksTable)
(message"donnnn"))))