测试计数器的存在莫名其妙地失败了

测试计数器的存在莫名其妙地失败了

编辑 3:我接受下面的答案,因为它解决了我的测试问题。奇怪的是,当我从标题调用该函数时,它并没有解决问题,但这超出了这个问题的范围,我将开一个新问题来回答我特定的次要问题

我目前正在调整一些关于脚注的功能。我尝试在 footnotemark 和 footnotetext 上实现一种机制,该机制需要测试具有给定名称的计数器是否存在。

编辑:在帖子的底部提供了一种更简单的最小示例! 我已经写了这个代码(简化)


%%%%%%%%%%% LOT OF PACKAGES AND DEFINITIONS %%%%%%%%%%
\pdfobjcompresslevel 0

\documentclass[a4paper,12pt,oneside,final, DIV=12, listof=totoc, bibliography=totoc, toc=bibliography, open=right, chapterprefix=true]{scrbook}

\usepackage[usenames,dvipsnames]{xcolor}
\usepackage[greek,english,french]{babel}
\def\frenchtablename{Tableau} 
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{pdfpages}
\usepackage{xspace}
\usepackage[final]{hyperref}
\usepackage{footnotehyper}
\usepackage{footnotebackref}
\usepackage{tablefootnote}

\usepackage{enumitem}
\setuptoc{toc}{totoc}
\usepackage{etoc, blindtext}

