在 xelatex 中使用“几何”设置正确的自定义页面大小时出现问题

在 xelatex 中使用“几何”设置正确的自定义页面大小时出现问题

我正在尝试使用包设置页面大小,geometry如下面的 MWE 所示,并使用以下命令进行编译xelatex test.tex

\documentclass[12pt]{article}

\usepackage[b5paper,pass]{geometry}
\geometry{b5paper}
\usepackage{tikz,enumitem}

\usepackage{fix-cm}

\usepackage{fontspec}
\defaultfontfeatures{Ligatures=TeX}
\setmainfont{Junicode}

\usepackage{layouts}

\usepackage{etoolbox}
\patchcmd{\drawpage}{\ifdrawparameters}{\iftrue}%
  {\typeout{^^J*******\string\drawpage fixed*******^^J}}%
  {\typeout{^^J*******\string\drawpage not fixed*******^^J}}

\usepackage{lipsum}



\begin{document}

\lipsum[1]

\end{document}

如果我尝试使用pdfinfo(在 Ubuntu 上)检查页面大小,我会得到美国信件的大小(?!):

$ pdfinfo -box -f 1 -l 1 test.pdf | grep Page
Pages:          1
Page    1 size: 612 x 792 pts (letter)
Page    1 MediaBox:     0.00     0.00   612.00   792.00
Page    1 CropBox:      0.00     0.00   612.00   792.00
Page    1 BleedBox:     0.00     0.00   612.00   792.00
Page    1 TrimBox:      0.00     0.00   612.00   792.00
Page    1 ArtBox:       0.00     0.00   612.00   792.00

但是,如果我输入b5paper-\documentclass[b5paper,12pt]{article}那么我也可以删除所有其他对geometry使用的引用b5paper- 因为当我使用该更改进行编译时,我得到:

$ pdfinfo -box -f 1 -l 1 test.pdf | grep Page
Pages:          1
Page    1 size: 498.9 x 708.66 pts
Page    1 MediaBox:     0.00     0.00   498.90   708.66
Page    1 CropBox:      0.00     0.00   498.90   708.66
Page    1 BleedBox:     0.00     0.00   498.90   708.66
Page    1 TrimBox:      0.00     0.00   498.90   708.66
Page    1 ArtBox:       0.00     0.00   498.90   708.66

...(我猜)这对应于正确的 B5 措施。

 

现在,据我所知,geometry只要这些更改是在之前发布的\begin{document},就应该能够更改纸张尺寸,对吗?如果是这样,为什么在这里不起作用?

我很困惑,因为我想用geometry这种方式设置一些自定义页面大小(因此我无法将其传播到命令\documentclass)。

在此先非常感谢关于如何在此示例中设置自定义页面大小的任何建议,
干杯!

答案1

