From 7a5213796bdde7d0578c623e01d72a3a3ca81eee Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 20 Apr 2022 19:42:41 +0000 Subject: luapstricks (20apr22) git-svn-id: svn://tug.org/texlive/trunk@63086 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/doc/lualatex/luapstricks/README.md | 40 +++-- .../tex/lualatex/luapstricks/luapstricks.lua | 183 ++++++++++++++++----- 2 files changed, 161 insertions(+), 62 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/lualatex/luapstricks/README.md b/Master/texmf-dist/doc/lualatex/luapstricks/README.md index 69a01740570..9e2f2a53972 100644 --- a/Master/texmf-dist/doc/lualatex/luapstricks/README.md +++ b/Master/texmf-dist/doc/lualatex/luapstricks/README.md @@ -1,35 +1,39 @@ # `luapstricks` -- A PSTricks backend for LuaTeX + Support PSTricks directly in LuaTeX, without requiring external processes, special environments or similar. Since recent PSTricks versions load `luapstricks` automatically when LuaLaTeX is used, this does not require changes to the document. Some advanced features require the `pdfmanagement-testphase` package to be loaded and activated. ## Usage - 1. Make sure that you have the latest pstricks version installed. - 2. Run `l3build install` *or* copy `luapstricks.lua` from this repository into the directory of your TeX files or another directory in your TeX search path. - 3. Compile your document with `lualatex`. - 4. Given that most people immediately stop reading after they get a result and you are still here, the previous stage probably failed. Write a bug report to the author. Otherwise go to step 7. - 5. Wait for a fix. - 6. Go back to step 2 and try again. - 7. It worked? That's great. Feel free to inform the author anyway and share the awesome images you created. + +1. Make sure that you have the latest pstricks version installed. +2. Run `l3build install` *or* copy `luapstricks.lua` from this repository into the directory of your TeX files or another directory in your TeX search path. +3. Compile your document with `lualatex`. +4. Given that most people immediately stop reading after they get a result and you are still here, the previous stage probably failed. Write a bug report to the author. Otherwise go to step 7. +5. Wait for a fix. +6. Go back to step 2 and try again. +7. It worked? That's great. Feel free to inform the author anyway and share the awesome images you created. ## Issues and feature requests + Should you find a bug or want to request a feature, please report it using the [issue tracker](https://github.com/zauguin/luapstricks/issues). ## License + This code is licensed under the LaTeX Project Public License 1.3. ## Acknowledgments + This project would never have reached a usable state without all the testing and suggestions by Pablo González Luengo. Also many thanks to Herbert Voß for adapting PSTricks and related packages to work with luapstricks. ## Demos + Documentation of PSTricks packages, created by `lualatex` and `luapstricks.lua`: - [pst-user](https://hvoss.org/PSTexa/pst-user.pdf) Main (historical) documentation without overlay stuff (is now in pst-ovl) -- [pstricks-add](https://hvoss.org/PSTexa/pstricks-add-doc.pdf) - - +- [pstricks-add](https://hvoss.org/PSTexa/pstricks-add-doc.pdf) - [pst-3d](https://hvoss.org/PSTexa/pst-3d-doc.pdf) - [pst-3dplot](https://hvoss.org/PSTexa/pst-3dplot-doc.pdf) - [pst-am](https://hvoss.org/PSTexa/pst-am-doc.pdf) @@ -48,12 +52,12 @@ Documentation of PSTricks packages, created by `lualatex` and `luapstricks.lua`: - [pst-platon](https://hvoss.org/PSTexa/pst-platon-doc.pdf) - [pst-plot](https://hvoss.org/PSTexa/pst-plot-doc.pdf) - [pst-poly](https://hvoss.org/PSTexa/pst-poly-doc.pdf) -- [pst-solarsystem](https://hvoss.org/PSTexa/pst-solarsystem-doc.pdf) -- [pst-soroban](https://hvoss.org/PSTexa/pst-soroban-doc.pdf) -- [pst-spinner](https://hvoss.org/PSTexa/pst-spinner-doc.pdf) -- [pst-stru](https://hvoss.org/PSTexa/pst-stru-doc.pdf) -- [pst-tools](https://hvoss.org/PSTexa/pst-tools-doc.pdf) +- [pst-solarsystem](https://hvoss.org/PSTexa/pst-solarsystem-doc.pdf) +- [pst-soroban](https://hvoss.org/PSTexa/pst-soroban-doc.pdf) +- [pst-spinner](https://hvoss.org/PSTexa/pst-spinner-doc.pdf) +- [pst-stru](https://hvoss.org/PSTexa/pst-stru-doc.pdf) +- [pst-tools](https://hvoss.org/PSTexa/pst-tools-doc.pdf) - [pst-tree](https://hvoss.org/PSTexa/pst-tree-doc.pdf) -- [pst-turtle](https://hvoss.org/PSTexa/pst-turtle-doc.pdf) -- [pst-vehicle](https://hvoss.org/PSTexa/pst-vehicle-doc.pdf) -- [pst-venn](https://hvoss.org/PSTexa/pst-venn-doc.pdf) +- [pst-turtle](https://hvoss.org/PSTexa/pst-turtle-doc.pdf) +- [pst-vehicle](https://hvoss.org/PSTexa/pst-vehicle-doc.pdf) +- [pst-venn](https://hvoss.org/PSTexa/pst-venn-doc.pdf) diff --git a/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua index e505f5458aa..874d141206b 100644 --- a/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua +++ b/Master/texmf-dist/tex/lualatex/luapstricks/luapstricks.lua @@ -1,5 +1,5 @@ ---- luapstricks.lua --- Copyright 2021 Marcel Krüger +-- Copyright 2021--2022 Marcel Krüger -- -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.3 @@ -18,12 +18,15 @@ if luatexbase then luatexbase.provides_module { name = 'luapstricks', - version = 'v0.4', - date = '2021-12-29', + version = 'v0.5', + date = '2022-04-20', description = 'PSTricks backend for LuaLaTeX', } end +local setwhatsitfield = node.setwhatsitfield or node.setfield +local late_lua_sub = node.subtype'late_lua' + local pdfprint = vf.pdf -- Set later to have the right mode local function gobble() end @@ -1638,6 +1641,56 @@ systemdict = {kind = 'dict', value = { push(a b and a or b) + end, + min = function() + local b, arg2 = pop() + local a, arg1 = pop(arg2) + local ta, tb = type(a), type(b) + if ta == 'table' and a.kind == 'executable' then + a = a.value ta = type(a) + end + if tb == 'table' and b.kind == 'executable' then + b = b.value tb = type(b) + end + if ta == 'number' then + if tb ~= 'number' then + ps_error('typecheck', arg1, arg2) + end + elseif ta == 'table' and ta.kind == 'string' then + if tb ~= 'table' or tb.kind ~= 'string' then + ps_error('typecheck', arg1, arg2) + end + a, b = a.value, b.value + else + ps_error('typecheck', arg1, arg2) + end + push(a < b and a or b) + end, + add = function() local b, arg2 = pop_num() local a = pop_num(arg2) @@ -2102,8 +2155,12 @@ systemdict = {kind = 'dict', value = { local state = graphics_stack[#graphics_stack] local current_path = state.current_path if current_path then - local i = #current_path + 1 - current_path[i], current_path[i+1], current_path[i+2] = x, y, 'm' + local i = #current_path + if i ~= 1 and current_path[i] == 'm' then + current_path[i-2], current_path[i-1] = x, y + else + current_path[i+1], current_path[i+2], current_path[i+3] = x, y, 'm' + end local current_point = state.current_point current_point[1], current_point[2] = x, y else @@ -2118,8 +2175,12 @@ systemdict = {kind = 'dict', value = { local x = pop_num() local current_point = state.current_point x, y = current_point[1] + x, current_point[2] + y - local i = #current_path + 1 - current_path[i], current_path[i+1], current_path[i+2] = x, y, 'm' + local i = #current_path + if i ~= 1 and current_path[i] == 'm' then + current_path[i-2], current_path[i-1] = x, y + else + current_path[i+1], current_path[i+2], current_path[i+3] = x, y, 'm' + end current_point[1], current_point[2] = x, y end, lineto = function() @@ -3994,20 +4055,67 @@ function execute_string(str, context) end end +--[[ + local readstate = status.readstate or status + local context = string.format('%s:%i', readstate.filename, readstate.linenumber) + local tokens = token.scan_argument(true) + local n = node.new('whatsit', late_lua_sub) + setwhatsitfield(n, 'data', function() + assert(not ps_tokens) + ps_tokens = tokens + ps_context = context + end) + local nn = node.new('glyph') + nn.subtype = 256 + nn.font, nn.char = fid, 0x1F3A8 + n.next = nn + if tex.nest.ptr == 0 then + -- Main vertical list. Here we might appear before the page starts properly + -- and should not freeze page specifications. Since we don't have any outer dimensions, + -- we can ensure this by sneaking our node into the current page list whithout going though + -- build_page. + tex.triggerbuildpage() -- First ensure that everything else is contributed properly. + tex.lists.page_head = node.insert_after(tex.lists.page_head, nil, n) + else + node.write(n) + end +end +]] local func = luatexbase.new_luafunction'luaPSTheader' token.set_lua('luaPSTheader', func, 'protected') lua.get_functions_table()[func] = function() - local stack_depth = #operand_stack - local filename = token.scan_argument() - local f = io.open(kpse.find_file(filename, 'PostScript header'), 'r') - local src = f:read'a' - f:close() - execute_string(src, filename) - if #operand_stack ~= stack_depth then - error'Unexpected values on operand stack' - end + local is_inline = token.scan_keyword'inline' + local readstate = status.readstate or status + local context = is_inline and string.format('%s:%i', readstate.filename, readstate.linenumber) + local data = token.scan_argument(true) + local n = node.new('whatsit', late_lua_sub) + setwhatsitfield(n, 'data', function() + if not is_inline then + context = data + local f = io.open(kpse.find_file(data, 'PostScript header'), 'r') + data = f:read'a' + f:close() + end + local stack_depth = #operand_stack + + local x, y = pdf.getpos() + local height = #operand_stack + operand_stack[height + 1], operand_stack[height + 2] = x/65781.76, y/65781.76 + systemdict.value.moveto() + + local saved_pdfprint = pdfprint + pdfprint = function(s) return pdf.print('direct', s .. '\n') end + execute_string(data, context) + flush_delayed() + pdfprint = saved_pdfprint + if #operand_stack ~= stack_depth then + error'Unexpected values on operand stack' + end + end) + node.write(n) end +--[[ local func = luatexbase.new_luafunction'showPS' token.set_lua('showPS', func, 'protected') lua.get_functions_table()[func] = function() @@ -4017,6 +4125,7 @@ lua.get_functions_table()[func] = function() execute_ps(tokens) systemdict.value.stack() end +]] local ps_tokens, ps_direct, ps_context, ps_pos_x, ps_pos_y local fid = font.define{ @@ -4100,40 +4209,26 @@ local modes = tex.getmodevalues() local func = luatexbase.new_luafunction'luaPST' token.set_lua('luaPST', func, 'protected') lua.get_functions_table()[func] = function() - local context = string.format('%s:%i', status.filename, status.linenumber) + local readstate = status.readstate or status + local context = string.format('%s:%i', readstate.filename, readstate.linenumber) local direct = token.scan_keyword'direct' local tokens = token.scan_argument(true) - local n = node.new('whatsit', 'late_lua') - function n.data() + local n = node.new('whatsit', late_lua_sub) + setwhatsitfield(n, 'data', function(n) assert(not ps_tokens) ps_tokens = tokens ps_direct = direct ps_context = context - end - local nn = node.new('glyph') - nn.subtype = 256 - nn.font, nn.char = fid, 0x1F3A8 - n.next = nn - local modename = modes[math.abs(tex.nest.top.mode)] - if 'horizontal' ~= modename then - n = node.hpack(n) -- Glyphs can only appear in hmode - if 'math' == modename then - local d = node.new'disc' - d.penalty = 10000 - d.replace = n - n = d - end - end - if tex.nest.ptr == 0 then - -- Main vertical list. Here we might appear before the page starts properly - -- and should not freeze page specifications. Since we don't have any outer dimensions, - -- we can ensure this by sneaking our node into the current page list whithout going though - -- build_page. - tex.triggerbuildpage() -- First ensure that everything else is contributed properly. - tex.lists.page_head = node.insert_after(tex.lists.page_head, nil, n) - else - node.write(n) - end + + local nn = node.new('glyph') + nn.subtype = 256 + nn.font, nn.char = fid, 0x1F3A8 + local list = node.new('hlist') + list.head = nn + list.direction = 0 + node.insert_after(n, n, list) + end) + node.write(n) end do -- cgit v1.2.3