1

EDIT 3: I accept the answer bellow as it resolve my problem of testing. Weirdly it did not resolve the problem when i call the function from a caption, but it is out of the scope of this question and i will open a new one for answering my specific secondary problem

I am currently tuning some functions about footnote. I try to implement a mechanism on footnotemark and footnotetext which need to test the existence of a counter with a given name.

EDIT : a way more simple minimal example is available at the botom of the post ! I have wrote this code (simplified)


%%%%%%%%%%% 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}

It's simple : in the footnotetext and in the footnotemark i test the existence of a counter created with a name that come with the argument. The idea is to create (of course) the counter if it's undifined (i have deleted these line here as they are commented in my tests).

On this simple test, the counter should have no mean to be defined as there is no "newcounter" BUT, inexplicably, the test go in the "defined" segment. (whether i call the footnotemark or footnotetext first it doesn't change anything -> it fall in both case in the defined segment. I have putted a counter in these segment to test it )

I have tested several variant of the code, with \isundifined or other macro like that, with no success. (edit : i have tested the solution proposed \ifcsname and it doesn't work neither)

I have also checked that a call to classical counter functions (like \value{}) with this name fail (logically), and it's the case.

I don't understand what could be wrong with this code. Any help would be appreciated ;)

eddi : I have included the begenning of the document (diverses package) and a minimal example inside a figure to test it. (it's a pdf_tex, you have to generate an adhoc one with inkscape i guess but i guess the test fails too outside a figure, here the fact that this is a figure seems to not be relevant in the problem). I have also commented the code to make it more clear

EDIT EDIT : NEW MINIMAL EXAMPLE (with ifcsname this time) :


%%%%%%%%%%% 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}

This code give : minimalresult

The BA and AA on the result show that the undefined bloc is never called. The 0 after BA and AA is the counter Lala which ensure that at this point the undefined bloc was never called.

4
  • 2
    Welcome to TeX.se. That's quite a bit of code. Could you please make it compilable by putting it into a complete document beginning with \documentclass and ending with \end{document}.
    – Alan Munn
    Mar 19, 2020 at 2:46
  • 2
    There are obvious mistakes such as the backslash in \stepcounter{\lalala}. It should be \stepcounter{lalala}. Maybe it is better going in smaller steps.
    – user194703
    Mar 19, 2020 at 2:48
  • @AlanMunn : i have edited the post to give a minimal example at the bottom of the post, the minimal example is compilable and i have put an image for the result Mar 19, 2020 at 11:40
  • @Schrödinger'scat : i have changed the lalala counter in the new minimal example, it didn't change the problem, the counter is still outputing 0. Mar 19, 2020 at 11:41

2 Answers 2

1

Test either with \ifcsname or with \@ifundefined. Be aware that using an undefined \csname sets it to \relax and that the two tests handles this differently:

\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}

enter image description here

12
  • Ok, but i have also tested with \@ifundefined with no success. Other comment on \@ifundefined seems to say that this defined the undefined as well with a relax in its definition.... I will try ifcsname but it was my initial solution with no luck ... Mar 19, 2020 at 10:43
  • No \@ifundefined doesn't define the command, at least not in a current latex, that was changed some years ago. Mar 19, 2020 at 10:50
  • Beside this: I have neither the time nor the will to try to extend your snippets to build a test document. Mar 19, 2020 at 10:57
  • Hum, i will try to make a more minimal example ... Mar 19, 2020 at 11:17
  • I have made a new minimal example at the bottom of the code, it is wayyyy smaller and reproduce the problem with your ifcsname :) Mar 19, 2020 at 11:42
1

It occurred to me that if \meaning can tell the difference between a counter and a macro, one could simply test the output of \meaning. That turned out to be more difficult than I anticipated.

\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}

demo

2
  • Thanks for the precision ! Have you a specific idea for the inside of a caption ? I have noticed that if the function are called from the inside of a caption, the function are called twice, which is awfull when it come to conditionnal assignement/testing ... Mar 22, 2020 at 1:48
  • This was intended as a demonstration of principle, not a working macro. I really don't get where you are going with this, but it seemed like an interesting problem. As for captions, IIRC something sets \let\label=\@gobble in the TOC, besides one can always use the optional [short caption]. You will also note that the \meaning test works even when the name is undefined, so you can skip the \@ifundefined test. Mar 22, 2020 at 2:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .