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.lua228
1 files changed, 92 insertions, 136 deletions
diff --git a/graphics/pstricks/contrib/luapstricks/luapstricks.lua b/graphics/pstricks/contrib/luapstricks/luapstricks.lua
index 874d141206..5482582d15 100644
--- a/graphics/pstricks/contrib/luapstricks/luapstricks.lua
+++ b/graphics/pstricks/contrib/luapstricks/luapstricks.lua
@@ -18,8 +18,8 @@
if luatexbase then
luatexbase.provides_module {
name = 'luapstricks',
- version = 'v0.5',
- date = '2022-04-20',
+ version = 'v0.6',
+ date = '2022-09-10',
description = 'PSTricks backend for LuaLaTeX',
}
end
@@ -29,6 +29,13 @@ local late_lua_sub = node.subtype'late_lua'
local pdfprint = vf.pdf -- Set later to have the right mode
local function gobble() end
+local function no_pdfprint_allowed()
+ pdfprint = gobble -- Don't warn more than once for each code block
+ tex.error("luapstricks: Graphics in immediate code segment", {
+ "There was an attempt to trigger drawing commands in an immediate code block. \z
+ This isn't allowed and will therefore be ignored."
+ })
+end
local pi = math.pi
local two_pi = 2*pi
@@ -4055,77 +4062,55 @@ 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 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
+-- If x, y shall be present iff direct ~= 'immediate'
+local function outer_execute(tokens, direct, context, x, y)
+ local TeXDict = userdict.value.TeXDict.value
+ local saved_ocount = TeXDict.ocount
+ local height = #operand_stack
+ TeXDict.ocount = height
+ local graphics_height
+ if direct ~= 'immediate' then
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'
+ if direct then
+ systemdict.value.moveto()
+ else
+ graphics_height = #graphics_stack
+ systemdict.value.gsave()
+ systemdict.value.translate()
end
- end)
- node.write(n)
-end
-
---[[
-local func = luatexbase.new_luafunction'showPS'
-token.set_lua('showPS', func, 'protected')
-lua.get_functions_table()[func] = function()
- local command = token.scan_argument(true)
- -- This will break if any graphics commands are used.
- local tokens = parse_ps(command)
- execute_ps(tokens)
- systemdict.value.stack()
+ end
+ local success, err = pcall(execute_string, tokens, context)
+ if not success then
+ if type(err) == 'table' and err.pserror then
+ tex.error(string.format('luapstricks: %q error occured while executing PS code from %q', err.pserror, err.context), {
+ string.format('The error occured while executing the PS command %q.\n%s', err.tok, err.trace)
+ })
+ else
+ error(err, 0)
+ end
+ end
+ flush_delayed()
+ if not direct then
+ systemdict.value.grestore()
+ if graphics_height ~= #graphics_stack then
+ if graphics_height < #graphics_stack then
+ texio.write_nl"luapstricks: PS block contains unbalanced gsave. grestore will be executed to compensate."
+ repeat
+ systemdict.value.grestore()
+ until graphics_height == #graphics_stack
+ else
+ texio.write_nl"luapstricks: PS block contains unbalanced grestore."
+ end
+ end
+ height = TeXDict.ocount or height
+ local new_height = #operand_stack
+ assert(new_height >= height)
+ for k = height + 1, new_height do
+ operand_stack[k] = nil
+ end
+ TeXDict.ocount = saved_ocount
+ end
end
-]]
local ps_tokens, ps_direct, ps_context, ps_pos_x, ps_pos_y
local fid = font.define{
@@ -4151,85 +4136,56 @@ local fid = font.define{
[1] = {
commands = {
{'lua', function()
- local tokens, direct = assert(ps_tokens), ps_direct
- ps_tokens = nil
- local x, y = pdf.getpos()
- local TeXDict = userdict.value.TeXDict.value
- local saved_ocount = TeXDict.ocount
- local height = #operand_stack
- TeXDict.ocount = height
- operand_stack[height + 1], operand_stack[height + 2] = ps_pos_x/65781.76, ps_pos_y/65781.76
- ps_pos_x, ps_pos_y = nil
- local graphics_height
- if direct then
- systemdict.value.moveto()
- else
- graphics_height = #graphics_stack
- systemdict.value.gsave()
- systemdict.value.translate()
- end
- local success, err = pcall(execute_string, tokens, ps_context)
- if not success then
- if type(err) == 'table' and err.pserror then
- tex.error(string.format('luapstricks: %q error occured while executing PS code from %q', err.pserror, err.context), {
- string.format('The error occured while executing the PS command %q.\n%s', err.tok, err.trace)
- })
- else
- error(err, 0)
- end
- end
- flush_delayed()
- if not direct then
- systemdict.value.grestore()
- if graphics_height ~= #graphics_stack then
- if graphics_height < #graphics_stack then
- texio.write_nl"luapstricks: PS block contains unbalanced gsave. grestore will be executed to compensate."
- repeat
- systemdict.value.grestore()
- until graphics_height == #graphics_stack
- else
- texio.write_nl"luapstricks: PS block contains unbalanced grestore."
- end
- end
- height = TeXDict.ocount or height
- local new_height = #operand_stack
- assert(new_height >= height)
- for k = height + 1, new_height do
- operand_stack[k] = nil
- end
- TeXDict.ocount = saved_ocount
- end
+ local tokens, x, y = assert(ps_tokens), ps_pos_x, ps_pos_y
+ ps_tokens, ps_pos_x, ps_pos_y = nil
+ return outer_execute(tokens, ps_direct, ps_context, x, y)
end}
}
},
},
}
-local modes = tex.getmodevalues()
local func = luatexbase.new_luafunction'luaPST'
token.set_lua('luaPST', func, 'protected')
lua.get_functions_table()[func] = function()
local readstate = status.readstate or status
local context = string.format('%s:%i', readstate.filename, readstate.linenumber)
- local direct = token.scan_keyword'direct'
+ local direct = token.scan_keyword'immediate' and 'immediate' or token.scan_keyword'direct' and 'direct'
+ local file = token.scan_keyword'file'
local tokens = token.scan_argument(true)
- 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
-
- 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)
+ if file then
+ context = tokens
+ local f = io.open(kpse.find_file(tokens, 'PostScript header'), 'r')
+ tokens = f:read'a'
+ f:close()
+ end
+ if direct == 'immediate' then
+ local saved_pdfprint = pdfprint
+ pdfprint = no_pdfprint_allowed
+ outer_execute(tokens, direct, context)
+ pdfprint = saved_pdfprint
+ else
+ 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
+
+ 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
end
+tex.runtoks(function()
+ tex.sprint[[\protected\def\luaPSTheader{\luaPST direct file}]]
+end)
do
func = luatexbase.new_luafunction'luaPSTcolor'