동적으로 생성된 테이블을 동적 콘텐츠로 채우는 방법은 무엇입니까?

동적으로 생성된 테이블을 동적 콘텐츠로 채우는 방법은 무엇입니까?

동적 데이터로 채우면서 테이블 형식을 동적으로 생성하려면 어떻게 해야 합니까?

예: 내가 가지고 있다고 가정해보자

\def\N{10}

\N각 열의 상단 셀에 열 번호가 포함된 열이 있는 테이블을 생성하고 싶습니다 .

\begin{tabular}{|c|c|c|...|c|}
1 & 2 & 3 & ... & N
\end{tabular}

이것이 내가 얻은 가장 가까운 것입니다:

\newtoks\cols
\cols={}
\newcounter{i}
\setcounter{i}{1}
\loop
\cols=\expandafter{\the\cols \arabic{i}}
\ifnum\value{i}<\N
\cols=\expandafter{\the\cols &}
\stepcounter{i}
\repeat

\begin{tabular}{|*{\N}{c|}}
\the\cols
\end{tabular}

하지만 으로 인해 \expandafter각 열에는 10이 포함된 10개의 열이 제공됩니다.

부분 확장과 같은 작업을 수행할 수 있는 방법이 있나요? 나는 단지 확장하고 싶지만 \arabic{i}물론 &.

답변1

문제는 다음 줄입니다.

\cols=\expandafter{\the\cols \arabic{i}}

\cols토큰 레지스터이므로 \arabic{i}확장되지 않습니다. 도움말 \expandafter대신 추가 기능을 사용 하고 카운터 값을 인쇄합니다 \arabic.

\cols=\expandafter{\the\expandafter\cols\the\value{i}}

완전한 예:

\documentclass{article}

\newtoks\cols
\newcounter{i}
\newcount\N

\begin{document}
  \N=10
  \cols={}
  \setcounter{i}{1}
  \loop
    \cols=\expandafter{\the\expandafter\cols\the\value{i}}
  \ifnum\value{i}<\N
    \cols=\expandafter{\the\cols &}
    \stepcounter{i}
  \repeat
  \begin{tabular}{|*{\N}{c|}}
    \the\cols
  \end{tabular}
\end{document}

결과

확장형 버전

다음 예에서는 e-TeX의 \numexpr. 지속적으로 \if둥지를 틀도록 주의를 기울이고 &너무 일찍 발견해서는 안 됩니다.

\documentclass{article}

\newcount\N

