
\authors
내 LaTeX 파일에서 내용을 가질 수 있는 변수를 만듭니다 .
[Doe] John Doe; [Potter] Harry Potter; [Clinton] Bill Clinton; [Obama] Barack Obama; ...
이는 동적으로 생성되므로 약간 변경할 수 있습니다(이름과 성을 검색하는 데이터 파일이 있습니다). 이 가변 텍스트를 성별로 정렬되고 깔끔하게 표시되는 목록으로 바꿀 수 있는 방법이 있나요?
Bill Clinton, John Doe, Barack Obama, Harry Potter,...
1) 이것이 가능합니까? 2) 이 초기 정보를 변수에 저장해야 합니까, 아니면 파일이나 다른 것에 저장해야 합니까?
답변1
expl3
다음은 모듈을 사용한 구현입니다 l3sort
.
\documentclass{article}
\usepackage{xparse,l3sort,pdftexcmds}
\ExplSyntaxOn
\cs_set_eq:Nc \konewka_strcmp:nn { pdf@strcmp }
\NewDocumentCommand{\addauthor}{ o m m }
{
\IfNoValueTF{#1}
{
\konewka_add_author:nnn { #3 } { #2 } { #3 }
}
{
\konewka_add_author:nnn { #1 } { #2 } { #3 }
}
}
\NewDocumentCommand{\printauthors}{ }
{
\konewka_print_authors:
}
\seq_new:N \g_konewka_authors_id_seq
\seq_new:N \l__konewka_authors_full_seq
\cs_new_protected:Npn \konewka_add_author:nnn #1 #2 #3
{
\seq_gput_right:Nn \g_konewka_authors_id_seq { #1 }
\prop_new:c { g_konewka_author_#1_prop }
\prop_gput:cnn { g_konewka_author_#1_prop } { fname } { #2 }
\prop_gput:cnn { g_konewka_author_#1_prop } { lname } { #3 }
}
\cs_new_protected:Npn \konewka_print_authors:
{
\seq_gsort:Nn \g_konewka_authors_id_seq
{
\string_compare:nnnTF {##1} {>} {##2} {\sort_reversed:} {\sort_ordered:}
}
\seq_clear:N \l__konewka_authors_full_seq
\seq_map_inline:Nn \g_konewka_authors_id_seq
{
\seq_put_right:Nx \l__konewka_authors_full_seq
{
\prop_item:cn { g_konewka_author_##1_prop } { fname }
\c_space_tl
\prop_item:cn { g_konewka_author_##1_prop } { lname }
}
}
\seq_use:Nn \l__konewka_authors_full_seq { ,~ }
}
\prg_new_conditional:Npnn \string_compare:nnn #1 #2 #3 {TF}
{
\if_int_compare:w \konewka_strcmp:nn {#1}{#3} #2 \c_zero
\prg_return_true:
\else:
\prg_return_false:
\fi
}
\ExplSyntaxOff
\begin{document}
\addauthor{John}{Doe}
\addauthor{Harry}{Potter}
\addauthor[Uthor]{Archibald}{\"Uthor}
\addauthor{Bill}{Clinton}
\addauthor{Barack}{Obama}
\printauthors
\end{document}
작성자는 \addauthor{<first name(s)>}{<last name>}
; 로 추가됩니다. 특수 문자 처리를 위해 선택적 인수가 허용됩니다. 이 선택적 인수는 속성 목록 색인화와 정렬 모두에 사용됩니다.
보다하위 섹션을 알파벳순으로 정렬또 다른 적용을 위해\seq_sort:Nn
성이 같은 두 명의 저자가 있는 경우 선택적 인수를 사용하세요. 예를 들어
\addauthor[Doe@Jane]{Jane}{Doe}
\addauthor[Doe@John]{John}{Doe}
선택적 인수는 정렬 순서를 결정합니다. ASCII 문자 앞에 오는 를 사용하면 @
두 명의 Doe 작성자가 "Doeb" 앞에 정렬된다는 것을 보장할 수 있습니다. 모든 작성자에 대해 동일한 아이디어, 즉 "lname@fname"을 정렬 키로 사용할 수 있지만 이렇게 하면 이름의 특수 문자에 문제가 발생할 수 있습니다.
정렬 키(성 또는 선택적 인수)가 이미 데이터베이스에 있는 경우 작성자를 추가하지 않는 버전은 다음과 같습니다.
\documentclass{article}
\usepackage{xparse,l3sort,pdftexcmds}
\ExplSyntaxOn
\cs_set_eq:Nc \konewka_strcmp:nn { pdf@strcmp }
\NewDocumentCommand{\addauthor}{ o m m }
{
\IfNoValueTF{#1}
{
\konewka_add_author:nnn { #3 } { #2 } { #3 }
}
{
\konewka_add_author:nnn { #1 } { #2 } { #3 }
}
}
\NewDocumentCommand{\printauthors}{ }
{
\konewka_print_authors:
}
\seq_new:N \g_konewka_authors_id_seq
\seq_new:N \l__konewka_authors_full_seq
\msg_new:nnn { konewka/authors } { author~exists }
{
The ~ author ~ #1 ~ already ~ exists; ~ it ~ won't ~ be ~ added ~ again
}
\cs_new_protected:Npn \konewka_add_author:nnn #1 #2 #3
{
\prop_if_exist:cTF { g_konewka_author_#1_prop }
{
\msg_warning:nnn { konewka/authors } { author~exists } { #1 }
}
{
\seq_gput_right:Nn \g_konewka_authors_id_seq { #1 }
\prop_new:c { g_konewka_author_#1_prop }
\prop_gput:cnn { g_konewka_author_#1_prop } { fname } { #2 }
\prop_gput:cnn { g_konewka_author_#1_prop } { lname } { #3 }
}
}
\cs_new_protected:Npn \konewka_print_authors:
{
\seq_gsort:Nn \g_konewka_authors_id_seq
{
\string_compare:nnnTF {##1} {>} {##2} {\sort_reversed:} {\sort_ordered:}
}
\seq_clear:N \l__konewka_authors_full_seq
\seq_map_inline:Nn \g_konewka_authors_id_seq
{
\seq_put_right:Nx \l__konewka_authors_full_seq
{
\prop_item:cn { g_konewka_author_##1_prop } { fname }
\c_space_tl
\prop_item:cn { g_konewka_author_##1_prop } { lname }
}
}
\seq_use:Nn \l__konewka_authors_full_seq { ,~ }
}
\prg_new_conditional:Npnn \string_compare:nnn #1 #2 #3 {TF}
{
\if_int_compare:w \konewka_strcmp:nn {#1}{#3} #2 \c_zero
\prg_return_true:
\else:
\prg_return_false:
\fi
}
\ExplSyntaxOff
\begin{document}
\addauthor{John}{Doe}
\addauthor{Harry}{Potter}
\addauthor[Uthor]{Archibald}{\"Uthor}
\addauthor{John}{Doe}
\addauthor{Bill}{Clinton}
\addauthor{Barack}{Obama}
\printauthors
\end{document}
이 파일을 실행하면 다음과 같은 경고가 생성됩니다.
*************************************************
* konewka/authors warning: "author exists"
*
* The author Doe already exists; it won't be added again
*************************************************
경고가 발생하는 대신 오류가 발생하도록 하려면 \msg_warning:nnn
다음으로 변경하세요 .\msg_error:nnn
답변2
설명을 위해 mergesort가 구현된 OPmac 매크로를 사용하여 일반 TeX에서 이 작업을 해결하는 방법을 보여줍니다.
\input opmac
\def\sort{\begingroup\setprimarysorting\def\iilist{}\sortA}
\def\sortA#1#2{\ifx\relax#1\sortB\else
\expandafter\addto\expandafter\iilist\csname,#1\endcsname
\expandafter\preparesorting\csname,#1\endcsname
\expandafter\edef\csname,#1\endcsname{{\tmpb}{#2}}%
\expandafter\sortA\fi
}
\def\sortB{\def\message##1{}\dosorting
\def\act##1{\ifx##1\relax\else \seconddata##1\sortC \expandafter\act\fi}%
\gdef\tmpb{}\expandafter\act\iilist\relax
\endgroup
}
\def\sortC#1&{\global\addto\tmpb{{#1}}}
\def\printauthors{\def\tmp{}\expandafter\printauthorsA\authors [] {} {}; }
\def\printauthorsA [#1] #2 #3; {%
\ifx^#1^\expandafter\sort\tmp\relax\relax
\def\tmp{}\expandafter\printauthorsB\tmpb\relax
\else\addto\tmp{{#1}{#2 #3}}\expandafter\printauthorsA\fi
}
\def\printauthorsB#1{\ifx\relax#1\else \tmp\def\tmp{, }#1\expandafter\printauthorsB\fi}
\def\authors{[Doe] John Doe; [Potter] Harry Potter; [Clinton] Bill Clinton;
[Uthor] Archibald \"Uthor; [Obama] Barack Obama; }
Authors: \printauthors
\bye
[괄호] 안의 데이터를 기준으로 정렬되지만, [괄호] 밖의 데이터도 인쇄됩니다. OPmac에서는 다국어 정렬 지원이 가능합니다.