On 8/21/2022 10:24 AM, 黄复雄 via ntg-context wrote:
Actually a few years ago I added some basic new features for doing vertical scripts effciently but (as often with these things) there was not that much follow up because no one seems to need / use it (or be triggered by the fact that it can be used).Currently, the ruby module does not seem to support cjk fonts? I have a preliminary implementation of furigana(pinyin in Chinese) as:
The attached files show two methods ... manual work as well as semi automatic (one needs to patch one font file for some recent optimizations).
As you can see, rubies work ok. Now, before trying to improve this, it makes more sense to think about what kind of vertical support is actually needed becaus in order for that to work ok it really has to work with other mechanism as well and there is only so much that tex can do.
Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
test-directions-005.pdf
Description: Adobe PDF document
\noheaderandfooterlines % in font-imp-scripts, line 145, comment a few lines % % orientate = function(character) % local width = character.width or 0 % local height = character.height or 0 % local depth = character.depth or 0 % -- character.width = height + depth + rightshift + rightshift % character.height = width - downshift % character.depth = shift % -- character.xoffset = height + rightshift % -- character.yoffset = - downshift % -- character.orientation = orientation % end \dontcomplain \setuplayout[middle] \starttext \startluacode local nuts = nodes.nuts local nextglyph = nuts.traversers.glyph local nextnode = nuts.traversers.node local newhlist = nuts.pool.hlist local newglue = nuts.pool.glue local newpenalty = nuts.pool.penalty local getprev = nuts.getprev local setnext = nuts.setnext local getnext = nuts.getnext local setprev = nuts.setprev local getboth = nuts.getboth local setboth = nuts.setboth local setlink = nuts.setlink local getlist = nuts.getlist local setlist = nuts.setlist local setwhd = nuts.setwhd local getwhd = nuts.getwhd local getid = nuts.getid local getchar = nuts.getchar local getbox = nuts.getbox local getdimensions = nuts.dimensions local setorientation = nuts.setorientation local getorientation = nuts.getorientation local glyph_code = nodes.nodecodes.glyph local kern_code = nodes.nodecodes.kern function document.manipulate_one(boxnumber) local box = getbox(1000) local list = getlist(b) local all = { } for n, c, f in nextglyph, list do if c > 200 then all[n] = true end end local o = 4 * 65536 for n, how in next, all do local prev, next = getboth(n) setboth(n) local l = newhlist(n) local w, h, d = getwhd(n) setlink(prev,l,next) if how then setwhd(l,h+d+o,w,0) setorientation(l,0x003,0,0,h,d-o) end if n == list then setlist(box,l) end end end local function flushrange(head,current,first,last) local prev = getprev(first) local next = getnext(last) local list = newhlist(first) setprev(first) setnext(last) local w, h, d = getdimensions(first) setwhd(list,h+d,w,0) setlink(prev,list,next) setorientation(list,0x001,0,0,h,d) if first == head then return list, list else return head, list end end local function flushchar(head,current) local next = getnext(current) local glue = newglue(n,655360) setlink(current,glue,next) return head, glue end function document.manipulate_two(boxnumber) local box = getbox(1000) local head = getlist(box) local first = false local last = false local current = head while current do local id = getid(current) if id == glyph_code then if getchar(current) < 200 then if first then last = current else first = current last = current end else if first then head, current = flushrange(head,current,first,last) first = false end head, current = flushchar(head,current) end elseif id == kern_code then if first then last = current end elseif first then head, current = flushrange(head,current,first,last) first = false end current = getnext(current) end if first then head, current = flushrange(head,current,first,last) end setlist(box,head) end \stopluacode % % % % % % % % % % \setuptolerance[verytolerant,stretch] \definefont[NotoCJK][NotoSanstc-Regular*default @ 24pt] \setupinterlinespace[40pt] \unexpanded\def\stripe#1{\hbox orientation 0 yoffset 3pt{\strut #1}} \setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript} \ctxlua{document.manipulate_one(1000)} \ruledvbox orientation 1 to \textwidth \bgroup \hsize \textheight \unhbox1000 \vfill \egroup \page \setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规\ruby{范}{x}汉字表 \stripe{test #1} }\stopscript} \ctxlua{document.manipulate_one(1000)} \ruledvbox orientation 1 to \textwidth \bgroup \hsize \textheight \unhbox1000 \vfill \egroup \page \setupinterlinespace[40pt] \definefontfeature [vertical] [vertical={% orientation=3,% down=.1,% right=.1,% ranges={% cjkcompatibility,% cjkcompatibilityforms,% cjkcompatibilityideographs,% cjkcompatibilityideographssupplement,% cjkradicalssupplement,% % cjkstrokes,% cjksymbolsandpunctuation,% cjkunifiedideographs,% cjkunifiedideographsextensiona,% cjkunifiedideographsextensionb,% cjkunifiedideographsextensionc,% cjkunifiedideographsextensiond,% cjkunifiedideographsextensione,% cjkunifiedideographsextensionf,% }% }] \definefont[NotoCJKvertical][NotoSanstc-Regular*default,vertical @ 24pt] \showglyphs \unexpanded\def\stripe#1{\hbox orientation 0 yoffset 3pt{\strut #1}} \setbox1000\hbox{\NotoCJKvertical\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript} \ruledvbox orientation 1 to \textwidth \bgroup \hsize \textheight \unhbox1000 \vfill \egroup \page \setbox1000\hbox{\NotoCJKvertical\startscript[hangul]\dorecurse{20}{通用规\ruby{范}{x}汉字表 \stripe{test #1} }\stopscript} \ruledvbox orientation 1 to \textwidth \bgroup \hsize \textheight \unhbox1000 \vfill \egroup % \stopscript \stoptext
test-directions-006.pdf
Description: Adobe PDF document
\dontcomplain % in font-imp-scripts, line 145, comment a few lines % % orientate = function(character) % local width = character.width or 0 % local height = character.height or 0 % local depth = character.depth or 0 % -- character.width = height + depth + rightshift + rightshift % character.height = width - downshift % character.depth = shift % -- character.xoffset = height + rightshift % -- character.yoffset = - downshift % -- character.orientation = orientation % end \setuplayout[middle] \starttext \startluacode local nuts = nodes.nuts local nextglyph = nuts.traversers.glyph local newhlist = nuts.pool.hlist local getboth = nuts.getboth local setboth = nuts.setboth local setlink = nuts.setlink local getlist = nuts.getlist local setlist = nuts.setlist local setwhd = nuts.setwhd local getwhd = nuts.getwhd local setorientation = nuts.setorientation local getbox = nuts.getbox local xheights = fonts.hashes.xheights local function is_vertical(c) return c >= 0x04E00 and c <= 0x09FFF end function document.manipulate_one(boxnumber) local box = getbox(boxnumber) local list = getlist(box) local all = { } for n, c, f in nextglyph, list do if is_vertical(c) then all[n] = f end end for n, f in next, all do local o = .2 * xheights[f] local prev, next = getboth(n) setboth(n) local l = newhlist(n) local w, h, d = getwhd(n) setlink(prev,l,next) setwhd(l,h+d+o,w,0) setorientation(l,0x003,o/2,-o/2,0,h,d-o) if n == list then setlist(box,l) end end end \stopluacode \startluacode function document.manipulate_two(boxnumber) local box = tex.getbox(boxnumber) local n = box.list local function is_vertical(c) return c >= 0x04E00 and c <= 0x09FFF end while n do if n.id == node.id("glyph") and is_vertical(n.char) then local o = .2 * fonts.hashes.identifiers[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 3pt{\strut #1}} \setuptolerance[verytolerant,stretch] \definefont[NotoCJK][NotoSanstc-Regular*default @ 24pt] \setupinterlinespace[40pt] % % % % % % % % % % \setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript} \ctxlua{document.manipulate_one(1000)} \ruledvbox orientation 1 to \textwidth \bgroup \hsize \textheight \unhbox1000 \vfill \egroup \page \setbox1000\hbox{\NotoCJK\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript} \ctxlua{document.manipulate_two(1000)} \ruledvbox orientation 1 to \textwidth \bgroup \hsize \textheight \unhbox1000 \vfill \egroup \page \setupinterlinespace[40pt] \definefontfeature [vertical] [vertical={% orientation=3,% down=.1,% right=.1,% ranges={% cjkcompatibility,% cjkcompatibilityforms,% cjkcompatibilityideographs,% cjkcompatibilityideographssupplement,% cjkradicalssupplement,% % cjkstrokes,% cjksymbolsandpunctuation,% cjkunifiedideographs,% cjkunifiedideographsextensiona,% cjkunifiedideographsextensionb,% cjkunifiedideographsextensionc,% cjkunifiedideographsextensiond,% cjkunifiedideographsextensione,% cjkunifiedideographsextensionf,% }% }] \definefont[NotoCJKvertical][NotoSanstc-Regular*default,vertical @ 24pt] \showglyphs \unexpanded\def\stripe#1{\hbox orientation 0 yoffset 3pt{\strut #1}} \setbox1000\hbox{\NotoCJKvertical\startscript[hangul]\dorecurse{20}{通用规范汉字表 \stripe{test #1} }\stopscript} \ruledvbox orientation 1 to \textwidth \bgroup \hsize \textheight \unhbox1000 \vfill \egroup % \stopscript \stoptext
___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / https://www.ntg.nl/mailman/listinfo/ntg-context webpage : https://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : https://contextgarden.net ___________________________________________________________________________________