(CSV) 파일에서 읽은 문자열을 카운터로 변환하는 방법

(CSV) 파일에서 읽은 문자열을 카운터로 변환하는 방법

다음과 같이 태그와 (페이지) nrs가 포함된 csv 파일이 있습니다.

tag,nr
t1,1
t2,5
t3,9

nr-column은 pdf 파일의 페이지 번호를 나타냅니다. 각 페이지에는 해당 태그가 있습니다. 태그가 주어지면 라텍스 문서의 그림에 해당 페이지를 표시하고 싶습니다.

datatools를 사용하면 csv 파일을 로드하고 지정된 태그의 페이지 번호를 가져올 수 있습니다. 예를 들어 태그의 경우 t2page nr 을 얻습니다 5.

하지만 이제 해당 페이지 nr을 includegraphics에 대한 인수로 제공하면 page=...오류 메시지가 나타납니다.

"! 숫자가 누락되어 0으로 처리됩니다."`

라텍스 5문자열을 포함 그래픽이 처리할 수 있는 페이지 번호로 변환하려면 어떤 추가 단계를 수행해야 합니까?

문제를 유발하는 단순화된 버전(포함 그래픽 대신 카운터 사용)은 다음과 같습니다.

\documentclass{article}
\usepackage{datatool}

\begin{document}

\DTLloaddb{tags}{prestags.csv}
\newcommand{\pagenr}{\DTLfetch{tags}{tag}{t2}{nr}}

\newcounter{snr}
\addtocounter{snr}{\pagenr}

\end{document}

% Output:

! Missing number, treated as zero.
<to be read again> 
                   \let 
l.10 \addtocounter{snr}{\pagenr}

이 문제를 해결하려면 어떻게 해야 합니까?

답변1

문제는 \DTLfetch매크로가 확장 가능하지 않다는 것입니다. 여기에 설명된 기술을 사용할 수 있습니다.

이것을 극복하기 위해. 다음은 해결된 예입니다.

\documentclass{article}
\begin{filecontents}{\jobname.csv}
tag,nr
t1,1
t2,5
t3,9
\end{filecontents}
\usepackage{datatool}
\newcommand{\getvar}[1]{\DTLfetchsave{\myvar}{tags}{tag}{#1}{nr}}
\newcommand{\DTLfetchsave}[5]{%
  \edtlgetrowforvalue{#2}{\dtlcolumnindex{#2}{#3}}{#4}%
  \dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{#2}{#5}}%
  \let#1\dtlcurrentvalue
}
\newcounter{snr}
\begin{document}

\DTLloaddb{tags}{prestags.csv}

\setcounter{snr}{3}
The counter value is \thesnr

\getvar{t2}
\addtocounter{snr}{\myvar}
The counter value is: \thesnr

\end{document}

코드 출력

답변2

여기서는 readarray패키지를 사용하여 csv 파일을 다이제스트하고 listofitems읽기를 사용하여 데이터를 목록에 배치합니다. 매크로는 \getvar확장 가능합니다.

\begin{filecontents*}[overwrite]{prestags.csv}
tag,nr
t1,1
t2,5
t3,9
\end{filecontents*}
\documentclass{article}
\usepackage{readarray,graphicx}
\begin{document}
\readarraysepchar{\\}
\readdef{prestags.csv}\mycsvdata
\setsepchar{\\/,}
\readlist*{\mycsvlist}{\mycsvdata}
\foreachitem\z\in\mycsvlist[]{%
  \expandafter\gdef\csname mytag\mycsvlist[\zcnt,1]\expandafter
    \endcsname\expandafter{\expandafter
    \mycsvlist\expandafter[\zcnt,2]}%
}
\newcommand\getvar[1]{\csname mytag#1\endcsname}

The t2 tag corresonds with page \getvar{t2}

\includegraphics[page=\getvar{t3},scale=.6]{readarray.pdf}
\end{document}

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

답변3

스크래치 매크로를 전역적으로 정의하는 것이 마음에 들지 않으면 다음을 사용할 수 있습니다 \DTLassignfirstmatch.

다음 예제를 컴파일할 때 두 가지 오류 메시지가 나타납니다.

이는 존재하지 않는 값을 검색하려고 시도하는 경우 어떤 일이 발생하는지 확인할 수 있도록 하기 위한 것입니다.

\begin{filecontents*}{prestags.csv}
tag,nr
t1,1
t2,5
t3,9
\end{filecontents*}

\makeatletter
\newcommand\MyStuffDTLfetchsavePackageError[7]{%
  \PackageError{#1}{#7}{%
    In order to retrieve from database `#2`\MessageBreak
    the value of the key `#5` in the first row\MessageBreak
    where the key `#3` has value `#4`,\MessageBreak
    database `#2` must exist and have keys\MessageBreak
    `#3` and `#5` and a row where the key `#3`\MessageBreak
    has the value `#4`.%
  }%
  \global\let#6=\dtlnovalue
}%
\DeclareRobustCommand{\MyStuffDTLfetchsave}[5]{%
  %#1 = macro to store as result
  %#2 = data base name
  %#3 = key 1
  %#4 = value of key 1
  %#5 = key 2
  \@bsphack
  \DTLifdbexists{#2}{%
    \DTLifhaskey{#2}{#3}{%
      \DTLifhaskey{#2}{#5}{%
        \global\let#1=\dtlnovalue
        \DTLassignfirstmatch{#2}{#3}{#4}{#1=#5}%
        \ifx#1\dtlnovalue\expandafter\@firstofone\else\expandafter\@gobble\fi
        {%
          \MyStuffDTLfetchsavePackageError{My Stuff}{#2}{#3}{#4}{#5}{#1}%
             {In data base `#2' no row's key `#3' holds the value `#4'}%
        }%
      }{%
        \MyStuffDTLfetchsavePackageError{My Stuff}{#2}{#3}{#4}{#5}{#1}%
          {There is no key `#5' in data base `#2'}%
      }%
    }{%
      \MyStuffDTLfetchsavePackageError{My Stuff}{#2}{#3}{#4}{#5}{#1}%
        {There is no key `#3' in data base `#2'}%
    }%
  }{%
    \MyStuffDTLfetchsavePackageError{My Stuff}{#2}{#3}{#4}{#5}{#1}%
      {Data base `#2' doesn't exist}%
  }%
  \@esphack
}%
\makeatother

\documentclass{article}
\usepackage{datatool}

\newcounter{snr}

\begin{document}

\DTLloaddb{tags}{prestags.csv}

\setcounter{snr}{3}%
\noindent The counter value is: \thesnr

\MyStuffDTLfetchsave{\scratchy}{tags}{tag}{t1}{nr}%
\ifx\scratchy\dtlnovalue
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t1` could not be retrieved.

  \noindent Calculations where this value would have been used were not performed.
\else
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t1` is: \scratchy

  \addtocounter{snr}{\scratchy}%
  \noindent After adding that value to the counter, the counter value is: \thesnr
\fi

\MyStuffDTLfetchsave{\scratchy}{tags}{tag}{t2}{nr}%
\ifx\scratchy\dtlnovalue
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t2` could not be retrieved.

  \noindent Calculations where this value would have been used were not performed.
\else
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t2` is: \scratchy

  \addtocounter{snr}{\scratchy}%
  \noindent After adding that value to the counter, the counter value is: \thesnr
\fi

\MyStuffDTLfetchsave{\scratchy}{tags}{tag}{t3}{nr}%
\ifx\scratchy\dtlnovalue
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t3` could not be retrieved.

  \noindent Calculations where this value would have been used were not performed.
\else
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t3` is: \scratchy

  \addtocounter{snr}{\scratchy}%
  \noindent After adding that value to the counter, the counter value is: \thesnr
\fi

\MyStuffDTLfetchsave{\scratchy}{tags}{tag}{t4}{nr}%
\ifx\scratchy\dtlnovalue
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t4` could not be retrieved.

  \noindent Calculations where this value would have been used were not performed.
\else
  \noindent The value of the key `nr` in the row where the key `tag` has the value `t4` is: \scratchy

  \addtocounter{snr}{\scratchy}%
  \noindent After adding that value to the counter, the counter value is: \thesnr
\fi

\end{document}

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

답변4

제안한대로@cabohah, DTLfetch질문의 줄은 다음 두 줄로 대체될 수 있습니다.

\DTLgetlocation{\rownr}{\colnr}{tags}{t2}
\DTLgetvalue{\pagenr}{tags}{\rownr}{\dtlcolumnindex{tags}{nr}}

이것은 간단한 변경이었기 때문에 결국에는 이것을 사용하게 되었습니다.

관련 정보