Zwykły TeX: Problemy, gdy \ loop ustawia parametry dla \ parshape

Dec 21 2020

Próbowałem napisać makro do zawijania tekstu wokół figury. Zdaję sobie sprawę, że jest dostępny w wersji Latex i istnieje inny pakiet, figflow dla plainTex. Po prostu uczę się pisać własne. Moim pierwszym krokiem było użycie \ parshape do stworzenia pustego obszaru dla figury. Utknąłem tutaj. Makro definiuję następująco:

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

To nie działa. Próbowałem \edef, ale też się nie udało. Czy ktoś może pomóc? Dzięki!

\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

Odpowiedzi

3 Skillmon Dec 21 2020 at 02:29

Odpowiedź pokazująca dość podstawową pętlę z \numexpr.

Kiedy używasz \parshapei chcesz, aby zmiana dotyczyła tylko określonej liczby wierszy, musisz dodać dodatkową linię, 0cm \hsizeaby powrócić do normalnych wierszy po zakończeniu \parshape, ponieważ \parshapepowtórzy ostatnią specyfikację dla każdego pozostałego wiersza akapitu.

\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

W przypadku stosunkowo prostej aplikacji, takiej jak ta (wcięcie obejmuje tylko jeden akapit), zwykły TeX oferuje \hangafter(liczba wierszy do wcięcia, dodatnia, jeśli od lewej, ujemna, jeśli z prawej, jak tutaj) i \hangindent(dodatnia, jeśli wcięcie zaczyna się po liczbie podanej przez \hangafter, ujemną, jeśli zaczyna się od linii 1) - patrz Knuth's The TeXbook , strona 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

Na \wrapkoniec można zdefiniować proste makro (dane wyjściowe są identyczne):

\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

Prosta rozszerzalna pętla expl3; łatwo jest określić żądaną liczbę specjalnych wierszy zamiast jednorazowo.

\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

Makro \wrapsamo w sobie jest rozwijalne, więc możesz to zrobić

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

i na początku określ różne kształty tego rodzaju.

1 wipet Dec 21 2020 at 05:00

OpTeX obsługuje \fornumpolecenia rozwijane , więc innym podejściem jest użycie tego \fonrumpolecenia w \parshapeparametrach. Ale OpTeX nie jest czystym TeXem, to rozszerzony zwykły TeX:

\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

Innym podejściem jest: przygotowanie listy \parshapeparametrów przed \parshapeuruchomieniem. Takie przygotowanie należy wykonać klasyczną (nierozszerzalną) komendą pętli.

\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

Oczywiście taki konkretny przykład mógłby zostać rozwiązany przez, o \hangafter=-6 \hangindent=-6cmczym wspomniał sgmoye. Ale przypuszczam, że podajesz ten przykład tylko jako materiał dotyczący \parshapezachowania.

Więcej wyjaśnień, jak to działa: po pierwsze: \parshapelistjest zdefiniowane jako puste, a tekst 0cm10cm (jeśli #2=10cm) jest dołączany do \parshapelist. Na \parshapelistkońcu pętli mamy 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm . Teraz prymityw \parshapejest przetwarzany:

\parshape 7 0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm10cm0cm\hsize

i robi prawdziwą pracę.

HenriMenke Dec 21 2020 at 02:22

Jak już wspomniano w komentarzach, \loop...\repeatnie jest rozszerzalny i dlatego \parshapeprzestaje czytać specyfikację. Możesz jednak zdefiniować prostą, w pełni rozszerzalną wersję programu \loopw zwykłym TeX-u, używając \romannumeral.

Zasadniczo sztuczka sprowadza się do tego, że największa rzymska cyfra modpowiada \romannumeral1000. Stąd \romannumeral2000zamienia się w mmi tak dalej. Możemy (ab) użyć tego do przekonwertowania naszej zmiennej pętli \romannumeralna sekwencję mi odciąć ją w każdej iteracji, aż nic nie zostanie.

Nazwałem makro \replicate. Nie jest tak potężny, jak \loopbrak dostępu do licznika pętli, ale jest w pełni rozszerzalny.

\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