オックスフォード(OUP)省略規則に従って数値/ページ参照範囲をフォーマットする

オックスフォード(OUP)省略規則に従って数値/ページ参照範囲をフォーマットする

オックスフォード スタイル ガイドのルールでは、数値の範囲とページ参照の省略について次のように規定されています。

一般的に、数字の範囲については、数字をできるだけ少なくする en ルールを使用します。30–1、42–3、132–6、1841–5ただし、各百の位では、10 から 19 までの数字は省略しないでください。これらは複合数ではなく単一の数字を表します。10–12、15–19、114–18、214–15、310–11。

TeX/LuaTeX でページ範囲または別の動的な数値範囲に対してこれを実装するにはどうすればよいですか?

答え1

\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}

私はテストケースのリストを入手しましたPeter Kahrelのページそして、これがすべて合格することを確認しました。

注: 私は、Kahrel のテスト ケースと、1000 を超える範囲の扱いに関する規則の解釈に同意しません。彼が「12991–3001」としているところを、私は 12991–13001 とします。その理由は、「12,991 から 13,001」ではなく「… から 3,001」と言うからです。私は個人的にこれほど大きな範囲を扱う必要がないので、上記のコードでは扱いません。

関連情報