@@ -63,6 +63,24 @@ local function _addDelimiter (t, sep)
6363 return ret
6464end
6565
66+ -- Simplify the second number in an Arabic page range.
67+ -- @tparam string p1 The first page number (assumed to be in Arabic format).
68+ -- @tparam string p2 The second page number (assumed to be in Arabic format).
69+ -- @tparam string format The format to use (either 'minimal' or 'minimal-two').
70+ -- @treturn string The simplified second page number.
71+ local function _simplifyArabicInRange (p1 , p2 , format )
72+ if # p1 > 1 and # p1 == # p2 then
73+ local ending = format == ' minimal' and 1 or 2
74+ for i = 1 , # p1 - ending do
75+ if p1 :sub (i , i ) ~= p2 :sub (i , i ) then
76+ return p2 :sub (i , - 1 )
77+ end
78+ end
79+ return p2 :sub (# p1 - ending + 1 , - 1 )
80+ end
81+ return p2
82+ end
83+
6684function package .buildIndex ()
6785 local nodes = SILE .scratch .info .thispage .index
6886 local pageno = pl .tablex .copy (SILE .scratch .counters .folio )
@@ -98,22 +116,33 @@ function package:_init (options)
98116 end
99117end
100118
119+ -- Format a list of pages, collapsing consecutive pages into ranges.
120+ -- @tparam table pages A list of pages with pageno and link fields.
121+ -- @treturn table A list of formatted page ranges.
101122function package :formatPageRanges (pages )
102123 local ranges = {}
103124 for _ , range in ipairs (_groupPageRanges (pages )) do
104125 if # range == 1 then
105126 table.insert (ranges , _linkWrapper (range [1 ].link , self .class .packages .counters :formatCounter (range [1 ].pageno )))
106127 else
128+ local p1 = self .class .packages .counters :formatCounter (range [1 ].pageno )
129+ local p2 = self .class .packages .counters :formatCounter (range [# range ].pageno )
130+ if self .config [' page-range-format' ] ~= ' expanded' and range [1 ].pageno .display == " arabic" then
131+ p2 = _simplifyArabicInRange (p1 , p2 , self .config [' page-range-format' ])
132+ end
107133 table.insert (ranges , {
108- _linkWrapper (range [1 ].link , self . class . packages . counters : formatCounter ( range [ 1 ]. pageno ) ),
134+ _linkWrapper (range [1 ].link , p1 ),
109135 self .config [' page-range-delimiter' ],
110- _linkWrapper (range [# range ].link , self . class . packages . counters : formatCounter ( range [ # range ]. pageno ) )
136+ _linkWrapper (range [# range ].link , p2 )
111137 })
112138 end
113139 end
114140 return _addDelimiter (ranges , self .config [' page-delimiter' ])
115141end
116142
143+ -- Format a list of pages.
144+ -- @tparam table pages A list of pages with pageno and link fields.
145+ -- @treturn table A list of formatted pages.
117146function package :formatPages (pages )
118147 if self .config [' page-range-format' ] ~= ' none' then
119148 return self :formatPageRanges (pages )
@@ -195,7 +224,13 @@ An index is essentially the same thing as a table of contents, but sorted.
195224The package accepts several configuration options:
196225\begin{itemize}
197226\item{\autodoc:parameter{page-range-format}: The format used to display page ranges.
198- Possible values are \autodoc:parameter{expanded} (default), \autodoc:parameter{none}.}
227+ Possible values are:
228+ \begin{itemize}
229+ \item{\code{none}: All numbers are displayed, without page range collapsing.}
230+ \item{\code{expanded}: All digits are displayed in both numbers in a page range: 42–45, 321–328, 2787–2816.}
231+ \item{\code{minimal}: All digits repeated in the second number are left out in a page range: 42–5, 321–8, 2787–816}
232+ \item{\code{minimal-two}: As \code{minimal}, but at least two digits are kept in the second number when it has two or more digits long.}
233+ \end{itemize}}
199234\item{\autodoc:parameter{page-range-delimiter}: The delimiter between the start and end of a page range.}
200235\item{\autodoc:parameter{page-delimiter}: The delimiter between pages.}
201236\end{itemize}
0 commit comments