这是我第一次使用 TeX Stack Exchange,所以如果我无意中冒犯了任何人,请原谅我。
编译环境(用来pdflatex
编译):
WSL: x86_64 Linux 5.15.133.1-microsoft-standard-WSL2
TeX Live: 2023/Arch Linux
示例文件夹文件如下:
├── file.txt
└── main.tex
file.txt
包含以下内容:
Hello World
以下是mwe
(来源main.tex
):
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
% file content in line by line (seq)
\ior_new:N \g_file_stream
\cs_new_protected:Nn \File_read_lines:n{
\ior_open:Nn \g_file_stream { #1 }
\seq_gclear_new:N \g_current_aux_hash_seq
\ior_map_inline:Nn \g_file_stream
{
\seq_gput_right:Nx \g_current_aux_hash_seq{ \tl_trim_spaces:n { ##1 } }
}
\ior_close:N \g_file_stream
}
% check
\NewDocumentCommand\Test{ m }{
% write hash to external_code.aux
\str_new:N \file_current_hash_str
\file_get_mdfive_hash:nN { #1 }\file_current_hash_str
\sys_shell_now:x {echo~ "\file_current_hash_str" >> external_code.aux}
% read hash seq from file external_code.aux
\File_read_lines:n {external_code.aux}
% check if in
\noindent The ~ \textbackslash seq_if_in:NnTF~ result~ is:\par
\begin{itemize}
\item \seq_if_in:NnTF \g_current_aux_hash_seq{\seq_item:Nn \g_current_aux_hash_seq{1}}{In\par}{Not~ In\par}
\item \seq_if_in:NnTF \g_current_aux_hash_seq{\str_use:N \file_current_hash_str}{In\par}{Not~ In\par}
\item \seq_if_in:NnTF \g_current_aux_hash_seq{B10A8DB164E0754105B7A99BE72E3FE5}{In\par}{Not~ In\par}
\end{itemize}
% direct output results
while~ the~ print~ result~ is~ the~ same
\begin{itemize}
\item \textbackslash file_current_hash_str~is:\str_use:N \file_current_hash_str\par
\item \textbackslash seq_item:Nn \textbackslash g_current_aux_hash_seq\{1\}~ is~:\seq_item:Nn \g_current_aux_hash_seq{1}\par
\end{itemize}
cs~ meaning~ cmd~ result:
\begin{itemize}
\item \cs_meaning:N \file_current_hash_str
\item \cs_meaning:N \g_current_aux_hash_seq
\end{itemize}
}
\ExplSyntaxOff
\begin{document}
\Test{file.txt}
\end{document}
我尝试\file_current_hash_str
使用\str_new
、、\seq_new
来设置变量tl_new
,但这些都不起作用。但我发现当我设置\file_current_hash_str
时
\newcommand{\cmdseq}{ Hello }
以下是mwe
我的尝试
\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
% set seq
\seq_new:N \test_seq
\seq_set_from_clist:Nn \test_seq{Hello, world, prime, bye}
% test if in
\newcommand{\cmdseq}{ Hello }
\seq_if_in:NVTF \test_seq{\cmdseq}{In\par}{Not~ In\par}
\ExplSyntaxOff
\end{document}
生成输出:
我想知道是否有办法解决这个问题,谢谢。
答案1
构造
\seq_if_in:NnTF \g_current_aux_hash_seq{\str_use:N \file_current_hash_str}
检查序列是否包含确切地 \str_use:N \file_current_hash_str
。相反,您想要检查序列是否包含字符串的值:
\seq_if_in:NVTF \g_current_aux_hash_seq \file_current_hash_str
您还需要观察类别代码。您有一个str
来自哈希函数的 ,但是如果您写入文件并使用 读回\io_map_stream:Nn
,则 中的值将使用正常的类别代码进行标记。因此使用\io_str_map_stream:Nn
来完成这项工作:
\begin{filecontents*}{\jobname.txt}
Hello world
\end{filecontents*}
\documentclass{article}
\ExplSyntaxOn
\ior_new:N \g__zpd_file_ior
\seq_new:N \g__zpd_file_seq
\cs_new_protected:Nn \zpd_file_read_lines:n
{
\ior_open:Nn \g__zpd_file_ior {#1}
\seq_gclear:N \g__zpd_file_seq
\ior_str_map_inline:Nn \g__zpd_file_ior
{
\seq_gput_right:Ne \g__zpd_file_seq
{ \tl_trim_spaces:n {##1} }
}
\ior_close:N \g__zpd_file_ior
}
\cs_generate_variant:Nn \zpd_file_read_lines:n { e }
\seq_new:N \g__zpd_hash_str
\NewDocumentCommand\Test{ m }
{
\file_get_mdfive_hash:nN {#1} \g__zpd_hash_str
\sys_shell_now:e { echo~ "\g__zpd_hash_str" >> \jobname.txt.hash}
% read hash seq from file external_code.aux
\zpd_file_read_lines:e { \jobname.txt.hash }
\seq_show:N \g__zpd_file_seq
\str_show:N \g__zpd_hash_str
% check if in
The ~ \textbackslash seq_if_in:NnTF~ result~ is:\par
\begin{itemize}
\item \seq_if_in:NVTF \g__zpd_file_seq \g__zpd_hash_str
{In\par}{Not~ In\par}
\end{itemize}
}
\ExplSyntaxOff
\begin{document}
\Test{\jobname.txt}
\end{document}
(我已经整理好了命名等等。)