\newglossaryentry에 \ifglsused 용어집을 사용하여 중첩된 조건부 용어집

\newglossaryentry에 \ifglsused 용어집을 사용하여 중첩된 조건부 용어집

다른 용어집 용어를 기반으로 하거나 관련된 용어집 항목을 조건부로 확장하려는 경우 조건문이 \ifglsused{}{}{}매우 유용하다는 것을 알았습니다.

상위 용어가 아직 사용되지 않은 경우 상위 수정 사항을 만족시키기 위해 \glsdisp{}{}전제 조건이 '사용'되지만 처음 사용할 때 프로그래밍된 대로 표시되지는 않는지 확인하는 데 사용합니다.

\ifglsused{TNF}{\glsdisp{TNF}{\TNFalpha}}{\glsdisp{TNF}{tumor necrosis factor--\textalpha~(\TNFalpha)}}아래 MWE의 항목 에서 설명한 것처럼 정상적으로 작동합니다.

흥미롭게도 이 동일한 평가는 하위 용어 자체의 선언 \newglossaryentry{}내부에 있는 경우 실패합니다.first={}

MWE:

\documentclass{article}
\usepackage[utf8]{inputenc}

\setlength\parindent{0pt}

%=========================================================================================================================================
% PACKAGES REQUIRED FOR GLOSSARIES
%=========================================================================================================================================

% Glossaries must be loaded before amsmath as per details in the following forum answer
% https://tex.stackexchange.com/questions/85696/what-causes-this-strange-interaction-between--and-amsmath
\usepackage[nogroupskip,toc,acronym]{glossaries} % must come after href   
\usepackage{scrwfile}%http://www.dickimaw-books.com/cgi-bin/faq.cgi?action=view&categorylabel=glossaries#glsnewwriteexceeded
\usepackage{siunitx,microtype,textcomp,textgreek}
\usepackage{etoolbox}
\makeglossaries

\newglossaryentry{TNF}{ 
    type={acronym}, 
    sort={tumor necrosis factor},  
    name={TNF}, 
    short={TNF}, 
    long={tumor necrosis factor}, 
    first={tumor necrosis factor (TNF)}, 
    description={tumor necrosis factor}     
}

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{ 
    type={acronym}, 
    sort={tumor necrosis factor alpha},  
    name={TNF--{\textalpha}}, 
    short={TNF--{\textalpha}}, 
    long={tumor necrosis factor alpha}, 
    first={\ifglsused{TNF}{\glsdisp{TNF}{\TNFalpha}}{\glsdisp{TNF}{tumor necrosis factor--\textalpha~(\TNFalpha)}}}, 
    description={tumor necrosis factor alpha}
}

\begin{document}

    \begin{itemize}
        %\item \gls{TNFalpha}
        \item \gls{TNF}
        \item \gls{TNFalpha}
        \item \glsentryfirst{TNFalpha}
        \item \ifglsused{TNF}{\glsdisp{TNF}{\TNFalpha}}{\glsdisp{TNF}{tumor necrosis factor--\textalpha~(\TNFalpha)}}
    \end{itemize}

\end{document} 

업데이트: 새 용어집 키(기본을 지정하는)와 용어집 항목 생성과 독립적으로 동일한 사용 및 표시 논리를 수행하는 새 함수를 만들어 이 문제를 해결했습니다. 내가 이것을 기반으로 한 함수 템플릿은 다음과 같습니다. 용어집에 새 필드 만들기 newglossaryentry

따라서 이 질문의 이유(중복을 최소화한 중첩된 용어집 확장)는 완전히 다른 접근 방식을 통해 해결되었으므로 여전히newglossaryentry

  • first={}나는 이것이 실제로 호출하기 전에 어떻게든 평가되고 있으므로 부울이 변경되지 않았으므로 실패 없이 영구적인 잘못된 평가를 보장한다는 것을 의미한다고 추측하고 있지만 \gls{}알아두면 좋을 것입니다.

  • 내 다음 추측은 이것이 \gls{}의 보호 상태와 관련이 있거나 심지어 코드가 평가되는 순서와 관련이 있다는 것입니다.

답변1

여기에는 두 가지 주요 문제가 있습니다.

분야 확장

로부터사용자 매뉴얼:

새 용어집 항목을 정의하면 , , name, 및 키 를 제외하고 기본적으로 확장이 수행됩니다 (이러한 키는 모두 를 통해 확장이 억제됩니다 ).descriptiondescriptionpluralsymbolsymbolpluralsort\glssetnoexpandfield

(이러한 예외의 이유는 해당 정보를 용어집 파일에 기록하는 데 사용된 이전 버전과의 호환성 때문입니다. 확장 억제는 쓰기 프로세스에서 취약한 명령을 보호하는 데 도움이 되었습니다.)

