首页边距不同

首页边距不同

为了满足我们公司设计的要求,我需要在每份文件的第一页上留出其他边距。正常的页面布局如下

\usepackage[left=3cm,right=2cm,bottom=3cm,top=2cm]{geometry}

但在第一页我需要

\usepackage[left=3cm,right=4.5cm,bottom=3cm,top=2cm]{geometry}

我知道类似的命令\newgeometry,但是对于这样的事情,我需要手动插入分页符。

如何才能在第一页实现不同的页边距,而无需手动进行分页?任何技巧(例如使用wrapfig或类似的东西)都是允许的。

这是我想要使用它的 MWE:

\documentclass[parskip=half,fontsize=11pt,ngerman]{scrlttr2}
\usepackage{babel,lipsum,txfonts}
\usepackage[left=3cm,right=2cm,bottom=3cm,top=2cm]{geometry}

\setkomavar{fromaddress}{Street}
\setkomavar{yourmail}{2013-01-10}
\setkomavar{subject}{Subject}

\begin{document}

\begin{letter}{Insert a name here}
\opening{Hi,}
\lipsum
\end{letter}

\end{document}

答案1

对于单页信件或段落之间的分页符这种简单情况,我们所需要的就是

\usepackage{everyshi}
\AtNextShipout{\global\rightskip=-2.5cm\relax}

使用修改后的版本大卫的魔法可以处理段落中间分页的情况。

\makeatletter
\newlength{\textwidth@wide}
\setlength{\textwidth@wide}{\textwidth}
\addtolength{\textwidth@wide}{2.5cm}

\def\shp#1{%
\@tempcnta\z@
\loop
\advance\@tempcnta\@ne
\edef\pshape{\pshape 0pt #1 }
\ifnum\@tempcnta<\value{nlines@first}
\repeat
\advance\@tempcntb\value{nlines@first}
}

\def\reshape{%
    \@tempcntb\z@%
    \def\pshape{}
    \shp{\textwidth}\shp{\textwidth@wide}%
    \def\par{\ifhmode\\\fi\hspace*{\parindent}\ignorespaces}%
    \parshape\@tempcntb\pshape%
}
\makeatother

David 小心翼翼地将这个魔法放入一个组中,但是,我无法让它在scrlttr2字母环境内的组中工作。这意味着可能会有很多意想不到的副作用。它只会在字母环境组内使用,所以可能不会那么糟糕。为了使重塑工作,需要知道第一页有多少行。我们可以使用lineno包来执行此操作。

