
Merge index entries that have the same key and use cleveref to render the page-number sequence.
63 lines
2.2 KiB
Racket
63 lines
2.2 KiB
Racket
#lang racket/base
|
|
(require "../core.rkt"
|
|
"../html-properties.rkt")
|
|
|
|
(provide same-index-entry?
|
|
extract-index-link-targets)
|
|
|
|
(define (same-index-entry? a-blocks b-blocks)
|
|
(and (= (length a-blocks) (length b-blocks))
|
|
;; We expect an index entry to have a single paragraph, but
|
|
;; allow a list:
|
|
(for/and ([a (in-list a-blocks)]
|
|
[b (in-list b-blocks)])
|
|
(and (paragraph? a)
|
|
(paragraph? b)
|
|
;; Compare paragraph content, paying attention to style,
|
|
;; but not paying attention to link targets:
|
|
(let loop ([a (paragraph-content a)]
|
|
[b (paragraph-content b)])
|
|
(cond
|
|
[(equal? a b) #t]
|
|
[(alpha-anchor-content a) => (lambda (a) (loop a b))]
|
|
[(alpha-anchor-content b) => (lambda (b) (loop a b))]
|
|
[(and (pair? a) (pair? b))
|
|
(and (loop (car a) (car b))
|
|
(loop (cdr a) (cdr b)))]
|
|
[(and (element? a)
|
|
(element? b))
|
|
(and (equal? (element-content a)
|
|
(element-content b))
|
|
(equal? (element-style a)
|
|
(element-style b)))]
|
|
[else #f]))))))
|
|
|
|
(define (alpha-anchor-content e)
|
|
(and (element? e)
|
|
(let ([s (element-style e)])
|
|
(and s
|
|
(style? s)
|
|
(not (style-name s))
|
|
(= 1 (length (style-properties s)))
|
|
(url-anchor? (car (style-properties s)))))
|
|
(let ([c (element-content e)])
|
|
(cond
|
|
[(and (pair? c) (null? (cdr c))) (car c)]
|
|
[else c]))))
|
|
|
|
(define (extract-index-link-targets blockss)
|
|
(apply
|
|
append
|
|
(for*/list ([blocks (in-list blockss)]
|
|
[b (in-list blocks)])
|
|
(cond
|
|
[(paragraph? b)
|
|
(let content-loop ([c (paragraph-content b)])
|
|
(cond
|
|
[(null? c) null]
|
|
[(pair? c) (append (content-loop (car c))
|
|
(content-loop (cdr c)))]
|
|
[(link-element? c) (list c)]
|
|
[else null]))]
|
|
[else null]))))
|