与......有关我的另一个问题关于挪威语,我需要按字母顺序对一些项目进行排序。
我使用此代码将定义的项目列表收集\vocab
到名为的数据库中vocabsort
。
\documentclass[11pt]{memoir}
\usepackage{multicol, hanging}
\usepackage[latin1]{inputenc}
\usepackage{datatool} % for sorting lists
\newcommand{\vocab}[3]{%\parskip=0pt \textbf{#1} (#2) #3~\par%
\DTLnewrow{vocabsort}%
\DTLnewdbentry{vocabsort}{norsk}{#1}%
\DTLnewdbentry{vocabsort}{class}{#2}%
\DTLnewdbentry{vocabsort}{english}{#3}%
}
\newenvironment{vocabsection}[1]{\noindent \hspace{1em} \textbf{#1} %
\DTLifdbexists{vocabsort}{\DTLcleardb{vocabsort}}{\DTLnewdb{vocabsort}}%
}%
{ \dtlsort{norsk}{vocabsort}{\dtlicompare}%
\displaysorteddb
}
\newcommand{\displaysorteddb}{%
\begin{multicols}{2}
\begin{hangparas}{0.5em}{1}
\begin{DTLenvforeach*}{vocabsort}{\norsk=norsk, \class=class, \english=english}
\textbf{\norsk} (\class) \english~\par
\end{DTLenvforeach*}
\end{hangparas}
\end{multicols}
}
\begin{document}
\subsection{Foo}
\begin{vocabsection}{Body Vocab}
\vocab{hør}{n.}{hair}
\vocab{hode}{n.}{head}
\vocab{øye}{n.}{eyes}
\vocab{øre}{n.}{ear}
\vocab{hake}{n.}{chin}
\vocab{nakke}{n.}{neck}
\vocab{hånd}{n.}{hand}
\vocab{finger}{n.}{finger}
\vocab{arm}{n.}{arm}
\end{vocabsection}
\end{document}
输出:
这个顺序不正确,因为正确的挪威语字母顺序是:
abcdefghijklmnopqrstu vwxyz æ ø å
因此,以 开头的单词h
实际上应该按以下顺序排列:
鳕鱼
霍德
赫尔
手
我如何实现这个目标?
答案1
(要使用此功能,您需要版本datatool
v2.25。我刚刚将其上传到 CTAN,因此大约需要一天时间才能到达镜像和 TeX 发行版。)
提供的比较处理程序datatool
(实际上在 中定义datatool-base.sty
)通过为字符串的每个元素分配数字代码来比较两个字符串。代码分配如下:
- 如果为空,则代码设置为 -1。
- 如果该字符(或宏)被识别为单词断开,则代码将设置为与空格字符的字符代码相同(32)。
- 如果“字符”实际上是一个宏(命令),则代码设置为 0。从 v2.24 开始,如果此宏被标识为 UTF-8 字符的第一个八位字节(并且已启用 UTF-8 选项),则使用
\dtlsetUTFviiicharcode{octets}{register}
(对于区分大小写的比较)或\dtlsetUTFviiilccharcode{octets}{register}
(对于不区分大小写的比较)来获取代码。 - 如果以上都不适用,则使用
\dtlsetcharcode{character}{register}
(用于区分大小写的比较)或\dtlsetlccharcode{character}{register}
(用于不区分大小写的比较)设置代码。这些命令是在 v2.24 中引入的。早期版本只是使用 TeX 的反引号方法设置字符代码(用于\lccode
不区分大小写的比较)。
(请注意,虽然这些新命令是在 v2.24 中引入的,但较新的 v2.25 修复了影响此答案的错误。)
因此,有两种方法依赖于文档的输入编码。
拉丁语-1
(这也适用于其他编码,其中每个字符被视为单个 TeX 标记。)
在这种情况下相关的两个命令是\dtlsetcharcode
和\dtlsetlccharcode
。默认定义是:
\newcommand*{\dtlsetcharcode}[2]{#2=`#1\relax}
\newcommand*{\dtlsetlccharcode}[2]{#2=\lccode`#1\relax}
(第一个参数是字符,第二个参数是用于存储字符代码的计数寄存器。)使用此方法,挪威语字符的代码如下:
Å 197
Æ 198
Ø 216
å 229
æ 230
ø 248
(供参考A
-> 65,Z
-> 90,a
-> 97,z
-> 122。)因此,这会将所有挪威语字符z
按上述顺序放在后面。如果要更改此顺序,则需要重新定义\dtlsetcharcode
和\dtlsetlccharcode
。例如,对于挪威语字母表:
\renewcommand*{\dtlsetcharcode}[2]{%
\ifstrequal{#1}{æ}%
{%
#2=123\relax
}%
{%
\ifstrequal{#1}{ø}%
{%
#2=124\relax
}%
{%
\ifstrequal{#1}{å}%
{%
#2=125\relax
}%
{%
\ifstrequal{#1}{Æ}%
{%
#2=91\relax
}%
{%
\ifstrequal{#1}{Ø}%
{%
#2=92\relax
}%
{%
\ifstrequal{#1}{Å}%
{%
#2=93\relax
}%
{%
#2=`#1\relax
}%
}%
}%
}%
}%
}%
}
\renewcommand*{\dtlsetlccharcode}[2]{%
\ifstrequal{#1}{æ}%
{%
#2=123\relax
}%
{%
\ifstrequal{#1}{ø}%
{%
#2=124\relax
}%
{%
\ifstrequal{#1}{å}%
{%
#2=125\relax
}%
{%
\ifstrequal{#1}{Æ}%
{%
#2=123\relax
}%
{%
\ifstrequal{#1}{Ø}%
{%
#2=124\relax
}%
{%
\ifstrequal{#1}{Å}%
{%
#2=125\relax
}%
{%
#2=\lccode`#1\relax
}%
}%
}%
}%
}%
}%
}
为了清晰起见,这些都使用了etoolbox
条件\ifstrequal
。使用 TeX 的条件语句可以实现更有效的方法,例如\ifnum
。例如:
\renewcommand*{\dtlsetcharcode}[2]{%
#2=`#1\relax
\ifnum#2=230\relax
#2=123\relax
\else
\ifnum#2=248\relax
#2=124\relax
\else
\ifnum#2=229\relax
#2=125\relax
\else
\ifnum#2=198\relax
#2=91\relax
\else
\ifnum#2=216\relax
#2=92\relax
\else
\ifnum#2=197\relax
#2=93\relax
\fi
\fi
\fi
\fi
\fi
\fi
}
\renewcommand*{\dtlsetlccharcode}[2]{%
#2=\lccode`#1\relax
\ifnum#2=230\relax
#2=123\relax
\else
\ifnum#2=248\relax
#2=124\relax
\else
\ifnum#2=229\relax
#2=125\relax
\fi
\fi
\fi
}
这些重新定义可以添加到您的示例中:
\documentclass[11pt]{memoir}
\usepackage{multicol}
\usepackage[latin1]{inputenc}
\usepackage{datatool}
\renewcommand*{\dtlsetcharcode}[2]{%
#2=`#1\relax
\ifnum#2=230\relax
#2=123\relax
\else
\ifnum#2=248\relax
#2=124\relax
\else
\ifnum#2=229\relax
#2=125\relax
\else
\ifnum#2=198\relax
#2=91\relax
\else
\ifnum#2=216\relax
#2=92\relax
\else
\ifnum#2=197\relax
#2=93\relax
\fi
\fi
\fi
\fi
\fi
\fi
}
\renewcommand*{\dtlsetlccharcode}[2]{%
#2=\lccode`#1\relax
\ifnum#2=230\relax
#2=123\relax
\else
\ifnum#2=248\relax
#2=124\relax
\else
\ifnum#2=229\relax
#2=125\relax
\fi
\fi
\fi
}
\newcommand{\vocab}[3]{%
\DTLnewrow{vocabsort}%
\DTLnewdbentry{vocabsort}{norsk}{#1}%
\DTLnewdbentry{vocabsort}{class}{#2}%
\DTLnewdbentry{vocabsort}{english}{#3}%
}
\newenvironment{vocabsection}[1]{\noindent \hspace{1em} \textbf{#1} %
\DTLifdbexists{vocabsort}{\DTLcleardb{vocabsort}}{\DTLnewdb{vocabsort}}%
}%
{ \dtlsort{norsk}{vocabsort}{\dtlicompare}%
\displaysorteddb
}
\newcommand{\displaysorteddb}{%
\begin{multicols}{2}
\begin{hangparas}{0.5em}{1}
\begin{DTLenvforeach*}{vocabsort}{\norsk=norsk, \class=class, \english=english}
\textbf{\norsk} (\class) \english~\par
\end{DTLenvforeach*}
\end{hangparas}
\end{multicols}
}
\begin{document}
\subsection{Foo}
\begin{vocabsection}{Body Vocab}
\vocab{hør}{n.}{hair}
\vocab{hode}{n.}{head}
\vocab{øye}{n.}{eyes}
\vocab{øre}{n.}{ear}
\vocab{hake}{n.}{chin}
\vocab{nakke}{n.}{neck}
\vocab{hånd}{n.}{hand}
\vocab{finger}{n.}{finger}
\vocab{arm}{n.}{arm}
\end{vocabsection}
\end{document}\newcommand{\displaysorteddb}{%
\begin{multicols}{2}
\begin{hangparas}{0.5em}{1}
\begin{DTLenvforeach*}{vocabsort}{\norsk=norsk, \class=class, \english=english}
\textbf{\norsk} (\class) \english~\par
\end{DTLenvforeach*}
\end{hangparas}
\end{multicols}
}
\begin{document}
\subsection{Foo}
\begin{vocabsection}{Body Vocab}
\vocab{hør}{n.}{hair}
\vocab{hode}{n.}{head}
\vocab{øye}{n.}{eyes}
\vocab{øre}{n.}{ear}
\vocab{hake}{n.}{chin}
\vocab{nakke}{n.}{neck}
\vocab{hånd}{n.}{hand}
\vocab{finger}{n.}{finger}
\vocab{arm}{n.}{arm}
\end{vocabsection}
\end{document}
得出的结果为:
具有所需的顺序:hake、hode、hør、hånd。
UTF-8
通过在加载前使用选项inputenc
来启用 UTF-8 支持(由 自动加载)。您也可以稍后使用 或 来启用或禁用它。utf8
datatool-base
datatool
\dtlenableUTFviii
\dtldisableUTFviii
在这种情况下,\dtlsetUTFviiicharcode
和\dtlsetUTFviiilccharcode
用于设置字符代码,其中第一个参数由组成 UTF-8 字符的两个八位字节标记组成。这些命令的默认定义是:
\newcommand*\dtlsetUTFviiicharcode[2]{\dtlsetdefaultUTFviiicharcode{#1}{#2}}
\newcommand*\dtlsetUTFviiilccharcode[2]{\dtlsetdefaultUTFviiilccharcode{#1}{#2}}
这些默认命令将一些常见的补充重音拉丁字符的代码设置为与无重音版本的代码相同。(例如,é
被赋予与 相同的字符代码e
。因此,示例文档的 UTF-8 版本为:
\documentclass[11pt]{memoir}
\usepackage{multicol}
\usepackage[utf8]{inputenc}
\usepackage{datatool}
\renewcommand*{\dtlsetUTFviiicharcode}[2]{%
\ifstrequal{#1}{Æ}%
{%
#2=91\relax
}%
{%
\ifstrequal{#1}{Ø}%
{%
#2=92\relax
}%
{%
\ifstrequal{#1}{Å}%
{%
#2=93\relax
}%
{%
\ifstrequal{#1}{æ}%
{%
#2=123\relax
}%
{%
\ifstrequal{#1}{ø}%
{%
#2=124\relax
}%
{%
\ifstrequal{#1}{å}%
{%
#2=125\relax
}%
{%
\dtlsetdefaultUTFviiicharcode{#1}{#2}%
}%
}%
}%
}%
}%
}%
}
\renewcommand*{\dtlsetUTFviiilccharcode}[2]{%
\ifstrequal{#1}{Æ}%
{%
#2=123\relax
}%
{%
\ifstrequal{#1}{Ø}%
{%
#2=124\relax
}%
{%
\ifstrequal{#1}{Å}%
{%
#2=125\relax
}%
{%
\ifstrequal{#1}{æ}%
{%
#2=123\relax
}%
{%
\ifstrequal{#1}{ø}%
{%
#2=124\relax
}%
{%
\ifstrequal{#1}{å}%
{%
#2=125\relax
}%
{%
\dtlsetdefaultUTFviiilccharcode{#1}{#2}%
}%
}%
}%
}%
}%
}%
}
\newcommand{\vocab}[3]{%
\DTLnewrow{vocabsort}%
\DTLnewdbentry{vocabsort}{norsk}{#1}%
\DTLnewdbentry{vocabsort}{class}{#2}%
\DTLnewdbentry{vocabsort}{english}{#3}%
}
\newenvironment{vocabsection}[1]{\noindent \hspace{1em} \textbf{#1} %
\DTLifdbexists{vocabsort}{\DTLcleardb{vocabsort}}{\DTLnewdb{vocabsort}}%
}%
{ \dtlsort{norsk}{vocabsort}{\dtlicompare}%
\displaysorteddb
}
\newcommand{\displaysorteddb}{%
\begin{multicols}{2}
\begin{hangparas}{0.5em}{1}
\begin{DTLenvforeach*}{vocabsort}{\norsk=norsk, \class=class, \english=english}
\textbf{\norsk} (\class) \english~\par
\end{DTLenvforeach*}
\end{hangparas}
\end{multicols}
}
\begin{document}
\subsection{Foo}
\begin{vocabsection}{Body Vocab}
\vocab{hør}{n.}{hair}
\vocab{hode}{n.}{head}
\vocab{øye}{n.}{eyes}
\vocab{øre}{n.}{ear}
\vocab{hake}{n.}{chin}
\vocab{nakke}{n.}{neck}
\vocab{hånd}{n.}{hand}
\vocab{finger}{n.}{finger}
\vocab{arm}{n.}{arm}
\end{vocabsection}
\end{document}
这会产生相同的结果:
答案2
这个问题可能类似于对索引条目进行排序的问题。当你想强制一个特定的排序位置(间接地,排序顺序)时,你必须为排序算法提供一些帮助。
在您的申请中,我会提供一个常规的英文字母替代品或者挪威语 英语用于对条目进行排序。为此,请在数据库中创建一个额外的字段,将 each 替换æ
为za
,将 each替换为 ,ø
将each 替换为 ,将zb
eachå
替换为zc
,以便按顺序对它们进行排序后 z
。
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{datatool,xparse}
\NewDocumentCommand{\vocab}{m o m m}{%\parskip=0pt \textbf{#1} (#2) #3~\par%
\DTLnewrow{vocabsort}%
\DTLnewdbentry{vocabsort}{norsk}{#1}% Norsk
\IfNoValueF{#2}{\DTLnewdbentry{vocabsort}{norsksort}{#2}}% Norsk sort
\DTLnewdbentry{vocabsort}{class}{#3}% Class
\DTLnewdbentry{vocabsort}{english}{#4}% English
}
\newenvironment{vocabsection}[1]{\noindent \textbf{#1} \par \medskip
\DTLifdbexists{vocabsort}{\DTLcleardb{vocabsort}}{\DTLnewdb{vocabsort}}%
}%
{ \dtlsort[norsk]{norsksort}{vocabsort}{\dtlicompare}%
\displaysorteddb
}
\newcommand{\displaysorteddb}{%
\begin{DTLenvforeach*}{vocabsort}{\norsk=norsk, \class=class, \english=english}
\textbf{\norsk} (\class) \english~\par
\end{DTLenvforeach*}
}
\begin{document}
\begin{vocabsection}{Body Vocab}
\vocab{hør}[hzbr]{n.}{hair} % ø > zb
\vocab{hode}{n.}{head}
\vocab{øye}[zbye]{n.}{eyes} % ø > zb
\vocab{øre}[zbre]{n.}{ear} % ø > zb
\vocab{hake}{n.}{chin}
\vocab{nakke}{n.}{neck}
\vocab{hånd}[hzcnd]{n.}{hand}% å > zc
\vocab{finger}{n.}{finger}
\vocab{arm}{n.}{arm}
\end{vocabsection}
\end{document}
排序顺序作为使用接口的可选第二个参数提供
\vocab{<norsk>}[<norsk sort>]{<class>}{<english>}
添加<norsk sort>
到数据库中的条件是它存在。宏
\dtlsort[norsk]{norsksort}{vocabsort}{\dtlicompare}
使用该字段norsksort
作为数据库中的排序首选项vocabsort
(使用i
不区分大小写的compare
),并且norsk
仅当norsksort
不存在(null 或\DTLstringnull
)时才使用。
a@b
如上所述,这与使用建议没有什么不同\index
;即放置b
在索引中,但按以下方式排序a
(请参阅第节2.2 基础知识/第 4 页makeindex
文档)。典型用法将涉及类似 的内容\index{alpha@$\alpha$}
。当然,\vocab
如果需要,也可以更改上述界面以接受类似的输入。