为了满足我们公司设计的要求,我需要在每份文件的第一页上留出其他边距。正常的页面布局如下
\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}{}{}{}{}{}{}{}