geometry好吧,最后,我想我已经能够在文档中间切换自定义页面大小和页面布局了(MWE 如下((MWE 在下面(另见上一篇geometrypass);点击图片查看完整尺寸):

首先,关于几何说几句话:

  • 您可以致电\geometry 仅有的在序言中,有多个命令只是替换先前设置的参数值
  • geometry首先计算布局(边距等) \begin{document},手册中称之为布局 L1
  • 该命令\restoregeometry只能恢复L1!
  • 该命令\newgeometry可以仅有的叫做 \begin{document}因此,在 L1 创建之后
  • 使用创建的布局\newgeometry可以\save/ \loadgeometry-ied
  • \newgeometry不是关心\paperwidth/ height!事实上,如果你认为你可以作弊:
    \setlength{\paperwidth}{100mm}
    \setlength{\paperheight}{100mm}
    \newgeometry{两侧,...}
    geometry会关心一点也不,并且实际上会将 paperwidth/height 重置回 documentclass 设置(或者我猜,geometry如果有的话,是最后命名的页面大小设置)。
  • 然而,geometry 考虑称为layoutwidth和的参数layoutheight,它们起到页面大小限制的作用。

因此,如何计算边距与/geometry中的实际页面设置无关。考虑到所有这些,可以提交以下清单来管理自定义页面大小和布局:\paperwidth\pdfpagewidth

  • 在序言中准备自定义页面大小作为新长度
  • 在序言命令中做好准备\generatePageLayouts\switchToLayoutPageA并且\switchToLayoutPageB
  • 之后\begin{document},首先调用\generatePageLayouts,不使用\paperwidth/进行任何实际的页面大小切换\pdfpagewidth
    • 它将调用\newgeometry/layoutwidth设置height为相应的自定义页面大小新长度,然后\savegeometry
  • 然后\switchToLayoutPageA排版内容
    • 它将使用\paperwidth/进行实际的页面切换\pdfpagewidth,并调用相应的loadgeometry
  • 然后\switchToLayoutPageB排版内容
    • 它会 -- || --

请注意,即使\loadgeometry重置\paperwidth/ height- 也可以在图像上看到,在由生成的表格中layouts:据报告,在两个都页面,即:\paperwidth = 614.295pt- 即使两个页面都不是该大小:

$ pdfinfo -box -f 1 -l 2 test.pdf | grep Page
Pages:          2
Page    1 size: 300 x 400 pts
Page    2 size: 400 x 500 pts

无论如何,这里是 MWE,编译如下xelatex test.tex

\documentclass{article}
% reminder: US letter: 596pt x 795pt

\newlength{\pagewidthA}
\newlength{\pageheightA}
\setlength{\pagewidthA}{300bp}
\setlength{\pageheightA}{400bp}

\newlength{\pagewidthB}
\newlength{\pageheightB}
\setlength{\pagewidthB}{400bp}
\setlength{\pageheightB}{500bp}

\newlength{\stockwidth}
\newlength{\stockheight}


\usepackage{geometry}

% these seem to have NO effect in preamble!
% geometry first has effect after begin{document}!
\pdfpagewidth=\pagewidthA \pdfpageheight=\pageheightA % to enforce?
\paperwidth=\pagewidthA \paperheight=\pageheightA     % for TikZ
\stockwidth=\pagewidthA \stockheight=\pageheightA % hyperref (memoir)?!

% this command will take effect into L1 layout just after \begin{document}
\geometry{twoside,inner=50bp,outer=30bp,top=50bp,bottom=50bp}


\usepackage{tikz,enumitem}
\usepackage{fix-cm}

\usepackage{fontspec}
\defaultfontfeatures{Ligatures=TeX}
\setmainfont{Junicode}

\usepackage{layouts}

\usepackage{etoolbox}
\patchcmd{\drawpage}{\ifdrawparameters}{\iftrue}%
  {\typeout{^^J*******\string\drawpage fixed*******^^J}}%
  {\typeout{^^J*******\string\drawpage not fixed*******^^J}}

\usepackage{lipsum}



\makeatletter
\newcommand{\printpagevalues}{%
  % from geometry.sty:
  * paper: \ifx\Gm@paper\@undefined<default>\else\Gm@paper\fi \\%
  * layout: \ifGm@layout<custom>\else<same size as paper>\fi \\%
  \@ifundefined{ifGm@layout}{}{%
  \ifGm@layout
  * layout(width,height): (\the\Gm@layoutwidth,\the\Gm@layoutheight) \\%
  \fi
  * layoutoffset:(h,v)=(\the\Gm@layouthoffset,\the\Gm@layoutvoffset) \\%
  }%
  \pagevalues % from package layouts
}
\makeatother

\newcommand{\generatePageLayouts}{%
  % this command must be called after \begin{document}!

  % geometry needs layoutwidth - cause it ignores the above paper sizes!
  % layoutwidth=148mm ok, layoutwidth=\paperwidth NOT ok
  % paperwidth gets reset again internally in newgeometry: in log: *geometry* verbose mode: * layout(width,height): (614.295pt,794.96999pt)
  % but by using \stockwidth, which here is just a custom length: * layout(width,height): (421.10078pt,597.50787pt)

  \newgeometry{layoutwidth=\pagewidthA,layoutheight=\pageheightA,left=1mm,right=5mm,bottom=1mm,top=1mm}
  \savegeometry{LayoutPageA}

  \newgeometry{layoutwidth=\pagewidthB,layoutheight=\pageheightB,twoside,inner=2.5cm,outer=0.5cm,top=1.5cm,bottom=1.5cm}
  \savegeometry{LayoutPageB}
}

\newcommand{\switchToLayoutPageA}{%
  % doesn't include page sizes; so page size too:
  \pdfpagewidth=\pagewidthA \pdfpageheight=\pageheightA % for PDF output
  \paperwidth=\pagewidthA \paperheight=\pageheightA     % for TikZ
  \stockwidth=\pagewidthA \stockheight=\pageheightA % hyperref (memoir)?!
  \loadgeometry{LayoutPageA} % note; \loadgeometry may reset paperwidth/h!
}

\newcommand{\switchToLayoutPageB}{%
  % doesn't include page sizes; so page size too:
  \pdfpagewidth=\pagewidthB \pdfpageheight=\pageheightB % for PDF output
  \paperwidth=\pagewidthB \paperheight=\pageheightB     % for TikZ
  \stockwidth=\pagewidthB \stockheight=\pageheightB % hyperref (memoir)?!
  \loadgeometry{LayoutPageB} % note; \loadgeometry may reset paperwidth/h!
}

\fontspec[Scale=1.0]{Junicode}



\begin{document}
  % here geometry layout L1 is instantiated;
  % without anything else, paper size defaults to US letter!
  % \restoregeometry command restores L1!!

  \fontsize{8}{9}\selectfont % this nowork in preamble!


  % generate page layouts first based on layoutwidth as page size;
  % don't switch actual page sizes yet:
  \generatePageLayouts{}


  %%% start with content

  % start with LayoutPageA (includes switching page size)
  \switchToLayoutPageA{}


    \pagestyle{empty} % no page numbers here
    \\
     \the\paperwidth
    \lipsum[1]
    \printpagevalues{}
    \clearpage

  % switch to LayoutPageB (includes switching page size)
  \switchToLayoutPageB{}


    % start page numbering here ("this will reset the page number"):
    \pagenumbering{arabic}
    % make page numbers visible
    \pagestyle{plain}


    \the\paperwidth
    \lipsum[1]

    Trying

    some

    text

    \printpagevalues{}

\end{document}

最后,上面的图像是这样生成的:

convert -density 150 -bordercolor LimeGreen -border 2 test.pdf[0] test1.png
convert -density 150 -bordercolor LimeGreen -border 2 test.pdf[1] test2.png
montage test1.png test2.png -geometry +2+2 -tile 2x1 test.png

好吧,希望这对某人有帮助,
干杯!

答案2

编辑 2:好的,我想我终于意识到了罪魁祸首,那就是包pass的选项geometry。事实证明,只要pass选项出现在geometry调用中 - 无论它是在选项中\usepackage[...]{geometry},还是在\geometry{pass}之前的调用中\begin{document}- 它都会“杀死”您可能在那里设置的任何边距设置,并恢复为 documentclass 所设置的任何设置,显然(因此,显然b5paper在 \usepackage[b5paper,pass]{geometry} 中包含下面的选项集与后续的pass)。

例如,我尝试使用以下代码设置边距(如下面代码所示):

\usepackage[pass,paperwidth=\classpagewidth,paperheight=\classpageheight,twoside,inner=1cm,outer=2cm,top=1cm,bottom=1cm]{geometry}

... 但什么也没起作用 - 因为pass就在那里!

知道了这一点,现在我可以geometry用以下代码替换相关命令:

\usepackage{geometry}
\geometry{pass,twoside,inner=1cm,outer=2cm,top=1cm,bottom=1cm}

...一切似乎都运行良好。

最后请注意,虽然我们不能使用\geometry{pass}after \begin{document}- 我们可以使用\newgeometry{pass}there; 在这种情况下,pass似乎不会如此大幅度地恢复所有页面长度。

顺便说一句,使用pass那里是因为修复了使用 xelatex 将整页 Tikz 图像置于页面上且无边距?


好的,我想我终于找到了某种 hack/解决方案/理解;基本上,似乎上述示例中的页面大小设置作为包的一部分被忽略了geometry,必须明确设置页面大小(如 hack 中所示)在文档中间更改纸张尺寸以及其他地方)。

在下面的例子中 - 请注意,页面大小的明确设置,即使它发生在geometry加载之前,似乎也不会受到加载geometry选项的影响:

\documentclass[12pt]{article}


\newlength{\classpageheight}
\newlength{\classpagewidth}
\newlength{\stockwidth}\newlength{\stockheight}

% since here page size stuff may get ignored,
% set explicitly custom page size
\setlength{\classpagewidth}{290pt}
\setlength{\classpageheight}{360pt}
\pdfpagewidth=\classpagewidth \pdfpageheight=\classpageheight % to enforce?
\paperwidth=\classpagewidth \paperheight=\classpageheight     % for TikZ
\stockwidth=\classpagewidth \stockheight=\classpageheight % hyperref (memoir)?!

\usepackage[b5paper,pass]{geometry}
\geometry{b5paper}


\usepackage{tikz,enumitem}

\usepackage{fix-cm}

\usepackage{fontspec}
\defaultfontfeatures{Ligatures=TeX}
\setmainfont{Junicode}

\usepackage{layouts}

\usepackage{etoolbox}
\patchcmd{\drawpage}{\ifdrawparameters}{\iftrue}%
  {\typeout{^^J*******\string\drawpage fixed*******^^J}}%
  {\typeout{^^J*******\string\drawpage not fixed*******^^J}}

\usepackage{lipsum}



\begin{document}

\lipsum[1]

\end{document}

请注意,在示例中,我\stockwidth仅因为定义了layouts它而对其进行了定义(否则出于中的目的memoir) - 这会导致hyperref包 hyperref 警告:页面高度 (\stockheight) 无效 (0.0pt),( hyperref) 使用 11in。

如果我使用它来构建它xelatex test.tex,然后检查页面大小,我会得到:

$ pdfinfo -box -f 1 -l 1 test.pdf | grep Page | grep size
Page    1 size: 288.92 x 358.66 pts

值得注意的是,我以为我要求的是 290 x 360 pts 页面;但pdfinfo显示大小实际上是 288.92 x 358.66 pts。结果发现,我需要的是“大点”(bp)LaTeX 长度单位- 所以如果我重写:

\setlength{\classpagewidth}{290bp}
\setlength{\classpageheight}{360bp}

...然后确实pdfinfo报告了请求的大小:

$ pdfinfo -box -f 1 -l 1 test.pdf | grep Page | grep size
Page    1 size: 290 x 360 pts

 

但仍然不确定这是否是应该做的事情...干杯!

相关内容