![如何用 LaTeX 定义 parshape 命令?](https://linux22.com/image/237116/%E5%A6%82%E4%BD%95%E7%94%A8%20LaTeX%20%E5%AE%9A%E4%B9%89%20parshape%20%E5%91%BD%E4%BB%A4%EF%BC%9F.png)
我想用一些\parshape
命令排版一本书,例如:
\documentclass{article}
\usepackage{lipsum}
\begin{document}
\parshape=4
0.2\textwidth 0.8\textwidth
0.2\textwidth 0.8\textwidth
0.2\textwidth 0.8\textwidth
0pt \textwidth
\lipsum
\end{document}
但由于线条和宽度可能经常变化,所以我想定义这样的命令
\newcounter{foo}
\setcounter{foo}{0}
\newcommand{\MyParShape}[3]
{
\parshape=#1
\loop
#2\textwidth #3\textwidth
\addtocounter{foo}{1}
\if\thefoo<#1-1\repeat
0pt \textwidth
}
所以我可以这样称呼它
\MyParShape{5}{0.5}{0.5}
或者
\MyParShape{10}{0.8}{0.2}
但这不起作用,我不是 TeX 原语的专家,有人可以帮忙吗?
答案1
正如 Harald 所说,这里的关键是你需要扩展所有内容。你可以在临时变量中执行此操作,正如他所展示的那样。或者,你可以使用类似可扩展的 '重复n次' 方法。这里,我假设 e-TeX 可用
\documentclass{article}
\usepackage{lipsum}
\makeatletter
\newcommand*\replicate[1]{%
\expandafter\replicate@aux\romannumeral\number\numexpr #1\relax000Q{}
}
\newcommand*\replicate@aux[1]{\csname replicate@aux@#1\endcsname}
\newcommand\replicate@aux@m{}
\long\def\replicate@aux@m#1Q#2#3{\replicate@aux#1Q{#2#3}{#3}}
\newcommand\replicate@aux@Q[2]{#1}
\DeclareRobustCommand*\MyParShape[3]{%
\parshape = #1
\replicate{#1 -1}{#2\textwidth #3\textwidth}%
0pt\textwidth
}
\newcommand*\my@parshape{}
\makeatother
\begin{document}
\MyParShape{3}{0.6}{0.4}
\lipsum
\end{document}
答案2
如果你需要的段落形状是这样的,那么使用
\hangindent=.2\textwidth \hangafter=-3
答案3
你的方法不起作用的原因是它在 TeX 的嘴里没有完全展开。现在构建一个完全可扩展的版本可能相当复杂。更简单的方法可能是首先构建一个包含完成的命令序列\parshape
和执行该命令的命令序列。在下面的完整示例中,我使用了一个令牌寄存器:
\documentclass{article}
\usepackage{lipsum}
\newtoks\pstoks
\newcounter{pscnt}
\makeatletter
\newcommand{\parshapestart}[1]{\pstoks{\parshape=#1 }}
\newcommand{\parshapeappend}[1]{\pstoks\expandafter{\the\pstoks#1}}
\newcommand{\parshapeadd}[3]
{
\setcounter{pscnt}{0}
\loop
\parshapeappend{#2\textwidth #3\textwidth}
\addtocounter{pscnt}{1}
\ifnum\c@pscnt<#1\repeat
}
\newcommand{\parshapeend}[1][0pt \textwidth]
{\parshapeappend{#1}\the\pstoks}
\makeatother
\begin{document}
\parshapestart{6}
\parshapeadd{3}{0.2}{0.8}
\parshapeadd{2}{0.1}{0.9}
\parshapeend
\lipsum
\end{document}
答案4
\documentclass{article}
\usepackage{lipsum}
\newcount\shapectr
\newcommand\myParShape[3]{%
\shapectr=0
\def\shapeLength{}
\loop
\edef\shapeLength{\shapeLength #2\textwidth #3\textwidth }
\advance\shapectr by 1
\ifnum\the\shapectr<#1\relax
\repeat
\expandafter\parshape\numexpr #1+1\relax
\shapeLength
0pt \textwidth%
}
\begin{document}
\myParShape{3}{0.2}{0.8}
\lipsum
\end{document}