乐趣区

关于tex:LuainConTeXt03两个世界

上一篇:ConTeXt 计算机

ConTeXt 里的 Lua。这句话博大精深。

ConTeXt 世界里的大部分设施是用 TeX 语言构建的。在 ConTeXt 源文件里,\ 前面追随一个或多个英文字母的文本称为管制序列。\ 前面追随单个非字母的文本,也称为管制序列。

例如

\starttext
foo \ConTeXt\ bar
\stoptext

其中,\starttext\ConTeXt\stoptext 以及 \ 空格 ,皆为管制序列。

所有的管制序列有着一个独特的使命,将排版信息输入到 PDF 文件里,简而言之,即排版。例如上例,排版后果如下图所示

每个管制序列都有其独特的作用。例如,在 ConTeXt 的世界里,只有位于 \starttext\stoptext 之间的内容,方有机会输入至 PDF 文件。

TeX 语言可能组合既有的管制序列,派生出新的管制序列,这是 TeX 世界生生不息的本源所在。无妨从人类语言字词组合的角度了解管制序列的组合,例如「人」和「间」的组合产生了「世间」。

TeX 语言所结构的世界在 TeX 源文件里占主体位置。Lua 语言通常仅呈现于管制序列 \ctxlua{...}

\startluacode
... ... ...
\stopluacode

中省略号批示的地位,其中 \ctxlua\startluacode 以及 \stopluacode 是沟通 TeX 世界和 Lua 世界的隧道,但 Lua 世界里通过计算产生的后果最终须要传递于 TeX 世界。

因而,TeX 世界看了 Lua 世界一眼说,世界是咱们的,也是你们的,但归根结底是咱们的。

Lua 世界说,归根结底是 PDF 的。

古代大多数字处理软件,例如微软 Word,金山 WPS,自在的 LibreOffice Writer……它们皆能将本人的排版后果转化为 PDF 文件。当初的网页浏览器也能将网页内容保留为 PDF 文件。有什么必要应用 TeX 制作 PDF 文件呢?

同样是照片,手机拍进去的,跟单反相机拍进去的,通常也不是一回事。TeX 很像单反相机。

假使对排版有所谋求,TeX 就值得学习。

假使 TeX 值得学习,ConTeXt 也就值得学习。

假使 ConTeXt 值得学习,ConTeXt 里的 Lua 也值得学习。因为 Lua 语言能让 TeX 世界更容易生生不息。

TeX 语言让 TeX 世界生生不息的形式像是一群原始人致力保护着一个火堆,免得断了火种。当 Lua 语言呈现在 TeX 世界里时,这个火堆就变成了火柴,打火机,火焰喷射器……

为了充分说明这一点,先理解一下 \title 这个管制序列,它用于排版文章的题目。例如

\starttext
\title{Hello world!}

... ... some text ... ...

\stoptext

假如上述内容是 ConTeXt 源文件 foo.tex 的全部内容,执行

$ context foo.tex

命令里,可毋庸写 .tex,以下命令与上述命令等价:

$ context foo

后果失去的 foo.pdf,它在我机器上的 PDF 阅读器里的样子如下图所示:

显然,作为题目的 Hello world! 的字号要比注释 ... ... some text ... ... 大了许多,这是很正当的,因为题目须要醒目。

ConTeXt 默认的题目款式并不是太好看,然而它容许用户自定义题目款式。例如,

\setuphead[title][align=middle]

\starttext
\title{Hello world}

... ... some text ... ...

\stoptext

在从新生成的 PDF 文件里,题目就位于页面正中了。

也能够设置题目的色彩,例如将其设置为暗绿色:

\setuphead[title][align=middle,color=darkgreen]

成果如下图所示:

以上对文章题目的地位和外观的调整,展示了 TeX 世界的能力所及之万一,尽管如此,假使我提出一个并不如许刁钻的问题,如何让题目里的字母序列从绿色突变为红色?就会让 TeX 世界感到乏力。若有不信,可尝试应用 TeX 语言解决以下两个问题:

  • 遍历一段文本,拜访它的每个字符。
  • 小数的加法运算,例如计算 0.1 + 0.3。

