假设有一份大型文件,其中不同费用的成本列在不同的地方。在列出这些成本的每个地方,我不仅希望有成本本身,而且还希望有关于还有多少预算可用的概览。考虑文件中指出的所有成本,包括文件中出现在其后面的成本。
平均能量损失
\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 之后),而是来自欧洲计算机现代字体。)
\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
仅在文档末尾存储一次总值。我不会生成链接,因为没有与总值相关联的位置,所以这没有多大意义。不要在命令中分配新计数器,计数器应始终全局分配。
\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}