Plain TeX: problemi quando \ loop per impostare i parametri per \ parshape

Dec 21 2020

Stavo cercando di scrivere una macro per avvolgere il testo attorno a una figura. Sono consapevole che è disponibile in Latex e c'è un altro pacchetto, figflow per plainTex. Sto solo imparando a scrivere il mio. Il mio primo passo è stato usare \ parshape per creare un'area vuota per la figura. Sono rimasto bloccato qui. Definisco la macro come segue:

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

Non funziona. Ho provato \edef, il che non ha funzionato neanche. Per favore qualcuno può aiutare? Grazie!

\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

Risposte

3 Skillmon Dec 21 2020 at 02:29

Una risposta che mostra un ciclo piuttosto semplice con \numexpr.

Quando si utilizza \parshapee si desidera influire solo su un numero specifico di righe, è necessario aggiungere una riga aggiuntiva con 0cm \hsizeper tornare alle righe normali dopo aver terminato \parshape, perché \parshaperipeterà l'ultima specifica per ogni riga rimanente del paragrafo.

\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

Per un'applicazione relativamente semplice come questa (il rientro si estende su un solo paragrafo), TeX semplice offre \hangafter(il numero di righe da indentare, positivo se da sinistra, negativo se da destra, come qui) e \hangindent(positivo se il rientro inizia dopo il numero da cui è stato dato \hangafter, negativo se inizia dalla riga 1) - vedi The TeXbook di Knuth , pagina 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

Per essere completo, si \wrappotrebbe definire una semplice macro (l'output è identico):

\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 semplice loop espandibile in expl3; è facile specificare il numero desiderato di righe speciali invece di essere una tantum.

\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 \wrapè essa stessa espandibile, quindi puoi farlo

\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
[...]

e definire all'inizio varie forme di questo tipo.

1 wipet Dec 21 2020 at 05:00

OpTeX supporta il \fornumcomando espandibile , quindi un altro approccio consiste nell'utilizzare questo \fonrumcomando all'interno dei \parshapeparametri. Ma OpTeX non è puro TeX puro, è TeX semplice esteso:

\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

Un altro approccio è: preparare un elenco di \parshapeparametri prima che \parshapevenga eseguito. Tale preparazione dovrebbe essere eseguita con il classico comando loop (non espandibile).

\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

Ovviamente, tale esempio concreto potrebbe essere risolto \hangafter=-6 \hangindent=-6cmcome menzionato da sgmoye. Ma suppongo che tu fornisca questo esempio solo come materiale di studio sul \parshapecomportamento.

Ulteriori spiegazioni, come funziona: primo: \parshapelistè definito come vuoto e il testo 0cm10cm (if #2=10cm) viene aggiunto al file \parshapelist. Abbiamo 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm \parshapelistalla fine del ciclo. Ora la primitiva \parshapeviene elaborata:

\parshape 7 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm\hsize

e fa il vero lavoro.

HenriMenke Dec 21 2020 at 02:22

Come già accennato nei commenti, \loop...\repeatnon è espandibile e quindi \parshapeinterrompe la lettura della specifica. Tuttavia, puoi definire una versione semplice e completamente espandibile di \loopin Plain TeX usando \romannumeral.

Essenzialmente il trucco si riduce al fatto che il numero romano più grande è mche corrisponde a \romannumeral1000. Quindi \romannumeral2000è trasformato in mme così via. Possiamo (ab) usarlo per convertire la nostra variabile di ciclo usando \romannumeralin una sequenza di me rimuoverne una in ogni iterazione finché non rimane nulla.

Ho chiamato la macro \replicate. Non è potente come \loopperché non puoi accedere al contatore di loop ma è completamente espandibile.

\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