欢迎加入本人建的"LuaTeX ConTeXt 学习互助"群:431714622,互助学习LuaTeX ConTeXt LaTeX相关技术,以及通过Lua、Python实现格式化文本、数据的自动排版。

根据vertical-typesetting-in-context-mkiv这个答问中的线索学习了Hans Hagen所写的开发文档followingup的第6节:Directions(方向)。

感觉ConTeXt LMTX(LuaMetaTeX)很强大,安装说明;据说2022版TeX live要换上。

以下主要是从文档中拷贝的代码,有些地方做了注释,更正了个别笔误。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
% \setuppapersize[A4][A4]
% \setuplayout[
%     backspace=20mm,
%     width=160mm,
%     topspace=20mm,
%     header=0mm,
%     footer=0mm,
%     height=250mm
% ]

% 根据 https://wiki.contextgarden.net/Chinese_Japanese_and_Korean
\mainlanguage[cn]
\language[cn]
\enableregime[utf]
\setscript[hanzi] % hyphenation

% 启用字体
\usetypescriptfile[mscore]
% \setupbodyfont [mschinese-literate,12pt]
\usebodyfont   [mschinese,12pt]
% \usebodyfont   [mschinese-light,12pt]
% \usebodyfont   [mschinese-literate,12pt]
% \definebodyfontenvironment[24pt]
% \definebodyfontenvironment[18pt]

% \setuppagenumber [numberconversion=cn]
% \definestructureconversionset[chinese][numbers][cn]
% 章节序号
% \setupheads [sectionconversionset=chinese]

% \define[2]\ChineseChapter{第#1章 #2}
% \setuphead[chapter][command=\ChineseChapter,style={\bf\switchtobodyfont[24pt]}]
\setuphead[section][style={\bf\switchtobodyfont[18pt]}]


% \setuppagenumbering[state=start,
%     alternative=singlesided,
%     location={footer, center},
%     style={\bf\switchtobodyfont[11pt]}
% ]

% \definefont[kaiti][name:kaiti*default at 24pt]

% \usemodule[zhspuncs]

% 行距
\setupinterlinespace[line=1.5em]

% 显式信息
\showboxes
% \showmakeup

\starttext

\section{朝向 orientation}

\subsection{使用与嵌套使用}

无朝向: This is a \LUAMETATEX\ goodie.

整体朝下: \hbox orientation 2{This is a \LUAMETATEX\ goodie.}

局部朝下: This is a \hbox orientation 2{\LUAMETATEX} goodie.

整体朝下、局部再朝下: \hbox orientation 2{This is a \hbox orientation 2{\LUAMETATEX} goodie.}

\subsection{6种朝向}

orientation 0—5:
\hbox orientation 0 {\TEX} and
\hbox orientation 1 {\TEX} and
\hbox orientation 2 {\TEX} and
\hbox orientation 3 {\TEX} and
\hbox orientation 4 {\TEX} and
\hbox orientation 5 {\TEX}

\subsection{锚点}

三位十六进制数表示的方向(前两位表示虚拟锚点):

0x<X><Y><O>

或TEX式:

"<X><Y><O>

X0-3分别表示如何水平对齐原空间边界: center, left(左外), right(右外), halfway left(左中) and halfway right(右中):
\hbox orientation "002 {\TEX} and
\hbox orientation "102 {\TEX} and
\hbox orientation "202 {\TEX} and
\hbox orientation "302 {\TEX} and
\hbox orientation "402 {\TEX}

Y0-3分别表示如何垂直对齐原基线: baseline, lower corner, upper corner or center:
\hbox orientation "002 {\TEX} and
\hbox orientation "012 {\TEX} and
\hbox orientation "022 {\TEX} and
\hbox orientation "032 {\TEX}

\page
\subsection{反向文本流}

两种方法,

一、指定盒子的流向为反向`direction 1`(\string\vbox同样可用):

\hbox{\hbox
    orientation 0
    direction 1
    {朱泙漫学屠龙于支离益,殚千金之家,三年技成,而无所用其巧。} }

二、使用命令`\string\righttoleft`:

\hbox{\hbox
    orientation 0
    direction 0
    {\righttoleft 朱泙漫学屠龙于支离益,殚千金之家,三年技成,而无所用其巧。} }

三、二者重复使用不会冲突:

\hbox{\hbox
    orientation 0
    direction 1
    {\righttoleft 朱泙漫学屠龙于支离益,殚千金之家,三年技成,而无所用其巧。} }

\subsection{偏置}

\hbox{偏置 0x0}
\hbox
    orientation 0
    xoffset 150pt
    yoffset 15pt
    {偏置 150x15}
\vbox
    orientation 0
    {\hbox{\string\hbox\ 偏置 0x0}}
\vbox
    orientation 0
    xoffset 150pt
    yoffset -15pt
    {\hbox{\string\hbox\ 偏置 150x-15}}


\subsection{竖排/直书}

\startluacode
local glyph_id = node.id("glyph")
local fontdata = fonts.hashes.identifiers -- assumes generic font loader
--判断是不是汉族(是否需要直排)
local function is_vertical(c)
    -- 常用的汉字编码范围,还有更多
    return c >= 0x04E00 and c <= 0x09FFF
end

-- 处理程序,输入一个盒子号码
function document.go_vertical(boxnumber)
    local box = tex.getbox(boxnumber)
    local n = box.list
    while n do
        if n.id == glyph_id and is_vertical(n.char) then
            local o = .2 * fontdata[n.font].parameters.xheight
            local prev, next = n.prev, n.next
            n.next, n.prev = nil, nil
            local l = nodes.new("hlist")
            l.list = n
            local w, h, d = n.width, n.height, n.depth
            if prev then
                prev.next, l.prev = l, prev
            else
                box.list = l
            end
            if next then
                l.next, next.prev = next, l
            end
            l.width, l.height, l.depth = h + d + o, w, 0
            l.orientation = 0x003
            l.xoffset, l.yoffset = o/2, -o/2
            l.hoffset, l.doffset = h, d - o
            n = next
        else
            n = n.next
        end
    end
end
\stopluacode

% 调整非中文的偏置
\unexpanded\def\stripe#1%
    {\hbox orientation 0 yoffset .2\exheight{\strut #1}}

% 生成一个横向盒子(测试材料)
\newbox\MyVerticalBox
\setbox\MyVerticalBox\hbox \bgroup
    \startscript[hangul]%
        \dorecurse{20}{%
            朱泙漫学屠龙于支离益,殚千金之家,三年技成,而无所用其巧。%
            \stripe{ test #1} }%
        \unskip % remove last space
    \stopscript
\egroup

% 处理盒子
\ctxlua{document.go_vertical(\number\MyVerticalBox)}

% 解开盒子重排在\ruledvbox
\ruledvbox orientation 1 to \textwidth \bgroup
    % \setupinterlinespace[40pt]
    \hsize .92\textheight
    \unhbox\MyVerticalBox
    \vfill
\egroup

% 还需要处理标点等问题

\stoptext
部分效果:

朝向

锚点

反向文本流

偏置

竖排

要做中文竖排/直书工具还有很多问题,比如标点。

评论