多语言文档
问题
我想关注“不要重复自己”的原则并创建一个输入列表,这些输入实际上是同一文档的不同语言版本。这个问题与此相关。
这个问题是一系列问题的一部分。我的目标是在节点内使用此列表tikz
,但为了保持简单,我从这个问题中删除了这一点。所以,对于那些感兴趣的人,以下是供参考的快速列表:
有关制作可以处理解析后输入列表项的宏的相关问题,请参阅:
对于具有节点支持的相同解决方案tikz
,请参阅:
更新2015-03-08:以下代码基于egreg的答案
50% 的时间有效
看如何使用存储在 aux 中的列表并将其输出插入 tikz 节点?
情况
我想创建一个包含以下内容的命令:
- iso 639-1 代码为 #1
- 母语中的语言名称为 #2
- 输入文件为#3
例子:\inputlanguagefile{En}{English}{./Languages/en.tex}
然后我想从这些输入中创建一个语言代码列表,可以在我的自定义\maketitle
命令中使用(警告:\maketitle 输入直接发送到tikz
节点)
问题
困难在于列表在创建之前被调用。我可能需要事先创建某种命令来循环遍历输入。文档看起来是这样的:
%\maketitle[subtitle]{title}
\maketitle[listoflanguagecodes]{Multilingual Document}
\inputlanguagefile{En}{English}{./Languages/en.tex}
\inputlanguagefile{Da}{Dansk}{./Languages/da.tex}
\inputlanguagefile{De}{Deutsch}{./Languages/de.tex}
\inputlanguagefile{It}{Italiano}{./Languages/it.tex}
\inputlanguagefile{Hu}{Magyarország}{./Languages/hu.tex}
重新定义 \maketitle
\maketitle[副标题]{标题} \maketitle[\listoflanguagecodes]{标题}
\renewcommand{\maketitle}[2][]{%
\thispagestyle{empty}
#1\\
#2
\clearpage
\setcounter{page}{1}
}%
第二个参数,即实际的语言名称仅用于创建语言目录etoc
。
平均能量损失
我正在尝试整理一个复杂设置的最小工作示例。工作正在进行中。
autolanglist/
├── Languages
│ ├── da.tex
│ ├── de.tex
│ └── en.tex
└── usermanual.tex
1 个目录,4 个文件
内容 usermanual.tex
\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
\usepackage[explicit]{titlesec}
\usepackage{tocloft}
\usepackage{etoc}
\usepackage{lipsum}
\usepackage{hyperref}
\newcounter{runningsectioncounter}
\setcounter{runningsectioncounter}{0}
\titleformat{\section}[hang]{\color{red}\Huge\bfseries}{}{0pt}{\thesection\quad#1}[\stepcounter{runningsectioncounter}]
% Use this \newlangfile{<code>}{<name>}{<file>} to add external language varieties
\newcommand{\inputlanguagefile}[3]{%
\newpage\pdfbookmark{#2}{bkm#1}%
\etoctoccontentsline{part}{#2}%
\setcounter{runningsectioncounter}{\value{section}}
\setcounter{section}{0}
\renewcommand*{\theHsection}{chX.\the\value{runningsectioncounter}} % Keeps hyperref happy (provides unique section numbers instead of using the section counter)
\input{#3}%
}
\renewcommand{\maketitle}[2][]{%
#1\\
#2
\clearpage
}%
\newcommand{\usermanualfrontmatter}{%
\maketitle[En, Da, De]{User Manual} % NOTE: This is the list of language codes should be automated!
\newpage
\setcounter{tocdepth}{0} % make ToC contain only parts
\renewcommand{\contentsname}{Language Directory} % change ToC Title
\tableofcontents
\newpage
\setcounter{tocdepth}{4}
\renewcommand{\contentsname}{Table of Contents} % reset ToC Title back to default
}%
\begin{document}
\usermanualfrontmatter{}
\inputlanguagefile{En}{English}{./Languages/en.tex}
\inputlanguagefile{Da}{Dansk}{./Languages/da.tex}
\inputlanguagefile{De}{Deutsch}{./Languages/de.tex}
\end{document}
./Languages/da.tex 的内容
\maketitle[da]{Brugsanvisning}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]
./Languages/de.tex 的内容
\maketitle[de]{Gebrauchsanweisung}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]
./Languages/en.tex 的内容
\maketitle[en]{User Manual}
\localtableofcontents
\clearpage
\section{Test}
\lipsum[50]
输出
第一页是缩小版的 A4 纸,但其余页面也调整为 100mm x 150mm,以节省本网站的屏幕空间 :) 我试图清楚地显示哪些列表应自动生成。其内容直到文档后面才添加(\inputlanguagefile
)。
答案1
您必须将数据写入文件中以便在下次运行时可以使用该信息;我们利用文件作为的一部分被读取的.aux
事实,因此在发出时将具有请求的值(在下次运行时) 。.aux
\begin{document}
\manuallanguages
\maketitle
\documentclass{article}
\makeatletter
\newcommand{\manuallanguages}{\@gobble} % initialization
\newcommand{\inputlanguagefile}[1]{%
\input{\manualfile{#1}}%
\protected@write\@auxout{}{\string\used@language{#1}}%
}
\AtEndDocument{\let\used@language\@gobble}
\newcommand{\used@language}[1]{%
\g@addto@macro\manuallanguages{\language@sep\format@language{#1}}%
}
\newcommand{\language@sep}{, }% separator
\newcommand{\format@language}[1]{%
\expandafter\expandafter\expandafter\@secondoftwo % or \@firstoftwo
\csname language@#1\endcsname
}
\newcommand\definemanuallanguage[2]{%
\@namedef{language@#1}{{#1}{#2}}%
}
\makeatother
\newcommand\manualfile[1]{./UserManual_#1}% use your own
\definemanuallanguage{en}{English}
\definemanuallanguage{de}{Deutsch}
\definemanuallanguage{da}{Dansk}
\begin{document}
\title{User Manuals\\
\manuallanguages}
\author{macmadness86}
\maketitle
\inputlanguagefile{en}
\inputlanguagefile{da}
\inputlanguagefile{de}
\end{document}
每个文件都以以下形式\inputlanguagefile
添加注释.aux
\used@language{xy}
其中 的xy
参数是\inputlanguagefile
。
定义\manualfile
根据您的设置进行工作,这里我将手册文件放在与主文件相同的目录中。
如果您只希望使用 ISO 缩写(小写),请更改\@secondoftwo
为\@firstoftwo
。
答案2
最后更新:展示如何调整在编辑中添加到问题中的具体代码。见底部。
正如你提到的埃托克,我会解释,有了它你就可以实现你想要的,而不必将东西写入文件aux
。
我还添加了内容hyperref
只是为了显示超链接将存在。
这个想法是,etoc
您可以通过命令打印以逗号分隔的所用语言列表\tableofcontents
,并且将此命令作为图片中的节点放置TikZ
是没有问题的。
更新添加了一个变体。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc, positioning}
\usepackage{etoc}
% in this example, user manuals are each printed in their own
% \part. If there were no other parts, we would not need to define
% a special division called "languagefile", we would simply use "part".
% I use a \part below in \inputlanguagefile
% to provide an hyperref target.
% Else, without \part, one would only need define a counter
% and do \refstepcounter in the \inputlanguagefile command.
% Without hyperref, there is no need to do anything extra.
\etocsetlevel{languagefile}{6}
\usepackage{hyperref}% just to check compatibility
\makeatletter
\newcommand\manualfile[1]% #1 = typically, two-letter abbrev for language
{./UserManual_#1.tex }% use your own preferred location
\newcommand\declaremanuallanguage[2]% #1 = abbrev, #2 = full name
{\@namedef{languagename@#1}{#2}}
\newcommand{\inputlanguagefile}[1]{%
\part{\@nameuse{languagename@#1}}
\etoctoccontentsline{languagefile}{\@nameuse{languagename@#1}}%
\input{\manualfile{#1}}}
\makeatother
\declaremanuallanguage{en}{English}
\declaremanuallanguage{de}{Deutsch}
\declaremanuallanguage{da}{Dansk}
\newcommand{\manuallanguages}{%
\begingroup
\etocsetnexttocdepth {-1}% limit the TOC to what we want
\etocsetlevel {part}{0}% move parts out of the way
\etocsetlevel {languagefile}{-1}% only interested in them
\etocsetstyle {languagefile}
% do the trick to get a separator, this is executed once
{\def\manual@sep{\def\manual@sep{, }}}
% then each entry will do ", " except the first
{\manual@sep\etocname}{}{}%
\etocsettocstyle {}{}% suppress standard Contents heading
% we will be in vertical mode.
\begin{tikzpicture}
\node [font=\Huge\bfseries] (title) at
($ (current page.north)!.25!(current page.south) $) {User manuals};
\node [font=\Large\bfseries] (subtitle) [below= 2cm of title]
{\tableofcontents};% etoc's magic ! Each entry is a link.
\end{tikzpicture}
\endgroup
%\clearpage
\setcounter{page}{1}
}%
% only for sample code, remove from final version
% as we don't provide an extension, .tex suffix is appended.
\usepackage{filecontents}
\begin{filecontents}{UserManual_en}
This is the English manual.
\end{filecontents}
\begin{filecontents}{UserManual_de}
Dies ist die deutsche Bedienungsanleitung.
\end{filecontents}
\begin{filecontents}{UserManual_da}
Dette er den danske manual.
\end{filecontents}
\begin{filecontents}{UserManual_fr}
Ceci est le manuel français.
\end{filecontents}
\title{\manuallanguages}
\author{macmadness86}
\begin{document}\pagestyle{empty}% only for cropping pages for png's
\maketitle\thispagestyle{empty}
\vskip1cm
\hrule
\clearpage
\inputlanguagefile{en}
\vskip1cm
\hrule
\clearpage
\inputlanguagefile{da}
\vskip1cm
\hrule
\clearpage
\inputlanguagefile{de}
\vskip1cm
\hrule
\end{document}
(规则只是要求即使裁剪后生成的图像宽度也应相同)
变体:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{calc, positioning}
\usepackage{etoc}
\usepackage{hyperref}% just to check compatibility
% location of user manuals
\newcommand\manualfile[1]{./UserManualv2_#1.tex }%
% innocent wrapper
\newcommand{\inputlanguagefile}[1]{\input{\manualfile{#1}}}
% a fictional sectioning unit,
\etocsetlevel{languagefile}{6}
\newcommand{\thisismanualfor}[1]{%
\part{#1}% convenient way to create an hyperref target
\etoctoccontentsline{languagefile}{#1}%
}%
\newcommand{\manuallanguages}{%
\begingroup
\etocsetnexttocdepth {-1}% limit the TOC to what we want
\etocsetlevel {part}{0}% move parts out of the way
\etocsetlevel {languagefile}{-1}% only interested in them
\etocsetstyle {languagefile}
% do the trick to get a separator, this is executed once
{\def\manual@sep{\def\manual@sep{, }}}
% then each entry will do ", " except the first
{\manual@sep\etocname}{}{}%
\etocsettocstyle {}{}% suppress standard Contents heading
% for the record: etoc always does a \par when doing \tableofcontents,
% which can be turned off via \etocinline command; it turns out
% we don't need to worry about this in the TikZ's node.
\begin{tikzpicture}
\node [font=\Huge\bfseries] (title) at
($ (current page.north)!.25!(current page.south) $) {User manuals};
\node [font=\Large\bfseries] (subtitle) [below= .5cm of title]
{\tableofcontents};% etoc's magic ! Each entry is a link.
\end{tikzpicture}
\endgroup
}%
% ONLY for sample code, REMOVE from final version
% as we don't provide an extension, .tex suffix is appended.
\usepackage{filecontents}
\begin{filecontents}{UserManualv2_en}
\thisismanualfor{English}%
This is the English manual.
\end{filecontents}
\begin{filecontents}{UserManualv2_de}
\thisismanualfor{Deutsch}%
Dies ist die deutsche Bedienungsanleitung.
\end{filecontents}
\begin{filecontents}{UserManualv2_da}
\thisismanualfor{Dansk}%
Dette er den danske manual.
\end{filecontents}
\begin{filecontents}{UserManualv2_fr}
\thisismanualfor{Français}%
Ceci est le manuel français.
\end{filecontents}
\title{\manuallanguages}
\author{macmadness86}
\begin{document}
\maketitle
\part{Introduction}
\inputlanguagefile{fr}
\inputlanguagefile{en}
\inputlanguagefile{da}
\part{Conclusion}
\hrule
\end{document}
现在问题有了完整的代码示例,我可以提供一个更直接针对具体目标的答案。
这是代码的副本,其中添加了用% ADD THIS
行标记的附加内容。
\documentclass{article}
%% \usepackage{fontspec} % commented out to compile with pdflatex
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
\usepackage[explicit]{titlesec}
\usepackage{tocloft}
\usepackage{etoc}
% ADDTHIS
\etocsetlevel{languageabbrev}{6}
%
\usepackage{lipsum}
\usepackage{hyperref}
\newcounter{runningsectioncounter}
\setcounter{runningsectioncounter}{0}
\titleformat{\section}[hang]{\color{red}\Huge\bfseries}{}{0pt}{\thesection\quad#1}[\stepcounter{runningsectioncounter}]
% Use this \newlangfile{<code>}{<name>}{<file>} to add external language varieties
\newcommand{\inputlanguagefile}[3]{%
\newpage\pdfbookmark{#2}{bkm#1}%
\etoctoccontentsline{part}{#2}%
% ADDTHIS
\etoctoccontentsline{languageabbrev}{#1}%
%
\setcounter{runningsectioncounter}{\value{section}}
\setcounter{section}{0}
\renewcommand*{\theHsection}{chX.\the\value{runningsectioncounter}} % Keeps hyperref happy (provides unique section numbers instead of using the section counter)
\input{#3}%
}
\renewcommand{\maketitle}[2][]{%
\begin{tikzpicture}[remember picture, overlay]
\node [font=\Huge] (title) at ($ (current page.north)!.25!(current page.south) $) {#2};
\node [font=\Large,below=2cm of title] (subtitle) {#1};
%\node [color=red,draw,below=1cm of subtitle] (note) {This list should be generated automatically.};
%\draw [->,ultra thick,red] (note) -- (subtitle);
\end{tikzpicture}
\clearpage
}%
\newcommand{\usermanualfrontmatter}{%
% ADDTHIS
\GetUsedLanguages
%
\maketitle[\UsedLanguages]{User Manual}
\newpage
\setcounter{tocdepth}{0} % make ToC contain only parts
\renewcommand{\contentsname}{Language Directory} % change ToC Title
\tableofcontents
\newpage
\setcounter{tocdepth}{4}
\renewcommand{\contentsname}{Table of Contents} % reset ToC Title back to default
}%
% ADDTHIS
\makeatletter % to use \g@addto@macro from LaTeX's kernel
\newcommand{\GetUsedLanguages}{%
\begingroup % work in a group to undo our changes automatically on exit
\etocsetnexttocdepth {-1}% limit the TOC to what we want
\etocsetlevel {part}{0}% move parts out of the way
\etocsetlevel {languageabbrev}{-1}% only interested in them
\etocsetstyle {languageabbrev}
{\gdef\UsedLanguages{}\etocskipfirstprefix}
{\g@addto@macro\UsedLanguages{, }}
{\expandafter\g@addto@macro\expandafter\UsedLanguages
\expandafter{\etocthename}}%
{}%
\etocsettocstyle {}{}% suppress standard Contents heading
\etocinline % suppress \par, thus TOC does not typeset anything at all
\tableofcontents % fill up \UsedLanguages
\endgroup
}
\makeatother
% ONLY FOR ALL IN ONE CODE SAMPLE
%
\usepackage{filecontents}
\begin{filecontents}{da.tex}
\maketitle[da]{Brugsanvisning}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]
\end{filecontents}
\begin{filecontents}{de.tex}
\maketitle[de]{Gebrauchsanweisung}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]
\end{filecontents}
\begin{filecontents}{en.tex}
\maketitle[en]{User Manual}
\localtableofcontents
\clearpage
\section{Test}
\lipsum[50]
\end{filecontents}
\begin{document}
\usermanualfrontmatter{}
\inputlanguagefile{En}{English}{./en.tex}
\inputlanguagefile{Da}{Dansk}{./da.tex}
\inputlanguagefile{De}{Deutsch}{./de.tex}
\end{document}