summaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-04-21 03:01:37 +0000
committerNorbert Preining <norbert@preining.info>2022-04-21 03:01:37 +0000
commit21fe0e070af2427bda486f49569e1a5cb3df486d (patch)
tree55d1fb5f8488adb2047db2ce4d40aeb4fe0bfdcf /graphics
parentb981b5402a493d6d8c0eb44c350072ff41deb068 (diff)
CTAN sync 202204210301
Diffstat (limited to 'graphics')
-rw-r--r--graphics/pstricks/contrib/luapstricks/README.md40
-rw-r--r--graphics/pstricks/contrib/luapstricks/luapstricks.lua183
2 files changed, 161 insertions, 62 deletions
diff --git a/graphics/pstricks/contrib/luapstricks/README.md b/graphics/pstricks/contrib/luapstricks/README.md
index 69a0174057..9e2f2a5397 100644
--- a/graphics/pstricks/contrib/luapstricks/README.md
+++ b/graphics/pstricks/contrib/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/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