输入内部输入和@的问题

输入内部输入和@的问题

我正在一个包中工作并且想要创建库,例如tikz及其usetikzlibrary

但是,当我@在私有宏名中使用时,当一个库使用另一个宏名时我会出现错误。

这是我的 MWE(说明如下):

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[brazilian]{babel}

% hack to make filecontents overwrite
\makeatletter
\let\oldfilec@ntents\filec@ntents
\gdef\filec@ntents{\filec@ntents@overwrite\oldfilec@ntents}
\makeatother


\begin{filecontents}{libraryone.tex}
    \def\@libonevar{lib 1 variable with @}
    \def\libonefunction{\@libonevar}
    \def\libonevar{lib 1 variable without @}
    \def\liboneotherfunction{\libonevar}
\end{filecontents}

\begin{filecontents}{librarytwo.tex}
    \loadlibrary{libraryone}
    \def\@libtwovar{lib 2 variable}
    \def\libtwofunction{\libonefunction}
    \def\libtwootherfunction{\liboneotherfunction}
\end{filecontents}
    

\begin{filecontents}{mypackage.sty}
    \def\@pkgvar{pkg variable}
    \def\pkgfuncion{\@pkgvar}
    \newcommand{\loadlibrary}[1]{
        \input{#1}
}
\end{filecontents}

\usepackage{mypackage}

\begin{document}
From package: \pkgfuncion

\loadlibrary{libraryone}
From library one: \libonefunction\ and \liboneotherfunction

\loadlibrary{librarytwo}
From library one: \libonefunction\ and \liboneotherfunction % \libonefunction fails!

\end{document}

如果我加载libraryone,我能够同时使用\libonefunctionliboneotherfunction。但是,如果我加载librarytwo,加载的libraryone\liboneotherfunctions停止工作,并显示类似“@ 的使用与其定义不符。来自库一:\libonefunction。”\liboneotherfunction一直运转良好。

如果我删除所有@问题就会消失,现在,我真的更喜欢继续使用它@来处理私人事务。

我读过类似这样的文章何时应使用 \input 和 \include?但我没有发现@其中存在宏名的问题。

有没有什么办法可以避免这个问题?

编辑

即使在@egreg 和@Ulrich Diez 回答之后,我的问题仍然存在。

这是我当前的实际代码(由于我认为\IfFileExists可能存在另一个问题,因此使用了 TeX 原语):

% usedslibrary: load libraries
\newcommand{\ds@loadlibrary}[1]{%
    \ifcsname ds@library#1loaded\endcsname%
        %\PackageWarning{dsdraw}{Library '#1' already loaded.}%
    \else%
        \openin15={#1.code.tex}%
        \ifeof15%
            \PackageWarning{dsdraw}{Couldn't find any library named '#1'.}%
        \else%
            \closein15%
            \makeatletter%
            \input{#1.code.tex}%
            %\makeatother%
            \expandafter\def\csname ds@library#1loaded\endcsname{defined}%
        \fi%
    \fi%
}

答案1

只需将 -command 嵌套在..\input之间:\makeatletter\makeatother

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[brazilian]{babel}


\begin{filecontents*}[overwrite,nosearch]{libraryone.tex}
\def\@libonevar{lib 1 variable with @}%
\def\libonefunction{\@libonevar}%
\def\libonevar{lib 1 variable without @}%
\def\liboneotherfunction{\libonevar}%
\end{filecontents*}

\begin{filecontents*}[overwrite,nosearch]{librarytwo.tex}
\loadlibrary{libraryone}%
\def\@libtwovar{lib 2 variable}%
\def\libtwofunction{\libonefunction}%
\def\libtwootherfunction{\liboneotherfunction}%
\end{filecontents*}
    

\begin{filecontents*}[overwrite,nosearch]{mypackage.sty}
\def\@pkgvar{pkg variable}%
\def\pkgfuncion{\@pkgvar}%
\newcommand{\loadlibrary}[1]{%
   \makeatletter\input{#1}\makeatother %<-------
}%
\end{filecontents*}

\usepackage{mypackage}

\begin{document}
From package: \pkgfuncion

\loadlibrary{libraryone}
From library one: \libonefunction\ and \liboneotherfunction

\loadlibrary{librarytwo}
From library one: \libtwofunction\ and \libtwootherfunction

\end{document}

在此处输入图片描述

答案2

当 TeX 处理时\usepackage{mypackage},它将执行以下\makeatletter操作\input{mypackage.sty}

这确实不是发生\input。由于\loadlibrary{libraryone}只是这样做\input{libraryone},TeX 将解释第一条指令

\def\@libonevar{lib 1 variable with @}

作为控制符号的定义\@。此定义需要紧接着\@libonevar接下来\libonefunction定义为 扩展为\@libonevar

当您也执行 时\loadlibrary{librarytwo}\@会得到不同的定义,现在它要求libtwovar跟在它后面。当您现在尝试 时 \libonefunction,TeX 会将其替换为\@libonevar并想要扩展\@,而 后面跟着错误的标记。

解决方案:如果您的库文件想要在@其中定义命令名称,请执行

\newcommand{\loadlibrary}[1]{%
  \makeatletter
  \input{#1}%
  \makeatother
}

顺便说一句,进行覆盖的 hackfilecontents不再是必要的;只需调用

\begin{filecontents}[overwrite]{<filename>}

完整示例。

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[brazilian]{babel}

\begin{filecontents}[overwrite]{libraryone.tex}
\def\@libonevar{lib 1 variable with @}
\def\libonefunction{\@libonevar}
\def\libonevar{lib 1 variable without @}
\def\liboneotherfunction{\libonevar}
\end{filecontents}

\begin{filecontents}[overwrite]{librarytwo.tex}
\loadlibrary{libraryone}
\def\@libtwovar{lib 2 variable}
\def\libtwofunction{\libonefunction}
\def\libtwootherfunction{\liboneotherfunction}
\end{filecontents}
    

\begin{filecontents}[overwrite]{mypackage.sty}
\def\@pkgvar{pkg variable}
\def\pkgfuncion{\@pkgvar}
\newcommand{\loadlibrary}[1]{%
    \makeatletter
    \input{#1}%
    \makeatother
}
\end{filecontents}

\usepackage{mypackage}

\begin{document}
From package: \pkgfuncion

\loadlibrary{libraryone}
From library one: \libonefunction\ and \liboneotherfunction

\loadlibrary{librarytwo}
From library one: \libonefunction\ and \liboneotherfunction % \libonefunction fails!

\end{document}

在此处输入图片描述

相关内容