\makeatletter
\newcommand*{\Ncols}{%
  \Ncols@aux{1}%
}
\newcommand*{\Ncols@aux}[1]{%
  \ifnum#1>\N
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi
  {% 
    \ifnum#1<2 \expandafter\@gobble\fi\Ncols@amp
    #1%
    \expandafter\Ncols@aux\expandafter{\the\numexpr(#1+1)}%
  }%
}
\newcommand*{\Ncols@amp}{&}
\makeatother

\begin{document}

\N=10
\begin{tabular}{|*{\N}{c|}}
\Ncols
\end{tabular}

\end{document}

결과

답변2

하이코의 대답코드의 문제, 해결 방법 및 확장 가능한 정수 루프를 사용하여 다른 스타일로 진행하는 방법을 설명했습니다( 덕분에 \numexpr).

A.Ellett의 답변pgffor및 를 사용하여 두 가지 솔루션을 더 제공합니다 pgfkeys.

DJP의 답변는 외부 도구를 사용하는 방법으로, 여기서는 Python code강력한 Sagevia 에 의해 처리됩니다 sagetex.

이러한 답변은 모두 매크로에서 TeX표를 숨기거나 전역 정의를 수행하거나 토큰 목록 레지스터를 준비하거나 다양한 종류의 조건을 사용하는 등의 추가 작업이 어떤 형태로든 필요합니다 .&\xdefTeX

xintFor패키지의 구성xinttools대안입니다 (참조쉼표로 구분된 목록을 반복하는 방법은 무엇입니까?) 이는 추가 코딩의 문제를 줄여줍니다.

\documentclass{article}
\usepackage{xinttools}
\newcommand{\N}{10}
\begin{document}
% \renewcommand{\N}{<nb of cols>}
\begin{tabular}{*{\N}c}
  \xintFor* #1 in {\xintSeq {1}{\N}}\do {\xintifForFirst{}{&}#1}\\
\end{tabular}
\end{document}

동적 테이블 형식

테스트 는 주어진 행(여기서는 한 행만)의 두 번째 및 다음 셀에만 \xintifForFirst{YES}{N0}표를 삽입하는 것입니다 . &매크로 \xintSeq는 정수의 산술 시퀀스를 생성합니다(예: {1}{2}{3}{4}). 인수 \xintFor* #1 in를 반복하여(별표가 없는 사촌은 \xintFor쉼표로 구분된 목록을 반복합니다) #1각 항목을 차례로 놓습니다.

위와 동일한 코드이지만 오히려 카운터 를 사용합니다 LaTeX.

\documentclass{article}
\usepackage{xinttools}
\newcounter{N}
\begin{document}
\setcounter{N}{10}
\begin{tabular}{*{\value{N}}c}
  \xintFor* #1 in {\xintSeq {1}{\value{N}}}\do {\xintifForFirst{}{&}#1}\\
\end{tabular}
\end{document}

이제 곱셈 테이블을 구성하는 보다 정교한 예(두 개의 중첩 루프를 사용함)가 있습니다. \numexpr행 인덱스와 열 인덱스의 곱셈에 사용됩니다.

동적 테이블 형식 2

코드는 다음과 같습니다.

\documentclass{article}
\usepackage{xinttools}

\newcommand\MultTable [4]{% 
  % #1, #2 row indices
  % #3, #4 column indices: we need #4-#3+2 columns
  \begin{tabular}{*{\numexpr#4-#3+2\relax}c}
  \hline
  % headerline
  $\times$\xintFor* ##1 in {\xintSeq {#3}{#4}}\do{&\textbf{##1}}\\
  \hline
  % #2-#1+1 rows, ##1=dynamic index of each row, ##2 column index
  \xintFor* ##1 in {\xintSeq {#1}{#2}}\do
     {\textbf{##1}
      \xintFor* ##2 in {\xintSeq {#3}{#4}}\do{&\the\numexpr ##1*##2\relax}
      \\
     }
  \hline
  \end{tabular}%
% efficiency note: one could do \edef\columnindices {\xintSeq {#3}{#4}}
% before the tabular
% and use \columnindices rather \xintSeq {#3}{#4} to avoid it being
% re-computed for each row
}

\begin{document}
\begin{table}[!htbp]
  \centering
  \MultTable {1}{10}{1}{10}
  \caption{Multiplication table}
\end{table}
\begin{table}[!htbp]
  \centering
  \MultTable {123}{132}{91}{98}
  \caption{Multiplication table}
\end{table}
\end{document}

\xintFor*사용자 명령 정의 내에서 사용한 것처럼 루프의 와 명령의 첫 번째 매개변수 사이의 혼동을 피하기 위해 LaTeX두 배로 늘려야 했습니다 .###1#1

답변3

약간의 Python을 배우는 것이 마음에 들지 않는다면 sagetex패키지는 동적 테이블을 쉽게 처리할 수 있습니다. 결국 Python은 강력한 언어입니다. sagetex에 대한 문서는 다음과 같습니다.여기그리고 example.pdf에서는 파스칼의 삼각형을 구성합니다. 귀하가 요청한 것과 더 가까운 코드는 다음과 같습니다. 첫 번째 행은 1부터 N까지입니다.

\documentclass{article}
\usepackage{sagetex}
\pagestyle{empty}
\begin{document}
\begin{sagesilent}
N = 5
M = 4
output = r"\begin{tabular}{"
for i in range(0,N):
    output += r"|c"
output += r"|}"
for j in range(0,M):
    for i in range(0,N-1):
        output += r"%d & "%((j+1)*(i+1))
    output += r"%d \\"%(N*(j+1))
output += r"\end{tabular}"
\end{sagesilent}
Here's the output:\\\\
\sagestr{output}
\end{document}

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

배워야 할 Python의 양이 제한되어 있으므로 TeX로 프로그래밍하는 것보다 쉬울 것입니다. 알아야 할 사항: for 루프는 범위에 나열된 마지막 값을 포함하지 않으며 r은 원시 문자열을 위한 것이며 문자열에 백슬래시와 같은 문자가 있어서 발생할 수 있는 문제를 방지합니다. 마지막으로 %d는 정수 삽입용이고, %f는 부동 소수점, %s는 문자열 삽입용입니다. 환경 sagesilent은 실제 코드를 조판하고 sagestr.

답변4

이는 의견 및 기타 답변에서 이미 제안한 대로 다양한 방법으로 수행할 수 있습니다. 다음은 pgffor및 를 사용하는 두 가지 솔루션입니다 pgfkeys.

이 첫 번째 솔루션은 키를 사용하지 않고도 작동합니다.

\documentclass{article}
\usepackage{pgffor}
\usepackage{etoolbox}

\makeatletter
\newcommand\aeDynamicTable{\ae@dynamicTable}
\def\ae@dynamicTable[#1]#2{%%
  \let\ae@table@content\relax%%
  \def\ae@new@column{&}
  \def\ae@row{0}%%
  \foreach \x in {1,...,#2}
    {%%
      \xdef\ae@row{\number\numexpr\ae@row+1\relax}%%
      \ifx\relax\ae@table@content
        \xdef\ae@table@content{\noexpand\@arabic{\x}}%
      \else
        \xdef\ae@table@content{\expandonce{\ae@table@content} \noexpand\@arabic{\x}}%%
      \fi
      \ifnum\ae@row=#1\relax
        \xdef\ae@row{0}%%
        \def\ae@new@line{\\}%%
        \def\ae@new@column{}%%
      \else
        \def\ae@new@line{}%%
        \def\ae@new@column{&}%%
      \fi
      \ifnum\x=#2\relax
        \def\ae@new@line{}%%
        \def\ae@new@column{}%%
      \fi
      \xdef\ae@table@content{\expandonce{\ae@table@content} \expandonce{\ae@new@column} \expandonce{\ae@new@line}}%
    }%%
    \begin{tabular}{|*{#1}{c|}}
      \ae@table@content 
    \end{tabular}%%
  }

\makeatother

\begin{document}

\aeDynamicTable[3]{5}

\aeDynamicTable[10]{35}

\end{document}

이 두 번째 예에서는 키를 사용하여 동일한 작업을 수행합니다.

\documentclass{article}
\usepackage{pgffor}
\usepackage{pgfkeys}
\usepackage{etoolbox}

\makeatletter
\def\ae@col@limit{}
\def\ae@max@cells{}
\pgfkeys{/ae/dynamic/table/.cd,
  cols/.store in=\ae@col@limit,
  cells/.store in=\ae@max@cells,
}

\newcommand\aeDynamicTable{\ae@dynamicTable}
\def\ae@dynamicTable#1{%%
  \pgfkeys{/ae/dynamic/table/.cd,#1}%% 
  \let\ae@table@content\relax%%
  \def\ae@new@column{&}
  \def\ae@col{0}%%
  \foreach \x in {1,...,\ae@max@cells}
    {%%
      \xdef\ae@col{\number\numexpr\ae@col+1\relax}%%
      \ifx\relax\ae@table@content
        \xdef\ae@table@content{\noexpand\@arabic{\x}}%
      \else
        \xdef\ae@table@content{\expandonce{\ae@table@content} \noexpand\@arabic{\x}}%%
      \fi
      \ifnum\ae@col=\ae@col@limit\relax
        \xdef\ae@col{0}%%
        \def\ae@new@line{\\}%%
        \def\ae@new@column{}%%
      \else
        \def\ae@new@line{}%%
        \def\ae@new@column{&}%%
      \fi
      \ifnum\x=\ae@max@cells\relax
        \def\ae@new@line{}%%
        \def\ae@new@column{}%%
      \fi
      \xdef\ae@table@content{\expandonce{\ae@table@content} \expandonce{\ae@new@column} \expandonce{\ae@new@line}}%
    }%%
    \begin{tabular}{|*{\ae@col@limit}{c|}}
      \ae@table@content 
    \end{tabular}%%
  }

\makeatother

\begin{document}

\aeDynamicTable{cols=3,cells=5}

\aeDynamicTable{cols=10,cells=35}

\end{document}

두 경우 모두 결과 테이블은 다음과 같습니다.

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

관련 정보