Tikz foreach không hoạt động với \ input hoặc \ directlua

Nov 12 2020

Khi tôi đang cố gắng để tải dữ liệu cho tikz's \foreachsử dụng \input, hoặc sau đó với \directluatôi nhận thấy rằng nó không được tách ra.

    \foreach \a / \n in {\directlua{tex.sprint("a/b")}}
      {\a}

Tôi có thể (và làm cách nào) buộc nó phải được phân tích cú pháp chính xác không?

kết quả trong

Trả lời

3 Skillmon Nov 12 2020 at 23:00

Bạn phải mở rộng \directluatrước khi \foreachquét đối số. Điều này có thể được thực hiện với \expandednguyên thủy:

\documentclass[]{article}

\usepackage[]{tikz}

\begin{document}
\expanded{\unexpanded{\foreach \a / \n in }{\directlua{tex.sprint("a/b")}}}
  {\a\ and \n}

\end{document}
2 Rmano Nov 13 2020 at 00:49

Đây là những gì tôi sử dụng khi muốn xem foreachqua nội dung tệp (không chắc chắn, nhưng có thể được sao chép từ Đọc dữ liệu để lặp lại với \ foreach từ tệp ):

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pgffor}
\begin{filecontents}[overwrite]{mylist.txt}
    a/b, 1/2,
    c/d
\end{filecontents}
\usepackage{catchfile}
\newcommand\loaddata[1]{\CatchFileDef\loadeddata{#1}{\endlinechar=-1}}
\begin{document}
    \loaddata{mylist.txt}
    \foreach \one/\two in \loadeddata {\one--\two\par}
\end{document}

2 HenriMenke Nov 14 2020 at 01:00

Bạn có thể sử dụng bản vá được cung cấp bên dưới để cung cấp expand listtùy chọn mở rộng hoàn toàn danh sách trước khi sử dụng.

\documentclass{article}
\usepackage{pgffor}
\begin{document}
\foreach [expand list=true] \a / \n in {\directlua{tex.sprint("a/b")}} {
    \a
}
\end{document}
diff --git a/tex/generic/pgf/utilities/pgffor.code.tex b/tex/generic/pgf/utilities/pgffor.code.tex
index cdb77b31..65b62b8c 100644
--- a/tex/generic/pgf/utilities/pgffor.code.tex
+++ b/tex/generic/pgf/utilities/pgffor.code.tex
@@ -79,10 +79,13 @@
     \fi%
 }
 
+\def\pgffor@expand@list@true{\let\pgffor@expand@list\edef}
+\def\pgffor@expand@list@false{\let\pgffor@expand@list\def}
 \def\pgffor@macro@list#1{%
   \expandafter\pgffor@normal@list\expandafter{#1}}
 \def\pgffor@normal@list#1{%
-  \def\pgffor@values{#1, \pgffor@stop,}%
+  \pgffor@expand@list\pgffor@values{#1}%
+  \expandafter\def\expandafter\pgffor@values\expandafter{\pgffor@values, \pgffor@stop,}%
   \ifx\pgffor@values\pgffor@emptyvalues
     \def\pgffor@values{\pgffor@stop,}%
   \fi%
@@ -619,6 +622,9 @@
     count/.code=\pgffor@count@parse#1\pgffor@stop,
     parse/.is if=pgffor@assign@parse,
     parse/.default=false,
+    expand list/.is if=pgffor@expand@list@,
+    expand list/.default=true,
+    expand list=false,
 }
 
 \def\pgffor@assign@parse#1{%

Thay vì vá cài đặt PGF của bạn (sẽ bị ghi đè bởi bản cập nhật tiếp theo), bạn cũng có thể đưa trực tiếp các định nghĩa cần thiết vào tài liệu của mình.

\documentclass{article}
\usepackage{pgffor}

\makeatletter
\def\pgffor@expand@list@true{\let\pgffor@expand@list\edef}
\def\pgffor@expand@list@false{\let\pgffor@expand@list\def}
\def\pgffor@normal@list#1{%
  \pgffor@expand@list\pgffor@values{#1}%
  \expandafter\def\expandafter\pgffor@values\expandafter{\pgffor@values, \pgffor@stop,}%
  \ifx\pgffor@values\pgffor@emptyvalues
    \def\pgffor@values{\pgffor@stop,}%
  \fi%
  \let\pgffor@body=\pgfutil@empty%
  \global\pgffor@continuetrue%
  \pgffor@collectbody}
\makeatother

\pgfqkeys{/pgf/foreach}{
  expand list/.is if=pgffor@expand@list@,
  expand list/.default=true,
  expand list=false,
}

\begin{document}
\foreach [expand list=true] \a / \n in {\directlua{tex.sprint("a/b")}} {
  \a
}
\end{document}