我正在尝试学习 LaTeX,我正在创建类似城市百科全书的东西。所以我做了类似\printcity{country}{city_name}
或 的命令\createcity{country/city_name}{Long city description.}
。效果很好。解决方案基于主题为变量赋值并检索以供日后使用的推荐方法是什么?. 但现在我必须输入
\printcity{Italy}{Florence}
\printcity{Poland}{Warsaw}
\printcity{country_name}{other_city}
所以,这真的不太舒服。特别是我真的想按字典顺序排列。但我不知道如何打印所有值。由于最小的代码示例可能会有所帮助,假设我的代码如下:
\documentclass{article}
\usepackage{pgfkeys}
\usepackage[utf8]{inputenc}
\usepackage{polski}
\usepackage[polish]{babel}
\newcommand{\setvalue}[1]{\pgfkeys{/variables/#1}}
\def\createcity#1#2{\setvalue{#1 = #2}}
\newcommand{\getvalue}[1]{\pgfkeysvalueof{/variables/#1}}
\def\printcity#1#2{\subsubsection*{#2} \getvalue{#1/#2}}
\newcommand{\declarecountry}[1]{%
\pgfkeys{
/variables/#1.is family,
/variables/#1.unknown/.style = {\pgfkeyscurrentpath/\pgfkeyscurrentname/.initial = ##1}
}%
}
\declarecountry{Poland/}
\createcity{Poland/Warsaw}{Capital rebuilt after WWII.}
\createcity{Poland/Cracow}{Second largest and one of the oldest cities in Poland.}
\createcity{Poland/Toruń}{The medieval old town of Toruń is the birthplace of Polish astronomer Nicolaus Copernicus.}
\begin{document}
\printcity{Poland}{Toruń}
\printcity{Poland}{Cracow}
\printcity{Poland}{Warsaw}
\end{document}
但是我怎样才能按字典顺序打印波兰的所有城市?(我不知道如何按任何顺序打印所有内容。因此,请将其包含在您的答案中。)
我正在使用 PDFLaTeX。
答案1
不要告诉约瑟夫。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\declarecountry}{m}
{
\prop_new:c { g_tacet_cities_#1_prop }
}
\NewDocumentCommand{\createcity}{mmm}
{
\prop_gput:cnn { g_tacet_cities_#1_prop } { #2 } { #3 }
}
\NewDocumentCommand{\printcity}{mm}
{
#2,~#1:~\prop_item:cn { g_tacet_cities_#1_prop } { #2 }
}
\NewDocumentCommand{\printcities}{m}
{
\tacet_cities_print:n { #1 }
}
\seq_new:N \l__tacet_cities_country_seq
\cs_new_protected:Nn \tacet_cities_print:n
{
\seq_clear:N \l__tacet_cities_country_seq
\prop_map_inline:cn { g_tacet_cities_#1_prop }
{
\seq_put_right:Nx \l__tacet_cities_country_seq { ##1 }
}
\seq_sort:Nn \l__tacet_cities_country_seq
{
\tacet_city_if_before:nnTF { ##1 } { ##2 }
{ \sort_return_same: }
{ \sort_return_swapped: }
}
\section{#1}
\seq_map_inline:Nn \l__tacet_cities_country_seq
{
\noindent
##1:~\prop_item:cn { g_tacet_cities_#1_prop } { ##1 }
\par
}
}
\prg_new_conditional:Nnn \tacet_city_if_before:nn { p,T,F,TF }
{% I hope the LaTeX3 police won't catch me
\int_compare:nTF { \pdftex_strcmp:D { #1 } { #2 } < 0 }
{
\prg_return_true:
}
{
\prg_return_false:
}
}
\ExplSyntaxOff
\begin{document}
\declarecountry{Italy}
\createcity{Italy}{Venice}{Some facts about Venice}
\createcity{Italy}{Milan}{Some facts about Milan}
\createcity{Italy}{Florence}{Some facts about Florence}
\createcity{Italy}{Rome}{Some facts about Rome}
\printcity{Italy}{Venice}
\printcities{Italy}
\end{document}
有点复杂
不同国家的城市往往有奇怪的口音,上述代码对它们不起作用。
这是一个扩展版本,其中对于名称中带有变音符号的城市,您还需要提供key
用于排序和调用(参见Düsseldorf
)的示例。
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\declarecountry}{m}
{
\seq_new:c { g_tacet_cities_#1_seq }
}
\NewDocumentCommand{\createcity}{mmm}
{
\tacet_cities_create:nnn { #1 } { #2 } { #3 }
}
\NewDocumentCommand{\printcity}{mm}
{
\prop_item:cn { g_tacet_cities_city_#1/#2_prop } { name }
,~
#1:~
\prop_item:cn { g_tacet_cities_city_#1/#2_prop } { text }
}
\NewDocumentCommand{\printcities}{m}
{
\tacet_cities_print:n { #1 }
}
\prop_new:N \l__tacet_cities_temp_prop
\tl_new:N \l__tacet_cities_temp_tl
\seq_new:N \l__tacet_cities_country_seq
\keys_define:nn { tacet/cities }
{
name .code:n = \prop_put:Nnn \l__tacet_cities_temp_prop { name } { #1 },
key .code:n = \prop_put:Nnn \l__tacet_cities_temp_prop { key } { #1 },
unknown .code:n = \prop_put:NnV \l__tacet_cities_temp_prop { name } \l_keys_key_tl,
}
\cs_new_protected:Nn \tacet_cities_create:nnn
{
\prop_clear:N \l__tacet_cities_temp_prop
\keys_set:nn { tacet/cities } { #2 }
\prop_if_in:NnTF \l__tacet_cities_temp_prop { key }
{
\prop_get:NnN \l__tacet_cities_temp_prop { key } \l__tacet_cities_temp_tl
}
{
\prop_get:NnN \l__tacet_cities_temp_prop { name } \l__tacet_cities_temp_tl
\prop_put:NnV \l__tacet_cities_temp_prop { key } \l__tacet_cities_temp_tl
}
\seq_gput_right:cV { g_tacet_cities_#1_seq } \l__tacet_cities_temp_tl
\prop_put:Nnn \l__tacet_cities_temp_prop { text } { #3 }
\prop_new:c { g_tacet_cities_city_#1/\l__tacet_cities_temp_tl _prop }
\prop_gset_eq:cN
{ g_tacet_cities_city_#1/\l__tacet_cities_temp_tl _prop }
\l__tacet_cities_temp_prop
}
\cs_new_protected:Nn \tacet_cities_print:n
{
\seq_set_eq:Nc \l__tacet_cities_country_seq { g_tacet_cities_#1_seq }
\seq_sort:Nn \l__tacet_cities_country_seq
{
\tacet_city_if_before:nnTF { ##1 } { ##2 }
{ \sort_return_same: }
{ \sort_return_swapped: }
}
\section{#1}
\seq_map_inline:Nn \l__tacet_cities_country_seq
{
\noindent
\prop_item:cn { g_tacet_cities_city_#1/##1_prop } { name }
:~
\prop_item:cn { g_tacet_cities_city_#1/##1_prop } { text }
\par
}
}
\prg_new_conditional:Nnn \tacet_city_if_before:nn { p,T,F,TF }
{% I hope the LaTeX3 police won't catch me
\int_compare:nTF { \pdftex_strcmp:D { #1 } { #2 } < 0 }
{
\prg_return_true:
}
{
\prg_return_false:
}
}
\ExplSyntaxOff
\begin{document}
\declarecountry{Italy}
\createcity{Italy}{Venice}{Some facts about Venice}
\createcity{Italy}{Milan}{Some facts about Milan}
\createcity{Italy}{Florence}{Some facts about Florence}
\createcity{Italy}{Rome}{Some facts about Rome}
\declarecountry{Germany}
\createcity{Germany}{Furtwangen}{A town in the Black Forest}
\createcity{Germany}{Bielefeld}{Does it exist?}
\createcity{Germany}{Berlin}{A big city}
\createcity{Germany}{Darmstadt}{Hosted the TUG Conference}
\createcity{Germany}{
name=Düsseldorf,
key=Dusseldorf,
}{This has the \emph{umlaut}}
\printcity{Italy}{Venice}
\printcity{Germany}{Dusseldorf}% the key!
\printcities{Italy}
\printcities{Germany}
\end{document}