"파일을 찾을 수 없습니다" 일반 텍스트 대신 명령을 사용하는 경우

"파일을 찾을 수 없습니다" 일반 텍스트 대신 명령을 사용하는 경우

안녕하세요,

원격 폴더의 파일에 액세스하는 효율적인 방법을 찾으려고 합니다. 경로에 대해 여러 명령을 정의했습니다.

아래 코드의 6행은 작동하며 올바른 파일을 포함하는 반면, 8행은 "파일을 찾을 수 없음"이라고 표시합니다. 그러나 이 두 경로가 정확히 동일하면 안 됩니까? 이런 명령을 연결하면 안 되나요?

1 \newcommand{\results}{../../code/data/results/}
2 \newcommand{\synthetic}{\results synthetic/}
3 \newcommand{\sine}[1]{sine_#1hz.pdf}
4
5
6 \includegraphics[width=.3\linewidth]{\synthetic sine_100hz.pdf}
7
8 \includegraphics[width=.3\linewidth]{\synthetic \sine{100}}

어쩌면 나는 명백한 것을 보지 못하고 있을 수도 있습니다. 명령에서 경로 이름을 사용하여 작업하는 것은 이번이 처음입니다. 내가 무엇을 놓치고 있는지 아는 사람 있나요?

건배

편집: 이것은 전체 코드 예입니다.

\documentclass[]{article}
\usepackage{graphicx}
\begin{document}

\newcommand{\results}{../../code/waveletTest/data/results/}
\newcommand{\synthetic}{\results synthetic/}
\newcommand{\sine}[1]{sine_#1hz.pdf}

\includegraphics[width=.3\linewidth]{\synthetic sine_100hz.pdf}

%\includegraphics[width=.3\linewidth]{\synthetic \sine{100}}

\end{document}

이 코드는 내가 원하는 파일을 보여줍니다. 마지막에서 다음 줄에 다시 주석을 달면 다음 오류가 발생합니다.

File `../../code/waveletTest/data/results/synthetic/sine_100hz.pdf' not found. ...width=.3\linewidth]{\synthetic \sine{100}}

답변1

내 시스템에서는 -command를 처리하는 일부 단계에서 \includegraphics다음과 같은 시퀀스를 얻습니다.
\filename@parse{\synthetic\sine{100}}

\filename@parse인수를 다음과 같이 분할하는 LaTeX 2ε-커널의 루틴입니다.

  1. 파일 경로입니다. 파일 경로는 매크로에 저장됩니다 \filename@area.
  2. 파일 이름(확장자 없음)입니다. 확장자 없이 파일 이름이 \filename@base.
  3. 파일 이름 확장자. 파일 이름의 확장자는 \filename@ext. 확장자가 없는 경우 는 \filename@ext와 같습니다 \relax.

무슨 일이 일어나는가:

내 시스템에서 \filename@parse구문: 은 다음과 같이 정의됩니다.
\filename@parse{⟨file-path/filename-specification⟩}

> \filename@parse=macro:
#1->\let \filename@area \@empty \expandafter \filename@path #1/\\

따라서 매크로와 동일하도록 \filename@parse초기화합니다 . 매크로는 인수를 처리하지 않고 비어 있거나 토큰으로 전혀 구성되지 않은 대체 텍스트를 전달하면서 최상위 확장 중에 토큰 스트림에서 사라집니다. 인수의 첫 번째 토큰을 "적중"한 후의 루틴\filename@area\empty\empty\filename@path\expandafter 한 번그리고 /\\결과에 추가합니다. (인수가 비어 있는 경우 명시적인 슬래시 문자 토큰(catcode 12(기타))은 확장할 수 없으므로 해롭지 않은 #1추가된 슬래시가 /적중됩니다 .\expandafter

루틴에 \filename@path대해서는 곧 설명하겠습니다. 이 시점에서는 다음과 같은 내용만 포함됩니다.\filename@path확장 불가능한 명시적 문자 토큰의 시퀀스를 처리하기 위해 들여쓰기되었습니다.카테고리 코드 12(기타)의 #1명시적인 슬래시 문자 토큰 과 파일 경로/파일 이름 끝에 대한 구분 기호/마커인 제어 기호 토큰이 뒤에 오는 파일 경로/파일 이름 사양( )을 형성합니다. -사양./\\

따라서 파일 경로/파일 이름 사양을 제공하기 위한 인수가 확장할 수 없는 명시적 문자 토큰의 시퀀스로 구성되지 않고 최상위 수준의 매크로 토큰으로 구성된 경우 "한 번 사용 \expandafter"이 수행됩니다. \filename@parse-expansion은 확장 불가능한 명시적 문자 토큰의 시퀀스를 생성합니다.
이 "한 번 적중 "은 내부적으로 를 사용하는 \expandafter와 같은 경우 시퀀스의 첫 번째 토큰을 한 번만 적중하면 전체 시퀀스를 얻는 데 충분한 토큰 시퀀스 측면에서만 파일 경로/파일 이름 사양을 제공할 수 있음 을 의미합니다. 파일 경로/파일 이름 사양을 형성하는 확장 불가능한 명시적 문자 토큰입니다.\includegraphics\filename@parse\expandafter

\expandafter시나리오에서 시퀀스의 첫 번째 토큰에 대한 단일 "적중"은 \synthetic \sine{100}확장할 수 없는 명시적 문자 토큰 시퀀스의 측면에서 전체(완전히 확장된) 파일 경로/파일 이름 사양을 생성하지 않지만 다음을 생성합니다. \results synthetic/\sine{100}더 많은 확장 작업이 수행되어야 하는 순서 입니다.

따라서 구성 요소(파일 경로, 확장자가 없는 파일 이름, 파일 이름 확장자) 분할/접속은 \filename@path해당 기본 루틴에 의해 올바르게 수행되지 않습니다.

\filename@path확장 불가능한 명시적 문자 토큰의 시퀀스 측면에서 제공될 파일 경로/파일 이름 사양을 "기대하는" 루틴 입니다 . 구문은 다음과 같습니다. 폴더/디렉토리 구분 기호 는 다음과 같이 정의됩니다.
\filename@path ⟨file-path/filename-specification in terms of a sequence of non-expandable explicit character-tokens⟩/\\
/

> \filename@path=macro:
#1/#2\\->\ifx \\#2\\\def \reserved@a {\filename@simple #1.\\}\else \edef \filen
ame@area {\filename@area #1/}\def \reserved@a {\filename@path #2\\}\fi \reserve
d@a 

\filename@path각 반복에서 파일 이름을 나타내는 마지막 세그먼트에 도달할 때까지 /파일 경로/파일 이름 사양의 다음 구분 세그먼트를 매크로에 추가하는 재귀 루프입니다 . \filename@area다음(그리고 아마도 마지막) 세그먼트는 #1. 다음 세그먼트 다음의 세그먼트는 에 있습니다 #2. 따라서 마지막 세그먼트에 대한 표시는 의 비어 있음입니다 #2.
비어 있는지 테스트하는 방법은 다음과 #2같습니다. 파일 이름을 나타내는 마지막 세그먼트에 도달하면 마지막 세그먼트/파일 이름에 점( )이 포함되어 있는지 확인하기 위해 매크로가 호출되므로 파일 이름에서 파일 이름 확장자를 분리해야 합니다. . 파일 이름 확장자를 분리해야 하는 경우 매크로를 사용하여 수행됩니다 .
\ifx\\#2\\⟨tokens in case #2 is empty⟩\else⟨tokens in case #2 is not empty⟩\fi
\filename@simple.\filename@dot

\filename@simple, 구문: 을 호출할 때 파일 이름을 나타내는 마지막 구분 세그먼트에서 시퀀스 가 ​​마지막 세그먼트에 추가됩니다. 따라서 점으로 구분된 인수 와 - 구분된 인수를 수집 하고 공백 여부에 따라 세그먼트에 있는 점이 점으로 구분된 인수의 구분 기호로 사용되었는지 또는 추가된 점이 점으로 구분된 인수로 사용되었는지 여부를 감지할 수 있습니다.
\filename@simple ⟨filename-specification in terms of a sequence of non-expandable explicit character-tokens⟩.\\
/.\\
\filename@simple#1\\#2#2

\filename@simple다음과 같이 정의됩니다:

> \filename@simple=macro:
#1.#2\\->\ifx \\#2\\\let \filename@ext \relax \else \edef \filename@ext {\filen
ame@dot #2\\}\fi \edef \filename@base {#1}

마지막 세그먼트/파일 이름에 점이 포함되어 있지 않으면 .추가된 시퀀스에서 .\\구분 기호로 사용되며 #1-delimited \\#2비어 있습니다. 그렇지 않으면 마지막 세그먼트의 첫 번째 점이 구분 기호로 사용되며 #1-delimited \\#2비어 있지 않습니다. 따라서 #2( \ifx\\#2\\...)의 공백은 마지막 세그먼트가 (점으로 구분된) 확장자가 없는 파일 이름을 형성하는지 아니면 점으로 파일 확장자와 분리된 파일 이름을 형성하는지 여부를 나타내는 지표로 사용됩니다. #2가 비어 있으면 " \filename@ext"는 \let와 같습니다 \relax. 그렇지 않으면 \filename@extvia 를 \edef정의 하는 동안 \filename@dot추가된 시퀀스를 제거하기 위해 첫 번째 점 뒤의 항목에 적용됩니다 .\\. 어쨌든 \filename@base첫 번째 점 이전의 항목으로 확장하도록 정의됩니다.

\filename@dot다음과 같이 정의됩니다:

> \filename@dot=macro:
#1.\\->#1

\filename@parse메커니즘은 좋습니다. 그러나 몇 가지 제한 사항이 있습니다.

예를 들어, 파일 이름에는 점이 최대 1개 포함되어 있다고 가정합니다.

예를 들어, 최대 1개의 점이 포함된 파일 이름의 경우 점은 파일 이름(확장자 없음)을 파일 이름 확장명과 분리하고 결과적으로 비어 있지 않다고 가정합니다. 점(일부 파일 시스템에서는 완벽하게 "합법적"임)으로 끝나는 파일 이름은 문제를 일으킬 수 있습니다.

예를 들어 특수 카테고리 코드가 있는 특수 문자는 고려되지 않습니다. 예를 들어 중괄호가 포함된 파일 경로/파일 이름 사양의 경우 중괄호는 균형이 맞지 않거나 제거될 수 있으며/또는 구분된 인수의 구분 기호로 점과 슬래시가 사용되지 않도록 "마스크"할 수 있습니다. 그런 것들이 문제를 일으키죠. 예를 들어, 해시를 포함하는 파일 경로/파일 이름 사양은 \reserved@a파일 경로/파일 이름 사양을 분할한 결과를 보유하는 매크로나 같은 임시 매크로를 정의할 때 문제를 일으킬 수 있습니다 .

예를 들어, 전체 파일 경로를 얻기에 충분하다는 \expandafter인수의 첫 번째 토큰에서 단일 확장 단계(→"최상위 확장"이라는 용어에 대한 내용)를 트리거하는 /에 의한 단일 "적중"이 있다고 가정합니다 . \filename@parse확장할 수 없는 명시적 문자 토큰의 시퀀스에 관한 /filename-사양입니다. 귀하의 시나리오에서는 그렇지 않으므로 항목을 분할하려는 시도가 \sine아직 확장되지 않은 동안 발생하므로 파일 이름 확장명에서 파일 이름(확장자 없음)을 분리하는 점은 \filename@simple아직 메커니즘에 의해 "표시"될 수 없습니다. 따라서 귀하의 시나리오에서 graphicx-package는 파일 이름 확장자가 지정되지 않았다고 잘못 "가정"합니다. graphicx-package가 파일 이름 확장자가 지정되지 않았다고 "가정"하는 경우(올바른 가정이든 잘못된 가정이든) 일부 기본 확장자를 사용하여 시도합니다.

예를 들어, 대신 , , 등을 사용 ../../code/waveletTest/data/results/synthetic/sine_100hz.pdf하여 시도합니다 .
../../code/waveletTest/data/results/synthetic/sine_100hz.pdf.pdf
../../code/waveletTest/data/results/synthetic/sine_100hz.pdf.png
../../code/waveletTest/data/results/synthetic/sine_100hz.pdf.jpg

그래서 "H"를 입력하는 것입니다.⟨반품⟩" 콘솔/화면에 오류 메시지가 나타나면 다음이 표시됩니다.

I could not locate the file with any of these extensions:
.pdf,.png,.jpg,.mps,.jpeg,.jbig2,.jb2,.PDF,.PNG,.JPG,.JPEG,.JBIG2,.JB2,.eps
Try typing  <return>  to proceed.
If that doesn't work, type  X <return>  to quit.

파일 이름 확장자를 생략하라는 David Carlisle(graphicx-package 작성자)의 제안은 .pdf비록 이 경우 파일 이름 확장자의 존재를 확인하기 전에 항목을 확장하더라도 여전히 다음과 같은 방식으로 발생하지 않는다는 사실을 목표로 합니다. 순수한 마음을 만족시킬 것입니다. 파일 이름 확장자가 지정되지 않는다는 graphicx-package의 가정은 정확할 것이며 따라서 graphicx-package는 작동하는 방식으로 기본 확장자를 시도합니다. graphicx-package는
../../code/waveletTest/data/results/synthetic/sine_100hz.pdf,
../../code/waveletTest/data/results/synthetic/sine_100hz.png, 등을 사용하여 시도합니다
../../code/waveletTest/data/results/synthetic/sine_100hz.jpg.
.
첫 번째는 이미 작동합니다.

이 모든 문제는 패키지를 로드하여 해결할 수 있습니다.grff파일:

\documentclass[]{article}
\usepackage{graphicx}
\usepackage{grffile}
\begin{document}

\newcommand{\results}{../../code/waveletTest/data/results/}
\newcommand{\synthetic}{\results synthetic/}
\newcommand{\sine}[1]{sine_#1hz.pdf}

%\includegraphics[width=.3\linewidth]{\synthetic sine_100hz.pdf}

\includegraphics[width=.3\linewidth]{\synthetic\sine{100}}

\end{document}

그런데:

아주 특별한 경우에는 \filename@parse다음을 추가하여 -mechanism을 속여 파일 이름 확장자를 올바르게 분리 할 수 있습니다 \expandafter.

\documentclass[]{article}
\usepackage{graphicx}
\begin{document}

\newcommand{\results}{../../code/waveletTest/data/results/}
\newcommand{\synthetic}{\results synthetic/}
\newcommand{\sine}[1]{sine_#1hz.pdf}

%\includegraphics[width=.3\linewidth]{\synthetic sine_100hz.pdf}

\includegraphics[width=.3\linewidth]{\expandafter\synthetic\sine{100}}

\end{document}

적어도 내 시스템에서는 이것이 작동합니다.

이것이 파일 이름 확장자를 올바르게 분리한다는 점에 유의하십시오.그러나 이것은 파일 이름과 파일 경로를 올바르게 분리하지 않습니다..
파일 경로는 비어 있는 것으로 간주됩니다. 파일 이름에 대한
순서가 \synthetic sine_100hz사용됩니다.
이건 상관 없을 것 같습니다.

그러나 \filename@parseLaTeX 2ε-kernel의 매크로입니다. 그리고 최근 LaTeX 2ε-kernel에는 많은 변화와 혁신이 있었습니다. 아마도 \filename@parse귀하의 시스템이 내 시스템에서처럼 작동하지 않을 수도 있습니다.

\expandafter나는 " 매크로의 최상위 확장에서 확장 불가능한 명시적 문자 토큰 측면에서 파일 경로/파일 이름 사양을 얻기 위해 인수의 첫 번째 토큰을 한 번 누르는 것"이 ​​제거되지 않을 것이라고 가정합니다. \filename@parse. 따라서 파일 경로/파일 이름 사양을 전달하기 위해 한 번의 히트가 필요한
일부 확장 속임수를 적용할 수 있습니다 .\romannumeral\expandafter

\documentclass[]{article}
\usepackage{graphicx}
\begin{document}

\newcommand{\results}{../../code/waveletTest/data/results/}
\newcommand{\synthetic}{\results synthetic/}
\newcommand{\sine}[1]{sine_#1hz.pdf}

%\includegraphics[width=.3\linewidth]{\synthetic sine_100hz.pdf}

\includegraphics[width=.3\linewidth]{\romannumeral0\expandafter\synthetic\sine{100}}

\end{document}

여기서 무슨 일이 일어나는가?

\filename@parse\expandafer"히트"합니다 \romannumeral.
그런 다음 \romannumeral-TeX 수집을 트리거함-⟨숫자⟩-수량이 진행 중입니다:

%\romannumeral-triggered gathering of a TeX-number-quantity is in progress:
0\expandafter\synthetic\sine{100}

이제 LaTeX는 숫자를 찾아서 0버립니다.
이제 TeX-를 수집하는 과정은 다음과 같습니다.⟨숫자⟩-수량은 더 많은 숫자를 모으는 과정으로 바뀌거나 TeX 수집을 종료하는 것으로 변합니다.⟨숫자⟩-수량:

%\romannumeral-triggered gathering of more digits is in progress; digit "0" found.
\expandafter\synthetic\sine{100}

이제 LaTeX가 확장됩니다 \expandafter. 확장 결과가 \expandafter확장되고 있습니다 \sine.

%\romannumeral-triggered gathering of more digits is in progress; digit "0" found.
\synthetic sine_100hz.pdf

이제 LaTeX가 확장됩니다 \synthetic.

%\romannumeral-triggered gathering of more digits is in progress; digit "0" found.
\results synthetic/sine_100hz.pdf

이제 LaTeX가 확장됩니다 \results.

%\romannumeral-triggered gathering of more digits is in progress; digit "0" found.
../../code/waveletTest/data/results/synthetic/sine_100hz.pdf

이제 LaTeX는 점을 찾습니다. 그 점은 숫자가 아닙니다. 공간 토큰과 달리 폐기되지 않습니다. 공간 토큰처럼 \romannumeralTeX-의 (구성 요소) 수집이 종료 됩니다.⟨숫자⟩-수량. 따라서 LaTeX는 숫자/숫자만 찾았 0으며 0은 양수가 아닙니다. 양수가 아닌 숫자를 사용하면 \romannumeral토큰이 전혀 반환되지 않습니다.

%\romannumeral done.
../../code/waveletTest/data/results/synthetic/sine_100hz.pdf

관련 정보