编辑 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}