关于tex:LuainConTeXt07时间管理

96次阅读

共计 6986 个字符,预计需要花费 18 分钟才能阅读完成。

上一篇:伪竖排

对每个人最偏心的莫过于工夫。绝大多数人的工夫,被极少数的人以花样繁多的管理学伎俩轻轻偷去了一部分。窃钱者蹲监狱,窃工夫者为老板。若每个人都能管好本人的工夫,天下必将大同。

工夫戳增强版

回顾一下之前在 card-env.tex 文件里定义的工夫戳:

\startluacode
my = {}
function my.is_cjk_char(c)
if c >= 0x3400 and c <= 0x4db5
or c >= 0x4e00 and c <= 0x9fa5
or c >= 0x9fa6 and c <= 0x9fbb
or c >= 0xf900 and c <= 0xfa2d
or c >= 0xfa30 and c <= 0xfa6a
or c >= 0xfa70 and c <= 0xfad9
or c >= 0x20000 and c <= 0x2a6d6
or c >= 0x2f800 and c <= 0x2fa1d
or c >= 0xff00 and c <= 0xffef
or c >= 0x2e80 and c <= 0x2eff
or c >= 0x3000 and c <= 0x303f
or c >= 0x31c0 and c <= 0x31ef then
return true;
else
return false;
end
end
function my.rotate(x, a)
pad = "\\kern.125em"
for _, c in utf8.codes(x) do
if my.is_cjk_char(c) then
context("%s{\\rotate[rotation=%d]{%s}}%s", pad, a, utf8.char(c), pad)
else
context("{\\raise.5\\maxdepth\\hbox{%s}}", utf8.char(c))
end
end
end
\stopluacode
\def\timestamp#1{\rotate[rotation=270]{\ctxlua{my.rotate("#1", 90)}}}
\setuptexttexts
[margin]
[][\hfill{\timestamp{20230126 日 凌晨 0444 分}}\hfill]

当初,将 \timestamp 定义为

\def\timestamp#1{%
\page
\setuptexttexts
[margin][][\hfill{\rotate[rotation=270]{\ctxlua{my.rotate("#1", 90)}}}\hfill]
}

重定义的 \timestamp 宏承受一个参数,应用 \page 另起新页,将参数内容安放于页面右侧留白区域。上面是 \timestamp 的用法示例:

\environment card-env
\starttext
\timestamp{2023 年 01 月 30 日}
测试页 1
\timestamp{2023 年 01 月 31 日}
测试页 2
\stoptext

\page 宏用于分页,仅在前后皆有内容时无效,例如

\starttext
\page
foo
\page
bar
\page
\stoptext

其中,第一个和第三个 \page 是无用的,会被 TeX 编译器疏忽,只有第二个 \page 无效,使得 foobar 各占一页。

待办事项

用 ConTeXt 的 xtable 能够模仿风行一时的 To do List。

首先,结构一个三列的表格:

\environment card-env
\starttext
\timestamp{20230131 日}
\definextable[todolist]
\startxtable[todolist]
\startxrow
\startxcell $\circ$ \stopxcell
\startxcell 晒太阳 \stopxcell
\startxcell $\checkmark$ \stopxcell
\stopxrow
\startxrow
\startxcell $\circ$ \stopxcell
\startxcell 包饺子 \stopxcell
\startxcell $\checkmark$ \stopxcell
\stopxrow
\startxrow
\startxcell $\circ$ \stopxcell
\startxcell 拖地板 \stopxcell
\startxcell $\checkmark$ \stopxcell
\stopxrow
\stopxtable
\stoptext

假使排版后果未呈现 $\cdot$ 和 $\checkmark$ 符号,可在 card-env.tex 里设定数学字体:

\definefontfamily[myfont][serif][sourcehanserifcn]
\definefontfamily[myfont][math][xitsmath] % <--- 增加这一行!\setscript[hanzi]
\setupbodyfont[myfont,7pt]

当初暗藏表格的边框,将第一列宽度调整为 1.5em,第二列宽度设置为 .9\textwidth,即版心宽度的 0.9 倍,第三列宽度设置为 .1\textwidth

