如何用 LaTeX 定义 parshape 命令?

如何用 LaTeX 定义 parshape 命令?

我想用一些\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}

相关内容