scribble/book-index: more book-like index style for Latex/PDF
Merge index entries that have the same key and use cleveref to render the page-number sequence.
This commit is contained in:
parent
9f799cd86e
commit
5f29095f02
|
@ -520,6 +520,14 @@ The recognized @tech{style properties} are as follows:
|
||||||
section. See also @racket[link-element] and
|
section. See also @racket[link-element] and
|
||||||
@racket[current-link-render-style].}
|
@racket[current-link-render-style].}
|
||||||
|
|
||||||
|
@item{@racket['enable-index-merge] --- On an index parts or one of
|
||||||
|
its enclosing parts for Latex output, causes index entries to
|
||||||
|
be merged when they have the same content, with multiple
|
||||||
|
references for the same entry combined with @ltx{Smanypageref}.
|
||||||
|
The @ltx{Smanypageref} Latex macro must be redefined to accept
|
||||||
|
multiple @litchar{,}-separated labels and generate a suitable set of
|
||||||
|
references. See also @racketmodname[scriblib/book-index].}
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
The @racket[to-collect] field contains @techlink{content} that is
|
The @racket[to-collect] field contains @techlink{content} that is
|
||||||
|
|
35
scribble-doc/scriblib/scribblings/book-index.scrbl
Normal file
35
scribble-doc/scriblib/scribblings/book-index.scrbl
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#lang scribble/manual
|
||||||
|
@(require (for-label scribble/core
|
||||||
|
racket/base
|
||||||
|
scriblib/book-index))
|
||||||
|
|
||||||
|
@title[#:tag "book-index"]{Book-Style Indexing}
|
||||||
|
|
||||||
|
@defmodule[scriblib/book-index]{Provides a list of style properties to
|
||||||
|
attach to a Scribble document that contains an index part, making the
|
||||||
|
index more suitable for a traditional rendering on paper. The style
|
||||||
|
properties cause index entries to be merged when they have the same
|
||||||
|
content, with (potentially) multiple page numbers attached to the
|
||||||
|
merged entry.}
|
||||||
|
|
||||||
|
@defthing[book-index-style-properties list?]{
|
||||||
|
|
||||||
|
Combine these style properties with others for the style of a part
|
||||||
|
(typically specified in @racket[title]) for a document that contains
|
||||||
|
an index. The style properties enable index merging and select an
|
||||||
|
implementation based on the @tt{cleveref} Latex package.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
@codeblock[#:keep-lang-line? #t]|{
|
||||||
|
#lang scribble/base
|
||||||
|
@(require scriblib/book-index
|
||||||
|
(only-in scribble/core make-style))
|
||||||
|
|
||||||
|
@title[#:style (make-style #f book-index-style-properties)]{Demo}
|
||||||
|
|
||||||
|
This paragraph is about @as-index{examples}.
|
||||||
|
|
||||||
|
This paragraph is about @as-index{examples}, too.
|
||||||
|
|
||||||
|
@index-section[]}|}
|
|
@ -10,3 +10,4 @@
|
||||||
@include-section["bibtex.scrbl"]
|
@include-section["bibtex.scrbl"]
|
||||||
@include-section["footnote.scrbl"]
|
@include-section["footnote.scrbl"]
|
||||||
@include-section["render-cond.scrbl"]
|
@include-section["render-cond.scrbl"]
|
||||||
|
@include-section["book-index.scrbl"]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(require "core.rkt"
|
(require "core.rkt"
|
||||||
"latex-properties.rkt"
|
"latex-properties.rkt"
|
||||||
"private/render-utils.rkt"
|
"private/render-utils.rkt"
|
||||||
|
"private/latex-index.rkt"
|
||||||
racket/class
|
racket/class
|
||||||
racket/runtime-path
|
racket/runtime-path
|
||||||
racket/port
|
racket/port
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
(define rendering-tt (make-parameter #f))
|
(define rendering-tt (make-parameter #f))
|
||||||
(define show-link-page-numbers (make-parameter #f))
|
(define show-link-page-numbers (make-parameter #f))
|
||||||
(define done-link-page-numbers (make-parameter #f))
|
(define done-link-page-numbers (make-parameter #f))
|
||||||
|
(define multiple-page-references (make-parameter #f))
|
||||||
(define disable-images (make-parameter #f))
|
(define disable-images (make-parameter #f))
|
||||||
(define escape-brackets (make-parameter #f))
|
(define escape-brackets (make-parameter #f))
|
||||||
(define suppress-newline-content (make-parameter #f))
|
(define suppress-newline-content (make-parameter #f))
|
||||||
|
@ -587,10 +589,19 @@
|
||||||
(when (and (link-element? e)
|
(when (and (link-element? e)
|
||||||
(show-link-page-numbers)
|
(show-link-page-numbers)
|
||||||
(not (done-link-page-numbers)))
|
(not (done-link-page-numbers)))
|
||||||
(printf ", \\pageref{t:~a}"
|
(define (make-ref e)
|
||||||
(t-encode
|
(string-append
|
||||||
(let ([v (resolve-get part ri (link-element-tag e))])
|
"t:"
|
||||||
(and v (vector-ref v 1))))))
|
(t-encode
|
||||||
|
(let ([v (resolve-get part ri (link-element-tag e))])
|
||||||
|
(and v (vector-ref v 1))))))
|
||||||
|
(cond
|
||||||
|
[(multiple-page-references) ; for index
|
||||||
|
=> (lambda (l)
|
||||||
|
(printf ", \\Smanypageref{~a}" ; using cleveref
|
||||||
|
(string-join (map make-ref l) ",")))]
|
||||||
|
[else
|
||||||
|
(printf ", \\pageref{~a}" (make-ref e))]))
|
||||||
null))
|
null))
|
||||||
|
|
||||||
(define/private (t-encode s)
|
(define/private (t-encode s)
|
||||||
|
@ -626,6 +637,11 @@
|
||||||
(let* ([s-name (style-name (table-style t))]
|
(let* ([s-name (style-name (table-style t))]
|
||||||
[boxed? (eq? 'boxed s-name)]
|
[boxed? (eq? 'boxed s-name)]
|
||||||
[index? (eq? 'index s-name)]
|
[index? (eq? 'index s-name)]
|
||||||
|
[merge-index? (let loop ([part part])
|
||||||
|
(or (memq 'enable-index-merge (style-properties (part-style part)))
|
||||||
|
(let* ([ci (part-collected-info part ri)]
|
||||||
|
[p (and ci (collected-info-parent ci))])
|
||||||
|
(and p (loop p)))))]
|
||||||
[tableform
|
[tableform
|
||||||
(cond [index? "list"]
|
(cond [index? "list"]
|
||||||
[(eq? 'block s-name) "tabular"]
|
[(eq? 'block s-name) "tabular"]
|
||||||
|
@ -758,6 +774,17 @@
|
||||||
(let ([flows (car blockss)]
|
(let ([flows (car blockss)]
|
||||||
[cell-styles (car cell-styless)])
|
[cell-styles (car cell-styless)])
|
||||||
(unless index? (add-clines prev-styles cell-styles))
|
(unless index? (add-clines prev-styles cell-styles))
|
||||||
|
(define group-size
|
||||||
|
(cond
|
||||||
|
[merge-index?
|
||||||
|
;; Merge entries that have the same text & style
|
||||||
|
(let loop ([blockss (cdr blockss)] [group-size 1])
|
||||||
|
(cond
|
||||||
|
[(null? blockss) group-size]
|
||||||
|
[(same-index-entry? flows (car blockss))
|
||||||
|
(loop (cdr blockss) (add1 group-size))]
|
||||||
|
[else group-size]))]
|
||||||
|
[else 1]))
|
||||||
(let loop ([flows flows]
|
(let loop ([flows flows]
|
||||||
[cell-styles cell-styles]
|
[cell-styles cell-styles]
|
||||||
[all-left-line?s all-left-line?s]
|
[all-left-line?s all-left-line?s]
|
||||||
|
@ -769,7 +796,10 @@
|
||||||
(cond
|
(cond
|
||||||
[index?
|
[index?
|
||||||
(printf "\n\\item ")
|
(printf "\n\\item ")
|
||||||
(render-cell 1)
|
(parameterize ([multiple-page-references
|
||||||
|
(and (group-size . > . 1)
|
||||||
|
(extract-index-link-targets (take blockss group-size)))])
|
||||||
|
(render-cell 1))
|
||||||
#f]
|
#f]
|
||||||
[(eq? 'cont (car flows))
|
[(eq? 'cont (car flows))
|
||||||
#f]
|
#f]
|
||||||
|
@ -798,17 +828,18 @@
|
||||||
(cdr cell-styles)
|
(cdr cell-styles)
|
||||||
(cdr all-left-line?s)
|
(cdr all-left-line?s)
|
||||||
right-line?))))
|
right-line?))))
|
||||||
|
(define rest-blockss (list-tail blockss group-size))
|
||||||
(unless (or index?
|
(unless (or index?
|
||||||
(and (null? (cdr blockss))
|
(and (null? rest-blockss)
|
||||||
(not (for/or ([cell-style (in-list cell-styles)])
|
(not (for/or ([cell-style (in-list cell-styles)])
|
||||||
(or (memq 'bottom-border (style-properties cell-style))
|
(or (memq 'bottom-border (style-properties cell-style))
|
||||||
(memq 'border (style-properties cell-style)))))))
|
(memq 'border (style-properties cell-style)))))))
|
||||||
(printf " \\\\\n"))
|
(printf " \\\\\n"))
|
||||||
(cond
|
(cond
|
||||||
[(null? (cdr blockss))
|
[(null? rest-blockss)
|
||||||
(unless index? (add-clines cell-styles #f))]
|
(unless index? (add-clines cell-styles #f))]
|
||||||
[else
|
[else
|
||||||
(loop (cdr blockss) (cdr cell-styless) cell-styles)])))
|
(loop rest-blockss (list-tail cell-styless group-size) cell-styles)])))
|
||||||
(unless inline?
|
(unless inline?
|
||||||
(printf "\\end{~a}~a"
|
(printf "\\end{~a}~a"
|
||||||
tableform
|
tableform
|
||||||
|
|
62
scribble-lib/scribble/private/latex-index.rkt
Normal file
62
scribble-lib/scribble/private/latex-index.rkt
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#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]))))
|
|
@ -15,4 +15,3 @@
|
||||||
\newcommand{\doHypersetup}{\hypersetup{bookmarks=true,bookmarksopen=true,bookmarksnumbered=true}}
|
\newcommand{\doHypersetup}{\hypersetup{bookmarks=true,bookmarksopen=true,bookmarksnumbered=true}}
|
||||||
\newcommand{\packageTocstyle}{\IfFileExists{tocstyle.sty}{\usepackage{tocstyle}\usetocstyle{standard}}{}}
|
\newcommand{\packageTocstyle}{\IfFileExists{tocstyle.sty}{\usepackage{tocstyle}\usetocstyle{standard}}{}}
|
||||||
\newcommand{\packageCJK}{\IfFileExists{CJK.sty}{\usepackage{CJK}}{}}
|
\newcommand{\packageCJK}{\IfFileExists{CJK.sty}{\usepackage{CJK}}{}}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
\packageTocstyle
|
\packageTocstyle
|
||||||
\packageCJK
|
\packageCJK
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% Configuration that is especially meant to be overridden:
|
% Configuration that is especially meant to be overridden:
|
||||||
|
|
||||||
|
@ -68,6 +69,11 @@
|
||||||
|
|
||||||
\newcommand{\SectionNumberLink}[2]{\hyperref[#1]{#2}}
|
\newcommand{\SectionNumberLink}[2]{\hyperref[#1]{#2}}
|
||||||
|
|
||||||
|
% Enabled with a 'enable-index-merge part style property. This default
|
||||||
|
% implementation isn't good enough, because the argument is a
|
||||||
|
% comma-separated sequence of labels:
|
||||||
|
\newcommand{\Smanypageref}[1]{\pageref{#1}}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% Fonts
|
% Fonts
|
||||||
|
|
||||||
|
|
12
scribble-lib/scriblib/book-index.rkt
Normal file
12
scribble-lib/scriblib/book-index.rkt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#lang racket/base
|
||||||
|
(require racket/runtime-path
|
||||||
|
scribble/latex-properties)
|
||||||
|
|
||||||
|
(provide book-index-style-properties)
|
||||||
|
|
||||||
|
(define-runtime-path book-index.tex "book-index.tex")
|
||||||
|
|
||||||
|
(define book-index-style-properties
|
||||||
|
(list
|
||||||
|
(tex-addition book-index.tex)
|
||||||
|
'enable-index-merge))
|
8
scribble-lib/scriblib/book-index.tex
Normal file
8
scribble-lib/scriblib/book-index.tex
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
\usepackage{cleveref}
|
||||||
|
|
||||||
|
\newcommand{\crefrangeconjunction}{, }
|
||||||
|
\newcommand{\crefpairconjunction}{, }
|
||||||
|
\newcommand{\crefmiddleconjunction}{, }
|
||||||
|
\newcommand{\creflastconjunction}{, }
|
||||||
|
|
||||||
|
\renewcommand{\Smanypageref}[1]{\labelcpageref{#1}}
|
Loading…
Reference in New Issue
Block a user