이를 실제로 보려면 glossaries디버깅 명령을 사용할 수 있습니다.문서화된 코드, 사용자 설명서에는 없음). 필드 \showgloname의 정의를 표시하고 name, 필드 \showglofirst의 정의를 표시하고 , 필드 의 정의를 표시합니다 (각 경우에 하나의 인수가 필요하며, 이것이 항목 레이블입니다). (MWE를 줄였습니다.)first\showglotexttext

\documentclass{article}

\usepackage{textgreek}
\usepackage[nogroupskip,toc,acronym]{glossaries}
\makeglossaries

\newglossaryentry{TNF}{ 
  type={acronym}, 
  sort={tumor necrosis factor},  
  name={TNF}, 
  first={tumor necrosis factor (TNF)}, 
  description={tumor necrosis factor}
}   

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha},
    first={tumor necrosis factor alpha~(\TNFalpha)},   
    description={tumor necrosis factor alpha}
}

\begin{document}
\showglofirst{TNF}
\showglofirst{TNFalpha}

\showgloname{TNF}
\showgloname{TNFalpha}

\showglotext{TNF}
\showglotext{TNFalpha}

\end{document}

출력이 생성되지는 않지만 성적표에 정의가 표시됩니다. (TeX의 대화형 모드에서 실행될 때 이러한 명령은 마치 오류 메시지인 것처럼 실행을 중단합니다.) 다음은 기록의 관련 부분입니다.

first항목의 필드 값 TNF:

> \glo@TNF@first=macro:
->tumor necrosis factor (TNF).

first항목의 필드 값 TNFalpha:

> \glo@TNFalpha@first=macro:
->tumor necrosis factor alpha\protect \nobreakspace  {}(TNF--{\textalpha }).

따라서 여기에서는 \TNFalpha명령이 확장되었으며 깨지지 않는 공간도 있지만 ~보호 \textalpha되어 있기 때문에 확장되지 않습니다.

name항목의 필드 값 TNF:

> \glo@TNF@name=macro:
->TNF.

name항목의 필드 값 TNFalpha:

> \glo@TNFalpha@name=macro:
->\TNFalpha .

키는 기본적으로 확장되지 않기 때문에 여기서는 \TNFalpha확장되지 않았습니다 .name

text는 명시적으로 사용되지 않았으므로 필드에서 값을 가져왔지만 name이 경우 확장이 수행됩니다.

text항목의 필드 값 TNF:

> \glo@TNF@text=macro:
->TNF.

text항목의 필드 값 TNFalpha:

> \glo@TNFalpha@text=macro:
->TNF--{\textalpha }.

name필드 와 달리 \TNFalpha이제 확장되었습니다.

\ifglsused따라서 키 내에서 사용하면 first기본적으로 평가됩니다.항목이 정의되면. 위의 예가 변경되어 현재 정의는 TNFalpha다음과 같습니다.

\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha}, 
    first={\ifglsused{TNF}{\TNFalpha}{tumor necrosis factor alpha~(\TNFalpha)}}, 
    description={tumor necrosis factor alpha}
}

그런 다음 \showglofirst{TNFalpha}여전히 동일한 결과를 생성합니다.

> \glo@TNFalpha@first=macro:
->tumor necrosis factor alpha\protect \nobreakspace  {}(TNF--{\textalpha }).

이는 TNFalpha정의할 때 가 TNF사용되지 않았기 때문에 정의가 의 잘못된 부분(세 번째 인수)으로 확장되기 때문 입니다 \ifglsused.

중첩된 링크

필드에 추가 \glsdisp(또는 유사한 명령) 하면 first중첩된 링크가 생성됩니다. \glsdisp및 내부적으로 모두 \gls동일한 명령을 사용하여 \@gls@link하이퍼링크를 처리하고 링크 텍스트를 내부에 래핑합니다 \glstextformat. 따라서 이러한 명령을 중첩하면 문제가 발생할 수 있습니다.

first가장 간단한 해결책은 및 필드 에 대한 확장을 끄고 필드 값에서 firstplural제거한 후 항목을 사용된 것으로 표시하는 것입니다. 이와 같이:\glsdisp\glsunsetTNF

\documentclass{article}

\usepackage{textgreek}
\usepackage[nogroupskip,toc,acronym]{glossaries}
\makeglossaries

\newglossaryentry{TNF}{ 
  type={acronym}, 
  sort={tumor necrosis factor},  
  name={TNF}, 
  first={tumor necrosis factor (TNF)}, 
  description={tumor necrosis factor}
}   

\glssetnoexpandfield{first}
\glssetnoexpandfield{firstpl}

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha}, 
    first={\ifglsused{TNF}{\TNFalpha}{\glsunset{TNF}tumor necrosis factor alpha~(\TNFalpha)}},
    description={tumor necrosis factor alpha}
}

\begin{document}
\gls{TNFalpha}. \gls{TNF}.

\end{document} 

이는 다음을 생성합니다.

종양 괴사 인자 알파(TNF-알파). TNF.

이렇게 서로 교환하면

