OSDN Git Service

Implement \yoko and \tate. (font rotation: not yet)
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Mon, 5 May 2014 06:47:26 +0000 (15:47 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Mon, 5 May 2014 06:47:26 +0000 (15:47 +0900)
src/ltj-direction.lua [new file with mode: 0644]
src/ltj-jfmglue.lua
src/ltj-kinsoku.lua
src/ltj-stack.lua
src/luatexja-core.sty
src/luatexja.lua
test/test51-vtest.pdf [new file with mode: 0644]
test/test51-vtest.tex [new file with mode: 0644]

diff --git a/src/ltj-direction.lua b/src/ltj-direction.lua
new file mode 100644 (file)
index 0000000..0bea28f
--- /dev/null
@@ -0,0 +1,246 @@
+--
+-- src/ltj-direction.lua
+--
+
+luatexja.load_module('base');      local ltjb = luatexja.base
+luatexja.load_module('stack');     local ltjs = luatexja.stack
+luatexja.direction = {}
+
+local attr_dir = luatexbase.attributes['ltj@dir']
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+
+local Dnode = node.direct or node
+local nullfunc = function (n) return n end
+local to_node = (Dnode ~= node) and Dnode.tonode or nullfunc
+local to_direct = (Dnode ~= node) and Dnode.todirect or nullfunc
+local has_attr = Dnode.has_attribute
+local set_attr = Dnode.set_attribute
+local insert_before = Dnode.insert_before
+local insert_after = Dnode.insert_after
+local getid = (Dnode ~= node) and Dnode.getid or function(n) return n.id end
+local getsubtype = (Dnode ~= node) and Dnode.getsubtype or function(n) return n.subtype end
+local getlist = (Dnode ~= node) and Dnode.getlist or function(n) return n.head end
+local setfield = (Dnode ~= node) and Dnode.setfield or function(n, i, c) n[i] = c end
+local getfield = (Dnode ~= node) and Dnode.getfield or function(n, i) return n[i] end
+local node_new = Dnode.new
+local node_tail = Dnode.tail
+local node_free = Dnode.free
+local node_remove = Dnode.remove
+local node_next = (Dnode ~= node) and Dnode.getnext or node.next
+local traverse_id = Dnode.traverse_id
+
+local id_kern = node.id('kern')
+local id_hlist = node.id('hlist')
+local id_vlist = node.id('vlist')
+local id_whatsit = node.id('whatsit')
+local sid_save = node.subtype('pdf_save')
+local sid_restore = node.subtype('pdf_restore')
+local sid_matrix = node.subtype('pdf_setmatrix')
+local sid_user = node.subtype('user_defined')
+
+local PROCESSED    = luatexja.icflag_table.PROCESSED
+local PACKED       = luatexja.icflag_table.PACKED
+local DIR = luatexja.stack_table_index.DIR
+local wh_DIR = luatexja.userid_table.DIR
+local dir_tate = 3
+local dir_yoko = 4
+
+do
+  local node_next = node.next
+  local function set_list_direction(v, name)
+    if node.next(tex.nest[tex.nest.ptr].head) then
+      ltjb.package_error('luatexja',
+                        "Use `\\" .. name .. "' at top of list", 
+                        'Direction change command by LuaTeX-ja is available\n'
+                           .. 'only while current list is null.')
+    else
+       ltjs.set_stack_table(luatexja.stack_table_index.DIR, v, true)
+    end
+  end
+  luatexja.direction.set_list_direction = set_list_direction
+end
+
+do 
+   local tex_getcount = tex.getcount
+   local function set_dir_flag(h)
+      local new_dir = ltjs.table_current_stack[DIR]
+      local w = node_new(id_whatsit, sid_user)
+      setfield(w, 'user_id', wh_DIR)
+      setfield(w, 'type', 100)
+      setfield(w, 'value', new_dir)
+      setfield(w, 'next', to_direct(h))
+      return to_node(w)
+   end
+   luatexbase.add_to_callback('hpack_filter', set_dir_flag, 'ltj.set_dir_flag', 10000)
+   luatexbase.add_to_callback('vpack_filter', 
+                             function (h)
+                                local box_set, cl = 0, tex.currentgrouplevel + 1
+                                for w in traverse_id(id_whatsit, to_direct(h)) do
+                                   if getfield(w, 'value')==cl then box_set = 1; break end
+                                end
+                                ltjs.report_stack_level(tex_getcount('ltj@@stack') + box_set)
+                                return set_dir_flag(h)
+                             end, 'ltj.set_dir_flag', 1)
+   luatexbase.add_to_callback('post_linebreak_filter', 
+                             function (h)
+                                local new_dir = ltjs.table_current_stack[DIR]
+                                for line in traverse_id(id_hlist, to_direct(h)) do
+                                   set_attr(line, attr_dir, new_dir)
+                                end
+                                return h
+                             end, 'ltj.set_dir_flag', 100)
+
+end
+
+local make_dir_node
+do
+   local get_h =function (w,h,d) return h end 
+   local get_d =function (w,h,d) return d end 
+   local get_h_d =function (w,h,d) return h+d end 
+   local get_h_neg =function (w,h,d) return -h end 
+   local get_d_neg =function (w,h,d) return -d end 
+   local get_w_half =function (w,h,d) return 0.5*w end 
+   local get_w_neg_half =function (w,h,d) return -0.5*w end 
+   local get_w_neg =function (w,h,d) return -w end
+   local get_w =function (w,h,d) return w end
+   local dir_node_aux = {
+      [dir_yoko] = { -- yoko を tate 中で組む
+        width  = get_h_d,
+        height = get_w_half,
+        depth  = get_w_half,
+        [id_hlist] = {
+           { 'kern', get_h }, 
+           { 'whatsit', sid_save },
+           { 'rotate', '0 1 -1 0' },
+           { 'kern', get_w_neg_half },
+           { 'box' },
+           { 'kern', get_w_neg_half },
+           { 'whatsit', sid_restore },
+        },
+        [id_vlist] = {
+           { 'kern', get_w},
+           { 'whatsit', sid_save },
+           { 'rotate', '0 1 -1 0' },
+           { 'box' },
+           { 'kern', get_h_neg},
+           { 'whatsit', sid_restore },
+        },
+      }, 
+      [dir_tate] = { -- tate を yoko 中で組む
+        width  = get_h_d,
+        height = get_w,
+        depth  = function() return 0 end,
+        [id_hlist] = {
+           { 'kern', get_d }, 
+           { 'whatsit', sid_save },
+           { 'rotate', '0 -1 1 0' },
+           { 'kern', get_w_neg },
+           { 'box' },
+           { 'whatsit', sid_restore },
+        }, 
+        [id_vlist] = {
+           { 'whatsit', sid_save },
+           { 'rotate', '0 -1 1 0' },
+           { 'kern', get_h_neg },
+           { 'kern', get_d_neg },
+           { 'box' },
+           { 'whatsit', sid_restore },
+        }, 
+      },
+   }
+
+   make_dir_node = function (head, b, new_dir)
+      -- head: list head, b: box
+      -- return value: (new head), (next of b), (new b), (is_b_dir_node)
+      -- (new b): b か dir_node に被せられた b
+      local old_dir
+      local bh = getlist(b)
+      if bh and getid(bh)==id_whatsit and getsubtype(bh)==sid_user
+          and getfield(bh, 'user_id')==wh_DIR then
+            old_dir = getfield(bh, 'value')
+            setfield(b, 'head', node_next(bh))
+           set_attr(b, attr_icflag, PROCESSED)
+            node_free(bh)
+            print('FROM WHATSit')
+      else
+        old_dir = has_attr(b, attr_dir)
+        if old_dir==0 then old_dir =4 end
+      end
+      print(old_dir, new_dir)
+      if old_dir==new_dir  then 
+        set_attr(b, attr_icflag, PROCESSED)
+        return head, node_next(b), b, false
+      elseif  -old_dir == new_dir  then 
+        return head, node_next(b), b, true
+      else
+        local nh, nb, ret, flag
+        if old_dir < 0 then 
+           -- b itself is a dir node; just unwrap
+           local bc = node_next(node_next(
+                                   node_next(node_next(bh))))
+           node_remove(bh, bc); 
+           nh, nb =  insert_before(head, b, bc), nil
+           nh, nb = node_remove(head, b)
+           setfield(b, 'next', nil); Dnode.flush_list(b)
+           ret, flag = bc, false
+        else
+           local bid = getid(b)
+           local db = node_new(bid) -- dir node
+           nh, nb =  insert_before(head, b, db), nil
+           nh, nb = node_remove(nh, b)
+           local w = getfield(b, 'width')
+           local h = getfield(b, 'height')
+           local d = getfield(b, 'depth')
+           local info = dir_node_aux[old_dir]
+           set_attr(db, attr_dir, -new_dir)
+           set_attr(b, attr_icflag, PROCESSED)
+           set_attr(db, attr_icflag, PROCESSED)
+           setfield(db, 'dir', getfield(b, 'dir'))
+           setfield(db, 'shift', 0)
+           setfield(db, 'width',  info.width(w,h,d))
+           setfield(db, 'height', info.height(w,h,d))
+           setfield(db, 'depth',  info.depth(w,h,d))
+           local db_head, db_tail  = nil
+           for _,v in ipairs(info[bid]) do
+              local cmd, arg, nn = v[1], v[2]
+              if cmd=='kern' then
+                 nn = node_new(id_kern)
+                 setfield(nn, 'kern', arg(w, h, d))
+              elseif cmd=='whatsit' then
+                 nn = node_new(id_whatsit, arg)
+              elseif cmd=='rotate' then
+                 nn = node_new(id_whatsit, sid_matrix)
+                 setfield(nn, 'data', arg)
+              elseif cmd=='box' then
+                 nn = b; setfield(b, 'next', nil)
+              end
+              if db_head then 
+                 insert_after(db_head, db_tail, nn)
+                 db_tail = nn
+              else
+                 db_head, db_tail = nn, nn
+              end
+           end
+           setfield(db, 'head', db_head)
+           ret, flag = db, true
+        end
+        return nh, nb, ret, flag
+      end
+   end
+   local function process_dir_node(head)
+      local h = to_direct(head)
+      local x, new_dir = h, ltjs.table_current_stack[DIR]
+      while x do
+        local xid = getid(x)
+        if (xid==id_hlist and has_attr(x, attr_icflag)~=PACKED) or xid==id_vlist then
+           h, x = make_dir_node(h, x, new_dir)
+        else
+           x = node_next(x)
+        end
+      end
+      return to_node(h)
+   end
+   luatexja.direction.make_dir_node = make_dir_node
+   luatexbase.add_to_callback('vpack_filter', 
+                             process_dir_node, 'ltj.dir_node', 10001)
+end
index eb01747..3e43335 100644 (file)
@@ -11,6 +11,7 @@ local err, warn, info, log = luatexbase .errwarinf(_NAME)
 
 luatexja.load_module('stack');     local ltjs = luatexja.stack
 luatexja.load_module('jfont');     local ltjf = luatexja.jfont
+luatexja.load_module('direction'); local ltjd = luatexja.direction
 local pairs = pairs
 
 local Dnode = node.direct or node
@@ -80,6 +81,7 @@ local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
 local kanji_skip
 local xkanji_skip
 local table_current_stack
+local list_dir
 
 local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
 local attr_icflag = luatexbase.attributes['ltj@icflag']
@@ -300,15 +302,18 @@ local calc_np_auxtable = {
       return true, check_next_ickern(node_next(lp)); 
    end,
    [id_hlist] = function(lp) 
-      Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp; 
-      set_attr(lp, attr_icflag, PROCESSED)
-      Np.id = (getfield(lp, 'shift')~=0) and id_box_like or id_hlist
-      return true, node_next(lp)
+      local op, flag
+      head, lp, op, flag = ltjd.make_dir_node(head, lp, list_dir)
+      Np.first = Np.first or op; Np.last = op; Np.nuc = op; 
+      Np.id = (flag or getfield(op, 'shift')~=0) and id_box_like or id_hlist
+      return true, lp
    end,
    box_like = function(lp)
-      Np.first = Np.first or lp; Np.nuc = lp; Np.last = lp;
-      Np.id = id_box_like; set_attr(lp, attr_icflag, PROCESSED)
-      return true, node_next(lp);
+      local op
+      head, lp, op = ltjd.make_dir_node(head, lp, list_dir)
+      Np.first = Np.first or op; Np.last = op; Np.nuc = op; 
+      Np.id = id_box_like;
+      return true, lp
    end,
    skip = function(lp) 
       set_attr(lp, attr_icflag, PROCESSED)
@@ -908,11 +913,13 @@ do
    local XKANJI_SKIP   = luatexja.icflag_table.XKANJI_SKIP
    local KSK  = luatexja.stack_table_index.KSK
    local XSK  = luatexja.stack_table_index.XSK
+   local DIR  = luatexja.stack_table_index.DIR
    init_var = function (mode)
       -- 1073741823: max_dimen
       Bp, widow_Bp, widow_Np = {}, {}, {first = nil}
       table_current_stack = ltjs.table_current_stack
-      
+
+      list_dir = table_current_stack[DIR]
       kanji_skip = node_new(id_glue)
       setfield(kanji_skip, 'spec', skip_table_to_spec(KSK))
       set_attr(kanji_skip, attr_icflag, KANJI_SKIP)
index 328bf99..af20172 100644 (file)
@@ -1,5 +1,20 @@
 return {
  [0]=500,
+ {
+  ["shrink"]=26214,
+  ["shrink_order"]=0,
+  ["stretch"]=26214,
+  ["stretch_order"]=0,
+  ["width"]=0,
+ },
+ {
+  ["shrink"]=65536,
+  ["shrink_order"]=0,
+  ["stretch"]=65536,
+  ["stretch_order"]=0,
+  ["width"]=157649,
+ },
+ 4,
  [1024]=12295,
  [1025]=19968,
  [1026]=20108,
index 2a90fd2..e92d063 100644 (file)
@@ -22,7 +22,7 @@ local charprop_stack_table = charprop_stack_table
 charprop_stack_table[0]={}
 
 
-function get_stack_level()
+function get_stack_level(is_v)
    local i = tex.getcount('ltj@@stack')
    local j = tex.currentgrouplevel
    if j > tex.getcount('ltj@@group@level') then
@@ -37,8 +37,8 @@ function get_stack_level()
       charprop_stack_table[i] = table.fastcopy(charprop_stack_table[i-1])
       tex.setcount('ltj@@stack', i)
       if gd~=0 then tex.globaldefs = gd end
-      if tex.nest[tex.nest.ptr].mode == hmode or
-        tex.nest[tex.nest.ptr].mode == -hmode then
+      if  is_v or tex.nest[tex.nest.ptr].mode == hmode or
+          tex.nest[tex.nest.ptr].mode == -hmode then
         local g = node_new(id_whatsit, sid_user)
         g.user_id=STCK; g.type=100; g.value=j; node.write(g)
       end
@@ -60,8 +60,8 @@ end
 --    end
 -- end
 
-function set_stack_table(m,p)
-   local i = get_stack_level()
+function set_stack_table(m,p, is_v)
+   local i = get_stack_level(is_v)
    charprop_stack_table[i][m] = p
    if luatexja.isglobal=='global' then
       for j,v in pairs(charprop_stack_table) do 
index d0a4a47..6565bba 100644 (file)
 %%%%%%%% Attributes for Japanese typesetting.
 \newluatexattribute\ltj@icflag    % attribute for italic correction
 \newluatexattribute\ltj@curjfnt   % index for ``current Japanese font''
-\newluatexattribute\ltj@origchar %
+\newluatexattribute\ltj@origchar  %
 \newluatexattribute\ltj@charclass %
 \newluatexattribute\ltj@autospc   % attribute for autospacing
 \newluatexattribute\ltj@autoxspc  % attribute for autoxspacing
 \newluatexattribute\ltj@yablshift % attribute for \yabaselineshift
 \newluatexattribute\ltj@ykblshift % attribute for \ykbaselineshift
 \newluatexattribute\jfam          % index for current jfam
+\newluatexattribute\ltj@dir       % temp attr for indicating box direction
+
+\ltj@dir=0
 \ltj@icflag=0
 \ltj@origchar=0
 \ltj@charclass=0
 \protected\def\inhibitglue{\ifhmode\ltj@@ihb\fi}
 \def\ltj@@ihb{\relax\directlua{luatexja.jfmglue.create_inhibitglue_node()}}
 
-%%%%%%%% \yoko, \tate, \ifydir, \iftdir
-%% At this moment, tategaki mode is not implemented;
-%% there is only yokogaki mode now.
-\let\yoko\relax
-\let\tate\relax
-\newif\ifydir\ydirtrue
-\newif\iftdir\tdirfalse
-
 %%%%%%%% \ltjdefcharrange<name>{100-200,3000-,5000,...}
 \protected\def\ltjdefcharrange#1#2{%
   {\ltj@tempcntc=#1 \expandafter\ltj@@dcrange#2,,}\ignorespaces}
 \newluatexcatcodetable\ltj@temp@cctb
 \def\ltj@overwrite@catcodetable#1{%
   \setluatexcatcodetable\ltj@temp@cctb{\luatexcatcodetable#1}%
-  \setluatexcatcodetable#1{\luatexcatcodetable\ltj@temp@cctb\catcode"FFFFF=14}%
+  \setluatexcatcodetable#1{\luatexcatcodetable\ltj@temp@cctb\catcode"FFFFF=14}%"
 }
 \ltj@overwrite@catcodetable\CatcodeTableLaTeX
 \ltj@overwrite@catcodetable\CatcodeTableLaTeXAtLetter
 \ltj@overwrite@catcodetable\CatcodeTableExpl
 
+%%%%%%%% \yoko, \tate, \ifydir, \iftdir
+\protected\def\tate{%
+  \directlua{luatexja.direction.set_list_direction(3, 'tate')}%
+}
+\protected\def\yoko{%
+  \directlua{luatexja.direction.set_list_direction(4, 'yoko')}%
+}
+\yoko
+\newif\ifydir\ydirtrue
+\newif\iftdir\tdirfalse
+
+
 %%------------------ all done
 \ltj@core@AtEnd
 \endinput
index 0e9f64e..0a6cdad 100644 (file)
@@ -48,6 +48,7 @@ stack_table_index.RIPOST = 0xC00000 -- characterごと,ruby post
 stack_table_index.JWP  = 0 -- これだけ
 stack_table_index.KSK  = 1 -- これだけ
 stack_table_index.XSK  = 2 -- これだけ
+stack_table_index.DIR  = 3 -- これだけ
 stack_table_index.MJT  = 0x100 -- 0--255
 stack_table_index.MJS  = 0x200 -- 0--255
 stack_table_index.MJSS = 0x300 -- 0--255
@@ -58,6 +59,7 @@ luatexja.userid_table = userid_table
 userid_table.IHB  = luatexbase.newuserwhatsitid('inhibitglue',  'luatexja') -- \inhibitglue
 userid_table.STCK = luatexbase.newuserwhatsitid('stack_marker', 'luatexja') -- スタック管理
 userid_table.BPAR = luatexbase.newuserwhatsitid('begin_par',    'luatexja') -- 「段落始め」
+userid_table.DIR  = luatexbase.newuserwhatsitid('direction',    'luatexja') -- 組方向
 
 ------------------------------------------------------------------------
 -- FIX node.remove
@@ -111,12 +113,14 @@ load_module('jfmglue');   local ltjj = luatexja.jfmglue
 load_module('setwidth');  local ltjw = luatexja.setwidth
 load_module('math');      local ltjm = luatexja.math
 load_module('tangle');    local ltjb = luatexja.base
+load_module('direction'); local ltjd = luatexja.direction
 
 local attr_jchar_class = luatexbase.attributes['ltj@charclass']
 local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
 local attr_yablshift = luatexbase.attributes['ltj@yablshift']
 local attr_icflag = luatexbase.attributes['ltj@icflag']
 local attr_uniqid = luatexbase.attributes['ltj@uniqid']
+local attr_dir = luatexbase.attributes['ltj@dir']
 local cat_lp = luatexbase.catcodetables['latex-package']
 
 -- Three aux. functions, bollowed from tex.web
@@ -360,6 +364,7 @@ local function debug_show_node_X(p,print_fn)
    local pt=node_type(p.id)
    local base = debug_depth .. string.format('%X', get_attr_icflag(p))
    .. ' ' .. pt .. ' ' .. tostring(p.subtype) .. ' '
+      .. ' dir=' .. tostring(has_attr(p, attr_dir)) .. ' '
    if pt == 'glyph' then
       s = base .. ' ' .. utf.char(p.char) .. ' '  .. tostring(p.font)
          .. ' (' .. print_scaled(p.height) .. '+' 
@@ -425,7 +430,7 @@ local function debug_show_node_X(p,print_fn)
       end
       print_fn(s)
    elseif pt == 'whatsit' then
-      s = base .. ' subtype: ' ..  tostring(p.subtype)
+      s = base
       if p.subtype==sid_user then
          if p.type ~= 110 then 
             s = s .. ' user_id: ' .. p.user_id .. ' ' .. p.value
diff --git a/test/test51-vtest.pdf b/test/test51-vtest.pdf
new file mode 100644 (file)
index 0000000..eab6d1f
Binary files /dev/null and b/test/test51-vtest.pdf differ
diff --git a/test/test51-vtest.tex b/test/test51-vtest.tex
new file mode 100644 (file)
index 0000000..62d6379
--- /dev/null
@@ -0,0 +1,83 @@
+%#!luatex
+
+\input luatexja.sty
+%\input lua-visual-debug.sty
+
+\catcode`\@=11
+\newdimen\@tempdima
+\newbox\@tempboxa
+\newdimen\fboxrule
+\newdimen\fboxsep
+\fboxrule=0.4pt\fboxsep=0pt
+\long\def\fbox#1{%
+  \leavevmode
+  \setbox\@tempboxa\hbox{\kern\fboxsep{#1}\kern\fboxsep}%
+  \@frameb@x\relax}
+\def\@frameb@x#1{%
+  \@tempdima\fboxrule
+  \advance\@tempdima\fboxsep
+  \advance\@tempdima\dp\@tempboxa
+  \hbox{%
+    \lower\@tempdima\hbox{%
+      \vbox{%
+        \hrule height\fboxrule
+        \hbox{%
+          \vrule width\fboxrule
+          #1%
+          \vbox{%
+            \vskip\fboxsep
+            \box\@tempboxa
+            \vskip\fboxsep}%
+          #1%
+          \vrule width\fboxrule}%
+        \hrule height\fboxrule}%
+                          }%
+        }%
+}
+
+\hbox{\yoko
+横水平Hxy\hbox{\yoko 横水平Hxy}かき◆
+\hbox{\tate 縦水平Hxy}◆おおおお
+\vbox{\yoko\hsize=30mm 横垂直Hxyああああああああああ}かき◆
+\vbox{\tate\hsize=30mm  縦垂直Hxy\hfill ああ\break ああああああああ}◆ああああ
+}
+\vfill\eject
+\hbox{\tate
+縦水平Hxy\hbox{\yoko 横水平Hxy}かき◆
+\hbox{\tate 縦水平Hxy}◆おおおお
+\vbox{\yoko\hsize=30mm 横垂直Hxyああああああああああ}かき◆
+\vbox{\tate\hsize=30mm  縦垂直Hxy\hfill ああ\break ああああああああ}◆ああああ
+}
+
+\vfill\eject
+
+
+\setbox0=\vbox{\yoko\hsize=100mm
+横垂直Hxy\hbox{\yoko 横水平Hxy}かき◆
+これは,意味のないサンプルテキストです.
+\hbox{\tate 縦水平Hxy}◆おおおお
+これは,意味のないサンプルテキストです.
+\vbox{\yoko\hsize=50mm 横垂直Hxyあああああああああああああああああああ}かき◆
+これは,意味のないサンプルテキストです.
+\vbox{\tate\hsize=50mm 縦垂直Hxyあああああああああああああああああああ}◆ああああ
+これは,意味のないサンプルテキスト\hbox{\tate 縦水平Hxy}◆おおおおです.
+}
+\copy0
+%{\showboxbreadth10000\showboxdepth10000
+%\showbox0}
+
+\vfill\eject
+\vbox{\tate\hsize=100mm
+縦垂直Hxy\hbox{\yoko 横水平Hxy}かき◆
+これは,意味のないサンプルテキストです.
+\hbox{\tate 縦水平Hxy}◆おおおお
+これは,意味のないサンプルテキストです.
+\vbox{\yoko\hsize=50mm 横垂直Hxyあああああああああああああああああああ}かき◆
+これは,意味のないサンプルテキストです.
+\vbox{\tate\hsize=50mm  縦垂直Hxyあああああああああああああああああああ}◆ああああ
+これは,意味のないサンプルテキスト\hbox{\tate 縦水平Hxy}◆おおおお
+です.
+}
+
+\end
+