هل هناك طريقة للتحقق مما إذا كانت التسمية محددة بالفعل في LaTeX؟

StackOverflow https://stackoverflow.com/questions/495841

  •  20-08-2019
  •  | 
  •  

سؤال

لقد قمت بتحرير السؤال بعد إجابة ديفيد هاناك (شكرًا للشغل!).لقد ساعدني في بناء الجملة، ولكن يبدو أنني لم أستخدم الوظيفة الصحيحة في البداية.

ما أريده بشكل أساسي هو السماح للمترجم بتجاهل تعريفات متعددة لتسمية معينة واستخدام الأول فقط.من أجل القيام بذلك، اعتقدت أنني سأفعل شيئًا مثل هذا:

    \makeatletter
    \newcommand{\mylabel}[1]{
        \@ifundefined{#1}{\label{#1}}{X}
    }
    \makeatother

لكن هذا لا ينجح، لأنه يتم اختيار الخيار الأول دائمًا (لا يهم إذا تم تعريف التسمية أم لا).أعتقد أن \@ifunidentified (و\ifunidentified المقترحة) تعمل فقط للأوامر وليس للتسميات، لكنني لا أعرف الكثير عن LaTeX.أي مساعدة مع هذا أن تكون كبيرة!شكرًا!

التحديث في وقت لاحق بكثير:لقد حددت إجابة ديفيد هاناك باعتبارها الإجابة الصحيحة على سؤالي، ولكنها ليست حلاً كاملاً، على الرغم من أنها ساعدتني حقًا.المشكلة هي، على ما أعتقد ولكنني لست متخصصًا، أنه على الرغم من أن كود David يتحقق لمعرفة ما إذا تم تعريف التسمية، إلا أنه يعمل فقط عندما يتم تعريف التسمية في تشغيل سابق (أي.موجود في ملف .aux).إذا تم تعريف اثنين من التصنيفات \mylabels بنفس الاسم في نفس التشغيل، فسيظل الثاني محددًا.أيضًا، حتى إذا تمكنت من التغلب على هذا الأمر، فسيجعل LaTeX يستخدم التسمية الأولى التي حددتها بتسلسل زمني، وليس بالضرورة الأولى في النص.على أي حال، فيما يلي الحل السريع والقذر.إنه يستخدم حقيقة أن العدادات تبدو محددة على الفور.

\newcommand{\mylabel}[1]{%
    \@ifundefined{c@#1}{%
        \newcounter{#1}%
        \setcounter{#1}{0}%
    }{}%
    \ifthenelse{\value{#1} > 0}{}{%
        \label{#1}%
        \addtocounter{#1}{1}%
    }%
}

لست متأكدًا مما إذا كان من الضروري تهيئة العداد إلى 0، حيث يبدو أنه افتراضي على الأرجح، لكن لم أتمكن من معرفة ما إذا كان هذا هو الحال، لذلك أنا آمن فقط.يستخدم هذا أيضًا الحزمة "ifthen"، والتي لست متأكدًا من أنها ضرورية.

هل كانت مفيدة؟

المحلول

@ هي شخصية خاصة في LaTeX.لجعل إعلانك صحيحًا من الناحية النحوية، سيتعين عليك إضافة سطرين آخرين:

\makeatletter
\newcommand{\mylabel}[1]{
    \@ifundefined{#1}{\label{#1}}{X}
}
\makeatother

يتحول السطر الأول @ إلى حرف عادي، فإن السطر الأخير يعكس تأثيره.

تحديث: قد ترغب أيضًا في إلقاء نظرة على "السهل" \ifundefined ماكرو لاتيكس.

تحديث 2

حسنًا، لقد قمت ببعض الأبحاث لمعرفة الإجابة على السؤال حقيقي مشكلة.المشكلة هي أن تعريف التسمية لا يؤدي إلى إنشاء ماكرو بهذا الاسم؛فهو يسبقه "r@".لذا حاول ما يلي:

\makeatletter
\newcommand{\mylabel}[1]{
    \@ifundefined{r@#1}{\label{#1}}{X}
}
\makeatother

لمزيد من التفاصيل الفنية، راجع السطر 3863 من latex.ltx في توزيع LaTeX الخاص بك (حيث يُذكر \def\newlabel{\@newl@bel r}).

نصائح أخرى

وأنا أيضا لست خبيرا اللثي، ولكن بعد يوم واحد من محاولة والبحث في الإنترنت ما يلي عملت بالنسبة لي. ولقد استخدمت عداد همية لحل المشكلة. نأمل أن يساعد هذا، على ما يبدو الكثير من الناس لا يبحثون عن ذلك.

\newcommand{\mylabel}[1]{
    \ifcsname c@#1\endcsname%
    \else%
        \newcounter{#1}\label{#1}%
    \fi%
}

وفيكتور Eijkhout "تكس حسب الموضوع"، p.143:

\def\ifUnDefinedCs#1{\expandafter\ifx\csname#1\endcsname\relax} 

وهذه يمكن استخدامها للتحقق ما إذا تم تعريف التسمية. إذا لم يكن كذلك، تتم طباعة التسمية:

\newcommand{\myautoref}[1]{\ifUnDefinedCs{r@#1}{\color{magenta}\IDontKnow\{#1\}}\else\autoref{#1}\fi} 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top