From 94397b74482b88818f737145af99c883802210d7 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Tue, 8 Feb 2011 17:08:00 +0100 Subject: beta 2011.02.08 17:08 --- scripts/context/lua/mtx-context.lua | 168 ++++++------ scripts/context/lua/mtxrun.lua | 122 ++++++--- scripts/context/stubs/mswin/mtxrun.lua | 122 ++++++--- scripts/context/stubs/unix/mtxrun | 122 ++++++--- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/core-job.lua | 12 +- tex/context/base/font-afm.lua | 82 +++++- tex/context/base/font-def.lua | 174 ++---------- tex/context/base/font-dum.lua | 4 +- tex/context/base/font-gds.lua | 2 +- tex/context/base/font-ini.lua | 4 + tex/context/base/font-ini.mkiv | 1 + tex/context/base/font-lua.lua | 45 ++++ tex/context/base/font-otf.lua | 63 ++++- tex/context/base/font-tfm.lua | 50 +++- tex/context/base/luat-dum.lua | 9 +- tex/context/base/luat-fmt.lua | 2 +- tex/context/base/mult-ini.lua | 2 +- tex/context/base/status-files.pdf | Bin 23255 -> 23266 bytes tex/context/base/trac-log.lua | 95 +++++-- tex/context/base/trac-set.lua | 26 +- tex/generic/context/luatex-fonts-demo-vf-1.lua | 36 +++ tex/generic/context/luatex-fonts-merged.lua | 356 +++++++++++++------------ tex/generic/context/luatex-fonts.lua | 3 + tex/generic/context/luatex-test.tex | 4 + 28 files changed, 931 insertions(+), 581 deletions(-) create mode 100644 tex/context/base/font-lua.lua create mode 100644 tex/generic/context/luatex-fonts-demo-vf-1.lua diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index b8ca6a11e..98935adce 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -6,6 +6,10 @@ if not modules then modules = { } end modules ['mtx-context'] = { license = "see context related readme files" } +local format, gmatch, match, gsub, find = string.format, string.gmatch, string.match, string.gsub, string.find +local quote = string.quote +local concat = table.concat + local basicinfo = [[ --run process (one or more) files (default action) --make create context formats @@ -210,11 +214,11 @@ do f = io.open(ctlname,'w') if f then f:write("\n\n") - f:write(string.format("\n",yn(ctxdata.runlocal))) + f:write(format("\n",yn(ctxdata.runlocal))) local sorted = table.sortedkeys(prepfiles) for i=1,#sorted do local name = sorted[i] - f:write(string.format("\t%s\n",yn(prepfiles[name]),name)) + f:write(format("\t%s\n",yn(prepfiles[name]),name)) end f:write("\n") f:close() @@ -470,14 +474,6 @@ function scripts.context.multipass.changed(oldhash, newhash) return false end -scripts.context.backends = { - pdftex = 'pdftex', - luatex = 'pdftex', - pdf = 'pdftex', - dvi = 'dvipdfmx', - dvips = 'dvips' -} - function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,currentrun,finalrun) -- take jobname from ctx jobname = file.removesuffix(jobname) @@ -486,39 +482,39 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,curr local function someflag(flag) return (ctxdata and ctxdata.flags[flag]) or environment.argument(flag) end - local function setvalue(flag,format,hash,default) + local function setvalue(flag,template,hash,default) local a = someflag(flag) or default if a and a ~= "" then if hash then if hash[a] then - f:write(format:format(a),"\n") + f:write(format(template,a),"\n") end else - f:write(format:format(a),"\n") + f:write(format(template,a),"\n") end end end - local function setvalues(flag,format,plural) + local function setvalues(flag,template,plural) if type(flag) == "table" then for k, v in next, flag do - f:write(format:format(v),"\n") + f:write(format(template,v),"\n") end else local a = someflag(flag) or (plural and someflag(flag.."s")) if a and a ~= "" then for v in a:gmatch("%s*([^,]+)") do - f:write(format:format(v),"\n") + f:write(format(template,v),"\n") end end end end - local function setfixed(flag,format,...) + local function setfixed(flag,template,...) if someflag(flag) then - f:write(format:format(...),"\n") + f:write(format(template,...),"\n") end end - local function setalways(format,...) - f:write(format:format(...),"\n") + local function setalways(template,...) + f:write(format(template,...),"\n") end -- -- This might change ... we can just pass the relevant flags directly. @@ -528,17 +524,9 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,curr setalways("\\unprotect") -- setalways("%% feedback and basic job control") - if type(environment.argument("trackers")) == "string" then - setvalue("trackers" , "\\enabletrackers[%s]") - end - if type(environment.argument("directives")) == "string" then - setvalue("directives", "\\enabledirectives[%s]") - end - if type(environment.argument("silent")) == "string" then - setvalue("silent", "\\enabledirectives[logs.blocked={%s}]") - elseif environment.argument("silent") then - setvalue("silent", "\\enabledirectives[logs.blocked=*]") -- maybe \silentmode - end + -- + -- Option file, we can pass more on the commandline some day soon. + -- setfixed ("timing" , "\\usemodule[timing]") setfixed ("batchmode" , "\\batchmode") setfixed ("batch" , "\\batchmode") @@ -558,11 +546,9 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,curr -- setalways("%% process info") -- - -- setvalue ("inputfile" , "\\setupsystem[inputfile=%s]") setalways( "\\setupsystem[inputfile=%s]",environment.argument("input") or environment.files[1] or "\\jobname") setvalue ("result" , "\\setupsystem[file=%s]") setalways( "\\setupsystem[\\c!n=%s,\\c!m=%s]", kindofrun or 0, currentrun or 0) - -- setalways( "\\setupsystem[\\c!type=%s]",os.type) -- windows or unix setvalues("path" , "\\usepath[%s]") setvalue ("setuppath" , "\\setupsystem[\\c!directory={%s}]") setvalue ("randomseed" , "\\setupsystem[\\c!random=%s]") @@ -577,7 +563,6 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,curr setalways("%% options (not that important)") -- setalways("\\startsetups *runtime:options") - setvalue ('output' , "\\setupoutput[%s]", scripts.context.backends, 'pdf') setfixed ("color" , "\\setupcolors[\\c!state=\\v!start]") setvalue ("separation" , "\\setupcolors[\\c!split=%s]") setfixed ("noarrange" , "\\setuparranging[\\v!disable]") @@ -606,7 +591,6 @@ function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,curr end function scripts.context.multipass.copyluafile(jobname) --- io.savedata(jobname..".tuc",io.loaddata(jobname..".tua") or "") local tuaname, tucname = jobname..".tua", jobname..".tuc" if lfs.isfile(tuaname) then os.remove(tucname) @@ -614,28 +598,6 @@ function scripts.context.multipass.copyluafile(jobname) end end --- obsolete: --- --- function scripts.context.multipass.copytuifile(jobname) --- local tuiname, tuoname = jobname .. ".tui", jobname .. ".tuo" --- if lfs.isfile(tuiname) then --- local f, g = io.open(tuiname), io.open(tuoname,'w') --- if f and g then --- g:write("% traditional utility file, only commands written by mtxrun/context\n%\n") --- for line in f:lines() do --- if line:find("^c ") then --- g:write((line:gsub("^c ","")),"%\n") --- end --- end --- g:write("\\endinput\n") --- f:close() --- g:close() --- end --- else --- -- os.remove(tuoname) --- end --- end - scripts.context.cldsuffixes = table.tohash { "cld", } @@ -702,12 +664,12 @@ local function analyze(filename) -- only files on current path return nil end -local function makestub(format,filename,prepname) +local function makestub(template,filename,prepname) local stubname = file.replacesuffix(file.basename(filename),'run') local f = io.open(stubname,'w') if f then f:write("\\starttext\n") - f:write(string.format(format,prepname or filename),"\n") + f:write(format(template,prepname or filename),"\n") f:write("\\stoptext\n") f:close() filename = stubname @@ -716,10 +678,10 @@ local function makestub(format,filename,prepname) end --~ function scripts.context.openpdf(name) ---~ os.spawn(string.format('pdfopen --file "%s" 2>&1', file.replacesuffix(name,"pdf"))) +--~ os.spawn(format('pdfopen --file "%s" 2>&1', file.replacesuffix(name,"pdf"))) --~ end --~ function scripts.context.closepdf(name) ---~ os.spawn(string.format('pdfclose --file "%s" 2>&1', file.replacesuffix(name,"pdf"))) +--~ os.spawn(format('pdfclose --file "%s" 2>&1', file.replacesuffix(name,"pdf"))) --~ end local pdfview -- delayed loading @@ -782,9 +744,9 @@ function scripts.context.run(ctxdata,filename) if texexec ~= "" then os.setenv("RUBYOPT","") local options = environment.reconstructcommandline(environment.arguments_after) - options = string.gsub(options,"--purge","") - options = string.gsub(options,"--purgeall","") - local command = string.format("ruby %s %s",texexec,options) + options = gsub(options,"--purge","") + options = gsub(options,"--purgeall","") + local command = format("ruby %s %s",texexec,options) if environment.argument("purge") then os.execute(command) scripts.context.purge_job(filename,false,true) @@ -884,10 +846,37 @@ function scripts.context.run(ctxdata,filename) report("warning: syntex is enabled") -- can add upto 5% runtime flags[#flags+1] = "--synctex=1" end - flags[#flags+1] = "--fmt=" .. string.quote(formatfile) - flags[#flags+1] = "--lua=" .. string.quote(scriptfile) + flags[#flags+1] = "--fmt=" .. quote(formatfile) + flags[#flags+1] = "--lua=" .. quote(scriptfile) flags[#flags+1] = "--backend=pdf" - local command = string.format("luatex %s %s", table.concat(flags," "), string.quote(filename)) + -- + -- We pass these directly. + -- + local silent = environment.argument("silent") + local directives = environment.argument("directives") + local trackers = environment.argument("trackers") + if silent == true then + silent = "*" + end + if type(silent) == "string" then + if type(directives) == "string" then + directives = format("%s,logs.blocked={%s}",directives,silent) + else + directives = format("logs.blocked={%s}",silent) + end + end + -- + if type(directives) == "string" then + flags[#flags+1] = format('--directives="%s"',directives) + end + if type(trackers) == "string" then + flags[#flags+1] = format('--trackers="%s"',trackers) + end + if type(backend) == "string" then + flags[#flags+1] = format('--backend="%s"',backend) + end + -- + local command = format("luatex %s %s", concat(flags," "), quote(filename)) local oldhash, newhash = scripts.context.multipass.hashfiles(jobname), { } local once = environment.argument("once") local maxnofruns = (once and 1) or scripts.context.multipass.nofruns @@ -897,6 +886,8 @@ function scripts.context.run(ctxdata,filename) local kindofrun = (once and 3) or (i==1 and 1) or (i==maxnofruns and 4) or 2 scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,false) -- kindofrun, currentrun, final report("run %s: %s",i,command) +--~ print("\n") -- cleaner, else continuation on same line + print("") -- cleaner, else continuation on same line local returncode, errorstring = os.spawn(command) --~ if returncode == 3 then --~ scripts.context.make(formatname) @@ -1030,8 +1021,8 @@ function scripts.context.pipe() end local flags = { "--interaction=scrollmode", - "--fmt=" .. string.quote(formatfile), - "--lua=" .. string.quote(scriptfile), + "--fmt=" .. quote(formatfile), + "--lua=" .. quote(scriptfile), "--backend=pdf", } local filename = environment.argument("dummyfile") or "" @@ -1044,7 +1035,7 @@ function scripts.context.pipe() scripts.context.multipass.makeoptionfile(filename,{ flags = flags },3,1,false) -- kindofrun, currentrun, final report("entering scrollmode using '%s' with optionfile, end job with \\end",filename) end - local command = string.format("luatex %s %s", table.concat(flags," "), string.quote(filename)) + local command = format("luatex %s %s", concat(flags," "), quote(filename)) os.spawn(command) if environment.argument("purge") then scripts.context.purge_job(filename) @@ -1065,7 +1056,7 @@ local make_mkiv_format = environment.make_format local function make_mkii_format(name,engine) if environment.argument(engine) then - local command = string.format("mtxrun texexec.rb --make --%s %s",name,engine) + local command = format("mtxrun texexec.rb --make --%s %s",name,engine) report("running command: %s",command) os.spawn(command) end @@ -1109,7 +1100,7 @@ function scripts.context.autoctx() if f then local chunk = f:read(512) or "" f:close() - local ctxname = string.match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>") + local ctxname = match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>") if ctxname then ctxdata = ctxrunner.new() ctxdata.jobname = firstfile @@ -1141,7 +1132,7 @@ function scripts.context.metapost() commands.writestatus = report -- no longer needed end local formatname = environment.argument("format") or "metafun" - if formatname == "" or type(format) == "boolean" then + if formatname == "" or type(formatname) == "boolean" then formatname = "metafun" end if environment.argument("pdf") then @@ -1149,7 +1140,7 @@ function scripts.context.metapost() local resultname = environment.argument("result") or basename local jobname = "mtx-context-metapost" local tempname = file.addsuffix(jobname,"tex") - io.savedata(tempname,string.format(template,"metafun",filename)) + io.savedata(tempname,format(template,"metafun",filename)) environment.files[1] = tempname environment.setargument("result",resultname) environment.setargument("once",true) @@ -1244,7 +1235,7 @@ function scripts.context.purge_job(jobname,all,mkiitoo) end end if #deleted > 0 then - report("purged files: %s", table.concat(deleted,", ")) + report("purged files: %s", concat(deleted,", ")) end end end @@ -1267,14 +1258,14 @@ function scripts.context.purge(all,pattern,mkiitoo) deleted[#deleted+1] = purge_file(name) elseif mkiitoo then for i=1,#special_runfiles do - if string.find(name,special_runfiles[i]) then + if find(name,special_runfiles[i]) then deleted[#deleted+1] = purge_file(name) end end end end if #deleted > 0 then - report("purged files: %s", table.concat(deleted,", ")) + report("purged files: %s", concat(deleted,", ")) end end @@ -1326,16 +1317,16 @@ function scripts.context.extras(pattern) if found == "" then report("unknown extra: %s", extra) else - pattern = file.join(dir.expandname(file.dirname(found)),string.format("mtx-context-%s.tex",pattern or "*")) + pattern = file.join(dir.expandname(file.dirname(found)),format("mtx-context-%s.tex",pattern or "*")) local list = dir.glob(pattern) for i=1,#list do local v = list[i] local data = io.loaddata(v) or "" - data = string.match(data,"begin help(.-)end help") + data = match(data,"begin help(.-)end help") if data then report() - report(string.format("extra: %s (%s)",string.gsub(v,"^.*mtx%-context%-(.-)%.tex$","%1"),v)) - for s in string.gmatch(data,"%% *(.-)[\n\r]") do + report(format("extra: %s (%s)",gsub(v,"^.*mtx%-context%-(.-)%.tex$","%1"),v)) + for s in gmatch(data,"%% *(.-)[\n\r]") do report(s) end report() @@ -1351,7 +1342,7 @@ function scripts.context.extra() scripts.context.extras(extra) else local fullextra = extra - if not string.find(fullextra,"mtx%-context%-") then + if not find(fullextra,"mtx%-context%-") then fullextra = "mtx-context-" .. extra end local foundextra = resolvers.findfile(fullextra) @@ -1431,7 +1422,7 @@ function scripts.context.update() end local function is_okay(basetree) for _, tree in next, validtrees do - local pattern = string.gsub(tree,"%-","%%-") + local pattern = gsub(tree,"%-","%%-") if basetree:find(pattern) then return tree end @@ -1536,6 +1527,17 @@ function scripts.context.update() end end +do + + local silent = environment.argument("silent") + if type(silent) == "string" then + directives.enable(format("logs.blocked={%s}",silent)) + elseif silent then + directives.enable("logs.blocked") + end + +end + if environment.argument("once") then scripts.context.multipass.nofruns = 1 elseif environment.argument("runs") then diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index afc472d1c..08200f9aa 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -4660,7 +4660,7 @@ local trace_initialize = false -- only for testing during development function setters.initialize(filename,name,values) -- filename only for diagnostics local setter = data[name] if setter then - local data = data.data + local data = setter.data if data then for key, value in next, values do -- key = gsub(key,"_",".") @@ -4849,7 +4849,7 @@ local function report(setter,...) if report then report(setter.name,...) else -- fallback, as this module is loaded before the logger - write_nl(format("%-16s: %s\n",setter.name,format(...))) + write_nl(format("%-15s : %s\n",setter.name,format(...))) end end @@ -4884,22 +4884,30 @@ local trace_directives = false local trace_directives = false trackers.regist local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) function directives.enable(...) - d_report("enabling: %s",concat({...}," ")) + if trace_directives then + d_report("enabling: %s",concat({...}," ")) + end d_enable(...) end function directives.disable(...) - d_report("disabling: %s",concat({...}," ")) + if trace_directives then + d_report("disabling: %s",concat({...}," ")) + end d_disable(...) end function experiments.enable(...) - e_report("enabling: %s",concat({...}," ")) + if trace_experiments then + e_report("enabling: %s",concat({...}," ")) + end e_enable(...) end function experiments.disable(...) - e_report("disabling: %s",concat({...}," ")) + if trace_experiments then + e_report("disabling: %s",concat({...}," ")) + end e_disable(...) end @@ -4919,10 +4927,12 @@ local flags = environment and environment.engineflags if flags then if trackers and flags.trackers then - t_enable(flags.trackers) + setters.initialize("flags","trackers", utilities.parsers.settings_to_hash(flags.trackers)) + -- t_enable(flags.trackers) end if directives and flags.directives then - d_enable(flags.directives) + setters.initialize("flags","directives", utilities.parsers.settings_to_hash(flags.directives)) + -- d_enable(flags.directives) end end @@ -4967,7 +4977,7 @@ if not modules then modules = { } end modules ['trac-log'] = { local write_nl, write = texio and texio.write_nl or print, texio and texio.write or io.write local format, gmatch, find = string.format, string.gmatch, string.find -local concat = table.concat +local concat, insert, remove = table.concat, table.insert, table.remove local escapedpattern = string.escapedpattern local texcount = tex and tex.count local next, type = next, type @@ -5010,31 +5020,71 @@ setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end } -- local separator = (tex and (tex.jobname or tex.formatname)) and ">" or "|" -local report, subreport +local report, subreport, status, settarget if tex and tex.jobname or tex.formatname then + local target = "term and log" + report = function(a,b,c,...) if c then - write_nl(format("%-15s > %s\n",a,format(b,c,...))) + write_nl(target,format("%-15s > %s\n",a,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s\n",a,b)) + write_nl(target,format("%-15s > %s\n",a,b)) elseif a then - write_nl(format("%-15s >\n", a)) + write_nl(target,format("%-15s >\n", a)) else - write_nl("\n") + write_nl(target,"\n") end end subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s > %s > %s\n",a,sub,format(b,c,...))) + write_nl(target,format("%-15s > %s > %s\n",a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s > %s\n",a,sub,b)) + write_nl(target,format("%-15s > %s > %s\n",a,sub,b)) elseif a then - write_nl(format("%-15s > %s >\n", a,sub)) + write_nl(target,format("%-15s > %s >\n", a,sub)) else - write_nl("\n") + write_nl(target,"\n") + end + end + + status = function(a,b,c,...) + if c then + write_nl(target,format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(target,format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(target,format("%-15s :\n", a)) + else + write_nl(target,"\n") + end + end + + local targets = { + logfile = "log", + log = "log", + file = "log", + console = "term", + terminal = "term", + both = "term and log", + } + + settarget = function(whereto) + target = targets[whereto or "both"] or targets.both + end + + local stack = { } + + pushtarget = function(newtarget) + insert(stack,target) + settarget(newtarget) + end + + poptarget = function() + if #stack > 0 then + settarget(remove(stack)) end end @@ -5064,22 +5114,30 @@ else end end -end - -function logs.status(a,b,c,...) -- at the tex end - if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) - elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s - elseif a then - write_nl(format("%-15s :\n", a)) - else - write_nl("\n") + status = function(a,b,c,...) -- not to be used in lua anyway + if c then + write_nl(format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(format("%-15s :\n", a)) + else + write_nl("\n") + end end + + settarget = ignore + pushtarget = ignore + poptarget = ignore + end -logs.report = report -logs.subreport = subreport +logs.report = report +logs.subreport = subreport +logs.status = status +logs.settarget = settarget +logs.pushtarget = pushtarget +logs.poptarget = poptarget -- installer @@ -13544,7 +13602,7 @@ local report_format = logs.new("resolvers","formats") local quoted = string.quoted -local function primaryflags() +local function primaryflags() -- not yet ok local trackers = environment.argument("trackers") local directives = environment.argument("directives") local flags = "" diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index afc472d1c..08200f9aa 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -4660,7 +4660,7 @@ local trace_initialize = false -- only for testing during development function setters.initialize(filename,name,values) -- filename only for diagnostics local setter = data[name] if setter then - local data = data.data + local data = setter.data if data then for key, value in next, values do -- key = gsub(key,"_",".") @@ -4849,7 +4849,7 @@ local function report(setter,...) if report then report(setter.name,...) else -- fallback, as this module is loaded before the logger - write_nl(format("%-16s: %s\n",setter.name,format(...))) + write_nl(format("%-15s : %s\n",setter.name,format(...))) end end @@ -4884,22 +4884,30 @@ local trace_directives = false local trace_directives = false trackers.regist local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) function directives.enable(...) - d_report("enabling: %s",concat({...}," ")) + if trace_directives then + d_report("enabling: %s",concat({...}," ")) + end d_enable(...) end function directives.disable(...) - d_report("disabling: %s",concat({...}," ")) + if trace_directives then + d_report("disabling: %s",concat({...}," ")) + end d_disable(...) end function experiments.enable(...) - e_report("enabling: %s",concat({...}," ")) + if trace_experiments then + e_report("enabling: %s",concat({...}," ")) + end e_enable(...) end function experiments.disable(...) - e_report("disabling: %s",concat({...}," ")) + if trace_experiments then + e_report("disabling: %s",concat({...}," ")) + end e_disable(...) end @@ -4919,10 +4927,12 @@ local flags = environment and environment.engineflags if flags then if trackers and flags.trackers then - t_enable(flags.trackers) + setters.initialize("flags","trackers", utilities.parsers.settings_to_hash(flags.trackers)) + -- t_enable(flags.trackers) end if directives and flags.directives then - d_enable(flags.directives) + setters.initialize("flags","directives", utilities.parsers.settings_to_hash(flags.directives)) + -- d_enable(flags.directives) end end @@ -4967,7 +4977,7 @@ if not modules then modules = { } end modules ['trac-log'] = { local write_nl, write = texio and texio.write_nl or print, texio and texio.write or io.write local format, gmatch, find = string.format, string.gmatch, string.find -local concat = table.concat +local concat, insert, remove = table.concat, table.insert, table.remove local escapedpattern = string.escapedpattern local texcount = tex and tex.count local next, type = next, type @@ -5010,31 +5020,71 @@ setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end } -- local separator = (tex and (tex.jobname or tex.formatname)) and ">" or "|" -local report, subreport +local report, subreport, status, settarget if tex and tex.jobname or tex.formatname then + local target = "term and log" + report = function(a,b,c,...) if c then - write_nl(format("%-15s > %s\n",a,format(b,c,...))) + write_nl(target,format("%-15s > %s\n",a,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s\n",a,b)) + write_nl(target,format("%-15s > %s\n",a,b)) elseif a then - write_nl(format("%-15s >\n", a)) + write_nl(target,format("%-15s >\n", a)) else - write_nl("\n") + write_nl(target,"\n") end end subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s > %s > %s\n",a,sub,format(b,c,...))) + write_nl(target,format("%-15s > %s > %s\n",a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s > %s\n",a,sub,b)) + write_nl(target,format("%-15s > %s > %s\n",a,sub,b)) elseif a then - write_nl(format("%-15s > %s >\n", a,sub)) + write_nl(target,format("%-15s > %s >\n", a,sub)) else - write_nl("\n") + write_nl(target,"\n") + end + end + + status = function(a,b,c,...) + if c then + write_nl(target,format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(target,format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(target,format("%-15s :\n", a)) + else + write_nl(target,"\n") + end + end + + local targets = { + logfile = "log", + log = "log", + file = "log", + console = "term", + terminal = "term", + both = "term and log", + } + + settarget = function(whereto) + target = targets[whereto or "both"] or targets.both + end + + local stack = { } + + pushtarget = function(newtarget) + insert(stack,target) + settarget(newtarget) + end + + poptarget = function() + if #stack > 0 then + settarget(remove(stack)) end end @@ -5064,22 +5114,30 @@ else end end -end - -function logs.status(a,b,c,...) -- at the tex end - if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) - elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s - elseif a then - write_nl(format("%-15s :\n", a)) - else - write_nl("\n") + status = function(a,b,c,...) -- not to be used in lua anyway + if c then + write_nl(format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(format("%-15s :\n", a)) + else + write_nl("\n") + end end + + settarget = ignore + pushtarget = ignore + poptarget = ignore + end -logs.report = report -logs.subreport = subreport +logs.report = report +logs.subreport = subreport +logs.status = status +logs.settarget = settarget +logs.pushtarget = pushtarget +logs.poptarget = poptarget -- installer @@ -13544,7 +13602,7 @@ local report_format = logs.new("resolvers","formats") local quoted = string.quoted -local function primaryflags() +local function primaryflags() -- not yet ok local trackers = environment.argument("trackers") local directives = environment.argument("directives") local flags = "" diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index afc472d1c..08200f9aa 100755 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -4660,7 +4660,7 @@ local trace_initialize = false -- only for testing during development function setters.initialize(filename,name,values) -- filename only for diagnostics local setter = data[name] if setter then - local data = data.data + local data = setter.data if data then for key, value in next, values do -- key = gsub(key,"_",".") @@ -4849,7 +4849,7 @@ local function report(setter,...) if report then report(setter.name,...) else -- fallback, as this module is loaded before the logger - write_nl(format("%-16s: %s\n",setter.name,format(...))) + write_nl(format("%-15s : %s\n",setter.name,format(...))) end end @@ -4884,22 +4884,30 @@ local trace_directives = false local trace_directives = false trackers.regist local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) function directives.enable(...) - d_report("enabling: %s",concat({...}," ")) + if trace_directives then + d_report("enabling: %s",concat({...}," ")) + end d_enable(...) end function directives.disable(...) - d_report("disabling: %s",concat({...}," ")) + if trace_directives then + d_report("disabling: %s",concat({...}," ")) + end d_disable(...) end function experiments.enable(...) - e_report("enabling: %s",concat({...}," ")) + if trace_experiments then + e_report("enabling: %s",concat({...}," ")) + end e_enable(...) end function experiments.disable(...) - e_report("disabling: %s",concat({...}," ")) + if trace_experiments then + e_report("disabling: %s",concat({...}," ")) + end e_disable(...) end @@ -4919,10 +4927,12 @@ local flags = environment and environment.engineflags if flags then if trackers and flags.trackers then - t_enable(flags.trackers) + setters.initialize("flags","trackers", utilities.parsers.settings_to_hash(flags.trackers)) + -- t_enable(flags.trackers) end if directives and flags.directives then - d_enable(flags.directives) + setters.initialize("flags","directives", utilities.parsers.settings_to_hash(flags.directives)) + -- d_enable(flags.directives) end end @@ -4967,7 +4977,7 @@ if not modules then modules = { } end modules ['trac-log'] = { local write_nl, write = texio and texio.write_nl or print, texio and texio.write or io.write local format, gmatch, find = string.format, string.gmatch, string.find -local concat = table.concat +local concat, insert, remove = table.concat, table.insert, table.remove local escapedpattern = string.escapedpattern local texcount = tex and tex.count local next, type = next, type @@ -5010,31 +5020,71 @@ setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end } -- local separator = (tex and (tex.jobname or tex.formatname)) and ">" or "|" -local report, subreport +local report, subreport, status, settarget if tex and tex.jobname or tex.formatname then + local target = "term and log" + report = function(a,b,c,...) if c then - write_nl(format("%-15s > %s\n",a,format(b,c,...))) + write_nl(target,format("%-15s > %s\n",a,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s\n",a,b)) + write_nl(target,format("%-15s > %s\n",a,b)) elseif a then - write_nl(format("%-15s >\n", a)) + write_nl(target,format("%-15s >\n", a)) else - write_nl("\n") + write_nl(target,"\n") end end subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s > %s > %s\n",a,sub,format(b,c,...))) + write_nl(target,format("%-15s > %s > %s\n",a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s > %s\n",a,sub,b)) + write_nl(target,format("%-15s > %s > %s\n",a,sub,b)) elseif a then - write_nl(format("%-15s > %s >\n", a,sub)) + write_nl(target,format("%-15s > %s >\n", a,sub)) else - write_nl("\n") + write_nl(target,"\n") + end + end + + status = function(a,b,c,...) + if c then + write_nl(target,format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(target,format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(target,format("%-15s :\n", a)) + else + write_nl(target,"\n") + end + end + + local targets = { + logfile = "log", + log = "log", + file = "log", + console = "term", + terminal = "term", + both = "term and log", + } + + settarget = function(whereto) + target = targets[whereto or "both"] or targets.both + end + + local stack = { } + + pushtarget = function(newtarget) + insert(stack,target) + settarget(newtarget) + end + + poptarget = function() + if #stack > 0 then + settarget(remove(stack)) end end @@ -5064,22 +5114,30 @@ else end end -end - -function logs.status(a,b,c,...) -- at the tex end - if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) - elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s - elseif a then - write_nl(format("%-15s :\n", a)) - else - write_nl("\n") + status = function(a,b,c,...) -- not to be used in lua anyway + if c then + write_nl(format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(format("%-15s :\n", a)) + else + write_nl("\n") + end end + + settarget = ignore + pushtarget = ignore + poptarget = ignore + end -logs.report = report -logs.subreport = subreport +logs.report = report +logs.subreport = subreport +logs.status = status +logs.settarget = settarget +logs.pushtarget = pushtarget +logs.poptarget = poptarget -- installer @@ -13544,7 +13602,7 @@ local report_format = logs.new("resolvers","formats") local quoted = string.quoted -local function primaryflags() +local function primaryflags() -- not yet ok local trackers = environment.argument("trackers") local directives = environment.argument("directives") local flags = "" diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index a136dc695..03427c7fa 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2011.02.08 10:06} +\newcontextversion{2011.02.08 17:08} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index d14bf8c28..a648f186a 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2011.02.08 10:06} +\newcontextversion{2011.02.08 17:08} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 54f284089..2bf65c51f 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2011.02.08 10:06} +\edef\contextversion{2011.02.08 17:08} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index a735801c0..040a93f6b 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2011.02.08 10:06} +\edef\contextversion{2011.02.08 17:08} %D For those who want to use this: diff --git a/tex/context/base/core-job.lua b/tex/context/base/core-job.lua index 07ff5259e..56e71f8ae 100644 --- a/tex/context/base/core-job.lua +++ b/tex/context/base/core-job.lua @@ -130,16 +130,22 @@ function commands.loadexamodes(filename) end end +local report_options = logs.new("system","options") + function commands.logoptionfile(name) -- todo: xml if xml logmode local f = io.open(name) if f then - texio.write_nl("log","%\n%\tbegin of optionfile\n%\n") + logs.pushtarget("logfile") + report_options("begin of optionfile") + report_options() for line in f:lines() do - texio.write("log",format("%%\t%s\n",line)) + report_options(line) end - texio.write("log","%\n%\tend of optionfile\n%\n") + report_options() + report_options("end of optionfile") f:close() + logs.poptarget() end end diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua index 71c4f9fc3..31ed1332a 100644 --- a/tex/context/base/font-afm.lua +++ b/tex/context/base/font-afm.lua @@ -17,9 +17,10 @@ where we handles font encodings. Eventually font encoding goes away.

--ldx]]-- -local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) -local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) -local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) +local trace_features = false trackers.register("afm.features", function(v) trace_features = v end) +local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) +local trace_loading = false trackers.register("afm.loading", function(v) trace_loading = v end) +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) local report_afm = logs.new("fonts","afm loading") @@ -28,6 +29,8 @@ local format, match, gmatch, lower, gsub, strip = string.format, string.match, s local lpegmatch = lpeg.match local abs = math.abs +local findbinfile = resolvers.findbinfile + local fonts = fonts fonts.afm = fonts.afm or { } @@ -42,6 +45,7 @@ afm.addkerns = true -- best leave this set to true afm.cache = containers.define("fonts", "afm", afm.version, true) local definers = fonts.definers +local readers = fonts.tfm.readers local afmfeatures = { aux = { }, @@ -494,9 +498,6 @@ local function adddimensions(data) -- we need to normalize afm to otf i.e. index end end -fonts.formats.afm = "type1" -fonts.formats.pfb = "type1" - local function copytotfm(data) if data then local glyphs = data.glyphs @@ -700,7 +701,7 @@ local function afmtotfm(specification) report_afm("forcing afm format for %s",afmname) end else - local tfmname = resolvers.findbinfile(afmname,"ofm") or "" + local tfmname = findbinfile(afmname,"ofm") or "" if tfmname ~= "" then if trace_loading then report_afm("fallback from afm to tfm for %s",afmname) @@ -764,7 +765,7 @@ need this features.

-- end -- end -function tfm.read_from_afm(specification) +local function read_from_afm(specification) local tfmtable = afmtotfm(specification) if tfmtable then tfmtable.name = specification.name @@ -898,3 +899,68 @@ base_initializers.fkcp = common_initializers.fakecaps register_feature('onum',false) register_feature('smcp',false) register_feature('fkcp',false) + +-- readers + +local check_tfm = readers.check_tfm + +fonts.formats.afm = "type1" +fonts.formats.pfb = "type1" + +local function check_afm(specification,fullname) + local foundname = findbinfile(fullname, 'afm') or "" -- just to be sure + if foundname == "" then + foundname = fonts.names.getfilename(fullname,"afm") + end + if foundname == "" and tfm.autoprefixedafm then + local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.* + if encoding and shortname and fonts.enc.known[encoding] then + shortname = findbinfile(shortname,'afm') or "" -- just to be sure + if shortname ~= "" then + foundname = shortname + if trace_defining then + report_afm("stripping encoding prefix from filename %s",afmname) + end + end + end + end + if foundname ~= "" then + specification.filename, specification.format = foundname, "afm" + return read_from_afm(specification) + end +end + +function readers.afm(specification,method) + local fullname, tfmtable = specification.filename or "", nil + if fullname == "" then + local forced = specification.forced or "" + if forced ~= "" then + tfmtable = check_afm(specification,specification.name .. "." .. forced) + end + if not tfmtable then + method = method or definers.method or "afm or tfm" + if method == "tfm" then + tfmtable = check_tfm(specification,specification.name) + elseif method == "afm" then + tfmtable = check_afm(specification,specification.name) + elseif method == "tfm or afm" then + tfmtable = check_tfm(specification,specification.name) or check_afm(specification,specification.name) + else -- method == "afm or tfm" or method == "" then + tfmtable = check_afm(specification,specification.name) or check_tfm(specification,specification.name) + end + end + else + tfmtable = check_afm(specification,fullname) + end + return tfmtable +end + +function readers.pfb(specification,method) -- only called when forced + local original = specification.specification + if trace_defining then + report_afm("using afm reader for '%s'",original) + end + specification.specification = gsub(original,"%.pfb",".afm") + specification.forced = "afm" + return readers.afm(specification,method) +end diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua index e8e6cfffe..678f7feed 100644 --- a/tex/context/base/font-def.lua +++ b/tex/context/base/font-def.lua @@ -20,7 +20,6 @@ trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*") local report_defining = logs.new("fonts","defining") -local report_afm = logs.new("fonts","afm loading") --[[ldx--

Here we deal with defining fonts. We do so by intercepting the @@ -37,7 +36,7 @@ tfm.readers = tfm.readers or { } tfm.fonts = allocate() local readers = tfm.readers -local sequence = allocate { 'otf', 'ttf', 'afm', 'tfm' } +local sequence = allocate { 'otf', 'ttf', 'afm', 'tfm', 'lua' } readers.sequence = sequence tfm.version = 1.01 @@ -193,10 +192,10 @@ function tfm.hashfeatures(specification) t[tn] = v .. '=' .. tostring(vtf[v]) end end - --~ if specification.mathsize then - --~ tn = tn + 1 - --~ t[tn] = "mathsize=" .. specification.mathsize - --~ end + -- if specification.mathsize then + -- tn = tn + 1 + -- t[tn] = "mathsize=" .. specification.mathsize + -- end if tn > 0 then return concat(t,"+") end @@ -224,21 +223,21 @@ function tfm.hashinstance(specification,force) size = math.round(tfm.scaled(size,fonts.designsizes[hash])) specification.size = size end ---~ local mathsize = specification.mathsize or 0 ---~ if mathsize > 0 then ---~ local textsize = specification.textsize ---~ if fallbacks then ---~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ] @ ' .. fallbacks ---~ else ---~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ]' ---~ end ---~ else + -- local mathsize = specification.mathsize or 0 + -- if mathsize > 0 then + -- local textsize = specification.textsize + -- if fallbacks then + -- return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ] @ ' .. fallbacks + -- else + -- return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ]' + -- end + -- else if fallbacks then return hash .. ' @ ' .. tostring(size) .. ' @ ' .. fallbacks else return hash .. ' @ ' .. tostring(size) end ---~ end + -- end end --[[ldx-- @@ -407,149 +406,6 @@ function tfm.readanddefine(name,size) -- no id return fonts.identifiers[id], id end ---[[ldx-- -

Next follow the readers. This code was written while -evolved. Each one has its own way of dealing with its format.

---ldx]]-- - -local function check_tfm(specification,fullname) - -- ofm directive blocks local path search unless set; btw, in context we - -- don't support ofm files anyway as this format is obsolete - local foundname = findbinfile(fullname, 'tfm') or "" -- just to be sure - if foundname == "" then - foundname = findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context - end - if foundname == "" then - foundname = fonts.names.getfilename(fullname,"tfm") - end - if foundname ~= "" then - specification.filename, specification.format = foundname, "ofm" - return tfm.read_from_tfm(specification) - end -end - -local function check_afm(specification,fullname) - local foundname = findbinfile(fullname, 'afm') or "" -- just to be sure - if foundname == "" then - foundname = fonts.names.getfilename(fullname,"afm") - end - if foundname == "" and tfm.autoprefixedafm then - local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.* - if encoding and shortname and fonts.enc.known[encoding] then - shortname = findbinfile(shortname,'afm') or "" -- just to be sure - if shortname ~= "" then - foundname = shortname - if trace_loading then - report_afm("stripping encoding prefix from filename %s",afmname) - end - end - end - end - if foundname ~= "" then - specification.filename, specification.format = foundname, "afm" - return tfm.read_from_afm(specification) - end -end - -function readers.tfm(specification) - local fullname, tfmtable = specification.filename or "", nil - if fullname == "" then - local forced = specification.forced or "" - if forced ~= "" then - tfmtable = check_tfm(specification,specification.name .. "." .. forced) - end - if not tfmtable then - tfmtable = check_tfm(specification,specification.name) - end - else - tfmtable = check_tfm(specification,fullname) - end - return tfmtable -end - -function readers.afm(specification,method) - local fullname, tfmtable = specification.filename or "", nil - if fullname == "" then - local forced = specification.forced or "" - if forced ~= "" then - tfmtable = check_afm(specification,specification.name .. "." .. forced) - end - if not tfmtable then - method = method or definers.method or "afm or tfm" - if method == "tfm" then - tfmtable = check_tfm(specification,specification.name) - elseif method == "afm" then - tfmtable = check_afm(specification,specification.name) - elseif method == "tfm or afm" then - tfmtable = check_tfm(specification,specification.name) or check_afm(specification,specification.name) - else -- method == "afm or tfm" or method == "" then - tfmtable = check_afm(specification,specification.name) or check_tfm(specification,specification.name) - end - end - else - tfmtable = check_afm(specification,fullname) - end - return tfmtable -end - -function readers.pfb(specification,method) -- only called when forced - local original = specification.specification - if trace_loading then - report_afm("using afm reader for '%s'",original) - end - specification.specification = gsub(original,"%.pfb",".afm") - specification.forced = "afm" - return readers.afm(specification,method) -end - --- maybe some day a set of names - -local function check_otf(forced,specification,suffix,what) - local name = specification.name - if forced then - name = file.addsuffix(name,suffix,true) - end - local fullname, tfmtable = findbinfile(name,suffix) or "", nil -- one shot - -- if false then -- can be enabled again when needed - -- if fullname == "" then - -- local fb = fonts.names.old_to_new[name] - -- if fb then - -- fullname = findbinfile(fb,suffix) or "" - -- end - -- end - -- if fullname == "" then - -- local fb = fonts.names.new_to_old[name] - -- if fb then - -- fullname = findbinfile(fb,suffix) or "" - -- end - -- end - -- end - if fullname == "" then - fullname = fonts.names.getfilename(name,suffix) - end - if fullname ~= "" then - specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then - tfmtable = tfm.read_from_otf(specification) -- we need to do it for all matches / todo - end - return tfmtable -end - -function readers.opentype(specification,suffix,what) - local forced = specification.forced or "" - if forced == "otf" then - return check_otf(true,specification,forced,"opentype") - elseif forced == "ttf" or forced == "ttc" or forced == "dfont" then - return check_otf(true,specification,forced,"truetype") - else - return check_otf(false,specification,suffix,what) - end -end - -function readers.otf (specification) return readers.opentype(specification,"otf","opentype") end -function readers.ttf (specification) return readers.opentype(specification,"ttf","truetype") end -function readers.ttc (specification) return readers.opentype(specification,"ttf","truetype") end -- !! -function readers.dfont(specification) return readers.opentype(specification,"ttf","truetype") end -- !! - --[[ldx--

We need to check for default features. For this we provide a helper function.

diff --git a/tex/context/base/font-dum.lua b/tex/context/base/font-dum.lua index dac820274..1d7612035 100644 --- a/tex/context/base/font-dum.lua +++ b/tex/context/base/font-dum.lua @@ -11,13 +11,13 @@ fonts = fonts or { } -- general fonts.otf.pack = false -- only makes sense in context -fonts.tfm.resolvevirtualtoo = false -- context specific (du eto resolver) +fonts.tfm.resolvevirtualtoo = false -- context specific (due to resolver) fonts.tfm.fontnamemode = "specification" -- somehow latex needs this (changed name!) -- readers fonts.tfm.readers = fonts.tfm.readers or { } -fonts.tfm.readers.sequence = { 'otf', 'ttf', 'tfm' } +fonts.tfm.readers.sequence = { 'otf', 'ttf', 'tfm', 'lua' } fonts.tfm.readers.afm = nil -- define diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua index 29142e45e..21833ace9 100644 --- a/tex/context/base/font-gds.lua +++ b/tex/context/base/font-gds.lua @@ -247,7 +247,7 @@ end -- installation (collected to keep the overview) -- also for type 1 fonts.otf.tables.features['goodies'] = 'Goodies on top of built in features' -fonts.otf.tables.features['featurset'] = 'Goodie Feature Set' +fonts.otf.tables.features['featureset'] = 'Goodie Feature Set' fonts.otf.tables.features['colorscheme'] = 'Goodie Color Scheme' fonts.otf.features.register('goodies') diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua index 216e6c23a..077be7c0c 100644 --- a/tex/context/base/font-ini.lua +++ b/tex/context/base/font-ini.lua @@ -109,3 +109,7 @@ function fonts.fontformat(filename,default) return default end end + +-- readers + +fonts.tfm.readers = fonts.tfm.readers or { } diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv index 25ed87eaa..12cdd2b8f 100644 --- a/tex/context/base/font-ini.mkiv +++ b/tex/context/base/font-ini.mkiv @@ -68,6 +68,7 @@ \registerctxluafile{font-tfm}{1.001} \registerctxluafile{font-enh}{1.001} \registerctxluafile{font-afm}{1.001} +\registerctxluafile{font-lua}{1.001} \registerctxluafile{font-cid}{1.001} % cid maps \registerctxluafile{font-ott}{1.001} % otf tables \registerctxluafile{font-otf}{1.001} % otf main diff --git a/tex/context/base/font-lua.lua b/tex/context/base/font-lua.lua new file mode 100644 index 000000000..fe07dd38b --- /dev/null +++ b/tex/context/base/font-lua.lua @@ -0,0 +1,45 @@ +if not modules then modules = { } end modules ['font-lua'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) + +local report_lua = logs.new("fonts","lua loading") + +fonts.formats.lua = "lua" + +local readers = fonts.tfm.readers + +local function check_lua(specification,fullname) + -- standard tex file lookup + local fullname = resolvers.findfile(fullname) or "" + if fullname ~= "" then + local loader = loadfile(fullname) + loader = loader and loader() + return loader and loader(specification) + end +end + +function readers.lua(specification) + local original = specification.specification + if trace_defining then + report_lua("using lua reader for '%s'",original) + end + local fullname, tfmtable = specification.filename or "", nil + if fullname == "" then + local forced = specification.forced or "" + if forced ~= "" then + tfmtable = check_lua(specification,specification.name .. "." .. forced) + end + if not tfmtable then + tfmtable = check_lua(specification,specification.name) + end + else + tfmtable = check_lua(specification,fullname) + end + return tfmtable +end diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index a543e0b0e..80046281a 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -36,6 +36,8 @@ local report_otf = logs.new("fonts","otf loading") local starttiming, stoptiming, elapsedtime = statistics.starttiming, statistics.stoptiming, statistics.elapsedtime +local findbinfile = resolvers.findbinfile + local fonts = fonts fonts.otf = fonts.otf or { } @@ -55,6 +57,7 @@ enhancers.patches = { } local patches = enhancers.patches local definers = fonts.definers +local readers = fonts.tfm.readers otf.glists = { "gsub", "gpos" } @@ -1611,11 +1614,6 @@ end -- we cannot share descriptions as virtual fonts might extend them (ok, we could -- use a cache with a hash -fonts.formats.dfont = "truetype" -fonts.formats.ttc = "truetype" -fonts.formats.ttf = "truetype" -fonts.formats.otf = "opentype" - local function copytotfm(data,cache_id) -- we can save a copy when we reorder the tma to unicode (nasty due to one->many) if data then local glyphs, pfminfo, metadata = data.glyphs or { }, data.pfminfo or { }, data.metadata or { } @@ -1831,7 +1829,7 @@ end otf.features.register('mathsize') -function tfm.read_from_otf(specification) -- wrong namespace +local function read_from_otf(specification) -- wrong namespace local tfmtable = otftotfm(specification) if tfmtable then local otfdata = tfmtable.shared.otfdata @@ -1917,3 +1915,56 @@ function otf.collectlookups(otfdata,kind,script,language) end return nil, nil end + +-- readers + +fonts.formats.dfont = "truetype" +fonts.formats.ttc = "truetype" +fonts.formats.ttf = "truetype" +fonts.formats.otf = "opentype" + +local function check_otf(forced,specification,suffix,what) + local name = specification.name + if forced then + name = file.addsuffix(name,suffix,true) + end + local fullname, tfmtable = findbinfile(name,suffix) or "", nil -- one shot + -- if false then -- can be enabled again when needed + -- if fullname == "" then + -- local fb = fonts.names.old_to_new[name] + -- if fb then + -- fullname = findbinfile(fb,suffix) or "" + -- end + -- end + -- if fullname == "" then + -- local fb = fonts.names.new_to_old[name] + -- if fb then + -- fullname = findbinfile(fb,suffix) or "" + -- end + -- end + -- end + if fullname == "" then + fullname = fonts.names.getfilename(name,suffix) + end + if fullname ~= "" then + specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then + tfmtable = read_from_otf(specification) -- we need to do it for all matches / todo + end + return tfmtable +end + +function readers.opentype(specification,suffix,what) + local forced = specification.forced or "" + if forced == "otf" then + return check_otf(true,specification,forced,"opentype") + elseif forced == "ttf" or forced == "ttc" or forced == "dfont" then + return check_otf(true,specification,forced,"truetype") + else + return check_otf(false,specification,suffix,what) + end +end + +function readers.otf (specification) return readers.opentype(specification,"otf","opentype") end +function readers.ttf (specification) return readers.opentype(specification,"ttf","truetype") end +function readers.ttc (specification) return readers.opentype(specification,"ttf","truetype") end -- !! +function readers.dfont(specification) return readers.opentype(specification,"ttf","truetype") end -- !! diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua index 3be220e80..ece478502 100644 --- a/tex/context/base/font-tfm.lua +++ b/tex/context/base/font-tfm.lua @@ -37,7 +37,9 @@ fonts.initializers = fonts.initializers or { } fonts.initializers.common = fonts.initializers.common or { } local set_attribute = node.set_attribute +local findbinfile = resolvers.findbinfile +local readers = fonts.tfm.readers local fontdata = fonts.identifiers local nodecodes = nodes.nodecodes @@ -56,9 +58,7 @@ tfm.fontnamemode = "fullpath" tfm.enhance = tfm.enhance or function() end -fonts.formats.tfm = "type1" -- we need to have at least a value here - -function tfm.read_from_tfm(specification) +local function read_from_tfm(specification) local fname, tfmdata = specification.filename or "", nil if fname ~= "" then if trace_defining then @@ -69,7 +69,7 @@ function tfm.read_from_tfm(specification) tfmdata.descriptions = tfmdata.descriptions or { } if tfm.resolvevirtualtoo then fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here - fname = resolvers.findbinfile(specification.name, 'ovf') + fname = findbinfile(specification.name, 'ovf') if fname and fname ~= "" then local vfdata = font.read_vf(fname,specification.size) -- not cached, fast enough if vfdata then @@ -745,10 +745,10 @@ function tfm.checkedfilename(metadata,whatever) local askedfilename = metadata.filename or "" if askedfilename ~= "" then askedfilename = resolvers.resolve(askedfilename) -- no shortcut - foundfilename = resolvers.findbinfile(askedfilename,"") or "" + foundfilename = findbinfile(askedfilename,"") or "" if foundfilename == "" then report_defining("source file '%s' is not found",askedfilename) - foundfilename = resolvers.findbinfile(file.basename(askedfilename),"") or "" + foundfilename = findbinfile(file.basename(askedfilename),"") or "" if foundfilename ~= "" then report_defining("using source file '%s' (cache mismatch)",foundfilename) end @@ -768,3 +768,41 @@ end statistics.register("fonts load time", function() return statistics.elapsedseconds(fonts) end) + +-- readers + +fonts.formats.tfm = "type1" -- we need to have at least a value here + +local function check_tfm(specification,fullname) + -- ofm directive blocks local path search unless set; btw, in context we + -- don't support ofm files anyway as this format is obsolete + local foundname = findbinfile(fullname, 'tfm') or "" -- just to be sure + if foundname == "" then + foundname = findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context + end + if foundname == "" then + foundname = fonts.names.getfilename(fullname,"tfm") + end + if foundname ~= "" then + specification.filename, specification.format = foundname, "ofm" + return read_from_tfm(specification) + end +end + +readers.check_tfm = check_tfm + +function readers.tfm(specification) + local fullname, tfmtable = specification.filename or "", nil + if fullname == "" then + local forced = specification.forced or "" + if forced ~= "" then + tfmtable = check_tfm(specification,specification.name .. "." .. forced) + end + if not tfmtable then + tfmtable = check_tfm(specification,specification.name) + end + else + tfmtable = check_tfm(specification,fullname) + end + return tfmtable +end diff --git a/tex/context/base/luat-dum.lua b/tex/context/base/luat-dum.lua index a7f602eb0..1d1a98e80 100644 --- a/tex/context/base/luat-dum.lua +++ b/tex/context/base/luat-dum.lua @@ -36,7 +36,6 @@ storage = { -- probably no longer needed logs = { new = function() return dummyfunction end, report = dummyfunction, - simple = dummyfunction, } callbacks = { register = function(n,f) return callback.register(n,f) end, @@ -69,8 +68,12 @@ local remapper = { function resolvers.findfile(name,kind) name = string.gsub(name,"\\","\/") - kind = string.lower(kind) - return kpse.find_file(name,(kind and kind ~= "" and (remapper[kind] or kind)) or file.extname(name,"tex")) + kind = kind and string.lower(kind) + local found = kpse.find_file(name,(kind and kind ~= "" and (remapper[kind] or kind)) or file.extname(name,"tex")) + if not found or found == "" then + found = kpse.find_file(name,"other text file") + end + return found end function resolvers.findbinfile(name,kind) diff --git a/tex/context/base/luat-fmt.lua b/tex/context/base/luat-fmt.lua index d6dd4efad..1c0e106a6 100644 --- a/tex/context/base/luat-fmt.lua +++ b/tex/context/base/luat-fmt.lua @@ -15,7 +15,7 @@ local report_format = logs.new("resolvers","formats") local quoted = string.quoted -local function primaryflags() +local function primaryflags() -- not yet ok local trackers = environment.argument("trackers") local directives = environment.argument("directives") local flags = "" diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua index e1c8610a3..c6be54ee6 100644 --- a/tex/context/base/mult-ini.lua +++ b/tex/context/base/mult-ini.lua @@ -129,7 +129,7 @@ end -- status -function commands.showstatus(category,message) +function commands.writestatus(category,message) local r = reporters[category] r(message) end diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 139a75836..e4f845c7a 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/trac-log.lua b/tex/context/base/trac-log.lua index 41bd40eaf..93e8decf9 100644 --- a/tex/context/base/trac-log.lua +++ b/tex/context/base/trac-log.lua @@ -13,7 +13,7 @@ if not modules then modules = { } end modules ['trac-log'] = { local write_nl, write = texio and texio.write_nl or print, texio and texio.write or io.write local format, gmatch, find = string.format, string.gmatch, string.find -local concat = table.concat +local concat, insert, remove = table.concat, table.insert, table.remove local escapedpattern = string.escapedpattern local texcount = tex and tex.count local next, type = next, type @@ -56,31 +56,71 @@ setmetatable(logs, { __index = function(t,k) t[k] = ignore ; return ignore end } -- local separator = (tex and (tex.jobname or tex.formatname)) and ">" or "|" -local report, subreport +local report, subreport, status, settarget if tex and tex.jobname or tex.formatname then + local target = "term and log" + report = function(a,b,c,...) if c then - write_nl(format("%-15s > %s\n",a,format(b,c,...))) + write_nl(target,format("%-15s > %s\n",a,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s\n",a,b)) + write_nl(target,format("%-15s > %s\n",a,b)) elseif a then - write_nl(format("%-15s >\n", a)) + write_nl(target,format("%-15s >\n", a)) else - write_nl("\n") + write_nl(target,"\n") end end subreport = function(a,sub,b,c,...) if c then - write_nl(format("%-15s > %s > %s\n",a,sub,format(b,c,...))) + write_nl(target,format("%-15s > %s > %s\n",a,sub,format(b,c,...))) elseif b then - write_nl(format("%-15s > %s > %s\n",a,sub,b)) + write_nl(target,format("%-15s > %s > %s\n",a,sub,b)) elseif a then - write_nl(format("%-15s > %s >\n", a,sub)) + write_nl(target,format("%-15s > %s >\n", a,sub)) else - write_nl("\n") + write_nl(target,"\n") + end + end + + status = function(a,b,c,...) + if c then + write_nl(target,format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(target,format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(target,format("%-15s :\n", a)) + else + write_nl(target,"\n") + end + end + + local targets = { + logfile = "log", + log = "log", + file = "log", + console = "term", + terminal = "term", + both = "term and log", + } + + settarget = function(whereto) + target = targets[whereto or "both"] or targets.both + end + + local stack = { } + + pushtarget = function(newtarget) + insert(stack,target) + settarget(newtarget) + end + + poptarget = function() + if #stack > 0 then + settarget(remove(stack)) end end @@ -110,22 +150,30 @@ else end end -end - -function logs.status(a,b,c,...) -- at the tex end - if c then - write_nl(format("%-15s : %s\n",a,format(b,c,...))) - elseif b then - write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s - elseif a then - write_nl(format("%-15s :\n", a)) - else - write_nl("\n") + status = function(a,b,c,...) -- not to be used in lua anyway + if c then + write_nl(format("%-15s : %s\n",a,format(b,c,...))) + elseif b then + write_nl(format("%-15s : %s\n",a,b)) -- b can have %'s + elseif a then + write_nl(format("%-15s :\n", a)) + else + write_nl("\n") + end end + + settarget = ignore + pushtarget = ignore + poptarget = ignore + end -logs.report = report -logs.subreport = subreport +logs.report = report +logs.subreport = subreport +logs.status = status +logs.settarget = settarget +logs.pushtarget = pushtarget +logs.poptarget = poptarget -- installer @@ -137,6 +185,7 @@ function logs.reporter(category,subcategory) local logger = data[category] if not logger then local state = false +--~ print(category,states) if states == true then state = true elseif type(states) == "table" then diff --git a/tex/context/base/trac-set.lua b/tex/context/base/trac-set.lua index 3cf14acb2..6829f95b0 100644 --- a/tex/context/base/trac-set.lua +++ b/tex/context/base/trac-set.lua @@ -29,7 +29,7 @@ local trace_initialize = false -- only for testing during development function setters.initialize(filename,name,values) -- filename only for diagnostics local setter = data[name] if setter then - local data = data.data + local data = setter.data if data then for key, value in next, values do -- key = gsub(key,"_",".") @@ -218,7 +218,7 @@ local function report(setter,...) if report then report(setter.name,...) else -- fallback, as this module is loaded before the logger - write_nl(format("%-16s: %s\n",setter.name,format(...))) + write_nl(format("%-15s : %s\n",setter.name,format(...))) end end @@ -253,22 +253,30 @@ local trace_directives = false local trace_directives = false trackers.regist local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end) function directives.enable(...) - d_report("enabling: %s",concat({...}," ")) + if trace_directives then + d_report("enabling: %s",concat({...}," ")) + end d_enable(...) end function directives.disable(...) - d_report("disabling: %s",concat({...}," ")) + if trace_directives then + d_report("disabling: %s",concat({...}," ")) + end d_disable(...) end function experiments.enable(...) - e_report("enabling: %s",concat({...}," ")) + if trace_experiments then + e_report("enabling: %s",concat({...}," ")) + end e_enable(...) end function experiments.disable(...) - e_report("disabling: %s",concat({...}," ")) + if trace_experiments then + e_report("disabling: %s",concat({...}," ")) + end e_disable(...) end @@ -288,10 +296,12 @@ local flags = environment and environment.engineflags if flags then if trackers and flags.trackers then - t_enable(flags.trackers) + setters.initialize("flags","trackers", utilities.parsers.settings_to_hash(flags.trackers)) + -- t_enable(flags.trackers) end if directives and flags.directives then - d_enable(flags.directives) + setters.initialize("flags","directives", utilities.parsers.settings_to_hash(flags.directives)) + -- d_enable(flags.directives) end end diff --git a/tex/generic/context/luatex-fonts-demo-vf-1.lua b/tex/generic/context/luatex-fonts-demo-vf-1.lua new file mode 100644 index 000000000..31ac4b87b --- /dev/null +++ b/tex/generic/context/luatex-fonts-demo-vf-1.lua @@ -0,0 +1,36 @@ +return function(specification) + local f1, id1 = fonts.tfm.readanddefine('lmroman10-regular', specification.size) + local f2, id2 = fonts.tfm.readanddefine('lmsans10-regular', specification.size) + local f3, id3 = fonts.tfm.readanddefine('lmtypewriter10-regular',specification.size) + if f1 and f2 and f3 then + f1.name = specification.name + f1.virtualized = true + f1.fonts = { + { id = id1 }, + { id = id2 }, + { id = id3 }, + } + local color = { [0] = + { "special", "pdf:0 g" }, + { "special", "pdf:1 0 0 rg" }, + { "special", "pdf:0 1 0 rg" }, + { "special", "pdf:0 0 1 rg" }, + } + local chars = { + fonts.identifiers[id1].characters, + fonts.identifiers[id2].characters, + fonts.identifiers[id3].characters, + } + for u, v in next, f1.characters do + local n = math.floor(math.random(1,3)+0.5) + local c = chars[n][u] or v + v.commands = { color[n], { 'slot', n, u }, color[0] } + v.kerns = nil + v.width = c.width + v.height = c.height + v.depth = c.depth + v.italic = nil + end + end + return f1 +end diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 4312d66ab..b9a85a292 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 02/08/11 10:06:31 +-- merge date : 02/08/11 17:08:08 do -- begin closure to overcome local limits and interference @@ -2399,7 +2399,6 @@ storage = { -- probably no longer needed logs = { new = function() return dummyfunction end, report = dummyfunction, - simple = dummyfunction, } callbacks = { register = function(n,f) return callback.register(n,f) end, @@ -2432,8 +2431,12 @@ local remapper = { function resolvers.findfile(name,kind) name = string.gsub(name,"\\","\/") - kind = string.lower(kind) - return kpse.find_file(name,(kind and kind ~= "" and (remapper[kind] or kind)) or file.extname(name,"tex")) + kind = kind and string.lower(kind) + local found = kpse.find_file(name,(kind and kind ~= "" and (remapper[kind] or kind)) or file.extname(name,"tex")) + if not found or found == "" then + found = kpse.find_file(name,"other text file") + end + return found end function resolvers.findbinfile(name,kind) @@ -3418,6 +3421,10 @@ function fonts.fontformat(filename,default) end end +-- readers + +fonts.tfm.readers = fonts.tfm.readers or { } + end -- closure do -- begin closure to overcome local limits and interference @@ -3461,7 +3468,9 @@ fonts.initializers = fonts.initializers or { } fonts.initializers.common = fonts.initializers.common or { } local set_attribute = node.set_attribute +local findbinfile = resolvers.findbinfile +local readers = fonts.tfm.readers local fontdata = fonts.identifiers local nodecodes = nodes.nodecodes @@ -3480,9 +3489,7 @@ tfm.fontnamemode = "fullpath" tfm.enhance = tfm.enhance or function() end -fonts.formats.tfm = "type1" -- we need to have at least a value here - -function tfm.read_from_tfm(specification) +local function read_from_tfm(specification) local fname, tfmdata = specification.filename or "", nil if fname ~= "" then if trace_defining then @@ -3493,7 +3500,7 @@ function tfm.read_from_tfm(specification) tfmdata.descriptions = tfmdata.descriptions or { } if tfm.resolvevirtualtoo then fonts.logger.save(tfmdata,file.extname(fname),specification) -- strange, why here - fname = resolvers.findbinfile(specification.name, 'ovf') + fname = findbinfile(specification.name, 'ovf') if fname and fname ~= "" then local vfdata = font.read_vf(fname,specification.size) -- not cached, fast enough if vfdata then @@ -4169,10 +4176,10 @@ function tfm.checkedfilename(metadata,whatever) local askedfilename = metadata.filename or "" if askedfilename ~= "" then askedfilename = resolvers.resolve(askedfilename) -- no shortcut - foundfilename = resolvers.findbinfile(askedfilename,"") or "" + foundfilename = findbinfile(askedfilename,"") or "" if foundfilename == "" then report_defining("source file '%s' is not found",askedfilename) - foundfilename = resolvers.findbinfile(file.basename(askedfilename),"") or "" + foundfilename = findbinfile(file.basename(askedfilename),"") or "" if foundfilename ~= "" then report_defining("using source file '%s' (cache mismatch)",foundfilename) end @@ -4193,6 +4200,44 @@ statistics.register("fonts load time", function() return statistics.elapsedseconds(fonts) end) +-- readers + +fonts.formats.tfm = "type1" -- we need to have at least a value here + +local function check_tfm(specification,fullname) + -- ofm directive blocks local path search unless set; btw, in context we + -- don't support ofm files anyway as this format is obsolete + local foundname = findbinfile(fullname, 'tfm') or "" -- just to be sure + if foundname == "" then + foundname = findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context + end + if foundname == "" then + foundname = fonts.names.getfilename(fullname,"tfm") + end + if foundname ~= "" then + specification.filename, specification.format = foundname, "ofm" + return read_from_tfm(specification) + end +end + +readers.check_tfm = check_tfm + +function readers.tfm(specification) + local fullname, tfmtable = specification.filename or "", nil + if fullname == "" then + local forced = specification.forced or "" + if forced ~= "" then + tfmtable = check_tfm(specification,specification.name .. "." .. forced) + end + if not tfmtable then + tfmtable = check_tfm(specification,specification.name) + end + else + tfmtable = check_tfm(specification,fullname) + end + return tfmtable +end + end -- closure do -- begin closure to overcome local limits and interference @@ -5596,6 +5641,56 @@ end -- closure do -- begin closure to overcome local limits and interference +if not modules then modules = { } end modules ['font-lua'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) + +local report_lua = logs.new("fonts","lua loading") + +fonts.formats.lua = "lua" + +local readers = fonts.tfm.readers + +local function check_lua(specification,fullname) + -- standard tex file lookup + local fullname = resolvers.findfile(fullname) or "" + if fullname ~= "" then + local loader = loadfile(fullname) + loader = loader and loader() + return loader and loader(specification) + end +end + +function readers.lua(specification) + local original = specification.specification + if trace_defining then + report_lua("using lua reader for '%s'",original) + end + local fullname, tfmtable = specification.filename or "", nil + if fullname == "" then + local forced = specification.forced or "" + if forced ~= "" then + tfmtable = check_lua(specification,specification.name .. "." .. forced) + end + if not tfmtable then + tfmtable = check_lua(specification,specification.name) + end + else + tfmtable = check_lua(specification,fullname) + end + return tfmtable +end + +end -- closure + +do -- begin closure to overcome local limits and interference + if not modules then modules = { } end modules ['font-otf'] = { version = 1.001, comment = "companion to font-ini.mkiv", @@ -5634,6 +5729,8 @@ local report_otf = logs.new("fonts","otf loading") local starttiming, stoptiming, elapsedtime = statistics.starttiming, statistics.stoptiming, statistics.elapsedtime +local findbinfile = resolvers.findbinfile + local fonts = fonts fonts.otf = fonts.otf or { } @@ -5653,6 +5750,7 @@ enhancers.patches = { } local patches = enhancers.patches local definers = fonts.definers +local readers = fonts.tfm.readers otf.glists = { "gsub", "gpos" } @@ -7209,11 +7307,6 @@ end -- we cannot share descriptions as virtual fonts might extend them (ok, we could -- use a cache with a hash -fonts.formats.dfont = "truetype" -fonts.formats.ttc = "truetype" -fonts.formats.ttf = "truetype" -fonts.formats.otf = "opentype" - local function copytotfm(data,cache_id) -- we can save a copy when we reorder the tma to unicode (nasty due to one->many) if data then local glyphs, pfminfo, metadata = data.glyphs or { }, data.pfminfo or { }, data.metadata or { } @@ -7429,7 +7522,7 @@ end otf.features.register('mathsize') -function tfm.read_from_otf(specification) -- wrong namespace +local function read_from_otf(specification) -- wrong namespace local tfmtable = otftotfm(specification) if tfmtable then local otfdata = tfmtable.shared.otfdata @@ -7516,6 +7609,59 @@ function otf.collectlookups(otfdata,kind,script,language) return nil, nil end +-- readers + +fonts.formats.dfont = "truetype" +fonts.formats.ttc = "truetype" +fonts.formats.ttf = "truetype" +fonts.formats.otf = "opentype" + +local function check_otf(forced,specification,suffix,what) + local name = specification.name + if forced then + name = file.addsuffix(name,suffix,true) + end + local fullname, tfmtable = findbinfile(name,suffix) or "", nil -- one shot + -- if false then -- can be enabled again when needed + -- if fullname == "" then + -- local fb = fonts.names.old_to_new[name] + -- if fb then + -- fullname = findbinfile(fb,suffix) or "" + -- end + -- end + -- if fullname == "" then + -- local fb = fonts.names.new_to_old[name] + -- if fb then + -- fullname = findbinfile(fb,suffix) or "" + -- end + -- end + -- end + if fullname == "" then + fullname = fonts.names.getfilename(name,suffix) + end + if fullname ~= "" then + specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then + tfmtable = read_from_otf(specification) -- we need to do it for all matches / todo + end + return tfmtable +end + +function readers.opentype(specification,suffix,what) + local forced = specification.forced or "" + if forced == "otf" then + return check_otf(true,specification,forced,"opentype") + elseif forced == "ttf" or forced == "ttc" or forced == "dfont" then + return check_otf(true,specification,forced,"truetype") + else + return check_otf(false,specification,suffix,what) + end +end + +function readers.otf (specification) return readers.opentype(specification,"otf","opentype") end +function readers.ttf (specification) return readers.opentype(specification,"ttf","truetype") end +function readers.ttc (specification) return readers.opentype(specification,"ttf","truetype") end -- !! +function readers.dfont(specification) return readers.opentype(specification,"ttf","truetype") end -- !! + end -- closure do -- begin closure to overcome local limits and interference @@ -15303,7 +15449,6 @@ trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading trackers.register("fonts.all", "fonts.*", "otf.*", "afm.*", "tfm.*") local report_defining = logs.new("fonts","defining") -local report_afm = logs.new("fonts","afm loading") --[[ldx--

Here we deal with defining fonts. We do so by intercepting the @@ -15320,7 +15465,7 @@ tfm.readers = tfm.readers or { } tfm.fonts = allocate() local readers = tfm.readers -local sequence = allocate { 'otf', 'ttf', 'afm', 'tfm' } +local sequence = allocate { 'otf', 'ttf', 'afm', 'tfm', 'lua' } readers.sequence = sequence tfm.version = 1.01 @@ -15476,10 +15621,10 @@ function tfm.hashfeatures(specification) t[tn] = v .. '=' .. tostring(vtf[v]) end end - --~ if specification.mathsize then - --~ tn = tn + 1 - --~ t[tn] = "mathsize=" .. specification.mathsize - --~ end + -- if specification.mathsize then + -- tn = tn + 1 + -- t[tn] = "mathsize=" .. specification.mathsize + -- end if tn > 0 then return concat(t,"+") end @@ -15507,21 +15652,21 @@ function tfm.hashinstance(specification,force) size = math.round(tfm.scaled(size,fonts.designsizes[hash])) specification.size = size end ---~ local mathsize = specification.mathsize or 0 ---~ if mathsize > 0 then ---~ local textsize = specification.textsize ---~ if fallbacks then ---~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ] @ ' .. fallbacks ---~ else ---~ return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ]' ---~ end ---~ else + -- local mathsize = specification.mathsize or 0 + -- if mathsize > 0 then + -- local textsize = specification.textsize + -- if fallbacks then + -- return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ] @ ' .. fallbacks + -- else + -- return hash .. ' @ ' .. tostring(size) .. ' [ ' .. tostring(mathsize) .. ' : ' .. tostring(textsize) .. ' ]' + -- end + -- else if fallbacks then return hash .. ' @ ' .. tostring(size) .. ' @ ' .. fallbacks else return hash .. ' @ ' .. tostring(size) end ---~ end + -- end end --[[ldx-- @@ -15690,149 +15835,6 @@ function tfm.readanddefine(name,size) -- no id return fonts.identifiers[id], id end ---[[ldx-- -

Next follow the readers. This code was written while -evolved. Each one has its own way of dealing with its format.

---ldx]]-- - -local function check_tfm(specification,fullname) - -- ofm directive blocks local path search unless set; btw, in context we - -- don't support ofm files anyway as this format is obsolete - local foundname = findbinfile(fullname, 'tfm') or "" -- just to be sure - if foundname == "" then - foundname = findbinfile(fullname, 'ofm') or "" -- bonus for usage outside context - end - if foundname == "" then - foundname = fonts.names.getfilename(fullname,"tfm") - end - if foundname ~= "" then - specification.filename, specification.format = foundname, "ofm" - return tfm.read_from_tfm(specification) - end -end - -local function check_afm(specification,fullname) - local foundname = findbinfile(fullname, 'afm') or "" -- just to be sure - if foundname == "" then - foundname = fonts.names.getfilename(fullname,"afm") - end - if foundname == "" and tfm.autoprefixedafm then - local encoding, shortname = match(fullname,"^(.-)%-(.*)$") -- context: encoding-name.* - if encoding and shortname and fonts.enc.known[encoding] then - shortname = findbinfile(shortname,'afm') or "" -- just to be sure - if shortname ~= "" then - foundname = shortname - if trace_loading then - report_afm("stripping encoding prefix from filename %s",afmname) - end - end - end - end - if foundname ~= "" then - specification.filename, specification.format = foundname, "afm" - return tfm.read_from_afm(specification) - end -end - -function readers.tfm(specification) - local fullname, tfmtable = specification.filename or "", nil - if fullname == "" then - local forced = specification.forced or "" - if forced ~= "" then - tfmtable = check_tfm(specification,specification.name .. "." .. forced) - end - if not tfmtable then - tfmtable = check_tfm(specification,specification.name) - end - else - tfmtable = check_tfm(specification,fullname) - end - return tfmtable -end - -function readers.afm(specification,method) - local fullname, tfmtable = specification.filename or "", nil - if fullname == "" then - local forced = specification.forced or "" - if forced ~= "" then - tfmtable = check_afm(specification,specification.name .. "." .. forced) - end - if not tfmtable then - method = method or definers.method or "afm or tfm" - if method == "tfm" then - tfmtable = check_tfm(specification,specification.name) - elseif method == "afm" then - tfmtable = check_afm(specification,specification.name) - elseif method == "tfm or afm" then - tfmtable = check_tfm(specification,specification.name) or check_afm(specification,specification.name) - else -- method == "afm or tfm" or method == "" then - tfmtable = check_afm(specification,specification.name) or check_tfm(specification,specification.name) - end - end - else - tfmtable = check_afm(specification,fullname) - end - return tfmtable -end - -function readers.pfb(specification,method) -- only called when forced - local original = specification.specification - if trace_loading then - report_afm("using afm reader for '%s'",original) - end - specification.specification = gsub(original,"%.pfb",".afm") - specification.forced = "afm" - return readers.afm(specification,method) -end - --- maybe some day a set of names - -local function check_otf(forced,specification,suffix,what) - local name = specification.name - if forced then - name = file.addsuffix(name,suffix,true) - end - local fullname, tfmtable = findbinfile(name,suffix) or "", nil -- one shot - -- if false then -- can be enabled again when needed - -- if fullname == "" then - -- local fb = fonts.names.old_to_new[name] - -- if fb then - -- fullname = findbinfile(fb,suffix) or "" - -- end - -- end - -- if fullname == "" then - -- local fb = fonts.names.new_to_old[name] - -- if fb then - -- fullname = findbinfile(fb,suffix) or "" - -- end - -- end - -- end - if fullname == "" then - fullname = fonts.names.getfilename(name,suffix) - end - if fullname ~= "" then - specification.filename, specification.format = fullname, what -- hm, so we do set the filename, then - tfmtable = tfm.read_from_otf(specification) -- we need to do it for all matches / todo - end - return tfmtable -end - -function readers.opentype(specification,suffix,what) - local forced = specification.forced or "" - if forced == "otf" then - return check_otf(true,specification,forced,"opentype") - elseif forced == "ttf" or forced == "ttc" or forced == "dfont" then - return check_otf(true,specification,forced,"truetype") - else - return check_otf(false,specification,suffix,what) - end -end - -function readers.otf (specification) return readers.opentype(specification,"otf","opentype") end -function readers.ttf (specification) return readers.opentype(specification,"ttf","truetype") end -function readers.ttc (specification) return readers.opentype(specification,"ttf","truetype") end -- !! -function readers.dfont(specification) return readers.opentype(specification,"ttf","truetype") end -- !! - --[[ldx--

We need to check for default features. For this we provide a helper function.

@@ -16112,13 +16114,13 @@ fonts = fonts or { } -- general fonts.otf.pack = false -- only makes sense in context -fonts.tfm.resolvevirtualtoo = false -- context specific (du eto resolver) +fonts.tfm.resolvevirtualtoo = false -- context specific (due to resolver) fonts.tfm.fontnamemode = "specification" -- somehow latex needs this (changed name!) -- readers fonts.tfm.readers = fonts.tfm.readers or { } -fonts.tfm.readers.sequence = { 'otf', 'ttf', 'tfm' } +fonts.tfm.readers.sequence = { 'otf', 'ttf', 'tfm', 'lua' } fonts.tfm.readers.afm = nil -- define diff --git a/tex/generic/context/luatex-fonts.lua b/tex/generic/context/luatex-fonts.lua index 5fffecb47..cff1800e7 100644 --- a/tex/generic/context/luatex-fonts.lua +++ b/tex/generic/context/luatex-fonts.lua @@ -112,6 +112,7 @@ else loadmodule('font-cid.lua') loadmodule('font-ott.lua') -- might be split loadmodule('font-map.lua') -- for loading lum file (will be stripped) + loadmodule('font-lua.lua') loadmodule('font-otf.lua') loadmodule('font-otd.lua') loadmodule('font-oti.lua') @@ -126,6 +127,8 @@ else end +resolvers.loadmodule = loadmodule + -- In order to deal with the fonts we need to initialize some -- callbacks. One can overload them later on if needed. diff --git a/tex/generic/context/luatex-test.tex b/tex/generic/context/luatex-test.tex index 594039053..9f57cfea9 100644 --- a/tex/generic/context/luatex-test.tex +++ b/tex/generic/context/luatex-test.tex @@ -48,4 +48,8 @@ endfig ; \endmplibcode +\font\mine=file:luatex-fonts-demo-vf-1.lua at 12pt + +\mine \input tufte \par + \end -- cgit v1.2.3