我可以创建\newwrite
这样的:
\newwrite\filehandle
\immediate\openout\filehandle=\jobname-semantically_useful_suffix.txt
\immediate\closeout\filehandle
假设我在宏中存储了一些语言:da、de、en……循环每种语言并将其存储为\langcode
我需要为每种语言提供一个唯一的文件句柄。我想要这样的东西:
\documentclass{article}
\usepackage{fontspec}% xelatex
\usepackage{tikz}% foreach
\usepackage{morewrites}% unnecessary for this example, but useful in practice to exceed 16-write limit in TeX
\def\writelangouts{%
\foreach \langcode in {da,de,en} {% from tikz package
\newwrite\filehandle-\langcode
\immediate\openout\filehandle-\langcode=\jobname-semantically_useful_suffix_\langcode.txt
\immediate\closeout\filehandle-\langcode
}%
}%
\AtEndDocument{\writelangouts}
\begin{document}
\jobname
\end{document}% \writelangouts executed here
我想要一份命名约定列表文件句柄宏(\newwrite
) 和文件名(\openout=filename
)。
- 我认为您不能使用
\csname...\endcsname
文件句柄宏。 - 我假设文件名取决于本地文件系统的命名约定。
笔记:
实际上,我正在定义分段命令(标题),将它们的数字写入宏,以便为每种语言创建类似目录的结构。然后,我将每种语言的输出与 Unix 实用程序进行比较diff
以查找差异。这对于交叉检查翻译特别有用。
例如
§ 1
§ 1.1
§ 1.1.1
§ 1.1.2
§ 1.2
§ 2
§ 2.1
§ 2.2
答案1
\newwrite\foo
将符号名称指定为等于写入文件寄存器,因此使用 可以实现的任何事情\csname ...\endcsname
也可以使用\newwrite
或实现\newread
,以及使用\openout
、\openin
、\closein
、\closeout
。
\newwrite
本身不是TeX
原语,而是通过 分配给宏名下一个空闲的输出流号\chardef
,同样如此\newread
——两个流方向彼此独立!
从这个意义上讲,文件句柄只不过是一个扩展为数字的宏,这样\immediate\write6
等等也是可能的。(或者考虑用\immediate\write18
(假设启用了 shell-escape)写入 shell)。
如果语句中有另一个宏\csname...\endcsname
,请使用\expandafter
。
\csname ... \endcsname
现在的问题是:这种方法有多可行?一直重复使用可能会很乏味!
\@starttoc
以下是来自命令的类似代码latex.ltx
:
\def\@starttoc#1{%
\begingroup
\makeatletter
\@input{\jobname.#1}%
\if@filesw
\expandafter\newwrite\csname tf@#1\endcsname
\immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
\fi
\@nobreakfalse
\endgroup}
可以看出,toc 文件的文件句柄是在每次\@starttoc
调用时动态生成的。
需要考虑的几点:
我的解决方案只有在打开、写入和关闭都在循环内时才正确
\foreach
,因为这会建立一个组,因此文件名句柄宏名称在 - 循环之外不可用\foreach
。但是,不建议使用此过程。真的有必要为每个文件使用一个新的句柄吗?不,其实不需要,因为显然文件句柄是生成的,文件是打开的等等,而“活动”文件是由
\foreach
循环变量决定的\langcode
,因此不可能轻易地同时写入多个文件(句柄)。
\documentclass{article}
\usepackage{fontspec}% xelatex
\usepackage{tikz}% foreach
\usepackage{morewrites}% unnecessary for this example, but useful in practice to exceed 16-write limit in TeX
\def\writelangouts{%
\foreach \langcode in {da,de,en} {% from tikz package
\expandafter\newwrite\csname filehandle-\langcode\endcsname
\immediate\openout\csname filehandle-\langcode\endcsname=\jobname-semantically_useful_suffix_\langcode.txt
\immediate\closeout\csname filehandle-\langcode\endcsname
}%
}%
\def\otherwritelangouts{%
\foreach \langcode in {da,de,en} {% from tikz package
\def\fhandle{\csname filehandle-\langcode\endcsname}
\newwrite\fhandle%
\immediate\openout\fhandle=\jobname-semantically_useful_suffix_\langcode.txt
\immediate\closeout\fhandle
}%
}%
\AtEndDocument{\writelangouts}
\begin{document}
\jobname
\end{document}
假设上述文件名为fhandle.tex
,则.log
- 文件显示生成了以下文件句柄(在文档末尾,因为\writelangouts
在 中使用\AtEndDocument
)
ABD: EveryShipout initializing macros
\AtBeginShipoutBox=\box53
\filehandle-da=\write5
\openout4 = `fhandle-semantically_useful_suffix_da.txt'.
\filehandle-de=\write6
\openout4 = `fhandle-semantically_useful_suffix_de.txt'.
\filehandle-en=\write7
\openout4 = `fhandle-semantically_useful_suffix_en.txt'.
答案2
如果您的任务是在同一循环中打开一个文件、写入数据并关闭它\foreach
,那么您只需要一个文件句柄。
\documentclass{article}
\usepackage{tikz}% foreach
\newwrite\langouts
\newcommand\writelangouts{%
\foreach \langcode in {da,de,en} {% from tikz package
\immediate\openout\langouts=\jobname-\langcode.txt
\immediate\write\langouts{This is \langcode}
\immediate\closeout\langouts
}%
}
\AtEndDocument{\writelangouts}
\begin{document}
\jobname
\end{document}
书面文件的内容
test-da.txt
This is da
test-de.txt
This is de
test-en.txt
This is en