加载几何包后更改几何形状

加载几何包后更改几何形状

我查看了一些相关问题但无法解决这个问题。

我有一个通用的 LaTeX 文件,我将这个geometry包加载到其中。

此文件(pre.tex此处称为)是加载许多包的通用站点范围文件。这些选项适用于站点上的几乎所有文件,但有时一个文件需要不同的几何选项。

因此我想在输入这个常见的 LaTeX 文件后更改几何设置。

我正在回答卸载 LaTeX 包但它给了我一个错误。这是一个 MWE:

\documentclass[11pt,titlepage]{article}%    
\makeatletter
\@namedef{geometry.sty}{}% a fake for a "loaded" package
\makeatother

\input{pre} %this has in it \usepackage{geometry} with some options

% I want to override common file and load geometry 
% with different options here
\usepackage[letterpaper,bindingoffset=0.2in,
            left=1.2in,right=1.2in,top=.8in,bottom=.8in,
            footskip=.25in]{geometry}

\begin{document}    
test    
\end{document}

pre.tex 刚刚那条线在哪里

\usepackage[letterpaper,bindingoffset=0.2in,left=2in,right=2in]{geometry}

错误lualatex file.tex来自

(/usr/local/texlive/2018/texmf-dist/tex/generic/ifxetex/ifxetex.sty))

! LaTeX Error: Option clash for package geometry.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...

l.12

?

奇怪的是,这个可以工作并且可以编译

\documentclass[11pt,titlepage]{article}%
\makeatletter
\@namedef{geometry.sty}{}% a fake for a "loaded" package
\makeatother

\input{pre} %this has in it \usepackage{geometry} 

\usepackage{geometry}

\begin{document}
test
\end{document}

所以只有当我想使用geometry与原始加载不同的选项再次加载时才会失败?

geometry一旦加载,包括加载时使用的任何选项,正确的删除方法是什么,以便如果特定文件想要使用不同的选项,他们可以使用不同的选项重新加载几何图形?

使用 TL 2018

答案1

很可能总是欺骗 LaTeX 允许你加载包两次不是一个好主意。即使你设法通过取消定义来实现这一点(我不会展示如何实现——虽然这很容易——这样人们就不会责怪我教这个 :),你也会得到一长串其他错误,例如\[email protected]

! LaTeX Error: Command \Gm@vrules@mpi already defined.
               Or name \end... illegal, see p.192 of the manual.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.927   \llap{\Gm@vrule}\hfil\Gm@vrule}}
                                        %
?

因为包不应该被加载两次,所以他们使用\newcommand,我们都知道这不会起作用两次。

也就是说,对于这种几何情况,您可以将选项传递给命令\geometry

\geometry{letterpaper,bindingoffset=0.2in,
          left=1.2in,right=1.2in,top=.8in,bottom=.8in,
          footskip=.25in}

来自手册:

\geometry{<options>}根据参数中指定的选项更改页面布局。此命令(如果有)应仅放置在前言中(之前\begin{document})。

几何包可以用作类的一部分或您在文档中使用的另一个包。该命令\geometry可以覆盖序言中的某些设置。允许多次使用\geometry,然后使用连接的选项进行处理。如果几何尚未加载,则只能使用而\usepackage[<options>]{geometry}不是\geometry

对于更一般的情况,我建议将您的代码变成pre.tex一个包pre.sty并向其中添加一些选项。例如,这是我在编写的一个类中所做的,该类具有预定义值但允许用户覆盖它们:

\RequirePackage{filecontents}
\begin{filecontents}{pre.sty}

\ProvidesPackage{pre}[2018-09-17 Nasser's geometry package]

% I'm using kvoptions, but you can adapt to your favorite keyval package
\RequirePackage{kvoptions}

% First pass options -- Here only the "interface" option will be declared
\SetupKeyvalOptions{%
  family=nasser@first,%
  prefix=nasser@@%
}
% Create the interface option
\DeclareStringOption{interface}

% Temporarily redefine \KV@errx to allow "undefined" options
\let\nasser@KVerr\KV@errx
\let\KV@errx\@gobble
% Process the interface option. Every other option is left untouched
\ProcessLocalKeyvalOptions{nasser@first}
\let\KV@errx\nasser@KVerr% Restore \KV@errx

% Now we can set the main option list of the package
\SetupKeyvalOptions{%
  family=nasser@main,%
  prefix=nasser@% Different prefix than before!
}

% Create a dummy interface option just to satisfy the option parser -- won't be used anywhere
\DeclareStringOption{interface}

% By now we have \nasser@@interface, a comma-separated list of package names

% Then, for each <package>, we create an option <package> and another force<package>
\@for\pkg:=\nasser@@interface\do{% (notice that for interface, the prefix is nasser@@ -- two @s)
  \DeclareStringOption{\pkg}% Soft option
  \DeclareStringOption{force\pkg}% Hard option
}%

% Now the user has passed the options and we can
\ProcessKeyvalOptions{nasser@main}

% Now the fun part begins :)
% We have three option lists to pass for a package:
%  - The "soft" option from the interface;
%  - The package default and;
%  - The "hard" option from the interface
% and we are going to pass them in that order to respect their hierarchy