\gls{TNF}. \gls{TNFalpha}.

대신에

\gls{TNFalpha}. \gls{TNF}.

그럼 결과는

종양괴사인자(TNF). TNF-알파.

편집하다:새 항목이 정의될 때마다 확장 설정이 확인되지만 필드를 확장해야 하는 항목이 있는 경우에만 확장을 다시 켜면 됩니다. 예를 들어:

\newcommand{\stuff}{foo}
\newglossaryentry{stuff1}{name={\stuff},description={stuff1}}
\renewcommand{\stuff}{bar}
\newglossaryentry{stuff2}{name={\stuff},description={stuff2}}

이러한 유형의 정의는 명시적으로 수행하면 약간 이상해 보이지만 내부적으로 \newglossaryentry. 위의 예에서 항목이 정의되면 정의가 계속 변경되는 임시 명령이므로 \stuff확장해야 합니다 . \stuff이러한 상황이 발생하지 않으면 \glsetnoexpandfield항목 정의를 시작하기 전에 모든 명령을 입력하면 됩니다.

대소문자 변경

첫 글자 대문자는 다음과 같은 \Gls용도 \makefirstuc로 제공됩니다.mfirstuc. 이 명령은 인수에 형식 지정 명령이 포함될 수 있는 가능성을 처리하려고 시도하지만 명령의 구문, 특히 인수가 텍스트인지 레이블인지를 결정하는 일반적인 방법이 없기 때문에 \makefirstuc몇 가지 제한 사항을 순서대로 적용해야 합니다. 제대로 작동하려면.

  1. 인수가 로 시작하면 \protect이를 버리고 \makefirstuc나머지에 적용됩니다. 예를 들어 \makefirstuc{\protect\textbf{foo}}는 와 같습니다 \makefirstuc{\textbf{foo}}.
  2. 인수는 \makefirstuc텍스트만으로 시작할 수 있습니다. 예를 들어 , 결과 \makefirstuc{foo}\MakeUppercase fooFoo입니다. 반면 에 Foo가 발생 \makefirstuc{{fo}o}합니다 .\MakeUppercase{fo}o
  3. 의 인수가 \makefirstuc인수 없이 제어 시퀀스로 시작하는 경우 해당 제어 시퀀스는 \ae또는 와 같은 문자 제어 시퀀스로 간주되며 \o대소문자 변경이 적용됩니다. 예를 들어, \makefirstuc{\ae foo}does \MakeUppercase\ae foowhich 결과는 Æfoo입니다. 이는 다음을 의미합니다.

    \newcommand{\foo}{foo}\makefirstuc{\foo}
    

    FOO를 생산 합니다 \MakeUppercase\foo.

  4. 인수가 \makefirstuc제어 시퀀스로 시작하고 그 뒤에 그룹이 오는 경우 제어 시퀀스는 형식 지정 명령으로 간주됩니다. 그룹화된 자료는 텍스트로 간주하여 대소문자 변경이 적용됩니다. 예를 들어, 다음과 같은 결과가 \makefirstuc{\textbf{foo}}나옵니다 .\textbf{\MakeUppercase foo}에프아.

\makefirstuc단일 인수를 사용하는 간단한 텍스트 블록 명령이 구문 분석하기에는 너무 복잡한 명령으로 확장될 수 있으므로 인수에 대해서는 확장이 수행되지 않습니다 .

\Gls{TNFalpha}처음 사용(또는 \Glsfirst{TNFalpha}) 시도 시 MWE로 돌아가기

\makefirstuc{\ifglsused{TNF}{\TNFalpha}{\glsunset{TNF}tumor necrosis
factor alpha~(\TNFalpha)}}

이는 사례 4(그룹이 뒤따르는 제어 순서)에 속합니다. 그래서 이것은 다음을 시도합니다

{\ifglsused{\MakeUppercase TNF}{\TNFalpha}{\glsunset{TNF}tumor necrosis 
factor alpha~(\TNFalpha)}}

이것이 오류 메시지의 원인입니다. 문제를 해결하는 유일한 방법은 첫 번째 인수가 대소문자 변경이 필요한 텍스트인 명령을 정의하는 것입니다. 예를 들어:

% \ifnotused{not used}{used}{label}
\newcommand*{\ifnotused}[3]{%
  \ifglsused{#3}{#2}{\glsunset{#3}#1}%
}

\newcommand{\TNFalpha}{TNF--{\textalpha}}
\newglossaryentry{TNFalpha}{
    type={acronym},
    sort={tumor necrosis factor alpha},
    name={\TNFalpha}, 
    first={\ifnotused{tumor necrosis factor alpha~(\TNFalpha)}{\TNFalpha}{TNF}},
    description={tumor necrosis factor alpha}
}

이미 대문자로 시작 하므로 조건부 in이 두 번째 인수를 선택하는 \TNFalpha경우를 처리하는 것에 대해 걱정할 필요가 없습니다 .\ifnotused

관련 정보