さまざまな費用のコストがさまざまな場所に記載されている大きな文書があるとします。これらのコストが記載されているすべてのポイントで、コスト自体だけでなく、まだ利用可能な予算の概要も表示したいと思います。ドキュメントに示されているすべてのコスト、およびドキュメント内でそれ以降に表示されるコストを考慮します。
ムウェ
\documentclass{article}
\usepackage{hyperref}
\makeatletter
\newcommand\mylabel[2]{\def\@currentlabel{#2}\phantomsection\label{mylabel:#1}}
\newcommand\myref[1]{\ref{mylabel:#1}}
\makeatother
\newcounter{FixMoney}
\setcounter{FixMoney}{1000}
\newcounter{SaveValue}
\setcounter{SaveValue}{\value{FixMoney}}
\makeatletter
\newcommand{\calcCosts}[1]{%
\bgroup
\newcount\PP
\PP=#1 %Piece Price
\setcounter{SaveValue}{\inteval{\value{SaveValue}-\the\PP}}%
\mylabel{overall}{\the\value{SaveValue}}Piece price:\,\the\PP\,€ / Money left overall \myref{overall}\,€)
\egroup}
\makeatother
\makeatletter
\begin{document}
\calcCosts{3}\\
\calcCosts{30}\\
\calcCosts{400}
\end{document}
出力はまさに私が期待し、達成したい内容です。左側に何かのコスト、右側に残りの予算があります。
しかし
次の警告が表示されます。
ラベル「mylabel:overall」が複数定義されています。
\label
ここで、この目的で使用するという私のアプローチが本当に正しいのか、あるいは同じ機能を別の方法で実現できるのかという疑問が生じます。
答え1
おそらく、オプションの引数を使用してハイパーリンクのアンカーを配置する場所を指定し、相互参照ラベルが必要な処理を実行するメカニズムです。
(必要なのは、欧州委員会のユーロ記号 ( \euro
eurosym をロードした後) ではなく、European Computer Modern Fonts のユーロ記号のようです。)
\documentclass{article}
% \euro - euro-symbol which complies to the symbol suggested and
% and copyrighted(!) by the European Commission -
% <https://european-union.europa.eu/institutions-law-budget/euro/design_en> :
\usepackage{eurosym}
% In correspondence
% <https://chat.stackexchange.com/transcript/message/63127536#63127536>
% David Carlisle revealed:
% Euro-symbol of European Computer Modern Fonts (ec - Computer
% modern fonts in T1 and TS1 encodings <https://www.ctan.org/tex-archive/fonts/ec>);
% in other words: Joerg Knappen's guess of what the euro symbol would be:
\newcommand\CMReuro{{%
\fontfamily{cmr}\fontencoding{TS1}\selectfont
\symbol{191}%
%\texteuro
}}
\usepackage{hyperref}
\makeatletter
\ExplSyntaxOn\@ifundefined{inteval}{\cs_new_eq:NN \inteval \int_eval:n}{}\ExplSyntaxOff
%--Basic Infrastructure----------------------------------------------------
\newcommand\InitializeNewKindOfBudget[2]{%
\@bsphack
\expandafter\@ifdefinable\expandafter{\csname(BudgetNameSpace)#1\endcsname}{%
\expandafter\protected@xdef\csname(BudgetNameSpace)#1\endcsname{\inteval{(#2)}}%
}%
\@esphack
}%
\newcommand\ReduceBudget[2]{%
\@bsphack
\expandafter\protected@xdef\csname(BudgetNameSpace)#1\endcsname{%
\inteval{(\csname(BudgetNameSpace)#1\endcsname)-(#2)}%
}%
\@esphack
}%
\newcommand\CurrentBudget[1]{\csname(BudgetNameSpace)#1\endcsname}%
\newcommand\Budgetlabel[2]{%
\@bsphack\begingroup
\Hy@localanchornametrue
\phantomsection
\protected@edef\@currentlabel{\csname(BudgetNameSpace)#1\endcsname}%
\label{#2}%
\endgroup\@esphack
}
%--Infrastructure for your scenario----------------------------------------
\InitializeNewKindOfBudget{MoneyForPieces}{1000}%
\NewDocumentCommand{\calcCosts}{om}{%
% #1 label to create; #2 amount of money to withdraw from MoneyForPieces.
\ReduceBudget{MoneyForPieces}{#2}%
\IfNoValueF{#1}{\Budgetlabel{MoneyForPieces}{#1}}%
Piece price:\,#2\,\CMReuro\ / Money left currently \CurrentBudget{MoneyForPieces}\,\CMReuro\ / Money left overall \ref*{overall}\,\CMReuro)
}%
\makeatother
\begin{document}
\noindent Budget total: \CurrentBudget{MoneyForPieces}\\
\calcCosts{3}\\
\calcCosts{30}\\
\calcCosts[overall]{400}
% Be aware that the outcome both of the command \texteuro and the unicode-
% character € is engine-dependent and differs depending on whether using
% latex, pdflatex, xelatex or lualatex and and may probably also vary
% between different LaTeX-releases.
\LARGE
\noindent
\verb|\euro|: \euro / \verb|\texteuro|: \texteuro / \verb|\CMReuro|: \CMReuro / \verb|€|: €
\end{document}
TeX Live 2020 で LuaLaTeX を使用してコンパイルすると、次のようになります。
整数だけでなく浮動小数点数で計算したい場合、非常に基本的な簿記のためのいくつかの非常に基本的なルーチンがここにあります:
\documentclass{article}
\usepackage{zref}
\usepackage{siunitx}
\usepackage{hyperref}
% \euro - euro sign which complies to the symbol suggested and
% and copyrighted(!) by the European Commission -
% <https://european-union.europa.eu/institutions-law-budget/euro/design_en> :
\usepackage{eurosym}
% Euro sign of European Computer Modern Fonts (ec - Computer
% modern fonts in T1 and TS1 encodings <https://www.ctan.org/tex-archive/fonts/ec>);
% in other words: Joerg Knappen's guess of what the euro sign would be:
\newcommand\CMReuro{{%
\fontfamily{cmr}\fontencoding{TS1}\selectfont
\symbol{191}%
%\texteuro
}}
\makeatletter
% A variant of \zref@setcurrent which sets properties globally
\ZREF@Robust\def\zref@setcurrentglobal#1#2{%
\zref@propexists{#1}{%
\expandafter\gdef\csname Z@C@#1\endcsname{#2}%
}%
}%
\ExplSyntaxOn
%
%--Generic infrastructure--------------------------------------------------
%
\cs_new_protected_nopar:Npn \InitializeNewPostingAccount #1#2{
\@bsphack
\zref@newprop{PostingAccount#1}{0}
\exp_args:Nnf
\zref@setcurrentglobal{PostingAccount#1}{\fp_to_decimal:n{(#2)}}
\@esphack
}%
\cs_new_protected_nopar:Npn \WithdrawFromPostingaccount #1#2 {
\@bsphack
\exp_args:Nnf
\zref@setcurrentglobal{PostingAccount#1}{
\fp_to_decimal:n{(\zref@getcurrent{PostingAccount#1})-(#2)}
}
\@esphack
}%
\cs_new_protected_nopar:Npn \SaldoOfPostingAccount #1 {
\fp_to_decimal:n {(\zref@getcurrent{PostingAccount#1})}
}
\cs_new_protected_nopar:Npn \RecordSaldoOfPostingAccountToLabel #1#2 {
\zref@labelbyprops{#2}{PostingAccount#1}
}
\cs_new_protected_nopar:Npn \ReferToRecordedSaldoOfPostingAccount #1#2#3 {
\zref@ifrefundefined{#2}
{\use_ii:nn}
{\zref@ifrefcontainsprop{#2}{PostingAccount#1}{\use_i:nn}{\use_ii:nn}}
{\PrintAmountOfMoney{\zref@extractdefault{#2}{PostingAccount#1}{0}}{#3}}
{\zref@refused{#2}\textsf{??}}
}
\cs_new_protected_nopar:Npn \PrintAmountOfMoney #1#2 {
\exp_args:Nne
\use:n {\SI [{% Adjust this according to your needs and the
% conventions in your country - refer to the
% documentation of siunitx:
add-decimal-zero,
add-integer-zero,
detect-mode=true,
round-integer-to-decimal=true,
round-mode=places,
round-half=up,
group-digits=true,
group-minimum-digits=2,
group-separator=\,,
output-decimal-marker={,},
round-precision={#2}}]}
{\fp_to_decimal:n{round(((#1)+0),#2,NaN)}}{\CMReuro}
}
%
%--Infrastructure for your scenario----------------------------------------
%
\InitializeNewPostingAccount{MoneyForPieces}{1000.24}%
\cs_new_protected_nopar:Npn \WithdrawFromMoneyForPieces #1 {
\WithdrawFromPostingaccount{MoneyForPieces}{#1}
Piece~price:\nobreakspace
\PrintAmountOfMoney{#1}{2}\nobreakspace/~
Money~left~currently~\PrintAmountOfMoney{\SaldoOfPostingAccount{MoneyForPieces}}{2}\nobreakspace/~
Money~left~overall~\ReferToRecordedSaldoOfPostingAccount{MoneyForPieces}{overall}{2})
}
\cs_new_protected_nopar:Npn\RecordFinalMoneyForPiecesSaldoToLabel {
\RecordSaldoOfPostingAccountToLabel{MoneyForPieces}{overall}
}
\ExplSyntaxOff
\makeatother
\begin{document}
\noindent
\begin{minipage}{1.1\textwidth}
\noindent Budget total: \PrintAmountOfMoney{\SaldoOfPostingAccount{MoneyForPieces}}{2}\\
\WithdrawFromMoneyForPieces{3.24}\\
\WithdrawFromMoneyForPieces{30}\\
\WithdrawFromMoneyForPieces{400}%
\RecordFinalMoneyForPiecesSaldoToLabel
\end{minipage}
% Be aware that the outcome both of the command \texteuro and the unicode-
% character € is engine-dependent and differs depending on whether using
% latex, pdflatex, xelatex or lualatex and and may probably also vary
% between different LaTeX-releases.
\LARGE
\bigskip
\noindent
Some different euro sign-notations yielding different symbols:
\noindent
\verb|\euro|: \euro/ \verb|\texteuro|: \texteuro/ \verb|\CMReuro|: \CMReuro/ \verb|€|: €
\end{document}
TeX Live 2020 で pdfLaTeX を使用してコンパイルすると、次のようになります。
答え2
全体の値は、ドキュメントの最後に 1 回だけ保存します。リンクは生成しません。全体の値に関連付けられた場所がないため、あまり意味がありません。コマンド内で新しいカウンターを割り当てないでください。カウンターは常にグローバルに割り当てる必要があります。
\documentclass{article}
\usepackage{hyperref}
\newcounter{FixMoney}
\setcounter{FixMoney}{1000}
\newcounter{SaveValue}
\setcounter{SaveValue}{\value{FixMoney}}
\newcommand{\calcCosts}[1]{%
\setcounter{SaveValue}{\inteval{\value{SaveValue}-#1}}%
Piece price:\,#1\,€ / (Money left overall \ref*{mylabel:overall}\,€)}
\makeatletter
\AddToHook{shipout/lastpage}{{\def\@currentlabel{\the\value{SaveValue}}\label{mylabel:overall}}}
\makeatother
\begin{document}
\calcCosts{3}\\
\calcCosts{30}\\
\calcCosts{400}
\end{document}