문자를 n번 반복

문자를 n번 반복

나는 내가 원하는 repeat모든 것을 허용하는 새로운 명령을 만들고 싶었습니다 . 몇번의 검색과 노력 끝에 다음과 같은 결과를 얻었습니다.charactersn times

\usepackage{multido}
\newcommand{\myrepeat}[2]{%
    \newcount\iterations%
    \iterations #1%
    \advance\iterations -1
    \multido{\iN=0+1}{\iterations}{#2\ }#2%
}

결과 PDF에서 명령 뒤에 이상한 공백이 있어서 주석 기호를 추가한 %다음 사라졌습니다.

내 질문은: 이 작업을 수행하는 더 좋은 방법이 있습니까? 이 방법은 이 방법만큼 이해하기 쉽고, 많은 종속성을 도입하지 않는 것이 좋습니다.

multido너무 복잡하지 않거나, 더 이상 복잡하지 않게 설명할 수 있다면 없는 것도 괜찮습니다. multido나는 그 이름이 어떤 일을 여러 번 한다는 것을 의미하기 때문에 그런 일에 사용하는 것이 좋다고 생각합니다 . 그러나 나는 그것을 하는 가장 쉽고 깨끗한 방법을 택했는지 확신하지 못합니다.

내 솔루션은 PDF에 항목을 추가하는 것보다 공간을 하나 더 적게 추가합니다. 1을 빼는 방법이 의심스러울 정도로 장황해 보입니다.

현재 두 가지 버전이 작동 중입니다.

@egreg의 내용이 수정되었습니다.

\makeatletter
\newcount\my@repeat@count% initialize a new counter for the loop
\newcommand{\myrepeat}[3]{% new command with 2 arguments
    \begingroup% ???
    \my@repeat@count=1% initialize at 1, so that there are argument - 1 iterations and the last iterations doesn't have a separator following it
    \@whilenum\my@repeat@count<#1\do{#2#3\advance\my@repeat@count1}#2% as long as the iteration count is smaller than the argument, advance, meaning that the counter will be increased by 1
    \endgroup% ???
}
\makeatother

\newcommand{\mediumgap}{%
    \myrepeat{5}{.....}{\ }
}

@christian이 수정한 내용:

\newcount\myloopcounter
\newcommand{\repeatit}[3][10]{%
    \myloopcounter1% initialize the loop counter
    \loop\ifnum\myloopcounter < #1
    #2#3%
    \advance\myloopcounter by 1%
    \repeat% start again
    #2%
}
\newcommand{\longgap}{%
    \repeatit[5]{.....}{\ }
}

어느 쪽이 다른 쪽보다 장점이 있는지는 모르겠습니다. 반복을 한 번 덜 수행하고 구분 기호 없이 다시 반복할 문자만 작성하는 대신 마지막 공백이나 구분 문자를 제거하는 더 좋은 방법이 있을 수도 있습니다. 나는 그것이 유용할 수 있고 단지 세 번째 매개변수일 뿐이라고 생각했기 때문에 구분 기호를 도입했습니다.

답변1

패키지 없음:

\documentclass{article}

\makeatletter
\newcount\my@repeat@count
\newcommand{\myrepeat}[2]{%
  \begingroup
  \my@repeat@count=\z@
  \@whilenum\my@repeat@count<#1\do{#2\advance\my@repeat@count\@ne}%
  \endgroup
}
\makeatother

\begin{document}

\myrepeat{4}{x}

\myrepeat{4}{\myrepeat{2}{x}}

\end{document}

왜 그룹인가? 중첩된 호출을 허용합니다.

여기에 이미지 설명을 입력하세요

문자를 반복하고 싶은 경우:

\documentclass{article}

\newcommand\myrepeat[2]{%
  \begingroup
  \lccode`m=`#2\relax
  \lowercase\expandafter{\romannumeral#1000}%
  \endgroup
}

\begin{document}

\myrepeat{4}{x}

\end{document}

Ulrich Diez가 올바르게 설명했듯이 이 코드는 카운터 등록을 반복 횟수로 허용하지 않습니다. 이를 지원하기 위해 약간 더 복잡한 버전은 다음과 같습니다.

\newcommand\myrepeat[2]{%
  \begingroup
  \lccode`m=`#2\relax
  \lowercase\expandafter{\romannumeral\number\number#1 000}%
  \endgroup
}

\romannumeral\number두 번째 것을 확장하는 첫 번째를 트리거합니다 . 예를 들어 #1연속적 으로 4가 있는 경우 (여기서 는 공간 토큰을 나타냄 )

\romannumeral\number\number4•000
\romannumeral\number4000
\romannumeral4000
mmmm

\count27대신에 as를 갖고 값 4를 유지하면 다음을 얻습니다 #1.\count27

\romannumeral\number\number\count27•000
\romannumeral\number4000
\romannumeral4000
mmmm

(명명된 카운터 레지스터) 가 있고 \foo다시 값 4를 보유하고 있다면 다음과 같습니다.

\romannumeral\number\number\foo•000
\romannumeral\number4•000
\romannumeral4000
mmmm

그러므로\number세 번째 경우를 다루려면 의 인스턴스가 필요합니다. 이는 공백이 "명시적" 숫자에 대한 검색을 종료한 다음 무시된다는 사실을 활용합니다(두 번째 토큰 확장 후 세 번째 경우 공백 토큰이 무시되지 않음 \number).

반복 사이에 텍스트도 넣으려면 첫 번째 접근 방식은 매우 간단합니다. 1에서 루프를 시작하면 됩니다.

\makeatletter
\newcount\my@repeat@count
\newcommand{\myrepeat}[3]{%
  % #1 = number of repetition
  % #2 = text to repeat
  % #3 = text in between
  \begingroup
  #2
  \my@repeat@count=\@ne
  \@whilenum\my@repeat@count<#1\do{#2#3\advance\my@repeat@count\@ne}%
  \endgroup
}
\makeatother

(반복 없이 호출하지 마세요).

재귀를 사용하는 다른 솔루션과 \romannumeral#1000이에 대한 오래된 아이디어는 한 번에 하나씩 사용할 수 있는 긴 m 문자열을 생성합니다.

\documentclass{article}

\makeatletter
\newcommand\myrepeat[3]{%
  % #1 is the number of repetitions
  % #2 is the code to repeat
  % #3 is the code to put in the middle
  \expandafter\myrepeat@aux\expandafter{\romannumeral\number\number#1 000}{#2}{#3}%
}
\newcommand{\myrepeat@aux}[3]{\myrepeat@auxi{#2}{#3}#1;;}
\def\myrepeat@auxi#1#2#3#4{%
  \ifx#3;%
    \expandafter\@gobble % recursion has ended
  \else
    \expandafter\@firstofone % still one m to swallow
  \fi
  {\myrepeat@auxii{#1}{#2}{#4}}%
}
\def\myrepeat@auxii#1#2#3{%
  #1\ifx#3;\else#2\fi
  \myrepeat@auxi{#1}{#2}#3% restart the recursion
}
\makeatletter

\begin{document}

\myrepeat{4}{x}{-}

\myrepeat{1}{x}{-}

X\myrepeat{0}{x}{-}X

\end{document}

여기에 이미지 설명을 입력하세요

재귀는 소비한다한 단계만 더 수행해야 하는지 여부를 구별하기 위해 토큰을 한 번에 하나씩 표시합니다. 재귀가 다시 시작되면 두 번째 토큰이 다시 배치됩니다.


그러나 이것은 단지 공부를 위한 것일 뿐입니다. 실제 응용 프로그램에서 나는 할 것입니다

\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\myrepeat}{O{}mm}
 {
  \int_compare:nT { #2 > 0 }
   {
    #3 \prg_replicate:nn { #2 - 1 } { #1#3 }
   }
 }
\ExplSyntaxOff

전화를 \myrepeat[-]{4}{x}받다

xxxxx

그리고 \myrepeat{3}{A}얻으려면

AAA

답변2

다음은 패키지 없이 일반 등을 사용하는 버전 \loop입니다 \repeat.

\documentclass{article}

\newcount\myloopcounter

\newcommand{\repeatit}[2][10]{%
  \myloopcounter0% initialize the loop counter
  \loop\ifnum\myloopcounter < #1 % Test if the loop counter is < #1
  #2%
  \advance\myloopcounter by 1 % 
  \repeat % start again
}

\begin{document}

\repeatit[5]{A}


\repeatit[20]{And now for something completely different\par}

\end{document}

여기에 이미지 설명을 입력하세요

답변3

FWIW, ConTeXt에서는 무언가를 반복하는 데 사용할 수 있습니다 \dorecurse. 예를 들어:

\dorecurse{10}{Hello world. }

Hello world.10번 인쇄됩니다 . 현재 반복 번호는 매크로에 저장됩니다 \recurselevel.

답변4

OpTeX에서는 매크로를 사용할 수 있습니다 \fornum:

\def\myrepeat#1#2{\fornum 1..#1\do {#2}}

\myrepeat{4}{x}

\myrepeat{4}{\myrepeat{2}{x}}

\message{\myrepeat{4}{\myrepeat{2}{x}}} % prints xxxxxxxx on the terminal.

\bye

매크로 \fornum는 완전히 확장 가능하므로 그룹을 열거나 닫지 않고도 중첩 루프를 사용할 수 있습니다.

관련 정보