我需要在 ConTeXt 中在对开页上输入平行文本(原文在右页,译文在左页)。我曾ledpar
在 Latex 中使用过,但对结果并不满意(文本在段落上对齐,如果其中一个文本比另一个文本长,则留下空白,这种情况很常见)。现在我想在 Context 中尝试一下。理想情况下,两个段落的高度应该相同,我想改变行间间距等。)
答案1
截至 2013 年 8 月,Context 的文本流功能状态仍不令人满意。MkIV 中的实现尤其如此,它还很初级。但是,旧版 Context(MkII,运行时加载的格式texexec
)确实提供了一种功能齐全的流机制,尽管功能有些有限。
马克二世
在 MkII 中你可以很容易地实现这样的目标:
(可怕的糟糕之处在于线的长度太短。)
背后的代码采用了 流模块 这是 Context 的一部分,用于并行排版几页双语文本:原文为希腊文,位于背面,拉丁文译文位于正面。请注意,由于原文较短,Context 会自动在左侧页面的第一段之后保留一些额外空间。然后,下一段均匀地位于两侧。
您需要做的是,本质上将两个输入文本划分为应并行放置的块。在每个部分的开头分别使用
\enableoutputstream [left]
或切换到所需页面\enableoutputstream [right]
,\synchronizeoutputstreams [...,...]
当块完成时调用:
\enableoutputstream [left]
... text that goes on verso pages, e.g. the original
\enableoutputstream [right]
... text that goes on recto pages, e.g. a translation
%% stop collecting content
\enableoutputstream [default]
%% set synchronization point
\synchronizeoutputstreams [left, right] %%
%% next chunk:
\enableoutputstream [left]
... repeat for as long as you wish
%% after you’re done, finalize:
\enableoutputstream [default] %% stop
\synchronizeoutputstreams [left,right] %% sync
\flushoutputstreampages [left,right] %% flush
这意味着输入文件必须以交错顺序包含两个文本,因此根据您的设置,您必须编写一个脚本来为您安排它。
下面列出了示例的完整代码(为方便起见,这里是 代码要点):
%% first a couple global settings
\setuppapersize [A7]
\enableregime [utf]
\setuptolerance [verytolerant,stretch] %% small page sizes ...
\setupbodyfont [10pt]
\usemodule [ancientgreek]
\setupheader [style=\tfx]
\setuppagenumbering [location=,state=start,alternative=doublesided]
%% now we define a couple wrappers for the streams macros
\usemodule [streams] %% m-streams.tex
%% 1) main environment for parallel typesetting
%% sets up running headers and ensures we begin verso
\def\startparallel {
\page [left]
\setupheadertexts
%% recto
[M. Tulli Ciceronis Timæus]
[pagenumber]
%% verso
[pagenumber]
[\localgreek{Πλάτωνος Τίμαιος}]
\enableoutputstream [default]%
}
%% 2) last pending stream content needs to be flushed on exit
\def\stopparallel {%
\enableoutputstream [default]%
\synchronizeoutputstreams [left,right]%
\flushoutputstreampages [left,right]%
}
%% 3) environment for Greek text on verso pages
\def \startplato {%% put Timaios on verso pages
\startgreek
\enableoutputstream [default]%
\synchronizeoutputstreams [left,right]%
\enableoutputstream [left]%
}
\let \stopplato \stopgreek
%% 4) environment for Latin text on recto pages
\def \startcicero {%% recto
\bgroup
\language [la]%
\enableoutputstream [right]%
}
\let \stopcicero \egroup
%% helper for typesetting pagination info consistently
\define[1]\pagination{\ifhmode\hskip\emwidth\fi{\rm[#1]}\hskip\emwidth}
%% ····································································
%% demonstration
%% ····································································
\starttext
\startparallel
\startplato
\pagination {27δ}
τί τὸ ὂν ἀεί, γένεσιν δὲ οὐκ ἔχον, καὶ τί τὸ γιγνόμενον μὲν
\pagination{28α}
ἀεί, ὂν δὲ οὐδέποτε; τὸ μὲν δὴ νοήσει μετὰ λόγου περιληπτόν, ἀεὶ
κατὰ ταὐτὰ ὄν, τὸ δ᾽ αὖ δόξῃ μετ᾽ αἰσθήσεως ἀλόγου δοξαστόν, γιγνόμενον
καὶ ἀπολλύμενον, ὄντως δὲ οὐδέποτε ὄν.
\stopplato
\startcicero
\pagination {3}
Quid est, quod semper sit neque ullum habeat ortum, et quod gignatur
nec umquam sit?
Quorum alterum intellegentia et ratione conprehenditur, quod unum atque
idem semper est; alterum, quod adfert opinionem sensus rationis
expers, quod totum opinabile est, id gignitur et interit nec umquam
esse uere potest.
\stopcicero
%% here the text will synchronize
\startplato
πᾶν δὲ αὖ τὸ γιγνόμενον ὑπ᾽ αἰτίου τινὸς ἐξ ἀνάγκης γίγνεσθαι: παντὶ
γὰρ ἀδύνατον χωρὶς αἰτίου γένεσιν σχεῖν.
ὅτου μὲν οὖν ἂν ὁ δημιουργὸς πρὸς τὸ κατὰ ταὐτὰ ἔχον βλέπων ἀεί,
τοιούτῳ τινὶ προσχρώμενος παραδείγματι, τὴν ἰδέαν καὶ δύναμιν αὐτοῦ
ἀπεργάζηται, καλὸν ἐξ ἀνάγκης
\pagination {28β}
οὕτως ἀποτελεῖσθαι πᾶν: οὗ δ᾽ ἂν εἰς γεγονός, γεννητῷ
παραδείγματι προσχρώμενος, οὐ καλόν.
\stopplato
\startcicero
Omne autem, quod gignitur, ex aliqua causa gigni necesse est; nullius
enim rei causa remota
\pagination {4}
reperiri origo potest.
Quocirca si is, qui aliquod munus efficere
molitur, eam speciem, quae semper eadem est, intuebitur atque id sibi
proponet exemplar, praeclarum opus efficiat necesse est; sin autem eam,
quae gignitur, numquam illam, quam expetet, pulchritudinem consequetur.
\stopcicero
%% here the text will synchronize again
\startplato
ὁ δὴ πᾶς οὐρανὸς -- ἢ κόσμος ἢ καὶ ἄλλο ὅτι ποτὲ ὀνομαζόμενος μάλιστ᾽ ἂν
δέχοιτο, τοῦθ᾽ ἡμῖν ὠνομάσθω -- σκεπτέον δ᾽ οὖν περὶ αὐτοῦ πρῶτον, ὅπερ
ὑπόκειται περὶ παντὸς ἐν ἀρχῇ δεῖν σκοπεῖν, πότερον ἦν ἀεί, γενέσεως
ἀρχὴν ἔχων οὐδεμίαν, ἢ γέγονεν, ἀπ᾽ ἀρχῆς τινος ἀρξάμενος.
γέγονεν: ὁρατὸς γὰρ ἁπτός τέ ἐστιν καὶ σῶμα ἔχων, πάντα δὲ τὰ τοιαῦτα
αἰσθητά, τὰ
\pagination {28ξ}
δ᾽ αἰσθητά, δόξῃ περιληπτὰ μετ᾽ αἰσθήσεως, γιγνόμενα καὶ γεννητὰ ἐφάνη.
τῷ δ᾽ αὖ γενομένῳ φαμὲν ὑπ᾽ αἰτίου τινὸς ἀνάγκην εἶναι γενέσθαι.
\stopplato
\startcicero
Omne igitur caelum siue mundus, siue quo alio uocabulo gaudet, hoc a
nobis nuncupatus
\pagination {5}
sit?
de quo id primum consideremus, quod principio est in omni
quaestione considerandum, semperne fuerit nullo generatus ortu, an
ortus sit ab aliquo temporis principatu.
Ortus est, quandoquidem cernitur et tangitur et est undique corporatus.
Omnia autem talia sensum mouent, sensusque mouentia quae sunt, eadem in
opinatione considunt; quae ortum habere gignique diximus, nihil autem
gigni posse sine causis.
\stopcicero
\stopparallel
\stoptext
此实现的一个主要限制是它只能处理两个输入流:左边一和一个正确的一个在对开页上。该机制并未设计用于将一个或两个页面划分为列,以便包含第三个或更多个流。此外,没有选项可以排版水平分割布局,例如,原文占据页面的顶部(一半、三分之一等),翻译占据页面的底部,也不能将其中一个文本流入页边距。总而言之,Context MkII 提供了并行排版的基本功能,但不足以满足任何更苛刻的要求。
第四型
如上所述,MkIV 对文本流的支持能力要差得多。考虑到它缺乏最基本的功能——在对开页上排列文本片段——我认为称其不可用是有道理的。实现位于
page-str.lua
和
page-str.mkiv
。如果针对 MkIV 进行更新,MkII 示例将如下所示:
(由于某种原因,文本似乎渗入了页脚。)
目前,MkIV 可以做的是在主 vlist 构建器阶段从页面获取输入,在同步点补偿不均匀的块长度,并排版生成的节点。但是,由于这是一次一个流而不是逐页完成的,因此实现缺乏以并行方式排列结果的方法。另一方面,这有点令人鼓舞,新的实现可以处理任意数量的流,而不仅仅是左流和右流。当然,在当前状态下,这并不算多。
该接口在某些方面与旧代码有所不同。最值得注意的是,属于同一类的流被分组在
\startoutputstream
一个主流的环境内。因此,每个块都遵循以下方案:
\startoutputstream [one] %% new master stream
... some text of first stream
\enableoutputstream [two] %% slave stream
... text of other stream
\synchronizestreams [one, two] %%
%% transition to next chunk
\enableoutputstream [one]
... text of first stream
\enableoutputstream [two] %% slave stream
... text of other stream
\synchronizestreams [one, two] %%
%% repeat as necessary ...
\disableoutputstream
\stopoutputstream %% -> closes \startoutputstream above
%% collecting is done, so here could follow some unrelated content without
%% interference
\synchronizestreams [one, two]%
%% finally, typeset what was collected
\flushoutputstream [one]%
\page
\flushoutputstream [two]%
示例的完整列表:
\setuppapersize [A7]
\setuptolerance [verytolerant,stretch] %% small page sizes ...
\setupheader [style=\tfx]
\setuppagenumbering [location=,state=start,alternative=doublesided]
\setupbodyfont [computer-modern-unicode,10pt] %% covers Greek as well
\enabletrackers[streams.flushing] %% useful debug output
%% we have to declare the streams we will use
%% 1) main environment for parallel typesetting
%% sets up running headers and ensures we begin verso
\def\startparallel {
\page [left]
\setupheadertexts
%% recto
[M. Tulli Ciceronis Timæus]
[pagenumber]
%% verso
[pagenumber]
[{\language[agr]Πλάτωνος Τίμαιος}]
\startoutputstream [greek]%% the reference for compensation
}
%% 2) last pending stream content needs to be flushed on exit
\def\stopparallel {%
\disableoutputstream
\stopoutputstream
\synchronizestreams [greek, latin]%
\flushoutputstream [greek]%
\page
\flushoutputstream [latin]%
}
%% 3) environment for Greek text on verso pages
\def \startplato {%% put Timaios on verso pages
\bgroup
\language [agr]%
\synchronizestreams [greek, latin]%
\enableoutputstream [greek]%
}
\let \stopplato \egroup
%% 4) environment for Latin text on recto pages
\def \startcicero {%% recto
\bgroup
\language [la]%
\enableoutputstream [latin]%
}
\let \stopcicero \egroup
%% helper for typesetting pagination info consistently
\define[1]\pagination{\ifhmode\hskip\emwidth\fi{\rm[#1]}\hskip\emwidth}
%% ····································································
%% demonstration
%% ····································································
\starttext
\startparallel
\startplato
\pagination {27δ}
τί τὸ ὂν ἀεί, γένεσιν δὲ οὐκ ἔχον, καὶ τί τὸ γιγνόμενον μὲν
\pagination{28α}
ἀεί, ὂν δὲ οὐδέποτε; τὸ μὲν δὴ νοήσει μετὰ λόγου περιληπτόν, ἀεὶ
κατὰ ταὐτὰ ὄν, τὸ δ᾽ αὖ δόξῃ μετ᾽ αἰσθήσεως ἀλόγου δοξαστόν, γιγνόμενον
καὶ ἀπολλύμενον, ὄντως δὲ οὐδέποτε ὄν.
\stopplato
\startcicero
\pagination {3}
Quid est, quod semper sit neque ullum habeat ortum, et quod gignatur
nec umquam sit?
Quorum alterum intellegentia et ratione conprehenditur, quod unum atque
idem semper est; alterum, quod adfert opinionem sensus rationis
expers, quod totum opinabile est, id gignitur et interit nec umquam
esse uere potest.
\stopcicero
%% here the text will synchronize
\startplato
πᾶν δὲ αὖ τὸ γιγνόμενον ὑπ᾽ αἰτίου τινὸς ἐξ ἀνάγκης γίγνεσθαι: παντὶ
γὰρ ἀδύνατον χωρὶς αἰτίου γένεσιν σχεῖν.
ὅτου μὲν οὖν ἂν ὁ δημιουργὸς πρὸς τὸ κατὰ ταὐτὰ ἔχον βλέπων ἀεί,
τοιούτῳ τινὶ προσχρώμενος παραδείγματι, τὴν ἰδέαν καὶ δύναμιν αὐτοῦ
ἀπεργάζηται, καλὸν ἐξ ἀνάγκης
\pagination {28β}
οὕτως ἀποτελεῖσθαι πᾶν: οὗ δ᾽ ἂν εἰς γεγονός, γεννητῷ
παραδείγματι προσχρώμενος, οὐ καλόν.
\stopplato
\startcicero
Omne autem, quod gignitur, ex aliqua causa gigni necesse est; nullius
enim rei causa remota
\pagination {4}
reperiri origo potest.
Quocirca si is, qui aliquod munus efficere
molitur, eam speciem, quae semper eadem est, intuebitur atque id sibi
proponet exemplar, praeclarum opus efficiat necesse est; sin autem eam,
quae gignitur, numquam illam, quam expetet, pulchritudinem consequetur.
\stopcicero
%% here the text will synchronize again
\startplato
ὁ δὴ πᾶς οὐρανὸς -- ἢ κόσμος ἢ καὶ ἄλλο ὅτι ποτὲ ὀνομαζόμενος μάλιστ᾽ ἂν
δέχοιτο, τοῦθ᾽ ἡμῖν ὠνομάσθω -- σκεπτέον δ᾽ οὖν περὶ αὐτοῦ πρῶτον, ὅπερ
ὑπόκειται περὶ παντὸς ἐν ἀρχῇ δεῖν σκοπεῖν, πότερον ἦν ἀεί, γενέσεως
ἀρχὴν ἔχων οὐδεμίαν, ἢ γέγονεν, ἀπ᾽ ἀρχῆς τινος ἀρξάμενος.
γέγονεν: ὁρατὸς γὰρ ἁπτός τέ ἐστιν καὶ σῶμα ἔχων, πάντα δὲ τὰ τοιαῦτα
αἰσθητά, τὰ
\pagination {28ξ}
δ᾽ αἰσθητά, δόξῃ περιληπτὰ μετ᾽ αἰσθήσεως, γιγνόμενα καὶ γεννητὰ ἐφάνη.
τῷ δ᾽ αὖ γενομένῳ φαμὲν ὑπ᾽ αἰτίου τινὸς ἀνάγκην εἶναι γενέσθαι.
\stopplato
\startcicero
Omne igitur caelum siue mundus, siue quo alio uocabulo gaudet, hoc a
nobis nuncupatus
\pagination {5}
sit?
de quo id primum consideremus, quod principio est in omni
quaestione considerandum, semperne fuerit nullo generatus ortu, an
ortus sit ab aliquo temporis principatu.
Ortus est, quandoquidem cernitur et tangitur et est undique corporatus.
Omnia autem talia sensum mouent, sensusque mouentia quae sunt, eadem in
opinatione considunt; quae ortum habere gignique diximus, nihil autem
gigni posse sine causis.
\stopcicero
\stopparallel
\stoptext
如果你是 Context 的(潜在)用户,请考虑要求在 MkIV 上提供完整的文本流 邮件列表所以汉斯知道需求很大。已经有 夫妻 尝试 在过去 但至今没有人成功说服他。