summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/node-syn.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-05-25 13:21:58 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-05-25 13:21:58 +0200
commit82aed3e7e8af29f359ebef4f93684d20e98107e6 (patch)
tree2b92c44d14566481aad5635f479b1b106d4e2347 /tex/context/base/mkiv/node-syn.lua
parentaceba29d651766f5621b9812d4c40e28029bc4ea (diff)
downloadcontext-82aed3e7e8af29f359ebef4f93684d20e98107e6.tar.gz
2017-05-25 12:56:00
Diffstat (limited to 'tex/context/base/mkiv/node-syn.lua')
-rw-r--r--tex/context/base/mkiv/node-syn.lua281
1 files changed, 205 insertions, 76 deletions
diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua
index 1b8e07382..a196f0b95 100644
--- a/tex/context/base/mkiv/node-syn.lua
+++ b/tex/context/base/mkiv/node-syn.lua
@@ -18,11 +18,13 @@ if not modules then modules = { } end modules ['node-syn'] = {
--
-- Possible optimizations: pack whole lines.
+-- InverseSearchCmdLine = mtxrun.exe --script synctex --edit --name="%f" --line="%l" $
+
local type, rawset = type, rawset
local concat = table.concat
local formatters = string.formatters
-local trace = false trackers.register("system.syntex.visualize", function(v) trace = v end)
+local trace = false trackers.register("system.synctex.visualize", function(v) trace = v end)
local nuts = nodes.nuts
local tonut = nuts.tonut
@@ -65,7 +67,12 @@ local a_fontkern = attributes.private("fontkern")
local get_synctex_fields = nuts.get_synctex_fields
local set_synctex_fields = nuts.set_synctex_fields
-local set_syntex_tag = nodes.set_synctex_tag
+local set_synctex_line = tex.set_synctex_line
+local set_synctex_tag = tex.set_synctex_tag
+local force_synctex_tag = tex.force_synctex_tag
+local force_synctex_line = tex.force_synctex_line
+----- get_synctex_tag = tex.get_synctex_tag
+----- get_synctex_line = tex.get_synctex_line
local getcount = tex.getcount
local setcount = tex.setcount
@@ -75,6 +82,9 @@ local getpos = function()
return getpos()
end
+
+local eol = "\010"
+
local f_glue = formatters["g%i,%i:%i,%i"]
local f_glyph = formatters["x%i,%i:%i,%i"]
local f_kern = formatters["k%i,%i:%i,%i:%i"]
@@ -88,6 +98,10 @@ local f_vvoid = formatters["v%i,%i:%i,%i:%i,%i,%i"]
local characters = fonts.hashes.characters
+local foundintree = resolvers.foundintree
+local suffixonly = file.suffix
+local nameonly = file.nameonly
+
local synctex = { }
luatex.synctex = synctex
@@ -95,25 +109,56 @@ luatex.synctex = synctex
local noftags = 0
local stnums = { }
-local sttags = table.setmetatableindex(function(t,name)
- noftags = noftags + 1
- t[name] = noftags
- stnums[noftags] = name
- return noftags
+local nofblocked = 0
+local blockedfilenames = { }
+local blockedsuffixes = {
+ mkii = true,
+ mkiv = true,
+ mkvi = true,
+ mkix = true,
+ mkxi = true,
+ -- lfg = true,
+}
+
+
+local sttags = table.setmetatableindex(function(t,name)
+ if blockedsuffixes[suffixonly(name)] then
+ -- Just so that I don't get the ones on my development tree.
+ nofblocked = nofblocked + 1
+ return 0
+ elseif blockedfilenames[nameonly(name)] then
+ -- So we can block specific files.
+ nofblocked = nofblocked + 1
+ return 0
+ elseif foundintree(name) then
+ -- One shouldn't edit styles etc this way.
+ nofblocked = nofblocked + 1
+ return 0
+ else
+ noftags = noftags + 1
+ t[name] = noftags
+ stnums[noftags] = name
+ return noftags
+ end
end)
-function synctex.setfilename(name)
- if set_syntex_tag and name then
- set_syntex_tag(sttags[name])
+function synctex.blockfilename(name)
+ blockedfilenames[nameonly(name)] = name
+end
+
+function synctex.setfilename(name,line)
+ if force_synctex_tag and name then
+ force_synctex_tag(sttags[name])
+ if line then
+ force_synctex_line(line)
+ end
end
end
function synctex.resetfilename()
- if set_syntex_tag then
- local name = luatex.currentfile()
- if name then
- set_syntex_tag(name)
- end
+ if force_synctex_tag then
+ force_synctex_tag(0)
+ force_synctex_line(0)
end
end
@@ -128,10 +173,14 @@ local last = 0
local filesdone = 0
local enabled = false
local compact = true
+-- local compact = false
+local fulltrace = false
+-- local fulltrace = true
+local logfile = false
local function writeanchor()
local size = f:seek("end")
- f:write("!" .. (size-last) .. "\n")
+ f:write("!" .. (size-last) ..eol)
last = size
end
@@ -139,34 +188,35 @@ local function writefiles()
local total = #stnums
if filesdone < total then
for i=filesdone+1,total do
- f:write("Input:"..i..":"..stnums[i].."\n")
+ f:write("Input:"..i..":"..stnums[i]..eol)
end
filesdone = total
end
end
local function flushpreamble()
- local jobname = tex.jobname
- stnums[0] = jobname
- f = io.open(file.replacesuffix(jobname,"syncctx"),"w")
- f:write("SyncTeX Version:1\n")
- f:write("Input:0:"..jobname.."\n")
+ logfile = file.replacesuffix(tex.jobname,"syncctx")
+ f = io.open(logfile,"wb")
+ f:write("SyncTeX Version:1"..eol)
writefiles()
- f:write("Output:pdf\n")
- f:write("Magnification:1000\n")
- f:write("Unit:1\n")
- f:write("X Offset:0\n")
- f:write("Y Offset:0\n")
- f:write("Content:\n")
+ f:write("Output:pdf"..eol)
+ f:write("Magnification:1000"..eol)
+ f:write("Unit:1"..eol)
+ f:write("X Offset:0"..eol)
+ f:write("Y Offset:0"..eol)
+ f:write("Content:"..eol)
flushpreamble = writefiles
end
local function flushpostamble()
+ if not f then
+ return
+ end
writeanchor()
- f:write("Postamble:\n")
- f:write("Count:"..nofobjects.."\n")
+ f:write("Postamble:"..eol)
+ f:write("Count:"..nofobjects..eol)
writeanchor()
- f:write("Post scriptum:\n")
+ f:write("Post scriptum:"..eol)
f:close()
enabled = false
end
@@ -261,7 +311,14 @@ end
-- end))
-- end
-local function collect(head,t,l)
+-- todo: why not only lines
+-- todo: larger ranges
+
+-- color is already handled so no colors
+
+-- we can have ranges .. more efficient but a bit more complex to analyze ... some day
+
+local function collect(head,t,l,dp,ht)
local current = head
while current do
local id = getid(current)
@@ -270,9 +327,20 @@ local function collect(head,t,l)
local last = current
while true do
id = getid(current)
+ -- traditionally glyphs have no synctex code which works sort of ok
+ -- but not when we don't leave hmode cq. have no par
+ --
if id == glyph_code or id == disc_code then
+ local tc, lc = get_synctex_fields(current)
+ if tc and tc > 0 then
+ t, l = tc, lc
+ end
last = current
elseif id == kern_code and (getsubtype(current) == fontkern_code or getattr(current,a_fontkern)) then
+ local tc, lc = get_synctex_fields(current)
+ if tc and tc > 0 then
+ t, l = tc, lc
+ end
last = current
else
if id == glue_code then
@@ -285,16 +353,13 @@ local function collect(head,t,l)
end
local w, h, d = getdimensions(first,getnext(last))
-- local w, h, d = getrangedimensions(head,first,getnext(last))
+ if dp and d < dp then d = dp end
+ if ht and h < ht then h = ht end
+ if h < 655360 then h = 655360 end
+ if d < 327680 then d = 327680 end
if trace then
- -- color is already handled so no colors
- head = insert_before(head,first,new_hlist(new_rule(w,32768,32768)))
+ head = insert_before(head,first,new_hlist(new_rule(w,fulltrace and h or 32768,fulltrace and d or 32768)))
end
-if h < 655360 then
- h = 655360
-end
-if d < 327680 then
- d = 327680
-end
head = x_hlist(head,first,t,l,w,h,d)
break
end
@@ -302,16 +367,13 @@ end
if not current then
local w, h, d = getdimensions(first,getnext(last))
-- local w, h, d = getrangedimensions(head,first,getnext(last))
+ if dp and d < dp then d = dp end
+ if ht and h < ht then h = ht end
+ if h < 655360 then h = 655360 end
+ if d < 327680 then d = 327680 end
if trace then
- -- color is already handled so no colors
- head = insert_before(head,first,new_hlist(new_rule(w,32768,32768)))
+ head = insert_before(head,first,new_hlist(new_rule(w,fulltrace and h or 32768,fulltrace and d or 32768)))
end
-if h < 655360 then
- h = 655360
-end
-if d < 327680 then
- d = 327680
-end
head = x_hlist(head,first,t,l,w,h,d)
return head
end
@@ -341,15 +403,15 @@ end
end
elseif list then
-- head = b_hlist(head,current,t,l,w,h,d)
- head = b_hlist(head,current,0,0,w,h,d)
- local l = collect(list,t,l)
+ head = b_hlist(head,current,0,0,w,h,d) -- todo: only d h when line
+ local l = collect(list,t,l,d,h)
if l ~= list then
setlist(current,l)
end
head, current = e_hlist(head,current)
else
-- head = x_hlist(head,current,t,l,w,h,d)
- head = x_hlist(head,current,0,0,w,h,d)
+ head = x_hlist(head,current,0,0,w,h,d) -- todo: only d h when line
end
end
elseif id == vlist_code then
@@ -436,37 +498,71 @@ function synctex.flush()
nofsheets = nofsheets + 1 -- could be realpageno
flushpreamble()
writeanchor()
- f:write("{"..nofsheets.."\n")
+ f:write("{"..nofsheets..eol)
if compact then
- f:write(f_vlist(0,0,0,0,tex.pagewidth,tex.pageheight,0))
- f:write("\n")
+ -- f:write(f_vlist(0,0,0,0,tex.pagewidth,tex.pageheight,0))
+ f:write(f_hlist(0,0,0,0,0,0,0))
+ f:write(eol)
+ f:write(f_vlist(0,0,0,0,0,0,0))
+ f:write(eol)
end
- f:write(concat(result,"\n"))
+ f:write(concat(result,eol))
if compact then
- f:write("\n")
+ f:write(eol)
f:write(s_vlist)
+ f:write(eol)
+ f:write(s_hlist)
end
- f:write("\n")
+ f:write(eol)
writeanchor()
- f:write("}"..nofsheets.."\n")
+ f:write("}"..nofsheets..eol)
nofobjects = nofobjects + 2
result, r = { }, 0
end
end
-function synctex.enable()
- if not enabled and node.set_synctex_mode then
- enabled = true
- node.set_synctex_mode(1)
- tex.normalsynctex = 0
- nodes.tasks.appendaction("shipouts", "after", "nodes.synctex.collect")
+local details = 1
+local state = 0
+
+directives.register("system.synctex.details",function(v)
+ details = tonumber(v) or 1
+end)
+
+local set_synctex_mode = tex.set_synctex_mode
+
+if set_synctex_mode then
+
+ function synctex.enable()
+ if not enabled then
+ enabled = true
+ state = details or 1
+ set_synctex_mode(state)
+ tex.normalsynctex = 0
+ directives.enable("system.synctex.xml")
+ nodes.tasks.appendaction("shipouts", "after", "nodes.synctex.collect")
+ elseif state > 0 then
+ set_synctex_mode(state)
+ end
end
-end
-function synctex.finish()
- if enabled then
- flushpostamble()
+ function synctex.disable()
+ if enabled then
+ set_synctex_mode(0)
+ end
end
+
+ function synctex.finish()
+ if enabled then
+ flushpostamble()
+ end
+ end
+
+else
+
+ function synctex.enable () end
+ function synctex.disable() end
+ function synctex.finish () end
+
end
-- not the best place
@@ -478,27 +574,60 @@ nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect")
-- moved here
local report_system = logs.reporter("system")
-local synctex = false
+local synctex_used = false
-directives.register("system.synctex", function(v)
+local function setsynctex(v)
if v == "context" then
- luatex.synctex.enable()
+ synctex.enable()
setcount("normalsynctex",0)
- synctex = true
+ synctex_used = true
else
v = tonumber(v) or (toboolean(v,true) and 1) or (v == "zipped" and 1) or (v == "unzipped" and -1) or 0
setcount("normalsynctex",v)
- synctex = v ~= 0
+ synctex_used = v ~= 0
end
- if synctex then
+ if synctex_used then
report_system("synctex functionality is enabled (%s), expect runtime overhead!",tostring(v))
else
report_system("synctex functionality is disabled!")
end
+end
+
+directives.register("system.synctex", setsynctex) -- 0|1|false|true|zipped|unzipped|context
+
+directives.register("system.synctex.context", function(v)
+ setsynctex(v and "context" or false)
end)
statistics.register("synctex tracing",function()
- if synctex or getcount("normalsynctex") ~= 0 then
- return "synctex has been enabled (extra log file generated)"
+ if synctex_used or getcount("normalsynctex") ~= 0 then
+ return string.format("%i referenced files, %i files ignored, logfile: %s",noftags,nofblocked,logfile)
end
end)
+
+interfaces.implement {
+ name = "synctexblockfilename",
+ arguments = "string",
+ actions = synctex.blockfilename,
+}
+
+interfaces.implement {
+ name = "synctexsetfilename",
+ arguments = "string",
+ actions = synctex.setfilename,
+}
+
+interfaces.implement {
+ name = "synctexresetfilename",
+ actions = synctex.resetfilename,
+}
+
+interfaces.implement {
+ name = "synctexenable",
+ actions = synctex.enable,
+}
+
+interfaces.implement {
+ name = "synctexdisable",
+ actions = synctex.disable,
+}