\setupxtable[todolist][frame=off]
\startxtable[todolist]
\startxrow
\startxcell[width=1.5em] $\circ$ \stopxcell
\startxcell[width=.9\textwidth] 晒太阳 \stopxcell
\startxcell[width=.1\textwidth] $\checkmark$ \stopxcell
\stopxrow
\startxrow
\startxcell $\circ$ \stopxcell
\startxcell 包饺子 \stopxcell
\startxcell $\checkmark$ \stopxcell
\stopxrow
\startxrow
\startxcell $\circ$ \stopxcell
\startxcell 拖地板 \stopxcell
\startxcell \stopxcell
\stopxrow
\stopxtable

Lua 表 -> ConTeXt 表格

为了减少一条待办事项,须要写一堆命令,不胜其繁。因为这些宏的呈现具备重复性,因而能够思考用 Lua 编程的形式予以简化,因为在 Lua 语言里,表格的语法非常简单。例如

\startxtable
\startxrow
\startxcell 1\stopxcell
\startxcell 2\stopxcell
\startxcell 3\stopxcell
\stopxrow
\stopxtable

所表白的表格模式,用 Lua 的表构造可表述为

{1, 2, 3}

上面的示例可将 Lua 表构造转化为 ConTeXt 表格:

\environment card-env
\startluacode
my = my or {}
local ctx = context
function my.add(row)
ctx.startxrow()
for _, v in ipairs(row) do
ctx.startxcell(); context(v); ctx.stopxcell()
end
ctx.stopxrow()
end
\stopluacode
\def\foo#1{\ctxlua{my.add({#1})}}
\starttext
% 将表格单元长宽均设为 2em,且令内容居中
\setupxtable[width=2em, height=2em, align={middle,lohi}]
\startxtable
\foo{4, 9, 2}
\foo{3, 5, 7}
\foo{8, 1, 6}
\stopxtable
\stoptext

以上述 Lua 代码为根底,略加修改,便可简化待办事项的增加:

\environment card-env
\definextable[todolist]
\setupxtable[todolist][frame=off]
\startluacode
my = my or {}
local ctx = context
local dim = number.todimen
local textwidth = tex.dimen.textwidth
function my.task(task, status)
ctx.startxrow()
-- 第一列
ctx.startxcell{width=dim(tex.sp("1.5em"))};
context("$\\circ$");
ctx.stopxcell()
-- 第二列
ctx.startxcell{width=dim(0.9 * textwidth)};
context("%s", task);
ctx.stopxcell()
-- 第三列
ctx.startxcell{width=dim(0.1 * textwidth),align="{middle,lohi}"};
context(status);
ctx.stopxcell()
ctx.stopxrow()
end
\stopluacode
\def\task#1#2{\ctxlua{my.task("#1", "#2")}}
\starttext
\timestamp{20230131 日}
\startxtable[todolist]
\task{晒太阳}{$\\checkmark$}
\task{包饺子}{$\\checkmark$}
\task{拖地板}{}
\stopxtable
\stoptext

留神,在上述代码里,\circ\checkmark 里的反斜线符号 \ 呈现在 Lua 语境里时,须要增加反斜线 \ 予以本义。若要躲避该问题,能够应用 Lua 的长字串语法。

Lua 长字串

以下 Lua i 代码定义了 4 个字符串变量:

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

其中,a 的值用的是 Lua 短字符串语法,而 bcd 的值用的是 Lua 长字符串语法。在长字符串语法中,\ 符号无需本义,且字符串能够间接换行,无需应用换行符 \n。例如,短字符串

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

与之等价的长字符串为

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

基于 Lua 长字串语法,待办事项的宏定义与用法示例可批改为

