luametalatex/luametalatex-baseregisters.lua

205 lines
8.0 KiB
Lua

local lmlt = luametalatex
local scan_dimen = token.scan_dimen
local scan_int = token.scan_int
local scan_keyword = token.scan_keyword
local count_code = lmlt.value.integer
local dimen_code = lmlt.value.dimension
local set_local = require'luametalatex-local'
local texmeta = getmetatable(tex)
local texmetaoldindex = texmeta.__index
local texmetaoldnewindex = texmeta.__newindex
local tex_variables = __luametalatex__preserved_tex_variables or {}
__luametalatex__preserved_tex_variables = nil
function texmeta.__index(t, k)
return tex_variables[k] or texmetaoldindex(t, k)
end
function texmeta.__newindex(t, k, v)
if tex_variables[k] then
return set_local(tex_variables, k, v)
else
return texmetaoldnewindex(t, k, v)
end
end
local function tex_variable(value, scanner, name, default)
lmlt.luacmd(name, function(_, scanning)
if scanning == 'value' then
return value, tex_variables[name]
else
scan_keyword'='
return set_local(tex_variables, name, scanner(), scanning and scanning & 4 == 4)
end
end, 'global', 'value')
if status.ini_version then
tex_variables[name] = default
end
end
local real_pdf_variables = __luametalatex__preserved_real_pdf_variables or {}
__luametalatex__preserved_real_pdf_variables = nil
local pdf_variable_names = {}
local pdf_toks_map = {}
local pdf_variables = setmetatable(pdf.variable, {
__index = function(_, k)
local v = real_pdf_variables[k]
if v then return v end
v = pdf_toks_map[k]
if v then
return tex.toks[v]
end
end,
__newindex = function(_, k, v)
if real_pdf_variables[k] then
return set_local(real_pdf_variables, k, v)
end
local toks = pdf_toks_map[k]
if toks then
tex.toks[toks] = v
end
end,
})
pdf.variable_names = pdf_variable_names
local pdf_toks
if status.ini_version then
local pdf_toks_list = {}
function pdf_toks(name, default)
pdf_variable_names[#pdf_variable_names+1] = name
pdf_toks_list[#pdf_toks_list+1] = {name, default}
end
function initialize_pdf_toks()
for i=1,#pdf_toks_list do
local entry = pdf_toks_list[i]
local csname = 'pdfvariable ' .. entry[1]
token.set_char(csname, 0) -- Ensure that csname exists
local t = token.create(csname)
tex.runtoks(function()
token.put_next(token.create'newtoks', t)
end)
pdf_toks_map[entry[1]] = t.index
tex.toks[t.index] = entry[2]
end
end
else
function pdf_toks(name, default)
pdf_variable_names[#pdf_variable_names+1] = name
local t = token.create('pdfvariable ' .. name)
pdf_toks_map[name] = t.index
tex.toks[t.index] = default
end
end
local function pdf_variable(value, scanner, name, default, force_default)
pdf_variable_names[#pdf_variable_names+1] = name
lmlt.luacmd('pdfvariable ' .. name, function(_, scanning)
if scanning == 'value' then
return value, real_pdf_variables[name]
elseif force_default then
scan_keyword'='
local new = scanner()
if new ~= default then
texio.write_nl('term and log', string.format("Unsupported PDF variable: \z
%q is not supported and fixed to %i, but you tried to set it to %i", name, default, new))
end
else
scan_keyword'='
return set_local(real_pdf_variables, name, scanner(), scanning == 'global')
end
end, 'global', 'protected', 'value')
if status.ini_version then
real_pdf_variables[name] = default
end
end
tex_variable(count_code, scan_int, 'suppressfontnotfounderror', 0)
tex_variable(count_code, scan_int, 'outputmode', 1) -- The "traditional" default would be 0,
-- but we do not actually support that.
tex_variable(count_code, scan_int, 'tracingscantokens', 0)
tex_variable(dimen_code, scan_dimen, 'pageheight', 0)
tex_variable(dimen_code, scan_dimen, 'pagewidth', 0)
tex_variable(dimen_code, scan_dimen, 'hoffset', 0)
tex_variable(dimen_code, scan_dimen, 'voffset', 0)
tex_variable(count_code, scan_int, 'bodydirection', 0)
tex_variable(count_code, scan_int, 'pagedirection', 0)
pdf_variable(dimen_code, scan_dimen, 'horigin', tex.sp'1in')
pdf_variable(dimen_code, scan_dimen, 'vorigin', tex.sp'1in')
pdf_variable(dimen_code, scan_dimen, 'linkmargin', tex.sp'0pt')
pdf_variable(dimen_code, scan_dimen, 'destmargin', tex.sp'0pt')
pdf_variable(dimen_code, scan_dimen, 'xformmargin', tex.sp'0pt')
pdf_variable(dimen_code, scan_dimen, 'threadmargin', tex.sp'0pt', true) -- We don't support threads, so this isn't doing anything
pdf_variable(count_code, scan_int, 'majorversion', 1)
pdf_variable(count_code, scan_int, 'minorversion', 7)
pdf_variable(count_code, scan_int, 'compresslevel', 9)
pdf_variable(count_code, scan_int, 'objcompresslevel', 3)
pdf_variable(count_code, scan_int, 'decimaldigits', 4, true) -- Will probably stay fixed, but should be more consistent
pdf_variable(count_code, scan_int, 'gentounicode', 0, true) -- We expect the fontloader to generade tounicode tables. Might change at some point
-- These two are ignored, but that is consistent with pdfTeX as long as imageapplygamma is 0:
pdf_variable(count_code, scan_int, 'gamma', 1000)
pdf_variable(count_code, scan_int, 'imagegamma', 1000)
pdf_variable(count_code, scan_int, 'imageapplygamma', 0, true)
pdf_variable(count_code, scan_int, 'imagehicolor', 1, true) -- We don't consider ancient PDF versions, no no reason to strip images
pdf_variable(count_code, scan_int, 'imageaddfilename', 0, true) -- Could be added, but I never saw a reason for this anyway.
pdf_variable(count_code, scan_int, 'inclusionerrorlevel', -1, true) -- FIXME: At least a warning should be supported
pdf_variable(count_code, scan_int, 'inclusioncopyfonts', 0, true) -- Would be fragile and restrict our ability to use "creative" font constructs
pdf_variable(count_code, scan_int, 'uniqueresname', 0, true) -- I add this if you show me a usecase
pdf_variable(count_code, scan_int, 'pagebox', 2, true) -- TODO (1: media, 2: crop, 3: bleed, 4: trim, 5: art
pdf_variable(count_code, scan_int, 'forcepagebox', 0, true) -- Considered obsolete even in pdfTeX
pdf_variable(count_code, scan_int, 'imageresolution', 72, true) -- TODO Also 0 should be the same as 72 ?!?!?!?
pdf_variable(count_code, scan_int, 'pkresolution', 1200) -- Original default is 72, but that's crazy
pdf_variable(count_code, scan_int, 'pkfixeddpi', 0) -- TODO: Implemented, but even when set to one, font sharing doesn't adapt yet.
-- Changing that is complicated because it has to be known pretty early.
pdf_toks('pkmode', '')
pdf_toks('pageattr', '')
pdf_toks('pagesattr', '')
pdf_toks('pageresources', '')
-- The following two are special: The should have force_default=true because we ignore them,
-- but they are token lists so that doesn't really work. Instead, we check during shipout that
-- the variables are empty. TODO: Find a nicer solution
-- The reason for not implementing them is that XForm specific resources and attributes make
-- much more sense, so these two generic ones are useless and error-prone.
pdf_toks('xformresources', '')
pdf_toks('xformattr', '')
function tex.getbodydir() return tex.bodydirection end
function tex.getpagedir() return tex.pagedirection end
function tex.setbodydir(i) tex.bodydirection = i end
function tex.setpagedir(i) tex.pagedirection = i end
local dir_regs = require 'luametalatex-dir-registers'
dir_regs 'textdir'
dir_regs 'bodydir'
dir_regs 'pagedir'
dir_regs 'pardir'
dir_regs 'linedir'
dir_regs 'mathdir'
if status.ini_version then
-- Run in pre_dump callback:
lua.prepared_code[#lua.prepared_code+1] = function()
local settings = " "
for k,v in next, {__luametalatex__preserved_tex_variables = tex_variables,
__luametalatex__preserved_real_pdf_variables = real_pdf_variables,} do
local entries = {}
for kk,vv in next, v do
-- entries[#entries+1] = string.format("[%q=%i],", kk, vv) -- If we ever get more compicated names here
entries[#entries+1] = string.format("%s=%i,", kk, vv)
end
settings = string.format("%s%s={%s}", settings, k, table.concat(entries))
end
return settings
end
end