\ pgfmathsetlengthmacro เข้ากันไม่ได้กับลูป?
รหัสต่อไปนี้รวบรวมอย่างสมบูรณ์แบบ:
\documentclass[]{article}
\usepackage[most]{tcolorbox}
\newcommand\UseImageLeft[1]{%
\IfFileExists{#1\i.jpg}%
{\includegraphics[scale=0.2]{#1\i.jpg}}%
{\includegraphics[scale=0.2]{example-image.jpg}}%
}
\def\ImageLeft{\UseImageLeft{Image-}}
% Problem ===================================
% \pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}
% =======================================
\begin{document}
\foreach \i in {1,...,2}{
% On any page (begin)
\begin{tcolorbox}[]
\begin{tcbitemize}[]
\tcbitem[] \ImageLeft
\end{tcbitemize}
\end{tcolorbox}
% On any page (end)
\newpage
}
\end{document}
ปัญหาของฉันคือฉันต้องการยกเลิกการแสดงความคิดเห็น\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}แต่รหัสไม่ได้รวบรวมอีกต่อไป ฉันจะแก้ไขสิ่งนี้ได้อย่างไร?
คำตอบ
ปัญหาที่ 1:
คุณสามารถใช้\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")} นอก\foreach -loop แต่ด้วย\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}แมโคร\ImageLeftถูกนำมาใช้ในการใช้งานซึ่งเปิด\UseImageLeftซึ่งใช้เปิด\iในขณะที่\iมีการกำหนดให้ผลผลิตจำนวนของภาพเท่านั้นภายใน\foreach -loop
ปัญหา 2:
คุณมี\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}รูปแบบใด
\pgfmathsetlengthmacro\LeftWidth{⟨expression⟩}
ด้วย
⟨expression⟩ = width("\ImageLeft")
ขณะที่
width("\ImageLeft")
ในการเปิดเป็นรูปแบบ
ที่มี=
width(⟨expression⟩)
⟨expression⟩"\ImageLeft"
ซึ่งหมายความว่า\ImageLeftได้รับการประเมินเป็นส่วนหนึ่งของ⟨expression⟩สองครั้ง:
ครั้งแรกเมื่อมี⟨expression⟩การ\pgfmathsetlengthmacro\LeftWidthประเมินการสร้างอาร์กิวเมนต์
ครั้งที่สองเมื่อมี⟨expression⟩การwidth(...)ประเมินการสร้างอาร์กิวเมนต์
pgfmanual.pdf ส่วน "95.2 Syntax for Mathematical Expressions: Operators" กล่าวในคำอธิบายของ-operator:"x"
... อย่างไรก็ตามเมื่อทุกนิพจน์ถูกขยายด้วย \ edef ก่อนที่จะแยกวิเคราะห์มาโคร (เช่นคำสั่งแบบอักษรเช่น \ tt หรือ \ Huge) อาจต้องได้รับการ "ป้องกัน" จากส่วนขยายนี้ (เช่น \ noexpand \ Huge) ตามหลักการแล้วคุณควรหลีกเลี่ยงมาโครดังกล่าวอยู่ดี เห็นได้ชัดว่าควรใช้ตัวดำเนินการเหล่านี้ด้วยความระมัดระวังเนื่องจากการคำนวณเพิ่มเติมไม่น่าจะเป็นไปได้กับผลลัพธ์
ข้อมูลนี้ไม่ได้เกี่ยวข้องกับ-operator เท่านั้น ข้อมูลนี้เกี่ยวข้องทุกครั้งที่ต้องประเมินไฟล์. มันเป็นกฎทั่วไปซึ่งถูกนำไปใช้ในระหว่างการประเมินผลของทุกคน ดังนั้นฉันจึงคิดว่าไม่ใช่ความคิดที่ดีที่จะถ่ายทอดข้อมูลนี้ในขณะที่อธิบายตัวดำเนินการพิเศษเท่านั้น"x"⟨expression⟩⟨expression⟩
เป็นไปอย่างนั้น:
เมื่อนำข้อมูลมารวมกันคุณจะพบว่า\ImageLeftมีการประเมิน\edefสองครั้ง ขณะที่การขยายตัวของห่วงโซ่เป็น\ImageLeft→การ\UseImageLeft→การ...\includegraphics...นี้แสดงให้เห็นว่าทั้งสองครั้งความพยายามที่จะประเมิน\includegraphicsผ่าน\edefใช้สถานที่
แต่ในกรณีที่คุณไม่ได้ใช้ TeX-distribution ล่าสุด\includegraphicsไม่สามารถใช้งานได้ใน\edefบริบทการขยายตัว เนื่องจากใน TeX-distribution รุ่นเก่า\includegraphicsไม่ได้รับการ "ป้องกัน" - "ป้องกัน" หมายถึงกลไกภายใน LaTeX สำหรับป้องกันการขยายคำสั่งในสถานการณ์ที่การขยายนั้นใช้ไม่ได้ผลและ "อาศัย" ในการมอบหมายงานชั่วคราว ในแง่ของ\defแม้ว่าการมอบหมายดังกล่าวจะไม่ได้รับการดำเนินการในขณะที่อยู่ระหว่างการ\edefประเมินราคา \edefทริกเกอร์การขยายโทเค็นที่ขยายได้ในขณะที่\defเป็นแบบดั้งเดิมที่ไม่สามารถขยายได้
ดังนั้นหากไม่ได้ใช้ TeX-distribution ล่าสุดคุณจำเป็นต้องใช้มาตรการป้องกันเพื่อป้องกันการขยาย / ประเมินคำสั่ง\ImageLeft(และป้องกันการขยาย / การประเมิน\includegraphics) ด้วยการ\edefประเมินค่าเหล่านี้ (ในการแจกแจง TeX ล่าสุดมาตรการป้องกันเหล่านี้ไม่ก่อให้เกิดความรำคาญหรือไม่จำเป็น)
คุณสามารถป้องกันการขยาย / การประเมินผลโดยนำหน้า\ImageLeftด้วย\noexpand\noexpand\noexpand.
ครั้งแรก\edef-evaluation นำไปใช้ในการ<code>\noexpand\noexpand\noexpand\ImageLeft</code>, อัตราผลตอบแทน
ที่สอง-evaluation จะถูกนำมาใช้ในที่ซึ่งอัตราผลตอบแทนในการเปิด:
<code>\noexpand\ImageLeft</code>\edef
<code>\ImageLeft</code>
ปัญหาที่ 3:
egreg ชี้ให้เห็นว่า\iมีการกำหนดไว้แล้วใน LaTeX และคุณอาจไม่ต้องการแทนที่คำจำกัดความนั้น ดังนั้นในตัวอย่างด้านล่างฉันใช้\NiceForEachElementแทน\i.
\documentclass[]{article}
\usepackage[most]{tcolorbox}
\newcommand\UseImageLeft[1]{%
\IfFileExists{#1\NiceForEachElement.jpg}%
{\includegraphics[scale=0.2]{#1\NiceForEachElement.jpg}}%
{\includegraphics[scale=0.2]{example-image.jpg}}%
}
\def\ImageLeft{\UseImageLeft{Image-}}
% Problem ===================================
%\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}
% =======================================
\begin{document}
\foreach \NiceForEachElement in {1,...,2}{%
\pgfmathsetlengthmacro\LeftWidth{width("\noexpand\noexpand\noexpand\ImageLeft")}%
%Activate the following line in case you wish to see on screen/console what the definition of \LeftWidth looks like now:
%\show\LeftWidth
% On any page (begin)
\begin{tcolorbox}[]%
\begin{tcbitemize}[]%
\tcbitem[] \ImageLeft
\end{tcbitemize}%
\end{tcolorbox}%
% On any page (end)
\newpage
}
\end{document}
หากคุณต้องการที่จะสามารถใช้\ImageLeftนอกวงเกินไปแล้วกำหนด\ImageLeftฯลฯ เพื่อดำเนินการโต้แย้งแทนของการประมวลผล/\i
ภายในลูปคุณสามารถส่งผ่าน/ เป็นอาร์กิวเมนต์ได้
นอกลูปคุณสามารถส่งผ่านหมายเลขของรูปภาพเป็นอาร์กิวเมนต์ได้โดยตรง\NiceForEachElement\i\NiceForEachElement
\documentclass[]{article}
\usepackage[most]{tcolorbox}
% Define the command \NiceForEachElement to ensure error-message in case it is already defined.
% This way you can ensure to a certain degree that using `\niceelement` as Foreach-variable
% does not override something that alerady exists.
\newcommand\NiceForEachElement{}%
\newcommand\UseImageLeft[2]{%
% #1 preceding phrase "image-"
% #2 number of image
\IfFileExists{#1#2.jpg}%
{\includegraphics[scale=0.2]{#1#2.jpg}}%
{\includegraphics[scale=0.2]{example-image.jpg}}%
}
\newcommand*\ImageLeft[1]{\UseImageLeft{Image-}{#1}}
% Problem ===================================
%\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}
% =======================================
\begin{document}
% outside the loop the width of Image-7.jpg or example-image.jpg:
\pgfmathsetlengthmacro\LeftWidth{width("\noexpand\noexpand\noexpand\ImageLeft{7}")}%
%Activate the following line in case you wish to see on screen/console what the definition of \LeftWidth looks like now:
%\show\LeftWidth
% inside the loop:
\foreach \NiceForEachElement in {1,...,2}{%
\pgfmathsetlengthmacro\LeftWidth{width("\noexpand\noexpand\noexpand\ImageLeft{\NiceForEachElement}")}%
%Activate the following line in case you wish to see on screen/console what the definition of \LeftWidth looks like now:
%\show\LeftWidth
% On any page (begin)
\begin{tcolorbox}[]%
\begin{tcbitemize}[]%
\tcbitem[] \ImageLeft{\NiceForEachElement}%
\end{tcbitemize}%
\end{tcolorbox}%
% On any page (end)
\newpage
}
\end{document}
อย่าใช้ตัวแปรการวนซ้ำนอกลูปทั้งในโค้ดที่เรียกใช้งานหรือในคำจำกัดความ
\documentclass[]{article}
\usepackage[most]{tcolorbox}
\newcommand\UseImageLeft[1]{%
\IfFileExists{#1.jpg}%
{\includegraphics[scale=0.2]{#1.jpg}}%
{\includegraphics[scale=0.2]{example-image.jpg}}%
}
\begin{document}
\foreach \i in {1,...,2}{%
\pgfmathsetlengthmacro\LeftWidth{width("\UseImageLeft{image\i}")}%
% On any page (begin)
\begin{tcolorbox}[]
\begin{tcbitemize}[]
\tcbitem[] \UseImageLeft{image\i}
\end{tcbitemize}
\end{tcolorbox}
% On any page (end)
\newpage
}^
\end{document}