Plain TeX: Problemas cuando \ loop para establecer parámetros para \ parshape

Dec 21 2020

Estaba intentando escribir una macro para envolver texto alrededor de una figura. Sé que está disponible en Latex y hay otro paquete, figflow para plainTex. Estoy aprendiendo a escribir el mío. Mi primer paso fue usar \ parshape para crear un área en blanco para la figura. Me quedé atrapado aquí. Defino la macro de la siguiente manera:

\newcount\ln
\def\wrap#1#2{\parshape=#1 \loop\relax\ifnum\ln<#1 0cm #2 \advance\ln by 1\repeat}

No funciona. Lo intenté \edef, que tampoco funcionó. ¿Alguien puede ayudarme? ¡Gracias!

\parshape{6}{10cm} Here is the definitive guide to the use of TeX, written by the system's creator, Donald E. Knuth. TeX represents the state of the art in computer typesetting. It is particularly valuable where the document, article, or book to be produced contains a lot of mathematics, and where the user is concerned about typographic quality. TeX software offers both writers and publishers the opportunity to produce technical text of all kinds, in an attractive form, with the speed and efficiency of a computer system. Novice and expert users alike will gain from The TeXbook the level of information they seek. Knuth warns newcomers away from the more difficult areas, while he entices experienced users with new challenges. The novice need not learn much about TeX to prepare a simple manuscript with it. But for the preparation of more complex documents, The TeXbook contains all the detail required. Knuth's familiar wit, and illustrations specially drawn by Duane Bibby, add a light touch to an unusually readable software manual. The TeXbook is the first in a five-volume series on Computers and Typesetting, all authored by Knuth
\bye

Respuestas

3 Skillmon Dec 21 2020 at 02:29

Una respuesta que muestra un bucle bastante básico con \numexpr.

Cuando esté utilizando \parshapey desee que solo se vea afectado un número específico de líneas, debe agregar una línea adicional 0cm \hsizepara volver a las líneas normales después de que \parshapehaya terminado, ya que \parshapese repetirá la última especificación para cada línea restante del párrafo.

\catcode`\@=11
\long\def\@gobble#1{}
\long\def\@secondoftwo#1#2{#2}
\def\wrap#1#2%
  {%
    \parshape=\numexpr#1+1\relax \wrap@{0}{#1}{#2} 0cm \hsize\relax
  }
\def\wrap@#1#2#3%
  {%
    \ifnum#1<#2
      0cm #3
      \expandafter\@secondoftwo
    \fi
    \@gobble{\expandafter\wrap@\expandafter{\the\numexpr#1+1}{#2}{#3}}%
  }
\catcode`\@=12

\wrap{6}{10cm} Here is the definitive guide to the use of TeX, written by the
system's creator, Donald E. Knuth. TeX represents the state of the art in
computer typesetting. It is particularly valuable where the document, article,
or book to be produced contains a lot of mathematics, and where the user is
concerned about typographic quality. TeX software offers both writers and
publishers the opportunity to produce technical text of all kinds, in an
attractive form, with the speed and efficiency of a computer system. Novice and
expert users alike will gain from The TeXbook the level of information they
seek. Knuth warns newcomers away from the more difficult areas, while he entices
experienced users with new challenges. The novice need not learn much about TeX
to prepare a simple manuscript with it. But for the preparation of more complex
documents, The TeXbook contains all the detail required. Knuth's familiar wit,
and illustrations specially drawn by Duane Bibby, add a light touch to an
unusually readable software manual. The TeXbook is the first in a five-volume
series on Computers and Typesetting, all authored by Knuth.
\bye

4 sgmoye Dec 21 2020 at 03:02

Para una aplicación relativamente simple como esta (la sangría se extiende solo a un párrafo), TeX simple ofrece \hangafter(el número de líneas a sangrar, positivo si es de la izquierda, negativo si es de la derecha, como aquí) y \hangindent(positivo si la sangría comienza después del número por el que da el número \hangafter, negativo si comienza en la línea 1); consulte The TeXbook de Knuth , página 102.

\hangafter=-6 \hangindent=-6cm
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

\bye

Para ser completo, se \wrappodría definir una macro simple (la salida es idéntica):

\def\wrap#1#2{\hangafter-#1\hangindent-#2}

\wrap{6}{6cm}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
2 egreg Dec 21 2020 at 03:49

Un simple bucle expandible en expl3; es fácil especificar el número deseado de líneas especiales en lugar de ser una sola.

\input expl3-generic

\ExplSyntaxOn

