# 《Lua-in-ConTeXt》09：学一点 Lua

## 变量

``````my = my or {}
local ctx = context
local dim = number.todimen
local textwidth = tex.dimen.textwidth
local w1, w2, w3 = tex.sp("1.5em"), nil, nil
w3 = w1; w2 = textwidth - (w1 + w3)``````

``````foo
local bar``````

``local w1, w2, w3 = tex.sp("1.5em"), nil, nil``

`=` 右侧的三个值分别赋于 `=` 左侧的三个局部变量。

``w3 = w1; w2 = textwidth - (w1 + w3)``

``````w3 = w1
w2 = textwidth - (w1 + w3)``````

``````my = {}    -- 表
local ctx = context   -- 表
local dim = number.todimen    -- 函数
local textwidth = tex.dimen.textwidth    -- 数字``````

`--` 是 Lua 语言的代码注释符号，Lua 解释器会忽略 `--` 及其之后直到行尾的内容。

``````local a = "\\starttext ... \\stoptext"
local b = [[\starttext ... \stoptext]]
local c = [=[\starttext ... \stoptext]=]
local d = [==[\starttext ... \stoptext]==]``````

``local a = "\\starttext\n ... \n\\stoptext"``

``````local a = [[\starttext
...
\stoptext]]``````

## 函数

``````function (x)
return x
end``````

``function (x) return x end``

``y = function (x) return x end``

``````function y (x)
return x
end``````

``````function z (y, x)
return x + y
end``````

``````function f (x, y)
return x * x, y * y, x + y
end

local a, b, c = f(2, 4)``````

## 表

``local my = {}``

``````my[1] = [[\starttext]]
my[2] = " ... ... ... "
my[3] = [[\stoptext]]``````

``local my = {[[\starttext]], " ... ... ... ", [[\stoptext]]``

``local foo = {1, "two", function (x) return x end, {3, 4, "hello"}}``

``foo[3](foo[2])``

Lua 解释器对上述语句的求值结果为字符串 `"two"`

`foo[4]` 是表。`foo[4][1]` 的值为 3。`foo[4][3]` 的值为 `"hello"`

Lua 语言将表的索引定义为从 1 开始，而不是 0。请记住这一点。

``local color = {red = 0.001, green = 0.803, blue = 0.222}``

``color.green``

``color["gree"]``

``color.alpha = 0.5``

``````my = {}
my.foo = "Hello world!"

my.y  = function (x) return x end

function my.test (x, y)
return x + y
end

return my``````

``````% 这是 foo.tex 文件
\environment card-env
\starttext
\startluacode
local mingyi = require("my-module")
context.title(my.foo)
context("1 + 2 = %d\n", my.test(1, 2))
\stopluacode
\stoptext``````

``\$ context foo``

## 条件

``````if 条件成立 then
一段程序
end``````

``````if 条件成立 then
一段程序
else
另一段程序
end``````

``````function my.is_cjk_char(c)
if c >= 0x3400 and c <= 0x4db5
... ... ...
or c >= 0x31c0 and c <= 0x31ef then
return true;
else
return false;
end
end``````

``````if 条件 1 成立 then
程序段 1
elseif 条件 2 成立 then
程序段 2
else if ... then
... ... ...
else
以上条件都不成立时会被执行的程序段
end``````

## 迭代

``````local sum = 0
for i = 1, 10 do
sum = sum + i
end``````

``````local sum = 0
for i = 1, 10, 2 do
sum = sum + i
end``````

`pairs` 可用于遍历由键值对构成的表。例如

``````\environment card-env
\starttext
\startluacode
local color = {red = 0.001, green = 0.122, blue = 1.000}
context.startitemize({"inmargin", "broad"})
for k, v in pairs(color) do
context.item(string.format([[\color[%s]{%s} = %f]], k, k, v))
end
context.stopitemize()
\stopluacode
\stoptext``````

`ipairs` 可用于在迭代过程里遍历索引表，即元素索引为 1, 2, ... 的表。如果希望表中元素依序遍历，应该考虑用索引表而非键值对表。`ipairs` 的用法与 `pairs` 相似，例如，

``````\environment card-env
\starttext
\startluacode
local function vector(v, s)
local n = #v  -- 索引表 v 里元素的个数
context("\\[")
for i, e in ipairs(v) do
if i == n then
context(s, e)
else
context(s .. ", ", e)
end
end
context("\\]")
end

x = {0.1, 0.2, 0.3}
y = {0.4, 0.6, 0.1}
z = {}
for i, v in ipairs(x) do
z[i] = x[i] + y[i]
end

local s = "%.1f"
context.startformula()
vector(x, s); context(" + "); vector(y, s); context(" = "); vector(z, s)
context.stopformula()
\stopluacode
\stoptext``````

``````for _, v in pairs(foo) do
... ... ...
end``````

5.9k 声望
1.9k 粉丝
0 条评论