这两个问题,本质上正是解决我下面提出的让题目字符色彩突变问题的要害。第一个问题,浏览《The TeX book》到第 20 章的时候,假使仍然气定神闲,兴许举手之劳便可解决。至于第二个问题,假使不动用一些 TeX 黑客们殚精竭虑编写的宏包 1,那就要本人殚精竭虑去写这样的宏包——须要大量的管制序列的组合,方能解决。

Lua 世界如何解决文本的遍历问题呢?在 Lua 语言里,一段文本能够示意为一个字符串,例如

local title = "Hello world!"

要遍历 title 的每个字符并赋之以突变的色彩,只需

local red, green, step  = 0, 1, (1 / #title)

function fancy_char(c)
    red = red + step
    if red > 1 then red = 1 end
    green = green - step
    if green < 0 then green = 0 end
    context("\\definecolor[fancy][r=%f,g=%f,b=0]", red, green)
    context("\\color[fancy]{" .. c .. "}")
end

string.gsub(title, ".", fancy_char)

上述 Lua 代码可产生经 Lua 解释器执行后,可产生一组 TeX 管制序列,它们与以下管制序列等价:

\definecolor[fancy][r=0.083333333333333,g=0.91666666666667,b=0]%
\color[fancy]{H}%
\definecolor[fancy][r=0.16666666666667,g=0.83333333333333,b=0]%
\color[fancy]{e}%
\definecolor[fancy][r=0.25,g=0.75,b=0]%
\color[fancy]{l}%
\definecolor[fancy][r=0.33333333333333,g=0.66666666666667,b=0]%
\color[fancy]{l}%
\definecolor[fancy][r=0.41666666666667,g=0.58333333333333,b=0]%
\color[fancy]{o}%
\definecolor[fancy][r=0.5,g=0.5,b=0]%
\color[fancy]{ }%
\definecolor[fancy][r=0.58333333333333,g=0.41666666666667,b=0]%
\color[fancy]{w}%
\definecolor[fancy][r=0.66666666666667,g=0.33333333333333,b=0]%
\color[fancy]{o}%
\definecolor[fancy][r=0.75,g=0.25,b=0]%
\color[fancy]{r}%
\definecolor[fancy][r=0.83333333333333,g=0.16666666666667,b=0]%
\color[fancy]{l}%
\definecolor[fancy][r=0.91666666666667,g=0.083333333333333,b=0]%
\color[fancy]{d}%
\definecolor[fancy][r=1.0,g=0,b=0]%
\color[fancy]{!}%

这组 TeX 管制序列可在 PDF 文件里输入色彩突变的文字:

假使将上述的 Lua 代码嵌入到 ConTeXt 源文件里,便可实现文章题目色彩的突变了。例如

\startluacode
local title, step
local red, green = 0, 1

function fancy_char(c)
    red = red + step
    if red > 1 then red = 1 end
    green = green - step
    if green < 0 then green = 0 end
    context("\\definecolor[fancy][r=%f,g=%f,b=0]", red, green)
    context("\\color[fancy]{" .. c .. "}")
end

function fancy(text)
    title = text
    step = 1 / #title
    string.gsub(title, ".", fancy_char)
end
\stopluacode

\define[1]\fancy{\ctxlua{fancy([=[#1]=])}}
\setuphead[title][align=middle,deeptextcommand=\fancy]

\starttext
\title{Hello world!}

... some text ...

\stoptext

生成的 PDF 如下图所示:

假使此刻看不懂上述代码,勿须焦虑。就像每天出门,咱们看到的这个世界,谁能真正相熟它呢?上述代码,展示的是一个简单的世界的概貌速写……不对,是两个世界的……而造访它们的旅程,从此刻刚刚开始。


  1. 见 https://www.texdev.net/2018/1… ↩
退出移动版