\cs_new:Npn \wrap #1 #2
 {
  \parshape
    \int_to_arabic:n { #1 + 1 } \c_space_tl % number of special lines
    \prg_replicate:nn { #1 } { 0pt~#2~ } % parameters for the special lines
    0pt~\hsize % further lines
  \ignorespaces
 }

\ExplSyntaxOff

\wrap{6}{10cm} Here is the definitive guide to the use of TeX, written by 
the system's creator, Donald E. Knuth. TeX represents the state of the art 
in computer typesetting. It is particularly valuable where the document, 
article, or book to be produced contains a lot of mathematics, and where 
the user is concerned about typographic quality. TeX software offers both 
writers and publishers the opportunity to produce technical text of all 
kinds, in an attractive form, with the speed and efficiency of a computer 
system. Novice and expert users alike will gain from The TeXbook the level 
of information they seek. Knuth warns newcomers away from the more difficult 
areas, while he entices experienced users with new challenges. The novice 
need not learn much about TeX to prepare a simple manuscript with it. But 
for the preparation of more complex documents, The TeXbook contains all 
the detail required. Knuth's familiar wit, and illustrations specially 
drawn by Duane Bibby, add a light touch to an unusually readable software 
manual. The TeXbook is the first in a five-volume series on Computers and 
Typesetting, all authored by Knuth

\bye

La macro \wrapes en sí misma expandible, por lo que puede hacer

\edef\wrapsix{\wrap{6}{10cm}}

\wrapsix Here is the definitive guide to the use of TeX, written by
the system's creator, Donald E. Knuth. TeX represents the state of the art
in computer typesetting. It is particularly valuable where the document,
article, or book to be produced contains a lot of mathematics, and where
[...]

y definir varias formas de este tipo al principio.

1 wipet Dec 21 2020 at 05:00

OpTeX admite \fornumcomandos expandibles , por lo que otro enfoque es usar este \fonrumcomando dentro de los \parshapeparámetros. Pero OpTeX no es TeX simple puro, es TeX simple extendido:

\def\wrap#1#2{\parshape \numexpr#1+1\relax\space \fornum 1..#1\do{0cm#2}0cm\hsize}

\wrap{6}{10cm}\lipsum[1]
\bye
1 wipet Dec 21 2020 at 04:53

Otro enfoque es: preparar una lista de \parshapeparámetros antes de \parshapeejecutar. Esta preparación debe realizarse mediante un comando de bucle clásico (no expandible).

\newcount\tmpnum
\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\wrap#1#2{\tmpnum=0 \def\parshapelist{}
    \loop \addto\parshapelist{0cm#2}\advance\tmpnum by1
          \ifnum\tmpnum<#1 \repeat
    \advance\tmpnum by1
    \parshape \the\tmpnum\space \parshapelist 0cm\hsize
}

\wrap{6}{10cm} Here is the definitive guide to the use of TeX, written by the
system's creator, Donald E. Knuth. TeX represents the state of the art in
computer typesetting. It is particularly valuable where the document, article,
or book to be produced contains a lot of mathematics, and where the user is
concerned about typographic quality. TeX software offers both writers and
publishers the opportunity to produce technical text of all kinds, in an
attractive form, with the speed and efficiency of a computer system. Novice and
expert users alike will gain from The TeXbook the level of information they
seek. Knuth warns newcomers away from the more difficult areas, while he entices
experienced users with new challenges. The novice need not learn much about TeX
to prepare a simple manuscript with it. But for the preparation of more complex
documents, The TeXbook contains all the detail required. Knuth's familiar wit,
and illustrations specially drawn by Duane Bibby, add a light touch to an
unusually readable software manual. The TeXbook is the first in a five-volume
series on Computers and Typesetting, all authored by Knuth.
\bye

Por supuesto, este ejemplo concreto podría resolverse \hangafter=-6 \hangindent=-6cmcomo lo menciona sgmoye. Pero supongo que da este ejemplo solo como estudio de material de \parshapecomportamiento.

Más explicación, cómo funciona: primero: \parshapelistse define como vacío y el texto 0cm10cm (si #2=10cm) se agrega al \parshapelist. Tenemos 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm \parshapelistal final del bucle. Ahora \parshapese procesa la primitiva :

\parshape 7 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm\hsize

y hace el trabajo real.

HenriMenke Dec 21 2020 at 02:22

Como ya se mencionó en los comentarios, \loop...\repeatno es ampliable y por lo tanto \parshapedeja de leer la especificación. Sin embargo, puede definir una versión simple completamente expandible de \loopen Plain TeX usando \romannumeral.

Básicamente, el truco se reduce al hecho de que el número romano más grande es el mque corresponde a \romannumeral1000. Por \romannumeral2000lo tanto, se convierte en mmy así sucesivamente. Podemos (ab) usar esto para convertir nuestra variable de ciclo usando \romannumeralen una secuencia de my quitar una en cada iteración hasta que no quede nada.

He llamado a la macro \replicate. No es tan poderoso \loopporque no puede acceder al contador de bucles, pero es completamente expandible.

\catcode`@=11

\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
\long\def\@gobble#1{}
\def\@ifx#1#2{%
    \ifx#1#2%
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
}

% replicate
\def\replicate#1{\expandafter\@replicate\romannumeral#1000\relax\relax}
\def\@replicate#1#2#{\@ifx{\relax}{#1}{\@gobble}{\@@replicate{#2}}}
\long\def\@@replicate#1#2{#2\@replicate#1{#2}}

\catcode`@=12

%%% begin document

\def\wrap#1#2{\parshape=#1\replicate{#1}{ 0cm #2}}

\input lorem\par

\wrap{6}{10cm} \input lorem\par

\input lorem\par

\bye