summaryrefslogtreecommitdiff
path: root/graphics/pstricks/contrib/luapstricks/luapstricks.lua
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pstricks/contrib/luapstricks/luapstricks.lua')
-rw-r--r--graphics/pstricks/contrib/luapstricks/luapstricks.lua183
1 files changed, 139 insertions, 44 deletions
diff --git a/graphics/pstricks/contrib/luapstricks/luapstricks.lua b/graphics/pstricks/contrib/luapstricks/luapstricks.lua
index e505f5458a..874d141206 100644
--- a/graphics/pstricks/contrib/luapstricks/luapstricks.lua
+++ b/graphics/pstricks/contrib/luapstricks/luapstricks.lua
@@ -1,5 +1,5 @@
---- luapstricks.lua
--- Copyright 2021 Marcel Krüger <tex@2krueger.de>
+-- Copyright 2021--2022 Marcel Krüger <tex@2krueger.de>
--
-- 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)
end,
+ -- The following two are GhostScript extensions
+ max = 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,
+ 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