expl3 中的字典顺序

expl3 中的字典顺序

expl3 中是否有检测字典顺序(字母顺序)的函数,例如,对 返回 TRUE "Abel" precedes "able"?浏览interface3文档表明没有。如果有的话,我就可以省去编写base 26转换的麻烦(而且这只适用于短词)。

答案1

目前,没有内置方法用于此类文本比较(有通用排序包装器,但必须提供比较代码)。原因是排序很复杂:规则是特定于语言的,并且需要大量的 Unicode 数据。

对于英语中的简单排序,可以利用字母的字符代码“正确”排序的事实。这可以利用\pdfstrcmppdfTeX 中的原语来利用,可以使用文档中但内部的函数访问expl3IE我们可能会在这里更改名称!)。这可能会导致

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \printsorted { m }
  { \rn_sort:n {#1} }
\clist_new:N \l__rn_sort_clist
\cs_new_protected:Npn \rn_sort:n #1
  {
    \group_begin:
      \clist_set:Nn \l__rn_sort_clist {#1}
      \clist_sort:Nn \l__rn_sort_clist
        {
          \int_compare:nNnTF { \__str_if_eq:nn {##1} {##2} } < 0
            { \sort_return_same: }
            { \sort_return_swapped: }
        }
      \clist_use:Nn \l__rn_sort_clist { , }
    \group_end:
  }
\ExplSyntaxOff
\begin{document}
\printsorted{Abel, abel}
\printsorted{abel, Abel}
\printsorted{abel,Bee}
\end{document}

请注意,由于我们只使用字符代码,所以所有以大写字母开头的字符串最终都会排在以小写字母开头的字符串之前:我们可以制作一个更复杂的版本,使用两部分排序来处理这个问题。


之所以\__str_if_eq:nn是内部的,是因为它基本上是直接访问,\pdfstrcmp但设置为与 pdfTeX、XeTeX、LuaTeX 和 e-(u)pTeX 配合使用。特别是,团队只使用它来测试相等性,而不是排序,这恰恰是因为与语言和大小写相关的问题。

答案2

使用 LuaTeX 可以实现类似的效果。在 Lua 中排序可能要快得多。

为了解析逗号列表,我使用了utilities.parsers.settings_to_arrayConTeXt。为此,我必须导入必要的 ConTeXt 核心文件。

从示例中可以看出,排序不支持 Unicode。但是,Luatable.sort接收两个参数,即要排序的表和可选的排序函数。这里可以实现一个自己的排序功能根据语言进行正确的排序。

\documentclass{article}
\usepackage{fontspec}

\directlua{ % Use ConTeXt libraries
dofile(kpse.find_file("l-lpeg.lua"))
dofile(kpse.find_file("util-sto.lua"))
dofile(kpse.find_file("util-prs.lua"))
}

\directlua{
function printsorted(keywords)
    local input = utilities.parsers.settings_to_array(keywords)
    table.sort(input)
    tex.sprint(table.concat(input,", "))
end
}

\newcommand\printsorted[1]{%
  \directlua{printsorted(\unexpanded{[==[#1]==]})}}

\begin{document}
\printsorted{Übermut, Angst, Okay, ungenau, Ökonom, Ärger}
\end{document}

相关内容