\usepackage[pagewise]{lineno}
\makeatletter
\newcounter{nlines@first}
\renewcommand{\@LN}[2]{\ifstrequal{#2}{0}{\stepcounter{nlines@first}}{}}
\def\LineNumber{}
\makeatother

然后我们只需要修补\opening设置行编号和重塑。

\usepackage{etoolbox}
\apptocmd{\opening}{\linenumbers\reshape}{}{}

综合起来

\documentclass[ngerman]{scrlttr2}
\usepackage{babel}
\usepackage[left=3cm,right=4.5cm,bottom=3cm,top=2cm]{geometry}
\usepackage[nopar]{lipsum}
\setlength{\parindent}{1cm}

\usepackage{everyshi}
\AtNextShipout{\global\rightskip=-2.5cm\relax}

\usepackage[pagewise]{lineno}
\makeatletter
\newcounter{nlines@first}
\renewcommand{\@LN}[2]{\ifstrequal{#2}{0}{\stepcounter{nlines@first}}{}}
\def\LineNumber{}
\makeatother

\makeatletter
\newlength{\textwidth@wide}
\setlength{\textwidth@wide}{\textwidth}
\addtolength{\textwidth@wide}{2.5cm}

\def\shp#1{%
\@tempcnta\z@
\loop
\advance\@tempcnta\@ne
\edef\pshape{\pshape 0pt #1 }
\ifnum\@tempcnta<\value{nlines@first}
\repeat
\advance\@tempcntb\value{nlines@first}
}

\def\reshape{%
    \@tempcntb\z@%
    \def\pshape{}
    \shp{\textwidth}\shp{\textwidth@wide}%
    \def\par{\ifhmode\\\fi\hspace*{\parindent}\ignorespaces}%
    \parshape\@tempcntb\pshape%
}
\makeatother

\usepackage{etoolbox}
\apptocmd{\opening}{\linenumbers\reshape}{}{}

\setkomavar{fromaddress}{Street}
\setkomavar{yourmail}{2013-01-10}
\setkomavar{subject}{Subject}

\begin{document}
\begin{letter}{My Name}
\opening{Hi,}
\lipsum[1-2]\par\lipsum[1-3]\par\lipsum[1-3]\par\lipsum[1-3]
\end{letter}
\end{document}

答案2

如果您不介意手动操作,则可以使用\rightskip和的组合\parshape。 的问题\rightskip是它将始终作用于整个段落,因此如果第二页的第一行属于从第一页开始的段落,则第二页的第一行仍会遵循错误的边距。 \parshape可以逐行处理,但您需要手动指定行数(或以某种方式自动化。

\documentclass[parskip=half,fontsize=11pt,ngerman]{scrlttr2}
\usepackage{babel,lipsum}
\usepackage[left=3cm,right=2cm,bottom=3cm,top=2cm]{geometry}
\setkomavar{fromaddress}{Street}
\setkomavar{yourmail}{2013-01-10}
\setkomavar{subject}{Subject}

\setlength{\rightskip}{2.5cm}

\begin{document}

\begin{letter}{Insert a name here}
\opening{Hi,}
\lipsum[1]
\lipsum[2]
\setlength{\rightskip}{0pt}
\parshape 8
0cm \dimexpr\textwidth-2.5cm\relax
0cm \dimexpr\textwidth-2.5cm\relax
0cm \dimexpr\textwidth-2.5cm\relax
0cm \dimexpr\textwidth-2.5cm\relax
0cm \dimexpr\textwidth-2.5cm\relax
0cm \dimexpr\textwidth-2.5cm\relax
0cm \dimexpr\textwidth-2.5cm\relax
0cm \textwidth
\lipsum[3]

\lipsum[4]
\end{letter}

\end{document}

我并不声称这是一个完美的解决方案,但也许它能给其他人提供一个可以借鉴的想法。


编辑指出仅使用\rightskip

第一页完成后重新设置右边距会更优雅。但是,如果第二页继续第一页开始的段落,您就会遇到问题:

\documentclass[parskip=half,fontsize=11pt,ngerman]{scrlttr2}
\usepackage{babel,lipsum}
\usepackage[left=3cm,right=2cm,bottom=3cm,top=2cm]{geometry}
\setkomavar{fromaddress}{Street}
\setkomavar{yourmail}{2013-01-10}
\setkomavar{subject}{Subject}

% reset \rightskip to zero when first page is done
\usepackage{everyshi}
\setlength{\rightskip}{2.5cm}
\AtNextShipout{\global\rightskip=0pt}

\begin{document}

\begin{letter}{Insert a name here}
\opening{Hi,}
\lipsum[1]
\lipsum[2]
\lipsum[3]
\lipsum[4]
\end{letter}

\end{document}

上述操作将导致第二页第一行的缩进错误。

答案3

我没有该scrlttr2课程的解决方案,但我认为如果你通过该课程找到答案letter,你应该能够让它发挥作用......

就像是

\usepackage{everyshi}
\AtNextShipout{\global\rightskip=-2.5cm\relax}

可以处理单页字母和第一个分页符出现在段落的字母的简单情况。在我看来,问题的关键是处理第一个分页符出现在段落中间的情况。大卫的回答通过定义parshape并跟踪您所在的位置来处理简单情况。如果您parshape从页面顶部开始,此解决方案非常有效。字母的问题在于页面顶部有可变数量的“内容”。对于类来说尤其如此scrlttr2,这就是我无法让它工作的原因。破坏 David 的代码来处理具有可变行数的页面(具有边距的字母类的第一页有 54 行)和可变宽度,结果为

\newlength{\textwidth@wide}
\setlength{\textwidth@wide}{\textwidth}
\addtolength{\textwidth@wide}{2.5cm}
\newcounter{nlines@first}
\setcounter{nlines@first}{54}

\def\shp#1{%
\@tempcnta\z@
\loop
\advance\@tempcnta\@ne
\edef\pshape{\pshape 0pt #1 }
\ifnum\@tempcnta<\value{nlines@first}
\repeat
\advance\@tempcntb\value{nlines@first}
}

\def\reshape{%
  \begingroup%
    \@tempcntb\z@%
    \def\pshape{}%
    \shp{\textwidth}\shp{\textwidth@wide}%
    \def\par{\ifhmode\\\fi\hspace*{\parindent}\ignorespaces}%
    \parshape\@tempcntb\pshape%
}

如果你从未使用过\opening,那么解决方案非常简单

\usepackage{etoolbox}
\apptocmd{\letter}{\reshape}{}{}
\pretocmd{\endletter}{\endgraf\endgroup}{}{}

\opening所做的远不止添加开口(例如,它添加了往返地址和日期)。要处理这个问题,我们需要撤消对环境的更改letter并修改\opening

\pretocmd{\opening}{\endgraf\endgroup}{}{}
\apptocmd{\opening}{
  \ifx\toaddress\@empty
  \else
    \expandafter\count@lines\expandafter{\toaddress}%
    \addtocounter{nlines@first}{-2}%
  \fi
  \addtocounter{nlines@first}{-4}%
  \reshape%
}{}{}
\patchcmd{\opening}{{\raggedleft\@date\par}}{\addtocounter{nlines@first}{-2}{\raggedleft\@date\par}}{}{}
\patchcmd{\opening}{\thispagestyle{empty}}{\thispagestyle{empty}\addtocounter{nlines@first}{-4}\expandafter\count@lines\expandafter{\fromaddress}}{}{}

我们定义辅助函数的地方

\newcommand{\count@lines}[1]{\@count@lines@#1\\@@@}
\long\def\@count@lines@ #1\\#2@@@{%
  \ifstrequal{#2}{}{}{%
    \addtocounter{nlines@first}{-1}%
    \@count@lines@#2@@@%
  }%
}

用于计算“收件人”和“发件人”地址的行数。

将所有内容整合到 MWE 中

\documentclass{letter}
\usepackage[left=3cm,right=4.5cm,bottom=3cm,top=2cm]{geometry}
\usepackage[nopar]{lipsum}

\setlength{\parindent}{1cm}
\usepackage{everyshi}
\AtNextShipout{\global\rightskip=-2.5cm\relax}

\usepackage{etoolbox}
\makeatletter

\newlength{\textwidth@wide}
\setlength{\textwidth@wide}{\textwidth}
\addtolength{\textwidth@wide}{2.5cm}

\newcounter{nlines@first}
\setcounter{nlines@first}{54}

\def\shp#1{%
\@tempcnta\z@
\loop
\advance\@tempcnta\@ne
\edef\pshape{\pshape 0pt #1 }
\ifnum\@tempcnta<\value{nlines@first}
\repeat
\advance\@tempcntb\value{nlines@first}
}

\def\reshape{%
  \begingroup%
    \@tempcntb\z@%
    \def\pshape{}%
    \shp{\textwidth}\shp{\textwidth@wide}%
    \def\par{\ifhmode\\\fi\hspace*{\parindent}\ignorespaces}%
    \parshape\@tempcntb\pshape%
}

\pretocmd{\opening}{\endgraf\endgroup}{}{}
\apptocmd{\opening}{
  \ifx\toaddress\@empty
  \else
    \expandafter\count@lines\expandafter{\toaddress}%
    \addtocounter{nlines@first}{-2}%
  \fi
  \addtocounter{nlines@first}{-4}%
  \reshape%
}{}{}
\patchcmd{\opening}{{\raggedleft\@date\par}}{\addtocounter{nlines@first}{-2}{\raggedleft\@date\par}}{}{}
\patchcmd{\opening}{\thispagestyle{empty}}{\thispagestyle{empty}\addtocounter{nlines@first}{-4}\expandafter\count@lines\expandafter{\fromaddress}}{}{}

\newcommand{\count@lines}[1]{\@count@lines@#1\\@@@}
\long\def\@count@lines@ #1\\#2@@@{%
  \ifstrequal{#2}{}{}{%
    \addtocounter{nlines@first}{-1}%
    \@count@lines@#2@@@%
  }%
}
\makeatother

\apptocmd{\letter}{\reshape}{}{}
\pretocmd{\endletter}{\endgraf\endgroup}{}{}

\address{W\\X\\Y\\Z}
\begin{document}
\begin{letter}{A\\B\\C\\D\\E\\F}
\opening{Hi,}
\lipsum[1-3]\par\lipsum[1-3]\par\lipsum[1-3]\par\lipsum[1-3]
\end{letter}
\end{document}

在此处输入图片描述

这个scrlttr2类的问题在于它\opening更复杂,但我认为如果你在信件开始前找到所有运出物品的高度,你可以让这种方法奏效。如果不行,你应该能够围绕这种方法创建一个不太通用的公司信头类。

答案4

它已经贬值了,但它会为你工作(因为你不使用memoir),changepage包裹

只需将第一页的内容括起来即可\begin{adjustwidth}{<leftmargin>}{<rightmargin>}\end{adjustwidth},并在左侧和右侧添加所需的额外边距。
对于您的具体问题:

\begin{adjustwidth}{}{+2.5cm}
    \lipsum
\end{adjustwidth}

更新:如果你不知道页面的结束位置(似乎是这样),你可以使用\changepage{<text height>}{<text width>}{<even-side margin>}{<odd-side margin>}{<column sep.>}{<topmargin>}{<headheight>}{<headsep>}{<footskip>}并添加页边距或更改页面上的文本限制,命令就会出现;页边距和限制将在下一页重置为文档值。
对于您的特定问题,它很简单:

\changepage{}{-2.5cm}{}{}{}{}{}{}{}

相关内容