..png)
In den Regeln des Oxford Style Guide heißt es zur Abkürzung von Zahlenbereichen und Seitenverweisen:
Für Zahlenspannen gilt im Allgemeinen die En-Regel, bei der auf die geringstmögliche Anzahl von Ziffern reduziert wird:30–1, 42–3, 132–6, 1841–5. Lassen Sie jedoch in jeder Hunderterstelle keine Ziffern der Gruppe 10 bis 19 weg, da diese einzelne und keine zusammengesetzten Zahlen darstellen:10–12, 15–19, 114–18, 214–15, 310–11.
Wie implementiere ich dies für einen Seitenbereich oder einen anderen dynamischen Zahlenbereich in TeX/LuaTeX?
Antwort1
\documentclass{article}
\usepackage{fontspec} % for easy UTF-8 support -- change en-dashes to '--' below to get rid of this dependency
\usepackage{luacode}
\usepackage{xifthen}
\usepackage{refcount}
\usepackage{lipsum} % used only for the test pages in this document
\begin{luacode}
function common_prefix(a, b)
for idx = 1, string.len(a) do
if a:sub(idx, idx) ~= b:sub(idx, idx) then
return a:sub(1, idx - 1)
end
end
end
function numberrange_string(a, b)
as = tostring(a)
bs = tostring(b)
if a == b then
return as
elseif as:len() ~= bs:len() then
return as .. "–" .. bs
else
common_range = common_prefix(as, bs)
if common_range:len() == 0 then
return as .. "–" .. bs
elseif as:sub(as:len() - 1, as:len() - 1) == "1" then
return common_range:sub(1, common_range:len() - 1) .. as:sub(common_range:len(), as:len()) .. "–" .. bs:sub(common_range:len(), bs:len())
else
return common_range:sub(1, common_range:len()) .. as:sub(common_range:len() + 1, as:len()) .. "–" .. bs:sub(common_range:len() + 1, bs:len())
end
end
end
function numberrange(a, b)
tex.print(numberrange_string(a, b))
end
\end{luacode}
\newcommand{\numberrange}[2]{\directlua{numberrange(#1, #2)}}
\newcommand{\pagerefrange}[2]{\ifthenelse{\equal{\getpagerefnumber{#1}}{\getpagerefnumber{#2}}}%
{p.~\pageref{#1}}%
{pp.~\numberrange{\getpagerefnumber{#1}}{\getpagerefnumber{#2}}}}
\begin{document}
Some simple number ranges: \numberrange{1}{2}, \numberrange{21}{24}, \numberrange{97}{156}, \numberrange{109}{112}, \numberrange{112}{115}, \numberrange{151}{158}, \numberrange{1100}{1113}, \numberrange{11564}{11615}, \numberrange{12991}{13001}*.
Some page ranges: Test 1: \pagerefrange{test1-start}{test1-end}; Test 2: \pagerefrange{test2-start}{test2-end}; Test 3: \pagerefrange{test3-start}{test3-end}; Test 4: \pagerefrange{test4-start}{test4-end}; Test 5: \pagerefrange{test5-start}{test5-end}.
\clearpage
Test 1 is all on the same page. \label{test1-start}\label{test1-end}
Test 2 starts on the same page as Test 1, but ends on a different one. \label{test2-start}
Test 5 also starts here. \label{test5-start}
\clearpage
This is the end of Test 2. \label{test2-end}
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage
Test 3 shows how ranges in the teens don’t get elided. \label{test3-start}
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage
Test 3 ends here. \label{test3-end}
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage
Test 4 shows how ranges in the twenties to nineties do get elided. \label{test4-start}
\clearpage \lipsum[1]
\clearpage \lipsum[1]
\clearpage
Test 4 ends here. \label{test4-end}
Test 5 also ends here. It shows how ranges where the ends have different numbers of digits are written in full. \label{test5-end}
\end{document}
Ich habe eine Liste mit Testfällen vonPeter Kahrels Seiteund bestätigt, dass dies alle Anforderungen erfüllt.
NB: Ich bin zufällig nicht einverstanden mit Kahrels Testfall und Interpretation der Regeln zur Behandlung von Bereichen, die sich über Zehntausende erstrecken: Wo er „12991–3001“ hat, hätte ich 12991–13001, mit der Begründung, dass man „zwölftausendneunhunderteinundneunzig bis dreizehntausendeins“ sagen würde und nicht „… bis dreitausendeins“. Da ich persönlich nicht mit so großen Bereichen umgehen muss, verarbeitet der obige Code sie nicht.