% First, the soft options which, if in conflict with the package defaults, are overridden
\@for\pkg:=\nasser@@interface\do{% Loop through every interface'd package
  \expandafter\ifx\csname nasser@\pkg\endcsname\relax% If the option wasn't used do nothing
  \else% else
    \expandafter\PassOptionsToPackage\expandafter{% \PassOptionsToPackage
      \csname nasser@\pkg\endcsname}% {soft,option,list}
      {\pkg}% {package}
  \fi
}

% Now we insert the package defaults
\PassOptionsToPackage{letterpaper,bindingoffset=0.2in,left=2in,right=2in}{geometry}

% And finally, the hard options which can override package defaults
\@for\pkg:=\nasser@@interface\do{% Loop through every interface'd package
  \expandafter\ifx\csname nasser@force\pkg\endcsname\relax% If the option wasn't used do nothing
  \else% else
    \expandafter\PassOptionsToPackage\expandafter{% \PassOptionsToPackage
      \csname nasser@force\pkg\endcsname}% {hard,option,list}
      {\pkg}% {package}
  \fi
}

% And finally load the package
\RequirePackage{geometry}
\endinput

\end{filecontents}
\documentclass[11pt,titlepage]{article}
\usepackage[%
  interface=geometry,%
  forcegeometry={%
    letterpaper,bindingoffset=0.2in,%
    left=1.2in,right=1.2in,top=.8in,bottom=.8in,%
    footskip=.25in%
    }%
  ]{pre}
% With \usepackage{pre}
% * h-part:(L,W,R)=(144.54pt, 310.76125pt, 144.54pt)
% * v-part:(T,H,B)=(95.39737pt, 556.47656pt, 143.09605pt)

% With \geometry
% * h-part:(L,W,R)=(86.72377pt, 426.39369pt, 86.72377pt)
% * v-part:(T,H,B)=(57.81621pt, 679.33757pt, 57.81621pt)

% With geometry option
% * h-part:(L,W,R)=(144.54pt, 310.76125pt, 144.54pt)
% * v-part:(T,H,B)=(57.81621pt, 679.33757pt, 57.81621pt)

% With forcegeometry option
% * h-part:(L,W,R)=(86.72377pt, 426.39369pt, 86.72377pt)
% * v-part:(T,H,B)=(57.81621pt, 679.33757pt, 57.81621pt)

\geometry{verbose}% Just to show settings in the log
\begin{document}
test
\end{document}

基本上,这会设置包加载,以便包中每个包都有一个默认选项列表,用户可以将尊重包默认值的附加选项传递给该包,并且还可以覆盖这些默认值(如果他们明确要求的话)。

代码很长,因为它允许与任意数量的包交互,并允许这种三级层次结构。但对于你的情况,只有一个包,没有层次结构(即任何选项都会覆盖包的默认值),它可以简化为:

\RequirePackage{filecontents}
\begin{filecontents}{pre.sty}

\ProvidesPackage{pre}[2018-09-17 Nasser's geometry package]

% I'm using kvoptions, but you can adapt to your favorite keyval package
\RequirePackage{kvoptions}

% Define the family and prefix for the options
\SetupKeyvalOptions{%
  family=nasser,%
  prefix=nasser@%
}%

% Decalre a "geometry" option
\DeclareStringOption{geometry}

% Process input option list
\ProcessKeyvalOptions*

% Now we insert the package defaults
\PassOptionsToPackage{letterpaper,bindingoffset=0.2in,left=2in,right=2in}{geometry}

% Then pass the package options to geometry
\PassOptionsToPackage{\nasser@geometry}{geometry}

% And finally load the package
\RequirePackage{geometry}
\endinput

\end{filecontents}
\documentclass[11pt,titlepage]{article}
\usepackage[%
  geometry={%
    letterpaper,bindingoffset=0.2in,%
    left=1.2in,right=1.2in,top=.8in,bottom=.8in,%
    footskip=.25in%
    }%
  ]{pre}

% With \usepackage{pre}
% * h-part:(L,W,R)=(144.54pt, 310.76125pt, 144.54pt)
% * v-part:(T,H,B)=(95.39737pt, 556.47656pt, 143.09605pt)

% With \geometry
% * h-part:(L,W,R)=(86.72377pt, 426.39369pt, 86.72377pt)
% * v-part:(T,H,B)=(57.81621pt, 679.33757pt, 57.81621pt)

% With geometry option
% * h-part:(L,W,R)=(86.72377pt, 426.39369pt, 86.72377pt)
% * v-part:(T,H,B)=(57.81621pt, 679.33757pt, 57.81621pt)

% \geometry{letterpaper,bindingoffset=0.2in,
%           left=1.2in,right=1.2in,top=.8in,bottom=.8in,
%           footskip=.25in}

\geometry{verbose}% Just to show settings in the log
\begin{document}
test
\end{document}

相关内容