
을 사용하여 포함하기 위해 "#"이 포함된 파일 이름을 가진 수백 개의 그림이 있습니다. 또는 \includegraphics
같은 패키지를 시도했지만 그 중 아무 것도 작동하지 않습니다. 수백 개의 파일 이름을 변경할 필요가 없도록 실제 솔루션을 제안할 수 있는 사람이 있습니까? 감사해요.grffile
currfile
업데이트: 1. 저는 Windows를 사용하고 있습니다. 2. 컴파일하면 "정의에 잘못된 매개변수 번호가 있습니다"라고 나옵니다.
답변1
#
사용하기 전에 의 catcode를 변경할 수 있습니다 .
\documentclass[]{article}
\usepackage{graphicx}
\begin{document}
{\catcode`\#=12 \includegraphics{test#abc}}
\end{document}
하지만 그런 이름은 피하는 것이 정말 좋습니다.
답변2
매크로 내부에서 까다로울 수 있는 catcode 변경에 대한 대안:
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{a\string##b.png}
\end{document}
답변3
카테고리 코드는 변경될 수 있습니다.답변울리케 피셔. 또는 해시를 매크로 안에 숨길 수도 있습니다.
\edef\hash{\string#}
\hash
숫자와 같은 문자의 범주 코드(12/기타)를 사용하여 해시로 확장되는 매크로로 정의됩니다.
예:
\documentclass{article}
\usepackage{graphicx}
% \usepackage{grffile}
\newcommand*{\hash}{}% print error message if \hash is already defined
\edef\hash{\string#}
\begin{document}
\includegraphics[width=.5\linewidth]{test\hash abc}% "test#abc"
\end{document}
답변4
문제는 그래픽/graphicx 패키지의 파일 이름 처리/구문 분석으로 인해 발생합니다.
인수로 제공된 파일 이름은 \includegraphics
임시 매크로의 정의 텍스트로 전달됩니다.
이러한 임시 매크로가 확장되면 연속 해시의 양이 절반으로 줄어들고 인수를 표시하기 위해 1..9 범위의 숫자 앞에 오는 마커에 대해 단일 해시가 사용됩니다.
\toks@{..}...\edef..{..\the\toks@..}
이 문제는 또는 를 통해 해결되었을 수 있습니다 \edef...{\unexpanded{..}..}
.
\detokenize
eTeX 확장의 -primitive를 사용할 수 있는 경우 토큰이 범주 코드 6(매개변수)의 명시적 문자 토큰인지 확인하는 기능을 구현할 수 있습니다.
따라서 eTeX 확장의 -프리미티브를 사용할 수 있는 경우 \detokenize
파일 이름의 모든 해시(카테고리 코드 6의 모든 명시적 문자 토큰)를 문자열화/카테고리 코드-12 펜던트로 재귀적으로 바꾸는 루틴을 구현할 수 있습니다. :
% This example uses \detokenize and thus requires eTeX extensions.
\documentclass{article}
\usepackage{graphicx}
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo,
%% \UD@PassFirstToSecond, \UD@Exchange, \UD@removespace
%% \UD@CheckWhetherNull, \UD@CheckWhetherBrace,
%% \UD@CheckWhetherLeadingSpace, \UD@ExtractFirstArg
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@removespace{}\UD@firstoftwo{\def\UD@removespace}{} {}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's first token is a catcode-1-character
%%.............................................................................
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has leading
%% catcode-1-token>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has no leading
%% catcode-1-token>}%
\newcommand\UD@CheckWhetherBrace[1]{%
\romannumeral0\expandafter\UD@secondoftwo\expandafter{\expandafter{%
\string#1.}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@firstoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% \UD@CheckWhetherLeadingSpace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>}%
\newcommand\UD@CheckWhetherLeadingSpace[1]{%
\romannumeral0\UD@CheckWhetherNull{#1}%
{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
{\expandafter\UD@secondoftwo\string{\UD@CheckWhetherLeadingSpaceB.#1 }{}}%
}%
\newcommand\UD@CheckWhetherLeadingSpaceB{}%
\long\def\UD@CheckWhetherLeadingSpaceB#1 {%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#1{}}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter}\expandafter\expandafter
\expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%% \UD@ExtractFirstArg{ABCDE} yields {A}
%%
%% \UD@ExtractFirstArg{{AB}CDE} yields {AB}
%%.............................................................................
\newcommand\UD@RemoveTillUD@SelDOm{}%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
\newcommand\UD@ExtractFirstArg[1]{%
\romannumeral0%
\UD@ExtractFirstArgLoop{#1\UD@SelDOm}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{ #1}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% \ReplaceEveryHash{<argument>}%
%%
%% Each explicit catcode-6(parameter)-character-token of the <argument>
%% will be replaced by its stringification.
%%
%% You obtain the result after two expansion-steps, i.e.,
%% in expansion-contexts you get the result after "hitting"
%% \ReplaceEveryHash by two \expandafter.
%%
%% As a side-effect, the routine does replace matching pairs of explicit
%% character tokens of catcode 1 and 2 by matching pairs of curly braces
%% of catcode 1 and 2.
%% I suppose this won't be a problem in most situations as usually the
%% curly braces are the only characters of category code 1 / 2...
%%
%% This routine needs \detokenize from the eTeX extensions.
%%-----------------------------------------------------------------------------
\newcommand\ReplaceEveryHash[1]{%
\romannumeral0\UD@ReplaceEveryHashLoop{#1}{}%
}%
\newcommand\UD@ReplaceEveryHashLoop[2]{%
\UD@CheckWhetherNull{#1}{ #2}{%
\UD@CheckWhetherLeadingSpace{#1}{%
\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@removespace#1}{#2 }%
}{%
\UD@CheckWhetherBrace{#1}{%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral0\expandafter\UD@ReplaceEveryHashLoop
\romannumeral0\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{}%
}{#2}}%
{\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@firstoftwo{}#1}}%
}{%
\expandafter\UD@CheckWhetherHash
\romannumeral0\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{#1}{#2}%
}%
}%
}%
}%
\newcommand\UD@CheckWhetherHash[3]{%
\expandafter\UD@CheckWhetherLeadingSpace\expandafter{\string#1}{%
\expandafter\expandafter\expandafter\UD@CheckWhetherNull
\expandafter\expandafter\expandafter{%
\expandafter\UD@removespace\string#1}{%
\expandafter\expandafter\expandafter\UD@CheckWhetherNull
\expandafter\expandafter\expandafter{%
\expandafter\UD@removespace\detokenize{#1}}{% Something whose stringification yields a single space
\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@firstoftwo{}#2}{#3#1}%
}{% Explicit space of catcode 6
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{\expandafter\UD@Exchange
\expandafter{\string#1}{#3}}{%
\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@firstoftwo{}#2}%
}%
}%
}{% Something whose stringification has a leading space
\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@firstoftwo{}#2}{#3#1}%
}%
}{%
\expandafter\expandafter\expandafter\UD@CheckWhetherNull
\expandafter\expandafter\expandafter{%
\expandafter\UD@firstoftwo
\expandafter{\expandafter}\string#1}{%
\expandafter\expandafter\expandafter\UD@CheckWhetherNull
\expandafter\expandafter\expandafter{%
\expandafter\UD@firstoftwo
\expandafter{\expandafter}\detokenize{#1}}{% No Hash
\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@firstoftwo{}#2}{#3#1}%
}{% Hash
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{\expandafter\UD@Exchange
\expandafter{\string#1}{#3}}{%
\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@firstoftwo{}#2}%
}%
}%
}{% No Hash
\expandafter\UD@ReplaceEveryHashLoop
\expandafter{\UD@firstoftwo{}#2}{#3#1}%
}%
}%
}%
%----------------------------------------------------------------------
\makeatother
\begin{document}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\mytempa
\expandafter\expandafter\expandafter{\ReplaceEveryHash{F#m.png}}
\includegraphics[width=5cm]{\mytempa}
\end{document}
하지만 단순히 해시를 교체하는 것이 최선의 해결책은 아닙니다. 이유: 파일 이름에는 해시 외에도 불균형 중괄호 등이 포함될 수 있습니다. 따라서 .tex-input-file에서 읽고 verbatim-category-code-régime에서 매크로 인수를 토큰화하는 루틴이 유용할 수 있습니다.
\UDcollectverbarg
다음 구문을 사용하여 매크로를 제공할 수 있습니다 .
\UDcollectverbarg{⟨^^M-replacement⟩}{⟨mandatory 1⟩}{⟨mandatory 2⟩}⟨verbatimized argument⟩
결과는 다음과 같습니다.
⟨mandatory 1⟩{⟨mandatory 2⟩{⟨verbatim argument⟩}}
^^M
, 줄의 끝을 나타내는 각 문자는 token-sequence 로 대체됩니다 ⟨^^M-replacement⟩
.
인수 ⟨mandatory 1⟩
및 ⟨mandatory 2⟩
는 필수입니다. 여러 토큰으로 구성된 경우 이러한 토큰은 catcode-1/2-explicit-character-token-pair / 중괄호에 중첩되어야 합니다.
읽기 및 토큰화가 필요한 경우 변경되지 않은 카테고리 코드 체계에 따라 수행됩니다. 또한
필수 ⟨verbatim argument⟩
입니다. 이는 축어적 카테고리 코드 체계에 따라 읽고 토큰화됩니다. 첫 번째 문자가 중괄호이면 인수가 중괄호 안에 중첩되어 있다고 "가정"됩니다. 그렇지 않으면 해당 인수의 끝이 의 인수처럼 첫 번째 문자로 구분되는 것으로 가정됩니다 \verb
.
빈 줄은 무시되지 않습니다.
⟨mandatory 2⟩
이 구문을 사용하면 inside 호출을 중첩하여 \UDcollectverbarg
내 에서 축어적 인수를 수집할 수 있으므로 이 구문을 선택했습니다 ⟨mandatory 1⟩
.
예:
\UDcollectverbarg{<^^M-replacement>}%
{\UDcollectverbarg{<^^M-replacement>}{\UDcollectverbarg{<^^M-replacement>}{<actionA>}}}% <- mandatory 1
{<actionB>}% <- mandatory 2
<verbatim argument 1><verbatim argument 2><verbatim argument 3>
수익률:
\UDcollectverbarg{<^^M-replacement>}{\UDcollectverbarg{<^^M-replacement>}{<actionA>}}% <- mandatory 1
{<actionB>{<verbatimd argument 1>}}% <- mandatory 2
<verbatim argument 2><verbatim argument 3>
수익률:
\UDcollectverbarg{<^^M-replacement>}{<actionA>}% <- mandatory 1
{<actionB>{<verbatim argument 1>}{<verbatim argument 2>}}% <- mandatory 2
<verbatim argument 3>
수익률:
<actionA>{<actionB>{<verbatim argument 1>}{<verbatim argument 2>}{<verbatim argument 3>}}
가정 <actionA>
= \@firstofone
:
\@firstofone{<actionB>{<verbatim argument 1>}{<verbatim argument 2>}{<verbatim argument 3>}}
수익률:
<actionB>{<verbatim argument 1>}{<verbatim argument 2>}{<verbatim argument 3>}
% This example does not require eTeX extensions.
\errorcontextlines=10000
\makeatletter
%%<-------------------- Code for \UDcollectverbarg -------------------->
%% Copyright (C) 2007 - 2019 by Ulrich Diez ([email protected])
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public Licence (LPPL), either
%% version 1.3 of this license or (at your option) any later
%% version. (The latest version of this license is in:
%% http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 1999/12/01 or later.)
%% The author of this work is Ulrich Diez.
%% This work has the LPPL maintenance status 'not maintained'.
%% Usage of any/every component of this work is at your own risk.
%% There is no warranty - neither for probably included
%% documentation nor for any other part/component of this work.
%% If something breaks, you usually may keep the pieces.
%
\newcommand\UD@firstofone[1]{#1}%
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
%%
%% Check whether argument is empty:
%%......................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%......................................................................
\begingroup
\catcode`\^^M=12 %
\UD@firstofone{%
\endgroup%
\newcommand\UDEndlreplace[2]{\romannumeral0\@UDEndlreplace{#2}#1^^M\relax{}}%
\newcommand*\@UDEndlreplace{}%
\long\def\@UDEndlreplace#1#2^^M#3\relax#4#5{%
\UD@CheckWhetherNull{#3}%
{ #5{#4#2}}{\@UDEndlreplace{#1}#3\relax{#4#2#1}{#5}}%
}%
}%
\newcommand\UDcollectverbarg[3]{%
\begingroup
\let\do\@makeother % <- this and the next line switch to
\dospecials % verbatim-category-code-régime.
\catcode`\{=1 % <- give opening curly brace the usual catcode so a
% curly-brace-balanced argument can be gathered in
% case of the first thing of the verbatimized-argument
% being a curly opening brace.
\catcode`\ =10 % <- give space and horizontal tab the usual catcode so \UD@collectverbarg
\catcode`\^^I=10 % cannot catch a space or a horizontal tab as its 4th undelimited argument.
% (Its 4th undelimited argument denotes the verbatim-
% syntax-delimiter in case of not gathering a
% curly-brace-nested argument.)
\kernel@ifnextchar\bgroup
{% seems a curly-brace-nested argument is to be caught:
\catcode`\}=2 % <- give closing curly brace the usual catcode also.
\UD@collectverbarg{#1}{#2}{#3}{}%
}{% seems an argument with verbatim-syntax-delimiter is to be caught:
\do\{% <- give opening curly brace the verbatim-catcode again.
\UD@collectverbarg{#1}{#2}{#3}%
}%
}%
\newcommand\UD@collectverbarg[4]{%
\do\ % <- Now that \UD@collectverbarg has the delimiter or
\do\^^I% emptiness in its 4th arg, give space and horizontal tab
% the verbatim-catcode again.
\do\^^M% <- Give the carriage-return-character the verbatim-catcode.
\long\def\@tempb##1#4{%
%\edef\@tempb{##1}%
\def\@tempb{##1}%
\@onelevel@sanitize\@tempb % <- Turn characters into their "12/other"-pendants.
% This may be important with things like the
% inputenc-package which may make characters
% active/which give them catcode 13(active).
\expandafter\UDEndlreplace\expandafter{\@tempb}{#1}{\def\@tempb}% <- this starts
% the loop for replacing endline-characters.
\expandafter\UD@@collectverbarg\expandafter{\@tempb}{#2}{#3}% <- this "spits
% out the result.
}%
\@tempb
}%
\newcommand\UD@@collectverbarg[3]{%
\endgroup
#2{#3{#1}}%
}%
%%<---------------- End of code for \UDcollectverbarg ----------------->
\makeatother
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\begingroup\catcode`\^^M=12\relax%
\UDcollectverbarg{^^M}{\endgroup\csname @firstofone\endcsname}{\def\mytempa}|F#m.png|%
\includegraphics[width=5cm]{\mytempa}
\end{document}