\rmfamily
\DeclareFontShape{T1}{lmr}{b}{sc}{<->ssub*cmr/bx/sc}{}
\DeclareFontShape{T1}{lmr}{bx}{sc}{<->ssub*cmr/bx/sc}{}
\usepackage[backend=biber,natbib=true, style=authoryear, autopunct=false, uniquename=false, uniquelist=false, mincitenames=1,maxcitenames=2,bibencoding=utf8, maxbibnames=99]{biblatex}
\usepackage{csquotes}
\usepackage[automark, headsepline, footsepline,plainfootsepline, plainheadsepline]{scrlayer-scrpage}
\pagestyle{scrheadings}
\usepackage{bookmark}
\usepackage{lipsum}
\usepackage{graphicx}
\graphicspath{ {images/} }
\usepackage[format=plain, font=small, labelfont=bf, textfont=it]{caption}
\usepackage{floatrow}
\usepackage{pifont}
\usepackage{placeins}
\usepackage{wrapfig}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{import}
\usepackage{subcaption}
\DeclareMathOperator{\e}{e}
\usepackage[french,onelanguage,noend]{algorithm2e}
\usepackage{amsmath,eqparbox,xintexpr}
\usepackage{nccmath}
\usepackage[float=false]{scrhack}
\usepackage{siunitx}
\sisetup{
  locale=FR,
  detect-all,
  output-decimal-marker={,},
  group-minimum-digits = 3,
  group-separator={\,},
  number-unit-product={\,},
  group-digits = integer,
  inter-unit-product=\ensuremath{{\cdot}},
%  tight-spacing=true,
}
\renewcommand*{\dictumauthorformat}[1]{#1}
\DeclareUnicodeCharacter{2212}{-}
\makeatletter
\newcommand\footnoteref[1]{\protected@xdef\@thefnmark{\ref{#1}}\@footnotemark}
\makeatother
\let\oldfootref\footref
\renewcommand{\footref}[1]{\,\oldfootref{#1}}
\usepackage{perpage}
\MakePerPage{footnote}

%%%%%%%%%%% LOT OF PACKAGES AND DEFINITIONS END %%%%%%%%%%

%%%%%%%%%%% BEGENNING OF THE WORK ON FOOTNOTES %%%%%%%%%%

%%% Counter for making unique ID for the footnotemark and footnotetext without [] %%%%%%
\newcounter{myHyperFootnoteCounterMARK}

%%%%% Counter for testing in which branch of testing we go  %%%%%%
\newcounter{lalala}

%%%%% WE change the definition of the two function to redefine them  %%%%%%
\let\oldfootnotetext\footnotetext
\let\oldfootnotemark\footnotemark
%
\makeatletter


%%%%% we use \@ifnextchar to switch between a case with optionnal argument (detection [ ) and a case with no optionnal argument to have two behaviour very different  %%%%%%
\renewcommand{\footnotetext}{\@ifnextchar[\my@OptHyperFootnotetext\my@HyperFootnotetext}

%%%%% part of the command without optionnal argument, it works, no change neededd %%%%
\newcommand{\my@HyperFootnotetext}[1]{%
    \def\myFootnoteTagtext{hfu:\themyHyperFootnoteCounterMARK}%
\oldfootnotetext{\hyperref[\myFootnoteTagtext]{$\uparrow$}~#1}
}

%%%%% define an new footnote with optional argument : the IF never reach the undefined case, the counter "lala" is never incrememented and "BA" is only shown in the text : i have tested diverses formulation \@ifundefined \ifcsname etc etc... %%%%%
\newcommand{\my@OptHyperFootnotetext}[2][plop]{
    \def\myFootnoteTagtextARGU{hfoi:#1}
    \def\mysavee{saved@Href@#1}

    \expandafter\ifx\csname c@counter@Href:#1\endcsname\undefined
    AB\thefootnote\theHfootnote
    \expandafter\let\expandafter\Hy@footnote@currentHref\csname\mysavee\endcsname
    \oldfootnotetext{\hyperref[\myFootnoteTagtextARGU]{$\uparrow$}~#2}
    \stepcounter{lalala}
    \else 
    \thelalala
    AA\thefootnote\theHfootnote
    \expandafter\let\expandafter\Hy@footnote@currentHref\csname\mysavee\endcsname%
    \oldfootnotetext{\hyperref[\myFootnoteTagtextARGU]{$\uparrow$}~#2}%
    \fi
}



%%%%% Same thing for footnotemark %%%%%
\renewcommand{\footnotemark}{\@ifnextchar[\my@OptHyperFootnotemark\my@HyperFootnotemark}%
%%%%% part of the command without optionnal argument, it works, no change needed %%%%
\newcommand{\my@HyperFootnotemark}{%
    \refstepcounter{myHyperFootnoteCounterMARK}%
    \def\myFootnoteTagtext{hfu:\themyHyperFootnoteCounterMARK}%
    \label{\myFootnoteTagtext}%
\oldfootnotemark%
}

%%%%% define an new footnote with optional argument : the IF never reach the undefined case, the counter "lala" is never incrememented and "BA" is only shown in the text : i have tested diverses formulation \@ifundefined \ifcsname etc etc... %%%%%

\newcommand{\my@OptHyperFootnotemark}[1][plop]{%
    \def\myFootnoteTagtextargu{hfoi:#1}%
    \def\mysave{saved@Href:#1}%
    \expandafter\ifx\csname c@counter@Href:#1\endcsname\undefined 
    BB\thefootnote\theHfootnote
    \label{\myFootnoteTagtextargu}
    \oldfootnotemark \global\expandafter\let\csname\mysave\endcsname\Hy@footnote@currentHref%
    \stepcounter{lalala}
    \else
    \thelalala
    BA\thefootnote\theHfootnote
    \label{\myFootnoteTagtextargu}
    \oldfootnotemark \global\expandafter\let\csname\mysave\endcsname\Hy@footnote@currentHref%
    \fi
}
%
\makeatother



%%%%%%% some package %%%%%%%
\KOMAoptions{DIV=last}

%%%%%% begin %%%%%%%
\begin{document}
\frontmatter


%%%%%% TEST %%%%%%

\chapter{TEST}
\section{Introduction}

BLALALALALALALALALALALA
BLALALALALALALALALALALA
BLALALALALALALALALALALA
BLALALALALALALALALALALA
BLALALALALALALALALALALA

%\makeatletter
\begin{figure}[ht]
   \centering
   {
     \begin{floatrow}[1]
        \ffigbox[\FBwidth]{\caption[Tino]{\label{Tino} The captionnnnnnnnnnnnnnn \footnotemark[truc] The captionnnnnnnnnnnnnnnPart2
 .}}
{\fbox{\def\svgwidth{0.9\textwidth}\import{images/part1/tino/}{tino_maineps.pdf_tex}}}.
     \end{floatrow}
   }
\end{figure}

\footnotetext[truc]{testfootnote}% 

\end{document}

很简单:在脚注文本和脚注标记中,我测试了使用参数附带的名称创建的计数器的存在性。想法是(当然)如果计数器未定义,则创建它(我已删除此处的这些行,因为它们在我的测试中被注释掉了)。

在这个简单的测试中,计数器不应该被定义,因为没有“新计数器”,但是,令人费解的是,测试进入了“已定义”段。(无论我先调用脚注标记还是脚注文本,它都不会改变任何东西 -> 在两种情况下它都属于已定义的段。我已经在这些段中放了一个计数器来测试它)

我已经使用 \isundifined 或其他类似的宏测试了几种代码变体,但均未成功。(编辑:我已经测试了建议的解决方案 \ifcsname,但它也不起作用)

我还检查过,调用具有此名称的经典计数器函数(如 \value{})会失败(逻辑上),事实确实如此。

我不明白这段代码可能出了什么问题。如能提供任何帮助我将不胜感激 ;)

eddi:我已经包含了文档的开头(diverses 包)和一个图形中的最小示例来测试它。(这是一个 pdf_tex,我猜你必须用 inkscape 生成一个临时的,但我猜测试在图形之外也会失败,这里这是一个图形的事实似乎与问题无关)。我还对代码进行了注释以使其更清晰

编辑编辑:新的最小示例(这次带有 ifcsname):


%%%%%%%%%%% LOT OF PACKAGES AND DEFINITIONS %%%%%%%%%%
\pdfobjcompresslevel 0

\documentclass[a4paper,12pt,oneside,final, DIV=12, listof=totoc, bibliography=totoc, toc=bibliography, open=right, chapterprefix=true]{scrbook}

\usepackage[greek,english,french]{babel}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[final]{hyperref}
\usepackage{footnotehyper}
\usepackage{footnotebackref}
\usepackage{tablefootnote}
\usepackage{amssymb}

\usepackage{perpage}
\MakePerPage{footnote}

%%%%%%%%%%% LOT OF PACKAGES AND DEFINITIONS END %%%%%%%%%%

%%%%%%%%%%% BEGENNING OF THE WORK ON FOOTNOTES %%%%%%%%%%

%%% Counter for making unique ID for the footnotemark and footnotetext without [] %%%%%%
\newcounter{myHyperFootnoteCounterMARK}
%%%%% Counter for testing in which branch of testing we go  %%%%%%
\newcounter{lalala}
%
\makeatletter

%%%%% define an new footnote with optional argument : the IF never reach the undefined case, the counter "lala" is never incrememented and "BA" is only shown in the text : i have tested diverses formulation \@ifundefined \ifcsname etc etc... %%%%%
\newcommand{\myOptHyperFootnotetext}[2][plop]{
    \def\myFootnoteTagtextARGU{hfoi:#1}
    \def\mysavee{saved@Href@#1}
    %
    \ifcsname c@counter@Href:#1\endcsname
    % CASE UNDEFINED
    AB\stepcounter{lalala}
    %
    \expandafter\let\expandafter\Hy@footnote@currentHref\csname\mysavee\endcsname
    \oldfootnotetext{\hyperref[\myFootnoteTagtextARGU]{$\uparrow$}~#2}
    %
    \else 
    % CASE DEFINED
    AA\thelalala
    %
    \expandafter\let\expandafter\Hy@footnote@currentHref\csname\mysavee\endcsname%
    \footnotetext{\hyperref[\myFootnoteTagtextARGU]{$\uparrow$}~#2}%
    %
    \fi
}

\newcommand{\myOptHyperFootnotemark}[1][plop]{%
    \def\myFootnoteTagtextargu{hfoi:#1}%
    \def\mysave{saved@Href:#1}%
    %
    \ifcsname c@counter@Href:#1\endcsname
    % CASE UNDEFINED
    BB\stepcounter{lalala}
    \label{\myFootnoteTagtextargu}
    %
    \oldfootnotemark \global\expandafter\let\csname\mysave\endcsname\Hy@footnote@currentHref%
    %
    \else   
    % CASE DEFINED
    BA\thelalala
    %
    \label{\myFootnoteTagtextargu}
    \footnotemark \global\expandafter\let\csname\mysave\endcsname\Hy@footnote@currentHref%
    \fi
}
%
\makeatother



%%%%%%% some package %%%%%%%
\KOMAoptions{DIV=last}

%%%%%% begin %%%%%%%
\begin{document}
\frontmatter


%%%%%% TEST %%%%%%

\chapter{TEST}
\section{Introduction}

EEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEE

\myOptHyperFootnotemark[truc]

EEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEE

\myOptHyperFootnotetext[truc]{testfootnote}% 

\end{document}

此代码提供: 最小结果

结果中的 BA 和 AA 表明未定义的 bloc 从未被调用。BA 和 AA 后面的 0 是计数器 Lala,确保此时未定义的 bloc 从未被调用。

答案1

使用\ifcsname或 使用进行测试\@ifundefined。请注意,使用未定义的 \csname 会将其设置为\relax,并且两个测试对此的处理方式不同:

\documentclass{article}

\begin{document}
\makeatletter 

\ifcsname c@counter@Href:XXX\endcsname
 defined \else undefined \fi


 \@ifundefined{c@counter@Href:XXX}
  {undefined}{defined}


\csname c@counter@Href:XXX\endcsname %sets it to \relax

\ifcsname c@counter@Href:XXX\endcsname
 defined \else undefined \fi


 \@ifundefined{c@counter@Href:XXX}
  {undefined}{defined}


\end{document}

在此处输入图片描述

答案2

我突然想到,如果\meaning能区分计数器和宏,就可以简单地测试一下 的输出\meaning。结果比我预想的要困难得多。

\documentclass{article}
\usepackage{xstring}

\makeatletter
\newcommand{\testcounter}[1]% name
{\bgroup
  \@ifundefined{c@#1}{not defined}{defined} -
  \StrCompare{\expandafter\meaning\csname c@#1\endcsname}{\meaning\c@page}[\pos]%
  \ifnum\pos=7
    counter
  \else
    \ifnum\pos=0
      page counter
    \else
      not a counter
    \fi
  \fi
\egroup\par}

\def\c@test{test}% fake counter
\makeatother

\begin{document}
foo: \testcounter{foo}

figure: \testcounter{figure}

page: \testcounter{page}

test: \testcounter{test}

\end{document}

演示

相关内容