\environment card-env
\definextable[todolist]
\setupxtable[todolist][frame=off]
\startluacode
my = my or {}
local ctx = context
local dim = number.todimen
local textwidth = tex.dimen.textwidth
function my.task(task, status)
ctx.startxrow()
-- 第一列
ctx.startxcell{width=dim(tex.sp("1.5em"))};
context([[$\circ$]]);
ctx.stopxcell()
-- 第二列
ctx.startxcell{width=dim(0.9 * textwidth)};
context([[%s]], task);
ctx.stopxcell()
-- 第三列
ctx.startxcell{width=dim(0.1 * textwidth),align="{middle,lohi}"};
context(status);
ctx.stopxcell()
ctx.stopxrow()
end
\stopluacode
\def\task#1#2{\ctxlua{my.task([[#1]], [[#2]])}}
\starttext
\timestamp{20230131 日}
\startxtable[todolist]
\task{晒太阳}{$\checkmark$}
\task{包饺子}{$\checkmark$}
\task{拖地板}{}
\stopxtable
\stoptext

将上述代码中的 \environment\starttext 语句之间的代码挪移到 card-env.tex 文件。

结语

card.tex:

\environment card-env
\starttext
\timestamp{20230131 日}
\startxtable[todolist]
\task{晒太阳}{$\checkmark$}
\task{包饺子}{$\checkmark$}
\task{拖地板}{}
\stopxtable
\stoptext

card-env.tex:

% 页面布局
\definepapersize[card][width=85.6mm,height=53.98mm]
\setuppapersize[card]
\setuplayout
[backspace=.1\paperwidth,
width=.8\paperwidth,
topspace=.015\paperheight,
height=.97\paperheight,
leftmargin=.666\backspace,
rightmargin=.666\cutspace,
headerdistance=.025\makeupheight,
footerdistance=.025\makeupheight,
textheight=.95\makeupheight]
% 字体
\definefontfamily[myfont][serif][sourcehanserifcn]
\definefontfamily[myfont][math][xitsmath]
\setscript[hanzi]
\setupbodyfont[myfont,7pt]
% 页码
\setuppagenumbering[location=]
\setupfootertexts[margin][][\hfill\pagenumber\hfill]
% 题目
\setuphead[title][align=middle]
% 工夫戳
\startluacode
my = {}
function my.is_cjk_char(c)
if c >= 0x3400 and c <= 0x4db5
or c >= 0x4e00 and c <= 0x9fa5
or c >= 0x9fa6 and c <= 0x9fbb
or c >= 0xf900 and c <= 0xfa2d
or c >= 0xfa30 and c <= 0xfa6a
or c >= 0xfa70 and c <= 0xfad9
or c >= 0x20000 and c <= 0x2a6d6
or c >= 0x2f800 and c <= 0x2fa1d
or c >= 0xff00 and c <= 0xffef
or c >= 0x2e80 and c <= 0x2eff
or c >= 0x3000 and c <= 0x303f
or c >= 0x31c0 and c <= 0x31ef then
return true;
else
return false;
end
end
function my.rotate(x, a)
pad = "\\kern.125em"
for _, c in utf8.codes(x) do
if my.is_cjk_char(c) then
context("%s{\\rotate[rotation=%d]{%s}}%s", pad, a, utf8.char(c), pad)
else
context("{\\raise.5\\maxdepth\\hbox{%s}}", utf8.char(c))
end
end
end
\stopluacode
\def\timestamp#1{%
\page
\setuptexttexts
[margin]
[][\hfill{\rotate[rotation=270]{\ctxlua{my.rotate("#1", 90)}}}\hfill]
}
% 待办事项
\definextable[todolist]
\setupxtable[todolist][frame=off]
\startluacode
my = my or {}
local ctx = context
local dim = number.todimen
local textwidth = tex.dimen.textwidth
function my.task(task, status)
ctx.startxrow()
-- 第一列
ctx.startxcell{width=dim(tex.sp("1.5em"))};
context([[$\circ$]]);
ctx.stopxcell()
-- 第二列
ctx.startxcell{width=dim(0.9 * textwidth)};
context([[%s]], task);
ctx.stopxcell()
-- 第三列
ctx.startxcell{width=dim(0.1 * textwidth),align="{middle,lohi}"};
context(status);
ctx.stopxcell()
ctx.stopxrow()
end
\stopluacode
\def\task#1#2{\ctxlua{my.task([[#1]], [[#2]])}}

正文完
 0