diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
commit | fc4466b32ed330a956ac603b00fd145524cff49a (patch) | |
tree | 2c50e2b8de13aa9233b2c76dffe201558f169e86 /Master/texmf-dist/tex/context/modules/mkiv | |
parent | 50e2368597d5f6fe2057195d0ae6a9f2044923e4 (diff) |
context (22apr16)
git-svn-id: svn://tug.org/texlive/trunk@40691 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/modules/mkiv')
163 files changed, 45072 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-barcodes.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-barcodes.mkiv new file mode 100644 index 00000000000..e4c43b37650 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-barcodes.mkiv @@ -0,0 +1,122 @@ +%D \module +%D [ file=m-barcodes, +%D version=2010.03.14, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Barcodes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{barcodes}{the 'zint' module is a better choice} + +% \startTEXpage +% \startPSTRICKS +% \pspicture(-4mm,-1mm)(38mm,26mm) +% \psbarcode{9781860742712}{includetext guardwhitespace}{ean13}% +% \endpspicture +% \stopPSTRICKS +% \stopTEXpage + +% 978-94-90688-01-1 +% +% 978 = ean isbn identifier (979 also) +% 94 = country code +% 90688 = publisher code +% 01 = title 1 +% 1 = checksum + +\usemodule[pstricks] + +\usePSTRICKSmodule[pst-barcode] + +\definefont[barcodefont][file:ocrb10] +% \definefont[barcodefont][file:texgyreheros-regular] + +\startluacode +moduledata.barcodes = { } + +local function split(code) + local t = { string.byte(code,1,#code) } + if #t >= 12 then + local s = 0 + for i=1,11,2 do + s = s + (t[i]-48) + end + for i=2,12,2 do + s = s + 3 * (t[i]-48) + end + local m = s % 10 + local c = (m > 0 and (10 - m)) or 0 + return t, s, m, c + end +end + +function moduledata.barcodes.isbn_1(original) + local code = string.gsub(original,"%-","") + local t, s, m, c = split(code) + if t then + if #t == 13 then + local e = ((c == t[13] - 48) and "correct") or "wrong" + logs.report("isbn code","code=%s, sum=%s, checksum=%s, modulo=%s, status=%s",original,s,m,c,e) + else + logs.report("isbn code","code=%s, sum=%s, checksum=%s, modulo=%s",original,s,m,c) + code= code .. c + end + end + context(code) +end + +function moduledata.barcodes.isbn_2(original) + local code = string.gsub(original,"%-","") + local t, s, m, c = split(code) + if t and #t == 12 then + original = original .. "-" .. c + end + context(original) +end +\stopluacode + +\startsetups barcode:isbn + \scale + [width=5cm] + { + \vbox { + \hbox { + \hskip3.7mm + \scale[width=34mm]{\barcodefont ISBN \ctxlua{moduledata.barcodes.isbn_2("\getvariable{barcode}{code}")}} + } + \par + \normalexpanded { \noexpand \setPSTRICKS { + \noexpand \pspicture(-4mm,-1mm)(38mm,26mm) + \noexpand \psbarcode { + \ctxlua{moduledata.barcodes.isbn_1("\getvariable{barcode}{code}")} + } { + includetext guardwhitespace + } { + ean13 + } + \noexpand \endpspicture + } + \noexpand \processPSTRICKS } + } + } +\stopsetups + +\unexpanded\def\barcode[#1]% + {\bgroup + \setvariables[barcode][type=isbn,#1]% + \directsetup{barcode:\getvariable{barcode}{type}}% + \egroup} + +\continueifinputfile{m-barcodes.mkiv} + +\starttext + \startTEXpage + \barcode[type=isbn,code=978-94-90688-01-1] + \stopTEXpage +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-chart.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-chart.lua new file mode 100644 index 00000000000..f1e7f4cb937 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-chart.lua @@ -0,0 +1,945 @@ +if not modules then modules = { } end modules ['x-flow'] = { + version = 1.001, + comment = "companion to m-flow.mkvi", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- when we can resolve mpcolor at the lua end we will +-- use metapost.graphic(....) directly + +-- todo: labels + +moduledata.charts = moduledata.charts or { } + +local gsub, match, find, format, lower = string.gsub, string.match, string.find, string.format, string.lower +local setmetatableindex = table.setmetatableindex +local P, S, C, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.match + +local report_chart = logs.reporter("chart") + +local variables = interfaces.variables + +local v_yes = variables.yes +local v_no = variables.no +local v_none = variables.none +local v_standard = variables.standard +local v_overlay = variables.overlay +local v_round = variables.round +local v_test = variables.test + +local defaults = { + chart = { + name = "", + option = "", + backgroundcolor = "", + width = 100*65536, + height = 50*65536, + dx = 30*65536, + dy = 30*65536, + offset = 0, + bodyfont = "", + dot = "", + hcompact = variables_no, + vcompact = variables_no, + autofocus = "", + focus = "", + labeloffset = 5*65536, + commentoffset = 5*65536, + exitoffset = 0, + + }, + shape = { -- FLOS + rulethickness = 65536, + default = "", + framecolor = "darkblue", + backgroundcolor = "lightgray", + }, + focus = { -- FLOF + rulethickness = 65536, + framecolor = "darkred", + backgroundcolor = "gray", + }, + line = { -- FLOL + rulethickness = 65536, + radius = 10*65536, + color = "darkgreen", + corner = "", + dash = "", + arrow = "", + offset = "", + }, + set = { -- FLOX + }, + split = { + nx = 3, + ny = 3, + command = "", + marking = "", + before = "", + after = "", + } +} + +local validshapes = { + ["node"] = { kind = "shape", number = 0 }, + ["action"] = { kind = "shape", number = 24 }, + ["procedure"] = { kind = "shape", number = 5 }, + ["product"] = { kind = "shape", number = 12 }, + ["decision"] = { kind = "shape", number = 14 }, + ["archive"] = { kind = "shape", number = 19 }, + ["loop"] = { kind = "shape", number = 35 }, + ["wait"] = { kind = "shape", number = 6 }, + ["subprocedure"] = { kind = "shape", number = 20 }, + ["singledocument"] = { kind = "shape", number = 32 }, + ["multidocument"] = { kind = "shape", number = 33 }, + + ["right"] = { kind = "line", number = 66 }, + ["left"] = { kind = "line", number = 67 }, + ["up"] = { kind = "line", number = 68 }, + ["down"] = { kind = "line", number = 69 }, +} + +local validlabellocations = { + l = "l", left = "l", + r = "r", right = "r", + t = "t", top = "t", + b = "b", bottom = "b", + lt = "lt", + rt = "rt", + lb = "lb", + rb = "rb", + tl = "tl", + tr = "tr", + bl = "bl", + br = "br", +} + +local validcommentlocations = { + l = "l", left = "l", + r = "r", right = "r", + t = "t", top = "t", + b = "b", bottom = "b", + lt = "lt", + rt = "rt", + lb = "lb", + rb = "rb", + tl = "tl", + tr = "tr", + bl = "bl", + br = "br", +} + +local validtextlocations = { + l = "l", left = "l", + r = "r", right = "r", + t = "t", top = "t", + b = "b", bottom = "b", + c = "c", center = "c", + m = "c", middle = "m", + lt = "lt", + rt = "rt", + lb = "lb", + rb = "rb", + tl = "lt", + tr = "rt", + bl = "lb", + br = "rb", +} + +setmetatableindex(validshapes,function(t,k) + local l = gsub(lower(k)," ","") + local v = rawget(t,l) + if not v then + local n = tonumber(k) + if n then + v = { kind = "shape", number = n } + else + v = rawget(t,"action") + end + end + t[k] = v + return v +end) + +local charts = { } + +local data, hash, temp, last_x, last_y, name + +function commands.flow_start_chart(chartname) + data = { } + hash = { } + last_x, last_y = 0, 0 + name = chartname +end + +function commands.flow_stop_chart() + charts[name] = { + data = data, + hash = hash, + last_x = last_x, + last_y = last_y, + } + data, hash, temp = nil, nil, nil +end + +-- function commands.flow_set(chartname,chartdata) +-- local hash = { } +-- local data = { } +-- charts[name] = { +-- data = data, +-- hash = hash, +-- } +-- for i=1,#chartdata do +-- local di = data[i] +-- local name = di.name or "" +-- if name then +-- data[#data+1] = { +-- name = name, +-- labels = di.labels or { }, +-- comments = di.comments or { }, +-- exits = di.exits or { }, +-- connections = di.connections or { }, +-- settings = di.settings or { }, +-- x = di.x or 1, +-- y = di.y or 1, +-- } +-- hash[name] = i +-- end +-- end +-- end + +function commands.flow_reset(chartname) + charts[name] = nil +end + +function commands.flow_set_current_cell(n) + temp = data[tonumber(n)] or { } +end + +function commands.flow_start_cell(settings) + temp = { + texts = { }, + labels = { }, + exits = { }, + connections = { }, + settings = settings, + x = 1, + y = 1, + realx = 1, + realy = 1, + name = "", + } +end + +function commands.flow_stop_cell() + data[#data+1] = temp + hash[temp.name or #data] = temp +end + +function commands.flow_set_name(str) + temp.name = str +end + +function commands.flow_set_shape(str) + temp.shape = str +end + +function commands.flow_set_destination(str) + temp.destination = str +end + +function commands.flow_set_text(align,str) + temp.texts[#temp.texts+1] = { + location = align, + text = str, + } +end + +function commands.flow_set_overlay(str) + temp.overlay = str +end + +function commands.flow_set_focus(str) + temp.focus = str +end + +function commands.flow_set_figure(str) + temp.figure = str +end + +function commands.flow_set_label(location,text) + temp.labels[#temp.labels+1] = { + location = location, + text = text, + } +end + +function commands.flow_set_comment(location,text) + local connections = temp.connections + if connections then + local connection = connections[#connections] + if connection then + local comments = connection.comments + if comments then + comments[#comments+1] = { + location = location, + text = text, + } + end + end + end +end + +function commands.flow_set_exit(location,text) + temp.exits[#temp.exits+1] = { + location = location, + text = text, + } +end + +function commands.flow_set_include(name,x,y,settings) + data[#data+1] = { + include = name, + x = x, + y = y, + -- settings = settings, + } +end + +local function inject(includedata,data,hash) + local subchart = charts[includedata.include] + if not subchart then + return + end + local subdata = subchart.data + if not subdata then + return + end + local xoffset = (includedata.x or 1) - 1 + local yoffset = (includedata.y or 1) - 1 + local settings = includedata.settings + for i=1,#subdata do + local si = subdata[i] + if si.include then + inject(si,data,hash) + else + local x = si.x + xoffset + local y = si.y + yoffset + local t = { + x = x, + y = y, + realx = x, + realy = y, + settings = settings, + } + setmetatableindex(t,si) + data[#data+1] = t + hash[si.name or #data] = t + end + end +end + +local function pack(data,field) + local list, max = { }, 0 + for e=1,#data do + local d = data[e] + local f = d[field] + list[f] = true + if f > max then + max = f + end + end + for i=1,max do + if not list[i] then + for e=1,#data do + local d = data[e] + local f = d[field] + if f > i then + d[field] = f - 1 + end + end + end + end +end + +local function expanded(chart,chartsettings) + local expandeddata = { } + local expandedhash = { } + local expandedchart = { + data = expandeddata, + hash = expandedhash, + } + setmetatableindex(expandedchart,chart) + local data = chart.data + local hash = chart.hash + for i=1,#data do + local di = data[i] + if di.include then + inject(di,expandeddata,expandedhash) + else + expandeddata[#expandeddata+1] = di + expandedhash[di.name or #expandeddata] = di + end + end + -- + expandedchart.settings = chartsettings or { } + -- make locals + chartsettings.shape = chartsettings.shape or { } + chartsettings.focus = chartsettings.focus or { } + chartsettings.line = chartsettings.line or { } + chartsettings.set = chartsettings.set or { } + chartsettings.split = chartsettings.split or { } + chartsettings.chart = chartsettings.chart or { } + setmetatableindex(chartsettings.shape,defaults.shape) + setmetatableindex(chartsettings.focus,defaults.focus) + setmetatableindex(chartsettings.line ,defaults.line ) + setmetatableindex(chartsettings.set ,defaults.set ) + setmetatableindex(chartsettings.split,defaults.split) + setmetatableindex(chartsettings.chart,defaults.chart) + -- + if chartsettings.chart.vcompact == v_yes then + pack(expandeddata,"y") + end + if chartsettings.chart.hcompact == v_yes then + pack(expandeddata,"x") + end + -- + for i=1,#expandeddata do + local cell = expandeddata[i] + local settings = cell.settings + if not settings then + cell.settings = chartsettings + else + settings.shape = settings.shape or { } + settings.focus = settings.focus or { } + settings.line = settings.line or { } + setmetatableindex(settings.shape,chartsettings.shape) + setmetatableindex(settings.focus,chartsettings.focus) + setmetatableindex(settings.line ,chartsettings.line) + end + end + return expandedchart +end + +local splitter = lpeg.splitat(",") + +function commands.flow_set_location(x,y) + if type(x) == "string" and not y then + x, y = lpegmatch(splitter,x) + end + if not x or x == "" then + x = last_x + elseif type(x) == "number" then + -- ok + elseif x == "+" then + x = last_x + 1 + elseif x == "-" then + x = last_x - 1 + elseif find(x,"^[%+%-]") then + x = last_x + (tonumber(x) or 0) + else + x = tonumber(x) + end + if not y or y == "" then + y = last_y + elseif type(y) == "number" then + -- ok + elseif y == "+" then + y = last_y + 1 + elseif x == "-" then + y = last_y - 1 + elseif find(y,"^[%+%-]") then + y = last_y + (tonumber(y) or 0) + else + y = tonumber(y) + end + temp.x = x or 1 + temp.y = y or 1 + temp.realx = x or 1 + temp.realy = y or 1 + last_x = x or last_x + last_y = y or last_y +end + +function commands.flow_set_connection(location,displacement,name) + local dx, dy = lpegmatch(splitter,displacement) + dx = tonumber(dx) + dy = tonumber(dy) + temp.connections[#temp.connections+1] = { + location = location, + dx = dx or 0, + dy = dy or 0, + name = name, + comments = { }, + } +end + +local function visible(chart,cell) + local x, y = cell.x, cell.y + return + x >= chart.from_x and x <= chart.to_x and + y >= chart.from_y and y <= chart.to_y and cell +end + +local function process_cells(chart,xoffset,yoffset) + local data = chart.data + if not data then + return + end + local focus = utilities.parsers.settings_to_hash(chart.settings.chart.focus or "") + for i=1,#data do + local cell = visible(chart,data[i]) + if cell then + local settings = cell.settings + local shapesettings = settings.shape + local shape = cell.shape + if not shape or shape == "" then + shape = shapesettings.default or "none" + end + if shape ~= v_none then + local shapedata = validshapes[shape] + context("flow_begin_sub_chart ;") -- when is this needed + if shapedata.kind == "line" then + local linesettings = settings.line + context("flow_shape_line_color := \\MPcolor{%s} ;", linesettings.color) + context("flow_shape_fill_color := \\MPcolor{%s} ;", linesettings.backgroundcolor) + context("flow_shape_line_width := %p ; ", linesettings.rulethickness) + elseif focus[cell.focus] or focus[cell.name] then + local focussettings = settings.focus + context("flow_shape_line_color := \\MPcolor{%s} ;", focussettings.framecolor) + context("flow_shape_fill_color := \\MPcolor{%s} ;", focussettings.backgroundcolor) + context("flow_shape_line_width := %p ; ", focussettings.rulethickness) + else + local shapesettings = settings.shape + context("flow_shape_line_color := \\MPcolor{%s} ;", shapesettings.framecolor) + context("flow_shape_fill_color := \\MPcolor{%s} ;", shapesettings.backgroundcolor) + context("flow_shape_line_width := %p ; " , shapesettings.rulethickness) + end + context("flow_peepshape := false ;") -- todo + context("flow_new_shape(%s,%s,%s) ;",cell.x+xoffset,cell.y+yoffset,shapedata.number) + context("flow_end_sub_chart ;") + end + end + end +end + +-- todo : make lpeg for splitter + +local sign = S("+p") / "1" + + S("-m") / "-1" + +local full = C(P("left")) + + C(P("right")) + + C(P("top")) + + C(P("bottom")) + +local char = P("l") / "left" + + P("r") / "right" + + P("t") / "top" + + P("b") / "bottom" + +local space = P(" ")^0 + +local what = space + * (sign + Cc("0")) + * space + * (full + char) + * space + * (sign + Cc("0")) + * space + * (full + char) + * space + * P(-1) + +-- print(lpegmatch(what,"lr")) +-- print(lpegmatch(what,"+l+r")) +-- print(lpegmatch(what,"+l")) +-- print(lpegmatch(what,"+ left+r ")) + +local function process_connections(chart,xoffset,yoffset) + local data = chart.data + local hash = chart.hash + if not data then + return + end + local settings = chart.settings + for i=1,#data do + local cell = visible(chart,data[i]) + if cell then + local connections = cell.connections + for j=1,#connections do + local connection = connections[j] + local othername = connection.name + local othercell = hash[othername] + if othercell then -- and visible(chart,data[i]) then + local cellx, celly = cell.x, cell.y + local otherx, othery, location = othercell.x, othercell.y, connection.location + if otherx > 0 and othery > 0 and cellx > 0 and celly > 0 and connection.location then + local what_cell, where_cell, what_other, where_other = lpegmatch(what,location) + if what_cell and where_cell and what_other and where_other then + local linesettings = settings.line + context("flow_smooth := %s ;", linesettings.corner == v_round and "true" or "false") + context("flow_dashline := %s ;", linesettings.dash == v_yes and "true" or "false") + context("flow_arrowtip := %s ;", linesettings.arrow == v_yes and "true" or "false") + context("flow_touchshape := %s ;", linesettings.offset == v_none and "true" or "false") + context("flow_dsp_x := %s ; flow_dsp_y := %s ;",connection.dx or 0, connection.dy or 0) + context("flow_connection_line_color := \\MPcolor{%s} ;",linesettings.color) + context("flow_connection_line_width := %p ;",linesettings.rulethickness) + context("flow_connect_%s_%s (%s) (%s,%s,%s) (%s,%s,%s) ;",where_cell,where_other,j,cellx,celly,what_cell,otherx,othery,what_other) + context("flow_dsp_x := 0 ; flow_dsp_y := 0 ;") + end + end + end + end + end + end +end + +local texttemplate = "\\setvariables[flowcell:text][x=%s,y=%s,text={%s},align={%s},figure={%s},destination={%s}]" + +local splitter = lpeg.splitat(":") + +local function process_texts(chart,xoffset,yoffset) + local data = chart.data + local hash = chart.hash + if not data then + return + end + for i=1,#data do + local cell = visible(chart,data[i]) + if cell then + local x = cell.x or 1 + local y = cell.y or 1 + local texts = cell.texts + for i=1,#texts do + local text = texts[i] + local data = text.text + local align = validlabellocations[text.align or ""] or text.align or "" + local figure = i == 1 and cell.figure or "" + local destination = i == 1 and cell.destination or "" + context('flow_chart_draw_text(%s,%s,textext("%s")) ;',x,y,format(texttemplate,x,y,data,align,figure,destination)) + end + local labels = cell.labels + for i=1,#labels do + local label = labels[i] + local text = label.text + local location = validlabellocations[label.location or ""] or label.location or "" + if text and location then + context('flow_chart_draw_label(%s,%s,"%s",textext("\\strut %s")) ;',x,y,location,text) + end + end + local exits = cell.exits + for i=1,#exits do + local exit = exits[i] + local text = exit.text + local location = validlabellocations[exit.location or ""] + if text and location then + -- maybe make autoexit an option + if location == "l" and x == chart.from_x + 1 or + location == "r" and x == chart.to_x - 1 or + location == "t" and y == chart.to_y - 1 or + location == "b" and y == chart.from_y + 1 then + context('flow_chart_draw_exit(%s,%s,"%s",textext("\\strut %s")) ;',x,y,location,text) + end + end + end + local connections = cell.connections + for i=1,#connections do + local comments = connections[i].comments + for j=1,#comments do + local comment = comments[j] + local text = comment.text + local location = comment.location or "" + local length = 0 + -- "tl" "tl:*" "tl:0.5" + local loc, len = lpegmatch(splitter,location) -- do the following in lpeg + if len == "*" then + location = validcommentlocations[loc] or "" + if location == "" then + location = "*" + else + location = location .. ":*" + end + elseif loc then + location = validcommentlocations[loc] or "*" + length = tonumber(len) or 0 + else + location = validcommentlocations[location] or "" + end + if text and location then + context('flow_chart_draw_comment(%s,%s,%s,"%s",%s,textext("\\strut %s")) ;',x,y,i,location,length,text) + end + end + end + end + end +end + +local function getchart(settings,forced_x,forced_y,forced_nx,forced_ny) + if not settings then + print("no settings given") + return + end + local chartname = settings.chart.name + if not chartname then + print("no name given") + return + end + local chart = charts[chartname] + if not chart then + print("no such chart",chartname) + return + end +-- chart = table.copy(chart) + chart = expanded(chart,settings) + local chartsettings = chart.settings.chart + local autofocus = chart.settings.chart.autofocus + if autofocus then + autofocus = utilities.parsers.settings_to_hash(autofocus) + if not next(autofocus) then + autofocus = false + end + end + -- check natural window + local x = forced_x or tonumber(chartsettings.x) + local y = forced_y or tonumber(chartsettings.y) + local nx = forced_nx or tonumber(chartsettings.nx) + local ny = forced_ny or tonumber(chartsettings.ny) + -- + local minx, miny, maxx, maxy = 0, 0, 0, 0 + local data = chart.data + for i=1,#data do + local cell = data[i] + if not autofocus or autofocus[cell.name] then -- offsets probably interfere with autofocus + local x = cell.x + local y = cell.y + if minx == 0 or x < minx then minx = x end + if miny == 0 or y < miny then miny = y end + if minx == 0 or x > maxx then maxx = x end + if miny == 0 or y > maxy then maxy = y end + end + end + -- print("1>",x,y,nx,ny) + -- print("2>",minx, miny, maxx, maxy) + -- check of window should be larger (maybe autofocus + nx/ny?) + if autofocus then + -- x and y are ignored + if nx and nx > 0 then + maxx = minx + nx - 1 + end + if ny and ny > 0 then + maxy = miny + ny - 1 + end + else + if x and x > 0 then + minx = x + end + if y and y > 0 then + miny = y + end + if nx and nx > 0 then + maxx = minx + nx - 1 + end + if ny and ny > 0 then + maxy = miny + ny - 1 + end + end +-- print("3>",minx, miny, maxx, maxy) + -- + local nx = maxx - minx + 1 + local ny = maxy - miny + 1 + -- relocate cells + for i=1,#data do + local cell = data[i] + cell.x = cell.realx - minx + 1 + cell.y = cell.realy - miny + 1 + end + chart.from_x = 1 + chart.from_y = 1 + chart.to_x = nx + chart.to_y = ny + chart.nx = nx + chart.ny = ny + -- + chart.shift_x = minx + 1 + chart.shift_y = miny + 1 + -- + return chart +end + +local function makechart(chart) + local settings = chart.settings + local chartsettings = settings.chart + -- + context.begingroup() + context.forgetall() + -- + context.startMPcode() + context("if unknown context_flow : input mp-char.mpiv ; fi ;") + context("flow_begin_chart(0,%s,%s);",chart.nx,chart.ny) + -- + if chartsettings.option == v_test or chartsettings.dot == v_yes then + context("flow_show_con_points := true ;") + context("flow_show_mid_points := true ;") + context("flow_show_all_points := true ;") + elseif chartsettings.dot ~= "" then -- no checking done, private option + context("flow_show_%s_points := true ;",chartsettings.dot) + end + -- + local backgroundcolor = chartsettings.backgroundcolor + if backgroundcolor and backgroundcolor ~= "" then + context("flow_chart_background_color := \\MPcolor{%s} ;",backgroundcolor) + end + -- + local shapewidth = chartsettings.width + local gridwidth = shapewidth + 2*chartsettings.dx + local shapeheight = chartsettings.height + local gridheight = shapeheight + 2*chartsettings.dy + local chartoffset = chartsettings.offset + local labeloffset = chartsettings.labeloffset + local exitoffset = chartsettings.exitoffset + local commentoffset = chartsettings.commentoffset + context("flow_grid_width := %p ;", gridwidth) + context("flow_grid_height := %p ;", gridheight) + context("flow_shape_width := %p ;", shapewidth) + context("flow_shape_height := %p ;", shapeheight) + context("flow_chart_offset := %p ;", chartoffset) + context("flow_label_offset := %p ;", labeloffset) + context("flow_exit_offset := %p ;", exitoffset) + context("flow_comment_offset := %p ;", commentoffset) + -- + local radius = settings.line.radius + local rulethickness = settings.line.rulethickness + local dx = chartsettings.dx + local dy = chartsettings.dy + if radius < rulethickness then + radius = 2.5*rulethickness + if radius > dx then + radius = dx + end + if radius > dy then + radius = dy + end + end + context("flow_connection_line_width := %p ;", rulethickness) + context("flow_connection_smooth_size := %p ;", radius) + context("flow_connection_arrow_size := %p ;", radius) + context("flow_connection_dash_size := %p ;", radius) + -- + local offset = chartsettings.offset -- todo: pass string + if offset == v_none or offset == v_overlay or offset == "" then + offset = -2.5 * radius -- or rulethickness? + elseif offset == v_standard then + offset = radius -- or rulethickness? + end + context("flow_chart_offset := %p ;",offset) + -- + context("flow_reverse_y := true ;") + process_cells(chart,0,0) + process_connections(chart,0,0) + process_texts(chart,0,0) + -- context("clip_chart(%s,%s,%s,%s) ;",x,y,nx,ny) -- todo: draw lines but not shapes + context("flow_end_chart ;") + context.stopMPcode() + context.endgroup() +end + +local function splitchart(chart) + local settings = chart.settings + local splitsettings = settings.split + local chartsettings = settings.chart + -- + local name = chartsettings.name + -- + local from_x = chart.from_x + local from_y = chart.from_y + local to_x = chart.to_x + local to_y = chart.to_y + -- + local step_x = splitsettings.nx or to_x + local step_y = splitsettings.ny or to_y + local delta_x = splitsettings.dx or 0 + local delta_y = splitsettings.dy or 0 + -- + report_chart("spliting %a from (%s,%s) upto (%s,%s) with steps (%s,%s) and overlap (%s,%s)", + name,from_x,from_y,to_x,to_y,step_x,step_y,delta_x,delta_y) + -- + local part_x = 0 + local first_x = from_x + while true do + part_x = part_x + 1 + local last_x = first_x + step_x - 1 + local done = last_x >= to_x + if done then + last_x = to_x + end +-- if first_x >= to_x then +-- break +-- end + local part_y = 0 + local first_y = from_y + while true do + part_y = part_y + 1 + local last_y = first_y + step_y - 1 + local done = last_y >= to_y + if done then + last_y = to_y + end +-- if first_y >= to_y then +-- break +-- end + -- +local data = chart.data +for i=1,#data do + local cell = data[i] +-- inspect(cell) + local cx, cy = cell.x, cell.y + if cx >= first_x and cx <= last_x then + if cy >= first_y and cy <= last_y then + report_chart("part (%s,%s) of %a is split from (%s,%s) -> (%s,%s)",part_x,part_y,name,first_x,first_y,last_x,last_y) + local x = first_x + local y = first_y + local nx = last_x - first_x + 1 + local ny = last_y - first_y + 1 + context.beforeFLOWsplit() + context.handleFLOWsplit(function() + makechart(getchart(settings,x,y,nx,ny)) -- we need to pass frozen settings ! + end) + context.afterFLOWsplit() + break + end + end +end + -- + if done then + break + else + first_y = last_y + 1 - delta_y + end + end + if done then + break + else + first_x = last_x + 1 - delta_x + end + end +end + +function commands.flow_make_chart(settings) + local chart = getchart(settings) + if chart then + local settings = chart.settings + if settings then + local chartsettings = settings.chart + if chartsettings and chartsettings.split == v_yes then + splitchart(chart) + else + makechart(chart) + end + else + makechart(chart) + end + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-chart.mkvi b/Master/texmf-dist/tex/context/modules/mkiv/m-chart.mkvi new file mode 100644 index 00000000000..a0c8b2244a9 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-chart.mkvi @@ -0,0 +1,540 @@ +%D \module +%D [ file=m-chart, +%D version=2011.10.1, % 1998.10.10, +%D title=\CONTEXT\ Modules, +%D subtitle=Flow Charts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo (if used): +% flowsets +% autoscaling (bodyfontsteps) +% comment +% overlay +% +% todo: +% \useFLOWchart[name][parent][setting,setting][additional settings] +% \useFLOWchart[name][parent][additional settings] +% setups +% mp instance with less files + +\registerctxluafile{m-chart}{} + +\unprotect + +% todo: figure out a nice way to define the lot: share current and +% support current as name (nb: we need to set parent then) + +\installcorenamespace {flowchart} % \def\??flch{@@flch} % chart +\installcorenamespace {flowline} % \def\??flln{@@flln} % line +\installcorenamespace {flowshape} % \def\??flsh{@@flsh} % shape +\installcorenamespace {flowfocus} % \def\??flfc{@@flfc} % focus +\installcorenamespace {flowsets} % \def\??flst{@@flst} % sets +\installcorenamespace {flowsplit} % \def\??flsp{@@flsp} % split + +\installsimplecommandhandler \??flowchart {FLOWchart} \??flowchart % maybe just a setuphandler +\installsimplecommandhandler \??flowline {FLOWline} \??flowline % maybe just a setuphandler +\installsimplecommandhandler \??flowshape {FLOWshape} \??flowshape % maybe just a setuphandler +\installsimplecommandhandler \??flowfocus {FLOWfocus} \??flowfocus % maybe just a setuphandler +\installsimplecommandhandler \??flowsets {FLOWsets} \??flowsets % maybe just a setuphandler +\installsimplecommandhandler \??flowsplit {FLOWsplit} \??flowsplit % maybe just a setuphandler + +\let\setupFLOWcharts\setupFLOWchart +\let\setupFLOWlines \setupFLOWline +\let\setupFLOWshapes\setupFLOWshape +\let\setupFLOWsets \setupFLOWset + +\setupFLOWcharts + [\c!width=12\bodyfontsize, + \c!height=7\bodyfontsize, + \c!offset=\FLOWlineparameter\c!rulethickness, + \c!dx=2\bodyfontsize, + \c!dy=2\bodyfontsize, + \c!nx=0, + \c!ny=0, + \c!x=1, + \c!y=1, + \c!labeloffset=.5\bodyfontsize, + \c!commentoffset=.5\bodyfontsize, + \c!exitoffset=\zeropoint, + % \c!split=\v!no, + % \c!maxwidth=, + % \c!maxheight=, + % \c!option=, + % \c!bodyfont=, + % \c!dot=, % private option + % \c!autofocus=, + % \c!focus=, + % \c!background=, + % \c!framecolor= + % \c!backgroundcolor=, % \s!white + \c!rulethickness=.15\bodyfontsize, %\linewidth, + \c!frame=\v!off] + +\setupFLOWlines + [\c!corner=\v!round, + \c!arrow=\v!yes, + \c!dash=\v!no, + \c!radius=.375\bodyfontsize, + \c!color=FLOWlinecolor, + \c!rulethickness=.15\bodyfontsize, + \c!offset=\zeropoint] + +\setupFLOWshapes + [\c!default=action, + \c!framecolor=FLOWframecolor, + \c!background=\v!color, + \c!backgroundcolor=FLOWbackgroundcolor, + \c!rulethickness=.15\bodyfontsize, + \c!offset=.5\bodyfontsize] + +\setupFLOWfocus + [\c!framecolor=FLOWfocuscolor, + \c!background=\FLOWshapeparameter\c!background, + \c!backgroundcolor=\FLOWshapeparameter\c!backgroundcolor, + \c!rulethickness=\FLOWshapeparameter\c!rulethickness, + \c!offset=\FLOWshapeparameter\c!offset] + +\setupFLOWsplit + [\c!dx=0, + \c!dy=0, + % \c!command=, + % \c!before=, + % \c!after=, + \c!nx=3, + \c!ny=4] + +\unexpanded\def\beforeFLOWsplit{\FLOWsplitparameter\c!before} +\unexpanded\def\afterFLOWsplit {\FLOWsplitparameter\c!after} +\unexpanded\def\handleFLOWsplit{\FLOWsplitparameter\c!command} + +\definecolor [FLOWfocuscolor] [s=.2] +\definecolor [FLOWlinecolor] [s=.5] +\definecolor [FLOWframecolor] [s=.7] +\definecolor [FLOWbackgroundcolor] [s=.9] + +\newtoks\everyFLOWchart + +\unexpanded\def\module_charts_process[#name]% + {\ctxcommand{flow_start_chart("#name")}} + +\unexpanded\def\startFLOWchart + {\startnointerference + \the\everyFLOWchart + \dosingleempty\module_charts_start_chart} + +\unexpanded\def\module_charts_start_chart[#name]% + {\ctxcommand{flow_start_chart("#name")}} + +\unexpanded\def\stopFLOWchart + {\ctxcommand{flow_stop_chart()}% + \stopnointerference} + +\unexpanded\def\defineFLOWchart % for old times sake + {\dodoubleempty\module_charts_FLOW_define} + +\unexpanded\def\module_charts_FLOW_define[#name][#settings]#cells% todo: save settings + {\startnointerference + \the\everyFLOWchart + \ctxcommand{flow_start_chart("#name")}% + #cells% + \ctxcommand{flow_stop_chart()}% + \stopnointerference} + +\unexpanded\def\startFLOWcell + {\dodoubleempty\module_charts_start_cell} + +\unexpanded\def\module_charts_start_cell[#1][#2]% + {\begingroup + \iffirstargument + \setupFLOWshape[#1]% + \fi + \ifsecondargument + \setupFLOWline[#2]% + \fi + \ctxcommand{flow_start_cell { + shape = { + rulethickness = \number\dimexpr\FLOWshapeparameter\c!rulethickness, + default = "\FLOWshapeparameter\c!default", + framecolor = "\FLOWshapeparameter\c!framecolor", + backgroundcolor = "\FLOWshapeparameter\c!backgroundcolor", + }, + focus = { + rulethickness = \number\dimexpr\FLOWfocusparameter\c!rulethickness, + framecolor = "\FLOWfocusparameter\c!framecolor", + backgroundcolor = "\FLOWfocusparameter\c!backgroundcolor", + }, + line = { + rulethickness = \number\dimexpr\FLOWlineparameter\c!rulethickness, + radius = \number\dimexpr\FLOWlineparameter\c!radius, + color = "\FLOWlineparameter\c!color", + corner = "\FLOWlineparameter\c!corner", + dash = "\FLOWlineparameter\c!dash", + arrow = "\FLOWlineparameter\c!arrow", + offset = \number\dimexpr\FLOWlineparameter\c!offset, + }, + } }% + \endgroup} + +\unexpanded\def\stopFLOWcell + {\ctxcommand{flow_stop_cell()}} + +\unexpanded\def\FLOWchart + {\dodoubleempty\module_charts_process} + +\def\module_charts_process[#name][#settings]% + {\bgroup % \vbox removed + \insidefloattrue + \dontcomplain + \setupFLOWchart[#settings]% + \usebodyfontparameter\FLOWchartparameter + \ctxcommand{flow_make_chart { + chart = { + name = "#name", + option = "\FLOWchartparameter\c!option", + backgroundcolor = "\FLOWchartparameter\c!backgroundcolor", + width = \number\dimexpr\FLOWchartparameter\c!width, + height = \number\dimexpr\FLOWchartparameter\c!height, + dx = \number\dimexpr\FLOWchartparameter\c!dx, + dy = \number\dimexpr\FLOWchartparameter\c!dy, + offset = \number\dimexpr\FLOWchartparameter\c!offset, + % bodyfont = "\FLOWchartparameter\c!bodyfont", + dot = "\FLOWchartparameter\c!dot", % private option + hcompact = "\FLOWchartparameter\c!hcompact", % undocumented option + vcompact = "\FLOWchartparameter\c!vcompact", % undocumented option + focus = "\FLOWchartparameter\c!focus", + autofocus = "\FLOWchartparameter\c!autofocus", + nx = "\FLOWchartparameter\c!nx", + ny = "\FLOWchartparameter\c!ny", + x = "\FLOWchartparameter\c!x", + y = "\FLOWchartparameter\c!y", + labeloffset = \number\dimexpr\FLOWchartparameter\c!labeloffset, + commentoffset = \number\dimexpr\FLOWchartparameter\c!commentoffset, + exitoffset = \number\dimexpr\FLOWchartparameter\c!exitoffset, + split = "\FLOWchartparameter\c!split", + }, + shape = { + rulethickness = \number\dimexpr\FLOWshapeparameter\c!rulethickness, + default = "\FLOWshapeparameter\c!default", + framecolor = "\FLOWshapeparameter\c!framecolor", + backgroundcolor = "\FLOWshapeparameter\c!backgroundcolor", + }, + focus = { + rulethickness = \number\dimexpr\FLOWfocusparameter\c!rulethickness, + framecolor = "\FLOWfocusparameter\c!framecolor", + backgroundcolor = "\FLOWfocusparameter\c!backgroundcolor", + }, + line = { + rulethickness = \number\dimexpr\FLOWlineparameter\c!rulethickness, + radius = \number\dimexpr\FLOWlineparameter\c!radius, + color = "\FLOWlineparameter\c!color", + corner = "\FLOWlineparameter\c!corner", + dash = "\FLOWlineparameter\c!dash", + arrow = "\FLOWlineparameter\c!arrow", + offset = "\FLOWlineparameter\c!offset", + }, + set = { + }, + split = { + nx = \number\FLOWsplitparameter\c!nx, + ny = \number\FLOWsplitparameter\c!ny, + dx = \number\FLOWsplitparameter\c!dx, + dy = \number\FLOWsplitparameter\c!dy, + command = "", + marking = "\FLOWsplitparameter\c!marking", + before = "", + after = "", + } + } }% + \egroup} + +\unexpanded\def\FLOWcharts + {\dodoubleempty\FLOW_charts} + +\def\FLOW_charts[#name][#settings] + {\begingroup + \setupFLOWchart[\c!split=\v!yes]% + \setupFLOWsplit[#settings]% + \module_charts_process[#name][]% \FLOWchart... + \endgroup} + +\appendtoks + \let\name \FLOW_name + \let\shape \FLOW_shape + \let\destination\FLOW_destination + \let\focus \FLOW_focus + \let\overlay \FLOW_overlay + \let\location \FLOW_location + \let\text \FLOW_text + \let\label \FLOW_label + \let\comment \FLOW_comment + \let\exit \FLOW_exit + \let\connection \FLOW_connection + \let\include \FLOW_include + \let\figure \FLOW_figure + % + \let\connect \FLOW_connection + \let\locate \FLOW_location + % + \let\includeFLOWchart\include +\to \everyFLOWchart + +\unexpanded\def\FLOW_name #name{\ctxcommand{flow_set_name("#name")}\ignorespaces} +\unexpanded\def\FLOW_shape #shape{\ctxcommand{flow_set_shape("#shape")}\ignorespaces} +\unexpanded\def\FLOW_destination#destination{\ctxcommand{flow_set_destination("#destination")}\ignorespaces} +\unexpanded\def\FLOW_focus #focus{\ctxcommand{flow_set_focus("#focus")}\ignorespaces} +\unexpanded\def\FLOW_overlay #overlay{\ctxcommand{flow_set_overlay("#overlay")}\ignorespaces} +\unexpanded\def\FLOW_location #location{\ctxcommand{flow_set_location("#location")}\ignorespaces} +\unexpanded\def\FLOW_figure #figure{\ctxcommand{flow_set_figure("#figure")}\ignorespaces} + +\unexpanded\def\FLOW_text {\dosingleempty\module_charts_FLOW_text} +\unexpanded\def\FLOW_label {\dosingleempty\module_charts_FLOW_label} +\unexpanded\def\FLOW_comment {\dosingleempty\module_charts_FLOW_comment} +\unexpanded\def\FLOW_exit {\dosingleempty\module_charts_FLOW_exit} +\unexpanded\def\FLOW_connection{\dodoubleempty\module_charts_FLOW_connection} +\unexpanded\def\FLOW_include {\dodoubleempty\module_charts_FLOW_include} + +\unexpanded\def\module_charts_FLOW_text [#align]#text{\ctxcommand{flow_set_text("#align",\!!bs\detokenize{#text}\!!es)}\ignorespaces} +\unexpanded\def\module_charts_FLOW_label [#location]#text{\ctxcommand{flow_set_label("#location",\!!bs\detokenize{#text}\!!es)}\ignorespaces} +\unexpanded\def\module_charts_FLOW_comment [#location]#text{\ctxcommand{flow_set_comment("#location",\!!bs\detokenize{#text}\!!es)}\ignorespaces} +\unexpanded\def\module_charts_FLOW_exit [#location]#text{\ctxcommand{flow_set_exit("#location",\!!bs\detokenize{#text}\!!es)}\ignorespaces} +\unexpanded\def\module_charts_FLOW_connection[#location][#offset]#name{\ctxcommand{flow_set_connection("#location","#offset","#name")}\ignorespaces} + +\unexpanded\def\module_charts_FLOW_include [#name][#settings]{% + \begingroup + \getparameters[FLOWi][x=1,y=1,#settings]% + \ctxcommand{flow_set_include("#name",\number\FLOWix,\number\FLOWiy,\!!bs\detokenize{#settings}\!!es)}% + \endgroup + \ignorespaces +} + +\setvariables + [flowcell:text] + [x=1, + y=1, + text=, + align=, + set=\setups{flowcell:text:place}] + +\def\FLOWx{\getvariable{flowcell:text}{x}} % compatibility (for Willi) +\def\FLOWy{\getvariable{flowcell:text}{y}} % compatibility (for Willi) + +% \c!background={\@@FLOWbackground,\FLOWoverlay}, + +\defineoverlay + [flowcell:figure] + [\overlayfigure{\getvariable{flowcell:text}{figure}}] + +\startsetups flowcell:text:place + \begingroup + \iftrialtypesetting + \directsetup{flowcell:text:place:indeed} + \else \iflocation + \doifelsenothing {\getvariable{flowcell:text}{destination}} { + \directsetup{flowcell:text:place:indeed} + } { + % tricky: scaling and moving around is not taken into account + \setupinteraction[\c!color=,\c!contrastcolor=] + \gotobox{\directsetup{flowcell:text:place:indeed}}[\getvariable{flowcell:text}{destination}] + } + \else + \directsetup{flowcell:text:place:indeed} + \fi \fi + \endgroup +\stopsetups + +\startsetups flowcell:text:place:indeed + \begingroup + \directsetup{flowcell:text:user} + \doifelsenothing {\getvariable{flowcell:text}{figure}} { + \expandcheckedcsname{flowcell:}{\getvariable{flowcell:text}{align}}\empty + {\getvariable{flowcell:text}{text}} + } { + \expandcheckedcsname{flowcell:}{\getvariable{flowcell:text}{align}}\empty + [\c!background=flowcell:figure] + {\getvariable{flowcell:text}{text}} + } + \endgroup +\stopsetups + +\defineframed % to be discussed: shape or global + [flowcell:base] + [\c!offset=\v!overlay, % no strut ? + \c!frame=\FLOWchartparameter\c!frame, + \c!background=\FLOWchartparameter\c!background, + \c!backgroundcolor=\FLOWchartparameter\c!backgroundcolor, + %\c!foregroundcolor=\FLOWshapeparameter\c!foregroundcolor, + \c!align=\v!middle, + \c!bottom=\vfill, + \c!top=\vfill, + \c!width=\FLOWchartparameter\c!width, + \c!height=\FLOWchartparameter\c!height, + % \c!rulethickness=\FLOWchartparameter\c!rulethickness, + \c!rulethickness=\zeropoint, % comment for tracing + \c!framecolor=\FLOWchartparameter\c!framecolor] + +\defineframed[flowcell:] [flowcell:base] +\defineframed[flowcell:l] [flowcell:base][\c!align=\v!flushleft] +\defineframed[flowcell:r] [flowcell:base][\c!align=\v!flushright] +\defineframed[flowcell:m] [flowcell:base][\c!align=\v!middle] +\defineframed[flowcell:c] [flowcell:base][\c!align=\v!middle] + +\defineframed[flowcell:t] [flowcell:base][\c!top=] +\defineframed[flowcell:b] [flowcell:base][\c!bottom=] + +\defineframed[flowcell:lt][flowcell:base][\c!top=,\c!align=\v!flushleft] +\defineframed[flowcell:rt][flowcell:base][\c!top=,\c!align=\v!flushright] +\defineframed[flowcell:mt][flowcell:base][\c!top=,\c!align=\v!middle] +\defineframed[flowcell:ct][flowcell:base][\c!top=,\c!align=\v!middle] + +\defineframed[flowcell:lb][flowcell:base][\c!bottom=,\c!align=\v!flushleft] +\defineframed[flowcell:rb][flowcell:base][\c!bottom=,\c!align=\v!flushright] +\defineframed[flowcell:mb][flowcell:base][\c!bottom=,\c!align=\v!middle] +\defineframed[flowcell:cb][flowcell:base][\c!bottom=,\c!align=\v!middle] + +% \startsetups flowcell:text:user +% \setupframed +% [flowcell:base] +% [background=flowcell] +% \definelayer +% [flowcell] +% [width=\namedframedparameter{flowcell:base}{width}, +% height=\namedframedparameter{flowcell:base}{height}] +% \setlayerframed +% [flowcell] +% [preset=rightbottom,offset=-2.75ex] +% [frame=off] +% {\tx\FLOWx.\FLOWy} +% \stopsetups +% +% % or: +% +% \setupframed +% [flowcell:base] +% [background={flowcell-1,flowcell-2}] +% +% \defineoverlay +% [flowcell-1] +% [\directsetup{flowcell-1}] +% +% \definelayer +% [flowcell-2] +% [width=\overlaywidth, +% height=\overlayheight] +% +% \startsetups flowcell-1 +% \setlayerframed +% [flowcell-2] +% [preset=rightbottom,offset=-2.75ex] +% [frame=off] +% {\tx\FLOWx.\FLOWy} +% \stopsetups + +% %D \starttyping +% %D \setupFLOWsplit +% %D [nx=5,ny=10, +% %D dx=0,dy=0, +% %D before=, +% %D after=\page] +% %D +% %D \FLOWcharts[mybigflow] +% %D \stoptyping +% %D +% %D \starttyping +% %D \splitfloat +% %D {\placefigure{What a big flowchart this is!}} +% %D {\FLOWcharts[mybigflow]} +% %D \stoptyping + +% \setupFLOWsplit +% [nx=5, +% ny=8, +% dx=1, +% dy=1, +% command=\framed, +% before=\page, +% after=\page] +% +% \FLOWchart[demo] \page +% \FLOWchart[demo][split=yes] \page +% \FLOWchart[demo][x=1,y=1,nx=5,ny=8] \page +% \FLOWchart[demo][x=1,y=9,nx=5,ny=10] \page + +\protect + +\continueifinputfile{m-chart.mkvi} + +\input chrt-xml.tex + +\usemodule[abr-01] + +\setupFLOWcharts[option=test] +\setupFLOWcharts[frame=on] +\setupinteraction[state=start] + +% \setupFLOWcharts[dx=30pt,dy=30pt] + +\startMPinclusions + predefined_shapes[101] := fullcircle ; +\stopMPinclusions + +\startFLOWchart[demo] + \startFLOWcell[framecolor=darkgray] + \name {start} + \location {1,1} + \shape {action} + \text {start} + \connection [bl] {one} + \stopFLOWcell + \startFLOWcell[framecolor=darkred] + \name {one} +% \destination{CloseDocument} + \location {2,2} +% \shape {action} + \shape {101} + \text {first} +% \label [b] {\bfx bottom} + \connection [rt] {two} +% \exit [l] {exit l} +% \exit [r] {exit r} +% \exit [t] {exit t} +% \exit [b] {exit b} + \stopFLOWcell + \setupFLOWshapes[framecolor=darkgray] + \startFLOWcell % [foregroundcolor=white] + \name {two} +% \destination{CloseDocument} + \location {3,3} + \shape {action} + \text {second} + \figure {cow.pdf} +% \label [l] {\bfx left} +% \exit [l] {exit l} +% \exit [r] {exit r} +% \exit [t] {exit t} +% \exit [b] {exit b} + \stopFLOWcell +\stopFLOWchart + +\starttext + +\startTEXpage +% \FLOWchart[convert-en] +% \FLOWchart[conversion 1] +% \FLOWchart[conversion 7] +% \FLOWchart[conversion 9] +% \FLOWchart[conversion 10] + \FLOWchart[demo] + +\stopTEXpage + +\startTEXpage + \FLOWchart[conversion 10] +\stopTEXpage + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-chemic.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-chemic.mkiv new file mode 100644 index 00000000000..1dd403fae79 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-chemic.mkiv @@ -0,0 +1,20 @@ +%D \module +%D [ file=ppchtex (m-chemic), +%D version=1997.03.19, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PPCHTEX\ (Plain Pictex Context cHemie \TEX), +%D author=Hans Hagen, +%D date=\currentdate, +%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten}, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{ppchtex}{not loaded as support for chemistry in now built in} + +% \usemodule[pictex] % we will get rid of this +% \input ppchtex.mkiv \relax + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-cweb.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-cweb.mkiv new file mode 100644 index 00000000000..2546b2342f3 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-cweb.mkiv @@ -0,0 +1,1373 @@ +%D \module +%D [ file=m-cweb, +%D version=1997.01.15, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\CWEB\ Pretty Printing Macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module has to be redone in the mkiv way. + +%D First some auxiliary stuff, to be moved to system module. + +\def\dodofindfirstcharacter#1% + {\ifx#1\relax + \let\next=\egroup + \else + \handlecase + {\expandafter\ifnum\expandafter\catcode\expandafter`#1=11 + \def\next##1\relax{\egroup\def\firstcharacter{#1}}% + \fi}% + \fi + \next} + +\def\dofindfirstcharacter#1#2% + {\def\firstcharacter{}% + \bgroup + \defconvertedargument\ascii{#2}% + \let\next\dodofindfirstcharacter + \let\handlecase#1% + \expandafter\next\ascii\relax} + +\def\normalcase#1% + {#1} + +\def\findfirstcharacter% + {\dofindfirstcharacter\lowercase} + +\def\FindFirstCharacter% + {\dofindfirstcharacter\normalcase} + +\def\FINDFIRSTCHARACTER% + {\dofindfirstcharacter\uppercase} + +% nog doen: +% +% \deactivateCWEB in output routine +% status info +% gelinkte entries +% parskip en parindent + +%D \gdef\CWEBquote#1.{{\em Quote :}\ #1.} % checks the . + +%D This module (re)implements the \CWEB\ macros as defined in +%D the file \type{cwebmac.tex}. +%D +%D \CWEB\ uses short, often one character long, names for +%D macros. This is no real problem because no one is supposed +%D to read and understand the files generated by \CWEB. The +%D standard macros are meant for \PLAIN\ \TEX\ users. In +%D \CONTEXT\ and other macro packages however, there is a +%D potential conflict with format specific or user defined +%D commands. Furthermore, the \CWEB\ macros implement their own +%D output routines. When integrating \CWEB\ documents in +%D another environment, the \CWEB\ specific macros have to be +%D made local. The first part of this module is dedicated to +%D this feature. +%D +%D Instead of using \type{\def} and \type{\let} for defining +%D macros, we use: +%D +%D \starttyping +%D \defCEBmacro arguments {meaning} +%D \letCEBmacro arguments {meaning} +%D \stoptyping +%D +%D \CWEB files contain implicit calls to macros that generate +%D the table of contents, the lists of sections and the index. +%D Because we want to be much more flexible, we implemented our +%D own alternatives, and therefore have to bypass the original +%D ones. The next macro is used for defining these obsolete +%D \CWEB\ macros. The dummies take care of arguments. +%D +%D \starttyping +%D \defCEBdummy arguments {meaning} +%D \stoptyping +%D +%D The list of \CWEB\ specific macro names is saved in a +%D \TOKENLIST. This serves two purposes. First it enables us to +%D activate the \CWEB\ macros, which are saved under a +%D different name, second it can be used to temporary restore +%D the meanings, for instance when the output routine builds +%D the page. + +\newtoks\CWEBmacros + +%D Activating and deactivating is done by means of: +%D +%D \starttyping +%D \activateCWEB +%D \deactivateCWEB +%D \stoptyping +%D +%D Which are implemented as: + +\def\activateCWEB% + {\let\doCWEB=\activateCWEBmacro + \the\CWEBmacros} + +\def\deactivateCWEB% + {\let\doCWEB=\deactivateCWEBmacro + \the\CWEBmacros} + +%D The three definition macros append the name of the macro to +%D the list. The first two macros save the meaning, the last one +%D assigns \type{{}} to the macro and gobbles original meaning. + +\long\def\defCWEBmacro#1% + {\appendtoks\doCWEB#1\to\CWEBmacros + \setvalue{newCWEB\string#1}} + +\long\def\letCWEBmacro#1% + {\appendtoks\doCWEB#1\to\CWEBmacros + \letvalue{newCWEB\string#1}} + +\long\def\defCWEBdummy#1#2#% + {\appendtoks\doCWEB#1\to\CWEBmacros + \setvalue{newCWEB\string#1}#2{}% + \gobbleoneargument} + +%D The macro \type{\defCWEBdummy} of course takes care of the +%D argument. This leaves the two (de|)|activating macros: + +\def\CWEBmacro#1% + {\getvalue{newCWEB\string#1}} + +\def\activateCWEBmacro#1% + {\letvalue{oldCWEB\string#1}=#1% + \def#1{\CWEBmacro#1}} + +\def\deactivateCWEBmacro#1% + {\expandafter\let\expandafter#1\expandafter=\csname oldCWEB\string#1\endcsname} + +%D I did consider loading the \CWEB\ macros using temporary +%D substitutes of \type{\def}, \type{\font}, \type{\newbox} etc. +%D The main problem is that the file contains more than +%D definitions and taking all kind of assignments into account +%D too would not make things easier. So I decided to stick to +%D the method as just described. + +%D Now we're ready for the real job. What follows is a partial +%D adaption of the file \type{cwebmac.tex}, version 3.1, dated +%D September 1994 and written by Levy and Knuth. When possible +%D we kept the original meaning, but we've granted ourselves +%D the freedom to reformat the macro's for readibility. +%D +%D We'll only present the macros we actually use. The source +%D however contains the original implementation. + +% standard macros for CWEB listings (in addition to plain.tex) +% Version 3.1 --- September 1994. +% +% \ifx\documentstyle\undefined\else\endinput\fi % LaTeX will use other macros +% +% \xdef\fmtversion{\fmtversion+CWEB3.1} + +%D \macros{.}{} +%D +%D \CWEBquote preserve a way to get the dot accent (all +%D other accents will still work as usual). + +\letCWEBmacro\: = \. + +% \parskip = 0pt % no stretch between paragraphs +% \parindent = 1em % for paragraphs and for the first line of C text + +% \font\ninerm = cmr9 +% \let\mc = \ninerm % medium caps +% \font\eightrm = cmr8 +% \let\sc = \eightrm % small caps (NOT a caps-and-small-caps font) +% \let\mainfont = \tenrm +% \let\cmntfont = \tenrm +% \font\tenss = cmss10 +% \let\cmntfont = \tenss % alternative comment font +% \font\titlefont = cmr7 scaled \magstep4 % title on the contents page +% \font\ttitlefont = cmtt10 scaled \magstep2 % typewriter type in title +% \font\tentex = cmtex10 % TeX extended character set (used in strings) +% \fontextraspace\tentex = 0pt % no double space after sentences + +%D \macros{mc,sc,cmntfont,eightrm}{} +%D +%D The naming of the fonts in in line with those in \PLAIN\ +%D \TEX. Although \CONTEXT\ implements its own scheme, there is +%D still support for the \PLAIN\ ones. We keep the original +%D names, but change their meaning. That way the macros obey +%D switching to other sizes or styles. + +\defCWEBmacro\mc {\tx} +\defCWEBmacro\sc {\txx} +\defCWEBmacro\cmntfont {\ss} +\defCWEBmacro\eightrm {\tx} + +%D \macros{tentex,sevenrm,sevensy,teni}{} +%D +%D The next one uses a temporary solution. The \type{cmtex10} +%D font is not part of the default mechanism. We make use of +%D the \CONTEXT\ variables \type{\textface}, \type{\scriptface} +%D and \type{\scriptscriptface}, which hold the current +%D sizes. + +\defCWEBmacro\tentex% + {\font\next=cmtex10 at \textface + \fontextraspace\next\zeropoint + \next} + +\defCWEBmacro\sevenrm {\getvalue{\scriptface rmtf}} +\defCWEBmacro\sevensy {\getvalue{\scriptface mmsy}} +\defCWEBmacro\teni {\getvalue{\textface mmmi}} + +%D \macros{CWEBpt}{} +%D +%D The original macros are based on a 10~point bodyfont size. We +%D therefore have to specify dimension in points a bit +%D different. Specifications like .6pt are changed to +%D \type{.06} times \type{\bodyfontsize}. + +\defCWEBmacro\CWEBpt {\bodyfontsize} % still dutch + +%D \macros{CEE,UNIX,TEX,CPLUSPLUS}{} +%D +%D Next come some logo's. It does not make much sense to use +%D the \CONTEXT\ logo mechanism here, so we simply say: + +\defCWEBmacro \CEE/{{\mc C\spacefactor1000}} +\defCWEBmacro \UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}} +\defCWEBmacro \TEX/{\TeX} +\defCWEBmacro\CPLUSPLUS/{{\mc C\PP\spacefactor1000}} +\defCWEBmacro \Cee{\CEE/} % for backward compatibility + +%D \macros{\ }{} +%D +%D Now we come to the real work: the short commands that make +%D up the typography. +%D +%D \CWEBquote italic type for identifiers. + +\defCWEBmacro\\#1% + {\leavevmode\hbox{\it#1\/\kern.05em}} + +%D \macros{\string|}{} +%D +%D \CWEBquote one letter identifiers look better this way. + +\defCWEBmacro\|#1% + {\leavevmode\hbox{$#1$}} + +%D \macros{\string\&}{} +%D +%D \CWEBquote boldface type for reserved words. + +\defCWEBmacro\% + {\leavevmode + \hbox + {\def\_% + {\kern.04em + \vbox{\hrule width.3em height .06\CWEBpt}% .6pt}% + \kern.08em}% + \bf#1\/\kern.05em}} + +%D \macros{.}{} +%D +%D Here we use the previously saved period. This macro +%D takes care of special characters in strings. + +\defCWEBmacro\.#1% + {\leavevmode + \hbox + {\tentex % typewriter type for strings + \let\\=\BS % backslash in a string + \let\{=\LB % left brace in a string + \let\}=\RB % right brace in a string + \let\~=\TL % tilde in a string + \let\ =\SP % space in a string + \let\_=\UL % underline in a string + \let\&=\AM % ampersand in a string + \let\^=\CF % circumflex in a string + #1\kern.05em}} + +%D \macros{)}{} +%D +%D Some discretionary hack. + +\defCWEBmacro\)% + {\discretionary{\hbox{\tentex\BS}}{}{}} + +%D \macros{AT}{} +%D +%D \CWEBquote at sign for control text (not needed in versions +%D $>=$ 2.9). + +\defCWEBmacro\AT{@} + +%D \macros{ATL,postATL,NOATL}{} +%D +%D A two step macro that handles whatever. + +\defCWEBmacro\ATL% + {\par + \noindent + \bgroup + \catcode`\_=12 + \postATL} + +\defCWEBmacro\postATL#1 #2 % + {\bf letter \\{\uppercase{\char"#1}} tangles as \tentex "#2"% + \egroup + \par} + +\defCWEBmacro\noATL#1 #2 % + {} + +%D \macros{noatl}{} +%D +%D \CWEBquote suppress output from \type{@l}. + +\defCWEBmacro\noatl% + {\let\ATL=\noATL} + +% \defCWEBmacro\ATH% +% {\X\kern-.5em:Preprocessor definitions\X} + +%D \macros{PB} +%D +%D \CWEBquote hook for program brackets {\tttf\string|...\string|} +%D in TeX part or section name. + +\defCWEBmacro\PB% + {\relax} + +% \chardef\AM = `\& % ampersand character in a string +% \chardef\BS = `\\ % backslash in a string +% \chardef\LB = `\{ % left brace in a string +% \chardef\RB = `\} % right brace in a string +% \chardef\TL = `\~ % tilde in a string +% \chardef\UL = `\_ % underline character in a string +% \chardef\CF = `\^ % circumflex character in a string + +\defCWEBmacro\AM {\char`\&} % ampersand character in a string +\defCWEBmacro\BS {\char`\\} % backslash in a string +\defCWEBmacro\LB {\char`\{} % left brace in a string +\defCWEBmacro\RB {\char`\}} % right brace in a string +\defCWEBmacro\TL {\char`\~} % tilde in a string +\defCWEBmacro\UL {\char`\_} % underline character in a string +\defCWEBmacro\CF {\char`\^} % circumflex character in a string + +\defCWEBmacro\SP {{\tt\char`\ }} % (visible) space in a string + +% \newbox\PPbox \setbox\PPbox=\hbox +% {\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt} +% \newbox\MMbox \setbox\MMbox=\hbox +% {\kern.5pt\raise1pt\hbox{\sevensy\char0\kern-1pt\char0}\kern.5pt} +% \newbox\MGbox \setbox\MGbox=\hbox % symbol for -> +% {\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt} +% \newbox\MODbox \setbox\MODbox=\hbox +% {\eightrm\%} +% +% \def\PP {\copy\PPbox} +% \def\MM {\copy\MMbox} +% \def\MG {\copy\MGbox} +% \def\MOD {\mathbin{\copy\MODbox}} + +\defCWEBmacro\PP% symbol for ++ + {\kern.05\CWEBpt + \raise.1\CWEBpt\hbox{\sevenrm+\kern-.1\CWEBpt+}% + \kern.05\CWEBpt} + +\defCWEBmacro\MM% + {\kern.05\CWEBpt + \raise.1\CWEBpt\hbox{\sevensy\char0\kern-.1\CWEBpt\char0}% + \kern.05\CWEBpt} + +\defCWEBmacro\MG% + {\kern-.2\CWEBpt + \lower.3\CWEBpt\hbox{\teni\char'176}% + \kern .1\CWEBpt} + +\defCWEBmacro\MRL#1% + {\mathrel{\let\K==#1}} + +% \def\MRL#1% +% {\KK#1} +% \def\KK#1#2% +% {\buildrel\;#1\over{#2}} + +\letCWEBmacro\GG = \gg +\letCWEBmacro\LL = \ll +\letCWEBmacro\NULL = \Lambda + +% \mathchardef\AND = "2026 % bitwise and; also \& (unary operator) + +\defCWEBmacro\AND% redefines itself (funny) + {\mathchardef\AND="2026 \AND} % bitwise and; also \& (unary operator) + +\letCWEBmacro\OR = \mid % bitwise or +\letCWEBmacro\XOR = \oplus % bitwise exclusive or +\defCWEBmacro\CM {{\sim}} % bitwise complement +\defCWEBmacro\MOD {\mathbin{\eightrm\%}} +\defCWEBmacro\DC {\kern.1em{::}\kern.1em} % symbol for :: +\defCWEBmacro\PA {\mathbin{.*}} % symbol for .* +\defCWEBmacro\MGA {\mathbin{\MG*}} % symbol for ->* +\defCWEBmacro\this {\&{this}} + +% \newbox \bak % backspace one em +% \newbox \bakk % backspace two ems +% +% \setbox\bak =\hbox to -1em{} +% \setbox\bakk=\hbox to -2em{} + +\newcount\CWEBind % current indentation in ems + +\defCWEBmacro\1% indent one more notch + {\global\advance\CWEBind by 1 + \hangindent\CWEBind em} + +\defCWEBmacro\2% indent one less notch + {\global\advance\CWEBind by -1 } + +\defCWEBmacro\3#1% optional break within a statement + {\hfil + \penalty#10 + \hfilneg} + +\defCWEBmacro\4% backspace one notch + {\hbox to -1em{}} + +\defCWEBmacro\5% optional break + {\hfil + \penalty-1 + \hfilneg + \kern2.5em + \hbox to -2em{}% + \ignorespaces} + +\defCWEBmacro\6% forced break + {\ifmmode + \else + \par + \hangindent\CWEBind em + \noindent + \kern\CWEBind em + \hbox to -2em{}% + \ignorespaces + \fi} + +\defCWEBmacro\7% forced break and a little extra space + {\Y + \6} + +\defCWEBmacro\8% no indentation + {\hskip-\CWEBind em + \hskip 2em} + +\defCWEBmacro\9#1% + {} + +\newcount\gdepth % depth of current major group, plus one +\newcount\secpagedepth +\secpagedepth=3 % page breaks will occur for depths -1, 0, and 1 + +% \newtoks\gtitle % title of current major group +% \newskip\intersecskip +% \intersecskip=12pt minus 3pt % space between sections + +% \let\yskip=\smallskip + +\defCWEBmacro\?% + {\mathrel?} + +% \def\note#1#2.% +% {\Y\noindent +% {\hangindent2em\baselineskip10pt\eightrm#1~#2.\par}} + +\defCWEBmacro\lapstar% + {\rlap{*}} + +% \def\stsec% +% {\rightskip=0pt % get out of C mode (cf. \B) +% \sfcode`;=1500 +% \pretolerance 200 +% \hyphenpenalty 50 +% \exhyphenpenalty 50 +% \noindent{\let\*=\lapstar\bf\secstar.\quad}} +% +% \let\startsection=\stsec + +\defCWEBmacro\defin#1% + {\global\advance\CWEBind by 2 \1\&{#1 } } % begin `define' or `format' + +% \def\A% xref for doubly defined section name +% {\note{See also section}} +% +% \def\As% xref for multiply defined section name +% {\note{See also sections}} + +\defCWEBmacro\B% + {\rightskip=0pt plus 100pt minus 10pt % go into C mode + \sfcode`;=3000 + \pretolerance 10000 + \hyphenpenalty 1000 % so strings can be broken (discretionary \ is inserted) + \exhyphenpenalty 10000 + \global\CWEBind=2 \1\ \unskip} + +\defCWEBmacro\C#1% + {\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$} + +% \let\SHC\C % "// short comments" treated like "/* ordinary comments */" + +\defCWEBmacro\SHC#1% + {\5\5\quad$//\,${\cmntfont#1}} + +% \def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$} +% \def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}} + +\defCWEBmacro\D% macro definition + {\defin{\#define}} + +\letCWEBmacro\E=\equiv % equivalence sign + +% \def\ET% conjunction between two section numbers +% { and~} +% +% \def\ETs% conjunction between the last two of several section numbers +% {, and~} + +\defCWEBmacro\F% format definition + {\defin{format}} + +\letCWEBmacro\G = \ge % greater than or equal sign + +% \H is long Hungarian umlaut accent + +\letCWEBmacro\I = \ne % unequal sign + +\defCWEBmacro\J% TANGLE's join operation + {\.{@\&}} + +% \let\K== % assignment operator + +\letCWEBmacro\K = \leftarrow % "honest" alternative to standard assignment operator + +% \L is Polish letter suppressed-L + +% \outer\def\M#1% +% {\MN{#1}% +% \ifon +% \vfil +% \penalty-100 +% \vfilneg % beginning of section +% \vskip\intersecskip +% \startsection +% \ignorespaces} +% +% \outer\def\N#1#2#3.% +% {\gdepth=#1% +% \gtitle={#3}% +% \MN{#2}% beginning of starred section +% \ifon +% \ifnum#1<\secpagedepth +% \vfil +% \eject % force page break if depth is small +% \else +% \vfil +% \penalty-100 +% \vfilneg +% \vskip\intersecskip +% \fi +% \fi +% \message{*\secno}% progress report +% \edef\next% +% {\write\cont % write to contents file +% {\ZZ{#3}{#1}{\secno}{\noexpand\the\pageno}}}% +% \next % \ZZ{title}{depth}{sec}{page} +% \ifon +% \startsection +% {\bf#3.\quad}% +% \ignorespaces} +% +% \def\MN#1% +% {\par % common code for \M, \N +% {\xdef\secstar{#1}% +% \let\*=\empty +% \xdef\secno{#1}}% remove \* from section name +% \ifx\secno\secstar +% \onmaybe +% \else +% \ontrue +% \fi +% \mark{{{\tensy x}\secno}{\the\gdepth}{\the\gtitle}}} +% +% each \mark is {section reference or null}{depth plus 1}{group title} + +% \O is Scandinavian letter O-with-slash +% \P is paragraph sign + +\defCWEBmacro\Q {\note{This code is cited in section}} % xref for mention of a section +\defCWEBmacro\Qs {\note{This code is cited in sections}} % xref for mentions of a section + +% \S is section sign + +\defCWEBmacro\T#1% + {\leavevmode % octal, hex or decimal constant + \hbox + {$\def\?{\kern.2em}% + \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant + \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick) + \let\~=\oct + \let\^=\hex + {#1}$}} + +\defCWEBmacro\U {\note{This code is used in section}} % xref for use of a section +\defCWEBmacro\Us {\note{This code is used in sections}} % xref for uses of a section + +\letCWEBmacro\R = \lnot % logical not +\letCWEBmacro\V = \lor % logical or +\letCWEBmacro\W = \land % logical and + +% defined later on +% +% \def\X#1:#2\X% +% {\ifmmode +% \gdef\XX{\null$\null}% +% \else +% \gdef\XX{}% +% \fi % section name +% \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX} + +\unprotect + +\def\theCWEByskip {\blank[\v!small]} +\def\theCWEBvskip {\blank[\v!big]} + +\protect + +\defCWEBmacro\Y% + {\par + \yskip} + +\defCWEBmacro\yskip% + {\theCWEByskip} + +\letCWEBmacro\Z = \le +% \letCWEBmacro\ZZ = \let % now you can \write the control sequence \ZZ +\letCWEBmacro\* = * + +\defCWEBmacro\oct% + {\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}} + +\defCWEBmacro\hex% + {\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} + +\defCWEBmacro\vb#1% + {\leavevmode + \hbox + {\kern.2\CWEBpt + \vrule + \vtop + {\vbox + {\hrule + \hbox{\strut\kern.2\CWEBpt\.{#1}\kern.2\CWEBpt}} + \hrule}% + \vrule + \kern.2\CWEBpt}} % verbatim string + +\def\onmaybe% + {\let\ifon=\maybe} + +\let\maybe=\iftrue + +\newif\ifon + +% \newif\iftitle +% \newif\ifpagesaved +% +% \def\lheader% +% {\mainfont +% \the\pageno +% \eightrm +% \qquad +% \grouptitle +% \hfill +% \title +% \qquad +% \mainfont +% \topsecno} % top line on left-hand pages +% +% \def\rheader% +% {\mainfont +% \topsecno +% \eightrm +% \qquad +% \title +% \hfill +% \grouptitle +% \qquad +% \mainfont +% \the\pageno} % top line on right-hand pages +% +% \def\grouptitle +% {\let\i=I +% \let\j=J +% \uppercase\expandafter{\expandafter\takethree\topmark}} +% +% \def\topsecno% +% {\expandafter\takeone\topmark} +% +% \def\takeone #1#2#3{#1} +% \def\taketwo #1#2#3{#2} +% \def\takethree #1#2#3{#3} +% +% \def\nullsec% +% {\eightrm +% \kern-2em} % the \kern-2em cancels \qquad in headers +% +% \let\page=\pagebody % \def\page {\box255 } +% \raggedbottom % \normalbottom % faster, but loses plain TeX footnotes +% +% \def\normaloutput#1#2#3% +% {\shipout\vbox +% {\ifodd +% \pageno +% \hoffset=\pageshift +% \fi +% \vbox to \fullpageheight +% {\iftitle +% \global\titlefalse +% \else +% \hbox to \pagewidth +% {\vbox to 10pt{}% +% \ifodd\pageno #3\else#2\fi} +% \fi +% \vfill#1}} % parameter #1 is the page itself +% \global\advance\pageno by 1} +% +% \gtitle={\.{CWEB} output} % this running head is reset by starred sections +% +% \mark{\noexpand\nullsec0{\the\gtitle}} +% +% \def\title% +% {\expandafter\uppercase\expandafter{\jobname}} +% +% \def\topofcontents% +% {\centerline{\titlefont\title} +% \vskip.7in +% \vfill} % this material will start the table of contents page + +\def\botofcontents% + {\vfill + \centerline{\covernote}} % this material will end the table of contents page + +\def\covernote% + {} + +% some leftover + +\defCWEBmacro\contentspagenumber{0} % default page number for table of contents + +% \newdimen\pagewidth \pagewidth = 158mm % the width of each page +% \newdimen\pageheight \pageheight = 223mm % the height of each page +% \newdimen\fullpageheight \fullpageheight = 240mm % page height including headlines +% \newdimen\pageshift \pageshift = 0in % shift righthand pages wrt lefthand ones +% +% \def\magnify#1% +% {\mag=#1 +% \pagewidth=6.5truein +% \pageheight=8.7truein +% \fullpageheight=9truein +% \setpage} +% +% \def\setpage% +% {\hsize\pagewidth +% \vsize\pageheight} % use after changing page size +% +% \def\contentsfile {\jobname.toc} % file that gets table of contents info +% \def\readcontents {\input \contentsfile} +% \def\readindex {\input \jobname.idx} +% \def\readsections {\input \jobname.scn} +% +% \newwrite\cont +% \output{\setbox0=\page % the first page is garbage +% \openout\cont=\contentsfile +% \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter +% \global\output{\normaloutput\page\lheader\rheader}} +% \setpage +% \vbox to \vsize{} % the first \topmark won't be null + +\defCWEBdummy\magnify#1% magnify the page + {} + +\defCWEBmacro\ch% + {\note{The following sections were changed by the change file:} + \let\*=\relax} + +% \newbox\sbox % saved box preceding the index +% \newbox\lbox % lefthand column in the index +% +% \def\inx% +% {\par\vskip6pt plus 1fil % we are beginning the index +% \def\page{\box255 } +% \normalbottom +% \write\cont{} % ensure that the contents file isn't empty +% \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother +% \closeout\cont % the contents information has been fully gathered +% \output +% {\ifpagesaved +% \normaloutput{\box\sbox}\lheader\rheader +% \fi +% \global\setbox\sbox=\page +% \global\pagesavedtrue} +% \pagesavedfalse +% \eject % eject the page-so-far and predecessors +% \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box +% \vsize=\pageheight +% \advance\vsize by -\ht\sbox % the remaining height +% \hsize=.5\pagewidth +% \advance\hsize by -10pt +% % column width for the index (20pt between cols) +% \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines +% \def\lr{L} % this tells whether the left or right column is next +% \output +% {\if L\lr +% \global\setbox\lbox=\page +% \gdef\lr{R} +% \else +% \normaloutput +% {\vbox to\pageheight +% {\box\sbox +% \vss +% \hbox to\pagewidth{\box\lbox\hfil\page}}} +% \lheader +% \rheader +% \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi} +% \message{Index:} +% \parskip 0pt plus .5pt +% \outer\def\I##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry +% \def\[##1]{$\underline{##1}$} % underlined index item +% \rm +% \rightskip0pt plus 2.5em +% \tolerance 10000 +% \let\*=\lapstar +% \hyphenpenalty 10000 +% \parindent0pt +% \readindex} +% +% \def\fin% +% {\par\vfill\eject % this is done when we are ending the index +% \ifpagesaved\null\vfill\eject\fi % output a null index column +% \if L\lr\else\null\vfill\eject\fi % finish the current page +% \parfillskip 0pt plus 1fil +% \def\grouptitle{NAMES OF THE SECTIONS} +% \let\topsecno=\nullsec +% \message{Section names:} +% \output={\normaloutput\page\lheader\rheader} +% \setpage +% \def\note##1##2.{\quad{\eightrm##1~##2.}} +% \def\Q{\note{Cited in section}} % crossref for mention of a section +% \def\Qs{\note{Cited in sections}} % crossref for mentions of a section +% \def\U{\note{Used in section}} % crossref for use of a section +% \def\Us{\note{Used in sections}} % crossref for uses of a section +% \def\I{\par\hangindent 2em}\let\*=* +% \readsections} +% +% \def\con% +% {\par\vfill\eject % finish the section names +% %\ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers +% \rightskip = 0pt +% \hyphenpenalty = 50 +% \tolerance = 200 +% \setpage +% \output={\normaloutput\page\lheader\rheader} +% \titletrue % prepare to output the table of contents +% \pageno=\contentspagenumber +% \def\grouptitle{TABLE OF CONTENTS} +% \message{Table of contents:} +% \topofcontents +% \line{\hfil Section\hbox to3em{\hss Page}} +% \let\ZZ=\contentsline +% \readcontents\relax % read the contents info +% \botofcontents +% \end} % print the contents page(s) and terminate +% +% \def\contentsline#1#2#3#4% +% {\ifnum#2=0 +% \smallbreak +% \fi +% \line{\consetup{#2}#1 +% \rm\leaders\hbox to .5em{.\hfil}\hfil\ #3\hbox to3em{\hss#4}}} +% + +\defCWEBmacro\consetup#1% + {\ifcase#1 \bf % depth -1 (@**) + \or % depth 0 (@*) + \or \hskip2em % depth 1 (@*1) + \or \hskip4em % depth 2 (@*2) + \or \hskip6em % depth 3 (@*3) + \or \hskip8em % depth 4 (@*4) + \or \hskip10em % depth 5 (@*5) + \else \hskip12em + \fi} % depth 6 or more + +\defCWEBdummy \inx {} % index +\defCWEBdummy \fin {} % finish +\defCWEBdummy \con {} % table of contents and finish + +\defCWEBdummy \noinx {} % no indexes or table of contents +\defCWEBdummy \nosecs {} % no index of section names or table of contents +\defCWEBdummy \nocon {} % no table of contents + +\defCWEBmacro\,% + {\relax + \ifmmode + \mskip\thinmuskip + \else + \thinspace + \fi} + +% \def\noinx% +% {\let\inx=\end} +% +% \def\nosecs% +% {\let\FIN=\fin +% \def\fin% +% {\let\parfillskip=\end +% \FIN}} +% +% \def\nocon% +% {\let\con=\end} +% +% \newcount\twodigits +% +% \def\hours% +% {\twodigits=\time +% \divide\twodigits by 60 +% \printtwodigits +% \multiply\twodigits by -60 +% \advance\twodigits by \time +% :\printtwodigits} +% +% \def\gobbleone1{} +% +% \def\printtwodigits% +% {\advance\twodigits by 100 +% \expandafter\gobbleone\number\twodigits +% \advance\twodigits by -100 } +% +% \def\today% +% {\ifcase\month +% \or January\or February\or March\or April\or May\or June% +% \or July\or August\or September\or October\or November\or December% +% \fi +% \space +% \number\day, \number\year} +% +% \def\datethis% +% {\def\startsection% +% {\leftline{\sc\today\ at \hours} +% \bigskip +% \let\startsection=\stsec +% \stsec}} +% +% \def\datecontentspage% +% {\def\topofcontents% +% {\leftline{\sc\today\ at \hours} +% \bigskip +% \centerline{\titlefont\title} +% \vfill}} + +\defCWEBdummy\datethis {} % say `\datethis' in limbo, to get your listing timestamped before section 1 +\defCWEBdummy\datecontentspage {} % timestamps the contents page + +\defCWEBmacro\TeX% + {{\ifmmode\it\fi + \leavevmode + \hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}} + +% alternative implementation + +\newif\ifCWEBnotes + +\defCWEBmacro\Q {\CWEBnotesfalse \note{This code is cited in section}} % xref for mention of a section +\defCWEBmacro\Qs {\CWEBnotestrue \note{This code is cited in sections}} % xref for mentions of a section + +\defCWEBmacro\U {\CWEBnotesfalse \note{This code is used in section}} % xref for use of a section +\defCWEBmacro\Us {\CWEBnotestrue \note{This code is used in sections}} % xref for uses of a section + +\defCWEBmacro\A {\CWEBnotesfalse \note{See also section}} % xref for doubly defined section name +\defCWEBmacro\As {\CWEBnotestrue \note{See also sections}} % xref for multiply defined section name + +\defCWEBmacro\ET% conjunction between two section numbers + { and~} + +\defCWEBmacro\ETs% conjunction between the last two of several section numbers + {, and~} + +%\def\processCWEBsectionnumbers[#1]% +% {\bgroup +% \def\CWEBcomma% +% {\def\CWEBcomma{, }}% +% \def\docommand##1% +% {\bgroup +% \def\[####1]{####1}% +% \xdef\CWEBreference{##1}% +% \egroup +% \CWEBcomma{\naar{\donottest{##1}}[web:\CWEBreference]}}% +% \processcommalist[{#1}]\docommand +% \egroup} + +% \def\processCWEBsectionnumbers[#1]% +% {\bgroup +% \def\CWEBcomma% +% {\def\CWEBcomma{, }}% +% \def\docommand##1% +% {\bgroup +% \def\(####1){####1}% +% \xdef\CWEBreference{##1}% +% \egroup +% \CWEBcomma +% {\localcolortrue\naar{\donottest{##1}}[web:\CWEBreference]}}% +% \bgroup +% \def\[##1]{\(##1)}\let\(=\relax\xdef\CWEBreferences{#1}% +% \egroup +% \unexpanded\def\(##1){\[##1]}% +% \processcommacommand[\CWEBreferences]\docommand +% \egroup} + +\def\processCWEBsectionnumbers[#1]% + {\bgroup + \def\CWEBcomma% + {\def\CWEBcomma{, }}% + \def\docommand##1% + {\bgroup + \def\[####1]{####1}% + \xdef\CWEBreference{##1}% + \egroup + \CWEBcomma{\localcolortrue\goto{\donottest{##1}}[web:\CWEBreference]}}% + \processlist{(}{)}{,}\docommand(#1) + \egroup} + +\def\processCWEBsectionnotes% + {\catcode`\s=12 + \doprocessCWEBsectionnotes} + +\def\doprocessCWEBsectionnotes#1.% + {\ifCWEBnotes + \def\next##1\ET##2##3.% + {\processCWEBsectionnumbers[##1]% + \if##2s% + {, and~\goto{##3}[web:##3]}% + \else + { and~\goto{##2##3}[web:##2##3]}% + \fi}% + \next#1.% + \else + \goto{#1}[web:#1]% + \fi + \afterCWEBnote % inside group! + \egroup} + +\let\afterCWEBnote=\relax + +\defCWEBmacro\note#1% + {\bgroup + \Y\noindent + \def\afterCWEBnote{\par}% + \hangindent2em + %\baselineskip10pt + \eightrm#1~\processCWEBsectionnotes} + +\def\oldCWEBmacroX#1:#2\X% original + {\ifmmode + \gdef\XX{\null$\null}% + \else + \gdef\XX{}% + \fi % section name + \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX} + +\defCWEBmacro\ATH% + {\oldCWEBmacroX\kern-.5em:Preprocessor definitions\X} + +\def\newCWEBmacroX#1:#2\X% original + {\ifmmode + \gdef\XX{\null$\null}% + \else + \gdef\XX{}% + \fi % section name + \XX$\langle\,$% + {#2\eightrm\kern.5em\processCWEBsectionnumbers[{#1}]}% + $\,\rangle$\XX} + +\defCWEBmacro\X#1:#2\X% + {\newCWEBmacroX#1:#2\X} + +\definemarking[CWEBfilename] +\definemarking[CWEBsectiontitle] +\definemarking[CWEBsectionnumber] +\definemarking[CWEBsectiondepth] + +\defCWEBmacro\M#1% + {\MN{#1}% + \ifon + \vfil + \penalty-100 + \vfilneg % beginning of section + \theCWEBvskip + \startsection + \pagereference[web:#1]% + \expanded{\marking[CWEBsectionnumber]{\secno}}% + \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}% + \ignorespaces} + +\defCWEBmacro\N#1#2#3.% + {\gdepth=#1% + \MN{#2}% beginning of starred section + \ifon + \ifnum#1<\secpagedepth + \vfil + \eject % force page break if depth is small + \else + \vfil + \penalty-100 + \vfilneg + \theCWEBvskip + \fi + \fi + \message{*\secno}% progress report + \makesectionformat % context + \defconvertedargument\ascii{#3}% + \edef\next% + {\write\CWEBcont % write to contents file + {\string\ZZ{\ascii}{#1}{\secno}% + {\sectionformat::\noexpand\userfolio}{\noexpand\realfolio}}}% + \next % \ZZ{title}{depth}{sec}{page} + \ifon + \startsection + \pagereference[web:#2]% + \marking[CWEBsectiontitle] {#3}% + \expanded{\marking[CWEBsectionnumber]{\secno}}% + \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}% + {\bf#3.\quad}% + \ignorespaces} + +\defCWEBmacro\MN#1% + {\par % common code for \M, \N + {\xdef\secstar{#1}% + \let\*=\empty + \xdef\secno{#1}}% remove \* from section name + \ifx\secno\secstar + \onmaybe + \else + \ontrue + \fi} + +\newif\iflinktoCWEBfile + +\def\setCWEBlinkfile#1% + {\linktoCWEBfiletrue + \def\otherCWEBfile{#1}} + +\unprotect + +\def\gotoCWEBsection#1[#2]% + {\iflinktoCWEBfile + \bgroup + \setupinteraction[\c!color=,\c!style=]% + \let\savedreferenceprefix=\referenceprefix + \localcolortrue + \goto{#1}[\otherCWEBfile::\savedreferenceprefix web:#2]% + \egroup + \else + #1% + \fi} + +\protect + +\defCWEBmacro\startsection% + {\rightskip=0pt % get out of C mode (cf. \B) + \sfcode`;=1500 + \pretolerance 200 + \hyphenpenalty 50 + \exhyphenpenalty 50 + \noindent + \bgroup + \let\*=\lapstar + \gotoCWEBsection{\bf\secstar.\quad}[\secno]% + \egroup} + +\def\ignoreCWEBinput% + {\let\normalinput=\input + \def\input ##1 % + {\let\input=\normalinput}} + +\def\loadCWEBmacros#1% + {\let\oldN=\N + \def\N{\bgroup\setbox0=\vbox\bgroup\endinput}% + \ignoreCWEBinput + \ReadFile{#1.tex}% + \egroup\egroup + \let\N=\oldN} + +\def\resetCWEBcontext% + {\catcode`\|=12 % used in context discretionaries + \everypar{} % used for context indentation and floats + \parskip=0pt % no stretch between cweb paragraphs + \parindent=1em} % is related to cweb backspace etc + +\newwrite\CWEBcont + +\def\processCWEBsource #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \ignoreCWEBinput + \immediate\openout\CWEBcont=#1.toc + \write\CWEBcont{\noexpand\unprotect} + \message{Source:} + \marking[CWEBfilename]{#1} + \ReadFile{#1.tex}\relax + \write\CWEBcont{\noexpand\protect} + \closeout\CWEBcont + \par + \egroup} + +\def\resetCWEBindexentry% + {\xdef\currentCWEBindexentry{}} + +\def\showCWEBindexentry#1% can be redefined + {\theCWEBvskip + \vskip3\lineheight + \goodbreak + \vskip-3\lineheight + {\pagereference[web:#1]\bf#1}% + \theCWEBvskip} + +\def\checkCWEBindexentry#1% + {\bgroup + \def\\##1{##1}% a dummy that also removes the {} + \def\|##1{##1}% another dummy + \def\.##1{*##1}% and another (the typewriter one) + \def\&##1{##1}% and a last one + \def\9##1{##1}% hold this one + \catcode`*=11 + \expandafter\def\expandafter\entry\expandafter{#1}% + \defconvertedcommand\ascii\entry + \expanded{\FINDFIRSTCHARACTER{\ascii}}% + \doifnot{\currentCWEBindexentry}{\firstcharacter} + {\doifnot{\firstcharacter}{*} % signal for \firstbunch + {\global\let\currentCWEBindexentry=\firstcharacter + \showCWEBindexentry{\currentCWEBindexentry}}}% + \egroup} + +\def\theCWEBbeforeindex {\startcolumns} +\def\theCWEBafterindex {\stopcolumns} + +\def\processCWEBindex #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \resetCWEBindexentry + \def\I##1, % + {\par + \checkCWEBindexentry{##1}% + \hangindent2em + \noindent##1:\kern1em% + \def\next####1.% + {\processCWEBsectionnumbers[{####1}]}% + \next}% + \def\[##1]% + {$\underline{##1}$}% + \let\*=\lapstar + \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines +% \parskip 0pt plus .5pt + \rightskip0pt plus 2.5em + \tolerance 10000 + \hyphenpenalty 10000 + \parindent0pt + \message{Index:} + \marking[CWEBfilename] {#1} + \marking[CWEBsectiontitle] {index} + \marking[CWEBsectionnumber]{} + \marking[CWEBsectiondepth]{} + \loadCWEBmacros{#1} + \theCWEBbeforeindex + \ReadFile{#1.idx}\relax + \theCWEBafterindex + \par + \egroup} + +\def\processCWEBsections #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \loadCWEBmacros{#1} + \parfillskip = 0pt plus 1fil + \parindent = 0pt + \let\topsecno=\nullsec + \def\note##1% + {\quad + \bgroup + \eightrm + ##1~\processCWEBsectionnotes} + \def\Q {\CWEBnotesfalse \note{Cited in section}} % crossref for mention of a section + \def\Qs{\CWEBnotestrue \note{Cited in sections}} % crossref for mentions of a section + \def\U {\CWEBnotesfalse \note{Used in section}} % crossref for use of a section + \def\Us{\CWEBnotestrue \note{Used in sections}} % crossref for uses of a section + \def\I {\par\hangindent 2em}% + \let\*=* + \message{Section names:} + \marking[CWEBfilename] {#1} + \marking[CWEBsectiontitle] {sections} + \marking[CWEBsectionnumber]{} + \marking[CWEBsectiondepth]{} + \loadCWEBmacros{#1} + \ReadFile{#1.scn}\relax + \par + \botofcontents + \par + \egroup} + +\def\processCWEBcontents #1 % + {\bgroup + \resetCWEBcontext + \activateCWEB + \loadCWEBmacros{#1} + \rightskip = 0pt + \hyphenpenalty = 50 + \tolerance = 200 + \parindent = 0pt + \line{\hfil Section\hbox to3em{\hss Page}} + \let\ZZ=\contentsline + \message{Table of contents:} + \marking[CWEBfilename] {#1} + \marking[CWEBsectiontitle] {table of contents} + \marking[CWEBsectionnumber]{} + \marking[CWEBsectiondepth]{} + \loadCWEBmacros{#1} + \ReadFile{#1.toc}\relax + \par + \egroup} + +\defCWEBmacro\contentsline#1#2#3#4#5% + {\ifnum#2=0 + \smallbreak + \fi + \line{\consetup{#2}#1 + \rm + \leaders\hbox to .5em{.\hfil}\hfil\ + {\localcolortrue\goto{#3}[web:#3]}% below: \gotorealpage ? should be changed + \hbox to3em{\localcolortrue\hss\gotorealpage{}{}{#5}{\translatednumber[#4]\presetgoto}}}} + +%D A last hack, needed because a file can overload of the +%D above. (Some day: a check like \type{\ifx#1\CWEBdefined}.) + +\def\outer#1#2% + {\ifx#2\undefined + \expandafter#1\expandafter#2% + \else + \expandafter#1\expandafter\ThrowAway + \fi} + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-database.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-database.lua new file mode 100644 index 00000000000..91e9636eeb0 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-database.lua @@ -0,0 +1,132 @@ +if not modules then modules = { } end modules ['m-database'] = { + version = 1.001, + comment = "companion to m-database.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local sub, gmatch = string.sub, string.gmatch +local concat = table.concat +local lpegpatterns, lpegmatch, lpegsplitat = lpeg.patterns, lpeg.match, lpeg.splitat +local lpegP, lpegC, lpegS, lpegCt, lpegCc, lpegCs = lpeg.P, lpeg.C, lpeg.S, lpeg.Ct, lpeg.Cc, lpeg.Cs +local stripstring = string.strip + +moduledata.database = moduledata.database or { } +moduledata.database.csv = moduledata.database.csv or { } + +-- One also needs to enable context.trace, here we only plug in some code (maybe +-- some day this tracker will also toggle the main context tracer. + +local trace_flush = false trackers.register("module.database.flush", function(v) trace_flush = v end) +local report_database = logs.reporter("database") + +local context = context + +local l_tab = lpegpatterns.tab +local l_space = lpegpatterns.space +local l_comma = lpegpatterns.comma +local l_empty = lpegS("\t\n\r ")^0 * lpegP(-1) + +local v_yes = interfaces.variables.yes + +local separators = { -- not interfaced + tab = l_tab, + tabs = l_tab^1, + comma = l_comma, + space = l_space, + spaces = l_space^1, +} + +function moduledata.database.csv.process(settings) + local data + if settings.type == "file" then + local filename = resolvers.finders.byscheme("any",settings.database) + data = filename ~= "" and io.loaddata(filename) + data = data and string.splitlines(data) + else + data = buffers.getlines(settings.database) + end + if data and #data > 0 then + local catcodes = tonumber(settings.catcodes) or tex.catcodetable + context.pushcatcodes(catcodes) + if trace_flush then + context.pushlogger(report_database) + end + local separatorchar, quotechar, commentchar = settings.separator, settings.quotechar, settings.commentchar + local before, after = settings.before or "", settings.after or "" + local first, last = settings.first or "", settings.last or "" + local left, right = settings.left or "", settings.right or "" + local setups = settings.setups or "" + local strip = settings.strip == v_yes or false + local command = settings.command or "" + separatorchar = (not separatorchar and ",") or separators[separatorchar] or separatorchar + local separator = type(separatorchar) == "string" and lpegS(separatorchar) or separatorchar + local whatever = lpegC((1 - separator)^0) + if quotechar and quotechar ~= "" then + local quotedata = nil + for chr in gmatch(quotechar,".") do + local quotechar = lpegP(chr) + local quoteword = lpegCs(((l_space^0 * quotechar)/"") * (1 - quotechar)^0 * ((quotechar * l_space^0)/"")) + if quotedata then + quotedata = quotedata + quoteword + else + quotedata = quoteword + end + end + whatever = quotedata + whatever + end + local checker = commentchar ~= "" and lpegS(commentchar) + if strip then + whatever = whatever / stripstring + end + if left ~= "" then + whatever = lpegCc(left) * whatever + end + if right ~= "" then + whatever = whatever * lpegCc(right) + end + if command ~= "" then + whatever = lpegCc("{") * whatever * lpegCc("}") + end + whatever = whatever * (separator/"" * whatever)^0 + if first ~= "" then + whatever = lpegCc(first) * whatever + end + if last ~= "" then + whatever = whatever * lpegCc(last) + end + if command ~= "" then + whatever = lpegCs(lpegCc(command) * whatever) + else + whatever = lpegCs(whatever) + end + local found = false + for i=1,#data do + local line = data[i] + if not lpegmatch(l_empty,line) and (not checker or not lpegmatch(checker,line)) then + if not found then + if setups ~= "" then + context.begingroup() + context.setups { setups } + end + context(before) + found = true + end + context(lpegmatch(whatever,line)) + end + end + if found then + context(after) + if setups ~= "" then + context.endgroup() + end + end + context.popcatcodes() + if trace_flush then + context.poplogger() + end + else + -- message + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-database.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-database.mkiv new file mode 100644 index 00000000000..cc7dd3d7207 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-database.mkiv @@ -0,0 +1,211 @@ +%D \module +%D [ file=m-database, +%D version=2010.08.04, +%D title=\CONTEXT\ Modules, +%D subtitle=Database Thingies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] + +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D For Mojca. + +\registerctxluafile{m-database}{1.001} + +\unprotect + +\definenamespace + [db] + [type=module, + comment=database module, + version=1, + name=database, + parent=db, + setup=yes, + command=yes] + +\setupdatabase + [\c!separator={,}, + \c!quotechar=, + \c!commentchar=, + \c!strip=\v!no, + \c!before=, + \c!after=, + \c!first=, + \c!last=, + \c!left=, + \c!right=] + +% \let\currentdatabase\empty \the\everypresetdatabase % or just: + +\setupdatabase + [\c!separator={,}] + +\def\module_database_process#1#2#3% + {\edef\currentdatabasetype{#1}% + \edef\currentdatabase {#2}% + \edef\currentdatabasename{#3}% + \ifx\currentdatabasename\empty + \let\currentdatabasename\currentdatabase + \let\currentdatabase\empty + \fi + \ctxlua{moduledata.database.csv.process { + name = "\currentdatabase", + type = "\currentdatabasetype", + database = "\currentdatabasename", + strip = "\databaseparameter\c!strip", + separator = \!!bs\databaseparameter\c!separator \!!es, + quotechar = \!!bs\databaseparameter\c!quotechar \!!es, + commentchar = \!!bs\databaseparameter\c!commentchar\!!es, + setups = \!!bs\databaseparameter\c!setups \!!es, + before = \!!bs\databaseparameter\c!before \!!es, + after = \!!bs\databaseparameter\c!after \!!es, + first = \!!bs\databaseparameter\c!first \!!es, + last = \!!bs\databaseparameter\c!last \!!es, + left = \!!bs\databaseparameter\c!left \!!es, + right = \!!bs\databaseparameter\c!right \!!es, + command = \!!bs\databaseparameter\c!command \!!es, + catcodes = \number\catcodetable + }}} + +\unexpanded\def\processdatabasebuffer{\dodoubleempty\module_database_process_buffer} +\unexpanded\def\processdatabasefile {\dodoubleempty\module_database_process_file} + +\def\module_database_process_buffer[#1][#2]{\module_database_process{buffer}{#1}{#2}} +\def\module_database_process_file [#1][#2]{\module_database_process{file} {#1}{#2}} + +% for old times sake: + +\unexpanded\def\defineseparatedlist {\dodoubleempty\module_database_separated_list_define} +\unexpanded\def\processseparatedfile{\dodoubleempty\module_database_separated_list_process} + +\def\module_database_separated_list_define[#1][#2]% + {\definedatabase[#1][#2]% + \setuvalue{\e!start#1}{\grabbufferdatadirect{#1}{\e!start#1}{\e!stop#1}}% + \setuvalue{\e!stop#1}{\processdatabasebuffer[#1][#1]}} + +\def\module_database_separated_list_process[#1][#2]% + {\processdatabasefile[#1][#2]} + +\unexpanded\def\startseparatedlist[#1]% to be interfaced + {\unexpanded\def\stopseparatedlist{\processdatabasebuffer[#1][#1]}% + \grabbufferdatadirect{#1}{startseparatedlist}{stopseparatedlist}} + +\let\setupseparatedlist\setupdatabase + +\protect + +\continueifinputfile{m-database.mkiv} + +\starttext + +% m-database.txt +% +% 1,2,3,4,5 +% 6,7,8,"9,x",0 +% A,B,C,D +% E,,F +% G + +\definedatabase[test] + +\setupdatabase + [test] + [separator={,}, + quotechar={"}, + before={<}, + after={>}, + first={\endgraf[}, + last={]\endgraf}, + left={ (}, + right={) }] + +\startbuffer[testbuffer] +1,2,3,4,5 +6,7,8,"9,x",0 +A,B,C,D +E,,F +G +\stopbuffer + +\processdatabasebuffer[test][testbuffer] + +\processdatabasefile[test][m-database.txt] + +\defineseparatedlist + [CSV] + [separator={,}, + before=\bTABLE,after=\eTABLE, + first=\bTR,last=\eTR, + left=\bTD,right=\eTD] + +% \startseparatedlist[CSV] +% a,b,c +% d,e,f +% \stopseparatedlist + +\startCSV +a,b,c +d,e,f +\stopCSV + +\defineseparatedlist + [CSV] + [separator={,+},quotechar={"'},commentchar=\letterhash, + before={\starttabulate[|l|l|l|]},after=\stoptabulate, + first=\NC,last=\NR, + left=,right=\NC] + +\startCSV +#a,b,"c,d" +a,b,"c,d" +a,'b,c',d +"a,b"+c+d +\stopCSV + +\defineseparatedlist + [CSV] + [separator=space, + first=\NC,last=\NR, + left=,right=\NC, + before={\starttabulate[|l|l|l|]},after=\stoptabulate] + +\startCSV +a b c +d e f +\stopCSV + +\startsetups csv:unix + \catcode\hashasciicode\commentcatcode +\stopsetups + +\defineseparatedlist + [CSV] + [setups=csv:unix, + separator={,}, + first=\NC,last=\NR, + left=,right=\NC, + before={\starttabulate[|l|l|l|]},after=\stoptabulate] + +\processseparatedfile[CSV][m-database.txt] + +\defineseparatedlist[CSV] + [separator=comma, + before=\bTABLE, after=\eTABLE, + first=\bTR, last=\eTR, + left=\bTD, right=\eTD] + +\startCSV +a,b,c,Ä +d,e,f,Å¡ +\stopCSV + +\startseparatedlist[CSV] +a,b,c,Ä +d,e,f,Å¡ +\stopseparatedlist + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-directives.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-directives.mkiv new file mode 100644 index 00000000000..8b551b27abd --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-directives.mkiv @@ -0,0 +1,3 @@ +\starttext + \showdirectives +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-educat.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-educat.mkiv new file mode 100644 index 00000000000..93b1a6c5db3 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-educat.mkiv @@ -0,0 +1,217 @@ +%D \module +%D [ file=m-educat, +%D version=2003.03.05, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Educational Extras, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module will collect a few macros cq.\ definitions +%D meant for educational use. Most of the code has been laying +%D around for some time and has been (or is still) used in +%D \PRAGMA\ projects. + +\unprotect + +\definesystemvariable{iv} + +\definecolor [answerareacolor] [s=.90] +\definecolor [answerlinecolor] [white] + +\definetextbackground + [\v!answerarea] + [\c!location=\v!text, + \c!n=0, + \c!frame=\v!off, + \c!framecolor=answerlinecolor, + \c!rulethickness=2pt, + \c!background=\v!color, + \c!backgroundcolor=answerareacolor, + \c!alternative=2] % betweenline + +% n=gedwongen +% m=extra auto + +\def\setupanswerarea + {\setuptextbackground[\v!answerarea]} + +\setvalue\e!answerspace + {\dosingleempty\doanswerspace} + +\def\doanswerspace[#1]% + {\begingroup + \dontcomplain + \setupanswerarea + [\c!n=0,\c!m=,#1,\c!location=\v!text]% + \doifelsenothing{\textbackgroundparameter\c!m} + {\expandafter\donoanswerspace} + {\expandafter\dodoanswerspace}% + [#1]} + +\def\donoanswerspace[#1]#2% + {\setupthinrules + [\c!alternative=\textbackgroundparameter\c!alternative, + \c!color=\textbackgroundparameter\c!framecolor, + \c!background=\textbackgroundparameter\c!background, + \c!backgroundcolor=\textbackgroundparameter\c!backgroundcolor, + \c!rulethickness=\textbackgroundparameter\c!rulethickness]% + \doifelse{\textbackgroundparameter\c!n}{*} + {\thinrule + \par} + {\scratchcounter0\textbackgroundparameter\c!n\relax + % tricky, guess + \def\processisolatedword##1% + {\setbox\scratchbox=\hbox{##1}% + \vbox{\hsize\wd\scratchbox\thinrule + \ifcase\scratchcounter\else + \setbox\scratchbox=\hbox{\space}% + \nobreak\hskip\zeropoint \!!minus \wd\scratchbox + \vbox{\hsize\wd\scratchbox\thinrule}% + \fi}}% + \processisolatedwords{#2}\processisolatedword + % so far + \ifcase\scratchcounter \else \ifnum\scratchcounter<3 + \nobreak \vbox{\hsize\scratchcounter em\thinrule}% + \else % more + \advance \scratchcounter -2 + \dorecurse\scratchcounter{\allowbreak\vbox{\hsize1em\thinrule}}% + \nobreak \vbox{\hsize2em\thinrule}% + \fi \fi}% + \endgroup} + +\def\dodoanswerspace[#1]#2% m case + {\getvalue{\e!start\v!answerarea}% + #2% + \doifelse{\textbackgroundparameter\c!m}{*} + {\hfill\strut + \getvalue{\e!stop\v!answerarea}% + \par} + {\scratchcounter0\textbackgroundparameter\c!m\relax + \ifcase\scratchcounter \else \ifnum\scratchcounter<3 + \nobreak \hbox to \scratchcounter em{\strut\hss}% + \else % more + \advance \scratchcounter -2 + \dorecurse\scratchcounter{\allowbreak\hbox to 1em{\strut\hss}}% + \nobreak \hbox to 2em{\strut\hss}% + \fi \fi + \getvalue{\e!stop\v!answerarea}}% + \endgroup} + +\setvalue{\e!start\e!answerlines}% + {\dosingleempty\dostartanswerlines} + +\def\dostartanswerlines[#1]% + {\begingroup + \dontcomplain + \setupanswerarea + [\c!n=0,\c!m=,#1,\c!location=\v!text]% + \doifnot{\textbackgroundparameter\c!option}\v!joinedup\softbreak + \doifelsenothing{\textbackgroundparameter\c!m} + {\expandafter\donostartanswerlines} + {\expandafter\dodostartanswerlines}% + [#1]} + +\def\donostartanswerlines[#1]% + {\setupthinrules + [\c!alternative=\textbackgroundparameter\c!alternative, + \c!color=\textbackgroundparameter\c!framecolor, + \c!background=\textbackgroundparameter\c!background, + \c!backgroundcolor=\textbackgroundparameter\c!backgroundcolor, + \c!rulethickness=\textbackgroundparameter\c!rulethickness]% + \thinrules[\c!n=\textbackgroundparameter\c!n]\par + \endgroup + \grabuntil{\e!stop\e!answerlines}} + +\def\dodostartanswerlines[#1]% + {\begingroup + \getvalue{\e!start\v!answerarea}% + \ignorespaces} + +\setvalue{\e!stop\e!answerlines}% + {\scratchcounter0\textbackgroundparameter\c!m\relax + % a \softbreak is more efficient in pos dan \par + \ifcase\scratchcounter + % nothing + \or + \softbreak + \else + \softbreak + \advance \scratchcounter \minusone + \dorecurse\scratchcounter{\strut\hfill\strut\softbreak}% + \fi + \strut\hfill\strut + \getvalue{\e!stop\v!answerarea}% + \par\endgroup\endgroup} + +\setvalue\e!answerlines + {\dosingleempty\doanswerlines} + +\def\doanswerlines[#1]#2% + {\getvalue{\e!start\e!answerlines}[#1]% + #2% + \getvalue{\e!stop\e!answerlines}} + +\protect \doifnotmode{demo}{\endinput} + +%D Test materiaal. + +\starttext + +\startnotmode[answers] + + \setupanswerarea[level=+1] + +\stopnotmode + +\setupcolors[state=start] + +test test test \answerspace [n=10] {Whow}. test test test +test tets test test \answerspace [n=10] {Whow}. test test +test test tets test test \answerspace [n=10] {Whow}. test +test test test tets test test \answerspace [n=10] {Whow}. +test test test test test test \answerspace [n=*] {Whow.} + +test test test test test test test \startanswerlines +[n=3] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[n=3,alternative=0] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[n=3,alternative=1] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[n=3,alternative=2] What A Junk Answer \stopanswerlines + +\startitemize[paragraph] +\item \startanswerlines [option=seried,n=2] xxx \stopanswerlines +\stopitemize + +test test test \answerspace [m=10] {Whow}. test test test +test tets test test \answerspace [m=10] {Whow}. test test +test test tets test test \answerspace [m=10] {Whow}. test +test test test tets test test \answerspace [m=10] {Whow}. +test test test test test test \answerspace [m=*] {Whow.} + +test test test test test test test \startanswerlines +[m=2] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[m=2,alternative=0] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[m=2,alternative=1] What A Junk Answer \stopanswerlines + +test test test test test test test \startanswerlines +[m=2,alternative=2] What A Junk Answer \stopanswerlines + +\startitemize[paragraph] +\item \startanswerlines [option=seried,m=2] xxx \stopanswerlines +\stopitemize + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-escrito.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-escrito.lua new file mode 100644 index 00000000000..0d7a04741d4 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-escrito.lua @@ -0,0 +1,7088 @@ +if not modules then modules = { } end modules ['m-escrito'] = { + version = 1.001, + comment = "companion to m-escrito.mkiv", + author = "Taco Hoekwater (BitText) and Hans Hagen (PRAGMA-ADE)", + license = "see below and context related readme files" +} + +-- This file is derived from Taco's escrito interpreter. Because the project was +-- more or less stopped, after some chatting we decided to preserve the result +-- and make it useable in ConTeXt. Hans went over all code, fixed a couple of +-- things, messed other things, made the code more efficient, wrapped all in +-- some helpers. So, a diff between the original and this file is depressingly +-- large. This means that you shouldn't bother Taco with the side effects (better +-- or worse) that result from this. + +-- Fonts need some work and I will do that when needed. I might cook up something +-- similar to what we do with MetaFun. First I need to run into a use case. After +-- all, this whole exercise is just that: getting an idea of what processing PS +-- code involves. + +-- Here is the usual copyright blabla: +-- +-- Copyright 2010 Taco Hoekwater <taco@luatex.org>. All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without modification, +-- are permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, this +-- list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright notice, this +-- list of conditions and the following disclaimer in the documentation and/or +-- other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR +-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +-- SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +-- OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +-- DAMAGE. + +-- We use a couple of do..ends later on because this rather large file has too many +-- locals otherwise. Possible optimizations are using insert/remove and getting rid +-- of the VM calls (in direct mode they are no-ops anyway). We can also share some +-- more code here and there. + +local type, unpack, tonumber, tostring, next = type, unpack, tonumber, tostring, next + +local format = string.format +local gmatch = string.gmatch +local match = string.match +local sub = string.sub +local char = string.char +local byte = string.byte + +local insert = table.insert +local remove = table.remove +local concat = table.concat +local reverse = table.reverse + +local abs = math.abs +local ceil = math.ceil +local floor = math.floor +local sin = math.sin +local cos = math.cos +local rad = math.rad +local sqrt = math.sqrt +local atan2 = math.atan2 +local tan = math.tan +local deg = math.deg +local pow = math.pow +local log = math.log +local log10 = math.log10 +local random = math.random +local setranseed = math.randomseed + +local bitand = bit32.band +local bitor = bit32.bor +local bitxor = bit32.bxor +local bitrshift = bit32.rshift +local bitlshift = bit32.lshift + +local lpegmatch = lpeg.match +local Ct, Cc, Cs, Cp, C, R, S, P, V = lpeg.Ct, lpeg.Cc, lpeg.Cs, lpeg.Cp, lpeg.C, lpeg.R, lpeg.S, lpeg.P, lpeg.V + +local formatters = string.formatters +local setmetatableindex = table.setmetatableindex + +-- Namespace + +-- HH: Here we assume just one session. If needed we can support more (just a matter +-- of push/pop) but it makes the code more complex and less efficient too. + +escrito = { } + +----- escrito = escrito +local initializers = { } +local devices = { } +local specials + +local DEBUG = false -- these will become trackers if needed +local INITDEBUG = false -- these will become trackers if needed +local MAX_INT = 0x7FFFFFFF -- we could have slightly larger ints because lua internally uses doubles + +initializers[#initializers+1] = function(reset) + if reset then + specials = nil + else + specials = { } + end +end + +local devicename +local device + +-- "boundingbox", +-- "randomseed", + +-- Composite objects +-- +-- Arrays, dicts and strings are stored in VM. To do this, VM is an integer-indexed table. This appears +-- a bit silly in lua because we are actually just emulating a C implementation detail (pointers) but it +-- is documented behavior. There is also supposed to be a VM stack, but I will worry about that when it +-- becomes time to implement save/restore. (TH) + +local VM -- todo: just a hash + +initializers[#initializers+1] = function() + VM = { } +end + +local directvm = true + +local add_VM, get_VM + +if directvm then -- if ok then we remove the functions + + add_VM = function(a) + return a + end + get_VM = function(i) + return i + end + +else + + add_VM = function(a) + local n = #VM + 1 + VM[n] = a + return n + end + + get_VM = function(i) + return VM[i] + end + +end + +-- Execution stack + +local execstack +local execstackptr +local do_exec +local next_object +local stopped + +initializers[#initializers+1] = function() + execstack = { } + execstackptr = 0 + stopped = false +end + +local function pop_execstack() + if execstackptr > 0 then + local value = execstack[execstackptr] + execstackptr = execstackptr - 1 + return value + else + return nil -- stackunderflow + end +end + +local function push_execstack(v) + execstackptr = execstackptr + 1 + execstack[execstackptr] = v +end + +-- Operand stack +-- +-- Most operand and exec stack entries are four-item arrays: +-- +-- [1] = "[integer|real|boolean|name|mark|null|save|font]" (a postscript interpreter type) +-- [2] = "[unlimited|read-only|execute-only|noaccess]" +-- [3] = "[executable|literal]" (exec attribute) +-- [4] = value (a VM index inthe case of names) +-- +-- But there are some exceptions. +-- +-- Dictionaries save the access attribute inside the value +-- +-- [1] = "dict" +-- [2] = irrelevant +-- [3] = "[executable|literal]" +-- [4] = value (a VM index) +-- +-- Operators have a fifth item: +-- +-- [1] = "operator" +-- [2] = "[unlimited|read-only|execute-only|noaccess]" +-- [3] = "[executable|literal]" +-- [4] = value +-- [5] = identifier (the operator name) +-- +-- Strings and files have a fifth and a sixth item, the fifth of which is +-- only relevant if the exec attribute is 'executable': +-- +-- [1] = "[string|file]" +-- [2] = "[unlimited|read-only|execute-only|noaccess]" +-- [3] = "[executable|literal]" +-- [4] = value (a VM index) (for input files, this holds the whole file) +-- [5] = exec-index +-- [6] = length +-- [7] = iomode (for files only) +-- [8] = filehandle (for files only) +-- +-- Arrays also have a seven items, the fifth is only relevant if +-- the exec attribute is 'executable', and the seventh is used to differentiate +-- between direct and indirect interpreter views of the object. +-- +-- [1] = "array" +-- [2] = "[unlimited|read-only|execute-only|noaccess]" +-- [3] = "[executable|literal]" +-- [4] = value (a VM index) +-- [5] = exec-index +-- [6] = length (a VM index) +-- [7] = "[d|i]" (direct vs. indirect) +-- +-- The exec stack also has an object with [1] == ".stopped", which is used +-- for "stopped" execution contexts + +local opstack +local opstackptr + +initializers[#initializers+1] = function() + opstack = { } + opstackptr = 0 +end + +local function pop_opstack() + if opstackptr > 0 then + local value = opstack[opstackptr] + opstackptr = opstackptr - 1 + return value + else + return nil -- stackunderflow + end +end + +local function push_opstack(v) + opstackptr = opstackptr + 1 + opstack[opstackptr] = v +end + +local function check_opstack(n) + return opstackptr >= n +end + +local function get_opstack() + if opstackptr > 0 then + return opstack[opstackptr] + else + return nil -- stackunderflow + end +end + +-- In case of error, the interpreter has to restore the opstack + +local function copy_opstack() + local t = { } + for n=1,opstackptr do + local sn = opstack[n] + t[n] = { unpack(sn) } + end + return t +end + +local function set_opstack(new) + opstackptr = #new + opstack = new +end + +-- Dict stack + +local dictstack +local dictstackptr + +initializers[#initializers+1] = function() + dictstack = { } + dictstackptr = 0 +end + +-- this finds a name in the current dictionary stack + +local function lookup(name) + for n=dictstackptr,1,-1 do + local found = get_VM(dictstack[n]) + if found then + local dict = found.dict + if dict then + local d = dict[name] + if d then + return d, n + end + end + end + end + return nil +end + +-- Graphics state stack + +-- device backends are easier if gsstate items use bare data instead of +-- ps objects, much as possible + +-- todo: just use one color array + +local gsstate + +initializers[#initializers+1] = function(reset) + if reset then + gsstate = nil + else + gsstate = { + matrix = { 1, 0, 0, 1, 0, 0 }, + color = { + gray = 0, + hsb = { }, + rgb = { }, + cmyk = { }, + type = "gray" + }, + position = { }, -- actual x and y undefined + path = { }, + clip = { }, + font = nil, + linewidth = 1, + linecap = 0, + linejoin = 0, + screen = nil, -- by default, we don't use a screen, which matches "1 0 {pop}" + transfer = nil, -- by default, we don't have a transfer function, which matches "{}" + flatness = 0, + miterlimit = 10, + dashpattern = { }, + dashoffset = 0, + } + end +end + +local function copy_gsstate() + local old = gsstate + local position = old.position + local matrix = old.matrix + local color = old.color + local rgb = color.rgb + local cmyk = color.cmyk + local hsb = color.hsb + return { + matrix = { matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6] }, + color = { + type = color.type, + gray = color.gray, + hsb = { hsb[1], hsb[2], hsb[3] }, + rgb = { rgb[1], rgb[2], rgb[3] }, + cmyk = { cmyk[1], cmyk[2], cmyk[3], cmyk[4] }, + }, + position = { position[1], position[2] }, + path = { unpack (old.path) }, + clip = { unpack (old.clip) }, + font = old.font, + linewidth = old.linewidth, + linecap = old.linecap, + linejoin = old.linejoin, + screen = old.screen, + transfer = nil, + flatness = old.flatness, + miterlimit = old.miterlimit, + dashpattern = { }, + dashoffset = 0, + } +end + +-- gsstack entries are of the form +-- [1] "[save|gsave]" +-- [2] {gsstate} + +local gsstack +local gsstackptr + +initializers[#initializers+1] = function(reset) + if reset then + gsstack = nil + gsstackptr = nil + else + gsstack = { } + gsstackptr = 0 + end +end + +local function push_gsstack(v) + gsstackptr = gsstackptr + 1 + gsstack[gsstackptr] = v +end + +local function pop_gsstack() + if gsstackptr > 0 then + local v = gsstack[gsstackptr] + gsstackptr = gsstackptr - 1 + return v + end +end + +-- Currentpage + +local currentpage + +initializers[#initializers+1] = function(reset) + if reset then + currentpage = nil + else + currentpage = { } + end +end + +-- Errordict + +-- The standard errordict entry. The rest of these dictionaries will be filled +-- in the new() function. + +local errordict +local dicterror + +-- find an error handler + +local function lookup_error(name) + local dict = get_VM(errordict).dict + return dict and dict[name] +end + +-- error handling and reporting + +local report = logs.reporter("escrito") + +local function ps_error(a) + -- can have print hook + return false, a +end + +-- Most entries in systemdict are operators, and the operators each have their own +-- implementation function. These functions are grouped by category cf. the summary +-- in the Adobe PostScript reference manual, the creation of the systemdict entries +-- is alphabetical. +-- +-- In the summary at the start of the operator sections, the first character means: +-- +-- "-" => todo +-- "+" => done +-- "*" => partial +-- "^" => see elsewhere + +local operators = { } + +-- Operand stack manipulation operators +-- +-- +pop +exch +dup +copy +index +roll +clear +count +mark +cleartomark +counttomark + +function operators.pop() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + return true +end + +function operators.exch() + if opstackptr < 2 then + return ps_error('stackunderflow') + end + local prv = opstackptr-1 + opstack[opstackptr], opstack[prv] = opstack[prv], opstack[opstackptr] + return true +end + +function operators.dup() + if opstackptr < 1 then + return ps_error('stackunderflow') + end + local nxt = opstackptr+1 + opstack[nxt] = opstack[opstackptr] + opstackptr = nxt + return true +end + +function operators.copy() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'integer' then + local va = a[4] + if va < 0 then + return ps_error('typecheck') + end + local thestack = opstackptr + if va > thestack then + return ps_error('stackunderflow') + end + -- use for loop + local n = thestack - va + 1 + while n <= thestack do + local b = opstack[n] + local tb = b[1] + if tb == 'array' or tb == 'string' or tb == 'dict' or tb == 'font' then + b = { tb, b[2], b[3], add_VM(get_VM(b[4])), b[5], b[6], b[7] } + end + push_opstack(b) + n = n + 1 + end + elseif ta == 'dict' then + local b = a + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'dict' then + return ps_error('typecheck') + end + local thedict = get_VM(b[4]) + local tobecopied = get_VM(a[4]) + if thedict.maxsize < tobecopied.size then + return ps_error('rangecheck') + end + if thedict.size ~= 0 then + return ps_error('typecheck') + end + local access = thedict.access + if access == 'read-only' or access == 'noaccess' then + return ps_error('invalidaccess') + end + local dict = { } + for k, v in next, tobecopied.dict do + dict[k] = v -- fixed, was thedict[a], must be thedict.dict + end + thedict.access = tobecopied.access + thedict.size = tobecopied.size + thedict.dict = dict + b = { b[1], b[2], b[3], add_VM(thedict) } + push_opstack(b) + elseif ta == 'array' then + local b = a + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'array' then + return ps_error('typecheck') + end + if b[6] < a[6] then + return ps_error('rangecheck') + end + local access = b[2] + if access == 'read-only' or access == 'noaccess' then + return ps_error('invalidaccess') + end + local array = { } + local thearray = get_VM(b[4]) + local tobecopied = get_VM(a[4]) + for k, v in next, tobecopied do + array[k] = v + end + b = { b[1], b[2], b[3], add_VM(array), a[5], a[6], a[7] } -- fixed, was thearray + push_opstack(b) + elseif ta == 'string' then + local b = a + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'string' then + return ps_error('typecheck') + end + if b[6] < a[6] then + return ps_error('rangecheck') + end + local access = b[2] + if access == 'read-only' or access == 'noaccess' then + return ps_error('invalidaccess') + end + local thestring = get_VM(b[4]) + local repl = get_VM(a[4]) + VM[b[4]] = repl .. sub(thestring,#repl+1,-1) + b = { b[1], b[2], b[3], add_VM(repl), a[5], b[6] } + push_opstack(b) + else + return ps_error('typecheck') + end + return true +end + +function operators.index() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not ta == 'integer' then + return ps_error('typecheck') + end + local n = a[4] + if n < 0 then + return ps_error('rangecheck') + end + if n >= opstackptr then + return ps_error('stackunderflow') + end + push_opstack(opstack[opstackptr-n]) + return true +end + +function operators.roll() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if b[1] ~= 'integer' then + return ps_error('typecheck') + end + if a[1] ~= 'integer' then + return ps_error('typecheck') + end + local stackcount = a[4] + if stackcount < 0 then + return ps_error('rangecheck') + end + if stackcount > opstackptr then + return ps_error('stackunderflow') + end + local rollcount = b[4] + if rollcount == 0 then + return true + end + if rollcount > 0 then + -- can be simplified + while rollcount > 0 do + local oldtop = opstack[opstackptr] + local n = 0 + while n < stackcount do + opstack[opstackptr-n] = opstack[opstackptr-n-1] + n = n + 1 + end + opstack[opstackptr-(stackcount-1)] = oldtop + rollcount = rollcount - 1 + end + else + -- can be simplified + while rollcount < 0 do + local oldbot = opstack[opstackptr-stackcount+1] + local n = stackcount - 1 + while n > 0 do + opstack[opstackptr-n] = opstack[opstackptr-n+1] + n = n - 1 + end + opstack[opstackptr] = oldbot + rollcount = rollcount + 1 + end + end + return true +end + +function operators.clear() + opstack = { } -- or just keep it + opstackptr = 0 + return true +end + +function operators.count() + push_opstack { 'integer', 'unlimited', 'literal', opstackptr } + return true +end + +function operators.mark() + push_opstack { 'mark', 'unlimited', 'literal', null } +end + +operators.beginarray = operators.mark + +function operators.cleartomark() + while opstackptr > 0 do + local val = pop_opstack() + if not val then + return ps_error('unmatchedmark') + end + if val[1] == 'mark' then + return true + end + end + return ps_error('unmatchedmark') +end + +function operators.counttomark() + local v = 0 + for n=opstackptr,1,-1 do + if opstack[n][1] == 'mark' then + push_opstack { 'integer', 'unlimited', 'literal', v } + return true + end + v = v + 1 + end + return ps_error('unmatchedmark') +end + +-- Arithmetic and math operators +-- +-- +add +div +idiv +mod +mul +sub +abs +neg +ceiling +floor +round +truncate +sqrt +atan +cos +-- +sin +exp +ln +log +rand +srand +rrand + +function operators.add() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = a[4] + b[4] + push_opstack { + (ta == 'real' or tb == 'real' or c > MAX_INT) and "real" or "integer", + 'unlimited', 'literal', c + } + return true +end + +function operators.sub() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = a[4] - b[4] + push_opstack { + (ta == 'real' or tb == 'real' or c > MAX_INT) and "real" or "integer", + 'unlimited', 'literal', c + } + return true +end + +function operators.div() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local va, vb = a[4], b[4] + if vb == 0 then + return ps_error('undefinedresult') + end + push_opstack { 'real', 'unlimited', 'literal', va / vb } + return true +end + +function operators.idiv() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if tb ~= 'integer' then + return ps_error('typecheck') + end + if ta ~= 'integer' then + return ps_error('typecheck') + end + local va, vb = a[4], b[4] + if vb == 0 then + return ps_error('undefinedresult') + end + push_opstack { 'integer', 'unlimited', 'literal', floor(va / vb) } + return true +end + +function operators.mod() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if tb ~= 'integer' then + return ps_error('typecheck') + end + if ta ~= 'integer' then + return ps_error('typecheck') + end + local va, vb = a[4], b[4] + if vb == 0 then + return ps_error('undefinedresult') + end + local neg = false + local v + if va < 0 then + v = -va + neg = true + else + v = va + end + local c = v % abs(vb) + if neg then + c = -c + end + push_opstack { 'integer', 'unlimited', 'literal', c } + return true +end + +function operators.mul() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = a[4] * b[4] + push_opstack { + (ta == 'real' or tb == 'real' or abs(c) > MAX_INT) and 'real' or 'integer', + 'unlimited', 'literal', c + } + return true +end + +function operators.abs() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local v = a[4] + local c = abs(v) + push_opstack { + (ta == 'real' or v == -(MAX_INT+1)) and 'real' or 'integer', -- hm, v or c + 'unlimited', 'literal', c + } + return true +end + +function operators.neg() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local v = a[4] + push_opstack { + (ta == 'real' or v == -(MAX_INT+1)) and 'real' or 'integer', + 'unlimited', 'literal', -v + } + return true +end + +function operators.ceiling() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = ceil(a[4]) + push_opstack { ta, 'unlimited', 'literal', c } + return true +end + +function operators.floor() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = floor(a[4]) + push_opstack { ta, 'unlimited', 'literal', c } + return true +end + +function operators.round() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = floor(a[4]+0.5) + push_opstack { ta, 'unlimited', 'literal', c } + return true +end + +function operators.truncate() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local v = a[4] + local c =v < 0 and -floor(-v) or floor(v) + push_opstack { ta, 'unlimited', 'literal', c } + return true +end + +function operators.sqrt() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local v = a[4] + if v < 0 then + return ps_error('rangecheck') + end + local c = sqrt(v) + push_opstack { 'real', 'unlimited', 'literal', c } + return true +end + +function operators.atan() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local va, vb = a[4], b[4] + if va == 0 and vb == 0 then + return ps_error('undefinedresult') + end + local c = deg(atan2(rad(va),rad(vb))) + if c < 0 then + c = c + 360 + end + push_opstack { 'real', 'unlimited', 'literal', c } + return true +end + +function operators.sin() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = sin(rad(a[4])) + -- this is because double calculation introduces a small error + if abs(c) < 1.0e-16 then + c = 0 + end + push_opstack { 'real', 'unlimited', 'literal', c } + return true +end + +function operators.cos() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local c = cos(rad(a[4])) + -- this is because double calculation introduces a small error + if abs(c) < 1.0e-16 then + c = 0 + end + push_opstack { 'real', 'unlimited', 'literal', c } + return true +end + +function operators.exp() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + local va, vb = a[4], b[4] + if va < 0 and floor(vb) ~= vb then + return ps_error('undefinedresult') + end + local c = pow(va,vb) + push_opstack { 'real', 'unlimited', 'literal', c } + return true +end + +function operators.ln() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local v = a[4] + if v <= 0 then + return ps_error('undefinedresult') + end + local c = log(v) + push_opstack { 'real', 'unlimited', 'literal', c } + return true +end + +function operators.log() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local v = a[4] + if v <= 0 then + return ps_error('undefinedresult') + end + local c = log10(v) + push_opstack { 'real', 'unlimited', 'literal', c } + return true +end + +escrito.randomseed = os.time() + +-- this interval is one off, but that'll do + +function operators.rand() + local c = random(MAX_INT) - 1 + push_opstack { 'integer', 'unlimited', 'literal', c } + return true +end + +function operators.srand() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta ~= 'integer' then + return ps_error('typecheck') + end + escrito.randomseed = a[4] + setranseed(escrito.randomseed) + return true +end + +function operators.rrand() + push_opstack { 'integer', 'unlimited', 'literal', escrito.randomseed } + return true +end + +-- Array operators +-- +-- +array ^[ +] +length +get +put +getinterval +putinterval +aload +astore ^copy +forall + +function operators.array() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local t = a[1] + local v = a[4] + if t ~= 'integer' then + return ps_error('typecheck') + end + if v < 0 then + return ps_error('rangecheck') + end + local array = { } + for i=1,v do + array[n] = { 'null', 'unlimited', 'literal', true } -- todo: share this one + end + push_opstack { 'array', 'unlimited', 'literal', add_VM(array), 0, v, 'd'} +end + +function operators.endarray() + local n = opstackptr + while n > 0 do + if opstack[n][1] == 'mark' then + break + end + n = n - 1 + end + if n == 0 then + return ps_error('unmatchedmark') + end + local top = opstackptr + local i = opstackptr - n + local array = { } + while i > 0 do + array[i] = pop_opstack() + i = i - 1 + end + pop_opstack() -- pop the mark + push_opstack { 'array', 'unlimited', 'literal', add_VM(array), #array, #array, 'd' } +end + +function operators.length() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local access = a[2] + if access == "noaccess" or access == "executeonly" then + return ps_error('invalidaccess') + end + local ta = a[1] + local va = a[4] + if ta == "dict" or ta == "font" then + va = get_VM(va).size + elseif ta == "array" or ta == "string" then + va = get_VM(va) + va = #va + else + return ps_error('typecheck') + end + push_opstack { 'integer', 'unlimited', 'literal', va } + return true +end + +function operators.get() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local access = a[2] + if access == "noaccess" or access == "execute-only" then + return ps_error('invalidaccess') + end + local ta = a[1] + local va = a[4] + if ta == "dict" then + local dict = get_VM(va) + local key = b + local tb = b[1] + local vb = b[4] + if tb == "string" or tb == "name" then + key = get_VM(vb) + end + local ddk = dict.dict[key] + if ddk then + push_opstack(ddk) + else + return ps_error('undefined') + end + elseif ta == "array" then + local tb = b[1] + local vb = b[4] + if tb ~= 'integer' then + return ps_error('typecheck') + end + if vb < 0 or vb >= a[6] then + return ps_error('rangecheck') + end + local array = get_VM(va) + local index = vb + 1 + push_opstack(array[index]) + elseif ta == "string" then + local tb = b[1] + local vb = b[4] + if tb ~= 'integer' then + return ps_error('typecheck') + end + if vb < 0 or vb >= a[6] then + return ps_error('rangecheck') + end + local thestring = get_VM(va) + local index = vb + 1 + local c = sub(thestring,index,index) + push_opstack { 'integer', 'unlimited', 'literal', byte(c) } + else + return ps_error('typecheck') + end + return true +end + +function operators.put() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == "dict" then + local dict = get_VM(a[4]) + if dict.access ~= 'unlimited' then + return ps_error('invalidaccess') + end + local key = b + local bt = b[1] + if bt == "string" or bt == "name" then + key = get_VM(b[4]) + end + local dd = dict.dict + local ds = dict.size + local ddk = dd[key] + if not ddk and (ds == dict.maxsize) then + return ps_error('dictfull') + end + if c[1] == 'array' then + c[7] = 'i' + end + if not ddk then + dict.size = ds + 1 + end + dd[key] = c + elseif ta == "array" then + if a[2] ~= 'unlimited' then + return ps_error('invalidaccess') + end + if b[1] ~= 'integer' then + return ps_error('typecheck') + end + local va, vb = a[4], b[4] + if vb < 0 or vb >= a[6] then + return ps_error('rangecheck') + end + local vm = VM[va] + local vi = bv + 1 + if vm[vi][1] == 'null' then + a[5] = a[5] + 1 + end + vm[vi] = c + elseif ta == "string" then + if a[2] ~= 'unlimited' then + return ps_error('invalidaccess') + end + if b[1] ~= 'integer' then + return ps_error('typecheck') + end + if c[1] ~= 'integer' then + return ps_error('typecheck') + end + local va, vb, vc = a[4], b[4], c[4] + if vb < 0 or vb >= a[6] then + return ps_error('rangecheck') + end + if vc < 0 or vc > 255 then + return ps_error('rangecheck') + end + local thestring = get_VM(va) + VM[va] = sub(thestring,1,vb) .. char(vc) .. sub(thestring,vb+2) + else + return ps_error('typecheck') + end + return true +end + +function operators.getinterval() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc = a[1], b[1], c[1] + local aa, ab, ac = a[2], b[2], c[2] + local va, vb, vc = a[4], b[4], c[4] + if ta ~= "array" and ta ~= 'string' then + return ps_error('typecheck') + end + if tb ~= 'integer' or tc ~= 'integer' then + return ps_error('typecheck') + end + if aa == "execute-only" or aa == 'noaccess' then + return ps_error('invalidaccess') + end + if vb < 0 or vc < 0 or vb + vc >= a[6] then + return ps_error('rangecheck') + end + -- vb : start + -- vc : number + if ta == 'array' then + local array = get_VM(va) + local subarray = { } + local index = 1 + while index <= vc do + subarray[index] = array[index+vb] + index = index + 1 + end + push_opstack { 'array', aa, a[3], add_VM(subarray), vc, vc, 'd' } + else + local thestring = get_VM(va) + local newstring = sub(thestring,vb+1,vb+vc) + push_opstack { 'string', aa, a[3], add_VM(newstring), vc, vc } + end + return true +end + +function operators.putinterval() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc = a[1], b[1], c[1] + local aa, ab, ac = a[2], b[2], c[2] + local va, vb, vc = a[4], b[4], c[4] + if ta ~= "array" and ta ~= 'string' then + return ps_error('typecheck') + end + if tc ~= "array" and tc ~= 'string' then + return ps_error('typecheck') + end + if ta ~= tc then + return ps_error('typecheck') + end + if aa ~= "unlimited" then + return ps_error('invalidaccess') + end + if tb ~= 'integer' then + return ps_error('typecheck') + end + if vb < 0 or vb + c[6] >= a[6] then + return ps_error('rangecheck') + end + if ta == 'array' then + local newarr = get_VM(vc) + local oldarr = get_VM(va) + local index = 1 + local lastindex = c[6] + local step = a[5] + while index <= lastindex do + if oldarr[vb+index][1] == 'null' then + a[5] = a[5] + 1 -- needs checking, a[5] not used + -- step = step + 1 + end + oldarr[vb+index] = newarr[index] + index = index + 1 + end + else + local thestring = get_VM(va) + VM[va] = sub(thestring,1,vb) .. get_VM(vc) .. sub(thestring,vb+c[6]+1) + end + return true +end + +function operators.aload() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + if ta ~= "array" then + return ps_error('typecheck') + end + if aa == "execute-only" or aa == 'noaccess' then + return ps_error('invalidaccess') + end + local array = get_VM(va) + for i=1,#array do + push_opstack(array[i]) + end + push_opstack(a) + return true +end + +function operators.astore() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + if ta ~= "array" then + return ps_error('typecheck') + end + if aa == "execute-only" or aa == 'noaccess' then + return ps_error('invalidaccess') + end + local array = get_VM(va) + local count = a[6] + for i=1,count do + local v = pop_opstack() + if not v then + return ps_error('stackunderflow') + end + array[i] = v + end + a[5] = a[5] + count + push_opstack(a) + return true +end + +function operators.forall() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + local tb, ab, vb = b[1], b[2], b[4] + if not tb == "array" and b[3] == 'executable' then + return ps_error('typecheck') + end + if tb == 'noaccess' then + return ps_error('invalidaccess') + end + if not (ta == "array" or ta == 'dict' or ta == 'string' or ta == "font") then + return ps_error('typecheck') + end + if aa == "execute-only" or aa == 'noaccess' then + return ps_error('invalidaccess') + end + push_execstack { '.exit', 'unlimited', 'literal', false } + local curstack = execstackptr + if ta == 'array' then + if a[6] == 0 then + return true + end + b[7] = 'i' + local thearray = get_VM(va) + for i=1,#thearray do + if stopped then + stopped = false + return false + end + push_opstack(thearray[i]) + b[5] = 1 + push_execstack(b) + while curstack <= execstackptr do + do_exec() + end + end + local entry = execstack[execstackptr] + if entry[1] == '.exit' and antry[4] == true then + pop_execstack() + return true + end + elseif ta == 'dict' or ta == 'font' then + local thedict = get_VM(va) + if thedict.size == 0 then + return true + end + b[7] = 'i' + local thedict = get_VM(va) + for k, v in next, thedict.dict do + if stopped then + stopped = false + return false + end + if type(k) == "string" then + push_opstack { 'name', 'unlimited', 'literal', add_VM(k) } + else + push_opstack(k) + end + push_opstack(v) + b[5] = 1 + push_execstack(b) + while curstack < execstackptr do + do_exec() + end + local entry = execstack[execstackptr] + if entry[1] == '.exit' and antry[4] == true then + pop_execstack() + return true + end + end + else -- string + if a[6] == 0 then + return true + end + b[7] = 'i' + local thestring = get_VM(va) + for v in gmatch(thestring,".") do -- we can use string.bytes + if stopped then + stopped = false + return false + end + push_opstack { 'integer', 'unlimited', 'literal', byte(v) } + b[5] = 1 + push_execstack(b) + while curstack < execstackptr do + do_exec() + end + local entry = execstack[execstackptr] + if entry[1] == '.exit' and antry[4] == true then + pop_execstack() + return true; + end + end + end + return true +end + +-- Dictionary operators +-- +-- +dict ^length +maxlength +begin +end +def +load +store ^get ^put +known +where ^copy +-- ^forall ^errordict ^systemdict ^userdict +currentdict +countdictstack +dictstack + +function operators.dict() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not a[1] == 'integer' then + return ps_error('typecheck') + end + local s = a[4] + if s < 0 then + return ps_error('rangecheck') + end + if s == 0 then -- level 2 feature + s = MAX_INT + end + push_opstack { + 'dict', + 'unlimited', + 'literal', + add_VM { + access = 'unlimited', + size = 0, + maxsize = s, + dict = { }, + } + } +end + +function operators.maxlength() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + if ta ~= 'dict' then + return ps_error('typecheck') + end + if aa == 'execute-only' or aa == 'noaccess' then + return ps_error('invalidaccess') + end + local thedict = get_VM(va) + push_opstack { 'integer', 'unlimited', 'literal', thedict.maxsize } +end + +function operators.begin() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'dict' then + return ps_error('typecheck') + end + dictstackptr = dictstackptr + 1 + dictstack[dictstackptr] = a[4] +end + +operators["end"] = function() + if dictstackptr < 3 then + return ps_error('dictstackunderflow') + end + dictstack[dictstackptr] = nil + dictstackptr = dictstackptr - 1 +end + +function operators.def() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not (a[1] == 'name' and a[3] == 'literal') then + return ps_error('typecheck') + end + if b[1] == 'array' then + b[7] = 'i' + end + local thedict = get_VM(dictstack[dictstackptr]) + if not thedict.dict[get_VM(a[4])] then + if thedict.size == thedict.maxsize then + -- return ps_error('dictfull') -- level 1 only + end + thedict.size = thedict.size + 1 + end + thedict.dict[get_VM(a[4])] = b + return true +end + +-- unclear: the book says this operator can return typecheck + +function operators.load() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local aa = a[2] + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + local v = lookup(get_VM(a[4])) + if not v then + return ps_error('undefined') + end + push_opstack(v) +end + +function operators.store() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not (a[1] == 'name' and a[3] == 'literal') then + return ps_error('typecheck') + end + if b[7] == 'array' then + b[7] = 'i' + end + local val, dictloc = lookup(a[4]) + if val then + local thedict = get_VM(dictstack[dictloc]) + if thedict.access == 'execute-only' or thedict.access == 'noaccess' then + return ps_error('invalidaccess') + end + thedict.dict[a[4]] = b + else + local thedict = get_VM(dictstack[dictstackptr]) + local access = thedict.access + local size = thedict.size + if access == 'execute-only' or access == 'noaccess' then + return ps_error('invalidaccess') + end + if size == thedict.maxsize then + return ps_error('dictfull') + end + thedict.size = size + 1 + thedict.dict[a[4]] = b + end + return true +end + +function operators.known() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + local tb, vb = b[1], b[4] + if ta ~= 'dict' then + return ps_error('typecheck') + end + if not (tb == 'name' or tb == 'operator') then + return ps_error('typecheck') + end + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + local thedict = get_VM(va) + push_opstack {'boolean', 'unlimited', 'literal', thedict.dict[vb] and true or false } + return true +end + +function operators.where() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not (a[1] == 'name' and a[3] == 'literal') then + return ps_error('typecheck') + end + local val, dictloc = lookup(get_VM(a[4])) + local thedict = dictloc and get_VM(dictstack[dictloc]) -- fixed + if val then + if thedict.access == 'execute-only' or thedict.access == 'noaccess' then + return ps_error('invalidaccess') + end + push_opstack {'dict', 'unlimited', 'literal', dictstack[dictloc]} + push_opstack {'boolean', 'unlimited', 'literal', true} + else + push_opstack {'boolean', 'unlimited', 'literal', false} + end + return true +end + +function operators.currentdict() + push_opstack { 'dict', 'unlimited', 'literal', dictstack[dictstackptr] } + return true +end + +function operators.countdictstack() + push_opstack { 'integer', 'unlimited', 'literal', dictstackptr } + return true +end + +function operators.dictstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not a[1] == 'array' then + return ps_error('typecheck') + end + if not a[2] == 'unlimited' then + return ps_error('invalidaccess') + end + if a[6] < dictstackptr then + return ps_error('rangecheck') + end + local thearray = get_VM(a[4]) + local subarray = { } + for i=1,dictstackptr do + thearray[n] = { 'dict', 'unlimited', 'literal', dictstack[i] } + subarray[n] = thearray[i] + end + a[5] = a[5] + dictstackptr + push_opstack { 'array', 'unlimited', 'literal', add_VM(subarray), dictstackptr, dictstackptr, '' } + return true +end + +-- String operators +-- +-- +string ^length ^get ^put ^getinterval ^putinterval ^copy ^forall +anchorsearch +search +-- +token + +function operators.string() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, va = a[1], a[4] + if ta ~= 'integer' then + return ps_error('typecheck') + end + if va < 0 then + return ps_error('rangecheck') + end + push_opstack { 'string', 'unlimited', 'literal', add_VM(''), 1, va } +end + +function operators.anchorsearch() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + local tb, ab, vb = b[1], b[2], b[4] + if not ta ~= 'string' then + return ps_error('typecheck') + end + if tb ~= 'string' then + return ps_error('typecheck') + end + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + if ab == 'noaccess' or ab == 'execute-only' then + return ps_error('invalidaccess') + end + local thestring = get_VM(va) + local thesearch = get_VM(vb) + local prefix = sub(thestring,1,#thesearch) + if prefix == thesearch then + if aa == 'read-only' then + return ps_error('invalidaccess') + end + local post = sub(thestring,#thesearch+1) + push_opstack { 'string', 'unlimited', 'literal', add_VM(post), 1, #post } + push_opstack { 'string', 'unlimited', 'literal', add_VM(prefix), 1, #prefix } + push_opstack { 'boolean', 'unlimited', 'literal', true } + else + push_opstack(a) + push_opstack { 'boolean', 'unlimited', 'literal', false } + end + return true +end + +function operators.search() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + local tb, ab, vb = b[1], b[2], b[4] + if not ta ~= 'string' then + return ps_error('typecheck') + end + if tb ~= 'string' then + return ps_error('typecheck') + end + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + if ab == 'noaccess' or ab == 'execute-only' then + return ps_error('invalidaccess') + end + local thestring = get_VM(a[4]) + local thesearch = get_VM(b[4]) + -- hm, can't this be done easier? + local n = 1 + local match + while n + #thesearch-1 <= #thestring do + match = sub(thestring,n,n+#thesearch-1) + if match == thesearch then + break + end + n = n + 1 + end + if match == thesearch then + if aa == 'read-only' then + return ps_error('invalidaccess') + end + local prefix = sub(thestring,1,n-1) + local post = sub(thestring,#thesearch+n) + push_opstack { 'string', 'unlimited', 'literal', add_VM(post), 1, #post } + push_opstack { 'string', 'unlimited', 'literal', add_VM(thesearch), 1, #thesearch } + push_opstack { 'string', 'unlimited', 'literal', add_VM(prefix), 1, #prefix } + push_opstack { 'boolean', 'unlimited', 'literal', true } + else + push_opstack(a) + push_opstack { 'boolean', 'unlimited', 'literal', false } + end + return true +end + +function operators.token() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa, va = a[1], a[2], a[4] + if not (ta == 'string' or ta == 'file') then + return ps_error('typecheck') + end + if aa ~= 'unlimited' then + return ps_error('invalidaccess') + end + -- some fiddling with the tokenization process is needed + if ta == 'string' then + local top = execstackptr + push_execstack { '.token', 'unlimited', 'literal', false } + push_execstack { a[1], a[2], 'executable', va, 1, a[6] } + local v, err = next_object() + if not v then + pop_execstack() + pop_execstack() + push_opstack { 'boolean', 'unlimited', 'literal', false } + else + local q = pop_execstack() + if execstack[execstackptr][1] == '.token' then + pop_execstack() + end + local tq, vq = q[1], q[4] + if tq == 'string' and vq ~= va then + push_execstack(q) + end + local thestring, substring + if vq ~= va then + thestring = "" + substring = "" + else + thestring = get_VM(vq) + substring = sub(thestring,q[5] or 0) + end + push_opstack { ta, aa, a[3], add_VM(substring), 1, #substring} + push_opstack(v) + push_opstack { 'boolean', 'unlimited', 'literal', true } + end + else -- file + if a[7] ~= 'r' then + return ps_error('invalidaccess') + end + push_execstack { '.token', 'unlimited', 'literal', false } + push_execstack { 'file', 'unlimited', 'executable', va, a[5], a[6], a[7], a[8] } + local v, err = next_object() + if not v then + pop_execstack() + pop_execstack() + push_opstack { 'boolean', 'unlimited', 'literal', false } + else + local q = pop_execstack() -- the file + a[5] = q[5] + if execstack[execstackptr][1] == '.token' then + pop_execstack() + end + push_opstack(v) + push_opstack { 'boolean', 'unlimited', 'literal', true } + end + end + return true +end + +-- Relational, boolean and bitwise operators +-- +-- +eq +ne +ge +gt +le +lt +and +not +or +xor ^true ^false +bitshift + +local function both() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa = a[1], a[2] + local tb, ab = b[1], b[2] + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + if ab == 'noaccess' or ab == 'execute-only' then + return ps_error('invalidaccess') + end + if (ta == 'dict' and tb == 'dict') or (ta == 'array' and tb =='array') then + return true, a[4], b[4] + elseif ((ta == 'string' or ta == 'name') and (tb == 'string' or tb == 'name' )) then + local astr = get_VM(a[4]) + local bstr = get_VM(b[4]) + return true, astr, bstr + elseif ((ta == 'integer' or ta == 'real') and (tb == 'integer' or tb == 'real')) or (ta == tb) then + return true, a[4], b[4] + else + return ps_error('typecheck') + end + return true +end + +function operators.eq() + local ok, a, b = both() + if ok then + push_opstack { 'boolean', 'unlimited', 'literal', a == b } + return true + else + return a + end +end + +function operators.ne() + local ok, a, b = both() + if ok then + push_opstack { 'boolean', 'unlimited', 'literal', a ~= b } + return true + else + return a + end +end + +local function both() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local aa, ab = a[2], b[2] + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + if ab == 'noaccess' or ab == 'execute-only' then + return ps_error('invalidaccess') + end + local ta, tb = a[1], b[1] + local va, vb = a[4], b[4] + if (ta == 'real' or ta == 'integer') and (tb == 'real' or tb == 'integer') then + return true, va, vb + elseif ta == 'string' and tb == 'string' then + local va = get_VM(va) + local vb = get_VM(vb) + return true, va, vb + else + return ps_error('typecheck') + end +end + +function operators.ge() + local ok, a, b = both() + if ok then + push_opstack { 'boolean', 'unlimited', 'literal', a >= b } + return true + else + return a + end +end + +function operators.gt() + local ok, a, b = both() + if ok then + push_opstack { 'boolean', 'unlimited', 'literal', a > b } + return true + else + return a + end +end + +function operators.le() + local ok, a, b = both() + if ok then + push_opstack { 'boolean', 'unlimited', 'literal', a <= b } + return true + else + return a + end +end + +function operators.lt() + local ok, a, b = both() + if ok then + push_opstack { 'boolean', 'unlimited', 'literal', a < b } + return true + else + return a + end +end + +local function both() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local aa, ab = a[2], b[2] + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + if ab == 'noaccess' or ab == 'execute-only' then + return ps_error('invalidaccess') + end + local ta, tb = a[1], b[1] + local va, vb = a[4], b[4] + if ta == 'boolean' and tb == 'boolean' then + return ta, va, vb + elseif ta == 'integer' and tb == 'integer' then + return ta, va, vb + else + return ps_error('typecheck') + end +end + +operators["and"]= function() + local ok, a, b = both() + if ok == 'boolean' then + push_opstack { 'boolean', 'unlimited', 'literal', a[1] and b[1] } + return true + elseif ok == 'integer' then + push_opstack { 'integer', 'unlimited', 'literal', bitand(a[1],b[1]) } + return true + else + return a + end +end + +operators["or"] = function() + local ok, a, b = both() + if ok == 'boolean' then + push_opstack {'boolean', 'unlimited', 'literal', a[1] or b[1] } + return true + elseif ok == 'integer' then + push_opstack {'integer', 'unlimited', 'literal', bitor(a[1],b[1]) } + return true + else + return a + end +end + +function operators.xor() + local ok, a, b = both() + if ok == 'boolean' then + push_opstack {'boolean', 'unlimited', 'literal', a[1] ~= b[1] } + return true + elseif ok == 'integer' then + push_opstack {'integer', 'unlimited', 'literal', bitxor(a[1],b[1]) } + return true + else + return a + end +end + +operators["not"] = function() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local aa = a[2] + local ta = a[1] + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + if ta == 'boolean' then + push_opstack { 'boolean', 'unlimited', 'literal', not a[4] } + elseif ta == 'integer' then + push_opstack { 'integer', 'unlimited', 'literal', -a[4] - 1 } + else + return ps_error('typecheck') + end + return true +end + +function operators.bitshift() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local aa, ab = a[2], b[2] + local ta, tb = a[1], b[1] + local va, vb = a[4], b[4] + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + if ab == 'noaccess' or ab == 'execute-only' then + return ps_error('invalidaccess') + end + if not (ta == 'integer' and tb == 'integer') then + return ps_error('typecheck') + end + push_opstack { 'integer', 'unlimited', 'literal', bitrshift(va,vb < 0 and -vb or vb) } + return true +end + +-- Control operators +-- +-- +exec +if +ifelse +for +repeat +loop +exit +stop +stopped +countexecstack +execstack +-- +quit +start + +function operators.exec() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] == 'array' then + a[7] = 'i' + a[5] = 1 + end + push_execstack(a) + return true +end + +operators["if"] = function() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'boolean' then + return ps_error('typecheck') + end + if b[1] ~= 'array' then + return ps_error('typecheck') + end + if a[4] == true then + b[7] = 'i' + b[5] = 1 + push_execstack(b) + end + return true +end + +function operators.ifelse() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'boolean' then + return ps_error('typecheck') + end + if b[1] ~= 'array' then + return ps_error('typecheck') + end + if c[1] ~= 'array' then + return ps_error('typecheck') + end + if a[4] == true then + b[5] = 1 + b[7] = 'i' + push_execstack(b) + else + c[5] = 1 + c[7] = 'i' + push_execstack(c) + end + return true +end + +operators["for"] = function() + local d = pop_opstack() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + local ta, tb, tc, td = a[1], b[1], c[1], d[1] + if not a then + return ps_error('stackunderflow') + end + if not (ta == 'integer' or ta == 'real') then + return ps_error('typecheck') + end + if not (tb == 'integer' or tb == 'real') then + return ps_error('typecheck') + end + if not (tc == 'integer' or tc == 'real') then + return ps_error('typecheck') + end + if not (td == 'array' and d[3] == 'executable') then + return ps_error('typecheck') + end + local initial = a[4] + local increment = b[4] + local limit = c[4] + if initial == limit then + return true + end + push_execstack { '.exit', 'unlimited', 'literal', false } + local curstack = execstackptr + local tokentype = (a[1] == 'real' or b[1] == 'real' or c[1] == 'real') and 'real' or 'integer' + d[7] = 'i' + local first, last + if increment >= 0 then + first, last = initial, limit + else + first, last = limit, limit + end + for control=first,last,increment do + if stopped then + stopped = false + return false + end + push_opstack { tokentype, 'unlimited', 'literal', control } + d[5] = 1 + push_execstack(d) + while curstack < execstackptr do + do_exec() + end + local entry = execstack[execstackptr] + if entry[1] == '.exit' and entry[4] == true then + pop_execstack() + return true; + end + end + return true +end + +operators["repeat"] = function() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'integer' then + return ps_error('typecheck') + end + if a[4] < 0 then + return ps_error('rangecheck') + end + if not (b[1] == 'array' and b[3] == 'executable') then + return ps_error('typecheck') + end + local limit = a[4] + if limit == 0 then + return true + end + push_execstack { '.exit', 'unlimited', 'literal', false } + local curstack = execstackptr + b[7] = 'i' + local control = 0 + while control < limit do + if stopped then + stopped = false + return false + end + b[5] = 1 + push_execstack(b) + while curstack < execstackptr do + do_exec() + end + local entry = execstack[execstackptr] + if entry[1] == '.exit' and entry[4] == true then + pop_execstack() + return true; + end + control = control + 1 + end + return true +end + +function operators.loop() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not (a[1] == 'array' and a[3] == 'executable') then + return ps_error('typecheck') + end + push_execstack { '.exit', 'unlimited', 'literal', false } + local curstack = execstackptr + a[7] = 'i' + while true do + if stopped then + stopped = false + return false + end + a[5] = 1 + push_execstack(a) + while curstack < execstackptr do + do_exec() + end + if execstackptr > 0 then + local entry = execstack[execstackptr] + if entry[1] == '.exit' and entry[4] == true then + pop_execstack() + return true + end + end + end + return true +end + +function operators.exit() + local v = pop_execstack() + while v do + local tv = val[1] + if tv == '.exit' then + push_execstack { '.exit', 'unlimited', 'literal', true } + return true + elseif tv == '.stopped' or tv == '.run' then + push_execstack(v) + return ps_error('invalidexit') + end + v = pop_execstack() + end + report("exit without context, quitting") + push_execstack { 'operator', 'unlimited', 'executable', operators.quit, "quit" } + return true +end + +function operators.stop() + local v = pop_execstack() + while v do + if val[1] == '.stopped' then + stopped = true + push_opstack { 'boolean', 'unlimited', 'executable', true } + return true + end + v = pop_execstack() + end + report("stop without context, quitting") + push_execstack { 'operator', 'unlimited', 'executable', operators.quit, "quit" } + return true +end + +function operators.stopped() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + -- push a special token on the exec stack (handled by next_object): + push_execstack { '.stopped', 'unlimited', 'literal', false } + a[3] = 'executable' + if a[1] == 'array' then + a[7] = 'i' + a[5] = 1 + end + push_execstack(a) + return true +end + +function operators.countexecstack() + push_opstack { 'integer', 'unlimited', 'literal', execstackptr } + return true +end + +function operators.execstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not a[1] == 'array' then + return ps_error('typecheck') + end + if not a[2] == 'unlimited' then + return ps_error('invalidaccess') + end + if a[6] < execstackptr then + return ps_error('rangecheck') + end + local thearray = get_VM(a[4]) + local subarray = { } + for n=1,execstackptr do + -- thearray[n] = execstack[n] + -- subarray[n] = thearray[n] + local v = execstack[n] + thearray[n] = v + subarray[n] = v + a[5] = a[5] + 1 + end + push_opstack { 'array', 'unlimited', 'literal', add_VM(subarray), execstackptr, execstackptr, "" } + return true +end + +-- clearing the execstack does the trick, +-- todo: leave open files to be handled by the lua interpreter, for now + +function operators.quit() + while execstackptr >= 0 do -- todo: for loop / slot 0? + execstack[execstackptr] = nil + execstackptr = execstackptr - 1 + end + return true +end + +-- does nothing, for now + +function operators.start() + return true +end + +-- Type, attribute and conversion operators +-- +-- +type +cvlit +cvx +xcheck +executeonly +noaccess +readonly +rcheck +wcheck +cvi +-- +cvn +cvr +cvrs +cvs + +function operators.type() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + push_opstack { "name", "unlimited", "executable", add_VM(a[1] .. "type") } + return true +end + +function operators.cvlit() -- no need to push/pop + local a = get_opstack() + if not a then + return ps_error('stackunderflow') + end + a[3] = 'literal' + return true +end + +function operators.cvx() + local a = get_opstack() + if not a then + return ps_error('stackunderflow') + end + a[3] = 'executable' + return true +end + +function operators.xcheck() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + push_opstack { 'boolean', 'unlimited', 'literal', a[3] == 'executable' } + return true +end + +function operators.executeonly() + local a = pop_opstack() -- get no push + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'string' or ta == 'file' or ta == 'array' then + if a[2] == 'noaccess' then + return ps_error('invalidaccess') + end + a[2] = 'execute-only' + else + return ps_error('typecheck') + end + push_opstack(a) + return true +end + +function operators.noaccess() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'string' or ta == 'file' or ta == 'array' then + if a[2] == 'noaccess' then + return ps_error('invalidaccess') + end + a[2] = 'noaccess' + elseif ta == "dict" then + local thedict = get_VM(a[4]) + if thedict.access == 'noaccess' then + return ps_error('invalidaccess') + end + thedict.access = 'noaccess' + else + return ps_error('typecheck') + end + push_opstack(a) + return true +end + +function operators.readonly() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'string' or ta == 'file' or ta == 'array' then + local aa = a[2] + if aa == 'noaccess' or aa == 'execute-only' then + return ps_error('invalidaccess') + end + a[2] = 'read-only' + elseif ta == 'dict' then + local thedict = get_VM(a[4]) + local access = thedict.access + if access == 'noaccess' or access == 'execute-only' then + return ps_error('invalidaccess') + end + thedict.access = 'read-only' + else + return ps_error('typecheck') + end + push_opstack(a) + return true +end + +function operators.rcheck() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + local aa + if ta == 'string' or ta == 'file' or ta == 'array' then + aa = a[2] + elseif ta == 'dict' then + aa = get_VM(a[4]).access + else + return ps_error('typecheck') + end + push_opstack { 'boolean', 'unlimited', 'literal', aa == 'unlimited' or aa == 'read-only' } + return true +end + +function operators.wcheck() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + local aa + if ta == 'string' or ta == 'file' or ta == 'array' then + aa = a[2] + elseif ta == 'dict' then + local thedict = get_VM(a[4]) + aa = thedict.access + else + return ps_error('typecheck') + end + push_opstack { 'boolean', 'unlimited', 'literal', aa == 'unlimited' } + return true +end + +function operators.cvi() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'string' then + push_opstack(a) + local ret, err = operators.token() + if not ret then + return ret, err + end + local b = pop_opstack() + if b[4] == false then + return ps_error('syntaxerror') + end + a = pop_opstack() + pop_opstack() -- get rid of the postmatch string remains + ta = a[1] + end + local aa = a[2] + if not (aa == 'unlimited' or aa == 'read-only') then + return ps_error('invalidaccess') + end + if ta == 'integer' then + push_opstack(a) + elseif ta == 'real' then + local va = a[4] + local c = va < 0 and -floor(-va) or floor(ava) + if abs(c) > MAX_INT then + return ps_error('rangecheck') + end + push_opstack { 'integer', 'unlimited', 'literal', c } + else + return ps_error('typecheck') + end + return true +end + +function operators.cvn() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, aa = a[1], a[2] + local ta = a[1] + if ta ~= 'string' then + return ps_error('typecheck') + end + if aa == 'execute-only' or aa == 'noaccess' then + return ps_error('invalidaccess') + end + push_opstack { 'name', aa, a[3], add_VM(get_VM(a[4])) } + return true +end + +function operators.cvr() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'string' then + push_opstack(a) + local ret, err = operators.token() + if not ret then + return ret, err + end + local b = pop_opstack() + if b[4] == false then + return ps_error('syntaxerror') + end + a = pop_opstack() + pop_opstack() -- get rid of the postmatch string remains + ta = a[1] + end + local aa = a[2] + if not (aa == 'unlimited' or aa == 'read-only') then + return ps_error('invalidaccess') + end + if ta == 'integer' then + push_opstack { 'real', 'unlimited', 'literal', a[4] } + elseif ta == 'real' then + push_opstack(a) + else + return ps_error('typecheck') + end + return true +end + +do + + local byte0 = byte('0') + local byteA = byte('A') - 10 + + function operators.cvrs() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc = a[1], b[1], c[1] + if not (ta == 'integer' or ta == 'real') then + return ps_error('typecheck') + end + if not tb == 'integer' then + return ps_error('typecheck') + end + if not tc == 'string' then + return ps_error('typecheck') + end + if not c[2] == 'unlimited' then + return ps_error('invalidaccess') + end + local va, vb, vc = a[4], b[4], c[4] + if (vb < 2 or vb > 36) then + return ps_error('rangecheck') + end + if ta == 'real' then + push_opstack(a) + local ret, err = operators.cvi() + if ret then + return ret, err + end + a = pop_opstack() + end + -- todo: use an lpeg + local decimal = va + local str = { } + local n = 0 + while decimal > 0 do + local digit = decimal % vb + n = n + 1 + str[n] = digit < 10 and char(digit+byte0) or char(digit+byteA) + decimal = floor(decimal/vb) + end + if n > c[6] then + return ps_error('rangecheck') + end + str = concat(reverse(str)) + local thestring = get_VM(vc) + VM[va] = str .. sub(thestring,n+1,-1) + push_opstack { c[1], c[2], c[3], add_VM(repl), n, n } + return true + end + +end + +function operators.cvs() + local b = pop_opstack() + local a = pop_opstack() + if not 4 then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + local ab = b[2] + if not tb == 'string' then + return ps_error('typecheck') + end + if not ab == 'unlimited' then + return ps_error('invalidaccess') + end + local va, vb = a[4], b[4] + if ta == 'real' then + if floor(va) == va then + va = tostring(va) .. '.0' + else + va = tostring(va) + end + elseif ta == 'integer' then + va = tostring(va) + elseif ta == 'string' or ta == 'name' then + va = get_VM(va) + elseif ta == 'operator' then + va = a[5] + elseif ta == 'boolean' then + va = tostring(va) + else + va = "--nostringval--" + end + local n = #va + if n > b[6] then + return ps_error('rangecheck') + end + local thestring = get_VM(vb) + VM[vb] = va .. sub(thestring,n+1,-1) + push_opstack { tb, ab, b[3], add_VM(va), n, n } + return true +end + +-- File operators +-- +-- +file +closefile +read +write +writestring +readhexstring +writehexstring +readline ^token +-- +bytesavailable +flush +flushfile +resetfile +status +run +currentfile +print ^= ^stack +-- +== ^pstack ^prompt +echo + +function operators.file() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if b[1] ~= 'string' then + return ps_error('typecheck') + end + if a[1] ~= 'string' then + return ps_error('typecheck') + end + local fmode = get_VM(b[4]) + local fname = get_VM(a[4]) + -- only accept (r), (w) and (a) + if fmode ~= "r" and fmode ~= "w" and fmode ~= "a" then + return ps_error('typecheck') + end + if fname == "%stdin" then + -- can only read from stdin + if fmode ~= "r" then + return ps_error('invalidfileaccess') + end + push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, io.stdin } + elseif fname == "%stdout" then + -- can't read from stdout i.e. can only append, in fact, but lets ignore that + if fmode == "r" then + return ps_error('invalidfileaccess') + end + push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, io.stdout } + elseif fname == "%stderr" then + -- cant read from stderr i.e. can only append, in fact, but lets ignore that + if fmode == "r" then + return ps_error('invalidfileaccess') + end + push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, io.stderr } + elseif fname == "%statementedit" or fname == "%lineedit"then + return ps_error('invalidfileaccess') + else + -- so it is a normal file + local myfile, error = io.open(fname,fmode) + if not myfile then + return ps_error('undefinedfilename') + end + if fmode == 'r' then + l = myfile:read("*a") + if not l then + return ps_error('invalidfileaccess') + end + -- myfile:close() -- do not close here, easier later on + push_opstack { 'file', 'unlimited', 'literal', add_VM(l), 1, #l, fmode, myfile} + else + push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, myfile} + end + end + return true +end + +function operators.read() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[7] ~= 'r' then + return ps_error('invalidaccess') + end + local b + local v = a[4] + local f = a[8] + if v > 0 then + local thestr = get_VM(v) + local n = a[5] + if n < a[6] then + byte = sub(thestr,n,n+1) + -- a[5] = n + 1 + end + else -- %stdin + b = f:read(1) + end + if b then + push_opstack { 'integer', 'unlimited', 'literal', byte(b) } + push_opstack { 'boolean', 'unlimited', 'literal', true } + else + f:close() + push_opstack { 'boolean', 'unlimited', 'literal', false} + end + return true +end + +function operators.write() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if b[1] ~= 'integer' then + return ps_error('typecheck') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[7] == 'r' then + return ps_error('ioerror') + end + a[8]:write(char(b[4] % 256)) + return true +end + +function operators.writestring() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if b[1] ~= 'string' then + return ps_error('typecheck') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[7] == 'r' then + return ps_error('ioerror') + end + a[8]:write(get_VM(b[4])) + return true +end + +function operators.writehexstring() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if b[1] ~= 'string' then + return ps_error('typecheck') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[7] == 'r' then + return ps_error('ioerror') + end + local f = a[8] + local s = get_VM(b[4]) + for w in gmatch(s,".") do + f:write(format("%x",byte(w))) -- we have a table for that somewhere + end + return true +end + +do + + local function get_string_line(a) + local str = get_VM(a[4]) + local start = a[5] + local theend = a[6] + if start == theend then + return nil + end + str = match(str,"[\n\r]*([^\n\r]*)",start) + a[5] = a[5] + #str + 1 -- ? + return str + end + + local function get_hexstring_line (a,b) + local thestring = get_VM(a[4]) + local start, theend = a[5], a[6] + if start == theend then + return nil + end + local prefix, result, n = nil, { }, 0 + local nmax = b[6] + while start < theend do + local b = sub(thestring,start,start) + if not b then + break + end + local hexbyte = tonumber(b,16) + if not hexbyte then + -- skip + elseif prefix then + n = n + 1 + result[n] = char(prefix*16+hexbyte) + if n == nmax then + break + else + prefix = nil + end + else + prefix = hexbyte + end + start = start + 1 + end + a[5] = start + 1 -- ? + return concat(result) + end + + function operators.readline() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[7] ~= 'r' then + return ps_error('invalidaccess') + end + local va = a[4] + if va > 0 then + va = get_string_line(a) + else + va = a[8]:read('*l') + end + if not va then + push_opstack { 'string', 'unlimited', 'literal', add_VM(''), 0, 0 } + push_opstack { 'boolean', 'unlimited', 'literal', false } + else + local n = #va + if n > b[6] then + return ps_error('rangecheck') + end + local thestring = get_VM(b[4]) + VM[b[4]] = va .. sub(thestring,#va+1, -1) + push_opstack { 'string', 'unlimited', 'literal', add_VM(va), n, n } + push_opstack { 'boolean', 'unlimited', 'literal', true } + end + return true + end + + function operators.readhexstring() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if not (ta == 'string' or ta == 'file') then + return ps_error('typecheck') + end + local thefile = a[8] + local va = a[4] + if va > 0 then + va = get_hexstring_line (a,b) + else + local prefix, result, n = nil, { }, 0 + -- todo: read #va bytes and lpeg + while true do + local b = thefile:read(1) + if not b then + break + end + local hexbyte = tonumber(b,16) + local nmax = b[6] + if not hexbyte then + -- skip + elseif prefix then + n = n + 1 + result[n] = char(prefix*16+hexbyte) + if n == nmax then + break + else + prefix = nil + end + else + prefix = hexbyte + end + end + va = concat(result) + end + local thestring = get_VM(b[4]) + local n = #va + VM[b[4]] = repl .. sub(thestring,n+1,-1) + push_opstack { b[1], b[2], b[3], add_VM(va), n, n } + push_opstack { 'boolean', 'unlimited', 'literal', n == b[6] } + return true + end + +end + +function operators.flush() + io.flush() + return true +end + +function operators.bytesavailable() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[7] ~= 'r' then + return ps_error('typecheck') + end + local waiting = (a[4] > 0) and (a[6] - a[5] + 1) or -1 + push_opstack { "integer", "unlimited", "literal", waiting } + return true +end + +-- this does not really do anything useful + +function operators.resetfile() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + return true +end + +function operators.flushfile() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[4] > 0 then + a[5] = a[6] + else + a[8]:flush() + end + return true +end + +function operators.closefile() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + if a[7] == 'r' then + a[5] = a[6] + else + push_opstack(a) + operators.flushfile() + end + a[8]:close() + return true +end + +function operators.status() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'file' then + return ps_error('typecheck') + end + local state = io.type(a[8]) + push_opstack { "boolean", 'unlimited', 'literal', not state or state == "closed file" } + return true +end + +function operators.run() + push_opstack { "string", "unlimited", "literal", add_VM("r"), 1, 1 } + local ret, err = operators.file() + if not ret then + return ret, err + end + ret, err = operators.cvx() + if not ret then + return ret, err + end + local a = pop_opstack() -- an executable file + push_execstack { ".run", "unlimited", "literal", false } -- constant + local curstack = execstackptr + local thefile = a[8] + push_execstack(a) + while curstack < execstackptr do + do_exec() + end + local state = io.type(thefile) + if not state or state == "closed file" then + -- okay + else + thefile:close() + end + if execstackptr > 0 then + local entry = execstack[execstackptr] + if entry[1] == '.run' and entry[4] == true then + pop_execstack() + end + end + return true +end + +function operators.currentfile() + local n = execstackptr + while n >= 0 do + local entry = execstack[n] + if entry[1] == 'file' and entry[7] == 'r' then + push_opstack(entry) + return true + end + n = n - 1 + end + push_opstack { 'file', 'unlimited', 'executable', add_VM(''), 0, 0, 'r', stdin } + return true +end + +function operators.print() + local a = pop_opstack() + if not a then return + ps_error('stackunderflow') + end + if a[1] ~= 'string' then + return ps_error('typecheck') + end + report(get_VM(a[4])) +end + +-- '=' is also defined as a procedure below; +-- +-- it is actually supposed to do this: "equaldict begin dup type exec end" +-- where each of the entries in equaldict handles one type only, but this +-- works just as well + +do + + local pattern = Cs( + Cc("(") + * ( + P("\n") / "\\n" + + P("\r") / "\\r" + + P("(") / "\\(" + + P(")") / "\\)" + + P("\\") / "\\\\" + + P("\b") / "\\b" + + P("\t") / "\\t" + + P("\f") / "\\f" + + R("\000\032","\127\255") / tonumber / formatters["\\%03o"] + + P(1) + )^0 + * Cc(")") + ) + + -- print(lpegmatch(pattern,[[h(a\nn)s]])) + + local function do_operator_equal(a) + local ta, va = a[1], a[4] + if ta == 'real' then + if floor(va) == va then + return tostring(va .. '.0') + else + return tostring(va) + end + elseif ta == 'integer' then + return tostring(va) + elseif ta == 'string' then + return lpegmatch(pattern,get_VM(va)) + elseif ta == 'boolean' then + return tostring(va) + elseif ta == 'operator' then + return '--' .. a[5] .. '--' + elseif ta == 'name' then + if a[3] == 'literal' then + return '/' .. get_VM(va) + else + return get_VM(va) + end + elseif ta == 'array' then + va = get_VM(va) + local isexec = a[3] == 'executable' + local result = { isexec and "{" or "[" } + local n = 1 + for i=1,#va do + n = n + 1 + result[n] = do_operator_equal(va[i]) + end + result[n+1] = isexec and "}" or "]" + return concat(result," ") + elseif ta == 'null' then + return 'null' + elseif ta == 'dict' then + return '-dicttype-' + elseif ta == 'save' then + return '-savetype-' + elseif ta == 'mark' then + return '-marktype-' + elseif ta == 'file' then + return '-filetype-' + elseif ta == 'font' then + return '-fonttype-' + end + end + + function operators.equal() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + report(do_operator_equal(a)) + return true + end + +end + +local function commonstack(seperator) + for n=1,opstackptr do + push_opstack { 'string', 'unlimited', 'literal', add_VM(seperator), 1 ,1 } + push_opstack(opstack[n]) + push_execstack { 'operator','unlimited','executable', operators.print, 'print'} + push_execstack { 'operator','unlimited','executable', operators.equal, '=='} + end + return true +end + +function operators.pstack() + return commonstack("\n") +end + +function operators.stack() + return commonstack(" ") +end + +-- this does not really do anything useful + +function operators.echo() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'boolean' then + return ps_error('typecheck') + end + return true +end + +-- Virtual memory operators +-- +-- +save +restore +vmstatus + +-- to be checked: we do a one-level shallow copy now, not sure if that +-- is good enough yet + +local savelevel = 0 + +initializers[#initializers+1] = function(reset) + savelevel = 0 +end + +function operators.save() + local saved_VM = { } + for k1, v1 in next, VM do + if type(v1) == "table" then + local t1 = { } + saved_VM[k1] = t1 + for k2, v2 in next, t1 do + if type(v2) == "table" then + local t2 = { } + t1[k2] = t2 + for k3, v3 in next, v2 do + t2[k3] = v3 + end + else + t1[k2] = v2 + end + end + else + saved_VM[k1] = v1 + end + end + push_gsstack { 'save', copy_gsstate() } + savelevel = savelevel + 1 + push_opstack { 'save', 'unlimited', 'executable', add_VM(saved_VM) } +end + +do + + local function validstack(stack,index,saved_VM) + -- loop over pstack, execstack, and dictstack to make sure + -- there are no entries with VM_id > #saved_VM + for i=index,1,-1 do + local v = stack[i] + if type(v) == "table" then + local tv = v[1] + if tv == "save" or tv == "string" or tv == "array" or tv == "dict" or tv == "name" or tv == "file" then + -- todo: check on %stdin/%stdout, but should be ok + if v[4] > #saved_VM then + return false + end + end + end + i = i - 1 + end + return true + end + + function operators.restore() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'save' then + return ps_error('typecheck') + end + if a[4] == 0 or savelevel == 0 then + return ps_error('invalidrestore') + end + local saved_VM = get_VM(a[4]) + if directvm then + else + if not validstack(execstack,execstackptr,saved_VM) then + return ps_error('invalidrestore') + end + if not validstack(dictstack,dictstackptr,saved_VM) then + return ps_error('invalidrestore') + end + if not validstack(opstack,opstackptr,saved_VM) then + return ps_error('invalidrestore') + end + end + while gsstackptr > 0 do + local g = gsstack[gsstackptr] + gsstackptr = gsstackptr - 1 + if g[1] == "save" then + gsstate = g[2] + return + end + end + a[4] = 0 -- invalidate save object + savelevel = savelevel - 1 + VM = saved_VM + end + +end + +function operators.vmstatus() + local n = 0 -- #VM * 100 + push_opstack { 'integer', 'unlimited', 'literal', savelevel } + push_opstack { 'integer', 'unlimited', 'literal', n } + push_opstack { 'integer', 'unlimited', 'literal', n } + return true +end + +-- Miscellaneous operators +-- +-- +bind +null +usertime +version + +-- the reference manual says bind only ERRORS on typecheck + +local function bind() + local a = pop_opstack() + if not a then + return true -- ps_error('stackunderflow') + end + if not a[1] == 'array' then + return ps_error('typecheck') + end + local proc = get_VM(a[4]) + for i=1,#proc do + local v = proc[i] + local t = v[1] + if t == 'name' then + if v[3] == 'executable' then + local op = lookup(get_VM(v[4])) + if op and op[1] == 'operator' then + proc[i] = op + end + end + elseif t == 'array' then + if v[2] == 'unlimited' then + push_opstack(v) + bind() -- recurse + pop_opstack() + proc[i][2] = 'read-only' + end + end + end + push_opstack(a) +end + +operators.bind = bind + +function operators.null() + push_opstack { 'null', 'unlimited', 'literal' } + return true +end + +function operators.usertime() + push_opstack { 'integer', 'unlimited', 'literal', floor(os.clock() * 1000) } + return true +end + +function operators.version() + push_opstack { 'string', 'unlimited', 'literal', add_VM('23.0') } + return true +end + +-- Graphics state operators +-- +-- +gsave +grestore +grestoreall +initgraphics +setlinewidth +currentlinewidth +setlinecap +currentlinecap +-- +setlinejoin +currentlinejoin +setmiterlimit +currentmiterlimit +setdash +currentdash +setflat +currentflat +-- +setgray +currentgray +sethsbcolor +currenthsbcolor +setrgbcolor +setcmykcolor +currentrgbcolor +setscreen +-- +currentscreen +settransfer +currenttransfer + +function operators.gsave() + push_gsstack { 'gsave', copy_gsstate() } + return true +end + +function operators.grestore() + if gsstackptr > 0 then + local g = gsstack[gsstackptr] + if g[1] == "gsave" then + gsstackptr = gsstackptr - 1 + gsstate = g[2] + end + end + return true +end + +function operators.grestoreall() -- needs checking + for i=gsstackptr,1,-1 do + local g = gsstack[i] + if g[1] == "save" then + gsstate = g[2] + gsstackptr = i + return true + end + end + gsstackptr = 0 + return true +end + +function operators.initgraphics() + local newstate = copy_gsstate() -- hm + newstate.matrix = { 1, 0, 0, 1, 0, 0 } + newstate.color = { gray = 0, hsb = { }, rgb = { }, cmyk = { }, type = "gray" } + newstate.position = { } -- actual x and y undefined + newstate.path = { } + newstate.linewidth = 1 + newstate.linecap = 0 + newstate.linejoin = 0 + newstate.miterlimit = 10 + newstate.dashpattern = { } + newstate.dashoffset = 0 + gsstate = newstate + device.initgraphics() + operators.initclip() + return true +end + +function operators.setlinewidth() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local t = a[1] + if not (t == 'integer' or t == 'real') then + return ps_error('typecheck') + end + gsstate.linewidth = a[4] + return true +end + +function operators.currentlinewidth() + local w = gsstate.linewidth + push_opstack { + (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer', + 'unlimited', + 'literal', + w, + } + return true +end + +function operators.setlinecap() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'integer' then + return ps_error('typecheck') + end + local c = a[4] + if c > 2 or c < 0 then + return ps_error('rangecheck') + end + gsstate.linecap = c + return true +end + +function operators.currentlinecap() + push_opstack { 'integer', 'unlimited', 'literal', gsstate.linecap } + return true +end + +function operators.setlinejoin() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'integer' then + return ps_error('typecheck') + end + local j = a[4] + if j > 2 or j < 0 then + return ps_error('rangecheck') + end + gsstate.linejoin = j + return true +end + +function operators.currentlinejoin() + push_opstack { 'integer', 'unlimited', 'literal', gsstate.linejoin } + return true +end + +function operators.setmiterlimit() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local t = a[1] + if not (t == 'integer' or t == 'real') then + return ps_error('typecheck') + end + local m = a[4] + if m < 1 then + return ps_error('rangecheck') + end + gsstate.miterlimit = m + return true +end + +function operators.currentmiterlimit() + local w = gsstate.miterlimit + push_opstack { + (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer', + 'unlimited', + 'literal', + w + } + return true +end + +function operators.setdash() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if ta ~= 'array' then + return ps_error('typecheck') + end + if not (tb == 'integer' or tb == 'real') then + return ps_error('typecheck') + end + local pattern = { } + local total = 0 + local thearray = get_VM(a[4]) + for i=1,#thearray do + local a = thearray[i] + local ta, va = a[1], a[4] + if ta ~= "integer" then + return ps_error('typecheck') + end + if va < 0 then + return ps_error('limitcheck') + end + total = total + va + pattern[#pattern+1] = va + end + if #pattern > 0 and total == 0 then + return ps_error('limitcheck') + end + gsstate.dashpattern = pattern + gsstate.dashoffset = b[4] + return true +end + +function operators.currentdash() + local thearray = gsstate.dashpattern + local pattern = { } + for i=1,#thearray do + pattern[i] = { 'integer', 'unlimited', 'literal', thearray[i] } + end + push_opstack { 'array', 'unlimited', 'literal', add_VM(pattern), #pattern, #pattern } + local w = gsstate.dashoffset + push_opstack { + (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer', 'unlimited', 'literal', w + } + return true +end + +function operators.setflat() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, va = a[1], a[4] + if not (ta == 'integer' or ta == 'real') then + return ps_error('typecheck') + end + gsstate.flatness = va + return true +end + +function operators.currentflat() + local w = gsstate.flatness + push_opstack { + (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer', 'unlimited', 'literal', w + } + return true +end + +-- Color conversion functions +-- +-- normally, level one colors are based on hsb, but for our backend it is better to +-- stick with the original request when possible + +do + + local function rgb_to_gray (r, g, b) + return 0.30 * r + 0.59 * g + 0.11 * b + end + + local function cmyk_to_gray (c, m, y, k) + return 0.30 * (1.0 - min(1.0,c+k)) + 0.59 * (1.0 - min(1.0,m+k)) + 0.11 * (1.0 - min(1.0,y+k)) + end + + local function cmyk_to_rgb (c, m, y, k) + return 1.0 - min(1.0,c+k), 1.0 - min(1.0,m+k), 1.0 - min(1.0,y+k) + end + + local function rgb_to_hsv(r, g, b) + local offset, maximum, other_1, other_2 + if r >= g and r >= b then + offset, maximum, other_1, other_2 = 0, r, g, b + elseif g >= r and g >= b then + offset, maximum, other_1, other_2 = 2, g, b, r + else + offset, maximum, other_1, other_2 = 4, b, r, g + end + if maximum == 0 then + return 0, 0, 0 + end + local minimum = other_1 < other_2 and other_1 or other_2 + if maximum == minimum then + return 0, 0, maximum + end + local delta = maximum - minimum + return (offset + (other_1-other_2)/delta)/6, delta/maximum, maximum + end + + local function gray_to_hsv (col) + return 0, 0, col + end + + local function gray_to_rgb (col) + return 1-col, 1-col, 1-col + end + + local function gray_to_cmyk (col) + return 0, 0, 0, col + end + + local function hsv_to_rgb(h,s,v) + local hi = floor(h * 6.0) % 6 + local f = (h * 6) - floor(h * 6) + local p = v * (1 - s) + local q = v * (1 - f * s) + local t = v * (1 - (1 - f) * s) + if hi == 0 then + return v, t, p + elseif hi == 1 then + return q, v, p + elseif hi == 2 then + return p, v, t + elseif hi == 3 then + return p, q, v + elseif hi == 4 then + return t, p, v + elseif hi == 5 then + return v, p, q + end + end + + local function hsv_to_gray(h,s,v) + return rgb_to_gray(hsv_to_rgb(h,s,v)) + end + + -- color operators + + function operators.setgray() + local g = pop_opstack() + if not g then + return ps_error('stackunderflow') + end + local gt = g[1] + if not (gt == 'integer' or gt == 'real') then + return ps_error('typecheck') + end + local gv = g[4] + local color = gsstate.color + color.type = "gray" + color.gray = (gv < 0 and 0) or (gv > 1 and 1) or gv + return true + end + + function operators.currentgray() + local color = gsstate.color + local t = color.type + local s + if t == "gray" then + s = color.gray + elseif t == "rgb" then + local col = color.rgb + s = rgb_to_gray(col[1],col[2],col[3]) + elseif t == "cmyk" then + local col = cmyk + s = cmyk_to_gray(col[1],col[2],col[3],col[4]) + else + local col = color.hsb + s = hsv_to_gray(col[1],col[2],col[3]) + end + push_opstack { (s == 0 or s == 1) and 'integer' or 'real', 'unlimited', 'literal', s } + return true + end + + function operators.sethsbcolor() + local b = pop_opstack() + local s = pop_opstack() + local h = pop_opstack() + if not h then + return ps_error('stackunderflow') + end + local ht, st, bt = h[1], s[1], b[1] + if not (ht == 'integer' or ht == 'real') then + return ps_error('typecheck') + end + if not (st == 'integer' or st == 'real') then + return ps_error('typecheck') + end + if not (bt == 'integer' or bt == 'real') then + return ps_error('typecheck') + end + local hv, sv, bv = h[4], s[4], b[4] + local color = gsstate.color + color.type = "hsb" + color.hsb = { + (hv < 0 and 0) or (hv > 1 and 1) or hv, + (sv < 0 and 0) or (sv > 1 and 1) or sv, + (bv < 0 and 0) or (bv > 1 and 1) or bv, + } + return true + end + + function operators.currenthsbcolor() + local color = gsstate.color + local t = color.type + local h, s, b + if t == "gray" then + h, s, b = gray_to_hsv(color.gray) + elseif t == "rgb" then + local col = color.rgb + h, s, b = rgb_to_hsv(col[1],col[2],col[3]) + elseif t == "cmyk" then + local col = color.cmyk + h, s, b = cmyk_to_hsv(col[1],col[2],col[3],col[4]) + else + local col = color.hsb + h, s, b = col[1], col[2], col[3] + end + push_opstack { (h == 0 or h == 1) and 'integer' or 'real', 'unlimited', 'literal', h } + push_opstack { (s == 0 or s == 1) and 'integer' or 'real', 'unlimited', 'literal', s } + push_opstack { (b == 0 or b == 1) and 'integer' or 'real', 'unlimited', 'literal', b } + return true + end + + function operators.setrgbcolor() + local b = pop_opstack() + local g = pop_opstack() + local r = pop_opstack() + if not r then + return ps_error('stackunderflow') + end + local rt, gt, bt = r[1], g[1], b[1] + if not (rt == 'integer' or rt == 'real') then + return ps_error('typecheck') + end + if not (gt == 'integer' or gt == 'real') then + return ps_error('typecheck') + end + if not (bt == 'integer' or bt == 'real') then + return ps_error('typecheck') + end + local rv, gv, bv = r[4], g[4], b[4] + local color = gsstate.color + color.type = "rgb" + color.rgb = { + (rv < 0 and 0) or (rv > 1 and 1) or rv, + (gv < 0 and 0) or (gv > 1 and 1) or gv, + (bv < 0 and 0) or (bv > 1 and 1) or bv, + } + return true + end + + function operators.currentrgbcolor() + local color = gsstate.color + local t = color.type + local r, g, b + if t == "gray" then + r, g, b = gray_to_rgb(color.gray) + elseif t == "rgb" then + local col = color.rgb + r, g, b = col[1], col[2], col[3] + elseif t == "cmyk" then + r, g, b = cmyk_to_rgb(color.cmyk) + else + local col = color.hsb + r, g, b = hsv_to_rgb(col[1], col[2], col[3]) + end + push_opstack { (r == 0 or r == 1) and "integer" or "real", 'unlimited', 'literal', r } + push_opstack { (g == 0 or g == 1) and "integer" or "real", 'unlimited', 'literal', g } + push_opstack { (b == 0 or b == 1) and "integer" or "real", 'unlimited', 'literal', b } + return true + end + + function operators.setcmykcolor() + local k = pop_opstack() + local y = pop_opstack() + local m = pop_opstack() + local c = pop_opstack() + if not c then + return ps_error('stackunderflow') + end + local ct, mt, yt, kt = c[1], m[1], y[1], k[1] + if not (ct == 'integer' or ct == 'real') then + return ps_error('typecheck') + end + if not (mt == 'integer' or mt == 'real') then + return ps_error('typecheck') + end + if not (yt == 'integer' or yt == 'real') then + return ps_error('typecheck') + end + if not (kt == 'integer' or kt == 'real') then + return ps_error('typecheck') + end + local cv, mv, yv, kv = c[4], m[4], y[4], k[4] + local color = gsstate.color + color.type = "cmyk" + color.cmyk = { + (cv < 0 and 0) or (cv > 1 and 1) or cv, + (mv < 0 and 0) or (mv > 1 and 1) or mv, + (yv < 0 and 0) or (yv > 1 and 1) or yv, + (kv < 0 and 0) or (kv > 1 and 1) or kv, + } + return true + end + + function operators.currentcmykcolor() + local color = gsstate.color + local t = color.type + local c, m, y, k + if t == "gray" then + c, m, y, k = gray_to_cmyk(color.gray) + elseif t == "rgb" then + c, m, y, k = rgb_to_cmyk(color.rgb) + elseif t == "cmyk" then + local col = color.cmyk + c, m, y, k = col[1], col[2], col[3], col[4] + else + local col = color.hsb + c, m, y, k = hsv_to_cmyk(col[1], col[2], col[3]) + end + push_opstack { (c == 0 or c == 1) and "integer" or "real", 'unlimited', 'literal', c } + push_opstack { (m == 0 or m == 1) and "integer" or "real", 'unlimited', 'literal', m } + push_opstack { (y == 0 or y == 1) and "integer" or "real", 'unlimited', 'literal', y } + push_opstack { (k == 0 or k == 1) and "integer" or "real", 'unlimited', 'literal', k } + return true + end + +end + +function operators.setscreen() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc, ac = a[1], b[1], c[1], c[3] + if not (tc == 'array' and ac == 'executable') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + local va, vb, vc = a[4], b[4], c[4] + if vb < 0 or vb > 360 then + return ps_error('rangecheck') + end + if va < 0 then + return ps_error('rangecheck') + end + gsstate.screen = { va, vb, vc } + return true +end + +function operators.currentscreen() + local w + if not gsstate.screen then + local popper = { 'operator', 'unlimited', 'executable', operators.pop, 'pop' } + push_opstack { 'integer', 'unlimited', 'literal', 1 } + push_opstack { 'integer', 'unlimited', 'literal', 0 } + push_opstack { 'array', 'unlimited', 'executable', add_VM{ popper }, 1, 1, 'd' } + else + local w1 = gsstate.screen[1] + local w2 = gsstate.screen[2] + local w3 = gsstate.screen[3] + push_opstack { + (abs(w) > MAX_INT or floor(w1) ~= w1) and 'real' or 'integer', 'unlimited', 'literal', w1 + } + push_opstack { + (abs(w) > MAX_INT or floor(w2) ~= w2) and 'real' or 'integer', 'unlimited', 'literal', w2 + } + local thearray = get_VM(w3) + push_opstack { 'array', 'unlimited', 'executable', w3, 1, #thearray, 'd' } -- w3 or thearray ? + end + return true +end + +function operators.settransfer() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not (a[1] == 'array' and a[3] == 'executable') then + return ps_error('typecheck') + end + local va = a[4] + if va < 0 then + return ps_error('rangecheck') + end + gsstate.transfer = va + return true +end + +function operators.currenttransfer() + local transfer = gsstate.transfer + if not transfer then + push_opstack { 'array', 'unlimited', 'executable', add_VM{ }, 0, 0, 'd'} + else + local thearray = get_VM(transfer) + push_opstack { 'array', 'unlimited', 'executable', transfer, 1, #thearray, 'd' } + end + return true +end + +-- Coordinate system and matrix operators +-- +-- +matrix +initmatrix +identmatrix +defaultmatrix +currentmatrix +setmatrix +translate +-- +scale +rotate +concat +concatmatrix +transform +dtransform +itransform +idtransform +-- +invertmatrix + +-- are these changed in place or not? if not then we can share + +function operators.matrix() + local matrix = { + {'real', 'unlimited', 'literal', 1}, + {'real', 'unlimited', 'literal', 0}, + {'real', 'unlimited', 'literal', 0}, + {'real', 'unlimited', 'literal', 1}, + {'real', 'unlimited', 'literal', 0}, + {'real', 'unlimited', 'literal', 0}, + } + push_opstack { 'array', 'unlimited', 'literal', add_VM(matrix), 6, 6 } + return true +end + +function operators.initmatrix() + gsstate.matrix = { 1, 0, 0, 1, 0, 0 } + return true +end + +function operators.identmatrix() + local a = pop_opstack() + if not a then return + ps_error('stackunderflow') + end + if a[1] ~= 'array' then + return ps_error('typecheck') + end + if a[6] < 6 then + return ps_error('rangecheck') + end + local m = VM[a[4]] -- or can we replace the numbers + m[1] = { 'real', 'unlimited', 'literal', 1 } + m[2] = { 'real', 'unlimited', 'literal', 0 } + m[3] = { 'real', 'unlimited', 'literal', 0 } + m[4] = { 'real', 'unlimited', 'literal', 1 } + m[5] = { 'real', 'unlimited', 'literal', 0 } + m[6] = { 'real', 'unlimited', 'literal', 0 } + a[5] = 6 + push_opstack(a) + return true +end + +operators.defaultmatrix = operators.identmatrix + +function operators.currentmatrix() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'array' then + return ps_error('typecheck') + end + if a[6] < 6 then + return ps_error('rangecheck') + end + local thearray = get_VM(a[4]) + local matrix = gsstate.matrix + for i=1,6 do + thearray[i] = {'real', 'unlimited', 'literal', matrix[i]} + end + push_opstack { 'array', 'unlimited', 'literal', a[4], 6, 6 } + return true +end + +function operators.setmatrix() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'array' then + return ps_error('typecheck') + end + if a[6] ~= 6 then + return ps_error('rangecheck') + end + local thearray = get_VM(a[4]) + local matrix = gsstate.matrix + for i=1,#thearray do + local a = thearray[i] + local ta, tv = a[1], a[4] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if i > 6 then + return ps_error('rangecheck') + end + matrix[i] = va + end + return true +end + +local function do_transform(matrix,a,b) + local x = matrix[1] * a + matrix[3] * b + matrix[5] + local y = matrix[2] * a + matrix[4] * b + matrix[6] + return x, y +end + +local function do_itransform(matrix,a,b) + local m1 = matrix[1] + local m4 = matrix[4] + if m1 == 0 or m4 == 0 then + return nil + end + local x = (a - matrix[5] - matrix[3] * b) / m1 + local y = (b - matrix[6] - matrix[2] * a) / m4 + return x, y +end + +local function do_concat (a,b) + local a1, a2, a3, a4, a5, a6 = a[1], a[2], a[3], a[4], a[5], a[6] + local b1, b2, b3, b4, b5, b6 = b[1], b[2], b[3], b[4], b[5], b[6] + local c1 = a1 * b1 + a2 * b3 + local c2 = a1 * b2 + a2 * b4 + local c3 = a1 * b3 + a3 * b4 + local c4 = a3 * b2 + a4 * b4 + local c5 = a5 * b1 + a6 * b3 + b5 + local c6 = a5 * b2 + a6 * b4 + b6 + -- this is because double calculation introduces a small error + return { + abs(c1) < 1.0e-16 and 0 or c1, + abs(c2) < 1.0e-16 and 0 or c2, + abs(c3) < 1.0e-16 and 0 or c3, + abs(c4) < 1.0e-16 and 0 or c4, + abs(c5) < 1.0e-16 and 0 or c5, + abs(c6) < 1.0e-16 and 0 or c6, + } +end + +local function do_inverse (a) + local a1, a2, a3, a4, a5, a6 = a[1], a[2], a[3], a[4], a[5], a[6] + local det = a1 * a4 - a3 * a2 + if det == 0 then + return nil + end + local c1 = a4 / det + local c3 = -a3 / det + local c2 = -a2 / det + local c4 = a1 / det + local c5 = (a3 * a6 - a5 * a4) / det + local c6 = (a5 * a2 - a1 * a6) / det + return { + abs(c1) < 1.0e-16 and 0 or c1, + abs(c2) < 1.0e-16 and 0 or c2, + abs(c3) < 1.0e-16 and 0 or c3, + abs(c4) < 1.0e-16 and 0 or c4, + abs(c5) < 1.0e-16 and 0 or c5, + abs(c6) < 1.0e-16 and 0 or c6, + } +end + +function operators.translate() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] == 'array' then + if a[6] ~= 6 then + return ps_error('typecheck') + end + local tf = a + local a = pop_opstack() + local b = pop_opstack() + if not b then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + local m = VM[tf[4]] + local old = { m[1][4], m[2][4], m[3][4], m[4][4], m[5][4], m[6][4] } + local c = do_concat(old,{1,0,0,1,b[4],a[4]}) + for i=1,6 do + m[i] = { 'real', 'unlimited', 'literal', c[i] } + end + tf[5] = 6 + push_opstack(tf) + else + local b = pop_opstack() + local ta = a[1] + local tb = b[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + gsstate.matrix = do_concat(gsstate.matrix,{1,0,0,1,b[4],a[4]}) + end + return true +end + +function operators.scale() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'array' then + local tf = a + if a[6] ~= 6 then + return ps_error('typecheck') + end + local a = pop_opstack() + local b = pop_opstack() + if not b then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + local v = VM[tf[4]] + local c = do_concat ( + { v[1][4], v[2][4], v[3][4], v[4][4], v[5][4], v[6][4] }, + { b[4], 0, 0, a[4], 0, 0 } + ) + for i=1,6 do + v[i] = { 'real', 'unlimited', 'literal', c[i] } + end + tf[5] = 6 + push_opstack(tf) + else + local b = pop_opstack() + if not b then + return ps_error('stackunderflow') + end + local ta, tb = a[1], b[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + gsstate.matrix = do_concat(gsstate.matrix, { b[4], 0, 0, a[4], 0, 0 }) + end + return true +end + +function operators.concat() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= "array" then + return ps_error('typecheck') + end + if a[6] ~= 6 then + return ps_error('typecheck') + end + local thearray = get_VM(a[4]) + local l = { } + for i=1,#thearray do + local v = thearray[i] + local t = v[1] + if not (t == 'real' or t == 'integer') then + return ps_error('typecheck') + end + l[i] = v[4] + end + gsstate.matrix = do_concat(gsstate.matrix,l) + return true +end + +function operators.concatmatrix() + local tf = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if tf[1] ~= "array" then return ps_error('typecheck') end + if b [1] ~= "array" then return ps_error('typecheck') end + if a [1] ~= "array" then return ps_error('typecheck') end + if tf[6] ~= 6 then return ps_error('typecheck') end + if b [6] ~= 6 then return ps_error('typecheck') end + if a [6] ~= 6 then return ps_error('typecheck') end + local al = { } + local thearray = get_VM(a[4]) + for i=1,#thearray do + local v = thearray[i] + local tv = v[1] + if not (tv == 'real' or tv == 'integer') then + return ps_error('typecheck') + end + al[i] = v[4] + end + local bl = { } + local thearray = get_VM(b[4]) + for i=1,#thearray do + local v = thearray[i] + local tv = v[1] + if not (tv == 'real' or tv == 'integer') then + return ps_error('typecheck') + end + bl[i] = v[4] + end + local c = do_concat(al, bl) + local m = VM[tf[4]] + for i=1,6 do + m[i] = { 'real', 'unlimited', 'literal', c[i] } + end + tf[5] = 6 + push_opstack(tf) + return true +end + +function operators.rotate() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta = a[1] + if ta == 'array' then + local tf + if a[6] ~= 6 then + return ps_error('typecheck') + end + tf = a + a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not (a[1] == 'real' or a[1] == 'integer') then + return ps_error('typecheck') + end + local m = VM[tf[4]] + local old = { m[1][4], m[2][4], m[3][4], m[4][4], m[5][4], m[6][4] } + local av = a[4] + local c = do_concat (old, {cos(rad(av)),sin(rad(av)),-sin(rad(av)),cos(rad(av)), 0, 0}) + for i=1,6 do + m[i] = { 'real', 'unlimited', 'literal', c[i] } + end + push_opstack(tf) + elseif ta == 'real' or ta == 'integer' then + local av = a[4] + gsstate.matrix = do_concat(gsstate.matrix,{cos(rad(av)),sin(rad(av)),-sin(rad(av)),cos(rad(av)),0,0}) + else + return ps_error('typecheck') + end + return true +end + +function operators.transform() + local a = pop_opstack() + local b = pop_opstack() + if not b then + ps_error('stackunderflow') + end + local tf + if a[1] == 'array' then + if a[6] ~= 6 then + return ps_error('typecheck') + end + local thearray = get_VM(a[4]) + tf = { } + for i=1,#thearray do + local v = thearray[i] + local v1 = v[1] + if not (v1 == 'real' or v1 == 'integer') then + return ps_error('typecheck') + end + tf[i] = v[4] + end + a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + else + tf = gsstate.matrix + end + local a1 = a[1] + local b1 = b[1] + if not (a1 == 'real' or a1 == 'integer') then + return ps_error('typecheck') + end + if not (b1 == 'real' or b1 == 'integer') then + return ps_error('typecheck') + end + local x, y = do_transform(tf,b[4],a[4]); + push_opstack { 'real', 'unlimited', 'literal', x } + push_opstack { 'real', 'unlimited', 'literal', y } + return true +end + +local function commontransform() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local tf + if a[1] == 'array' then + if a[6] ~= 6 then + return ps_error('typecheck') + end + tf = { } + local thearray = get_VM(a[4]) + for i=1,#thearray do + local v = thearray[i] + local tv = v[1] + if not (tv == 'real' or tv == 'integer') then + return ps_error('typecheck') + end + tf[i] = v[4] + end + a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + else + tf = gsstate.matrix + end + local b = pop_opstack() + if not b then + return ps_error('stackunderflow') + end + local ta = a[1] + local tb = b[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + return true, tf, a, b +end + +function operators.dtransform() + local ok, tf, a, b = commontransform() + if ok then + local x, y = do_transform({tf[1],tf[2],tf[3],tf[4],0,0},b[4],a[4]) + if not x then + return ps_error('undefinedresult') + end + push_opstack { 'real', 'unlimited', 'literal', x } + push_opstack { 'real', 'unlimited', 'literal', y } + return true + else + return false, tf + end +end + +function operators.itransform() + local ok, tf, a, b = commontransform() + if ok then + local x, y = do_itransform(tf,b[4],a[4]) + if not x then + return ps_error('undefinedresult') + end + push_opstack { 'real', 'unlimited', 'literal', x } + push_opstack { 'real', 'unlimited', 'literal', y } + return true + else + return false, tf + end +end + +function operators.idtransform() + local ok, tf, a, b = commontransform() + if ok then + local x,y = do_itransform({tf[1],tf[2],tf[3],tf[4],0,0},b[4],a[4]); + if not x then + return ps_error('undefinedresult') + end + push_opstack { 'real', 'unlimited', 'literal', x } + push_opstack { 'real', 'unlimited', 'literal', y } + return true + else + return false, tf + end +end + +function operators.invertmatrix() + local tf = pop_opstack() + if not tf then + return ps_error('stackunderflow') + end + if tf[1] ~= "array" then + return ps_error('typecheck') + end + if tf[6] ~= 6 then + return ps_error('typecheck') + end + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= "array" then + return ps_error('typecheck') + end + if a[6] ~= 6 then + return ps_error('typecheck') + end + local al = { } + local thearray = get_VM(a[4]) + for i=1,#thearray do + local v = thearray[i] + local tv = v[1] + if not (tv == 'real' or tv == 'integer') then + return ps_error('typecheck') + end + al[i] = v[4] + end + local c = do_inverse(al) + if not c then + return ps_error('undefinedresult') + end + local m = VM[tf[4]] + for i=1,6 do + m[i] = { 'real', 'unlimited', 'literal', c[i] } + end + tf[5] = 6 + push_opstack(tf) + return true +end + +-- Path construction operators +-- +-- +newpath +currentpoint +moveto +rmoveto +lineto +rlineto +arc +arcn +arcto +curveto +rcurveto +-- +closepath +flattenpath -reversepath -strokepath -charpath +clippath -pathbbox -pathforall +-- +initclip *clip *eoclip + +function operators.newpath() + gsstate.path = { } + gsstate.position = { } + return true +end + +function operators.currentpoint() + local position = gsstate.position + if #position == 0 then + return ps_error('nocurrentpoint') + end + local x, y = do_itransform(gsstate.matrix, position[1], position[2]) + if not x then + return ps_error('undefinedresult') + end + push_opstack { 'real', 'unlimited', 'literal', x } + push_opstack { 'real', 'unlimited', 'literal', y } +end + +function operators.moveto() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local b1 = b[1] + local a1 = a[1] + if not (b1 == 'real' or b1 == 'integer') then + return ps_error('typecheck') + end + if not (a1 == 'real' or a1 == 'integer') then + return ps_error('typecheck') + end + local path = gsstate.path + local length = #path + local x, y = do_transform(gsstate.matrix, a[4], b[4]) + if length > 0 and path[length][1] == "moveto" then + -- replace last moveto + else + length = length + 1 + end + path[length] = { "moveto", x, y } + gsstate.position = { x, y } + return true +end + +function operators.rmoveto() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local bt = b[1] + local at = a[1] + if not (bt == 'real' or bt == 'integer') then + return ps_error('typecheck') + end + if not (at == 'real' or at == 'integer') then + return ps_error('typecheck') + end + local position = gsstate.position + local path = gsstate.path + local length = #path + if #position == 0 then + return ps_error('nocurrentpoint') + end + local x, y = do_transform(gsstate.matrix, a[4], b[4]) + x = position[1] + x + y = position[2] + y + position[1] = x + position[2] = y + if length > 0 and path[length][1] == "moveto" then + -- replace last moveto + else + length = length + 1 + end + path[length] = { "moveto", x, y } + return true +end + +function operators.lineto() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local at = a[1] + local bt = b[1] + if not (bt == 'real' or bt == 'integer') then + return ps_error('typecheck') + end + if not (at == 'real' or at == 'integer') then + return ps_error('typecheck') + end + local position = gsstate.position + local path = gsstate.path + local length = #path + if #position == 0 then + return ps_error('nocurrentpoint') + end + local x, y = do_transform(gsstate.matrix, a[4], b[4]) + gsstate.position = { x, y } + path[length+1] = { "lineto", x, y } + return true +end + +function operators.rlineto() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local at = a[1] + local bt = b[1] + if not (bt == 'real' or bt == 'integer') then + return ps_error('typecheck') + end + if not (at == 'real' or at == 'integer') then + return ps_error('typecheck') + end + local position = gsstate.position + local path = gsstate.path + local length = #path + if #position == 0 then + return ps_error('nocurrentpoint') + end + local x, y = do_transform(gsstate.matrix, a[4], b[4]) + x = position[1] + x + y = position[2] + y + position[1] = x + position[2] = y + path[length+1] = { "lineto", x, y } + return true +end + +local function arc_to_curve (x, y, r, aa, theta) + local th = rad(theta/2.0) + local x0 = cos(th) + local y0 = sin(th) + local x1 = (4.0-x0)/3.0 + local y1 = ((1.0-x0)*(3.0-x0))/(3.0*y0) -- y0 != 0... + local x2 = x1 + local y2 = -y1 + -- local x3 = x0 + -- local y3 = -y0 + + local bezAng = rad(aa) + th + local cBezAng = cos(bezAng) + local sBezAng = sin(bezAng) + + local rx0 = (cBezAng * x0) - (sBezAng * y0) + local ry0 = (sBezAng * x0) + (cBezAng * y0) + local rx1 = (cBezAng * x1) - (sBezAng * y1) + local ry1 = (sBezAng * x1) + (cBezAng * y1) + local rx2 = (cBezAng * x2) - (sBezAng * y2) + local ry2 = (sBezAng * x2) + (cBezAng * y2) + -- local rx3 = (cBezAng * x3) - (sBezAng * y3) + -- local ry3 = (sBezAng * x3) + (cBezAng * y3) + + local px0 = x + r*rx0 + local py0 = y + r*ry0 + local px1 = x + r*rx1 + local py1 = y + r*ry1 + local px2 = x + r*rx2 + local py2 = y + r*ry2 + -- local px3 = x + r*rx3 + -- local py3 = y + r*ry3 + + return px2, py2, px1, py1, px0, py0 -- no px3, py3 +end + +local function arc_start(x,y,r,aa) + local x3 = 1 + local y3 = 0 + local bezAng = rad(aa) + local cBezAng = cos(bezAng) + local sBezAng = sin(bezAng) + local rx3 = (cBezAng * x3) - (sBezAng * y3) + local ry3 = (sBezAng * x3) + (cBezAng * y3) + local px3 = x + r*rx3 + local py3 = y + r*ry3 + return px3, py3 +end + +local function do_arc(matrix,path,x,y,r,aa,ab) + local endx, endy + local segments = floor((ab-aa+44.999999999)/45) + if segments == 0 then + return do_transform(gsstate.matrix, x,y) + end + local theta = (ab-aa) / segments + while segments>0 do + local x1, y1, x2, y2, x3, y3 = arc_to_curve(x,y,r,aa,theta) + local px2, py2 = do_transform(matrix,x2,y2) + local px1, py1 = do_transform(matrix,x1,y1) + endx, endy = do_transform(matrix, x3,y3) + path[#path+1] = { "curveto", px1, py1, px2, py2, endx, endy } + segments = segments - 1 + aa = aa + theta + end + return endx, endy +end + +local function do_arcn(matrix,path,x,y,r,aa,ab) + local endx, endy + local segments = floor((aa-ab+44.999999999)/45) + if segments == 0 then + return do_transform(matrix, x,y) + end + local theta = (aa-ab) / segments + while segments > 0 do + local x1, y1, x2, y2, x3, y3 = arc_to_curve(x,y,r,aa,-theta) + local px1, py1 = do_transform(matrix,x1,y1) + local px2, py2 = do_transform(matrix,x2,y2) + endx, endy = do_transform(matrix,x3,y3) + path[#path+1] = { "curveto", px1 , py1 , px2 , py2 , endx , endy } + segments = segments - 1 + aa = aa - theta + end + return endx, endy +end + +local function commonarc(action) + local e = pop_opstack() + local d = pop_opstack() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc, td, te = a[1], b[1], c[1], d[1], e[1], f[1] + if not (ta == 'real' or ta == 'integer') then return ps_error('typecheck') end + if not (tb == 'real' or tb == 'integer') then return ps_error('typecheck') end + if not (tc == 'real' or tc == 'integer') then return ps_error('typecheck') end + if not (td == 'real' or td == 'integer') then return ps_error('typecheck') end + if not (te == 'real' or te == 'integer') then return ps_error('typecheck') end + local position = gsstate.position + local path = gsstate.path + local matrix = gsstate.matrix + local vd = d[4] + local ve = e[4] + if vd < 0 or ve < 0 or vd > 360 or ve > 360 or (vd-ve) <= 0 then + return ps_error('limitcheck') + end + local r = c[4] + if r == 0 then + ps_error('limitcheck') + end + local x = a[4] + local y = b[4] + local x0, y0 = arc_start(x,y,r,vd) -- find starting points + local startx, starty = do_transform(matrix,x0,y0) + path[#path+1] = { #position == 2 and "lineto" or "moveto", startx, starty } + position[1], position[2] = action(matrix,path,x,y,r,vd,ve) + return true +end + +function operators.arc() + commonarc(do_arc) +end + +function operators.arcn() + commonarc(do_arcn) +end + +local function vlength (a,b) + return sqrt(a^2+b^2) +end + +local function vscal_ (a,b,c) + return a*b, a*c +end + +-- this is of_the_way + +local function between (dist, pa, pb) + local pa1, pa2 = pa[1], pa[2] + local pb1, pb2 = pb[1], pb[2] + return { + pa1 + dist * (pb1 - pa1), + pa2 + dist * (pb2 - pa2), + } +end + +local function sign (a) + return a < 0 and -1 or 1 +end + +local function do_arcto(x,y,r) -- todo: check with original + local h = gsstate.position + local tx1, tx2, ty1, ty2 + local c1, c2 + local x1, x2 = x[1], x[2] + local y1, y2 = y[1], y[2] + local h1, h2 = h[1], h[2] + local ux, uy = x1 - h1, x2 - h2 + local vx, vy = y1 - x1, y2 - x2 + local lx, ly = vlength(ux,uy), vlength(vx,vy) + local sx, sy = ux*vy - uy*vx, ux*vx + uy*vy + if sx == 0 and sy == 0 then + sx = r + sy = 0 + else + sx = r + sy = atan2(sx,sy) + end + local a_arcto = sx*tan(abs(sy)/2) + if sx*sy*lx*ly == 0 then + tx1 = x1 + tx2 = x2 + ty1 = x1 + ty2 = x2 + c1 = x1 + c2 = x2 + else + local tx = between(a_arcto/lx,x,h) + local ty = between(a_arcto/ly,x,y) + local cc, dd = vscal_(sign(sy)*sx/lx,-uy,ux) + tx1 = tx[1] + tx2 = tx[2] + ty1 = ty[1] + ty2 = ty[2] + c1 = tx1 + cc + c2 = tx2 + dd + end + -- now tx is the starting point, ty is the endpoint, + -- c is the center of the circle. find the two angles + local anga = deg(atan2(tx2-c2,tx1-c1)) -- todo, -90 is wrong + local angb = deg(atan2(ty2-c2,ty1-c1)) -- todo, -90 is wrong + return c1, c2, r, anga, angb, tx1, tx2, ty1, ty2 +end + +function operators.arcto() + local e = pop_opstack() + local d = pop_opstack() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc, td, te = a[1], b[2], c[1], d[1], e[1] + if not (ta == 'real' or ta == 'integer') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (tc == 'real' or tc == 'integer') then + return ps_error('typecheck') + end + if not (td == 'real' or td == 'integer') then + return ps_error('typecheck') + end + if not (te == 'real' or te == 'integer') then + return ps_error('typecheck') + end + local x1, y1, x2, y2, r = a[4], b[4], c[4], d[4], e[4] + local position = gsstate.position + local path = gsstate.path + if #position == 0 then + return ps_error('nocurrentpoint') + end + local x, y, r, anga, angb, tx1, tx2, ty1, ty2 = do_arcto({x1,y1},{x2, y2},r) + local vx, vy = do_transform(gsstate.matrix,tx1,tx2) + path[#path+1] = { "lineto", vx, vy } + if anga == angb then + -- do nothing + elseif anga > angb then + position[1], position[2] = do_arcn(x,y,r,anga,angb) + else + position[1], position[2] = do_arc (x,y,r,anga,angb) + end + push_opstack { 'real', 'unlimited', 'literal', tx1 } + push_opstack { 'real', 'unlimited', 'literal', tx2 } + push_opstack { 'real', 'unlimited', 'literal', ty1 } + push_opstack { 'real', 'unlimited', 'literal', ty2 } +end + +function operators.curveto() + local f = pop_opstack() + local e = pop_opstack() + local d = pop_opstack() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local f1 = f[1] if not (f1 == 'real' or f1 == 'integer') then return ps_error('typecheck') end + local e1 = e[1] if not (e1 == 'real' or e1 == 'integer') then return ps_error('typecheck') end + local d1 = d[1] if not (d1 == 'real' or d1 == 'integer') then return ps_error('typecheck') end + local c1 = c[1] if not (c1 == 'real' or c1 == 'integer') then return ps_error('typecheck') end + local b1 = b[1] if not (b1 == 'real' or b1 == 'integer') then return ps_error('typecheck') end + local a1 = a[1] if not (a1 == 'real' or a1 == 'integer') then return ps_error('typecheck') end + -- + if #gsstate.position == 0 then + return ps_error('nocurrentpoint') + end + -- + local matrix = gsstate.matrix + local x, y = do_transform(matrix, e[4], f[4]) + local ax, ay = do_transform(matrix, a[4], b[4]) + local bx, by = do_transform(matrix, c[4], d[4]) + gsstate.position = { x, y } + -- + local path = gsstate.path + path[#path+1] = { "curveto", ax, ay, bx, by, x, y } + return true +end + +function operators.rcurveto() + local f = pop_opstack() + local e = pop_opstack() + local d = pop_opstack() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ft if not (ft == 'real' or ft == 'integer') then return ps_error('typecheck') end + local et if not (et == 'real' or et == 'integer') then return ps_error('typecheck') end + local dt if not (dt == 'real' or dt == 'integer') then return ps_error('typecheck') end + local ct if not (ct == 'real' or ct == 'integer') then return ps_error('typecheck') end + local bt if not (bt == 'real' or bt == 'integer') then return ps_error('typecheck') end + local at if not (at == 'real' or at == 'integer') then return ps_error('typecheck') end + local position = gsstate.position + local path = gsstate.path + if #position == 0 then + return ps_error('nocurrentpoint') + end + local x, y = do_transform(matrix, e[4], f[4]) + local ax, ay = do_transform(matrix, a[4], b[4]) + local bx, by = do_transform(matrix, c[4], d[4]) + local px = position[1] + x + local py = position[2] + y + path[#path+1] = { + "curveto", + position[1] + ax, + position[2] + ay, + position[1] + bx, + position[2] + by, + px, + py + } + position[1] = px + position[2] = py + return true +end + +function operators.closepath() + local path = gsstate.path + local length = #path + if length > 0 and path[length][1] ~= 'closepath' then + local m = path[1] + local a = m[2] + local b = m[3] + local x, y = do_transform(gsstate.matrix, a, b) + gsstate.position = { x, y } + path[length+1] = { "closepath", x, y } + end + return true +end + +-- finds a point on a bezier curve +-- P(x,y) = (1-t)^3*(x0,y0)+3*(1-t)^2*t*(x1,y1)+3*(1-t)*t^2*(x2,y2)+t^3*(x3,y3) + +local function bezier_at(t,x0,y0,x1,y1,x2,y2,x3,y3) + local v = (1 - t) + local x = (v^3)*x0 + 3*(v^2)*t*x1 + 3*v*(t^2)*x2 + (t^3)*x3 + local y = (v^3)*y0 + 3*(v^2)*t*y1 + 3*v*(t^2)*y2 + (t^3)*y3 + return x, y +end + +local delta = 10 -- 100 + +local function good_enough (flatness,c,ct1,ct2,l) + local c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y = c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8] + local l0x, l0y, l1x, l1y = l[1], l[2], l[3], l[4] + local t = 0 + while t < delta do + local td = t/delta + local bx, by = bezier_at(ct1+(ct2-ct1)*td,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y) + local lx, ly = (1-td)*l0x + td*l1x, (1-td)*l0y + td*l1y + local dist = vlength(bx-lx,by-ly) + if dist > flatness then + return false + end + t = t + 1 + end + return true +end + +-- argument d is recursion depth, 10 levels should be enough to reach a conclusion +-- (and already generates over 1000 lineto's in the worst case) + +local function splitter (flatness,p,d,c,ct1,ct2,l) + local c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y = c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8] + d = d + 1 + local r = good_enough(flatness,c,ct1,ct1+ct2,l) + if r or d > 10 then + p[#p + 1] = { 'lineto', l[3], l[4] } + else + local ct22 = ct2/2 + local l2x, l2y = bezier_at(ct1+ct22,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y) + local l1 = { l[1], l[2], l2x, l2y } + local l2 = { l2x, l2y, l[3], l[4] } + splitter(flatness,p,d,c,ct1,ct22,l1) + splitter(flatness,p,d,c,ct1+ct22,ct22,l2) + end +end + +local function flattencurve( homex, homey, curve, flatness) + local p = { } + local c6 = curve[6] + local c7 = curve[7] + local thecurve = { homex, homey, curve[2], curve[3], curve[4], curve[5], c6, c7 } + local theline = { homex, homey, c6, c7 } + splitter(flatness, p, 0, thecurve, 0, 1, theline) + return p +end + +local function do_flattenpath (p, flatness) + local x, y + local px = { } + local nx = 0 + -- we don't care about differences less than a a permille of a point, ever + if flatness < 0.001 then + flatness = 0.001 + end + if p then + for i=1,#p do + local v = p[i] + local t = v[1] + if t == "curveto" then + local pxl = flattencurve(x,y,v,flatness) + for i=1,#pxl do + nx = nx + 1 ; px[nx] = pxl[i] + end + x, y = v[6], v[7] + elseif t == "lineto" or t == "moveto" then + x, y = v[2], v[3] + nx = nx + 1 ; px[nx] = v + else + nx = nx + 1 ; px[nx] = v + end + end + end + return px +end + +function operators.flattenpath() + gsstate.path = do_flattenpath(gsstate.path,gsstate.flatness) +end + +function operators.clippath() + gsstate.path = gsstate.clip + return true +end + +function operators.initclip() + device.initclip() + return true +end + +function operators.eofill() + local color = gsstate.color + local thecolor = color[color.type] + if type(thecolor) == "table" then + thecolor = { unpack(thecolor) } + end + currentpage[#currentpage+1] = { + type = 'eofill', + path = gsstate.path, + colortype = color.type, + color = thecolor, + } + operators.newpath() + return true +end + +-- todo: this only fixes the output, not the actual clipping path +-- in the gsstate ! + +function operators.clip() + currentpage[#currentpage+1] = { + type = 'clip', + path = gsstate.path, + } + return true +end + +-- todo: this only fixes the output, not the actual clipping path +-- in the gsstate ! + +function operators.eoclip() + currentpage[#currentpage+1] = { + type = 'eoclip', + path = gsstate.path, + } + return true +end + +-- Painting operators +-- +-- +erasepage +fill +eofill +stroke -image -imagemask + +-- general graphics todo: transfer function, flatness + +function operators.erasepage() + currentpage = { } + return true +end + +function operators.stroke() + local color = gsstate.color + local ctype = color.type + local thecolor = color[ctype] + -- if type(thecolor) == "table" then + -- thecolor = { unpack(thecolor) } + -- end + currentpage[#currentpage+1] = { + type = 'stroke', + path = gsstate.path, + colortype = ctype, + color = thecolor, + miterlimit = gsstate.miterlimit, + linewidth = gsstate.linewidth, + linecap = gsstate.linecap, + linejoin = gsstate.linejoin, + -- dashpattern = { unpack (gsstate.dashpattern) }, -- unpack? we don't manipulate + dashpattern = gsstate.dashpattern, + dashoffset = gsstate.dashoffset + } + operators.newpath() + return true +end + +function operators.fill() + local color = gsstate.color + local ctype = color.type + local thecolor = color[ctype] + -- if type(thecolor) == "table" then + -- thecolor = { unpack(thecolor) } + -- end + currentpage[#currentpage+1] = { + type = 'fill', + path = gsstate.path, + colortype = ctype, + color = thecolor, + } + operators.newpath() + return true +end + +-- Device setup and output operators +-- +-- +showpage +copypage +banddevice +framedevice +nulldevice +renderbands + +-- will be replaced by the argument of 'new' + +-- this reports the bounding box of a page + +-- todo: linewidth for strokes +-- todo: clips +-- todo: strings (width&height) + +local calculatebox = false + +initializers[#initializers+1] = function() + calculatebox = true +end + +local function boundingbox(page) + + local bounding = specials.boundingbox + if bounding and not calculatebox then + return unpack(bounding) + end + + local minx, miny, maxx, maxy + local startx, starty + local linewidth + + local function update_bbox (x,y) + if not minx then + minx = x + miny = y + maxx = x + maxy = y + end + if linewidth then + local xx = x + linewidth/2 + if xx > maxx then maxx = xx elseif xx < minx then minx = xx end + local xx = x - linewidth/2 + if xx > maxx then maxx = xx elseif xx < minx then minx = xx end + local yy = y + linewidth/2 + if yy > maxy then maxy = yy elseif yy < miny then miny = yy end + local yy = y - linewidth/2 + if yy > maxy then maxy = yy elseif yy < miny then miny = yy end + else + if x > maxx then maxx = x elseif x < minx then minx = x end + if y > maxy then maxy = y elseif y < miny then miny = y end + end + startx, starty = x, y + end + + for i=1,#page do + local object = page[i] + local p = do_flattenpath(object.path,0.5) + linewidth = object.type == "stroke" and object.linewidth + for i=1,#p do + local segment = p[i] + local type = segment[1] + if type == "lineto" then + if startx then + update_bbox(startx,starty) + end + update_bbox(segment[2],segment[3]) + elseif type == "curveto" then + if startx then + update_bbox(startx,starty) + end + update_bbox(segment[6],segment[7]) + elseif type == "moveto" then + startx, starty = segment[2], segment[3] + end + end + end + if minx then + return minx, miny, maxx, maxy + else + return 0, 0, 0, 0 + end +end + +------------------------------------------------------------------ + +local function boundingbox (page) + + local bounding = specials.boundingbox + if bounding and not calculatebox then + return unpack(bounding) + end + + local minx, miny, maxx, maxy + local startx, starty + local linewidth + + local function update_bbox (x,y) + if not minx then + minx = x + miny = y + maxx = x + maxy = y + end + if linewidth then + local xx = x + linewidth/2 + if xx > maxx then + maxx = xx + elseif xx < minx then + minx = xx + end + local xx = x - linewidth/2 + if xx > maxx then + maxx = xx + elseif xx < minx then + minx = xx + end + local yy = y + linewidth/2 + if yy > maxy then + maxy = yy + elseif yy < miny then + miny = yy + end + local yy = y - linewidth/2 + if yy > maxy then + maxy = yy + elseif yy < miny then + miny = yy + end + else + if x > maxx then + maxx = x + elseif x < minx then + minx = x + end + if y > maxy then + maxy = y + elseif y < miny then + miny = y + end + end + startx, starty = x, y + end + + local delta = 10 -- 100 + + local function good_enough (ct1,ct2, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l1x, l1y) + local t = 0 + while t < delta do + local td = t/delta + local bx, by = bezier_at(ct1+(ct2-ct1)*td,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y) + local lx, ly = (1-td)*l0x + td*l1x, (1-td)*l0y + td*l1y + local dist = sqrt((bx-lx)^2+(by-ly)^2) -- vlength(bx-lx,by-ly) + if dist > 0.5 then + return false + end + t = t + 1 + end + return true + end + + local function splitter (d,ct1,ct2, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l1x, l1y) + d = d + 1 + local r = good_enough(ct1,ct1+ct2, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l1x, l1y) + if r or d > 10 then + if startx then + update_bbox(l1x, l1y) + end + else + local ct22 = ct2/2 + local l2x, l2y = bezier_at(ct1+ct22,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y) + splitter(d,ct1, ct22, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l2x, l2y) + splitter(d,ct1+ct22,ct22, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l2x, l2y, l1x, l1y) + end + end + + for i=1,#page do + local object = page[i] + local p = object.path + linewidth = object.type == "stroke" and object.linewidth + for i=1,#p do + local segment = p[i] + local type = segment[1] + if type == "lineto" then + if startx then + update_bbox(startx,starty) + end + update_bbox(segment[2],segment[3]) + elseif type == "curveto" then + local c6 = segment[6] + local c7 = segment[7] + splitter(0, 0, 1, startx, starty, segment[2], segment[3], segment[4], segment[5], c6, c7, startx, starty, c6, c7) + elseif type == "moveto" then + startx, starty = segment[2], segment[3] + end + end + end + if minx then + return minx, miny, maxx, maxy + else + return 0, 0, 0, 0 + end +end + +------------------------------------------------------------------ + +-- most time is spend in calculating the boundingbox + +-- NULL output + +devices.null = { + initgraphics = function() gsstate.matrix = { 1, 0, 0, 1, 0, 0 } end, + initclip = function() gsstate.clip = { } end, + showpage = function() return "" end, +} + +-- PDF output + +local pdf = { + initgraphics = function() gsstate.matrix = { 1, 0, 0, 1, 0, 0 } end, + initclip = function() gsstate.clip = { } end, + -- startpage = function(llc,lly,urx,ury) end, + -- flushpage = function() end, + -- stoppage = function() end, +} + +devices.pdf = pdf + +function pdf.showpage(page) + -- + local startpage = pdf.startpage + local stoppage = pdf.stoppage + local flushpage = pdf.flushpage + local showfont = pdf.showfont + -- + if not flushpage then + return + end + -- + if startpage then + startpage(boundingbox(page)) + end + -- + local t = { "q" } + local n = 1 + local g_colortype = "notacolor" + local g_color = "" + local g_miterlimit = -1 + local g_linejoin = -1 + local g_linecap = -1 + local g_linewidth = -1 + local g_dashpattern = nil + local g_dashoffset = -1 + local flush = devices.pdf.flush + for i=1,#page do + local object = page[i] + local path = object.path + local otyp = object.type + if otype ~= "clip" and otype ~= "eoclip" then + local colortype = object.colortype + local color = object.color + if colortype == "gray" then + local v = formatters["%f g %f G"](color,color) + if g_color ~= v then + g_colortype = "gray" + g_color = v + n = n + 1 ; t[n] = v + end + elseif colortype == "rgb" then + local r, g, b = color[1], color[2], color[3] + local v = formatters["%f %f %f rg %f %f %f RG"](r,g,b,r,g,b) + if g_color ~= v then + g_colortype = "rgb" + g_color = v + n = n + 1 ; t[n] = v + end + elseif colortype == "cmyk" then + local c, m, y, k = color[1], color[2], color[3], color[4] + local v = formatters["%f %f %f %f k %f %f %f %f K"](c,m,y,k,c,m,y,k) + if g_color ~= v then + g_colortype = "cmyk" + g_color = v + n = n + 1 ; t[n] = v + end + elseif colortype == "hsb" then + local r, g, b = hsv_to_rgb(color[1],color[2],color[3]) + local v = formatters["%f %f %f rg %f %f %f RG"](r,g,b,r,g,b) + if g_color ~= v then + g_colortype = "rgb" + g_color = v + n = n + 1 ; t[n] = v + end + end + end + if otype == "stroke" then + local miterlimit = object.miterlimit + if g_miterlimit ~= miterlimit then + g_miterlimit = miterlimit + n = n + 1 ; t[n] = formatters["%f M"](miterlimit) + end + local linejoin = object.linejoin + if g_linejoin ~= linejoin then + g_linejoin = linejoin + n = n + 1 ; t[n] = formatters["%d j"](linejoin) + end + local linecap = object.linecap + if g_linecap ~= linecap then + g_linecap = linecap + n = n + 1 ; t[n] = formatters["%d J"](linecap) + end + local linewidth = object.linewidth + if g_linewidth ~= linewidth then + g_linewidth = linewidth + n = n + 1 ; t[n] = formatters["%f w"](linewidth) + end + local dashpattern = object.dashpattern + local dashoffset = object.dashoffset + if g_dashpattern ~= dashpattern or g_dashoffset ~= dashoffset then + g_dashpattern = dashpattern + g_dashoffset = dashoffset + local l = #dashpattern + if l == 0 then + n = n + 1 ; t[n] = "[] 0 d" + else + n = n + 1 ; t[n] = formatters["[% t] %d d"](dashpattern,dashoffset) + end + end + end + if path then + for i=1,#path do + local segment = path[i] + local styp = segment[1] + if styp == "moveto" then + n = n + 1 ; t[n] = formatters["%f %f m"](segment[2],segment[3]) + elseif styp == "lineto" then + n = n + 1 ; t[n] = formatters["%f %f l"](segment[2],segment[3]) + elseif styp == "curveto" then + n = n + 1 ; t[n] = formatters["%f %f %f %f %f %f c"](segment[2],segment[3],segment[4],segment[5],segment[6],segment[7]) + elseif styp == "closepath" then + n = n + 1 ; t[n] = "h" + else + report("unknown path segment type %a",styp) + end + end + end + if otyp == "stroke" then + n = n + 1 ; t[n] = "S" + elseif otyp == "fill" then + n = n + 1 ; t[n] = "f" + elseif otyp == "eofill" then + n = n + 1 ; t[n] = "f*" + elseif otyp == "clip" then + n = n + 1 ; t[n] = "W n" + elseif otyp == "eoclip" then + n = n + 1 ; t[n] = "W* n" + elseif otyp == "show" then + if showfont then + if n > 0 then + flushpage(concat(t,"\n")) + n = 0 ; t = { } + end + showfont(object) + end + else + -- nothing to do + end + end + n = n + 1 ; t[n] = "Q" + flushpage(concat(t,"\n")) + -- + if startpage then + stoppage() + end +end + +function operators.showpage() + local copies = lookup("#copies") + if copies and copies[1] == 'integer' and copies[4] >= 1 then + local amount = floor(copies[4]) + local render = device.showpage + if render then + for i=1,amount do + render(currentpage) + end + end + end + operators.erasepage() + operators.initgraphics() + return true +end + +function operators.copypage() + local render = device.showpage + if render then + render(currentpage) + end + return true +end + +function operators.banddevice() + local d = pop_opstack() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc, td = a[1], b[1], c[1], d[1] + if not (ta == 'array' and a[5] == 6) then + return ps_error('typecheck') + end + if not (td == 'array' and d[3] == 'executable') then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (tc == 'real' or tc == 'integer') then + return ps_error('typecheck') + end + local dev = device.banddevice + if dev then + dev(a,b,c,d) + else + return ps_error('undefined') -- fixed + end + return true +end + +function operators.renderbands() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if not (a[1] == 'array' and a[3] == 'executable') then + return ps_error('typecheck') + end + local dev = device.renderbands + if dev then + dev(d) + else + return ps_error('undefined') + end + return true +end + +function operators.framedevice() + local d = pop_opstack() + local c = pop_opstack() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + local ta, tb, tc, td = a[1], b[1], c[1], d[1] + if not (ta == 'array' and a[5] == 6) then + return ps_error('typecheck') + end + if not (tb == 'real' or tb == 'integer') then + return ps_error('typecheck') + end + if not (tc == 'real' or tc == 'integer') then + return ps_error('typecheck') + end + if not (td == 'array' and d[3] == 'executable') then + return ps_error('typecheck') + end + local dev = device.framedevice + if dev then + dev(a,b,c,d) + else + return ps_error('undefined') + end + return true +end + +function operators.nulldevice() + gsstate.device = "null" + operators.initgraphics() + return true +end + +-- Character and font operators +-- +-- +definefont *findfont +scalefont +makefont +setfont +currentfont +show -ashow -widthshow +-- -awidthshow +kshow -stringwidth ^FontDirectory ^StandardEncoding + +-- Fonts are a bit special because it is needed to cooperate with the enclosing PDF document. + +local FontDirectory + +initializers[#initializers+1] = function(reset) + if reset then + FontDirectory = nil + else + FontDirectory = add_VM { + access = 'unlimited', + size = 0, + maxsize = 5000, + dict = { }, + } + end +end + +-- loading actual fonts is a worryingly slow exercise + +local fontmap + +initializers[#initializers+1] = function() + if reset then + fontmap = nil + else + fontmap = { + ['Courier-Bold'] = 'NimbusMonL-Bold.ps', + ['Courier-BoldOblique'] = 'NimbusMonL-BoldObli.ps', + ['Courier'] = 'NimbusMonL-Regu.ps', + ['Courier-Oblique'] = 'NimbusMonL-ReguObli.ps', + ['Times-Bold'] = 'NimbusRomNo9L-Medi.ps', + ['Times-BoldItalic'] = 'NimbusRomNo9L-MediItal.ps', + ['Times-Roman'] = 'NimbusRomNo9L-Regu.ps', + ['Times-Italic'] = 'NimbusRomNo9L-ReguItal.ps', + ['Helvetica-Bold'] = 'NimbusSanL-Bold.ps', + ['Helvetica-BoldOblique'] = 'NimbusSanL-BoldItal.ps', + ['Helvetica'] = 'NimbusSanL-Regu.ps', + ['Helvetica-Oblique'] = 'NimbusSanL-ReguItal.ps', + ['Symbol'] = 'StandardSymL.ps', + } + end +end + +-- this can be overwritten by the user + +local function findfont(fontname) + return fontmap[fontname] +end + +-- tests required keys in a font dict + +local function checkfont(f) + -- FontMatrix + local matrix = f['FontMatrix'] + if not matrix or matrix[1] ~= 'array' or matrix[5] ~= 6 then + return false + end + local thearray = get_VM(matrix[4]) + for i=1,#thearray do + local v = thearray[i] + local tv = v[1] + if not (tv == 'real' or tv == 'integer') then + return false + end + end + -- FontType + local ftype = f['FontType'] + if not ftype or ftype[1] ~= 'integer' then + return false + end + -- FontBBox + local bbox = f['FontBBox'] + -- do not test [5] here, because it can be '1' (executable array) + if not bbox or bbox[1] ~= 'array' or bbox[6] ~= 4 then + return false + end + local thearray = get_VM(bbox[4]) + for i=1,#thearray do + local v = thearray[i] + local tv = v[1] + if not (tv == 'real' or tv == 'integer') then + return false + end + end + -- Encoding + local bbox = f['Encoding'] + if not bbox or bbox[1] ~= 'array' or bbox[5] ~= 256 then + return false + end + local thearray = get_VM(bbox[4]) + for i=1,#thearray do + local v = thearray[i] + local tv = v[1] + if tv[1] ~= 'name' then + return false + end + end + return true +end + +-- objects of type font as essentially the same as objects of type dict + +function operators.definefont() + local b = pop_opstack() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if b[1] ~= 'dict' then + return ps_error('typecheck') + end + -- force keys to be names + if a[1] ~= 'name' then + return ps_error('typecheck') + end + local fontdict = get_VM(b[4]) + if not checkfont(fontdict.dict) then + return ps_error('invalidfont') + end + -- check that a FID will fit + if fontdict.size == fontdict.maxsize then + return ps_error('invalidfont') + end + fontdict.dict['FID'] = {'font', 'executable', 'literal', b[4]} + fontdict.size = fontdict.size + 1 + fontdict.access = 'read-only' + local dict = get_VM(FontDirectory) + local key = get_VM(a[4]) + if not dict.dict[key] and dict.size == dict.maxsize then + -- return ps_error('dictfull') -- level 1 only + end + if not dict.dict[key] then + dict.size = dict.size + 1 + end + dict.dict[key] = fontdict.dict['FID'] + push_opstack(b) + return true +end + +function operators.findfont() + local a = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if a[1] ~= 'name' then + return ps_error('typecheck') + end + local fontdict = get_VM(FontDirectory) + local key = get_VM(a[4]) + local dict = dict.dict + if not dict[key] then + fname = findfont(key) + if not fname then + return ps_error('invalidfont') + end + local oldfontkeys = { } + for k, v in next, dict do + oldfontkeys[i] = 1 + end + report("loading font file %a",fname) + local theopstack = opstackptr + local run = formatters['/eexec {pop} def (%s) run'](fname) + push_execstack { '.stopped', 'unlimited', 'literal', false } + local curstack = execstackptr + push_execstack { 'string', 'unlimited', 'executable', add_VM(run), 1, #run } + while curstack < execstackptr do + do_exec() + end + if execstack[execstackptr][1] == '.stopped' then + pop_execstack() + end + opstackptr = theopstack + local fkey, ftab + for k, v in next, dict do + if not oldfontkeys[k] then + -- this is the new dict + fkey = k + ftab = v + break + end + end + if not fkey then + return ps_error('invalidfont') + end + dict[key] = ftab -- set up the user requested name as well + end + push_opstack(dict[key]) + return true +end + +local function pushscaledcopy(fontdict,matrix) + local olddict = fontdict.dict + if not checkfont(olddict) then + return ps_error('invalidfont') + end + local newdict = { } + local oldsize = fontdict.size + local newfontdict = { + dict = newdict, + access = 'read-only', + size = oldsize, + maxsize = oldsize, + } + for k, v in next, olddict do + if k == "FontMatrix" then + local oldmatrix = get_VM(v[4]) + local old = { + oldmatrix[1][4], + oldmatrix[2][4], + oldmatrix[3][4], + oldmatrix[4][4], + oldmatrix[5][4], + oldmatrix[6][4], + } + local c = do_concat(old,matrix) + local new = { + { 'real', 'unlimited', 'literal', c[1] }, + { 'real', 'unlimited', 'literal', c[2] }, + { 'real', 'unlimited', 'literal', c[3] }, + { 'real', 'unlimited', 'literal', c[4] }, + { 'real', 'unlimited', 'literal', c[5] }, + { 'real', 'unlimited', 'literal', c[6] } + } + newdict[k] = { 'array', 'unlimited', 'literal', add_VM(new), 6, 6 } + elseif k == "FID" then + -- updated later + else + newfontdict.dict[k] = v + end + end + local f = add_VM(newfontdict) + newdict['FID'] = { 'font', 'read-only', 'literal', f } + push_opstack { 'font', 'read-only', 'literal', f } -- share ? + return true +end + +function operators.scalefont() + local s = pop_opstack() + local b = pop_opstack() + if not b then + return ps_error('stackunderflow') + end + if b[1] ~= 'font' then + return ps_error('typecheck') + end + if not (s[1] == 'integer' or s[1] == 'real') then + return ps_error('typecheck') + end + local scals = s[4] + local matrix = { scale, 0, 0, scale, 0, 0 } + local fontdict = get_VM(b[4]) + return pushscaledcopy(fontdict,matrix) +end + +function operators.makefont() + local s = pop_opstack() + local b = pop_opstack() + if not b then + return ps_error('stackunderflow') + end + if b[1] ~= 'font' then + return ps_error('typecheck') + end + if s[1] ~= 'array' then + return ps_error('typecheck') + end + if s[6] ~= 6 then + return ps_error('rangecheck') + end + local matrix = { } + local array = get_VM(s[4]) + for i=1,#array do + local v = array[i] + local tv = v[1] + if not (tv == 'real' or tv == 'integer') then + return ps_error('typecheck') + end + matrix[i] = v[4] + end + local fontdict = get_VM(b[4]) + pushscaledcopy(fontdict,matrix) + return true +end + +function operators.setfont() + local b = pop_opstack() + if not b then + return ps_error('stackunderflow') + end + if b[1] ~= 'font' then + return ps_error('typecheck') + end + gsstate.font = b[4] + return true +end + +-- todo: the invalidfont error is temporary. 'start' should set up at least one font in +-- FontDirectory and assing it as the current font + +function operators.currentfont() + if not gsstate.font then + return ps_error('invalidfont') + end + push_opstack {'font', 'read-only', 'literal', gsstate.font } + return true +end + +function do_show(fontdict,s) + local stringmatrix = { } + local truematrix = { } + local stringencoding = { } + -- + local dict = fontdict.dict + local fontname = get_VM(dict['FontName'][4]) + local fontmatrix = get_VM(dict['FontMatrix'][4]) + local encoding = get_VM(dict['Encoding'][4]) + local matrix = gsstate.matrix + local position = gsstate.position + local color = gsstate.color + local colortype = color.type + local colordata = color[colortype] + -- + if fontmatrix then + for i=1,#fontmatrix do + stringmatrix[i] = fontmatrix[i][4] + end + end + if matrix then + for i=1,#matrix do + truematrix[i] = matrix[i] + end + end + if encoding then + for i=1,#m do + stringencoding[i] = get_VM(e[i][4]) + end + end + if type(colordata) == "table" then + colordata = { unpack(colordata) } -- copy + end + currentpage[#currentpage+1] = { + type = 'show', + string = s, + fontname = fontname, + adjust = nil, + x = position[1], + y = position[2], + encoding = stringencoding, + fontmatrix = stringmatrix, + matrix = truematrix, + colortype = colortype, + color = colordata, + } + -- todo: update currentpoint, needing 'stringwidth' +end + +function operators.show() + local s = pop_opstack() + if not s then + return ps_error('stackunderflow') + end + if s[1] ~= 'string' then + return ps_error('typecheck') + end + if #gsstate.position == 0 then + return ps_error('nocurrentpoint') + end + if not gsstate.font then + return ps_error('invalidfont') + end + local fontdict = get_VM(gsstate.font) + if fontdict.access == "noaccess" then + return ps_error('invalidaccess') + end + if not checkfont(fontdict.dict) then + return ps_error('invalidfont') + end + do_show(fontdict,get_VM(s[4])) +end + + +function operators.kshow() + local a = pop_opstack() + local b = pop_opstack() + if not a then + return ps_error('stackunderflow') + end + if b[1] ~= "array" and b[3] == 'executable' then + return ps_error('typecheck') + end + if b[2] == 'noaccess' then + return ps_error('invalidaccess') + end + if not a[1] == 'string' then + return ps_error('typecheck') + end + if a[2] == "execute-only" or a[2] == 'noaccess' then + return ps_error('invalidaccess') + end + local fontdict = get_VM(gsstate.font) + if fontdict.access == "noaccess" then + return ps_error('invalidaccess') + end + if #gsstate.position == 0 then + return ps_error('nocurrentpoint') + end + -- ok, that were the errors + push_execstack { '.exit', 'unlimited', 'literal', false } + local curstack = execstackptr + if a[6] == 0 then + return true + end + b[7] = 'i' + local thestring = get_VM(a[4]) + local v = sub(thestring,1,1) + thestring = sub(thestring,2,-1) + do_show(fontdict,v) + for w in gmatch(thestring,".") do + if stopped then + stopped = false + return false + end + push_opstack { 'integer', 'unlimited', 'literal', byte(v) } + push_opstack { 'integer', 'unlimited', 'literal', byte(w) } + b[5] = 1 + push_execstack(b) + while curstack < execstackptr do + do_exec() + end + local entry = execstack[execstackptr] + if entry[1] == '.exit' and entry[4] == true then + pop_execstack() + return true; + end + do_show(fontdict,w) + v = w + end + return true +end + +local the_standardencoding = { + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', + 'quoteright', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', + 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four', + 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', + 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', + 'bracketright', 'asciicircum', 'underscore', 'quoteleft', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', + 'braceright', 'asciitilde', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', 'exclamdown', 'cent', 'sterling', 'fraction', 'yen', + 'florin', 'section', 'currency', 'quotesingle', 'quotedblleft', + 'guillemotleft', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', + '.notdef', 'endash', 'dagger', 'daggerdbl', 'periodcentered', '.notdef', + 'paragraph', 'bullet', 'quotesinglbase', 'quotedblbase', + 'quotedblright', 'guillemotright', 'ellipsis', 'perthousand', '.notdef', + 'questiondown', 'grave', 'acute', 'circumflex', 'tilde', 'macron', + 'breve', 'dotaccent', 'dieresis', '.notdef', 'ring', 'cedilla', + '.notdef', 'hungarumlaut', 'ogonek', 'caron', 'emdash', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + '.notdef', '.notdef', '.notdef', 'AE', '.notdef', 'ordfeminine', + '.notdef', '.notdef', '.notdef', '.notdef', 'Lslash', 'Oslash', 'OE', + 'ordmasculine', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', + 'ae', '.notdef', '.notdef', '.notdef', 'dotlessi', '.notdef', + '.notdef', 'lslash', 'oslash', 'oe', 'germandbls', '.notdef', + '.notdef', '.notdef', '.notdef' +} + +local function standardencoding() + local a = { } + for i=1,#the_standardencoding do + a[i] = { 'name', 'unlimited', 'literal', add_VM(the_standardencoding[i]) } + end + return a +end + +-- Font cache operators +-- +-- -cachestatus -setcachedevice -setcharwidth -setcachelimit + +-- userdict (initially empty) + +local systemdict +local userdict + +initializers[#initializers+1] = function(reset) + if reset then + systemdict = nil + else + dictstackptr = dictstackptr + 1 + dictstack[dictstackptr] = add_VM { + access = 'unlimited', + maxsize = MAX_INTEGER, + size = 0, + dict = { }, + } + if directvm then + systemdict = dictstack[dictstackptr] + else + systemdict = dictstackptr + end + end +end + +initializers[#initializers+1] = function(reset) + if reset then + userdict = nil + else + dictstackptr = dictstackptr + 1 + dictstack[dictstackptr] = add_VM { + access = 'unlimited', + maxsize = MAX_INTEGER, + size = 0, + dict = { }, + } + if directvm then + userdict = dictstack[dictstackptr] + else + userdict = dictstackptr + end + end +end + +initializers[#initializers+1] = function(reset) + if reset then + -- already done + else + local dict = { + ['$error'] = { 'dict', 'unlimited', 'literal', dicterror }, + ['['] = { 'operator', 'unlimited', 'executable', operators.beginarray, '[' }, + [']'] = { 'operator', 'unlimited', 'executable', operators.endarray, ']' }, + -- ['='] = { 'operator', 'unlimited', 'executable', operators.EQ, '=' }, + ['=='] = { 'operator', 'unlimited', 'executable', operators.equal, '==' }, + ['abs'] = { 'operator', 'unlimited', 'executable', operators.abs, 'abs' }, + ['add'] = { 'operator', 'unlimited', 'executable', operators.add, 'add' }, + ['aload'] = { 'operator', 'unlimited', 'executable', operators.aload, 'aload' }, + ['anchorsearch'] = { 'operator', 'unlimited', 'executable', operators.anchorsearch, 'anchorsearch' }, + ['and'] = { 'operator', 'unlimited', 'executable', operators["and"], 'and' }, + ['arc'] = { 'operator', 'unlimited', 'executable', operators.arc, 'arc' }, + ['arcn'] = { 'operator', 'unlimited', 'executable', operators.arcn, 'arcn' }, + ['arcto'] = { 'operator', 'unlimited', 'executable', operators.arcto, 'arcto' }, + ['array'] = { 'operator', 'unlimited', 'executable', operators.array, 'array' }, + ['astore'] = { 'operator', 'unlimited', 'executable', operators.astore, 'astore' }, + ['atan'] = { 'operator', 'unlimited', 'executable', operators.atan, 'atan' }, + ['banddevice'] = { 'operator', 'unlimited', 'executable', operators.banddevice, 'banddevice' }, + ['bind'] = { 'operator', 'unlimited', 'executable', operators.bind, 'bind' }, + ['bitshift'] = { 'operator', 'unlimited', 'executable', operators.bitshift, 'bitshift' }, + ['begin'] = { 'operator', 'unlimited', 'executable', operators.begin, 'begin' }, + ['bytesavailable'] = { 'operator', 'unlimited', 'executable', operators.bytesavailable, 'bytesavailable' }, + ['ceiling'] = { 'operator', 'unlimited', 'executable', operators.ceiling, 'ceiling' }, + ['clear'] = { 'operator', 'unlimited', 'executable', operators.clear, 'clear' }, + ['cleartomark'] = { 'operator', 'unlimited', 'executable', operators.cleartomark, 'cleartomark' }, + ['clip'] = { 'operator', 'unlimited', 'executable', operators.clip, 'clip' }, + ['clippath'] = { 'operator', 'unlimited', 'executable', operators.clippath, 'clippath' }, + ['closefile'] = { 'operator', 'unlimited', 'executable', operators.closefile, 'closefile' }, + ['closepath'] = { 'operator', 'unlimited', 'executable', operators.closepath, 'closepath' }, + ['concat'] = { 'operator', 'unlimited', 'executable', operators.concat, 'concat' }, + ['concatmatrix'] = { 'operator', 'unlimited', 'executable', operators.concatmatrix, 'concatmatrix' }, + ['copy'] = { 'operator', 'unlimited', 'executable', operators.copy, 'copy' }, + ['copypage'] = { 'operator', 'unlimited', 'executable', operators.copypage, 'copypage' }, + ['cos'] = { 'operator', 'unlimited', 'executable', operators.cos, 'cos' }, + ['count'] = { 'operator', 'unlimited', 'executable', operators.count, 'count' }, + ['countdictstack'] = { 'operator', 'unlimited', 'executable', operators.countdictstack, 'countdictstack' }, + ['countexecstack'] = { 'operator', 'unlimited', 'executable', operators.countexecstack, 'countexecstack' }, + ['counttomark'] = { 'operator', 'unlimited', 'executable', operators.counttomark, 'counttomark' }, + ['currentdash'] = { 'operator', 'unlimited', 'executable', operators.currentdash, 'currentdash' }, + ['currentdict'] = { 'operator', 'unlimited', 'executable', operators.currentdict, 'currentdict' }, + ['currentfile'] = { 'operator', 'unlimited', 'executable', operators.currentfile, 'currentfile' }, + ['currentflat'] = { 'operator', 'unlimited', 'executable', operators.currentflat, 'currentflat' }, + ['currentfont'] = { 'operator', 'unlimited', 'executable', operators.currentfont, 'currentfont' }, + ['currentgray'] = { 'operator', 'unlimited', 'executable', operators.currentgray, 'currentgray' }, + ['currenthsbcolor'] = { 'operator', 'unlimited', 'executable', operators.currenthsbcolor, 'currenthsbcolor' }, + ['currentlinecap'] = { 'operator', 'unlimited', 'executable', operators.currentlinecap, 'currentlinecap' }, + ['currentlinejoin'] = { 'operator', 'unlimited', 'executable', operators.currentlinejoin, 'currentlinejoin' }, + ['currentlinewidth'] = { 'operator', 'unlimited', 'executable', operators.currentlinewidth, 'currentlinewidth' }, + ['currentmatrix'] = { 'operator', 'unlimited', 'executable', operators.currentmatrix, 'currentmatrix' }, + ['currentmiterlimit'] = { 'operator', 'unlimited', 'executable', operators.currentmiterlimit, 'currentmiterlimit' }, + ['currentpoint'] = { 'operator', 'unlimited', 'executable', operators.currentpoint, 'currentpoint' }, + ['currentrgbcolor'] = { 'operator', 'unlimited', 'executable', operators.currentrgbcolor, 'currentrgbcolor' }, + ['currentcmykcolor'] = { 'operator', 'unlimited', 'executable', operators.currentcmykcolor, 'currentcmykcolor' }, + ['currentscreen'] = { 'operator', 'unlimited', 'executable', operators.currentscreen, 'currentscreen' }, + ['currenttransfer'] = { 'operator', 'unlimited', 'executable', operators.currenttransfer, 'currenttransfer' }, + ['curveto'] = { 'operator', 'unlimited', 'executable', operators.curveto, 'curveto' }, + ['cvi'] = { 'operator', 'unlimited', 'executable', operators.cvi, 'cvi' }, + ['cvlit'] = { 'operator', 'unlimited', 'executable', operators.cvlit, 'cvlit' }, + ['cvn'] = { 'operator', 'unlimited', 'executable', operators.cvn, 'cvn' }, + ['cvr'] = { 'operator', 'unlimited', 'executable', operators.cvr, 'cvr' }, + ['cvrs'] = { 'operator', 'unlimited', 'executable', operators.cvrs, 'cvrs' }, + ['cvs'] = { 'operator', 'unlimited', 'executable', operators.cvs, 'cvs' }, + ['cvx'] = { 'operator', 'unlimited', 'executable', operators.cvx, 'cvx' }, + ['def'] = { 'operator', 'unlimited', 'executable', operators.def, 'def' }, + ['definefont'] = { 'operator', 'unlimited', 'executable', operators.definefont, 'definefont' }, + ['dict'] = { 'operator', 'unlimited', 'executable', operators.dict, 'dict' }, + ['dictstack'] = { 'operator', 'unlimited', 'executable', operators.dictstack, 'dictstack' }, + ['div'] = { 'operator', 'unlimited', 'executable', operators.div, 'div' }, + ['dtransform'] = { 'operator', 'unlimited', 'executable', operators.dtransform, 'dtransform' }, + ['dup'] = { 'operator', 'unlimited', 'executable', operators.dup, 'dup' }, + ['echo'] = { 'operator', 'unlimited', 'executable', operators.echo, 'echo' }, + ['end'] = { 'operator', 'unlimited', 'executable', operators["end"], 'end' }, + ['eoclip'] = { 'operator', 'unlimited', 'executable', operators.eoclip, 'eoclip' }, + ['eofill'] = { 'operator', 'unlimited', 'executable', operators.eofill, 'eofill' }, + ['eq'] = { 'operator', 'unlimited', 'executable', operators.eq, 'eq' }, + ['errordict'] = { 'dict', 'unlimited', 'literal', errordict }, + ['exch'] = { 'operator', 'unlimited', 'executable', operators.exch, 'exch' }, + ['exec'] = { 'operator', 'unlimited', 'executable', operators.exec, 'exec' }, + ['execstack'] = { 'operator', 'unlimited', 'executable', operators.execstack, 'execstack' }, + ['executeonly'] = { 'operator', 'unlimited', 'executable', operators.executeonly, 'executeonly' }, + ['exit'] = { 'operator', 'unlimited', 'executable', operators.exit, 'exit' }, + ['exp'] = { 'operator', 'unlimited', 'executable', operators.exp, 'exp' }, + ['false'] = { 'boolean', 'unlimited', 'literal', false }, + ['file'] = { 'operator', 'unlimited', 'executable', operators.file, 'file' }, + ['fill'] = { 'operator', 'unlimited', 'executable', operators.fill, 'fill' }, + ['findfont'] = { 'operator', 'unlimited', 'executable', operators.findfont, 'findfont' }, + ['FontDirectory'] = { 'dict', 'unlimited', 'literal', escrito['FontDirectory'] }, + ['flattenpath'] = { 'operator', 'unlimited', 'executable', operators.flattenpath, 'flattenpath' }, + ['floor'] = { 'operator', 'unlimited', 'executable', operators.floor, 'floor' }, + ['flush'] = { 'operator', 'unlimited', 'executable', operators.flush, 'flush' }, + ['flushfile'] = { 'operator', 'unlimited', 'executable', operators.flushfile, 'flushfile' }, + ['for'] = { 'operator', 'unlimited', 'executable', operators["for"], 'for' }, + ['forall'] = { 'operator', 'unlimited', 'executable', operators.forall, 'forall' }, + ['framedevice'] = { 'operator', 'unlimited', 'executable', operators.framedevice, 'framedevice' }, + ['ge'] = { 'operator', 'unlimited', 'executable', operators.ge, 'ge' }, + ['get'] = { 'operator', 'unlimited', 'executable', operators.get, 'get' }, + ['getinterval'] = { 'operator', 'unlimited', 'executable', operators.getinterval, 'getinterval' }, + ['grestore'] = { 'operator', 'unlimited', 'executable', operators.grestore, 'grestore' }, + ['grestoreall'] = { 'operator', 'unlimited', 'executable', operators.grestoreall, 'grestoreall' }, + ['gsave'] = { 'operator', 'unlimited', 'executable', operators.gsave, 'gsave' }, + ['gt'] = { 'operator', 'unlimited', 'executable', operators.gt, 'gt' }, + ['identmatrix'] = { 'operator', 'unlimited', 'executable', operators.identmatrix, 'identmatrix' }, + ['idiv'] = { 'operator', 'unlimited', 'executable', operators.idiv, 'idiv' }, + ['if'] = { 'operator', 'unlimited', 'executable', operators["if"], 'if' }, + ['ifelse'] = { 'operator', 'unlimited', 'executable', operators.ifelse, 'ifelse' }, + ['index'] = { 'operator', 'unlimited', 'executable', operators.index, 'index' }, + ['initclip'] = { 'operator', 'unlimited', 'executable', operators.initclip, 'initclip' }, + ['initgraphics'] = { 'operator', 'unlimited', 'executable', operators.initgraphics, 'initgraphics' }, + ['initmatrix'] = { 'operator', 'unlimited', 'executable', operators.initmatrix, 'initmatrix' }, + ['invertmatrix'] = { 'operator', 'unlimited', 'executable', operators.invertmatrix, 'invertmatrix' }, + ['idtransform'] = { 'operator', 'unlimited', 'executable', operators.idtransform, 'idtransform' }, + ['itransform'] = { 'operator', 'unlimited', 'executable', operators.itransform, 'itransform' }, + ['known'] = { 'operator', 'unlimited', 'executable', operators.known, 'known' }, + ['kshow'] = { 'operator', 'unlimited', 'executable', operators.kshow, 'kshow' }, + ['le'] = { 'operator', 'unlimited', 'executable', operators.le, 'le' }, + ['length'] = { 'operator', 'unlimited', 'executable', operators.length, 'length' }, + ['lineto'] = { 'operator', 'unlimited', 'executable', operators.lineto, 'lineto' }, + ['ln'] = { 'operator', 'unlimited', 'executable', operators.ln, 'ln' }, + ['load'] = { 'operator', 'unlimited', 'executable', operators.load, 'load' }, + ['log'] = { 'operator', 'unlimited', 'executable', operators.log, 'log' }, + ['loop'] = { 'operator', 'unlimited', 'executable', operators.loop, 'loop' }, + ['lt'] = { 'operator', 'unlimited', 'executable', operators.lt, 'lt' }, + ['makefont'] = { 'operator', 'unlimited', 'executable', operators.makefont, 'makefont' }, + ['mark'] = { 'operator', 'unlimited', 'executable', operators.mark, 'mark' }, + ['matrix'] = { 'operator', 'unlimited', 'executable', operators.matrix, 'matrix' }, + ['maxlength'] = { 'operator', 'unlimited', 'executable', operators.maxlength, 'maxlength' }, + ['mod'] = { 'operator', 'unlimited', 'executable', operators.mod, 'mod' }, + ['moveto'] = { 'operator', 'unlimited', 'executable', operators.moveto, 'moveto' }, + ['mul'] = { 'operator', 'unlimited', 'executable', operators.mul, 'mul' }, + ['ne'] = { 'operator', 'unlimited', 'executable', operators.ne, 'ne' }, + ['neg'] = { 'operator', 'unlimited', 'executable', operators.neg, 'neg' }, + ['newpath'] = { 'operator', 'unlimited', 'executable', operators.newpath, 'newpath' }, + ['noaccess'] = { 'operator', 'unlimited', 'executable', operators.noaccess, 'noaccess' }, + ['not'] = { 'operator', 'unlimited', 'executable', operators["not"], 'not' }, + ['null'] = { 'operator', 'unlimited', 'executable', operators.null, 'null' }, + ['or'] = { 'operator', 'unlimited', 'executable', operators["or"], 'or' }, + ['pop'] = { 'operator', 'unlimited', 'executable', operators.pop, 'pop' }, + ['print'] = { 'operator', 'unlimited', 'executable', operators.print, 'print' }, + ['pstack'] = { 'operator', 'unlimited', 'executable', operators.pstack, 'pstack' }, + ['put'] = { 'operator', 'unlimited', 'executable', operators.put, 'put' }, + ['putinterval'] = { 'operator', 'unlimited', 'executable', operators.putinterval, 'putinterval' }, + ['quit'] = { 'operator', 'unlimited', 'executable', operators.quit, 'quit' }, + ['rand'] = { 'operator', 'unlimited', 'executable', operators.rand, 'rand' }, + ['rcheck'] = { 'operator', 'unlimited', 'executable', operators.rcheck, 'rcheck' }, + ['rcurveto'] = { 'operator', 'unlimited', 'executable', operators.rcurveto, 'rcurveto' }, + ['read'] = { 'operator', 'unlimited', 'executable', operators.read, 'read' }, + ['readhexstring'] = { 'operator', 'unlimited', 'executable', operators.readhexstring, 'readhexstring' }, + ['readline'] = { 'operator', 'unlimited', 'executable', operators.readline, 'readline' }, + ['readonly'] = { 'operator', 'unlimited', 'executable', operators.readonly, 'readonly' }, + ['renderbands'] = { 'operator', 'unlimited', 'executable', operators.renderbands, 'renderbands' }, + ['repeat'] = { 'operator', 'unlimited', 'executable', operators["repeat"], 'repeat' }, + ['resetfile'] = { 'operator', 'unlimited', 'executable', operators.resetfile, 'resetfile' }, + ['restore'] = { 'operator', 'unlimited', 'executable', operators.restore, 'restore' }, + ['rlineto'] = { 'operator', 'unlimited', 'executable', operators.rlineto, 'rlineto' }, + ['rmoveto'] = { 'operator', 'unlimited', 'executable', operators.rmoveto, 'rmoveto' }, + ['roll'] = { 'operator', 'unlimited', 'executable', operators.roll, 'roll' }, + ['rotate'] = { 'operator', 'unlimited', 'executable', operators.rotate, 'rotate' }, + ['round'] = { 'operator', 'unlimited', 'executable', operators.round, 'round' }, + ['rrand'] = { 'operator', 'unlimited', 'executable', operators.rrand, 'rrand' }, + ['run'] = { 'operator', 'unlimited', 'executable', operators.run, 'run' }, + ['save'] = { 'operator', 'unlimited', 'executable', operators.save, 'save' }, + ['scale'] = { 'operator', 'unlimited', 'executable', operators.scale, 'scale' }, + ['scalefont'] = { 'operator', 'unlimited', 'executable', operators.scalefont, 'scalefont' }, + ['search'] = { 'operator', 'unlimited', 'executable', operators.search, 'search' }, + ['setdash'] = { 'operator', 'unlimited', 'executable', operators.setdash, 'setdash' }, + ['setflat'] = { 'operator', 'unlimited', 'executable', operators.setflat, 'setflat' }, + ['setfont'] = { 'operator', 'unlimited', 'executable', operators.setfont, 'setfont' }, + ['setgray'] = { 'operator', 'unlimited', 'executable', operators.setgray, 'setgray' }, + ['sethsbcolor'] = { 'operator', 'unlimited', 'executable', operators.sethsbcolor, 'sethsbcolor' }, + ['setlinecap'] = { 'operator', 'unlimited', 'executable', operators.setlinecap, 'setlinecap' }, + ['setlinejoin'] = { 'operator', 'unlimited', 'executable', operators.setlinejoin, 'setlinejoin' }, + ['setlinewidth'] = { 'operator', 'unlimited', 'executable', operators.setlinewidth, 'setlinewidth' }, + ['setmatrix'] = { 'operator', 'unlimited', 'executable', operators.setmatrix, 'setmatrix' }, + ['setmiterlimit'] = { 'operator', 'unlimited', 'executable', operators.setmiterlimit, 'setmiterlimit' }, + ['setrgbcolor'] = { 'operator', 'unlimited', 'executable', operators.setrgbcolor, 'setrgbcolor' }, + ['setcmykcolor'] = { 'operator', 'unlimited', 'executable', operators.setcmykcolor, 'setcmykcolor' }, + ['setscreen'] = { 'operator', 'unlimited', 'executable', operators.setscreen, 'setscreen' }, + ['settransfer'] = { 'operator', 'unlimited', 'executable', operators.settransfer, 'settransfer' }, + ['show'] = { 'operator', 'unlimited', 'executable', operators.show, 'show' }, + ['showpage'] = { 'operator', 'unlimited', 'executable', operators.showpage, 'showpage' }, + ['sin'] = { 'operator', 'unlimited', 'executable', operators.sin, 'sin' }, + ['sqrt'] = { 'operator', 'unlimited', 'executable', operators.sqrt, 'sqrt' }, + ['srand'] = { 'operator', 'unlimited', 'executable', operators.srand, 'srand' }, + ['stack'] = { 'operator', 'unlimited', 'executable', operators.stack, 'stack' }, + ['start'] = { 'operator', 'unlimited', 'executable', operators.start, 'start' }, + ['StandardEncoding'] = { 'array', 'unlimited', 'literal', add_VM(standardencoding()), 256, 256 }, + ['status'] = { 'operator', 'unlimited', 'executable', operators.status, 'status' }, + ['stop'] = { 'operator', 'unlimited', 'executable', operators.stop, 'stop' }, + ['stopped'] = { 'operator', 'unlimited', 'executable', operators.stopped, 'stopped' }, + ['store'] = { 'operator', 'unlimited', 'executable', operators.store, 'store' }, + ['string'] = { 'operator', 'unlimited', 'executable', operators.string, 'string' }, + ['stroke'] = { 'operator', 'unlimited', 'executable', operators.stroke, 'stroke' }, + ['sub'] = { 'operator', 'unlimited', 'executable', operators.sub, 'sub' }, + ['systemdict'] = { 'dict', 'unlimited', 'literal', systemdict }, + ['token'] = { 'operator', 'unlimited', 'executable', operators.token, 'token' }, + ['translate'] = { 'operator', 'unlimited', 'executable', operators.translate, 'translate' }, + ['transform'] = { 'operator', 'unlimited', 'executable', operators.transform, 'transform' }, + ['true'] = { 'boolean', 'unlimited', 'literal', true }, + ['truncate'] = { 'operator', 'unlimited', 'executable', operators.truncate, 'truncate' }, + ['type'] = { 'operator', 'unlimited', 'executable', operators.type, 'type' }, + ['userdict'] = { 'dict', 'unlimited', 'literal', userdict }, + ['usertime'] = { 'operator', 'unlimited', 'executable', operators.usertime, 'usertime' }, + ['version'] = { 'operator', 'unlimited', 'executable', operators.version, 'version' }, + ['vmstatus'] = { 'operator', 'unlimited', 'executable', operators.vmstatus, 'vmstatus' }, + ['wcheck'] = { 'operator', 'unlimited', 'executable', operators.wcheck, 'wcheck' }, + ['where'] = { 'operator', 'unlimited', 'executable', operators.where, 'where' }, + ['write'] = { 'operator', 'unlimited', 'executable', operators.write, 'write' }, + ['writehexstring'] = { 'operator', 'unlimited', 'executable', operators.writehexstring, 'writehexstring' }, + ['writestring'] = { 'operator', 'unlimited', 'executable', operators.writestring, 'writestring' }, + ['xcheck'] = { 'operator', 'unlimited', 'executable', operators.xcheck, 'xcheck' }, + ['xor'] = { 'operator', 'unlimited', 'executable', operators.xor, 'xor' }, + } + if directvm then + systemdict.dict = dict + else + VM[dictstack[systemdict]].dict = dict + end + end +end + +initializers[#initializers+1] = function(reset) + if reset then + dicterror = nil + errordict = nil + else + dicterror = add_VM { + access = 'unlimited', + size = 1, + maxsize = 40, + dict = { + newerror = { 'boolean', 'unlimited', 'literal', false } + }, + } + -- + errordict = add_VM { + access = 'unlimited', + size = 0, + maxsize = 40, + dict = { }, + } + -- + local d + if directvm then + d = systemdict.dict + else + d = VM[dictstack[systemdict]].dict + end + -- still needed ? + d['errordict'] = { 'dict', 'unlimited', 'literal', errordict } + d['systemdict'] = { 'dict', 'unlimited', 'literal', systemdict } + d['userdict'] = { 'dict', 'unlimited', 'literal', userdict } + d['$error'] = { 'dict', 'unlimited', 'literal', dicterror } + end +end + +-- What follows is the main interpreter, with the tokenizer first + +-- procedure scanning stack for the tokenizer + +local procstack +local procstackptr + +initializers[#initializers+1] = function(reset) + if reset then + procstack = nil + procstackptr = nil + else + procstack = { } + procstackptr = 0 + end +end + +-- lpeg parser for tokenization + +do + + local function push(v) + if procstackptr > 0 then + local top = procstack[procstackptr] + if top then + top[#top+1] = v + else + procstack[procstackptr] = { v } + end + return false + else + push_execstack(v) + return true + end + end + + local function start() + procstackptr = procstackptr + 1 + return true + end + + local function stop() + local v = procstack[procstackptr] + procstack[procstackptr] = { } + procstackptr = procstackptr - 1 + if push {'array', 'unlimited', 'executable', add_VM(v), 1, #v, 'd' } then + return true + end + end + + local function hexify(a) + return char(tonumber(a,16)) + end + + local function octify(a) + return char(tonumber(a,8)) + end + + local function radixed(base,value) + base = tonumber(base) + if base > 36 or base < 2 then + return nil + end + value = tonumber(value,base) + if not value then + return "error", false + elseif value > MAX_INT then + return "integer", value + else + return "real", value + end + end + + local space = S(' ') + local spacing = S(' \t\r\n\f') + local sign = S('+-')^-1 + local digit = R('09') + local period = P('.') + local letters = R('!~') - S('[]<>{}()%') + local hexdigit = R('09','af','AF') + local radixdigit = R('09','az','AZ') + + local p_integer = (sign * digit^1 * #(1-letters)) / tonumber + local p_real = ((sign * digit^0 * period * digit^0 + period * digit^1) * (S('eE') * sign * digit^1)^-1 * #(1-letters)) / tonumber + local p_literal = Cs(P("/")/"" * letters^1 * letters^0) + local p_symbol = C(letters^1 * letters^0) + ----- p_radixed = C(digit^1) * P("#") * C(radixdigit^1) * #(1-letters) / radixed-- weird #() here + local p_radixed = C(digit^1) * P("#") * C(radixdigit^1) / radixed + local p_unhexed = P("<") * Cs(((C(hexdigit*hexdigit) * Cc(16))/tonumber/char+spacing/"")^0) * P(">") + local p_comment = P('%') * (1 - S('\r\n'))^0 * Cc(true) + local p_bounding = P('%%BoundingBox:') * Ct((space^0 * p_integer)^4) * (1 - S('\r\n'))^0 + local p_lbrace = C("{") + local p_rbrace = C("}") + local p_lbracket = C("[") + local p_rbracket = C("]") + local p_finish = Cc(false) + + local p_string = + P("(") + * Cs( P { + ( + (1 - S("()\\"))^1 + + P("\\")/"" * ( + (C(digit *digit * digit) * Cc(8)) / tonumber / char + + P("n") / "\n" + P("r") / "\r" + P("t") / "\t" + + P("b") / "\b" + P("f") / "\f" + P("\\") / "\\" + + 1 + ) + + P("(") * V(1) * P(")") + )^0 + }) + * P(")") + + -- inspect(lpegmatch(p_radixed,"10#123")) + -- inspect(lpegmatch(p_unhexed,"<A2B3 C3>")) + -- inspect(lpegmatch(p_string,[[(foo(bar \124\125 \( bar\n bar\\bar))]])) + + local p_unhexed = Cc('string') * p_unhexed + local p_string = Cc('string') * p_string + local p_array_start = Cc('name') * p_lbracket + local p_array_stop = Cc('name') * p_rbracket + local p_exec_start = Cc('start') * p_lbrace + local p_exec_stop = Cc('stop') * p_rbrace + local p_integer = Cc('integer') * p_integer + local p_real = Cc('real') * p_real + local p_radixed = p_radixed + local p_symbol = Cc('name') * p_symbol + local p_literal = Cc('literal') * p_literal + local p_comment = Cc('comment') * p_comment + local p_bounding = Cc('bounding') * p_bounding + local p_finish = Cc("eof") * p_finish + local p_whitespace = spacing^0 + + local tokens = p_whitespace + * ( + p_bounding + + p_comment + + p_string + + p_unhexed + + p_array_start + + p_array_stop + + p_exec_start + + p_exec_stop + + p_real + + p_radixed + + p_integer + + p_literal + + p_symbol + + p_finish + )^-1 + * Cp() + + -- we can do push etc in the lpeg but the call is not faster than the check + -- and this stays closer to the original + + local function tokenize() + local object = execstack[execstackptr] + local sequence = object[4] + local position = object[5] + local length = object[6] + local tokentype = nil + local value = nil + while position < length do + tokentype, value, position = lpegmatch(tokens,get_VM(sequence),position) + if not position then + return false + elseif position >= length then + pop_execstack() + else + object[5] = position + end + if not value then + return false -- handle_error('syntaxerror') + elseif tokentype == 'integer' or tokentype == 'real' then + if push { tokentype, 'unlimited', 'literal', value } then + return true + end + elseif tokentype == 'name' then + if push { 'name', 'unlimited', 'executable', add_VM(value) } then + return true + end + elseif tokentype == 'literal' then + if push { 'name', 'unlimited', 'literal', add_VM(value) } then + return true + end + elseif tokentype == 'string' then + if push { 'string', 'unlimited', 'literal', add_VM(value), 1, #value } then + return true + end + elseif tokentype == 'start' then + if start() then + -- stay + end + elseif tokentype == 'stop' then + if stop() then + return true + end + elseif tokentype == 'bounding' then + specials.boundingbox = value + end + end + return position >= length + end + + -- the exec stack can contain a limited amount of interesting item types + -- to be handled by next_object: + -- executable arrays (procedures) + -- executable strings + -- executable files + + next_object = function() + if execstackptr == 0 then + return nil + end + local object = execstack[execstackptr] + if not object then + return nil + end + local otyp = object[1] + local exec = object[3] == 'executable' + if not exec then + return pop_execstack() + elseif otyp == 'array' then + if object[7] == 'd' then + return pop_execstack() + else + local proc = get_VM(object[4]) + local o = object[5] + local val = proc[o] + if o >= #proc then + object[5] = 1 + pop_execstack() + else + object[5] = o + 1 + end + return val + end + elseif otyp == 'string' then + if not tokenize() then + report("tokenizer failed on string") + return nil + else + return next_object() -- recurse + end + elseif otyp == 'file' then + if object[4] == 0 then + report('sorry, interactive mode is not supported') + end + if not tokenize() then + report("tokenizer failed on file") + return nil + else + return next_object() -- recurse + end + else + return pop_execstack() + end + end + +-- The main execution control function + + local detail = false -- much faster + + local report_exec = logs.reporter("escrito","exec") + + do_exec = function() -- already a local + local ret + local savedopstack = detail and copy_opstack() + local object = next_object() + if not object then + return false + end + local otyp = object[1] + if DEBUG then + if otyp == 'operator' then + report_exec("%s %s %s",otyp,object[3],object[5]) + elseif otyp == 'dict' then + local d = get_VM(object[4]) + report_exec("%s %s <%s:%s>",otyp,object[3],d.size or '',d.maxsize or '') + elseif otyp == 'array' or otyp == 'file' or otyp == 'save' then + report_exec("%s <%s:%s>",object[3],object[5] or '',object[6] or '') + elseif otyp == 'string' or otyp == 'name' then + report_exec("%s %s %s",otyp,object[3],get_VM(object[4])) + else + report_exec("%s %s %s",otyp,object[3],tostring(object[4])) + end + end + if otyp == 'real' or otyp == 'integer' or otyp == 'boolean' or otyp == 'mark' or otyp == 'save' or otyp == 'font' then + push_opstack(object) + elseif otyp == '.stopped' then + -- when .stopped is seen here, stop was never called + push_opstack { 'boolean', 'unlimited', 'executable', false} + elseif otyp == '.exit' then + -- when .exit is seen here, exit was never called + elseif otyp == 'array' then + if object[2] == 'noaccess' then + escrito.errorname = 'noaccess' + else + push_opstack(object) + end + elseif otyp == 'string' then + if object[2] == 'noaccess' then + escrito.errorname = 'noaccess' + else + push_opstack(object) + end + elseif otyp == 'dict' then + local dict = get_VM(object[4]) + if dict.access == 'noaccess' then + escrito.errorname = 'noaccess' + else + push_opstack(object) + end + elseif otyp == 'file' then + if object[2] == 'noaccess' then + errorname = 'noaccess' + else + push_opstack(object) + end + elseif otyp == 'null' then + push_opstack(object) + elseif otyp == 'operator' then + if object[3]=='executable' then + ret, escrito.errorname = object[4]() + else + push_opstack(object) + end + elseif otyp == 'save' then + -- todo + elseif otyp == 'name' then + if object[3] == 'executable' then + local v = lookup(get_VM(object[4])) + if not v then + if escrito.errorname then + -- doesn't work, needs thinking + error ("recursive error detected inside '" .. escrito.errorname .. "'") + end + escrito.errorname = 'undefined' + else + if DEBUG then + local vt = v[1] + if vt == 'operator' then + print ('exec2: ' .. vt .. ' ' .. v[3] .. ' '.. v[5]) + elseif vt == 'dict' or vt == 'array' or vt == 'file' or vt == 'save' then + print ('exec2: ' .. vt .. ' ' .. v[3] .. ' <'.. (v[5] or '') .. '>') + elseif vt == 'string' or vt == 'name' then + print ('exec2: ' .. vt .. ' ' .. v[3] .. ' '.. get_VM(v[4])) + else + print ('exec2: ' .. vt .. ' ' .. v[3] .. ' '.. tostring(v[4])) + end + end + push_execstack(v) + end + else + push_opstack(object) + end + elseif otyp == 'null' then + -- do nothing + elseif otyp == 'array' then + push_opstack(object) + end + + if escrito.errorname then + if savedopstack then + local v = lookup_error(escrito.errorname) + if not v then + print("unknown error handler for '" .. escrito.errorname .. "', quitting") + return false + else + set_opstack(savedopstack) + push_opstack { otyp, object[2], "literal", object[4], object[5], object[6], object[7] } + push_opstack { 'string','unlimited','literal',add_VM(escrito.errorname), 1 } + push_execstack(v) + end + escrito.errorname = nil + else + print("error '" .. escrito.errorname .. "', quitting") + -- os.exit() + end + end + + return true + end + +end + +do + + -- some of the errors will never actually happen + + local errornames = { + "dictfull", "dictstackoverflow", "dictstackunderflow", "execstackoverflow", + "interrupt", "invalidaccess", "invalidexit", "invalidfileaccess", "invalidfont", "invalidrestore", + "ioerror", "limitcheck", "nocurrentpoint", "rangecheck", "stackoverflow", "stackunderflow", + "syntaxerror", "timeout", "typecheck", "undefined", "undefinedfilename", "undefinedresult", + "unmatchedmark", "unregistered", "VMerror" + } + + local generic_error_proc = [[{ + $error /newerror true put + $error exch /errorname exch put + $error exch /command exch put + count array astore $error /ostack 3 -1 roll put + $error /dstack countdictstack array dictstack put + countexecstack array execstack aload pop pop count array astore $error /estack 3 -1 roll put + stop + } bind ]] + + local generic_handleerror_proc = [[{ + $error begin + /newerror false def + (%%[ Error: ) print + errorname print + (; OffendingCommand: ) print + command == + ( ]%%\n) print flush + end + }]] + + local enabled + + local function interpret(data) + if enabled then + push_opstack { 'file', 'unlimited', 'executable', add_VM(data), 1, #data, 'r', stdin } + push_execstack { 'operator', 'unlimited', 'executable', operators.stopped, 'stopped' } + while true do + if not do_exec() then + local v = pop_opstack() + if v and v[4] == true then + local proc = { + { 'name', 'unlimited', 'executable', add_VM('errordict') }, -- hm, errordict + { 'name', 'unlimited', 'literal', add_VM('handleerror') }, + { 'operator', 'unlimited', 'executable', operators.get, 'get' }, + { 'operator', 'unlimited', 'executable', operators.exec, 'exec' }, + } + push_execstack { 'array', 'unlimited', 'executable', add_VM(proc), 1, #proc, 'i' } + else + return + end + end + end + end + end + + local function close() + for i=1,#initializers do + initializers[i](true) + end + enabled = false + end + + local function open(options) + enabled = true + local starttime = os.clock() + local stoptime = nil + for i=1,#initializers do + initializers[i]() + end + if type(options) == "table" then + devicename = options.device or "pdf" + findfont = options.findfont or findfont + randomseed = options.randomseed or randomseed -- todo + calculatebox = options.calculatebox + else + devicename = "pdf" + end + device = devices[devicename] or devices.pdf + operators.initgraphics() + for i=1,#errornames do + interpret(formatters["errordict /%s %s put"](errornames[i],generic_error_proc), INITDEBUG) + end + -- set up the error handler + interpret("systemdict /= { 20 string cvs print } bind put", INITDEBUG) + interpret("systemdict /prompt { (PS>) print flush } bind put", INITDEBUG) + interpret(format("errordict /handleerror %s bind put", generic_handleerror_proc), INITDEBUG) + interpret("systemdict /handleerror {errordict /handleerror get exec } bind put", INITDEBUG) + -- user dict initializations + interpret(format("/quit { stop } bind def"), INITDEBUG) + interpret(format("userdict /#copies 1 put"), INITDEBUG) + local job = { + runtime = 0, + interpret = interpret, + boundingbox = boundingbox, + close = function() + close() + local runtime = os.clock() - starttime + job.runtime = runtime + return runtime + end, + } + return job + end + + escrito.open = open + + if context then + + function escrito.convert(options) + if type(options) == "table" then + local data = options.data + if not data or data == "" then + local buffer = options.buffer + local filename = options.filename -- needs escaping + if buffer and buffer ~= "" then + data = buffers.getcontent(buffer) + elseif filename and filename ~= "" then + data = io.loaddata(filename) -- use resolver + end + end + if data and data ~= "" then + local e = open(options) +-- print(data) + e.interpret(data) + return e.close() + end + end + return 0 + end + + end + + escrito.devices = devices + +end + +return escrito diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-escrito.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-escrito.mkiv new file mode 100644 index 00000000000..76385791884 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-escrito.mkiv @@ -0,0 +1,184 @@ +%D \module +%D [ file=m-escrito, +%D version=2015.09.27, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=ESCRITO, +%D author={Taco Hoekwater \& Hans Hagen}, +%D date=\currentdate, +%D copyright={\CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\registerctxluafile{m-escrito}{1.001} + +%D This is a fun project and not meant for production (yet). It's a follow up on a +%D project by Taco presented at a Bacho\TeX\ meeting years ago. I probably messed up +%D the code so much that some things don't work but then, fonts are not really +%D supported well anyway. However for simple \POSTSCRIPT\ things work out ok. +%D +%D I (Hans) will occasionally have a look at the code. Who knows what our trips to +%D \TeX\ meetings lead to. + +\unprotect + +\unexpanded\def\startESCRITOgraphic#1#2#3#4% + {\dontleavehmode + \begingroup + \MPllx#1\onebasepoint + \MPlly#2\onebasepoint + \MPurx#3\onebasepoint + \MPury#4\onebasepoint + \setbox\b_meta_graphic\hbox\bgroup} + +\unexpanded\def\stopESCRITOgraphic + {\egroup + \setbox\b_meta_graphic\ruledhbox\bgroup + \kern-\MPllx\raise-\MPlly\box\b_meta_graphic + \egroup + \wd\b_meta_graphic\dimexpr\MPurx-\MPllx\relax + \ht\b_meta_graphic\dimexpr\MPury-\MPlly\relax + \dp\b_meta_graphic\zeropoint + \box\b_meta_graphic + \endgroup} + +\unexpanded\def\flushESCRITOtext#1#2#3% no fratures so pretty weak, better use overlays + {\smash{\rlap{\definedfont[#1 at #2bp]#3}}} + +\unexpanded\def\stopESCRITO + {\edef\p_option{\namedbufferparameter{ESCRITO}\c!option}% + \ctxlua{escrito.convert { + buffer = "\thedefinedbuffer{ESCRITO}", + calculatebox = \ifx\p_option\v!fit true\else false\fi, + }}} + +\unexpanded\def\processESCRITO[#1]% + {\begingroup + \getdummyparameters[\c!file=,\c!option=,#1]% + \edef\p_option{\dummyparameter\c!option}% + \ctxlua{escrito.convert { + filename = "\dummyparameter\c!file", + calculatebox = \ifx\p_option\v!fit true\else false\fi, + }}% + \endgroup} + +\definebuffer + [ESCRITO] + +\setupbuffer + [ESCRITO] + [\c!option=, + \c!after=\processESCRITO] + +\protect + +% This will move to m-escrito.lua once we know how to deal with it ... no time +% now. + +\startluacode + + local literal = nodes.pool.register(node.new("whatsit",nodes.whatsitcodes.pdfliteral)) + literal.mode = 0 + + local function newliteral(result) + local l = nodes.copy(literal) + l.data = result + return l + end + + local p = escrito.devices.pdf + + function p.startpage(llx,lly,urx,ury) + context.startESCRITOgraphic(llx,lly,urx,ury) + end + + function p.stoppage() + context.stopESCRITOgraphic() + end + + function p.flushpage(result) + context(newliteral(result)) + end + + -- todo + + local fontnames = { } + local fontfiles = { } + + fontnames['NimbusSanL-Regu'] = 'Sans' + fontnames['StandardSymL'] = 'rpsyr' + fontnames['dejavuserif-regular'] = 'dejavuserif-regular' + + function p.showfont(object) + local color = object.color + local ctype = object.colortype + local matrix = object.matrix + local text = object.string + local size = object.fontmatrix[1] * 1000 + local result = { "q" } + context(newliteral(formatters['%f %f %f %f %f %f cm'](matrix[1],matrix[2],matrix[3],matrix[4],matrix[5],matrix[6]))) + if ctype == "rgb" then + local r, g, b = color[1], color[2], color[3] + context(newliteral(formatters["%f %f %f rg %f %f %f RG"](r,g,b,r,g,b))) + elseif ctype == "cmyk" then + local c, m, y, k = color[1], color[2], color[3], color[4] + context(newliteral(formatters["%f %f %f k %f %f %f K"](c,m,y,k,c,m,y,k))) + elseif ctype == "gray" then + context(newliteral(formatters["%f g %f G"](color,color))) + end + context.flushESCRITOtext(fontnames[object.fontname],size,text) + context(newliteral("Q")) + end + + local function findfont(fontname) + return fontfiles[fontname] + end + +\stopluacode + +\continueifinputfile{m-escrito.mkiv} + +\starttext + +% \startluacode +% local n = 5 +% for i=1,n do +% context.startTEXpage() +% local runtime = escrito.convert { filename = "tiger.eps", calculatebox = true } +% context.par() +% context("calculated boundingbox, time: %s",runtime) +% context.stopTEXpage() +% end +% for i=1,n do +% context.startTEXpage() +% local runtime = escrito.convert { filename = "tiger.eps", calculatebox = false } +% context.par() +% context("built in boundingbox, time: %s",runtime) +% context.stopTEXpage() +% end +% \stopluacode + +\startTEXpage + \startESCRITO + (tiger.eps) run + \stopESCRITO +\stopTEXpage + +\startTEXpage + \setupbuffer[ESCRITO][option=fit]% + \startESCRITO + (tiger.eps) run + \stopESCRITO +\stopTEXpage + +\startTEXpage + \processESCRITO[file=tiger.eps] +\stopTEXpage + +\startTEXpage + \processESCRITO[file=tiger.eps,option=fit] +\stopTEXpage + +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-fields.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-fields.mkiv new file mode 100644 index 00000000000..46b77f8d39b --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-fields.mkiv @@ -0,0 +1,70 @@ +%D \module +%D [ file=m-fields, +%D version=2010.03.14, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Fields, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D A rather old example of field usage is the following. It +%D makes no sense to have this in the core. +%D +%D \starttyping +%D before \fillinfield[oeps]{whatever} after +%D \stoptyping + +\startJSpreamble{FillInField} used later + function CheckFillInField(right) { + if (event.value.toLowerCase() == right.toLowerCase()) { + event.target.hidden = true ; + } + event.value = "" + } +\stopJSpreamble + +\newcount\noffillinfields + +\definefieldcategory + [fillinfield] + [\c!n=1024, + \c!height=\strutht, + \c!depth=\strutdp, + \c!align=\v!middle, + \c!color=red, + \c!fieldframecolor=blue, + \c!fieldbackgroundcolor=\s!white, + \c!validate=JS(CheckFillInField{\therightanswer})] + +\def\fillinfield + {\dosingleempty\dofillinfield} + +\def\dofillinfield[#1]#2% + {\dontleavehmode + \hbox + {\forgetall + \global\advance\noffillinfields\plusone + \edef\currentfillinfieldname{fillinfield:\number\noffillinfields}% + \useJSscripts[ans]% + \definefieldbody + [\currentfillinfieldname] + [\c!type=\v!line, + \c!category=fillinfield]% + \doifelsenothing{#1} + {\def\therightanswer{#2}} + {\def\therightanswer{#1}}% + \setbox0\hbox{\strut#2}% + \setbox2\hbox{\strut\therightanswer}% + \dimen0=\dimexpr\ifdim\wd0>\wd2 \wd0 \else \wd2 \fi + .2em\relax + \hbox to \wd0 + {\wd0\zeropoint + \box0 + \hss\fieldbody[\currentfillinfieldname][\c!width=\dimen0]\hss}}} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-format.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-format.mkiv new file mode 100644 index 00000000000..f9dd348a49c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-format.mkiv @@ -0,0 +1,411 @@ +%D \module +%D [ file=m-formay, +%D version=ancient, +%D title=\CONTEXT\ Modules, +%D subtitle=Ancient Formatting Code, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Here is some code that I had laying around and had forgotten +%D about. Let's make it a module and see if there is interest in +%D such things. + +% \defineformatblock [poem] +% \defineformatsegment [verse] % [poem] +% \defineformatline [line] % [verse] +% +% \startpoem [title] [author] +% \startverse [ref] +% \startline [ref] +% +% block : voor na tussen *tekstletter *tekstkleur +% +% segment : voor na tussen *tekstletter *tekstkleur +% : links rechts linkeroffset rechteroffset +% : ?marge *evenmarge *onevenmarge breedte +% : nummer *nummercommando *conversie +% : nummerletter nummerkleur *label +% +% line : voor na tussen *tekstletter *tekstkleur +% : nummer *nummercommando *conversie +% : nummerletter nummerkleur *label +% +% * = todo + +\unprotect + +\definesystemvariable {fx} % format block +\definesystemvariable {fy} % format segment +\definesystemvariable {fz} % format line + +\def\defineformatblock + {\dodoubleempty\dodefineformatblock} + +\def\dodefineformatblock[#1][#2]% + {\setupformatblock + [#1] + [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank, + \c!textstyle=,\c!textcolor=,#2]% + \setvalue{\e!start#1}{\startformatblock[#1]}% + \setvalue{\e!stop #1}{\stopformatblock}} + +\def\setupformatblock + {\dodoubleempty\dosetupformatblock} + +\def\setupformatblock[#1]% + {\getparameters[\??fx#1]} + +\def\startformatblock[#1]% + {\dotriplegroupempty\dostartformatblock{#1}} + +\def\dostartformatblock#1#2#3 + {\bgroup + \getvalue{\??fx#1\c!before} + \doglobal\newcounter\formatsegmentcounter + \doglobal\newcounter\formatlinecounter + \doglobal\newcounter\formatlinesubcounter + \doglobal\newcounter\formatlinemaxcounter + \doifsomething{#2}{\leftaligned{#2}\getvalue{\??fx#1\c!inbetween}} + \def\stopformatblock% + {\doifsomething{#3}{\getvalue{\??fx#1\c!inbetween}\leftaligned{#3}} + \getvalue{\??fx#1\c!after} + \egroup}} + +\def\defineformatsegment + {\dodoubleempty\dodefineformatsegment} + +\def\dodefineformatsegment[#1][#2]% + {\setupformatsegment + [#1] + [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank, + \c!textstyle=,\c!textcolor=,\c!left=,\c!right=, + \c!leftoffset=\!!zeropoint,\c!rightoffset=\!!zeropoint, + %\c!margin=\!!zeropoint,\c!evenmargin=\!!zeropoint,\c!oddmargin=\hsize, + \c!width=\hsize,\c!numberstyle=,\c!numbercolor=,\c!number=\v!no, + \c!numbercommand=,\c!conversion=,\c!label=, + #2]% + \setvalue{\e!start#1}{\startformatsegment[#1]}% + \setvalue{\e!stop #1}{\stopformatsegment}} + +\def\setupformatsegment + {\dodoubleempty\dosetupformatsegment} + +\def\setupformatsegment[#1]% + {\getparameters[\??fy#1]} + +\def\placeformatsegmentcounter + {\formatsegmentcounter\quad\hphantom{\placeformatlinecounter}} + +\def\placeformatlinecounter + {\formatlinecounter} + +\def\startformatsegment[#1]% + {\bgroup + \doifelsevalue{\??fy#1\c!number}\v!yes + {\def\doplaceformatsegmentcounter + {\inleftmargin + {\doattributes{\??fy#1}\c!numberstyle\c!numbercolor + {\placeformatsegmentcounter}}}} + {\let\doplaceformatsegmentcounter\relax}% + \getvalue{\??fy#1\c!before} + \doglobal\increment\formatsegmentcounter + \def\formatrightoffset{\getvalue{\??fy#1\c!rightoffset}} + \def\formatleftoffset {\getvalue{\??fy#1\c!leftoffset}} + \def\formatminwidth {\getvalue{\??fy#1\c!minwidth}} + \def\formatwidth {\getvalue{\??fy#1\c!width}} + %\def\formatmargin {\getvalue{\??fy#1\c!margin}} + \def\formatbefore {\getvalue{\??fy#1\c!before}} + \def\formatinbetween {\getvalue{\??fy#1\c!inbetween}} + \def\formatafter {\getvalue{\??fy#1\c!after}} + \def\formatleft {\getvalue{\??fy#1\c!left}} + \def\formatright {\getvalue{\??fy#1\c!right}} + \@@segmentvarianta + \getvalue{@@segmentvariant\getvalue{\??fy#1\c!alternative}} + \def\stopformatsegment + {\getvalue{\??fy#1\c!after} + \egroup}} + +\newif\iftraceformatblock + +\def\@@segmentvarianta % ragged right, symbols + {\let\formatraggedness\raggedright + \let\dostartformatline\dostartformatlineab + \let\formatleftfirst\relax \let\formatrightfirst\hfill + \let\formatleftnext \hfill \let\formatrightnext \relax} + +\def\@@segmentvariantb % ragged right, equal parts, symbols + {\let\formatraggedness\raggedcenter + \let\dostartformatline\dostartformatlineab + \let\formatleftfirst\relax \let\formatrightfirst\hfill + \let\formatleftnext \hfill \let\formatrightnext \relax} + +\def\@@segmentvariantc % ragged right + {\let\formatraggedness\veryraggedright + \let\dostartformatline\dostartformatlinecde + \let\formatleftnext\relax \let\formatrightnext\hfill} + +\def\@@segmentvariantd % ragged center + {\let\formatraggedness\veryraggedcenter + \let\dostartformatline\dostartformatlinecde + \let\formatleftnext\hfill \let\formatrightnext\hfill} + +\def\@@segmentvariante % ragged left + {\let\formatraggedness\veryraggedleft + \let\dostartformatline\dostartformatlinecde + \let\formatleftnext\hfill \let\formatrightnext\relax} + +\def\defineformatline + {\dodoubleempty\dodefineformatline} + +\def\dodefineformatline[#1][#2]% + {\setupformatline + [#1] + [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank, + \c!textstyle=,\c!textcolor=, + \c!number=\v!no,\c!numbercommand=,\c!conversion=, + \c!numberstyle=,\c!numbercolor=,\c!label=, + #2]% + \setvalue{\e!start#1}{\startformatline[#1]}% + \setvalue{\e!stop #1}{\stopformatline}} + +\def\setupformatline + {\dodoubleempty\dosetupformatline} + +\def\setupformatline[#1]% + {\getparameters[\??fz#1]} + +\newconditional\formatforcedbreak + +\def\startformatline[#1]% + {\bgroup + \doifelsevalue{\??fz#1\c!number}\v!yes + {\def\doplaceformatlinecounter + {\inleftmargin + {\doattributes{\??fz#1}\c!numberstyle\c!numbercolor + {\placeformatlinecounter}}}} + {\let\doplaceformatlinecounter\relax}% + \global\setfalse\formatforcedbreak + \def\\{\break\global\settrue\formatforcedbreak}% + \hsize\formatwidth + \doglobal\increment\formatlinecounter + \par + \nobreak + \def\stopformatline + {\unskip\unskip\unskip\unskip\unskip\egroup + \let\doplaceformatsegmentcounter\relax} + \postponenotes + \dowithnextbox{\dostartformatline}\hbox\bgroup\ignorespaces} + +\def\dostartformatlineab + {%\dosetleftskipadaption\formatmargin + %\advance\hsize-\leftskipadaption\relax + \ifdim\nextboxwd>\hsize + \beginofshapebox + \forgetall + \hangafter\plusone + \hangindent\formatleftoffset + \formatraggedness + \hskip\formatrightoffset + \unhbox\nextbox\par + \endofshapebox + %\advance\hsize \leftskipadaption + \doglobal\newcounter\formatlinesubcounter + \reshapebox + {\doglobal\increment\formatlinesubcounter} + \global\let\formatlinemaxcounter\formatlinesubcounter + \reshapebox + {\doglobal\decrement\formatlinesubcounter + \ifnum\formatlinesubcounter=\zerocount + \doplaceformatsegmentcounter + \doplaceformatlinecounter + \hskip-\formatrightoffset + %\hskip\leftskipadaption + \formatleftfirst + \unhbox\shapebox + \ifnum\formatlinemaxcounter>\plusone + \ifx\formatright\empty\else + \shapedhbox to \zeropoint{\formatright\hss}% + \fi + \fi + \formatrightfirst + \iftraceformatblock + \ruledhskip\formatrightoffset\hskip-\formatrightoffset + \fi + \else + %\hskip\leftskipadaption + \iftraceformatblock + \ruledhskip\formatleftoffset\hskip-\formatleftoffset + \fi + \formatleftnext + \ifx\formatleft\empty\else + \shapedhbox to \zeropoint{\hss\formatleft}% + \fi + \unhbox\shapebox + \formatrightnext + \fi} + \flushshapebox + \else + \dontleavehmode\hbox + {\doplaceformatsegmentcounter + \doplaceformatlinecounter + %\hskip\leftskipadaption + \formatleftfirst + \unhbox\nextbox + \formatrightfirst} + \fi + \par + \egroup} + +\def\dostartformatlinecde + {%\dosetleftskipadaption\formatmargin + %\advance\hsize -\leftskipadaption\relax + \dimen0=\hsize + \ifconditional\formatforcedbreak\else + \ifdim\formatminwidth>\zeropoint\relax + \ifdim\nextboxwd>\hsize + \doloop + {\global\dimen1=\dimen0 + \beginofshapebox + \hsize\dimen0 + \forgetall + \formatraggedness + \unhcopy\nextbox\par + \endofshapebox + \reshapebox + {\setbox\scratchbox=\hbox{\unhbox\shapebox}% + \ifdim\wd\scratchbox<\dimen1 + \global\dimen1=\wd\scratchbox + \fi} + \ifdim\dimen1<\formatminwidth\relax + \advance\dimen0 by -.25em + \else + \exitloop + \fi + \ifdim\dimen0<10em + \dimen0=\hsize + \exitloop + \fi} + \fi + \fi + \fi + \beginofshapebox + \hsize\dimen0 + \forgetall + \formatraggedness + \unhcopy\nextbox\par + \endofshapebox + %\advance\hsize \leftskipadaption + \doglobal\newcounter\formatlinesubcounter + \reshapebox + {\doglobal\increment\formatlinesubcounter}% + \global\let\formatlinemaxcounter\formatlinesubcounter + \reshapebox + {\doglobal\decrement\formatlinesubcounter + \ifnum\formatlinesubcounter=\zerocount + \doplaceformatsegmentcounter + \doplaceformatlinecounter + \fi + %\hskip\leftskipadaption + \formatleftnext + \unhbox\shapebox + \formatrightnext\strut}% strut prevents unskip + \flushshapebox + \par + \egroup} + +\defineformatblock[poem] + [\c!before=\blank, + \c!inbetween={\blank[\v!medium]}, + \c!after=\blank] + +\defineformatsegment[verse] + [\c!alternative=\v!left, + \c!width=\hsize, + %\c!margin=\!!zeropoint, + \c!before={\blank[\v!medium]}, + \c!after={\blank[\v!medium]}, + \c!inbetween={\blank[\v!medium]}, + \c!leftoffset=3em, + \c!rightoffset=2em, + \c!minwidth=5em, + \c!left={\mathematics{[}\enspace}, + \c!right={\enspace\mathematics{]}}] + +\defineformatline[line] + [] + +\protect + +\doifnotmode{demo} {\endinput} + +% evt defineblank[formatbefore,formatinbetween,formatafter] + +%\showframe \traceformatblocktrue + +\usemodule[visual] + +\setuplayout[height=middle,topspace=1cm,header=0pt,footer=0pt] +\setupbodyfont[10pt] + +% All interfaces supported, but testing with english; todo: +% more options, more alternatives, inheritance and mixed +% definitions, and so. + +\starttext + +\startbuffer +\startbuffer[poem] +\startpoem{A Random Poem}{Hans Hagen} + \startverse + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \stopverse + \startverse + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \startline \fakewords{4}{8} \stopline + \stopverse +\stoppoem +\stopbuffer + +\setupformatsegment[verse][width=.4\hsize,number=yes,numberstyle=slanted] +\setupformatline [line] [number=yes,numberstyle=smallslanted] + +\startbuffer[x] +\setupformatsegment[verse][leftoffset=0pt,rightoffset=0pt,left=,right=] +\stopbuffer + +\section{Alternative A} + +\setupformatsegment[verse][alternative=a] {\getbuffer[poem]} +\setupformatsegment[verse][alternative=a] {\getbuffer[x,poem]} + +\section{Alternative B} + +\setupformatsegment[verse][alternative=b] {\getbuffer[poem]} +\setupformatsegment[verse][alternative=b] {\getbuffer[x,poem]} + +\section{Alternative C} + +\setupformatsegment[verse][alternative=c] {\getbuffer[poem]} + +\section{Alternative D} + +\setupformatsegment[verse][alternative=d] {\getbuffer[poem]} + +\section{Alternative E} + +\setupformatsegment[verse][alternative=e] {\getbuffer[poem]} +\stopbuffer + +\typebuffer \getbuffer + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-graph.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-graph.mkiv new file mode 100644 index 00000000000..62c4ec4cb87 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-graph.mkiv @@ -0,0 +1,133 @@ +%D \module +%D [ file=m-graph, +%D version=2008.09.08, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\METAPOST\ graph module support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% We just assume lua specification instead of the graph ones that +% are limited by what mp can do. We support @ as replacement for +% the percent symbol. We also add a specifier when no one is given. + +\unprotect + +\defineMPinstance + [graph] + [\s!format=metafun, + \s!extensions=\v!yes, + \s!initializations=\v!yes, + \c!method=\s!double] + +\startMPdefinitions{graph} + if unknown context_grap : input mp-grap.mpiv ; fi ; +\stopMPdefinitions + +\protect + +\continueifinputfile{m-graph.mkiv} + +%D We put this test here as in \type {meta-tex.mkiv} it would abort due to redefinition +%D of namespaces. + +\starttext + +\startMPpage[instance=graph] + label.rt(format("@g","1e-8"), (0, 0)) ; + label.rt(format("@g","1e+8"), (2cm, 0)) ; + label.rt(format("@g","1e-10"), (0, -0.5cm)) ; + label.rt(format("@g","1e+10"), (2cm,-0.5cm)) ; + label.rt(format("@g","1e-12"), (0, -1.0cm)) ; + label.rt(format("@g","1e+12"), (2cm,-1.0cm)) ; + label.rt(format("@g","1e-0"), (0, -1.5cm)) ; + label.rt(format("@g","1e+0"), (2cm,-1.5cm)) ; + label.rt(format("@g","1"), (0, -2.0cm)) ; + label.rt(format("@g","1"), (2cm,-2.0cm)) ; + label.rt(format("@g","1e-102"),(0, -2.5cm)) ; + label.rt(format("@g","1e+102"),(2cm,-2.5cm)) ; + currentpicture := currentpicture shifted (-4cm,0) ; + % + label.rt(format("@j","1e-8"), (0, 0)) ; + label.rt(format("@j","1e+8"), (2cm, 0)) ; + label.rt(format("@j","1e-10"), (0, -0.5cm)) ; + label.rt(format("@j","1e+10"), (2cm,-0.5cm)) ; + label.rt(format("@j","1e-12"), (0, -1.0cm)) ; + label.rt(format("@j","1e+12"), (2cm,-1.0cm)) ; + label.rt(format("@j","1e-0"), (0, -1.5cm)) ; + label.rt(format("@j","1e+0"), (2cm,-1.5cm)) ; + label.rt(format("@j","1"), (0, -2.0cm)) ; + label.rt(format("@j","1"), (2cm,-2.0cm)) ; + label.rt(format("@j","1e-102"),(0, -2.5cm)) ; + label.rt(format("@j","1e+102"),(2cm,-2.5cm)) ; + label.rt(formatted("(@f,@f)",(1.23,4.56)),(0cm,-3.0cm)) ; + label.rt(formatted("(@i,@i)",(1.23,4.56)),(0cm,-3.5cm)) ; + label.rt(formatted("(@g,@g)",(1.23,4.56)),(0cm,-4.0cm)) ; + label.rt(formatted("(@e,@e)",(1.23,4.56)),(0cm,-4.5cm)) ; + label.rt(formatted("(@j,@j)",(1.23,4.56)),(0cm,-5.0cm)) ; +\stopMPpage + +\stoptext + +% \startMPpage[instance=graph] +% draw begingraph(3in,2in); +% gdraw "t:/metapost/grphdata/agepop91.d"; +% endgraph; +% \stopMPpage + +% \startMPpage[instance=graph] +% draw begingraph(3in,2in); +% gdraw "agepop91.d" plot btex $\bullet$ etex; +% endgraph; +% \stopMPpage + +% \startMPpage[instance=graph] +% draw begingraph(3in,2in); +% glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT); +% glabel.bot(btex Age in years etex, OUT); +% gdraw "agepopm.d"; +% endgraph; +% \stopMPpage + +% \startMPpage[instance=graph] +% draw begingraph(3in,2in); +% glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT); +% glabel.bot(btex Age in years etex, OUT); +% setrange(origin, whatever,whatever); +% gdraw "agepopm.d"; +% endgraph; +% \stopMPpage + +% \startMPpage[instance=graph] +% draw begingraph(2.3in,2in); +% setcoords(log,log); +% glabel.lft(btex Seconds etex,OUT); +% glabel.bot(btex Matrix size etex, +% OUT); +% gdraw "matmul.d" dashed evenly; +% glabel.ulft(btex Standard etex,8); +% gdraw "matmul.d"; +% glabel.lrt(btex Strassen etex,7); +% endgraph; +% \stopMPpage + +% \startMPpage[instance=graph] +% draw begingraph(6.5cm,4.5cm); +% setrange(80,0, 90,whatever); +% glabel.bot(btex Year etex, OUT); +% glabel.lft(btex \vbox{\hbox{Emissions in} \hbox{thousands of} +% \hbox{metric tons} \hbox{(heavy line)}}etex, OUT); +% gdraw "lead.d" withpen pencircle scaled 1.5pt; +% autogrid(,otick.lft); +% setcoords(linear,linear); +% setrange(80,0, 90,whatever); +% glabel.rt(btex \vbox{\hbox{Micrograms} \hbox{per cubic} +% \hbox{meter of air} \hbox{(thin line)}}etex, OUT); +% gdraw "lead.d"; +% autogrid(otick.bot,otick.rt); +% endgraph; +% \stopMPpage diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-hemistich.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-hemistich.mkiv new file mode 100644 index 00000000000..7a849d415be --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-hemistich.mkiv @@ -0,0 +1,120 @@ +%D \module +%D [ file=m-hemistich, +%D version=2013.08.26, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Hemistiches, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is an experimental module for Idris. More is possible but not now. + +\unprotect + +\installcorenamespace{hemistich} + +\installcommandhandler \??hemistich {hemistich} \??hemistich + +\setuphemistich + [\c!width=\v!local, + \c!distance=4\emwidth, + \c!separator=\vl\hskip.25em\vl] + +\unexpanded\def\hemistiches + {\dosingleempty\dohemistiches} + +\unexpanded\def\dohemistiches + {\dodohemistiches\empty} + +\unexpanded\def\dodohemistiches#1[#2]#3#4% + {\dontleavehmode + \begingroup + \doifelseassignment{#2} + {\edef\currenthemistich{#1}% + \setupcurrenthemistich[#2]} + {\def\currenthemistich{#2}}% + \doifelse{\hemistichparameter\c!width}\v!local + {\scratchwidth\availablehsize} + {\scratchwidth\hemistichparameter\c!width\relax}% + \spaceskip\zeropoint\s!plus\plusone\s!fill\relax + \dostarttagged\t!division\currenthemistich + \hbox to \scratchwidth\bgroup + \scratchwidth.5\dimexpr\scratchwidth-\hemistichparameter\c!distance\relax + \hbox to \scratchwidth\bgroup + \dostarttagged\t!construct\c!lefttext + \usehemistichstyleandcolor\c!leftstyle\c!leftcolor#3% + \dostoptagged + \egroup + \hss + \begingroup + \dostarttagged\t!construct\c!separator + \usehemistichstyleandcolor\c!separatorstyle\c!separatorcolor + \hemistichparameter\c!separator + \dostoptagged + \endgroup + \hss + \hbox to \scratchwidth\bgroup + \dostarttagged\t!construct\c!righttext + \usehemistichstyleandcolor\c!rightstyle\c!rightcolor#4% + \dostoptagged + \egroup + \egroup + \dostoptagged + \endgroup} + +\unexpanded\def\hemistichescaesura#1#2#3% + {\dodohemistiches\empty[\c!separator={#2}]{#1}{#3}} + +\appendtoks + \setvalue{\currenthemistich}{\dohemistiches{\currenthemistich}}% +\to \everydefinehemistich + +\protect + +\continueifinputfile{m-hemistich.mkiv} + +\setuphemistich + [leftcolor=darkred, + separatorcolor=darkgreen, + rightcolor=darkblue] + +\setupwhitespace + [big] + +\starttext + +% \righttoleft + +\hemistichescaesura{left side of the brain}{equals}{right side of the brain} + +\hemistiches{left side of the brain}{right side of the brain} + +\startitemize + \startitem + \hemistiches{left side of the brain}{right side of the brain} + \startitemize + \startitem + \hemistiches{left side of the brain}{right side of the brain} + \startitemize + \startitem + \hemistiches{left side of the brain}{right side of the brain} + \stopitem + \stopitemize + \stopitem + \stopitemize + \startitem + \hemistiches{left side of the brain}{right side of the brain} + \stopitem + \stopitem +\stopitemize + +\startitemize +\item \hemistiches{left side of the brain}{right side of the brain} +\stopitemize + +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-ipsum.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-ipsum.mkiv new file mode 100644 index 00000000000..1c5901d8696 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-ipsum.mkiv @@ -0,0 +1,198 @@ +%D \module +%D [ file=m-ipsum, +%D version=2012.07.19, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Ipsum, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D After some discussing on the mailing list I made this example of +%D an implementation. Of course there can be alternatives as it's a +%D nice exercise in module writing. + +\startluacode + +local patterns = lpeg.patterns + +local variables = interfaces.variables +local v_random = variables.random + +local lowercase = characters.lower + +local ipsum = { } +moduledata.ipsum = ipsum + +local data = { } + +local function getfiledata(settings) + local filename = settings.filename or "" + local filedata = data[filename] + if not filedata then + local text = resolvers.loadtexfile(filename) or "" + local paragraphs = lpeg.match(patterns.paragraphs,text) or { } + local sentences = lpeg.match(patterns.sentences, text) or { } + local words = lpeg.match(patterns.words, text) or { } + for i=1,#words do + words[i] = lowercase(words[i]) + end + filedata = { + -- [variables.paragraphs] = paragraphs, + [variables.paragraph] = paragraphs, + [variables.lines] = sentences, + [variables.line] = sentences, + [variables.words] = words, + [variables.word] = words, + } + -- inspect(filedata) + data[filename] = filedata + end + local d = filedata[settings.alternative or v_paragraph] or filedata[v_paragraph] or { } + local nd = #d + local n = settings.n + if n ~= v_random then + n = tonumber(n) or 0 + if n == 0 then + n = nd + end + end + return d, n, nd +end + +function moduledata.ipsum.typeset(settings) + local d, n, nd = getfiledata(settings) + if nd > 0 then + context(settings.before) + if n == v_random then + context(settings.left) + context(d[math.random(1,nd)]) + context(settings.right) + else + for i=1,n do + context(settings.left) + context(d[i]) + context(settings.right) + if i < n then + context(settings.inbetween) + end + end + end + context(settings.after) + end +end + +function moduledata.ipsum.direct(settings) + local d, n, nd = getfiledata(settings) + if nd == 0 then + -- nothing + elseif n == v_random then + context(d[math.random(1,nd)]) + else + for i=1,n do + context(d[i]) + if i < n then + context(settings.separator) + end + end + end +end + +\stopluacode + +\unprotect + +\installnamespace {ipsum} + +\installcommandhandler \????ipsum {ipsum} \????ipsum + +\setupipsum + [\c!file=lorem, + \c!alternative=\v!paragraph, + %\c!language=, + %\c!styl=, + %\c!color=, + \c!n=0, + \c!left=, + \c!right=, + \c!before=, + \c!after=, + \c!separator=, + \c!inbetween=] + +\installactionhandler{ipsum} % grouped + +\startsetups[handler:action:ipsum] + \useipsumstyleandcolor\c!style\c!color + \uselanguageparameter\ipsumparameter + \ctxlua{moduledata.ipsum.typeset { + alternative = "\ipsumparameter\c!alternative", + filename = "\ipsumparameter\c!file", + n = "\ipsumparameter\c!n", + left = "\luaescapestring{\ipsumparameter\c!left}", + right = "\luaescapestring{\ipsumparameter\c!right}", + before = "\luaescapestring{\ipsumparameter\c!before}", + after = "\luaescapestring{\ipsumparameter\c!after}", + inbetween = "\luaescapestring{\ipsumparameter\c!inbetween}", + }} +\stopsetups + +\def\directipsum#1% only one argument, expanded + {\ctxlua{moduledata.ipsum.typeset { + alternative = "\namedipsumparameter{#1}\c!alternative", + filename = "\namedipsumparameter{#1}\c!file", + n = "\namedipsumparameter{#1}\c!n", + separator = "\luaescapestring{\ipsumparameter\c!separator}", + }} +} + +\protect + +\continueifinputfile{m-ipsum.mkiv} + +\setupbodyfont[dejavu,11pt] + +\starttext + + \ipsum[alternative=paragraph,before=\blank,after=\blank,language=la] + + \ipsum[alternative=lines,n=2,right=\par,before=\blank,after=\blank,language=la] + + \ipsum[alternative=lines,n=random,before=\blank,after=\blank,language=la] + + \ipsum[alternative=lines,before=\startitemize,after=\stopitemize,left=\startitem,right=\stopitem,language=la] + + \ipsum[alternative=words,left=(,right=),inbetween=\space,language=la] + + \page + + \defineipsum + [ward] + [file=ward, + before=\blank, + after=\blank] + + \defineipsum + [ward:itemize] + [ward] + [alternative=lines, + before={\startitemize[packed]}, + after=\stopitemize, + left=\startitem, + right=\stopitem] + + \defineipsum + [ward:title] + [ward] + [alternative=lines, + n=random] + + \subject{\directipsum{ward:title}} + + \ipsum[ward] + \ipsum[ward:itemize] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-json.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-json.mkiv new file mode 100644 index 00000000000..095b49558b4 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-json.mkiv @@ -0,0 +1,32 @@ +%D \module +%D [ file=m-json, +%D version=2012.08.03, +%D title=\CONTEXT\ Modules, +%D subtitle=Json, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module is a side effect of looking into json. Currently there are +%D only a few helpers: +%D +%D \starttyping +%D moduledata.json.tolua (str) +%D moduledata.json.tostring(val) +%D \stoptyping +%D +%D Nothing spectacular but maybe handy to have around. + +\startmodule [json] + +% check for: utilities.json + +\registerctxluafile{util-jsn}{} + +% \def\u#1#2#3#4{\cldcontext{utf.char(0x#1#2#3#4)}} + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-layout.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-layout.mkiv new file mode 100644 index 00000000000..5ccf0e98731 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-layout.mkiv @@ -0,0 +1,102 @@ +%D \module +%D [ file=m-layout, +%D version=2004.01.16, +%D title=\CONTEXT\ Modules, +%D subtitle=Additional Layouts, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% layout-preset - thf th tf + +%D This is a preliminary module, don't depend on these dimensions yet. + +\readsysfile{lang-frq}\donothing\donothing +\readsysfile{lang-frd}\donothing\donothing + +\unprotect + +% \def\layouthwratio{\withoutpt\the\dimexpr8\paperheight/\dimexpr(\paperwidth/ 8192)\relax} +% \def\layouthwratio{\withoutpt\the\dimexpr4\paperheight/\dimexpr(\paperwidth/16384)\relax} +% \def\layouthwratio{\withoutpt\the\dimexpr2\paperheight/\dimexpr(\paperwidth/32768)\relax} + +\def\layouthwratio + {\withoutpt\the\dimexpr2\paperheight/(\paperwidth/32768)\relax} + +\def\layouthfheight + {\dimexpr\layoutparameter\c!header+\layoutparameter\c!headerdistance+ + \layoutparameter\c!footer+\layoutparameter\c!footerdistance\relax} + +\startsetups[preset-1] + + \xdef\layoutwidth {\dimexpr\layoutparameter\c!width\relax} + \gdef\layoutheight{\dimexpr\layouthwratio\dimexpr\layoutwidth\relax+\layouthfheight\relax} + +\stopsetups + +\definelayout + [preset-1-1] + [\c!preset=preset-1, + \c!backspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax, + \c!width=\dimexpr2\paperwidth/3\relax, + \c!cutspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax, + \c!margin=\dimexpr(\paperwidth-\layoutwidth)/3\relax, + \c!header=2\lineheight, + \c!headerdistance=\lineheight, + \c!height=\v!middle, % \layoutheight + \c!footerdistance=\layoutparameter\c!headerdistance, % \lineheight, + \c!footer=\layoutparameter\c!header, % 2\lineheight, + \c!topspace=\dimexpr1\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax, + \c!bottomspace=\dimexpr2\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax] + +\startsetups[preset-2] + + \gdef\layouthstep{\dimexpr\paperwidth /\layoutparameter\c!columns\relax} + \gdef\layoutvstep{\dimexpr\paperheight/\layoutparameter\c!columns\relax} + +\stopsetups + +\definelayout + [preset-2-1] + [\c!preset=preset-2, + \c!columns=12, + \c!backspace=\layouthstep, + \c!width=\v!middle, + \c!cutspace=2\layouthstep, + \c!margin=\layouthstep, + \c!header=2\lineheight, + \c!headerdistance=\lineheight, + \c!height=\v!middle, % \layoutheight + \c!footerdistance=\layoutparameter\c!headerdistance, + \c!footer=\layoutparameter\c!header, + \c!topspace=\dimexpr\layoutvstep-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax, + \c!bottomspace=\dimexpr(2\layoutvstep)-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax] + +\definelayout + [preset-2-2] + [\c!preset=preset-2, + \c!columns=12, + \c!backspace=\layouthstep, + \c!width=\v!middle, + \c!cutspace=2\layouthstep, + \c!margin=\layouthstep, + \c!header=2\lineheight, + \c!headerdistance=\lineheight, + \c!height=\v!middle, % \layoutheight + \c!footerdistance=\layoutparameter\c!headerdistance, + \c!footer=\layoutparameter\c!header, + \c!topspace=\layoutvstep, + \c!bottomspace=\layoutvstep] % maybe 1.5 + +% \setuplayout[preset-1-1] test \showframe \page +% \setuplayout[preset-1-1][width=65\averagecharwidth] \setuplayout[preset-1-1] test \showframe \page +% \setuplayout[preset-2-1] test \showframe \page +% \setuplayout[preset-2-1][columns=10] \setuplayout[preset-2-1] test \showframe \page +% \setuplayout[preset-2-2] test \showframe \page +% \setuplayout[preset-2-2][columns=10] \setuplayout[preset-2-2] test \showframe \page + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-logcategories.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-logcategories.mkiv new file mode 100644 index 00000000000..954cd58c483 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-logcategories.mkiv @@ -0,0 +1,3 @@ +\starttext + \showlogcategories +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-markdown.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-markdown.lua new file mode 100644 index 00000000000..1f9402f60e3 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-markdown.lua @@ -0,0 +1,824 @@ +if not modules then modules = { } end modules ['m-markdown'] = { + version = 1.002, + comment = "companion to m-markdown.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "see below", + license = "see context related readme files" +} + +--[[ +Copyright (C) 2009 John MacFarlane / Khaled Hosny / Hans Hagen + +The main parser is derived from the lunamark parser written by John MacFarlane. You +can download lunamark from: + + http://github.com/jgm/lunamark.git + +Khaled Hosny provided the context writer for lunamark and that was used as starting +point for the mapping. The original code can be fetched from the above location. + +While playing with the original code I got the feeling that lpeg could perform better. +The slowdown was due to the fact that the parser's lpeg was reconstructed each time a +nested parse was needed. After changing that code a bit I could bring down parsing of +some test code from 2 seconds to less than 0.1 second so I decided to stick to this +parser instead of writing my own. After all, the peg code looks pretty impressive and +visiting Johns pandoc pages is worth the effort: + + http://johnmacfarlane.net/pandoc/ + +The code here is mostly meant for processing snippets embedded in a context +documents and is no replacement for pandoc at all. Therefore an alternative is to use +pandoc in combination with Aditya's filter module. + +As I changed (and optimized) the original code, it will be clear that all errors +are mine. Eventually I might also adapt the parser code a bit more. When I ran into of +closure stack limitations I decided to flatten the code. The following implementation +seems to be a couple of hundred times faster than what I started with which is not that +bad. + +This is a second rewrite. The mentioned speed gain largely depended on the kind of +content: blocks, references and items can be rather demanding. Also, There were +some limitations with respect to the captures. So, table storage has been removed in +favor of strings, and nesting has been simplified. The first example at the end of this +file now takes .33 seconds for 567KB code (resulting in over 1MB) so we're getting there. + +There will be a third rewrite eventually. +]]-- + +-- todo: we have better quote and tag scanners in ctx +-- todo: provide an xhtml mapping +-- todo: add a couple of extensions +-- todo: check patches to the real peg + +local type, next, tonumber = type, next, tonumber +local lower, upper, gsub, rep, gmatch, format, length = string.lower, string.upper, string.gsub, string.rep, string.gmatch, string.format, string.len +local concat = table.concat +local P, R, S, V, C, Ct, Cg, Cb, Cmt, Cc, Cf, Cs = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cg, lpeg.Cb, lpeg.Cmt, lpeg.Cc, lpeg.Cf, lpeg.Cs +local lpegmatch = lpeg.match +local utfbyte, utfchar = utf.byte, utf.char + +moduledata = moduledata or { } +moduledata.markdown = moduledata.markdown or { } +local markdown = moduledata.markdown + +local nofruns, nofbytes, nofhtmlblobs = 0, 0, 0 + +--------------------------------------------------------------------------------------------- + +local nestedparser +local syntax + +nestedparser = function(str) return lpegmatch(syntax,str) end + +--------------------------------------------------------------------------------------------- + +local asterisk = P("*") +local dash = P("-") +local plus = P("+") +local underscore = P("_") +local period = P(".") +local hash = P("#") +local ampersand = P("&") +local backtick = P("`") +local less = P("<") +local more = P(">") +local space = P(" ") +local squote = P("'") +local dquote = P('"') +local lparent = P("(") +local rparent = P(")") +local lbracket = P("[") +local rbracket = P("]") +local slash = P("/") +local equal = P("=") +local colon = P(":") +local semicolon = P(";") +local exclamation = P("!") + +local digit = R("09") +local hexdigit = R("09","af","AF") +local alphanumeric = R("AZ","az","09") + +local doubleasterisks = P("**") +local doubleunderscores = P("__") +local fourspaces = P(" ") + +local any = P(1) +local always = P("") + +local tab = P("\t") +local spacechar = S("\t ") +local spacing = S(" \n\r\t") +local newline = P("\r")^-1 * P("\n") +local spaceornewline = spacechar + newline +local nonspacechar = any - spaceornewline +local optionalspace = spacechar^0 +local spaces = spacechar^1 +local eof = - any +local nonindentspace = space^-3 +local blankline = optionalspace * C(newline) +local blanklines = blankline^0 +local skipblanklines = (optionalspace * newline)^0 +local linechar = P(1 - newline) +local indent = fourspaces + (nonindentspace * tab) / "" +local indentedline = indent /"" * C(linechar^1 * (newline + eof)) +local optionallyindentedline = indent^-1 /"" * C(linechar^1 * (newline + eof)) +local spnl = optionalspace * (newline * optionalspace)^-1 +local specialchar = S("*_`*&[]<!\\") +local normalchar = any - (specialchar + spaceornewline) +local line = C((any - newline)^0 * newline) + + C(any^1 * eof) +local nonemptyline = (any - newline)^1 * newline + +--------------------------------------------------------------------------------------------- + +local function lineof(c) + return (nonindentspace * (P(c) * optionalspace)^3 * newline * blankline^1) +end + +local lineof_asterisks = lineof(asterisk) +local lineof_dashes = lineof(dash) +local lineof_underscores = lineof(underscore) + +local bullet = nonindentspace * (plus + (asterisk - lineof_asterisks) + (dash - lineof_dashes)) * spaces +local enumerator = nonindentspace * digit^1 * period * spaces + +--------------------------------------------------------------------------------------------- + +local openticks = Cg(backtick^1, "ticks") +local closeticks = space^-1 * Cmt(C(backtick^1) * Cb("ticks"), function(s,i,a,b) return #a == #b and i end) +local intickschar = (any - S(" \n\r`")) + + (newline * -blankline) + + (space - closeticks) + + (backtick^1 - closeticks) +local inticks = openticks * space^-1 * C(intickschar^1) * closeticks + +--------------------------------------------------------------------------------------------- + +local leader = space^-3 +local nestedbrackets = P { lbracket * ((1 - lbracket - rbracket) + V(1))^0 * rbracket } +local tag = lbracket * C((nestedbrackets + 1 - rbracket)^0) * rbracket +local url = less * C((1-more)^0) * more + + C((1-spacing- rparent)^1) -- sneaky: ) for resolver +local title_s = squote * lpeg.C((1-squote )^0) * squote +local title_d = dquote * lpeg.C((1-dquote )^0) * dquote +local title_p = lparent * lpeg.C((1-rparent)^0) * rparent +local title = title_s + title_d + title_p +local optionaltitle = ((spacing^0 * title * spacechar^0) + lpeg.Cc("")) + +local references = { } + +local function register_link(tag,url,title) + tag = lower(gsub(tag, "[ \n\r\t]+", " ")) + references[tag] = { url, title } +end + +local function direct_link(label,url,title) -- title is typical html thing + return label, url, title +end + +local function indirect_link(label,tag) + if tag == "" then + tag = label + end + tag = lower(gsub(tag, "[ \n\r\t]+", " ")) + local r = references[tag] + if r then + return label, r[1], r[2] + else + return label, tag, "" + end +end + +local define_reference_parser = (leader * tag * colon * spacechar^0 * url * optionaltitle) / register_link +local direct_link_parser = tag * spacechar^0 * lparent * (url + Cc("")) * optionaltitle * rparent / direct_link +local indirect_link_parser = tag * spacechar^0 * tag / indirect_link + +local rparser = (define_reference_parser+1)^0 + +local function referenceparser(str) + references = { } + lpegmatch(rparser,str) +end + +-- local reftest = [[ +-- [1]: <http://example.com/> +-- [3]:http://example.com/ (Optional Title Here) +-- [2]: http://example.com/ 'Optional Title Here' +-- [a]: http://example.com/ "Optional *oeps* Title Here" +-- ]] +-- +-- local linktest = [[ +-- [This link] (http://example.net/) +-- [an example] (http://example.com/ "Title") +-- [an example][1] +-- [an example] [2] +-- ]] +-- +-- lpeg.match((define_reference_parser+1)^0,reftest) +-- +-- inspect(references) +-- +-- lpeg.match((direct_link_parser/print + indirect_link_parser/print + 1)^0,linktest) + +--------------------------------------------------------------------------------------------- + +local blocktags = table.tohash { + "address", "blockquote" , "center", "dir", "div", "p", "pre", + "li", "ol", "ul", "dl", "dd", + "form", "fieldset", "isindex", "menu", "noframes", "frameset", + "h1", "h2", "h3", "h4", "h5", "h6", + "hr", "ht", "script", "noscript", + "table", "tbody", "tfoot", "thead", "th", "td", "tr", +} + +----- htmlattributevalue = squote * C((any - (blankline + squote))^0) * squote +----- + dquote * C((any - (blankline + dquote))^0) * dquote +----- + (any - S("\t >"))^1 -- any - tab - space - more +----- htmlattribute = (alphanumeric + S("_-"))^1 * spnl * (equal * spnl * htmlattributevalue)^-1 * spnl +----- htmlcomment = P("<!--") * (any - P("-->"))^0 * P("-->") + +----- htmltag = less * spnl * slash^-1 * alphanumeric^1 * spnl * htmlattribute^0 * slash^-1 * spnl * more +----- +----- blocktag = Cmt(C(alphanumeric^1), function(s,i,a) return blocktags[lower(a)] and i, a end) +----- +----- openblocktag = less * Cg(blocktag, "opentag") * spnl * htmlattribute^0 * more +----- closeblocktag = less * slash * Cmt(C(alphanumeric^1) * Cb("opentag"), function(s,i,a,b) return lower(a) == lower(b) and i end) * spnl * more +----- selfclosingblocktag = less * blocktag * spnl * htmlattribute^0 * slash * more +----- +----- displayhtml = Cs { "HtmlBlock", +----- InBlockTags = openblocktag * (V("HtmlBlock") + (any - closeblocktag))^0 * closeblocktag, +----- HtmlBlock = C(V("InBlockTags") + selfclosingblocktag + htmlcomment), +----- } +----- +----- inlinehtml = Cs(htmlcomment + htmltag) + +-- There is no reason to support crappy html, so we expect proper attributes. + +local htmlattributevalue = squote * C((any - (blankline + squote))^0) * squote + + dquote * C((any - (blankline + dquote))^0) * dquote +local htmlattribute = (alphanumeric + S("_-"))^1 * spnl * equal * spnl * htmlattributevalue * spnl + +local htmlcomment = P("<!--") * (any - P("-->"))^0 * P("-->") +local htmlinstruction = P("<?") * (any - P("?>" ))^0 * P("?>" ) + +-- We don't care too much about matching elements and there is no reason why display elements could not +-- have inline elements so the above should be patched then. Well, markdown mixed with html is not meant +-- for anything else than webpages anyway. + +local blocktag = Cmt(C(alphanumeric^1), function(s,i,a) return blocktags[lower(a)] and i, a end) + +local openelement = less * alphanumeric^1 * spnl * htmlattribute^0 * more +local closeelement = less * slash * alphanumeric^1 * spnl * more +local emptyelement = less * alphanumeric^1 * spnl * htmlattribute^0 * slash * more + +local displaytext = (any - less)^1 +local inlinetext = displaytext / nestedparser + +local displayhtml = #(less * blocktag * spnl * htmlattribute^0 * more) + * Cs { "HtmlBlock", + InBlockTags = openelement * (V("HtmlBlock") + displaytext)^0 * closeelement, + HtmlBlock = (V("InBlockTags") + emptyelement + htmlcomment + htmlinstruction), + } + +local inlinehtml = Cs { "HtmlBlock", + InBlockTags = openelement * (V("HtmlBlock") + inlinetext)^0 * closeelement, + HtmlBlock = (V("InBlockTags") + emptyelement + htmlcomment + htmlinstruction), + } + +--------------------------------------------------------------------------------------------- + +local hexentity = ampersand * hash * S("Xx") * C(hexdigit ^1) * semicolon +local decentity = ampersand * hash * C(digit ^1) * semicolon +local tagentity = ampersand * C(alphanumeric^1) * semicolon + +--------------------------------------------------------------------------------------------- + +-- --[[ + +local escaped = { + ["{" ] = "", + ["}" ] = "", + ["$" ] = "", + ["&" ] = "", + ["#" ] = "", + ["~" ] = "", + ["|" ] = "", + ["%%"] = "", + ["\\"] = "", +} + +for k, v in next, escaped do + escaped[k] = "\\char" .. utfbyte(k) .. "{}" +end + +local function c_string(s) -- has to be done more often + return (gsub(s,".",escaped)) +end + +local c_linebreak = "\\crlf\n" -- is this ok? +local c_space = " " + +local function c_paragraph(c) + return c .. "\n\n" -- { "\\startparagraph ", c, " \\stopparagraph\n" } +end + +local function listitem(c) + return format("\n\\startitem\n%s\n\\stopitem\n",nestedparser(c)) +end + +local function c_tightbulletlist(c) + return format("\n\\startmarkdownitemize[packed]\n%s\\stopmarkdownitemize\n",c) +end + +local function c_loosebulletlist(c) + return format("\n\\startmarkdownitemize\n\\stopmarkdownitemize\n",c) +end + +local function c_tightorderedlist(c) + return format("\n\\startmarkdownitemize[n,packed]\n%s\\stopmarkdownitemize\n",c) +end + +local function c_looseorderedlist(c) + return format("\n\\startmarkdownitemize[n]\n%s\\stopmarkdownitemize\n",c) +end + +local function c_inline_html(content) + nofhtmlblobs = nofhtmlblobs + 1 + return format("\\markdowninlinehtml{%s}",content) +end + +local function c_display_html(content) + nofhtmlblobs = nofhtmlblobs + 1 + return format("\\startmarkdowndisplayhtml\n%s\n\\stopmarkdowndisplayhtml",content) +end + +local function c_emphasis(c) + return format("\\markdownemphasis{%s}",c) +end + +local function c_strong(c) + return format("\\markdownstrong{%s}",c) +end + +local function c_blockquote(c) + return format("\\startmarkdownblockquote\n%s\\stopmarkdownblockquote\n",nestedparser(c)) +end + +local function c_verbatim(c) + return format("\\startmarkdowntyping\n%s\\stopmarkdowntyping\n",c) +end + +local function c_code(c) + return format("\\markdowntype{%s}",c) +end + +local levels = { "", "", "", "", "", "" } + +local function c_start_document() + levels = { "", "", "", "", "", "" } + return "" +end + +local function c_stop_document() + return concat(levels,"\n") or "" +end + +local function c_heading(level,c) + if level > #levels then + level = #levels + end + local finish = concat(levels,"\n",level) or "" + for i=level+1,#levels do + levels[i] = "" + end + levels[level] = "\\stopstructurelevel" + return format("%s\\startstructurelevel[markdown][title={%s}]\n",finish,c) +end + +local function c_hrule() + return "\\markdownrule\n" +end + +local function c_link(lab,src,tit) + return format("\\goto{%s}[url(%s)]",nestedparser(lab),src) +end + +local function c_image(lab,src,tit) + return format("\\externalfigure[%s]",src) +end + +local function c_email_link(address) + return format("\\goto{%s}[url(mailto:%s)]",c_string(address),address) +end + +local function c_url_link(url) + return format("\\goto{%s}[url(%s)]",c_string(url),url) +end + +local function f_heading(c,n) + return c_heading(n,c) +end + +local function c_hex_entity(s) + return utfchar(tonumber(s,16)) +end + +local function c_dec_entity(s) + return utfchar(tonumber(s)) +end + +local function c_tag_entity(s) + return s -- we can use the default resolver +end + +--]] + +--------------------------------------------------------------------------------------------- + +--[[ + +local escaped = { + ["<"] = "<", + [">"] = ">", + ["&"] = "&", + ['"'] = """, +} + +local function c_string(s) -- has to be done more often + return (gsub(s,".",escaped)) +end + +local c_linebreak = "<br/>" +local c_space = " " + +local function c_paragraph(c) + return format("<p>%s</p>\n", c) +end + +local function listitem(c) + return format("<li>%s</li>",nestedparser(c)) +end + +local function c_tightbulletlist(c) + return format("<ul>\n%s\n</ul>\n",c) +end + +local function c_loosebulletlist(c) + return format("<ul>\n%s\n</ul>\n",c) +end + +local function c_tightorderedlist(c) + return format("<ol>\n%s\n</ol>\n",c) +end + +local function c_looseorderedlist(c) + return format("<ol>\n%s\n</ol>\n",c) +end + +local function c_inline_html(content) + nofhtmlblobs = nofhtmlblobs + 1 + return content +end + +local function c_display_html(content) + nofhtmlblobs = nofhtmlblobs + 1 + return format("\n%s\n",content) +end + +local function c_emphasis(c) + return format("<em>%s</em>",c) +end + +local function c_strong(c) + return format("<strong>%s</strong>",c) +end + +local function c_blockquote(c) + return format("<blockquote>\n%s\n</blockquote>",nestedparser(c)) +end + +local function c_verbatim(c) + return format("<pre><code>%s</code></pre>",c) +end + +local function c_code(c) + return format("<code>%s</code>",c) +end + +local c_start_document = "" +local c_stop_document = "" + +local function c_heading(level,c) + return format("<h%d>%s</h%d>\n",level,c,level) +end + +local function c_hrule() + return "<hr/>\n" +end + +local function c_link(lab,src,tit) + local titattr = #tit > 0 and format(" title=%q",tit) or "" + return format("<a href=%q%s>%s</a>",src,titattr,nestedparser(lab)) +end + +local function c_image(lab,src,tit) + return format("<img href=%q title=%q>%s</a>",src,tit,nestedparser(lab)) +end + +local function c_email_link(address) + return format("<a href=%q>%s</a>","mailto:",address,c_escape(address)) +end + +local function c_url_link(url) + return format("<a href=%q>%s</a>",url,c_string(url)) +end + +local function f_heading(c,n) + return c_heading(n,c) +end + +local function c_hex_entity(s) + return utfchar(tonumber(s,16)) +end + +local function c_dec_entity(s) + return utfchar(tonumber(s)) +end + +local function c_tag_entity(s) + return format("&%s;",s) +end + +--]] + +--------------------------------------------------------------------------------------------- + +local Str = normalchar^1 / c_string +local Space = spacechar^1 / c_space +local Symbol = specialchar / c_string +local Code = inticks / c_code + +local HeadingStart = C(hash * hash^-5) / length +local HeadingStop = optionalspace * hash^0 * optionalspace * newline * blanklines +local HeadingLevel = equal^3 * Cc(1) + + dash ^3 * Cc(2) + +local NormalEndline = optionalspace * newline * -( + blankline + + more + + HeadingStart + + ( line * (P("===")^3 + P("---")^3) * newline ) + ) / c_space + +local LineBreak = P(" ") * NormalEndline / c_linebreak + +local TerminalEndline = optionalspace * newline * eof / "" + +local Endline = LineBreak + + TerminalEndline + + NormalEndline + +local AutoLinkUrl = less * C(alphanumeric^1 * P("://") * (any - (newline + more))^1) * more / c_url_link +local AutoLinkEmail = less * C((alphanumeric + S("-_+"))^1 * P("@") * (any - (newline + more))^1) * more / c_email_link + +local DirectLink = direct_link_parser / c_link +local IndirectLink = indirect_link_parser / c_link + +local ImageLink = exclamation * (direct_link_parser + indirect_link_parser) / c_image -- we can combine this with image ... smaller lpeg + +local UlOrStarLine = asterisk^4 + + underscore^4 + + (spaces * S("*_")^1 * #spaces) / c_string + +local EscapedChar = P("\\") * C(P(1 - newline)) / c_string + +local InlineHtml = inlinehtml / c_inline_html +local DisplayHtml = displayhtml / c_display_html +local HtmlEntity = hexentity / c_hex_entity + + decentity / c_dec_entity + + tagentity / c_tag_entity + +local NestedList = Cs(optionallyindentedline - (bullet + enumerator))^1 / nestedparser + +local ListBlockLine = -blankline * -(indent^-1 * (bullet + enumerator)) * optionallyindentedline + +local Verbatim = Cs(blanklines * (indentedline - blankline)^1) / c_verbatim + * (blankline^1 + eof) -- not really needed, probably capture trailing? we can do that beforehand + +local Blockquote = Cs(( + ((nonindentspace * more * space^-1)/"" * linechar^0 * newline)^1 + * ((linechar - blankline)^1 * newline)^0 + * blankline^0 + )^1) / c_blockquote + +local HorizontalRule = (lineof_asterisks + lineof_dashes + lineof_underscores) / c_hrule + +local Reference = define_reference_parser / "" + +-- could be a mini grammar + +local ListBlock = line * ListBlockLine^0 +local ListContinuationBlock = blanklines * indent * ListBlock +local ListItem = Cs(ListBlock * (NestedList + ListContinuationBlock^0)) / listitem + +---- LeadingLines = blankline^0 / "" +---- TrailingLines = blankline^1 * #(any) / "\n" + +syntax = Cs { "Document", + + Document = V("Display")^0, + + Display = blankline -- ^1/"\n" + + Blockquote + + Verbatim + + Reference + + HorizontalRule + + HeadingStart * optionalspace * Cs((V("Inline") - HeadingStop)^1) * HeadingStop / c_heading + + Cs((V("Inline") - Endline)^1) * newline * HeadingLevel * newline * blanklines / f_heading + + Cs((bullet /"" * ListItem)^1) * blanklines * -bullet / c_tightbulletlist + + Cs((bullet /"" * ListItem * C(blanklines))^1) / c_loosebulletlist + + Cs((enumerator /"" * ListItem)^1) * blanklines * -enumerator / c_tightorderedlist + + Cs((enumerator /"" * ListItem * C(blanklines))^1) / c_looseorderedlist + + DisplayHtml + + nonindentspace * Cs(V("Inline")^1)* newline * blankline^1 / c_paragraph + + V("Inline")^1, + + Inline = Str + + Space + + Endline + + UlOrStarLine -- still needed ? + + doubleasterisks * -spaceornewline * Cs((V("Inline") - doubleasterisks )^1) * doubleasterisks / c_strong + + doubleunderscores * -spaceornewline * Cs((V("Inline") - doubleunderscores)^1) * doubleunderscores / c_strong + + asterisk * -spaceornewline * Cs((V("Inline") - asterisk )^1) * asterisk / c_emphasis + + underscore * -spaceornewline * Cs((V("Inline") - underscore )^1) * underscore / c_emphasis + + ImageLink + + DirectLink + + IndirectLink + + AutoLinkUrl + + AutoLinkEmail + + Code + + InlineHtml + + HtmlEntity + + EscapedChar + + Symbol, + +} + +--------------------------------------------------------------------------------------------- + +local function convert(str) + nofruns = nofruns + 1 + nofbytes = nofbytes + #str + statistics.starttiming(markdown) + referenceparser(str) + local result = c_start_document() .. nestedparser(str) .. c_stop_document() + statistics.stoptiming(markdown) + return result +end + +markdown.convert = convert + +function markdown.typesetstring(data) + if data and data ~= "" then + local result = convert(data) + context.viafile(result) + end +end + +function markdown.typesetbuffer(name) + markdown.typesetstring(buffers.getcontent(name)) +end + +function markdown.typesetfile(name) + local fullname = resolvers.findctxfile(name) + if fullname and fullname ~= "" then + markdown.typesetstring(io.loaddata(fullname)) + end +end + +statistics.register("markdown",function() + if nofruns > 0 then + return format("%s bytes converted, %s runs, %s html blobs, %s seconds used", + nofbytes, nofruns, nofhtmlblobs, statistics.elapsedtime(markdown)) + end +end) + +--------------------------------------------------------------------------------------------- + +--~ context.starttext() +--~ moduledata.markdown.convert(str) +--~ context.stoptext() + +if not tex.jobname then + + local one = [[ +Test *123* +========== + +<b>BOLD *BOLD* BOLD</b> + +<pre>PRE <b>PRE</b> PRE</pre> + + +* Test +** Test +* Test1 + * Test2 +* Test + +Test +==== + +> test +> test **123** *123* +> test `code` + +test + +Test +==== + +> test +> test +> test + +test +oeps + +more + + code + code + +oeps + +[an example][a] + +[an example] [2] + +[a]: http://example.com/ "Optional *oeps* Title Here" +[2]: http://example.com/ 'Optional Title Here' +[3]: http://example.com/ (Optional Title Here) + +[an example][a] + +[an example] [2] + +[an [tricky] example](http://example.com/ "Title") + +[This **xx** link](http://example.net/) + ]] + +-- This snippet takes some 4 seconds in the original parser (the one that is +-- a bit clearer from the perspective of grammars but somewhat messy with +-- respect to the captures. In the above parser it takes .1 second. Also, +-- in the later case only memory is the limit. + + local two = [[ +Test +==== +* Test +** Test +* Test +** Test +* Test + +Test +==== + +> test +> test +> test + +test + +Test +==== + +> test +> test +> test + +test + ]] + + local function test(str) + local n = 1 -- 000 + local t = os.clock() + local one = convert(str) + -- print("runtime",1,#str,#one,os.clock()-t) + str = string.rep(str,n) + local t = os.clock() + local two = convert(str) + print(two) + -- print("runtime",n,#str,#two,os.clock()-t) + -- print(format("==============\n%s\n==============",one)) + end + + -- test(one) + -- test(two) + -- test(io.read("*all")) + + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-markdown.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-markdown.mkiv new file mode 100644 index 00000000000..6e003651309 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-markdown.mkiv @@ -0,0 +1,88 @@ +%D \module +%D [ file=x-markdown, +%D version=2011.07.19, +%D title=\CONTEXT\ Modules, +%D subtitle=Processing MarkDown, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Modules / MarkDown Renderer} + +%D This module deals with markdown which is a document encoding that +%D some \CONTEXT\ like much. It reminds me of the kind of minimal coding +%D we used before we ran into \TEX\ and were using a somewhat simple +%D rendering (pagination, etc) of documents. As I'm no user myself, it +%D is up to others to provide documentation and examples. + +\registerctxluafile{m-markdown}{1.001} + +\unprotect + +% basic interface + +\definebuffer[markdown] + +\unexpanded\def\stopmarkdown + {\ctxlua{moduledata.markdown.typesetbuffer("\thedefinedbuffer{markdown}")}} + +\unexpanded\def\processmarkdownfile#1% maybe [] or both + {\ctxlua{moduledata.markdown.typesetfile("#1")}} + +\unexpanded\def\markdown#1% maybe [] or both + {\ctxlua{moduledata.markdown.typesetstring(\!!bs#1\!!es)}} + +% commands + +\defineitemgroup + [markdownitemize] + +\definetyping + [markdowntyping] + +\definetype + [markdowntype] + +\definetype + [markdowninlinehtml] + +\definetyping + [markdowndisplayhtml] + +\definedelimitedtext + [markdownblockquote] + [quotation] + +\definehighlight + [markdownemphasis] + [style=\em] + +\definehighlight + [markdownstrong] + [style=\bf] + +\definestructurelevels + [markdown] + [\v!chapter, + \v!section, + \v!subsection, + \v!subsubsection, + \v!subsubsubsection, + \v!subsubsubsubsection] + +\unexpanded\def\markdownrule + {\hairline\par} + +\protect + +\continueifinputfile{m-markdown.mkiv} + +\starttext + \startmarkdown + % some examples needed + \stopmarkdown +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-mathcrap.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-mathcrap.mkiv new file mode 100644 index 00000000000..25efd2d5de3 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-mathcrap.mkiv @@ -0,0 +1,76 @@ +%D \module +%D [ file=m-mathcrap, +%D version=2010.05.30, +%D title=\CONTEXT\ Modules, +%D subtitle=Math Crap, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is meant for those who want to use the (incomplete and sort of useless) +%D unicode superscripts and subscripts. We should look ahead and collapse them +%D but I will only implement that in calcmath when the need is there. Now the +%D spacing can be somewhat non optimal but probably that does not matter here. +%D +%D \startbuffer +%D $aâ‚€â‚₂₃₄₅₆₇₈₉₋₌₊$ +%D \stopbuffer +%D +%D \typebuffer \blank \getbuffer \blank + +\unprotect + +\unexpanded\def\mathunicodesupercrap#1{\mathortext{{\normalsuperscript{#1}}}{\high{#1}}} +\unexpanded\def\mathunicodesubcrap #1{\mathortext{{\normalsubscript {#1}}}{\low {#1}}} + +\ifdefined\installanddefineactivecharacter\else + + \def\installanddefineactivecharacter #1 #2% we need this as command + {\normalexpanded{\noexpand\installactivecharacter \utfchar{#1} }% + \defineactivecharacter #1 {#2}} + +\fi + +\installanddefineactivecharacter "2070 {\mathunicodesupercrap 0} +\installanddefineactivecharacter "00B9 {\mathunicodesupercrap 1} +\installanddefineactivecharacter "00B2 {\mathunicodesupercrap 2} +\installanddefineactivecharacter "00B3 {\mathunicodesupercrap 3} +\installanddefineactivecharacter "2074 {\mathunicodesupercrap 4} +\installanddefineactivecharacter "2075 {\mathunicodesupercrap 5} +\installanddefineactivecharacter "2076 {\mathunicodesupercrap 6} +\installanddefineactivecharacter "2077 {\mathunicodesupercrap 7} +\installanddefineactivecharacter "2078 {\mathunicodesupercrap 8} +\installanddefineactivecharacter "2079 {\mathunicodesupercrap 9} +\installanddefineactivecharacter "207A {\mathunicodesupercrap +} +\installanddefineactivecharacter "207B {\mathunicodesupercrap -} +\installanddefineactivecharacter "207C {\mathunicodesupercrap =} +\installanddefineactivecharacter "207D {\mathunicodesupercrap (} +\installanddefineactivecharacter "207E {\mathunicodesupercrap )} +\installanddefineactivecharacter "207F {\mathunicodesupercrap n} + +\installanddefineactivecharacter "2080 {\mathunicodesubcrap 0} +\installanddefineactivecharacter "2081 {\mathunicodesubcrap 1} +\installanddefineactivecharacter "2082 {\mathunicodesubcrap 2} +\installanddefineactivecharacter "2083 {\mathunicodesubcrap 3} +\installanddefineactivecharacter "2084 {\mathunicodesubcrap 4} +\installanddefineactivecharacter "2085 {\mathunicodesubcrap 5} +\installanddefineactivecharacter "2086 {\mathunicodesubcrap 6} +\installanddefineactivecharacter "2087 {\mathunicodesubcrap 7} +\installanddefineactivecharacter "2088 {\mathunicodesubcrap 8} +\installanddefineactivecharacter "2089 {\mathunicodesubcrap 9} +\installanddefineactivecharacter "208A {\mathunicodesubcrap +} +\installanddefineactivecharacter "208B {\mathunicodesubcrap -} +\installanddefineactivecharacter "208C {\mathunicodesubcrap =} +\installanddefineactivecharacter "208D {\mathunicodesubcrap (} +\installanddefineactivecharacter "208E {\mathunicodesubcrap )} +\installanddefineactivecharacter "2090 {\mathunicodesubcrap A} +\installanddefineactivecharacter "2091 {\mathunicodesubcrap E} +\installanddefineactivecharacter "2092 {\mathunicodesubcrap O} +\installanddefineactivecharacter "2093 {\mathunicodesubcrap X} +%installanddefineactivecharacter "2094 {\mathunicodesubcrap ?} % SCHWAA + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv new file mode 100644 index 00000000000..ccb376e39c7 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv @@ -0,0 +1,495 @@ +%D \module +%D [ file=m-matrix, +%D version=2014.11.04, % already a year older +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Matrices, +%D author={Jeong Dalyoung \& Hans Hagen}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This code is based on a post by Dalyoung on the context list. After that +%D we turned it into a module and improved the code a bit. Feel free to ask +%D us for more. Once we're satisfied, a more general helper l-matrix could +%D be made. Dalyoung does the clever bits, and Hans only cleanes up and +%D optimizes a bit. + +% \registerctxluafile{l-matrix}{1.001} % not yet + +\startmodule[matrix] + +\startluacode + +local settings_to_hash = utilities.parsers.settings_to_hash +local formatters = string.formatters +local copy = table.copy +local insert = table.insert +local remove = table.remove + +local matrix = { } +moduledata.matrix = matrix + +local f_matrix_slot = formatters["%s_{%s%s}"] + +function matrix.symbolic(sym, x, y, nx ,ny) -- symMatrix("a", "m", "n") + local nx = nx or 2 + local ny = ny or nx + local function filled(i,y) + local mrow = { } + for j=1,nx do + mrow[#mrow+1] = f_matrix_slot(sym,i,j) + end + mrow[#mrow+1] = "\\cdots" + mrow[#mrow+1] = f_matrix_slot(sym,i,y) + return mrow + end + local function dummy() + local mrow = { } + for j=1,nx do + mrow[#mrow+1] = "\\vdots" + end + mrow[#mrow+1] = "\\ddots" + mrow[#mrow+1] = "\\vdots" + return mrow + end + -- + local mm = { } + for i=1,ny do + mm[i] = filled(i,y) + end + mm[#mm+1] = dummy() + mm[#mm+1] = filled(x,y) + return mm +end + +-- todo: define a matrix at the tex end so that we have more control + +local fences_p = { + left = "\\left(\\,", + right = "\\,\\right)", +} + +local fences_b = { + left = "\\left[\\,", + right = "\\,\\right]", +} + +function matrix.typeset(m,options) + local options = settings_to_hash(options or "") + context.startmatrix(options.determinant and fences_b or fences_p) + for i=1, #m do + local mi = m[i] + for j=1,#mi do + context.NC(mi[j]) + end + context.NR() + end + context.stopmatrix() +end + +-- interchange two rows (i-th, j-th) + +function matrix.swap(t,i,j) + t[i], t[j] = t[j], t[i] +end + +-- replace i-th row with factor * (i-th row) + +function matrix.multiply(m,i,factor) + local mi = m[i] + for k=1,#mi do + mi[k] = factor * mi[k] + end + return m +end + +-- scalar product "factor * m" + +function matrix.scalar(m, factor) + for i=1,#m do + local mi = m[i] + for j=1,#mi do + mi[j] = factor * mi[j] + end + end + return m +end + +-- replace i-th row with i-th row + factor * (j-th row) + +function matrix.sumrow(m,i,j,factor) + local mi = m[i] + local mj = m[j] + for k=1,#mi do + mi[k] = mi[k] + factor * mj[k] + end +end + +-- transpose of a matrix + +function matrix.transpose(m) + local t = { } + for j=1,#m[1] do + local r = { } + for i=1,#m do + r[i] = m[i][j] + end + t[j] = r + end + return t +end + +-- inner product of two vectors + +function matrix.inner(u,v) + local nu = #u + if nu == 0 then + return 0 + end + local nv = #v + if nv ~= nu then + return 0 + end + local result = 0 + for i=1,nu do + result = result + u[i] * v[i] + end + return result +end + +-- product of two matrices + +function matrix.product(m1,m2) + local product = { } + if #m1[1] == #m2 then + for i=1,#m1 do + local m1i = m1[i] + local mrow = { } + for j=1,#m2[1] do + local temp = 0 + for k=1,#m1[1] do + temp = temp + m1i[k] * m2[k][j] + end + mrow[j] = temp + end + product[i] = mrow + end + end + return product +end + +local function uppertri(m,sign) + local temp = copy(m) + for i=1,#temp-1 do + local pivot = temp[i][i] + if pivot == 0 then + local pRow = i +1 + while temp[pRow][i] == 0 do + pRow = pRow + 1 + if pRow > #temp then -- if there is no nonzero number + return temp + end + end + temp[i], temp[pRow] = temp[pRow], temp[i] + if sign then + sign = -sign + end + end + local mi = temp[i] + for k=i+1, #temp do + local factor = -temp[k][i]/mi[i] + local mk = temp[k] + for l=i,#mk do + mk[l] = mk[l] + factor * mi[l] + end + end + end + if sign then + return temp, sign + else + return temp + end +end + +matrix.uppertri = uppertri + +function matrix.determinant(m) + if #m == #m[1] then + local d = 1 + local t, s = uppertri(m,1) + for i=1,#t do + d = d * t[i][i] + end + return s*d + else + return 0 + end +end + +local function rowechelon(m,r) + local temp = copy(m) + local pRow = 1 + local pCol = 1 + while pRow <= #temp do + local pivot = temp[pRow][pCol] + if pivot == 0 then + local i = pRow + local n = #temp + while temp[i][pCol] == 0 do + i = i + 1 + if i > n then + -- no nonzero number in a column + pCol = pCol + 1 + if pCol > #temp[pRow] then + -- there is no nonzero number in a row + return temp + end + i = pRow + end + end + temp[pRow], temp[i] = temp[i], temp[pRow] + end + local row = temp[pRow] + pivot = row[pCol] + for l=pCol,#row do + row[l] = row[l]/pivot + end + + if r == 1 then + -- make the "reduced row echelon form" + local row = temp[pRow] + for k=1,pRow-1 do + local current = temp[k] + local factor = -current[pCol] + local mk = current + for l=pCol,#mk do + mk[l] = mk[l] + factor * row[l] + end + end + end + -- just make the row echelon form + local row = temp[pRow] + for k=pRow+1, #temp do + local current = temp[k] + local factor = -current[pCol] + local mk = current + for l=pCol,#mk do + mk[l] = mk[l] + factor * row[l] + end + end + pRow = pRow + 1 + pCol = pCol + 1 + + if pRow > #temp or pCol > #temp[1] then + pRow = #temp + 1 + end + end + return temp +end + +matrix.rowechelon = rowechelon +matrix.rowEchelon = rowechelon + +-- solve the linear equation m X = c + +local function solve(m,c) + local n = #m + if n ~= #c then + return copy(m) + end + local newm = copy(m) + local temp = copy(c) + for i=1,n do + insert(newm[i],temp[i]) + end + return rowechelon(newm,1) +end + +matrix.solve = solve + +-- find the inverse matrix of m + +local function inverse(m) + local n = #m + local temp = copy(m) + if n ~= #m[1] then + return temp + end + for i=1,n do + for j=1,n do + insert(temp[i],j == i and 1 or 0) + end + end + temp = rowechelon(temp,1) + for i=1,n do + for j=1,n do + remove(temp[i], 1) + end + end + return temp +end + +matrix.inverse = inverse + +\stopluacode + +\stopmodule + +\unexpanded\def\ctxmodulematrix#1{\ctxlua{moduledata.matrix.#1}} + +\continueifinputfile{m-matrix.mkiv} + +\starttext + +\startluacode +document.DemoMatrixA = { + { 0, 2, 4, -4, 1 }, + { 0, 0, 2, 3, 4 }, + { 2, 2, -6, 2, 4 }, + { 2, 0, -6, 9, 7 }, + { 2, 3, 4, 5, 6 }, + { 6, 6, -6, 6, 6 }, +} + +document.DemoMatrixB = { + { 0, 2, 4, -4, 1 }, + { 0, 0, 2, 3, 4 }, + { 2, 2, -6, 2, 4 }, + { 2, 0, -6, 9, 7 }, + { 2, 2, -6, 2, 4 }, + { 2, 2, -6, 2, 4 }, +} +\stopluacode + +\startsubject[title={A symbolic matrix}] + +\ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n"))} +\ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n", 4, 8))} + +\stopsubject + +\startsubject[title={Swap two rows (2 and 4)}] + +\startluacode +moduledata.matrix.typeset(document.DemoMatrixA) +context.blank() +moduledata.matrix.swap(document.DemoMatrixA, 2, 4) +context.blank() +moduledata.matrix.typeset(document.DemoMatrixA) +\stopluacode + +\stopsubject + +\startsubject[title={Multiply $3 \times r_2$}] + +\startluacode +moduledata.matrix.typeset(document.DemoMatrixA) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.multiply(document.DemoMatrixA, 2, 3)) +\stopluacode + +\stopsubject + +\startsubject[title={Row 2 + $3 \times r_4$}] + +\startluacode +moduledata.matrix.typeset(document.DemoMatrixA) +context.blank() +moduledata.matrix.sumrow(document.DemoMatrixA, 2, 3, 4) +context.blank() +moduledata.matrix.typeset(document.DemoMatrixA) +\stopluacode + +\stopsubject + +\startsubject[title={Transpose a matrix}] + +\startluacode +moduledata.matrix.typeset(document.DemoMatrixA) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.transpose(document.DemoMatrixA)) +\stopluacode + +\stopsubject + +\startsubject[title={The inner product of two vectors}] + +\startluacode +context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2 })) +context.blank() +context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 })) +\stopluacode + +\startsubject[title={The product of two matrices}] + +\startluacode +moduledata.matrix.typeset(document.DemoMatrixA) +context.blank() +moduledata.matrix.typeset(moduledata.matrix.product(document.DemoMatrixA,document.DemoMatrixA)) +\stopluacode + +\stopsubject + +\startsubject[title={An Upper Triangular Matrix}] + +\ctxmodulematrix{typeset(moduledata.matrix.uppertri(document.DemoMatrixB))} + +\startsubject[title={A determinant}] + +\startluacode +local m = { + { 1, 2, 4 }, + { 0, 0, 2 }, + { 2, 2, -6 }, +} +context(moduledata.matrix.determinant(m)) +\stopluacode + +\stopsubject + +\startsubject[title={Row echelon form}] + +\startluacode +local m = { + { 1, 3, -2, 0, 2, 0, 0 }, + { 2, 6, -5, -2, 4, -3, -1 }, + { 0, 0, 5, 10, 0, 15, 5 }, + { 2, 6, 0, 8, 4, 18, 6 }, +} + +moduledata.matrix.typeset(m) +moduledata.matrix.typeset(moduledata.matrix.rowechelon(m,1)) +\stopluacode + +\stopsubject + +\startsubject[title={Solving linear equation}] + +\startluacode +local m = { + { 1, 3, -2, 0 }, + { 2, 0, 1, 2 }, + { 6, -5, -2, 4 }, + { -3, -1, 5, 10 }, +} + +local c = { 5, 2, 6, 8 } + +moduledata.matrix.typeset(moduledata.matrix.solve(m,c)) +\stopluacode + +\stopsubject + +\startsubject[title={Inverse matrix}] + +\startcombination[2*1] + {\ctxlua{moduledata.matrix.typeset { { 1, 1, 1 }, { 0, 2, 3 }, { 3, 2, 1 } }}} {} + {\ctxlua{moduledata.matrix.typeset(moduledata.matrix.inverse { { 1, 1, 1 }, { 0, 2, 3 }, { 3, 2, 1 } })}} {} +\stopcombination + +\stopsubject + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-mkii.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-mkii.mkiv new file mode 100644 index 00000000000..dcfd29d2092 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-mkii.mkiv @@ -0,0 +1,21 @@ +% todo + +\unprotect + +\writestatus\m!system{loading some mkii compatibility hacks} + +% Compatibility for font-ini + +\let\normalxi=\xi + +\definebodyfontswitch [xii] [\!!twelvepoint] +\definebodyfontswitch [xi] [\!!elevenpoint] +\definebodyfontswitch [x] [\!!tenpoint] +\definebodyfontswitch [ix] [\!!ninepoint] +\definebodyfontswitch [viii] [\!!eightpoint] +\definebodyfontswitch [vii] [\!!sevenpoint] +\definebodyfontswitch [vi] [\!!sixpoint] + +\unexpanded\def\xi{\ifmmode\normalxi\else\elevenpoint\fi} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-mkivhacks.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-mkivhacks.mkiv new file mode 100644 index 00000000000..3ed002e1d50 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-mkivhacks.mkiv @@ -0,0 +1,50 @@ +%D \module +%D [ file=m-mkivhacks, +%D version=2008.10.20, +%D title=\CONTEXT\ Modules, +%D subtitle=Temporary Compatilibility Hacks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D For Aditya, who needed it for his thesis. + +\startluacode + -- -- a lot or work + -- + -- mathematics.slots.euler = { + -- [0x03B1] = { "mr", 0x0B }, -- alpha + -- } + -- + -- mathematics.slots.euler = table.merge(mathematics.slots.traditional,mathematics.slots.euler) + -- + -- versus a quick hack + + document.hacks = document.hacks or { } + + function document.hacks() + mathematics.families.lcgreek = mathematics.families.mr + mathematics.families.ucgreek = mathematics.families.mr + mathematics.families.vargreek = mathematics.families.mr + + mathematics.define(mathematics.slots.euler) + end +\stopluacode + +% \usemodule[mkivhacks] \setups{eulermath} +% \definetypeface[modern][mm][math][euler][default] +% \usemathcollection[eul] +% \switchtobodyfont[modern,11pt] +% \starttext +% $\alpha$ +% \stoptext + +\startsetups eulermath + \ctxlua{document.hacks()} +\stopsetups + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-morse.mkvi b/Master/texmf-dist/tex/context/modules/mkiv/m-morse.mkvi new file mode 100644 index 00000000000..a2c20dff745 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-morse.mkvi @@ -0,0 +1,273 @@ +%D \module +%D [ file=m-morse, +%D version=2010.12.10, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Morse, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo: act upon the node list +% make it a buffer operation +% nice in cld manual + +\startluacode + +moduledata.morse = moduledata.morse or { } +local morse = moduledata.morse + +local utfcharacters, gsub = string.utfcharacters, string.gsub +local ucchars, shchars = characters.ucchars, characters.shchars + +local codes = { + + ["A"] = "·—", + ["B"] = "—···", + ["C"] = "—·—·", + ["D"] = "—··", + ["E"] = "·", + ["F"] = "··—·", + ["G"] = "——·", + ["H"] = "····", + ["I"] = "··", + ["J"] = "·———", + ["K"] = "—·—", + ["L"] = "·—··", + ["M"] = "——", + ["N"] = "—·", + ["O"] = "———", + ["P"] = "·——·", + ["Q"] = "——·—", + ["R"] = "·—·", + ["S"] = "···", + ["T"] = "—", + ["U"] = "··—", + ["V"] = "···—", + ["W"] = "·——", + ["X"] = "—··—", + ["Y"] = "—·——", + ["Z"] = "——··", + + ["0"] = "—————", + ["1"] = "·————", + ["2"] = "··———", + ["3"] = "···——", + ["4"] = "····—", + ["5"] = "·····", + ["6"] = "—····", + ["7"] = "——···", + ["8"] = "———··", + ["9"] = "————·", + + ["."] = "·—·—·—", + [","] = "——··——", + [":"] = "———···", + [";"] = "—·—·—", + + ["?"] = "··——··", + ["!"] = "—·—·——", + + ["-"] = "—····—", + ["/"] = "—··—· ", + + ["("] = "—·——·", + [")"] = "—·——·—", + + ["="] = "—···—", + ["@"] = "·——·—·", + + ["'"] = "·————·", + ['"'] = "·—··—·", + + ["À"] = "·——·—", + ["Ã…"] = "·——·—", + ["Ä"] = "·—·—", + ["Æ"] = "·—·—", + ["Ç"] = "—·—··", + ["É"] = "··—··", + ["È"] = "·—··—", + ["Ñ"] = "——·——", + ["Ö"] = "———·", + ["Ø"] = "———·", + ["Ãœ"] = "··——", + ["ß"] = "··· ···", + +} + +morse.codes = codes + +local fallbackself = false + +local function codefallback(t,k) + if k then + local u = ucchars[k] + local v = rawget(t,u) or rawget(t,shchars[u]) or false + t[k] = v + return v + elseif fallbackself then + return k + else + return false + end +end + +table.setmetatableindex(codes,codefallback) + +local MorseBetweenWords = context.MorseBetweenWords +local MorseBetweenCharacters = context.MorseBetweenCharacters +local MorseLong = context.MorseLong +local MorseShort = context.MorseShort +local MorseSpace = context.MorseSpace +local MorseUnknown = context.MorseUnknown + +local function toverbose(str) + str = gsub(str,"%s*+%s*","+") + str = gsub(str,"%s+"," ") + local done = false + for m in utfcharacters(str) do + if done then + MorseBetweenCharacters() + end + if m == "·" or m == "." then + MorseShort() + done = true + elseif m == "—" or m == "-" then + MorseLong() + done = true + elseif m == " " then + if done then + MorseBetweenCharacters() + end + done = false + elseif m == "+" then + MorseBetweenWords() + done = false + else + MorseUnknown(m) + end + end +end + +local function toregular(str) + local inmorse = false + for s in utfcharacters(str) do + local m = codes[s] + if m then + if inmorse then + MorseBetweenWords() + else + inmorse = true + end + local done = false + for m in utfcharacters(m) do + if done then + MorseBetweenCharacters() + else + done = true + end + if m == "·" then + MorseShort() + elseif m == "—" then + MorseLong() + elseif m == " " then + MorseBetweenCharacters() + end + end + inmorse = true + elseif s == "\n" or s == " " then + MorseSpace() + inmorse = false + else + if inmorse then + MorseBetweenWords() + else + inmorse = true + end + MorseUnknown(s) + end + end +end + +local function tomorse(str,verbose) + if verbose then + toverbose(str) + else + toregular(str) + end +end + +morse.tomorse = tomorse + +function morse.filetomorse(name,verbose) + tomorse(resolvers.loadtexfile(name),verbose) +end + +function morse.showtable() + context.starttabulate { "|l|l|" } -- { "|l|l|l|" } + for k, v in table.sortedpairs(codes) do + context.NC() context(k) + -- context.NC() context(v) + context.NC() tomorse(v,true) + context.NC() context.NR() + end + context.stoptabulate() +end + +\stopluacode + +\unprotect + +% todo: \setupmorse, but probably it's not worth the trouble. + +\def\MorseWidth {0.4em} +\def\MorseHeight {0.2em} +%def\MorseShort {\dontleavehmode\blackrule[\c!height=\MorseHeight,\c!width=\dimexpr\MorseWidth]} +%def\MorseLong {\dontleavehmode\blackrule[\c!height=\MorseHeight,\c!width=3\dimexpr\MorseWidth]} +\def\MorseShort {\dontleavehmode\vrule\!!width \dimexpr\MorseWidth\!!height\MorseHeight\!!depth\zeropoint\relax} +\def\MorseLong {\dontleavehmode\vrule\!!width3\dimexpr\MorseWidth\!!height\MorseHeight\!!depth\zeropoint\relax} +\def\MorseBetweenCharacters {\kern\MorseWidth} +\def\MorseBetweenWords {\hskip3\dimexpr\MorseWidth\relax} +\def\MorseSpace {\hskip7\dimexpr\MorseWidth\relax} +\def\MorseUnknown #text{[\detokenize{#text}]} + +\unexpanded\def\MorseCode #text{\ctxlua{moduledata.morse.tomorse(\!!bs#text\!!es,true)}} +\unexpanded\def\MorseString #text{\ctxlua{moduledata.morse.tomorse(\!!bs#text\!!es)}} +\unexpanded\def\MorseFile #text{\ctxlua{moduledata.morse.filetomorse("#text")}} +\unexpanded\def\MorseTable {\ctxlua{moduledata.morse.showtable()}} + +\let\Morse \MorseString + +%def\MorseShort {·} +%def\MorseLong {—} + +\protect + +\continueifinputfile{m-morse.mkvi} + +\starttext + +\MorseTable + +\startlines +\MorseCode{—·—· ——— —· — · —··— —+—— —·— ·· ···—} +\MorseCode{—·—· ——— —· — · —··— — + —— —·— ·· ···—} +\Morse{ÀÃÂÃÄÅà áâãäå} +\Morse{ÆÇæç} +\Morse{ÈÉÊËèéêë} +\Morse{ÃŒÃÃŽÃìÃîï} +\Morse{Ññ} +\Morse{ÒÓÔÕÖòóôõö} +\Morse{Øø} +\Morse{ÙÚÛÜùúû} +\Morse{Ãýÿ} +\Morse{ß} +\Morse{Ţţ} +\stoplines + +\Morse{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-narrowtt.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-narrowtt.mkiv new file mode 100644 index 00000000000..7d497a02f18 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-narrowtt.mkiv @@ -0,0 +1,39 @@ +%D \module +%D [ file=m-narrowtt, +%D version=2005.09.08, +%D title=\CONTEXT\ Modules, +%D subtitle=Narrow Verbatim, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Test file +%D +%D \starttyping +%D \startTEX +%D \usemodule[narrowtt] +%D \starttext +%D \starttyping +%D Test test test. +%D \stoptyping +%D test \type {test} test \type{test} test +%D \starttyping +%D Test test test. +%D \stoptyping +%D \stoptext +%D \stopTEX + +\unprotect + +\definetypeface + [narrowtt] [tt] + [mono] [modern-condensed] [\s!default] [\s!features=\s!none] + +\definetyping[n\v!typing] \setuptyping[n\v!typing][style=\narrowtt] +\definetype [n\v!type] \setuptype [n\v!type] [style=\narrowtt] + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.lua new file mode 100644 index 00000000000..da80faed9ec --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.lua @@ -0,0 +1,175 @@ +if not modules then modules = { } end modules ['m-nodechart'] = { + version = 1.001, + comment = "companion to m-nodechart.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format = string.format +local points = number.nopts +local ptfactor = number.dimenfactors.pt + +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes +local penaltycodes = nodes.penaltycodes +local gluecodes = nodes.gluecodes +local whatsitcodes = nodes.whatsitcodes + +moduledata.charts = moduledata.charts or { } +moduledata.charts.nodes = moduledata.charts.nodes or { } + +local formatters = { } + +-- subtype font char lang left right uchyph components xoffset yoffset width height depth + +function formatters.glyph(n,comment) + return format("\\doFLOWglyphnode{%s}{%s}{%s}{%s}{U+%05X}",comment,n.subtype,n.font,n.char,n.char) +end + +-- pre post replace + +function formatters.disc(n,comment) + return format("\\doFLOWdiscnode{%s}{%s}",comment,n.subtype) +end + +-- subtype kern + +function formatters.kern(n,comment) + -- return format("\\doFLOWkernnode{%s}{%s}{%s}",comment,kerncodes[n.subtype],points(n.kern)) + return format("\\doFLOWkernnode{%s}{%s}{%.4f}",comment,kerncodes[n.subtype],n.kern*ptfactor) +end + +-- subtype penalty + +function formatters.penalty(n,comment) + return format("\\doFLOWpenaltynode{%s}{%s}{%s}",comment,"penalty",n.penalty) +end + +-- subtype width leader spec (stretch shrink ... + +function formatters.glue(n,comment) + return format("\\doFLOWgluenode{%s}{%s}{%.4f}{%.4f}{%.4f}",comment,gluecodes[n.subtype],n.width*ptfactor,n.stretch*ptfactor,n.shrink*ptfactor) +end + +-- subtype width leader spec (stretch shrink ... + +function formatters.whatsit(n,comment) + return whatsitcodes[n.id] or "unknown whatsit" +end + +function formatters.dir(n,comment) + return format("\\doFLOWdirnode{%s}{%s}{%s}",comment,"dir",n.dir) +end + +function formatters.localpar(n,comment) + return format("\\doFLOWdirnode{%s}{%s}{%s}",comment,"localpar",n.dir) +end + +-- I will make a dedicated set of shapes for this. + +local shapes = { + glyph = "procedure", + disc = "procedure", + kern = "action", + penalty = "action", + glue = "action", +} + +local function flow_nodes_to_chart(specification) + local head = specification.head + local box = specification.box + local comment = specification.comment or "" + local x = specification.x or 1 + local y = specification.y or 0 + -- + if box then + box = tex.getbox(tonumber(box)) + head = box and box.list + end + -- + local current = head + -- + while current do + local nodecode = nodecodes[current.id] + local formatter = formatters[nodecode] + local shape = shapes[nodecode] + y = y + 1 + local next = current.next + commands.flow_start_cell { shape = { framecolor = "nodechart:" .. nodecode } } + commands.flow_set_name(tostring(current)) + commands.flow_set_location(x,y) + if shape then + commands.flow_set_shape(shape) + end + if formatter then + commands.flow_set_text("node",formatter(current,comment)) + else + commands.flow_set_text("node",nodecode) + end + if next then + commands.flow_set_connection("bt","",tostring(next)) + end + if nodecode == "glyph" then + local components = current.components + if components then + commands.flow_set_connection("rl","",tostring(components)) + commands.flow_stop_cell() + n = flow_nodes_to_chart { head = components, comment = "component",x = x+2, y = y-1 } + else + commands.flow_stop_cell() + end + elseif nodecode == "disc" then + local pre = current.pre + local pos = current.post + local rep = current.replace + if pre and not rep and not rep then + if pre then + commands.flow_set_connection("rl","",tostring(pre)) + end + commands.flow_stop_cell() + if pre then + n = flow_nodes_to_chart { head = pre, comment = "prebreak", x = x+1, y = y-1 } + end + else + if pre then + commands.flow_set_connection("+rl","",tostring(pre)) + end + if rep then + commands.flow_set_connection("rl","",tostring(rep)) + end + if pos then + commands.flow_set_connection("-rl","",tostring(pos)) + end + commands.flow_stop_cell() + if pre then + n = flow_nodes_to_chart{ head = pre, comment = "prebreak", x = x+1, y = y-2 } + end + if rep then + n = flow_nodes_to_chart{ head = rep, comment = "replacement", x = x+1, y = y-1 } + end + if pos then + n = flow_nodes_to_chart{ head = pos, comment = "postbreak", x = x+1, y = y } + end + end + elseif nodecode == "hlist" then + local list = current.list + if list then + commands.flow_set_connection("rl","",tostring(list)) + commands.flow_stop_cell() + n = flow_nodes_to_chart { head = list, comment = "list", x = x+2, y = y-1 } + else + commands.flow_stop_cell() + end + else + commands.flow_stop_cell() + end + current = next + end +end + +function moduledata.charts.nodes.chart(specification) + commands.flow_start_chart(specification.name) + flow_nodes_to_chart(specification) + commands.flow_stop_chart() +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.mkvi b/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.mkvi new file mode 100644 index 00000000000..c9d9858506c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.mkvi @@ -0,0 +1,125 @@ +%D \module +%D [ file=m-nodechart, +%D version=2011.11.11, % nos sure when it started, needed for fonts-mkiv +%D title=\CONTEXT\ Modules, +%D subtitle=Node Visualization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] + +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\registerctxluafile{m-nodechart}{1.001} + +\usemodule[chart] + +\unprotect + +\def\enspaceminus{\hskip.5em minus .25em\relax} + +\starttexdefinition unexpanded doFLOWglyphnode #comment #subtype #font #char #unicode + \dontleavehmode\hbox{\bf\setstrut\strut \doifsomething{#comment}{#comment\enspaceminus:\enspaceminus}glyph #subtype} + \vss + \dontleavehmode\hbox{\tx\setstrut\strut font\enspaceminus#font:\enspace#unicode:\enspaceminus\setfontofid{#font}\char#char} +\stoptexdefinition + +\starttexdefinition unexpanded doFLOWdiscnode #comment #subtype + \dontleavehmode\hbox{\bf\setstrut\strut disc} + \vss + \dontleavehmode\hbox{\tx\setstrut\strut} +\stoptexdefinition + +\starttexdefinition unexpanded doFLOWkernnode #comment #subtype #kern + \dontleavehmode\hbox{\bf\setstrut\strut#subtype} + \vss + \dontleavehmode\hbox{\tx\setstrut\strut#kern} +\stoptexdefinition + +\starttexdefinition unexpanded doFLOWpenaltynode #comment #subtype #penalty + \dontleavehmode\hbox{\bf\setstrut\strut#subtype} + \vss + \dontleavehmode\hbox{\tx\setstrut\strut#penalty} +\stoptexdefinition + +\starttexdefinition unexpanded doFLOWgluenode #comment #subtype #width #shrink #stretch + \dontleavehmode\hbox{\bf\setstrut\strut#subtype} + \vss + \dontleavehmode\hbox{\tx\setstrut\strut#width\enspaceminus-\enspaceminus#shrink\enspaceminus+\enspaceminus#stretch} +\stoptexdefinition + +\starttexdefinition unexpanded doFLOWdirnode #comment #subtype #direction + \dontleavehmode\hbox{\bf\setstrut\strut#subtype} + \vss + \dontleavehmode\hbox{\tx\setstrut\strut#direction} +\stoptexdefinition + +\defineframed + [flowcell:node] + [flowcell:base] + [\c!top=\vss, + \c!bottom=\vss, + \c!align=\v!middle, + \c!foregroundstyle=\tt] + +% this is a temporary interface ... we will have instances and optional settings + +\unexpanded\def\boxtoFLOWchart[#name]#box% + {\ctxlua{moduledata.charts.nodes.chart { + name = "#name", + box = \number#box, + }}} + +\unexpanded\def\nextboxtoFLOWchart[#name]% + {\dowithnextbox{\boxtoFLOWchart[#name]\nextbox}} + +\unexpanded\def\hboxtoFLOWchart[#name]% + {\nextboxtoFLOWchart[#name]\hbox} + +\unexpanded\def\vboxtoFLOWchart[#name]% + {\nextboxtoFLOWchart[#name]\vbox} + +\protect + +\continueifinputfile{m-nodechart.mkvi} + +\definecolor[nodechart:glyph][darkred] + +\setupbodyfont[dejavu,10pt] + +\starttext + +\startTEXpage[offset=10pt] + + \hboxtoFLOWchart[dummy]{an affil\discretionary{-}{-}{!}iation} + + \FLOWchart[dummy][width=14em,height=3em,dx=1em,dy=.75em,hcompact=yes] + +\stopTEXpage + +\startTEXpage[offset=10pt] + + \hboxtoFLOWchart[dummy]{an affiliation} + + \FLOWchart[dummy][width=14em,height=3em,dx=.5em,dy=.75em,hcompact=yes] + +\stopTEXpage + +\startTEXpage[offset=10pt] + + \hboxtoFLOWchart[dummy]{\nl effe fijn fietsen} + + \FLOWchart[dummy][width=14em,height=3em,dx=.5em,dy=.75em,hcompact=yes] + +\stopTEXpage + +\startTEXpage[offset=10pt] + + \hboxtoFLOWchart[dummy]{\righttoleft t\kern 1pt est} + + \FLOWchart[dummy][width=14em,height=3em,dx=.5em,dy=.75em,hcompact=yes] + +\stopTEXpage + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-ntb-to-xtb.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-ntb-to-xtb.mkiv new file mode 100644 index 00000000000..55b4ab25926 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-ntb-to-xtb.mkiv @@ -0,0 +1,5 @@ +\loadmkvifile{tabl-xnt} + +\mapTABLEtoxtable + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-obsolete.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-obsolete.mkiv new file mode 100644 index 00000000000..2d4518181e6 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-obsolete.mkiv @@ -0,0 +1,5 @@ +\unprotect + +\writestatus\m!system{skipping obsolete module} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-oldfun.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-oldfun.mkiv new file mode 100644 index 00000000000..3f2ec0263ed --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-oldfun.mkiv @@ -0,0 +1,714 @@ +%D \module +%D [ file=m-oldfun, % was: supp-fun +%D version=1995.10.10, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Fun Stuff, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D Beware, these macros wil be replaced and at some point this +%D module will not be preloaded any more. + +%D This module implements some typographics tricks that can +%D be fun when designing document layouts. The examples use +%D macros that are typical to \CONTEXT, but non \CONTEXT\ +%D users can use the drop caps and first line treatment +%D macros without problems. This module will be extended +%D when the need for more of such tricks arises. + +\writestatus{loading}{ConTeXt Support Macros / Fun Stuff} + +%D \macros +%D {DroppedCaps, DroppedString, DroppedIndent, DroppedLines} +%D +%D \startbuffer +%D \DroppedCaps +%D {\color[green]} {SerifBold} +%D {\the\dimexpr2.2\baselineskip} {2pt} {\the\baselineskip} {2} +%D Let's start +%D \stopbuffer +%D +%D \getbuffer with dropped caps, those blown up first +%D characters of a paragraph. It's hard to implement a general +%D mechanism that suits all situations, but dropped caps are so +%D seldomly used that we can permit ourselves a rather user +%D unfriendly implementation. +%D +%D \typebuffer +%D +%D As we will see, there are 7 different settings involved. The +%D first argument takes a command that is used to do whatever +%D fancy things we want to do, but normally this one will be +%D empty. The second argument takes the font. Because we're +%D dealing with something very typographic, there is no real +%D reason to adopt complicated font switching schemes, a mere +%D name will do. Font encodings can bring no harm, because the +%D alphanumeric characters are nearly always located at their +%D natural position in the encoding vector. +%D +%D \startbuffer +%D \DroppedCaps +%D {\color[red]} {SerifBold} +%D {\the\baselineskip} {0pt} {0pt} {1} +%D This simple +%D \stopbuffer +%D +%D \getbuffer case shows us what happens when we apply minimal +%D values. Here we used: +%D +%D \typebuffer +%D +%D \startbuffer +%D \DroppedCaps +%D {\color[red]} {SerifBold} +%D {\the\dimexpr2\baselineskip} {0pt} {\the\baselineskip} {2} +%D Is this ugly +%D \stopbuffer +%D +%D \getbuffer example the third argument tells +%D this macro that we want a dropped capital scaled to the +%D baseline distance. The two zero point arguments are the +%D horizontal and vertical offsets and the last arguments +%D determines the hanging indentation. In this paragraph we +%D set the height to two times the baselinedistance and use +%D two hanging lines: +%D +%D \typebuffer +%D +%D Here, the first character is moved down one baseline. Here +%D we also see why the horizontal offset is important. The +%D first example (showing the~L) sets this to a few points and +%D also used a slightly larger height. +%D +%D Of course common users (typist) are not supposed to see this +%D kind of fuzzy definitions, but fortunately \TEX\ permits us +%D to hide them in macros. Using a macro also enables us to +%D garantee consistency throughout the document: +%D +%D \startbuffer +%D \def\MyDroppedCaps% +%D {\DroppedCaps +%D {\color[green]} {SerifBold} +%D {\the\dimexpr5\baselineskip} {3pt} {\the\dimexpr3\baselineskip} {4}} +%D +%D \MyDroppedCaps The implementation +%D \stopbuffer +%D +%D \typebuffer +%D +%D \getbuffer of the general macro is rather simple and only +%D depends on the arguments given and the dimensions of the +%D strut box. We explicitly load the font, which is no problem +%D because \TEX\ does not load a font twice. We could have +%D combined some arguments, like the height, vertical offset +%D and the number of lines, but the current implementation +%D proved to be the most flexible. One should be aware of the +%D fact that the offsets depend on the design of the glyphs +%D used. + +\let\DroppedIndent\!!zeropoint \def\DroppedLines{0} + +\def\DroppedString{ABCDEFGHIJKLMNOPQRSTUVWXYZ} + +\let\globaldropcaps\global % will be an option, but on by default + +\unexpanded\def\localdropcaps{\let\globaldropcaps\relax} + +\chardef\DroppedStatus = 0 % 0=done 1=starting 2=doing 3=error +\chardef\DropMode = 0 % 1 == marginhang + +\ifx\keeplinestogether\undefined + \let\keeplinestogether\gobbleoneargument +\fi + +\unexpanded\def\DroppedCaps#1#2#3#4#5#6#7% does not yet handle accented chars + {\defconvertedargument\asciia{#7}% + \defconvertedcommand \asciib{\DroppedString}% + \doifelseinstring\asciia\asciib + {\noindentation + \dontleavehmode + \checkindentation % redo this one + %\ifhmode\hskip-\parindent\fi % sensitive for context mechanism + \keeplinestogether{#6}% + \setbox0\hbox{\definedfont[#2 at #3]#1{#7}\hskip#4}% + \ifdim\dp0>\strutdp % one of those Q's , will be option + \setbox2\hbox{\raise\dp0\hbox{\lower\strutdp\copy0}}% + \ht2\ht0 + \dp0\strutdp + \setbox0\box2 + \fi + \setbox0\hbox + {\ifnum\DropMode=\plusone + \hskip-\wd0\wd0\zeropoint + \fi + \lower#5\box0}% + \ht0\strutht + \dp0\strutdp + \ifnum\DropMode=\plusone + \globaldropcaps\let\DroppedIndent\!!zeropoint + \globaldropcaps\edef\DroppedLines{\number\maxdimen}% + \globaldropcaps\chardef\DroppedStatus\plusthree + \else + \globaldropcaps\edef\DroppedIndent{\the\wd0}% + \globaldropcaps\edef\DroppedLines {\number#6}% + \globaldropcaps\chardef\DroppedStatus\plustwo + \globaldropcaps\hangindent\DroppedIndent + \globaldropcaps\hangafter-\DroppedLines +% \noindent + \noindentation + \checkindentation % redo this one + \hskip-\DroppedIndent + \fi + \vbox{\forgetall\box0}% + \nobreak + \let\next\ignorespaces} % Could be a one character word ! + {\globaldropcaps\let\DroppedIndent\!!zeropoint + \globaldropcaps\edef\DroppedLines{\number\maxdimen}% + \globaldropcaps\chardef\DroppedStatus\plusthree + \def\next{#7}}% + \let\globaldropcaps\global + \next} + +%D Before we go to the next topic, we summarize this command: +%D +%D \starttyping +%D \DroppedCaps +%D {command} {font} +%D {height} {hoffset} {voffset} {lines} +%D \stoptyping +%D +%D Sometimes you need to make sure that the global settings are +%D kept local, as in: +%D +% %D \startbuffer +% %D \defineparagraphs[SomePar][n=2,rule=on] +% %D \setupparagraphs [SomePar][1][width=.5\textwidth] +% %D \setupparagraphs [SomePar][2][width=.5\textwidth] +%D \startbuffer +%D \defineparagraphs[SomePar][n=2,rule=on] +%D \setupparagraphs [SomePar][1][width=.5\textwidth] +%D \setupparagraphs [SomePar][2][width=.5\textwidth] +%D +%D \startSomePar +%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need +%D to explicitly keep the hanging indentation local, like it or +%D not. +%D \SomePar +%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need +%D to explicitly keep the hanging indentation local, like it or +%D not. +%D \stopSomePar +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {AutoDroppedCaps, CheckDroppedCaps} +%D +%D {\em To be documented.} + +% example usage +% +% \def\bpar{\ifvmode\CheckDroppedCaps\fi} +% \def\epar{\ifhmode\par\fi\CheckDroppedCaps} + +\newcount\lastprevgraf +\newcount\droppedlines + +\unexpanded\def\CheckDroppedCaps + {\global\lastprevgraf\prevgraf} + +\unexpanded\def\AutoDroppedCaps % will be proper core stuff since it + {\globaldropcaps\chardef\DroppedStatus\plusone + \global\lastprevgraf\zerocount + \global\droppedlines\zerocount + \EveryPar{\doAutoDroppedCaps}} + +\let\AutoDroppedNext\relax + +\ifx\AutoDroppedCapsCommand\undefined + \unexpanded\def\AutoDroppedCapsCommand{\NiceDroppedCaps{}{SerifBold}{.125em}{3}} +\fi + +\unexpanded\def\doAutoDroppedCaps + {\ifcase\DroppedStatus % done + \let\next\relax + \or % starting + % \ifnum\lastprevgraf>0 % tricky, probably a wrong par + % \globaldropcaps\chardef\DroppedStatus=3 % and inhibits dropped + % \let\next\relax % caps after titles and more than once + % \else % so let's nill this rubishly code fragment + \let\next\AutoDroppedCapsCommand + % \fi % and hope for the best + \or % doing + \global\advance\droppedlines \lastprevgraf + \ifnum\droppedlines=\zerocount + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \else\ifnum\droppedlines>\zerocount + \ifnum\droppedlines<\DroppedLines\relax + \globaldropcaps\hangindent\DroppedIndent + \globaldropcaps\hangafter-\DroppedLines + \globaldropcaps\advance\hangafter \droppedlines + \hskip-\parindent % brrr + \let\next\AutoDroppedNext + \else + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \fi + \else + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \fi\fi + \or % error + \globaldropcaps\chardef\DroppedStatus\zerocount + \let\next\relax + \fi + \next} + +%D \macros +%D {LineDroppedCaps, NiceDroppedCaps} +%D +%D To save definitions, we also provide: +%D +%D \starttyping +%D \LineDroppedCaps {command} {font} {hoffset} {lines} +%D \NiceDroppedCaps {command} {font} {hoffset} {lines} +%D \stoptyping +%D +%D The first command scales the font to the exact height, while +%D the second command scales the font to a nice 2.5 times the +%D line height, a value that gives a pleasant grayness. + +\unexpanded\def\DoLineDroppedCaps#1#2#3#4#5% compensation command font offset lines + {\scratchcounter#5% + \advance\scratchcounter \minusone + \scratchdimen\scratchcounter\baselineskip + \advance\scratchdimen #1% + \NormalizeFontHeight\DummyFont{W}\scratchdimen{#3}% + \DroppedCaps{#2}{#3}\TheNormalizedFontSize{#4} + {\scratchcounter\baselineskip}{#5}} + +\unexpanded\def\LineDroppedCaps% command font offset lines + {\DoLineDroppedCaps{\strutht}} + +\unexpanded\def\NiceDroppedCaps% command font offset lines + {\DoLineDroppedCaps{.5\baselineskip}} + +%D \macros +%D {TreatFirstLine} +%D +%D \startbuffer +%D \TreatFirstLine {\sc} {} {} {} +%D Instead of limiting its action to one token, the next macro +%D treats the whole first line. This paragraph was typeset by +%D saying: +%D \stopbuffer +%D +%D \getbuffer +%D +%D \typebuffer +%D +%D \startbuffer +%D \TreatFirstLine {\startcolor[red]\bf} {\stopcolor} {} {} +%D The combined color and font effect is also possible, +%D although one must be careful in using macros that accumulate +%D grouping, but the commands used here are pretty save in that +%D respect. +%D \stopbuffer +%D +%D \getbuffer +%D +%D \typebuffer +%D +%D Before we explain the third and fourth argument, we show the +%D implementation. Those who know a bit about the way \TEX\ +%D treats tokens, will probably see in one glance that this +%D alternative works all right for most text||only situations +%D in which there is enough text available for the first line, +%D but that more complicated things will blow. One has to live +%D with that. A workaround is rather trivial but obscures the +%D principles used. + +\unexpanded\def\TreatFirstLine#1#2#3#4% before, after, first, next + {\leavevmode + \bgroup + \forgetall + \bgroup + #1% + \setbox0\emptybox + \setbox2\emptybox + \def\grabfirstline##1 % + {\setbox2\hbox + {\ifvoid0 + {#3{\ignorespaces##1}}% + \else + \unhcopy0\ {#4{##1}}% + \fi}% + \ifdim\wd2=\zeropoint + \setbox0\emptybox + \setbox2\emptybox + \@EA\grabfirstline + \else\ifdim\wd2>\hsize + \hbox to \hsize{\strut\unhbox0}#2\egroup + \break##1\ + \egroup + \else + \setbox0\box2 + \@EAEAEA\grabfirstline + \fi\fi}% + \grabfirstline} + +%D \startbuffer +%D \gdef\FunnyCommand +%D {\getrandomfloat\FunnyR{0}{1}% +%D \getrandomfloat\FunnyG{0}{1}% +%D \getrandomfloat\FunnyB{0}{1}% +%D \definecolor[FunnyColor][r=\FunnyR,g=\FunnyG,b=\FunnyB]% +%D \color[FunnyColor]} +%D +%D %\TreatFirstLine {\bf} {} {\FunnyCommand} {\FunnyCommand} +%D The third and fourth argument can be used to gain special +%D effects on the individual words. Of course one needs ... +%D \stopbuffer +%D +%D \getbuffer +%D to know a bit more about the macro package used to get real +%D nice effects, but this example probably demonstrates the +%D principles well. +%D +%D \typebuffer +%D +%D Like in dropped caps case, one can hide such treatments in a +%D macro, like: +%D +%D \starttyping +%D \def\MyTreatFirstLine% +%D {\TreatFirstLine{\bf}{}{\FunnyCommand}{\FunnyCommand}} +%D \stoptyping + +%D \macros +%D {reshapebox} +%D +%D \startbuffer +%D \beginofshapebox +%D When using \CONTEXT, one can also apply this funny command +%D to whole lines by using the reshape mechanism. Describing +%D this interesting mechanism falls outside the scope of this +%D module, so we only show the trick. This is an example of +%D low level \CONTEXT\ functionality: it's all there, and it's +%D stable, but not entirely meant for novice users. +%D \endofshapebox +%D +%D \reshapebox{\FunnyCommand{\box\shapebox}} \flushshapebox +%D \stopbuffer +%D +%D \getbuffer +%D +%D \typebuffer +%D +%D This mechanism permits hyphenation and therefore gives +%D better results than the previously discussed macro +%D \type{\TreatFirstLine}. + +%D \macros +%D {TreatFirstCharacter} +%D +%D \startbuffer +%D \TreatFirstCharacter{\bf\color[green]} Just to be +%D \stopbuffer +%D +%D \getbuffer complete we also offer a very simple one +%D character alternative, that is not that hard to understand: + +\unexpanded\def\TreatFirstCharacter#1#2% command, character + {{#1{#2}}} + +%D A previous paragraph started with: +%D +%D \typebuffer + +%D \macros +%D {StackCharacters} +%D +%D The next hack deals with vertical stacking. + +\unexpanded\def\StackCharacters#1#2#3#4% sequence vsize vskip command + {\vbox #2 + {\forgetall + \baselineskip\zeropoint + \def\StackCharacter##1{#4{##1}\cr\noalign{#3}}% + \halign + {\hss##\hss&##\cr + \handletokens#1\with\StackCharacter\cr}}} + +%D \startbuffer +%D \StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand} +%D \stopbuffer +%D +%D Such a stack looks like: +%D +%D \startlinecorrection +%D \hbox to \hsize +%D {$\hss\bfd +%D \vcenter{\StackCharacters{TEX} {}{\vskip.2ex}{\FunnyCommand}}% +%D \hss +%D \vcenter{\StackCharacters{CON} {}{\vskip.2ex}{\FunnyCommand}} +%D \hss +%D \vcenter{\StackCharacters{TEXT} {}{\vskip.2ex}{\FunnyCommand}} +%D \hss +%D \vcenter{\StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}} +%D \hss$} +%D \stoplinecorrection +%D +%D and is typeset by saying: +%D +%D \typebuffer +%D +%D An alternative would have been +%D +%D \starttyping +%D \StackCharacters {CONTEXT} {to 5cm} {\vfill} {\FunnyCommand} +%D \stoptyping + +%D \macros +%D {processtokens} +%D +%D At a lower level horizontal and vertical manipulations are +%D already supported by: +%D +%D \starttyping +%D \processtokens {begin} {between} {end} {space} {text} +%D \stoptyping +%D +%D \startbuffer[a] +%D \processtokens +%D {\hbox to .5\hsize\bgroup} {\hfill} +%D {\egroup} {\space} {LET'S HAVE} +%D \stopbuffer +%D +%D \startbuffer[b] +%D \processtokens +%D {\vbox\bgroup\raggedcenter\hsize1em} +%D {\vskip.25ex} {\egroup} {\strut} {FUN} +%D \stopbuffer +%D +%D This macro is able to typeset: +%D +%D \leavevmode\hbox to \hsize +%D {$\hfil\hfil +%D \vcenter{\bf\getbuffer[a]}% +%D \hfil +%D \vcenter{\bfd\getbuffer[b]}% +%D \hfil\hfil$} +%D +%D which was specified as: +%D +%D \typebuffer[a] +%D \typebuffer[b] + +%D \macros +%D {NormalizeFontHeight, NormalizeFontWidth, +%D TheNormalizedFontSize} +%D +%D Next we introduce some font manipulation macros. When we +%D want to typeset some text spread in a well defined area, it +%D can be considered bad practice to manipulate character and +%D word spacing. In such situations the next few macros can be +%D of help: +%D +%D \starttyping +%D \NormalizeFontHeight \name {sample text} {height} {font} +%D \NormalizeFontWidth \name {sample text} {width} {font} +%D \stoptyping +%D +%D These are implemented using an auxilliary macro: + +\unexpanded\def\NormalizeFontHeight{\NormalizeFontSize\ht} +\unexpanded\def\NormalizeFontWidth {\NormalizeFontSize\wd} + +\unexpanded\def\NormalizeFontSize#1#2#3#4#5% + {\bgroup + \dimen0=#4% #4 can be \ht0 or so + \setbox0\hbox{\definedfont[#5 at 5pt]#3}% 10pt + \ifdim\wd0>\zeropoint + \dimen2=#10 % #1 is \wd or \ht + \dimen4=\maxdimen % 10000pt + \divide\dimen4 \dimen2 + \divide\dimen0 1638 % 1000 + \dimen0=\number\dimen4\dimen0 + \divide \dimen0 \plustwo % ... + \xdef\TheNormalizedFontSize{\the\dimen0}% + \else + \dimen0\bodyfontsize + \fi + \normalexpanded{\egroup\def\noexpand#2{\definedfont[#5 at \the\dimen0]}}} + +%D Afterwards, we have access to the calculated size by: + +\let\TheNormalizedFontSize\!!zeropoint + +%D Extra: + +\unexpanded\def\WidthSpanningText#1#2#3% text width font + {\hbox{\NormalizeFontWidth\temp{#1}{#2}{#3}\temp\the\everydefinedfont#1}} + +%D Consider for instance: +%D +%D \startbuffer +%D \NormalizeFontHeight \tmp {X} {2\baselineskip} {cmr10} +%D +%D {\tmp To Be Or Not To Be} +%D \stopbuffer +%D +%D \typebuffer +%D +%D This shows up as (we also show the baselines): +%D +%D {\showbaselines\getbuffer} +%D +%D The horizontal counterpart is: +%D +%D \startbuffer +%D \NormalizeFontWidth \tmp {This Line Fits} {\hsize} {cmr10} +%D +%D \hbox{\tmp This Line Fits} +%D \stopbuffer +%D +%D \typebuffer +%D +%D The calculated font scale is avaliable in the macro +%D \type{\NormalizedFontSize}. +%D +%D \startlinecorrection +%D \ruledhbox{\getbuffer} +%D \stoplinecorrection +%D +%D One can of course combine these macros with the ones +%D described earlier, like in: +%D +%D \starttyping +%D \NormalizeFontHeight {text} \DroppedFont {2\baselineskip} {cmbx12} +%D +%D \def\NicelyDroppedCaps +%D {\DroppedCaps +%D {\color[green]} +%D {\DroppedFont} +%D {2pt} +%D {\baselineskip} +%D {2}} +%D \stoptyping +%D +%D It's up to the reader to test this one. + +\unexpanded\def\FirstNCharacters#1#2% \FirstNCharacters{3}{fr{\"o}beln} + {\bgroup + \scratchcounter\zerocount + \def\docommand##1% + {\ifnum\scratchcounter=#1\else + ##1\relax % catches ##1 = \"e and alike + \advance\scratchcounter\plusone + \fi} + \handletokens#2\with\docommand + \egroup} + +%D \macros +%D {FittingText} +%D +%D First used in Pascal (demo-bbv): +%D +%D \startbuffer +%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1} +%D {\veryraggedright +%D \hangindent1em\hangafter1\relax +%D \begstrut \dorecurse{8}{Bram Marta }\unskip \endstrut}} +%D +%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1} +%D {\raggedleft\begstrut Bram\\Marta \unskip\endstrut}} +%D \stopbuffer +%D +%D \typebuffer +%D +%D \startlinecorrection +%D \getbuffer +%D \stoplinecorrection + +% #1 width #2 height #3 font #4 size #5 step #6 interlinie #7 text + +\unexpanded\def\FittingText#1#2#3#4#5#6#7% + {\bgroup + \forgetall + \dontcomplain + \setuptolerance[\v!verytolerant]% == \tolerance4500 + \hsize#1% + \def\\{\softbreak}% + \!!heighta#4% + \!!heightb#2% + \doloop + {\ifdim\!!heighta>\onepoint + \expanded{\definefont[\s!dummy][#3 at \the\!!heighta][\c!interlinespace=#6]}% + \getvalue\s!dummy + \setbox\scratchbox\vbox{#7\endgraf}% + \ifdim\ht\scratchbox>\!!heightb + \advance\!!heighta-#5% + \else + \beginshapebox + \unvcopy\scratchbox + \endshapebox + \global\dimen1\hsize + \reshapebox + {\setbox\shapebox\hbox{\unhbox\shapebox}% + \ifdim\wd\shapebox>\dimen1 + \global\dimen1\wd\shapebox + \fi}% + \ifdim\dimen1>\hsize + \advance\!!heighta-#5% + \else + \exitloop + \fi + \fi + \else + \exitloop + \fi}% + %\writestatus{\strippedcsname\FittingText}{height: \the\!!heighta}% + \unvbox\scratchbox + \egroup} + +% \font width gap font spec text + +\unexpanded\def\NormalizeFontWidthSpread#1#2#3#4#5#6% + {\global\setfalse\NFSpread + \scratchdimen#3% + \scratchdimen-.5\scratchdimen + \advance\scratchdimen#2\relax + \NormalizeFontWidth + #1% + {\def\+{\global\settrue\NFSpread\gobbleuntil\relax}% + \def\\{\gobbleuntil\relax}% newline + \setupspacing + #6\relax}% + {\scratchdimen}% + {#4}% + \ifconditional\NFSpread + % de gap valt in de binding + \else + \definefont[\strippedcsname#1][#4 #5]% + \fi} + +\unexpanded\def\SpreadGapText#1#2% + {{\def\+{\kern#1}#2}} + +\unexpanded\def\GapText#1#2#3#4#5% width distance font spec title + {\bgroup + \NormalizeFontWidthSpread\DummyFont{#1}{#2}{#3}{#4}{#5}% + \DummyFont\setupspacing\SpreadGapText{#2}{#5}\endgraf + \egroup} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-oldnum.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-oldnum.mkiv new file mode 100644 index 00000000000..382c56eb674 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-oldnum.mkiv @@ -0,0 +1,416 @@ +%D \module +%D [ file=m-oldnum, % was: supp-num +%D version=1998.05.15, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Numbers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% See end for transition to mkiv. + +\writestatus{loading}{ConTeXt Support Macros / Numbers} + +\unprotect + +%D \macros +%D {digits, setdigitmode, setdigitsign} +%D +%D Depending on the digit mode the command \type {\digits} +%D normalizes number patterns depending on the language set. +%D +%D \starttyping +%D This will never be a \digits{1.000.000} seller. +%D \stoptyping +%D +%D or +%D +%D \starttyping +%D I will never grow longer than \digits 1.86 \Meter. +%D \stoptyping +%D +%D The different modes are shown in: +%D +%D \startbuffer +%D \setdigitmode 1 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 2 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 3 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 4 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 5 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \setdigitmode 6 \digits 12.345,90 \digits 12.345.000 \digits 1,23 +%D \stopbuffer +%D +%D \typebuffer +% +% This is typset as: +% +% \startlines +% \getbuffer +% \stoplines +%D +%D The sign can be typeset as is or within the space of a +%D digit. +%D +%D \startbuffer +%D \setdigitsign 0 \digits +12.345,90 +%D \setdigitsign 1 \digits +12.345,90 +%D \setdigitsign 2 \digits +12.345,90 +%D \setdigitsign 3 \digits +12.345,90 +%D \stopbuffer +%D +%D \typebuffer +%D +% This is typset as: +% +% \startlines +% \getbuffer +% \stoplines + +\chardef\digitoutputmode=1 % 0..6 +\chardef\digitsignmode =0 % 0..3 + +\unexpanded\def\setdigitmode{\chardef\digitoutputmode} +\unexpanded\def\setdigitsign{\chardef\digitsignmode} + +%D The digit modes are: +%D +%D \startitemize[packed] +%D \item periods \& comma +%D \item commas \& period +%D \item thinmuskips \& comma +%D \item thinmuskips \& period +%D \item thickmuskips \& comma +%D \item thickmuskips \& period +%D \stopitemize + +\let\collecteddigits \empty \chardef\digitinputmode =1 +\let\saveddigits \empty \chardef\skipdigit =0 +\let\savedpowerdigits\empty \chardef\powerdigits =0 + +%D The first stage of the \type {\digit} macro takes care of +%D the grouped call, the other branch handles the fuzzy +%D delimited calls. + +\ifdefined\mbox \else \let\mbox\hbox \fi + +\unexpanded\def\digits + {\bgroup + \let~@% + \doifelsenextbgroup\dodigits{\doifelsenextchar\normalmathshift\domathdigits\grabdigit}} + +\def\dodigits#1% + {\grabdigit#1\relax} + +\def\domathdigits$#1$% + {\mbox{\grabdigit#1\relax}} % adding $ $ goes wrong in tabulate + +\def\grabdigit + {\futurelet\next\scandigit} + +%D Watch the test for \type {\nextobeyedline}, because the +%D endofline token can be \type {\def'd}, not \type {\let}'d, +%D we need to do an indirect test (see \type {verb-ini.tex}) +%D for details. (This probably needs an update.) + +\ifx\normalmathshift\undefined \let\normalmathshift=$ \fi + +\unexpanded\def\scandigit + {\ifx\next\blankspace + \let\next\handledigits + \else\ifx\next\nextobeyedline % the indirect one + \let\next\handledigits + \else\ifx\next\bgroup + \let\next\handledigits + \else\ifx\next\egroup + \let\next\handledigits + \else\ifx\next\normalmathshift + \let\next\handledigits + \else + \let\next\collectdigit + \fi\fi\fi\fi\fi + \next} + +%D We store the power||of||ten (to be signaled by \type {^}, +%D \type {e} or~\type {E}) in a seperate macro so that we can +%D typeset it in superscript. The space placeholders are +%D replaced by a \type {@}. + +\unexpanded\def\savedigit#1#2% + {\edef#1{#1\saveddigits#2}\let\saveddigits\empty} + +\unexpanded\def\collectdigit#1% + {\ifx#1~% + \savedigit\collecteddigits @% + \else\if#1_% tricky as can be several catcodes ... will become lua code anyway + \savedigit\collecteddigits @% + \else\if\noexpand#1\relax + \let\grabdigit\handledigits + \else\ifcase\powerdigits + \if#1E% + \chardef\powerdigits\plusone + \else\if#1e% + \chardef\powerdigits\plusone + \else\if#1^% + \chardef\powerdigits\plusone + \else + \savedigit\collecteddigits#1% + %\doifelsenumber{#1} + % {\savedigit\collecteddigits#1} + % {\def\saveddigits{#1}}% + \fi\fi\fi + \else + \savedigit\savedpowerdigits#1% + %\doifelsenumber{#1} + % {\savedigit\savedpowerdigits#1} + % {\def\saveddigits{#1}}% + \fi\fi\fi\fi + \grabdigit} + +\let\handlemathdigits\firstofoneargument +\let\handletextdigits\mathematics + +\unexpanded\def\handledigits + {%\ifcase\powerdigits + % \edef\collecteddigits{\collecteddigits\saveddigits}% + %\else + % \edef\savedpowerdigits{\savedpowerdigits\saveddigits}% + %\fi + \ifmmode + \handlemathdigits{\dohandledigits}% + \else + \dontleavehmode\hbox{\handletextdigits{\dohandledigits}}% + \fi + \egroup} + +%D Although we could do with one pass, a second pass for +%D handling the stored sequence is more readable. + +\ifnum\texengine=\luatexengine + + \def\dohandledigits + {\mathcode`\,="002C \mathcode`\.="002E % pretty hard coded + \expandafter\handletokens\collecteddigits\with\scandigits + \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi} + + \chardef\mathaxisfontid\zerocount + +\else + + \def\dohandledigits + {\mathcode`\,="013B \mathcode`\.="013A % pretty hard coded + \expandafter\handletokens\collecteddigits\with\scandigits + \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi} + + \chardef\mathaxisfontid\plustwo + +\fi + +\def\doscandigit#1% + {\ifcase\skipdigit\@EA\hbox\else\@EA\hphantom\fi\bgroup + \mathematics % brr, needed because of stored punctuation + {\ifnum\digitinputmode=#1\relax + \ifcase\digitoutputmode + \or .% + \or ,% + \or \mskip\thinmuskip + \or \mskip\thinmuskip + \or \mskip\thickmuskip + \or \mskip\thickmuskip + \fi + \else + \ifodd\digitoutputmode,\else.\fi + \fi}% + \egroup} + +%D The signs can be made smaller and sqeezed into the width +%D of a digit. Watch the \type {\mathaxisheight} trickery (this +%D font related register stored the math axis). + +% 0,= +% 0,== second = results in delta(00,=) +% 0,- is invalid, should be = +% 0,-- is invalid, should be == + +\unexpanded\def\digitzeroamount + {\digitsgn\zeroamount + \def\digitzeroamount + {\hphantom + {00\setbox\scratchbox\hbox{$\zeroamount$}% + \hskip-\wd\scratchbox}% + \let\digitzeroamount\empty}} + +\unexpanded\def\scandigits#1% + {\if#1.\digitsep1\else + \if#1,\digitsep2\else + \if#1@\digitnop \else + \if#1_\digitnop \else + \if#1/\digitsgn{\hphantom{+}}\chardef\skipdigit0\else + \if#1-\ifcase\skipdigit\digitsgn-\else + \box\digitsepbox\digitzeroamount \fi\chardef\skipdigit0\else + \if#1+\digitsgn+\chardef\skipdigit0\else + \if#1=\box\digitsepbox\digitzeroamount \chardef\skipdigit0\else + \if#1s\digitsgn{\hphantom{\positive}}\chardef\skipdigit0\else + \if#1p\digitsgn\positive\chardef\skipdigit0\else + \if#1m\digitsgn\negative\chardef\skipdigit0\else + \if#1n\digitsgn\negative\chardef\skipdigit0\else + \box\digitsepbox #1\chardef\skipdigit0\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +\newbox\digitsepbox \chardef\autodigitmode=1 + +\unexpanded\def\digitsep#1% + {\ifcase\autodigitmode + \doscandigit#1% + \else + \setbox\digitsepbox\hbox{\doscandigit#1}% + \fi + \chardef\skipdigit0\relax} + +% strange, does not work +% +% \def\digitnop +% {\hphantom{\box\digitsepbox}% +% \hphantom{0}\chardef\skipdigit1\relax} +% +% while this works + +\unexpanded\def\digitnop + {\hbox{\hphantom{\box\digitsepbox}}% + \hphantom{0}\chardef\skipdigit1\relax} + +% but this doesn't +% +% \def\digitnop +% {\hphantom{\box\digitsepbox0}% +% \chardef\skipdigit1\relax} + +\unexpanded\def\digitsgn#1% + {\ifcase\digitsignmode#1\else + \hbox + {\setbox\scratchbox\hbox{0}% + \scratchdimen\mathaxisheight\textfont\mathaxisfontid + \def\digitsgn##1##2% + {\advance\scratchdimen-\mathaxisheight##1\mathaxisfontid + \raise\scratchdimen + \hbox to \wd\scratchbox{\hss$##2#1$\hss}}% + \ifcase\digitsignmode\or + \digitsgn\textfont \textstyle \or + \digitsgn\scriptfont \scriptstyle \or + \digitsgn\scriptscriptfont\scriptscriptstyle\fi}% + \fi} + +\ifx\undefined\zeroamount \def\zeroamount{-} \fi +\ifx\undefined\positive \def\positive {+} \fi +\ifx\undefined\negative \def\negative {-} \fi + +%D The digit parser handles a bunch of special characters as +%D well as different formats. We strongly suggest you to use +%D the grouped call. +%D +%D \starttabulate[|l|l|l|] +%D \NC \type{.} \NC , . \NC comma or period \NC \NR +%D \NC \type{,} \NC , . \NC comma or period \NC \NR +%D \NC \type{@} \NC \NC invisible space \NC \NR +%D \NC \type{_} \NC \NC invisible space \NC \NR +%D \NC \type{/} \NC \NC invisible sign \NC \NR +%D \NC \type{-} \NC $-$ \NC minus sign \NC \NR +%D \NC \type{+} \NC $+$ \NC plus sign \NC \NR +%D \NC \type{s} \NC \NC invisible high sign \NC \NR +%D \NC \type{p} \NC $\positive$ \NC high plus sign \NC \NR +%D \NC \type{m} \NC $\negative$ \NC high minus sign \NC \NR +%D \NC \type{n} \NC $\negative$ \NC high minus (negative) sign \NC \NR +%D \NC \type{=} \NC $\zeroamount$ \NC zero padding \NC \NR +%D \stoptabulate +%D +%D These triggers are used in the following examples. +%D +%D \startbuffer +%D \digits 12 +%D \digits{~~~.~~~.~~~.68.712,34} +%D \digits ~~~.~~~.~~~.68.712,34 +%D \digits ___.___.111.68.712,34 +%D \digits 111.111.111.68.712,34 +%D \digits 12.345,90 +%D \digits 12.345.000 +%D \digits 12,34 +%D \digits{392.857.230.68.712,34} +%D {\digits1234} +%D \digits{1234} +%D \digits 1234\relax +%D $\digits 123.222,00$ +%D \digits 123.222,00 +%D \digits 123.222,== +%D \digits 123.222,00^10 +%D \digits 123.222,00e10 +%D \digits /123.222,00e-12 +%D \digits -123.222,00e-12 +%D \digits +123.222,00e-12 +%D \digits n123.222,00e-12 +%D \digits s123.222,00e-12 +%D \digits p123.222,00e-12 +%D \stopbuffer +%D +%D \typebuffer +% +% \startlines +% \getbuffer +% \stoplines + +%D \macros +%D {Digits} +%D +%D We also permit: + +\let\Digits\digits + +%D These macros are complicated by the fact that we also +%D have to support cases like: +%D +%D \starttyping +%D {\digits1234} +%D \digits{1234} +%D \digits 1234\whatever +%D $\digits 123.222,00$ +%D \digits 123.222,00. +%D \stoptyping +%D +%D The latter case shows us that trailing non digits are to +%D be passed untreated. +%D +%D Another interesting case is: +%D +%D \starttyping +%D \digits 123.222,00^10 +%D \stoptyping +%D +%D The separator is defined as: + +% \def\digitpowerseparator% +% {\cdot10} % {\times10} + +\def\digitpowerseparator + {\ifx\collecteddigits\empty\else\cdot\fi10} + +%D \macros +%D {digittemplate} +%D +%D Users can specify the way they enter those digits by saying +%D something like: +%D +%D \starttyping +%D \digittemplate 12.000.000,00 % \digittemplate ., +%D \stoptyping + +\unexpanded\def\digittemplate #1 % + {\chardef\digitinputmode\zerocount + \handletokens#1\with\scandigittemplate} + +\unexpanded\def\scandigittemplate#1% + {\if #1.\ifcase\digitinputmode\chardef\digitinputmode\plusone \fi% period + \else\if#1,\ifcase\digitinputmode\chardef\digitinputmode\plustwo \fi% comma + \fi\fi} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-pictex.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-pictex.mkiv new file mode 100644 index 00000000000..73aad3f57df --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-pictex.mkiv @@ -0,0 +1,46 @@ +%D \module +%D [ file=m-pictex, +%D version=1997.01.15, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PICTEX\ Loading Macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Just in case someone still uses \PICTEX: + +\ifdefined\beginpicture \else + + \ifdefined\grid \else + \let\normalgrid\grid + \fi + + \ifdefined\axis \else + \let\normalaxis\axis + \fi + + \ifdefined\fiverm \else + \font\fiverm=cmr5 + \fi + + \input prepictex.tex \relax + \input pictex.tex \relax + \input postpictex.tex \relax + + \ifdefined\normalgrid + \let\pictexgrid\grid + \let\grid\normalgrid + \fi + + \ifdefined\normalaxis + \let\pictexaxis\axis + \let\axis\normalaxis + \fi + +\fi + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-pipemode.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-pipemode.mkiv new file mode 100644 index 00000000000..e96394c431e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-pipemode.mkiv @@ -0,0 +1,7 @@ +% For Mojca: context --global m-pipemode.mkiv + +\disabledirectives[system.errorcontext] + +\starttext + +\let\stoptext\relax diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-pstricks.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-pstricks.lua new file mode 100644 index 00000000000..b151e313ac8 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-pstricks.lua @@ -0,0 +1,74 @@ +if not modules then modules = { } end modules ['m-pstricks'] = { + version = 1.001, + comment = "companion to m-pstricks.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- The following will be done when I need ps tricks figures +-- in large quantities: +-- +-- + hash graphics and only process them once +-- + save md5 checksums in tuc file +-- +-- It's no big deal but has a low priority. + +local format, lower, concat, gmatch = string.format, string.lower, table.concat, string.gmatch +local variables = interfaces.variables + +moduledata.pstricks = moduledata.pstricks or { } + +local report_pstricks = logs.reporter("pstricks") + +local template = [[ +\starttext + \pushcatcodetable + \setcatcodetable\texcatcodes + \usemodule[pstric] + %s + \popcatcodetable + \startTEXpage + \hbox\bgroup + \ignorespaces + %s + \removeunwantedspaces + \egroup + \obeydepth %% temp hack as we need to figure this out + \stopTEXpage +\stoptext +]] + +local loaded = { } +local graphics = 0 + +function moduledata.pstricks.usemodule(names) + for name in gmatch(names,"([^%s,]+)") do + loaded[#loaded+1] = format([[\readfile{%s}{}{}]],name) + end +end + +function moduledata.pstricks.process(n) + graphics = graphics + 1 + local name = format("%s-pstricks-%04i",tex.jobname,graphics) + local data = buffers.collectcontent("def-"..n) + local tmpfile = name .. ".tmp" + local epsfile = name .. ".ps" + local pdffile = name .. ".pdf" + local loaded = concat(loaded,"\n") + os.remove(epsfile) + os.remove(pdffile) + io.savedata(tmpfile,format(template,loaded,data)) + os.execute(format("mtxrun --script texexec %s --once --dvips",tmpfile)) + if lfs.isfile(epsfile) then + os.execute(format("ps2pdf %s %s",epsfile,pdffile)) + -- todo: direct call but not now + if lfs.isfile(pdffile) then + context.externalfigure( { pdffile }, { object = variables.no } ) + else + report_pstricks("run failed, no pdf file") + end + else + report_pstricks("run failed, no ps file") + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-pstricks.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-pstricks.mkiv new file mode 100644 index 00000000000..421607aafe9 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-pstricks.mkiv @@ -0,0 +1,65 @@ +%D \module +%D [ file=m-pstricks, +%D version=2010.03.14, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PSTRICKS\ Connections, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\registerctxluafile{m-pstricks}{} + +\unprotect + +% best we can make a special colors module +% +% \let\@unused\plussixteen +% \let\alloc@ \gobblefivearguments +% +% \def\loadpstrickscolors#1% +% {\pushmacro\dodefinecolor +% \pushmacro\dodefinepalet +% \pushmacro\dodefinecolorgroup +% \def\dodefinecolor[##1][##2]% +% {\doifassignmentelse{##2} +% {\getparameters[pstricks][r=0,g=0,b=0,##2]% +% \expanded{\newrgbcolor{##1}{{\pstricksr} {\pstricksg} {\pstricksb}}}}% +% {}}% +% \def\dodefinepalet [##1][##2]{}% +% \def\dodefinecolorgroup[##1][##2][##3]{}% +% \writestatus{pstricks}{loading colors from #1}% +% \input #1 \relax +% \popmacro\dodefinecolorgroup +% \popmacro\dodefinepalet +% \popmacro\dodefinecolor} +% +% \input multido \relax +% \input pstricks \relax +% \input pst-plot \relax +% +% \loadpstrickscolors{colo-rgb} + +\definebuffer[PSTRICKS] + +\unexpanded\def\processPSTRICKS {\ctxlua{moduledata.pstricks.process(\thebuffernumber{PSTRICKS})}} +\unexpanded\def\usePSTRICKSmodule[#1]{\ctxlua{moduledata.pstricks.usemodule("#1")}} +\unexpanded\def\setPSTRICKS #1{\setbuffer[def-\thebuffernumber{PSTRICKS}]#1\endbuffer} + +\let\stopPSTRICKS\processPSTRICKS + +%D \starttyping +%D \usemodule[pstricks] +%D \usePSTRICKSmodule[pst-barcode] +%D +%D \startPSTRICKS +%D \pspicture(-4mm,-1mm)(38mm,26mm) +%D \psbarcode{9781860742712}{includetext guardwhitespace}{ean13}% +%D \endpspicture +%D \stopPSTRICKS +%D \stoptyping + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-punk.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-punk.mkiv new file mode 100644 index 00000000000..331e90d2e99 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-punk.mkiv @@ -0,0 +1,257 @@ +%D \module +%D [ file=m-punk, +%D version=2008.04.15, +%D title=\CONTEXT\ Modules, +%D subtitle=Punk Support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\ifx\luaversion\undefined \endinput \fi + +% At some point the font generation code will move into the +% ConTeXt MkIV kernel. + +\startluacode +local concat = table.concat +local chardata = characters.data +local fontdata = fonts.hashes.identifiers + +fonts.mp = fonts.mp or { } + +fonts.mp.version = fonts.mp.version or 1.15 +fonts.mp.inline = true +fonts.mp.cache = containers.define("fonts", "mp", fonts.mp.version, true) + +metapost.characters = metapost.characters or { } + +-- todo: use table share as in otf + +local characters, descriptions = { }, { } +local factor, l, n, w, h, d, total, variants = 100, { }, 0, 0, 0, 0, 0, 0, true + +-- A next version of mplib will provide the tfm font information which +-- gives better glyph dimensions, plus additional kerning information. + +local flusher = { + startfigure = function(chrnum,llx,lly,urx,ury) + l, n = { }, chrnum + w, h, d = urx - llx, ury, -lly + total = total + 1 + inline = fonts.mp.inline + end, + flushfigure = function(t) + for i=1, #t do + l[#l+1] = t[i] + end + end, + stopfigure = function() + local cd = chardata[n] + if inline then + descriptions[n] = { + -- unicode = n, + name = cd and cd.adobename, + width = w*100, + height = h*100, + depth = d*100, + boundingbox = { 0, -d, w, h }, + } + characters[n] = { + commands = { -- todo: xforms, should happen in backend + { "special", "pdf: " .. concat(l," ") }, + } + } + else + descriptions[n] = { + -- unicode = n, + name = cd and cd.adobename, + width = w*100, + height = h*100, + depth = d*100, + boundingbox = { 0, -d, w, h }, + } + characters[n] = { + commands = { + { "image", { stream = concat(l," "), bbox = { 0, -d*65536, w*65536, h*65536 } } }, + } + } + end + end +} + +metapost.characters.instances = metapost.characters.instances or 10 + +function metapost.characters.process(mpxformat, name, instances, scalefactor) + statistics.starttiming(metapost.characters) + scalefactor = scalefactor or 1 + instances = instances or metapost.characters.instances or 10 + local fontname = file.removesuffix(file.basename(name)) + local hash = file.robustname(string.format("%s %05i %03i", fontname, scalefactor*1000, instances)) + local lists = containers.read(fonts.mp.cache, hash) + if not lists then + statistics.starttiming(flusher) + -- we can use a format per font + local data = io.loaddata(resolvers.findfile(name)) + metapost.reset(mpxformat) + metapost.setoutercolor(2) -- no outer color and no reset either + lists = { } + for i=1,instances do + characters = { } + descriptions = { } + metapost.process( + mpxformat, + { + "randomseed := " .. i*10 .. ";", + "scale_factor := " .. scalefactor .. " ;", + data + }, + false, + flusher, + false, + false, + "all" + ) + lists[i] = { + characters = characters, + descriptions = descriptions, + parameters = { + designsize = 655360, + slant = 0, + space = 333 * scalefactor, + space_stretch = 166.5 * scalefactor, + space_shrink = 111 * scalefactor, + x_height = 431 * scalefactor, + quad = 1000 * scalefactor, + extra_space = 0, + }, + properties = { + name = string.format("%s-%03i",hash,i), + virtualized = true, + spacer = "space", + } + } + end + metapost.reset(mpxformat) -- saves memory + lists = containers.write(fonts.mp.cache, hash, lists) + statistics.stoptiming(flusher) + end + variants = variants + #lists + statistics.stoptiming(metapost.characters) + return lists +end + +function fonts.handlers.vf.combiner.commands.metafont(g,v) + local size = g.specification.size + local data = metapost.characters.process(v[2],v[3],v[4],size/655360) + local list, t = { }, { } + for d=1,#data do + t = data[d] + t = fonts.constructors.scale(t, -1000) + local id = font.nextid() + t.fonts = { { id = id } } + fontdata[id] = t + fonts.handlers.vf.helpers.composecharacters(t) + list[d] = font.define(t) + end + for k, v in next, t do + g[k] = v -- kind of replace, when not present, make nil + end + g.properties.virtualized = true + g.variants = list +end + +fonts.definers.methods.install( "punk", { + { "metafont", "mfplain", "punkfont.mp", 10 }, +} ) +fonts.definers.methods.install( "punkbold", { + { "metafont", "mfplain", "punkfont-bold.mp", 10 }, +} ) +fonts.definers.methods.install( "punkslanted", { + { "metafont", "mfplain", "punkfont-slanted.mp", 10 }, +} ) +fonts.definers.methods.install( "punkboldslanted", { + { "metafont", "mfplain", "punkfont-boldslanted.mp", 10 }, +} ) + +-- typesetters.cases.register("RandomPunk", function(current) +-- local used = fontdata[current].variants +-- if used then +-- local f = math.random(1,#used) +-- current.font = used[f] +-- return current, true +-- else +-- return current, false +-- end +-- end) + +local getfont = nodes.nuts.getfont +local setfield = nodes.nuts.setfield +local random = math.random + +typesetters.cases.register("RandomPunk", function(start) + local used = fontdata[getfont(start)].variants + if used then + local f = random(1,#used) + setfield(start,"font",used[f]) + return start, true + else + return start, false + end +end) + +metapost.characters.flusher = flusher + +statistics.register("metapost font generation", function() + local time = statistics.elapsedtime(flusher) + if total > 0 then + return string.format("%i glyphs, %.3f seconds runtime, %i glyphs/second", total, time, total/time) + else + return string.format("%i glyphs, %.3f seconds runtime", total, time) + end +end) + +statistics.register("metapost font loading",function() + local time = statistics.elapsedtime(metapost.characters) + if variants > 0 then + return string.format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time) + else + return string.format("%.3f seconds, %i instances", time, variants) + end +end) +\stopluacode + +\unexpanded\def\EnableRandomPunk {\setcharactercasing[RandomPunk]} +\unexpanded\def\RandomPunk {\groupedcommand\EnableRandomPunk\donothing} +\unexpanded\def\StartRandomPunk {\begingroup\EnableRandomPunk} +\unexpanded\def\StopRandomPunk {\endgroup} + +\starttypescript [serif] [punk] + \definefontsynonym [Serif] [demo@punk] + \definefontsynonym [SerifBold] [demobold@punkbold] + \definefontsynonym [SerifSlanted] [demoslanted@punkslanted] + \definefontsynonym [SerifBoldSlanted] [demoboldslanted@punkboldslanted] + \definefontsynonym [SerifItalic] [SerifSlanted] + \definefontsynonym [SerifBoldItalic] [SerifBoldSlanted] +\stoptypescript + +\starttypescript [punk] + \definetypeface [punk] [rm] [serif] [punk] [default] +\stoptypescript + +\endinput + +\usetypescript[punk] + +\setupbodyfont[punk,14pt] + +\starttext + \definedfont[demo@punk at 10pt]hello world\par + \definedfont[demo@punk at 12pt]hello world\par + \definedfont[demo@punk at 16pt]hello world\par + \definedfont[demo@punk at 20pt]hello world\par +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-scite.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-scite.mkiv new file mode 100644 index 00000000000..71f31becef3 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-scite.mkiv @@ -0,0 +1,289 @@ +%D \module +%D [ file=m-scite, +%D version=2014.04.28, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\SCITE\ lexers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% We can simplify the scite lexers, as long as we're able to return the +% lexed result table and provide alexer module with the functions that +% the lexer expects (so I need to decipher the cxx file). +% +% lexer._TOKENSTYLES : table +% lexer._CHILDREN : flag +% lexer._EXTRASTYLES : table +% lexer._GRAMMAR : flag +% +% lexers.load : function +% lexers.lex : function +% +% And some properties that map styles onto scintilla styling. I get the +% impression that we end up with something simpler, a hybrid between the +% scite lexing and the current context way, so we get an intermediate +% step, with some penalty for context, but at least I don't have to +% maintain two sets (three sets as we also have a line based series). + +% TODO: as these files are in tds we can locate them and set the lexer root +% to that one. Currently we're on: we're on context/documents. + +% TODO: tab + +% This is an experiment: eventually we need to hook it into the verbatim code +% and deal with widow lines and so. + +\startluacode + +-- todo: merge with collapse +-- todo: prehash whitespaces + +-- todo: hook into the pretty print code +-- todo: a simple catcode regime with only \ { } + +local gsub, sub, find = string.gsub, string.sub, string.find +local concat = table.concat +local formatters = string.formatters +local lpegmatch = lpeg.match +local setmetatableindex = table.setmetatableindex + +local scite = require("util-sci") +buffers.scite = scite + +-- context output: + +local f_def_color = formatters["\\definecolor[slxc%s][h=%s%s%s]%%"] +local f_fore_none = formatters["\\def\\slx%s#1{{\\slxc%s#1}}%%"] +local f_fore_bold = formatters["\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"] +local f_none_bold = formatters["\\def\\slx%s#1{{\\bf#1}}%%"] +local f_none_none = formatters["\\def\\slx%s#1{{#1}}%%"] +local f_texstyled = formatters["\\slx%s{%s}"] + +local f_mapping = [[ +\let\string\slxL\string\letterleftbrace +\let\string\slxR\string\letterrightbrace +\let\string\slxM\string\letterdollar +\let\string\slxV\string\letterbar +\let\string\slxU\string\letterhat +\let\string\slxD\string\letterunderscore +\let\string\slxH\string\letterhash +\let\string\slxB\string\letterbackslash +\let\string\slxP\string\letterpercent +\let\string\slxT\string\lettertilde +\let\string\slxS\string\fixedspace +%]] + +local replacer = lpeg.replacer { + ["{"] = "\\slxL ", + ["}"] = "\\slxR ", + ["$"] = "\\slxM ", + ["^"] = "\\slxU ", + ["_"] = "\\slxD ", + ["|"] = "\\slxV ", + ["#"] = "\\slxH ", + ["\\"] = "\\slxB ", + ["%"] = "\\slxP ", + ["~"] = "\\slxT ", + [" "] = "\\slxS ", +} + +local colors = nil + +local function exportcolors() + if not colors then + scite.loadscitelexer() + local function black(f) + return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00') + end + local result, r = { f_mapping }, 1 + for k, v in table.sortedhash(lexer.context.styles) do + local fore = v.fore + if fore and not black(fore) then + r = r + 1 + result[r] = f_def_color(k,fore[1],fore[2],fore[3]) + end + end + r = r + 1 + result[r] = "%" + for k, v in table.sortedhash(lexer.context.styles) do + local bold = v.bold + local fore = v.fore + r = r + 1 + if fore and not black(fore) then + if bold then + result[r] = f_fore_bold(k,k) + else + result[r] = f_fore_none(k,k) + end + else + if bold then + result[r] = f_none_bold(k) + else + result[r] = f_none_none(k) + end + end + end + colors = concat(result,"\n") + end + return colors +end + +local function exportwhites() + return setmetatableindex(function(t,k) + local v = find(k,"white") and true or false + t[k] = v + return v + end) +end + +local function exportstyled(lexer,text) + local result = lexer.lex(lexer,text,0) + local start = 1 + local whites = exportwhites() + local buffer = { } + for i=1,#result,2 do + local style = result[i] + local position = result[i+1] + local txt = sub(text,start,position-1) + txt = lpegmatch(replacer,txt) + if whites[style] then + buffer[#buffer+1] = txt + else + buffer[#buffer+1] = f_texstyled(style,txt) + end + start = position + end + buffer = concat(buffer) + return buffer +end + +function scite.installcommands() + context(exportcolors()) +end + +local function lexdata(data,lexname) + buffers.assign("lex",exportstyled(scite.loadedlexers[lexname],data or "")) +end + +scite.lexdata = lexdata + +function scite.lexbuffer(name,lexname) + lexdata(buffers.getcontent(name) or "",lexname or "tex") +end + +function scite.lexfile(filename,lexname) + lexdata(io.loaddata(filename) or "",lexname or file.suffix(filename)) +end + +-- html output + +\stopluacode + +% This is a preliminary interface. + +\unprotect + +\unexpanded\def\installscitecommands + {\ctxlua{buffers.scite.installcommands()}% + \let\installscitecommands\relax} + +\unexpanded\def\startscite + {\begingroup + \dosingleempty\buff_scite_start} + +\def\buff_scite_start[#1]% + {\edef\currentscitelexer{#1}% + \dostartbuffer[@scite@][startscite][stopscite]} + +\unexpanded\def\stopscite + {\scitebuffer[\ifx\currentscitelexer\empty tex\else\currentscitelexer\fi][@scite@]% + \endgroup} + +\unexpanded\def\scitefile + {\dosingleargument\module_scite_file} + +\unexpanded\def\module_scite_file[#1]% + {\start + \ctxlua{buffers.scite.lexfile("#1")}% + \installscitecommands + \tt + \dontcomplain + \startcontextcode + \startlines + \getbuffer[lex]% + \stoplines + \stopcontextcode + \stop} + +\unexpanded\def\scitebuffer + {\dodoubleargument\module_scite_buffer} + +\unexpanded\def\module_scite_buffer[#1][#2]% + {\start + \ifsecondargument + \ctxlua{buffers.scite.lexbuffer("#2","#1")}% + \else + \ctxlua{buffers.scite.lexbuffer("#1","tex")}% + \fi + \installscitecommands + \tt + \dontcomplain + \setcatcodetable\ctxcatcodes % needed in xml + \startlines + \getbuffer[lex]% + \stoplines + \stop} + +\protect + +\continueifinputfile{m-scite.mkiv} + +\setupbodyfont[dejavu,8pt] + +\setuplayout + [width=middle, + height=middle, + header=1cm, + footer=1cm, + topspace=1cm, + bottomspace=1cm, + backspace=1cm] + +\startbuffer[demo] +\startsubsubject[title={oeps}] + +\startMPcode + draw fullcircle + scaled 2cm + withpen pencircle scaled 1mm + withcolor .5green; + draw textext ( + lua ( + "local function f(s) return string.upper(s) end mp.quoted(f('foo'))" + ) + ) withcolor .5red ; +\stopMPcode + +\startluacode + context("foo") +\stopluacode + +\stopsubsubject +\stopbuffer + +\starttext + +% \scitefile[../lexers/scite-context-lexer.lua] \page +% \scitefile[t:/manuals/about/about-metafun.tex] \page +% \scitefile[t:/sources/strc-sec.mkiv] \page +% \scitefile[e:/tmp/mp.w] \page +% \scitefile[t:/manuals/hybrid/tugboat.bib] \page +\scitefile[e:/tmp/test.bib] \page + +% \getbuffer[demo] \scitebuffer[demo] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-spreadsheet.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-spreadsheet.lua new file mode 100644 index 00000000000..1b3c5cb34f5 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-spreadsheet.lua @@ -0,0 +1,332 @@ +if not modules then modules = { } end modules ['m-spreadsheet'] = { + version = 1.001, + comment = "companion to m-spreadsheet.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local byte, format, gsub, find = string.byte, string.format, string.gsub, string.find +local R, P, S, C, V, Cs, Cc, Ct, Cg, Cf, Carg = lpeg.R, lpeg.P, lpeg.S, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Carg +local lpegmatch, patterns = lpeg.match, lpeg.patterns +local setmetatable, loadstring, next, tostring, tonumber,rawget = setmetatable, loadstring, next, tostring, tonumber, rawget +local formatters = string.formatters + +local context = context + +local splitthousands = utilities.parsers.splitthousands +local variables = interfaces.variables + +local v_yes = variables.yes + +moduledata = moduledata or { } + +local spreadsheets = { } +moduledata.spreadsheets = spreadsheets + +local data = { + -- nothing yet +} + +local settings = { + period = ".", + comma = ",", +} + +spreadsheets.data = data +spreadsheets.settings = settings + +local defaultname = "default" +local stack = { } +local current = defaultname + +local d_mt ; d_mt = { + __index = function(t,k) + local v = { } + setmetatable(v,d_mt) + t[k] = v + return v + end, +} + +local s_mt ; s_mt = { + __index = function(t,k) + local v = settings[k] + t[k] = v + return v + end, +} + +function spreadsheets.setup(t) + for k, v in next, t do + settings[k] = v + end +end + +local function emptydata(name,settings) + local data = { } + local specifications = { } + local settings = settings or { } + setmetatable(data,d_mt) + setmetatable(specifications,d_mt) + setmetatable(settings,s_mt) + return { + name = name, + data = data, + maxcol = 0, + maxrow = 0, + settings = settings, + temp = { }, -- for local usage + specifications = specifications, + } +end + +function spreadsheets.reset(name) + if not name or name == "" then name = defaultname end + data[name] = emptydata(name,data[name] and data[name].settings) +end + +function spreadsheets.start(name,s) + if not name or name == "" then + name = defaultname + end + if not s then + s = { } + end + table.insert(stack,current) + current = name + if data[current] then + setmetatable(s,s_mt) + data[current].settings = s + else + data[current] = emptydata(name,s) + end +end + +function spreadsheets.stop() + current = table.remove(stack) +end + +spreadsheets.reset() + +local offset = byte("A") - 1 + +local function assign(s,n) + return formatters["moduledata.spreadsheets.data['%s'].data[%s]"](n,byte(s)-offset) +end + +function datacell(a,b,...) + local n = 0 + if b then + local t = { a, b, ... } + for i=1,#t do + n = n * (i-1) * 26 + byte(t[i]) - offset + end + else + n = byte(a) - offset + end + return formatters["dat[%s]"](n) +end + +local function checktemplate(s) + if find(s,"%",1,true) then + -- normal template + return s + elseif find(s,"@",1,true) then + -- tex specific template + return gsub(s,"@","%%") + else + -- tex specific quick template + return "%" .. s + end +end + +local quoted = Cs(patterns.unquoted) +local spaces = patterns.whitespace^0 +local cell = C(R("AZ"))^1 / datacell * (Cc("[") * (R("09")^1) * Cc("]") + #P(1)) + +-- A nasty aspect of lpeg: Cf ( spaces * Cc("") * { "start" ... this will create a table that will +-- be reused, so we accumulate! + +local pattern = Cf ( spaces * Ct("") * { "start", + start = V("value") + V("set") + V("format") + V("string") + V("code"), + value = Cg(P([[=]]) * spaces * Cc("kind") * Cc("value")) * V("code"), + set = Cg(P([[!]]) * spaces * Cc("kind") * Cc("set")) * V("code"), + format = Cg(P([[@]]) * spaces * Cc("kind") * Cc("format")) * spaces * Cg(Cc("template") * Cs(quoted/checktemplate)) * V("code"), + string = Cg(#S([["']]) * Cc("kind") * Cc("string")) * Cg(Cc("content") * quoted), + code = spaces * Cg(Cc("code") * Cs((cell + P(1))^0)), +}, rawset) + +local functions = { } +spreadsheets.functions = functions + +function functions._s_(row,col,c,f,t) + local r = 0 + if f and t then -- f..t + -- ok + elseif f then -- 1..f + f, t = 1, f + else + f, t = 1, row - 1 + end + for i=f,t do + local ci = c[i] + if type(ci) == "number" then + r = r + ci + end + end + return r +end + +functions.fmt = string.tformat + +local f_code = formatters [ [[ + local _m_ = moduledata.spreadsheets + local dat = _m_.data['%s'].data + local tmp = _m_.temp + local fnc = _m_.functions + local row = %s + local col = %s + function fnc.sum(...) return fnc._s_(row,col,...) end + local sum = fnc.sum + local fmt = fnc.fmt + return %s +]] ] + +-- to be considered: a weak cache + +local function propername(name) + if name ~= "" then + return name + elseif current ~= "" then + return current + else + return defaultname + end +end + +-- if name == "" then name = current if name == "" then name = defaultname end end + +local function execute(name,r,c,str) + if str ~= "" then + local d = data[name] + if c > d.maxcol then + d.maxcol = c + end + if r > d.maxrow then + d.maxrow = r + end + local specification = lpegmatch(pattern,str,1,name) + d.specifications[c][r] = specification + local kind = specification.kind + if kind == "string" then + return specification.content or "" + else + local code = specification.code + if code and code ~= "" then + code = f_code(name,r,c,code or "") + local result = loadstring(code) -- utilities.lua.strippedloadstring(code,true) -- when tracing + result = result and result() + if type(result) == "function" then + result = result() + end + if type(result) == "number" then + d.data[c][r] = result + end + if not result then + -- nothing + elseif kind == "set" then + -- no return + elseif kind == "format" then + return formatters[specification.template](result) + else + return result + end + end + end + end +end + +function spreadsheets.set(name,r,c,str) + name = propername(name) + execute(name,r,c,str) +end + +function spreadsheets.get(name,r,c,str) + name = propername(name) + local dname = data[name] + if not dname then + -- nothing + elseif not str or str == "" then + context(dname.data[c][r] or 0) + else + local result = execute(name,r,c,str) + if result then +-- if type(result) == "number" then +-- dname.data[c][r] = result +-- result = tostring(result) +-- end + local settings = dname.settings + local split = settings.split + local period = settings.period + local comma = settings.comma + if split == v_yes then + result = splitthousands(result) + end + if period == "" then period = nil end + if comma == "" then comma = nil end + result = gsub(result,".",{ ["."] = period, [","] = comma }) + context(result) + end + end +end + +function spreadsheets.doifelsecell(name,r,c) + name = propername(name) + local d = data[name] + local d = d and d.data + local r = d and rawget(d,r) + local c = r and rawget(r,c) + commands.doifelse(c) +end + +local function simplify(name) + name = propername(name) + local data = data[name] + if data then + data = data.data + local temp = { } + for k, v in next, data do + local t = { } + temp[k] = t + for kk, vv in next, v do + if type(vv) == "function" then + t[kk] = "<function>" + else + t[kk] = vv + end + end + end + return temp + end +end + +local function serialize(name) + local s = simplify(name) + if s then + return table.serialize(s,name) + else + return formatters["<unknown spreadsheet %a>"](name) + end +end + +spreadsheets.simplify = simplify +spreadsheets.serialize = serialize + +function spreadsheets.inspect(name) + inspect(serialize(name)) +end + +function spreadsheets.tocontext(name) + context.tocontext(simplify(name)) +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-spreadsheet.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-spreadsheet.mkiv new file mode 100644 index 00000000000..914a2b57a9e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-spreadsheet.mkiv @@ -0,0 +1,221 @@ +%D \module +%D [ file=m-spreadsheet, +%D version=2011.02.21, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Spreadsheets, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is an experimental follow up on discussion on the mailing list. + +\registerctxluafile{m-spreadsheet}{1.001} + +\unprotect + +% todo: get(...) set(..) ctx(...) + +\installcorenamespace{spreadsheet} + +\installcommandhandler \??spreadsheet {spreadsheet} \??spreadsheet + +\appendtoks + \ctxlua{moduledata.spreadsheets.setup{ % global ! + period = \!!bs\spreadsheetparameter\c!period\!!es, + comma = \!!bs\spreadsheetparameter\c!comma\!!es, + split = \!!bs\spreadsheetparameter\c!split\!!es, + }}% +\to \everysetupspreadsheet + +\setupspreadsheet + [%\c!comma=, + %\c!period=, + \c!split=\v!no] + +\unexpanded\def\resetspreadsheet + {\dosingleempty\module_spreadsheet_reset} + +\unexpanded\def\module_spreadsheet_reset[#1]% + {\ctxlua{moduledata.spreadsheets.reset("#1")}} + +\unexpanded\def\startspreadsheet + {\dosingleempty\module_spreadsheet_start} + +\unexpanded\def\module_spreadsheet_start[#1]% + {\pushmacro\currentspreadsheet + \edef\currentspreadsheet{#1}% + \checkspreadsheetparent + \edef\m_spreadsheet_period{\spreadsheetparameter\c!period}% + \edef\m_spreadsheet_comma {\spreadsheetparameter\c!comma}% + \ctxlua{moduledata.spreadsheets.start("#1", { + period = \!!bs\detokenize\expandafter{\m_spreadsheet_period}\!!es, + comma = \!!bs\detokenize\expandafter{\m_spreadsheet_comma}\!!es, + split = \!!bs\spreadsheetparameter\c!split\!!es, + })}} + +\unexpanded\def\stopspreadsheet + {\ctxlua{moduledata.spreadsheets.stop()}% + \popmacro\currentspreadsheet} + +\unexpanded\def\showspreadsheet + {\dosingleempty\module_spreadsheet_show} + +\unexpanded\def\module_spreadsheet_show[#1]% + {\ctxlua{moduledata.spreadsheets.tocontext("#1")}} + +\unexpanded\def\inspectspreadsheet + {\dosingleempty\module_spreadsheet_inspect} + +\unexpanded\def\module_spreadsheet_inspect[#1]% + {\ctxlua{moduledata.spreadsheets.inspect("#1")}} + +\unexpanded\def\setspreadsheet + {\dosingleempty\module_spreadsheet_set} + +\unexpanded\def\module_spreadsheet_set[#1]#2#3#4% + {\ctxlua{moduledata.spreadsheets.set("#1",\number#2,\number#3,"#4")}} + +\unexpanded\def\getspreadsheet + {\dosingleempty\module_spreadsheet_get} + +\unexpanded\def\module_spreadsheet_get[#1]#2#3#4% + {\ctxlua{moduledata.spreadsheets.get("#1",\number#2,\number#3,"#4")}} + +\unexpanded\def\doifelsespreadsheetcell + {\dosingleempty\module_spreadsheet_doifelse_cell} + +\let\doifspreadsheetcellelse\doifelsespreadsheetcell + +\unexpanded\def\module_spreadsheet_doifelse_cell[#1]#2#3% + {\ctxlua{moduledata.spreadsheets.doifelsecell("#1",\number#2,\number#3)}} + +\ifdefined\tblrow + + \def\TABLEsetspreadsheet#1{\ctxlua{moduledata.spreadsheets.set("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}} + \def\TABLEgetspreadsheet#1{\ctxlua{moduledata.spreadsheets.get("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}} + +\else + + \def\TABLEsetspreadsheet#1{\ctxlua{moduledata.spreadsheets.set("",\number\c_tabl_ntb_row+1,\number\c_tabl_ntb_col,\!!bs#1\!!es)}} + \def\TABLEgetspreadsheet#1{\ctxlua{moduledata.spreadsheets.get("",\number\c_tabl_ntb_row+1,\number\c_tabl_ntb_col,\!!bs#1\!!es)}} + +\fi + +\appendtoks + \module_spreadsheet_reset[\currentspreadsheet]% + \let\setspr\TABLEsetspreadsheet + \let\getspr\TABLEgetspreadsheet +\to \everyTABLEpass + +\unexpanded\def\startspreadsheettable % quick and dirty + {\dodoubleempty\module_spreadsheet_start_table} + +\unexpanded\def\module_spreadsheet_start_table[#1][#2]% + {\bgroup + \let\startrow \module_spreadsheet_row_start + \let\stoprow \module_spreadsheet_row_stop + \let\startcell\module_spreadsheet_cell_start + \let\stopcell \module_spreadsheet_cell_stop + \doifelseassignment{#1} + {\module_spreadsheet_start + \directsetup{spreadsheet:before:\currentspreadsheet}% + \bTABLE[\c!align=\v!flushright,#1]} + {\module_spreadsheet_start[#1]% + \directsetup{spreadsheet:before:\currentspreadsheet}% + \bTABLE[\c!align=\v!flushright,#2]}} + +\unexpanded\def\stopspreadsheettable + {\eTABLE + \directsetup{spreadsheet:after:\currentspreadsheet}% + \stopspreadsheet + \egroup} + +\unexpanded\def\module_spreadsheet_row_start{\bTR} +\unexpanded\def\module_spreadsheet_row_stop {\eTR} + +\unexpanded\def\module_spreadsheet_cell_start + {\doifelsenextoptional\module_spreadsheet_cell_start_yes\module_spreadsheet_cell_start_nop} + +\unexpanded\def\module_spreadsheet_cell_start_yes[#1]#2\stopcell + {\bTD[#1]\getspr{#2}\eTD} + +\unexpanded\def\module_spreadsheet_cell_start_nop#1\stopcell + {\bTD\getspr{#1}\eTD} + +\let\module_spreadsheet_cell_stop\relax + +\protect + +\continueifinputfile{m-spreadsheet.mkiv} + +\starttext + +\bTABLE[align=middle] + \bTR + \bTD \getspr{100} \eTD \bTD test \setspr{30} \eTD + \eTR + \bTR + \bTD \getspr{20} \eTD \bTD \getspr{4+3} \eTD + \eTR + \bTR + \bTD \getspr{A[1] + A[2]} \eTD + \bTD \getspr{B1 + B2} \eTD + \eTR + \bTR + \bTD[nx=2] \bf \getspr{(A[3] + B[3]) /100} \eTD + \eTR + \bTR + \bTD[nx=2] \bf \getspr{string.format("\letterpercent0.3f",(A[3] + B[3]) /100)} \eTD + \eTR + \bTR + \bTD[nx=2] \bf \getspr{fmt("@0.3f",(sum(A,1,2)) / 10)} \eTD + \eTR +\eTABLE + +\setupspreadsheet[mysheet] + +\startspreadsheet[mysheet] + +\bTABLE[align=middle] + \bTR + \bTD \getspr{100} \eTD \bTD test \setspr{30} \eTD + \eTR + \bTR + \bTD \getspr{20} \eTD \bTD \getspr{4+3.5} \eTD + \eTR + \bTR + \bTD \getspr{A[1] + A[2]} \eTD + \bTD \getspr{B[1] + B[2]} \eTD + \eTR + \bTR + \bTD[nx=2] \bf \getspr{A[3] + B[3]} \eTD + \eTR +\eTABLE + +\stopspreadsheet + +\blank + +\setupspreadsheet[test][period={{\bf\middlered .}},comma={{\bf\middlegreen ,}},split=yes] + +\startspreadsheettable[test] + \startrow + \startcell 123456.78 \stopcell + \startcell 1234567.89 \stopcell + \startcell A[1] + B[1] \stopcell + \stoprow +\stopspreadsheettable + +\blank + +% \showspreadsheet +% \showspreadsheet[mysheet] + +\doifelsespreadsheetcell[mysheet]{1}{2}{YES}{NOP} +\doifelsespreadsheetcell[myshoot]{1}{2}{YES}{NOP} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-sql.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-sql.mkiv new file mode 100644 index 00000000000..f1df2833a00 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-sql.mkiv @@ -0,0 +1,29 @@ +%D \module +%D [ file=m-sql, +%D version=2012.07.12, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=SQL, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[sql] + +\registerctxluafile{util-tpl}{} +\registerctxluafile{util-sql}{} + +\setupmodule + +\doifsomething {\currentmoduleparameter{method}}{ + \ctxlua{utilities.sql.setmethod("\currentmoduleparameter{method}")} +} + +\doifsomething {\currentmoduleparameter{server}} { + \ctxlua{utilities.sql.setserver("\currentmoduleparameter{server}")} +} + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-steps.lua b/Master/texmf-dist/tex/context/modules/mkiv/m-steps.lua new file mode 100644 index 00000000000..8eb4815506e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-steps.lua @@ -0,0 +1,226 @@ +if not modules then modules = { } end modules ['x-flow'] = { + version = 1.001, + comment = "companion to m-flow.mkvi", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- when we can resolve mpcolor at the lua end we will use metapost.graphic(....) directly + +moduledata.steps = moduledata.steps or { } + +local variables = interfaces.variables + +local trace_charts = false + +local defaults = { + chart = { + dx = 10*65436, + dy = 10*65436, + }, + cell = { + alternative = 1, + offset = 2*65436, + rulethickness = 65436, + framecolor = "blue", + backgroundcolor = "gray", + }, + text = { + alternative = 1, + offset = 2*65436, + distance = 4*65436, + rulethickness = 65436, + framecolor = "red", + backgroundcolor = "gray", + }, + line = { + alternative = 1, + rulethickness = 65436, + height = 30*65436, + distance = 10*65436, + offset = 5*65436, + color = "green", + }, +} + +-- todo : name (no name then direct) +-- maybe: includes +-- maybe: flush ranges + +local charts = { } +local steps = { } + +function commands.step_start_chart(name) + name = name or "" + steps = { } + charts[name] = { + steps = steps, + } +end + +function commands.step_stop_chart() +end + +function commands.step_make_chart(settings) + local chartsettings = settings.chart + if not chartsettings then + print("no chart") + return + end + local chartname = chartsettings.name + if not chartname then + print("no name given") + return + end + local chart = charts[chartname] + if not chart then + print("no such chart",chartname) + return + end + local steps = chart.steps or { } + -- + table.setmetatableindex(settings,defaults) + -- + if trace_charts then + inspect(steps) + end + -- + local textsettings = settings.text + local cellsettings = settings.cell + local linesettings = settings.line + -- + context.startMPcode() + context("if unknown context_cell : input mp-step.mpiv ; fi ;") + context("step_begin_chart ;") + -- + if chartsettings.alternative == variables.vertical then + context("chart_vertical := true ;") + end + -- + context("text_line_color := \\MPcolor{%s} ;", textsettings.framecolor) + context("text_line_width := %p ;", textsettings.rulethickness) + context("text_fill_color := \\MPcolor{%s} ;", textsettings.backgroundcolor) + context("text_offset := %p ;", textsettings.offset) + context("text_distance_set := %p ;", textsettings.distance) + -- + context("cell_line_color := \\MPcolor{%s} ;", cellsettings.framecolor) + context("cell_line_width := %p ;", cellsettings.rulethickness) + context("cell_fill_color := \\MPcolor{%s} ;", cellsettings.backgroundcolor) + context("cell_offset := %p ;", cellsettings.offset) + context("cell_distance_x := %p ;", cellsettings.dx) + context("cell_distance_y := %p ;", cellsettings.dy) + -- + context("line_line_color := \\MPcolor{%s} ;", linesettings.color) + context("line_line_width := %p ;", linesettings.rulethickness) + context("line_distance := %p ;", linesettings.distance) + context("line_offset := %p ;", linesettings.offset) + -- + for i=1,#steps do + local step = steps[i] + context("step_begin_cell ;") + if step.cell_top ~= "" then + context('step_cell_top("%s") ;',string.strip(step.cell_top)) + end + if step.cell_bot ~= "" then + context('step_cell_bot("%s") ;',string.strip(step.cell_bot)) + end + if step.text_top ~= "" then + context('step_text_top("%s") ;',string.strip(step.text_top)) + end + if step.text_mid ~= "" then + context('step_text_mid("%s") ;',string.strip(step.text_mid)) + end + if step.text_bot ~= "" then + context('step_text_bot("%s") ;',string.strip(step.text_bot)) + end + context("step_end_cell ;") + end + -- + context("step_end_chart ;") + context.stopMPcode() +end + +function commands.step_cells(top,bot) + steps[#steps+1] = { + cell_top = top or "", + cell_bot = bot or "", + text_top = "", + text_mid = "", + text_bot = "", + } +end + +function commands.step_texts(top,bot) + if #steps > 0 then + steps[#steps].text_top = top or "" + steps[#steps].text_bot = bot or "" + end +end + +function commands.step_cell(top) + steps[#steps+1] = { + cell_top = top or "", + cell_bot = "", + text_top = "", + text_mid = "", + text_bot = "", + } +end + +function commands.step_text(top) + if #steps > 0 then + steps[#steps].text_top = top or "" + end +end + +function commands.step_textset(left,middle,right) + if #steps > 0 then + steps[#steps].text_top = left or "" + steps[#steps].text_mid = middle or "" + steps[#steps].text_bot = right or "" + end +end + +function commands.step_start_cell() + steps[#steps+1] = { + cell_top = "", + cell_bot = "", + text_top = "", + text_mid = "", + text_bot = "", + } +end + +function commands.step_stop_cell() +end + +function commands.step_text_top(str) + if #steps > 0 then + steps[#steps].text_top = str or "" + end +end + +function commands.step_text_mid(str) + if #steps > 0 then + steps[#steps].text_mid = str or "" + end +end + +function commands.step_text_bot(str) + if #steps > 0 then + steps[#steps].text_bot = str or "" + end +end + +function commands.step_cell_top(str) + if #steps > 0 then + steps[#steps].cell_top = str or "" + end +end + +function commands.step_cell_bot(str) + if #steps > 0 then + steps[#steps].cell_bot = str or "" + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-steps.mkvi b/Master/texmf-dist/tex/context/modules/mkiv/m-steps.mkvi new file mode 100644 index 00000000000..c9c5a063620 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-steps.mkvi @@ -0,0 +1,382 @@ +%D \module +%D [ file=m-steps, +%D version=2011.10.07, % 2001.05.28, +%D title=\CONTEXT\ Modules, +%D subtitle=Step Charts \& Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% multiple texts? + +\registerctxluafile{m-steps}{} + +\unprotect + +\installcorenamespace {stepcharts} +\installcorenamespace {steptables} +\installcorenamespace {stepcells} +\installcorenamespace {steptexts} +\installcorenamespace {steplines} + +\installsimplecommandhandler \??stepcharts {STEPchart} \??stepcharts +\installsimplecommandhandler \??steptables {STEPtable} \??steptables +\installsimplecommandhandler \??stepcells {STEPcell} \??stepcells +\installsimplecommandhandler \??steptexts {STEPtext} \??steptexts +\installsimplecommandhandler \??steplines {STEPline} \??steplines + +\let\setupSTEPcharts\setupSTEPchart +\let\setupSTEPtables\setupSTEPtable +\let\setupSTEPcells \setupSTEPcell +\let\setupSTEPtexts \setupSTEPtext +\let\setupSTEPlines \setupSTEPline + +% numeric text_text_distance ; text_text_distance := 20pt ; +% numeric step_distance ; step_distance := 20pt ; + +\setupSTEPcharts + [\c!alternative=\v!horizontal, + \c!before=\blank, + \c!after=\blank] +% \c!offset=.15\bodyfontsize +% \c!height=2ex + +% \setupSTEPtables +% [\c!before=\blank, +% \c!after=\blank, +% \c!distance=.25em, +% \c!voffset=1ex, +% \c!method=1, +% \c!width=4em, +% \c!offset=.15\bodyfontsize] + +\setupSTEPcells + [\c!alternative=1, % TODO +% \c!style=, +% \c!color=, + \c!dx=\bodyfontsize, + \c!dy=\bodyfontsize, + \c!background=\v!color, + \c!backgroundcolor=STEPbackgroundcolor, + \c!rulethickness=.1\bodyfontsize, + \c!framecolor=STEPframecolor, + \c!offset=.25\bodyfontsize] + +\setupSTEPtexts + [\c!alternative=1, % TODO +% \c!style=\v!smallbodyfont, +% \c!color=, + \c!background=\v!color, + \c!backgroundcolor=STEPbackgroundcolor, + \c!rulethickness=.1\bodyfontsize, + \c!framecolor=STEPframecolor, + \c!distance=.5\bodyfontsize, + \c!offset=.25\bodyfontsize] + +\setupSTEPlines + [\c!alternative=1, % TODO + \c!rulethickness=.15\bodyfontsize, + \c!height=3\bodyfontsize, + \c!distance=.5\bodyfontsize, + \c!offset=.25\bodyfontsize, + \c!color=STEPlinecolor] + +\definecolor [STEPlinecolor] [s=.5] +\definecolor [STEPframecolor] [s=.7] +\definecolor [STEPbackgroundcolor] [s=.9] + +\newtoks\everySTEPchart + +\unexpanded\def\startSTEPchart + {\begingroup + \dodoubleempty\module_steps_start_chart} + +\def\module_steps_start_chart[#name][#settings]% + {\startnointerference + \iffirstargument + \doifelseassignment{#name} + {\let\currentSTEPchart\empty + \xdef\module_steps_flush_chart{\module_steps_chart[][#name]}} + {\edef\currentSTEPchart{#name}% + \glet\module_steps_flush_chart\relax}% settings are not stored + \else + \let\currentSTEPchart\empty + \gdef\module_steps_flush_chart{\module_steps_chart[][]}% + \fi + \the\everySTEPchart + \ctxcommand{step_start_chart("\currentSTEPchart")}} + +\unexpanded\def\stopSTEPchart + {\ctxcommand{step_stop_chart()}% + \stopnointerference + \module_steps_flush_chart + \endgroup} + +\unexpanded\def\startSTEPtable + {\begingroup + \setupSTEPchart[\c!alternative=\v!vertical]% + \dodoubleempty\module_steps_start_chart} + +\let\stopSTEPtable\stopSTEPchart + +\let\module_steps_flush_chart\relax + +\unexpanded\def\STEPchart + {\dodoubleempty\module_steps_chart} + +\unexpanded\def\module_steps_chart[#name][#settings]% + {\begingroup + \setupSTEPchart[#settings]% + \ifinsidefloat + \makeSTEPchart[#name]% + \else + \STEPchartparameter\c!before + \startbaselinecorrection + \setlocalhsize + \makeSTEPchart[#name]% + \stopbaselinecorrection + \STEPchartparameter\c!after + \fi + \endgroup} + +\unexpanded\def\makeSTEPchart[#name]% + {\ctxcommand{step_make_chart { + chart = { + name = "#name", + alternative = "\STEPchartparameter\c!alternative", + }, + cell = { + alternative = "\STEPcellparameter\c!alternative", % TODO: shapes + offset = \number\dimexpr\STEPcellparameter\c!offset, + rulethickness = \number\dimexpr\STEPcellparameter\c!rulethickness, + framecolor = "\STEPcellparameter\c!framecolor", + backgroundcolor = "\STEPcellparameter\c!backgroundcolor", + dx = \number\dimexpr\STEPcellparameter\c!dx, + dy = \number\dimexpr\STEPcellparameter\c!dy, + }, + text = { + alternative = "\STEPtextparameter\c!alternative", % TODO: shapes + offset = \number\dimexpr\STEPtextparameter\c!offset, + distance = \number\dimexpr\STEPtextparameter\c!distance, + rulethickness = \number\dimexpr\STEPtextparameter\c!rulethickness, + framecolor = "\STEPtextparameter\c!framecolor", + backgroundcolor = "\STEPtextparameter\c!backgroundcolor", + }, + line = { + alternative = "\STEPlineparameter\c!alternative", % TODO: dash, arrow + rulethickness = \number\dimexpr\STEPlineparameter\c!rulethickness, + height = \number\dimexpr\STEPlineparameter\c!height, + distance = \number\dimexpr\STEPlineparameter\c!distance, + offset = \number\dimexpr\STEPlineparameter\c!offset, + color = "\STEPlineparameter\c!color", + }, + }}} + +\unexpanded\def\startSTEPcell + {\ctxcommand{step_start_cell()}} + +\unexpanded\def\stopSTEPcell + {\ctxcommand{step_stop_cell()}} + +\unexpanded\def\module_steps_cells#top#bot% + {\ctxcommand{step_cells(\!!bs\detokenize{#top}\!!es,\!!bs\detokenize{#bot}\!!es)}} + +\unexpanded\def\module_steps_texts#top#bot% + {\ctxcommand{step_texts(\!!bs\detokenize{#top}\!!es,\!!bs\detokenize{#bot}\!!es)}} + +\unexpanded\def\module_steps_cell#str% + {\ctxcommand{step_cell(\!!bs\detokenize{#str}\!!es)}} + +\unexpanded\def\module_steps_text#str% + {\ctxcommand{step_text(\!!bs\detokenize{#str}\!!es)}} + +\unexpanded\def\module_steps_textset#left#middle#right% + {\ctxcommand{step_textset(\!!bs\detokenize{#left}\!!es,\!!bs\detokenize{#middle}\!!es,\!!bs\detokenize{#right}\!!es)}} + +\unexpanded\def\module_steps_toptext#top% + {\ctxcommand{step_text_top(\!!bs\detokenize{#top}\!!es)}} + +\unexpanded\def\module_steps_bottext#bot% + {\ctxcommand{step_text_bot(\!!bs\detokenize{#bot}\!!es)}} + +\unexpanded\def\module_steps_topcell#top% + {\ctxcommand{step_cell_top(\!!bs\detokenize{#top}\!!es)}} + +\unexpanded\def\module_steps_botcell#bot% + {\ctxcommand{step_cell_bot(\!!bs\detokenize{#bot}\!!es)}} + +\appendtoks + \let\cells \module_steps_cells + \let\texts \module_steps_texts + \let\cell \module_steps_cell + \let\text \module_steps_text + \let\textset\module_steps_textset + \let\toptext\module_steps_toptext + \let\bottext\module_steps_bottext + \let\topcell\module_steps_topcell + \let\botcell\module_steps_botcell +\to \everySTEPchart + +% todo: mapping can be done in lua + +\startxmlsetups xml:step:define + \xmlsetsetup{#1} {stepchart|steptable} {xml:step:*} +\stopxmlsetups + +\xmlregistersetup{xml:step:define} + +\startxmlsetups xml:step:stepchart + \startSTEPchart + \xmlfilter{#1}{/(cells|texts|stepcell|cell|text)/command(xml:step:*)} + \stopSTEPchart +\stopxmlsetups + +\startxmlsetups xml:step:steptable + \startSTEPtable + \xmlfilter{#1}{/(cells|texts|stepcell|cell|text)/command(xml:step:*)} + \stopSTEPtable +\stopxmlsetups + +\startxmlsetups xml:step:cells + \cells {\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} +\stopxmlsetups + +\startxmlsetups xml:step:texts + \texts {\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} +\stopxmlsetups + +\startxmlsetups xml:step:stepcell + \cells {\xmltext{#1}{/topcell}} {\xmltext{#1}{/botcell}} + \texts {\xmltext{#1}{/toptext}} {\xmltext{#1}{/bottext}} +\stopxmlsetups + +\startxmlsetups xml:step:cell + \cell {\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:step:text + \text {\xmlflush{#1}} +\stopxmlsetups + +\protect + +\continueifinputfile{m-steps.mkvi} + +\starttext + +\startbuffer +<stepchart> + <cell> some cell </cell> + <text> some text </text> + <cell> some cell </cell> + <text> some text </text> + <cell> some cell </cell> +</stepchart> +\stopbuffer + +\typebuffer \processxmlbuffer + + +\startbuffer +<steptable> + <cell> some cell </cell> + <text> some text </text> + <cell> some cell </cell> + <text> some text </text> + <cell> some cell </cell> +</steptable> +\stopbuffer + +\typebuffer \processxmlbuffer + +\page + +\startSTEPchart + \cells {A} {B} + \cells {one} {five} \texts{$+2$}{$-2$} + \cells {two} {four} \texts{$+3$}{$-3$} + \cells {three} {three} \texts{$+4$}{$-4$} + \cells {four} {two} \texts{$+5$}{$-5$} + \cells {five} {one} +\stopSTEPchart + +\startSTEPtable + \cell {one} \textset{$x$} {=}{$a+b+c$} + \cell {two} \textset{$c+d$}{=}{$y$} + \cell {three} +\stopSTEPtable + + +\page + +\startbuffer +<stepchart> + <cells> <top> some text </top> <bot> some text </bot> </cells> + <texts> <top> text </top> <bot> text </bot> </texts> + <cells> <top> some text </top> <bot> some text </bot> </cells> +</stepchart> +\stopbuffer + +\processxmlbuffer + +\startbuffer +<stepchart> + <cell> some text </cell> + <texts> <top> text </top> <bot> text </bot> </texts> + <cell> some text </cell> +</stepchart> +\stopbuffer + +\processxmlbuffer + +\page + +\startSTEPchart[second] + \startSTEPcell + \topcell {A} + \botcell {B} + \startSTEPcell + \topcell {one} + \botcell {five} + \toptext {$+2$} + \bottext {$-2$} + \stopSTEPcell + \startSTEPcell + \topcell {two} + \botcell {four} + \toptext {$+3$} + \bottext {$-3$} + \stopSTEPcell + \startSTEPcell + \topcell {three} + \botcell {three} + \toptext {$+4$} + \bottext {$-4$} + \stopSTEPcell + \startSTEPcell + \topcell {four} + \botcell {two} + \toptext {$+5$} + \bottext {$-5$} + \stopSTEPcell + \startSTEPcell + \topcell {five} + \botcell {one} + \stopSTEPcell +\stopSTEPchart + +\STEPchart[first][alternative=horizontal] +\STEPchart[first][alternative=vertical] + +\page + +\STEPchart[second][alternative=horizontal] +\STEPchart[second][alternative=vertical] + +\page + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-subsub.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-subsub.mkiv new file mode 100644 index 00000000000..88be1168000 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-subsub.mkiv @@ -0,0 +1,76 @@ +%D \module +%D [ file=m-subsub, +%D version=2000.12.14, +%D title=\CONTEXT\ Private Modules, +%D subtitle=More Section Levels, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. This module is not public. + +\unprotect + +\definesection[\s!section-8] +\definesection[\s!section-9] +\definesection[\s!section-10] +\definesection[\s!section-11] +\definesection[\s!section-12] + +\definehead + [\v!subsubsubsubsubsection] + [\c!section=\s!section-8, + \c!default=\v!subsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsection] + [\c!section=\s!section-9, + \c!default=\v!subsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsubsection] + [\c!section=\s!section-10, + \c!default=\v!subsubsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsubsubsection] + [\c!section=\s!section-11, + \c!default=\v!subsubsubsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubsubsubsubsection] + [\c!section=\s!section-12, + \c!default=\v!subsubsubsubsubsubsubsubsection] + +\definehead + [\v!subsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\definehead + [\v!subsubsubsubsubsubsubsubsubsubject] + [\c!coupling=\v!subsubsubsubsubsubsubsubsubsection, + \c!default=\v!subsubsubsubsubsubsubsubsubsection, + \c!incrementnumber=\v!no] + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-timing.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-timing.mkiv new file mode 100644 index 00000000000..5502768f697 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-timing.mkiv @@ -0,0 +1,102 @@ +%D \module +%D [ file=m-timing, +%D version=2007.12.23, +%D title=\CONTEXT\ Modules, +%D subtitle=Timing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\ifdefined\ShowNamedUsage \endinput \fi + +%D Written at the end of 2007, this module is dedicated to Taco. Reaching this +%D point in \LUATEX\ was a non trivial effort. By visualizing a bit what happens +%D when pages come out of \LUATEX, you may get an idea what is involved. It took +%D much time an dedication to reach this point in the development. Add to that +%D those daily Skype intense discussion, testing and debugging moments. Time flies +%D but progress is impressive. The motto of this module could be: what you see +%D is what you get. An there is much more to come \unknown. + +% \usemodule[timing] +% \setupcolors[state=start] +% \starttext +% \dorecurse{200}{\input tufte \par} \ShowUsage{} +% \stoptext + +\definecolor[usage:line] [darkred] +\definecolor[usage:time] [darkblue] +\definecolor[usage:frame][darkgray] + +\ctxloadluafile{trac-tim}{} + +\startluacode +local progress = moduledata.progress + +function progress.show(filename,parameters,nodes,other) + for n, name in pairs(parameters or progress.parameters()) do + context.ShowNamedUsage(filename or progress.defaultfilename,name,other or "") + end + for n, name in pairs(nodes or progress.nodes(filename)) do + context.ShowNamedUsage(filename or progress.defaultfilename,name,other or "") + end +end +\stopluacode + +% \everyfirstshipout + +\startnotmode[no-timing] + \appendtoks\ctxlua{moduledata.progress.store()}\to\everystarttext + \appendtoks\ctxlua{moduledata.progress.store()}\to\everyshipout + \ctxlua{luatex.registerstopactions(function() moduledata.progress.save() end)} +\stopnotmode + +\unexpanded\def\ShowNamedUsage#1#2#3% + {\setbox\scratchbox\vbox\bgroup + \startMPcode + begingroup ; save p, q, b, h, w ; + path p, q, b ; numeric h, w ; + p := \cldcontext{moduledata.progress.path("#1","#2")} ; + % p := p shifted -llcorner p ; + if bbwidth(p) > 0 : + h := 100 ; w := 2 * h ; + w := \the\textwidth-3pt ; % correct for pen + p := p xstretched w ; + b := boundingbox (llcorner p -- llcorner p shifted (w,h)) ; + pickup pencircle scaled 3pt ; linecap := butt ; + draw b withcolor \MPcolor{usage:frame} ; + draw p withcolor \MPcolor{usage:line} ; + if ("#3" <> "") and ("#3" <> "#2") : + q := \cldcontext{moduledata.progress.path("#1","#3")} ; + % q := q shifted -llcorner q ; + if bbwidth(q) > 1 : + q := q xstretched w ; + pickup pencircle scaled 1.5pt ; linecap := butt ; + draw q withcolor \MPcolor{usage:time} ; + fi ; + fi ; + fi ; + endgroup ; + \stopMPcode + \egroup + \scratchdimen\wd\scratchbox + \ifdim\scratchdimen>\zeropoint + \startlinecorrection + \box\scratchbox \endgraf + \hbox to \scratchdimen{\tttf\strut\detokenize{#2}\hss + min:\cldcontext{moduledata.progress.bot("#1","\detokenize{#2}")}, % + max:\cldcontext{moduledata.progress.top("#1","\detokenize{#2}")}, % + pages:\cldcontext{moduledata.progress.pages("#1")}% + }% + \stoplinecorrection + \fi} + +\unexpanded\def\LoadUsage #1{\ctxlua{moduledata.progress.convert("#1")}} +\unexpanded\def\ShowUsage #1{\ctxlua{moduledata.progress.show("#1",nil,nil,"elapsed_time")}} +\unexpanded\def\ShowMemoryUsage#1{\ctxlua{moduledata.progress.show("#1",nil,{}, "elapsed_time")}} +\unexpanded\def\ShowNodeUsage #1{\ctxlua{moduledata.progress.show("#1",{},nil, "elapsed_time")}} + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-trackers.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-trackers.mkiv new file mode 100644 index 00000000000..95c34b16f65 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-trackers.mkiv @@ -0,0 +1,3 @@ +\starttext + \showtrackers +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-translate.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-translate.mkiv new file mode 100644 index 00000000000..2e6cbe95088 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-translate.mkiv @@ -0,0 +1,127 @@ +%D \module +%D [ file=m-translate, +%D version=2008.10.09, +%D title=\CONTEXT\ Modules, +%D subtitle=Translations, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D We can make this module more clever (wildcards and such) but since +%D it's only a demo we stick to the simple case for now. After all, it's +%D better to fix your source. + +\startluacode + local translators = { } + + moduledata.translators = translators + + local compiled, list = nil, nil + + -- function translators.register(from,to) + -- local l = lpeg.P(from)/to + -- if not list then + -- list = l + -- else + -- list = list + l + -- end + -- compiled = nil + -- end + -- + -- function translators.translate(s) + -- if list then + -- if not compiled then + -- compiled = lpeg.Cs((list + lpeg.P(1))^0) + -- end + -- return compiled:match(s) + -- else + -- return s + -- end + -- end + + -- local function prepare() + + function translators.register(from,to) + if not list then + list = { [from] = to } + else + list[from] = to + end + compiled = nil + end + + function translators.translate(s) + if list then + if not compiled then + local tree = lpeg.utfchartabletopattern(list) + compiled = lpeg.Cs((tree/list + lpeg.patterns.utf8character)^0 * lpeg.P(-1)) -- the P(1) is needed in order to accept non utf + end + return compiled:match(s) + else + return s + end + end + + local textlineactions = resolvers.openers.helpers.textlineactions + + utilities.sequencers.appendaction(textlineactions,"after","moduledata.translators.translate") + + function translators.enable() + utilities.sequencers.enableaction(textlineactions,"moduledata.translators.translate") + end + + function translators.disable() + utilities.sequencers.disableaction(textlineactions,"moduledata.translators.translate") + end + + function translators.reset(s) + translators.enable() + list, compiled = nil, nil + end + + translators.disable() +\stopluacode + +\unprotect + +\unexpanded\def\translateinput + {\dodoubleargument\module_translate_input} + +\def\module_translate_input[#1][#2]% + {\ctxlua{moduledata.translators.register(\!!bs#1\!!es,\!!bs#2\!!es)}} + +\unexpanded\def\resetinputtranslation + {\ctxlua{moduledata.translators.reset()}} + +\unexpanded\def\enableinputtranslation + {\ctxlua{moduledata.translators.enable()}} + +\unexpanded\def\disableinputtranslation + {\ctxlua{moduledata.translators.disable()}} + +\unexpanded\def\readtranslatedfile#1% + {\enableinputtranslation + \readfile{#1}\donothing\donothing + \disableinputtranslation} + +\protect + +\continueifinputfile{m-translate.mkiv} + +\starttext + + \translateinput[Moica][Mojca] + % \translateinput[Idris][Idris (aka ادريس)] + \translateinput[Idris][Idris (aka <something arabic here>)] + + \enableinputtranslation + + Well, it's not that hard to satisfy Idris' and Moicas \TEX\ needs. + + \readtranslatedfile{tufte} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-units.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-units.mkiv new file mode 100644 index 00000000000..f85a8ba8a5e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-units.mkiv @@ -0,0 +1,914 @@ +%D \module +%D [ file=m-units, +%D version=1997.03.19, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Scientific Units, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Best use the built in unit handle! + +%D Scientific units can be typeset in math mode pretty well, +%D but occasionally one has to take care of spacing. +%D Furthermore, entering these units is not that natural as +%D wanted. Therefore this module presents a more natural way of +%D doing things, like: +%D +%D \starttyping +%D 1.23 \Cubic \Meter \Per \Second +%D \stoptyping +%D +%D This example shows that we use the order in which we say +%D things, instead of typeset things. There is a separate +%D manual for this module. + +%D Message number~1 deals with overruling the \type {\Degrees} +%D macro defined in the core modules. Let's say that this is +%D an upward compatibility issue. + +\startmessages dutch library: units + title: eenheden + 1: gebruik \string\Degrees\space\string\Celsius\space in plaats van \string\Celsius ! +\stopmessages + +\startmessages english library: units + title: units + 1: use \string\Degrees\space\string\Celsius\space instead of \string\Celsius ! +\stopmessages + +\startmessages german library: units + title: Einheiten + 1: Verwende \string\Degrees\space\string\Celsius\space statt \string\Celsius ! +\stopmessages + +\startmessages italian library: units + title: unita + 1: usare \string\Degrees\space\string\Celsius\space invece di \string\Celsius ! +\stopmessages + +\startmessages norwegian library: units + title: enheter + 1: bruk \string\Degrees\space\string\Celsius\space istedenfor \string\Celsius ! +\stopmessages + +\startmessages romanian library: units + title: unitati + 1: folositi \string\Degrees\space\string\Celsius\space in locul \string\Celsius ! +\stopmessages + +\startmessages french library: units + title: unitas + 1: utilisez \string\Degrees\space\string\Celsius\space A la place de \string\Celsius ! +\stopmessages + +\registerctxluafile{x-mathml}{} + +\unprotect + +\writestatus{\m!units}{The units module is obsolete because functionality is built into the core.} + +\let\unit\undefined + +\definesynonyms + [\v!unit] + [\v!units] + [\unitmeaning] + +\setupsynonyms + [\v!unit] + [\c!synonymcommand=\dimension] + +\startmodule[units] + +%D This runtime loadable module implements a way of defining +%D units. The core macro is \type {\dimension}, a rather clever +%D one that is able to cooperate with some other dimension +%D related macros. As said, this module enables user to enter: +%D +%D \starttyping +%D some 10 \Square \Meter \Per \Second or more +%D \stoptyping +%D +%D The units itself are implemented as synonyms. +%D +%D \starttyping +%D \definesynonyms [unit] [units] [\unitmeaning] +%D \setupsynonyms [unit] [textstyle=\dimension] +%D \stoptyping +%D +%D This definition means that we can ask for the meaning of a +%D unit using \type {\unitmeaning} and get a list of used +%D units by saying \type {\placelistofunits} +%D +%D We have to use the command \type {\unitmeaning} instead +%D of \type {\meaning}, simply because the latter is a \TEX\ +%D primitive we don't want to loose. We use the label text +%D mechanism for translations. + +%D \macros +%D {dimension} +%D +%D The core of this module is the low level macro \type +%D {\dimension}. Before presenting this macro, it's best to +%D look at some applications, because it's supposed to show +%D some intelligence that can beter be understood from the +%D context. +%D +%D The next useless examples show some of the cases we want +%D to handle in a proper way. +%D +%D \starttyping +%D ... 10 \Square \Meter \Per \Volt \ +%D ... 10 \Square \Meter \Volt \ +%D ... 10 \Meter \Volt \ +%D ... 10 \Milli \Square \Meter \Per \Volt \ +%D ... 10 \Square \Milli \Meter \Per \Volt \ +%D ... 10 \Meter \Times \Meter \ +%D ... 10 \Square \Meter \Times \Meter \ +%D ... 10 \Square \Milli \Meter \Times \Meter \ +%D \stoptyping + +%D \macros +%D {mathematicstypeface, dimensiontypeface, +%D dimensionhalfspace, dimensionbackspace} +%D +%D There are some low level constants, that can be changed +%D when needed. Some day I will write a decent setup command. + +\def\mathematicstypeface{\rm} +\def\dimensiontypeface {\tf} + +\def\dimensionhalfspace {\ifmmode\,\else\hskip+.1em\relax\fi} +\def\dimensionbackspace {\ifmmode\!\else\hskip-.1em\relax\fi} + +%D \macros +%D {smashdimensionpower} +%D +%D Sometimes the baseline distance is not enough to provide +%D for superscripts, so we smash their height by default. + +\newif\ifsmashdimensionpower \smashdimensionpowertrue + +%D The dimension mechanism uses a lot of signals to keep +%D track if the current state. + +\newsignal\dimensionsignal +\newsignal\dimensionpowersignal +\newsignal\dimensionmidfixsignal +\newsignal\dimensionaddfixsignal + +\let\thedimensionprefix = \empty +\let\thedimensionpower = \empty + +%D \macros +%D {spaceddimensions,textdimensions} +%D +%D The actual definition of \type {\dimension} overruled the +%D one in the core modules. The boolean can be used to +%D force spacing between units. The rather ugly test prevents +%D problems with nested dimensions. + +\newif\ifspaceddimensions \spaceddimensionsfalse % user switch +\newif\iftextdimensions \textdimensionsfalse % user switch + +%D You can see the consequence of forcing text dimensions +%D when you compare the following code: +%D +%D \starttyping +%D {\rm test \Square \Meter \Per \Second\ ziezo\Degrees} \par +%D {\ss test \Square \Meter \Per \Second\ ziezo} \par +%D {\tt test \Square \Meter \Per \Second\ ziezo} +%D +%D \textdimensionstrue +%D +%D {\rm test \Square \Meter \Per \Second\ ziezo} \par +%D {\ss test \Square \Meter \Per \Second\ ziezo} \par +%D {\tt test \Square \Meter \Per \Second\ ziezo} +%D \stoptyping + +\newif\ifnesteddimension \nesteddimensionfalse % local switch + +\def\dodimensionpower#1% + {\iftextdimensions\expandafter\high\else\expandafter\normalsuperscript\fi{#1}} + +\def\ustartmathmode {\iftextdimensions\else\expandafter\startmathmode \fi} +\def\ustopmathmode {\iftextdimensions\else\expandafter\stopmathmode \fi} +\def\umathematicstypeface{\iftextdimensions\else\expandafter\mathematicstypeface\fi} + +%D In forced text mode, we ignore spacing in monospaced fonts. + +\def\udimensionhalfspace {\dodimensionspace\dimensionhalfspace} +\def\udimensionbackspace {\dodimensionspace\dimensionbackspace} + +\def\dodimensionspace + {\iftextdimensions + \begingroup + \setbox0\hbox{i}% + \setbox2\hbox{m}% + \ifdim\wd0=\wd2 + \endgroup + \@EAEAEA\gobbleoneargument + \else + \endgroup + \fi + \fi} + +\unexpanded\def\dimension#1% + {\begingroup + \global\let\savedthedimensionprefix\thedimensionprefix + \global\let\savedthedimensionpower\thedimensionpower + \unexpanded\def\dimension##1{\global\nesteddimensiontrue}% + \let\dimensionprefix\dimension + \let\dimensionmidfix\dimension + \let\dimensionsuffix\dimension + \let\dimensionpower \dimension + \global\nesteddimensionfalse + \setbox\scratchbox\hbox{\ustartmathmode#1\ustopmathmode}% pre-roll + \global\let\thedimensionprefix\savedthedimensionprefix + \global\let\thedimensionpower \savedthedimensionpower + \endgroup + \ifnesteddimension#1\else\dodimension{#1}\fi} + +\def\dodimension#1% + {\dontbreakdimension + \ifdim\scratchdimen=\zeropoint\relax + \ifmmode + \udimensionhalfspace + \udimensionhalfspace + \fi + \ustartmathmode\dimensiontypeface + \else + \ustartmathmode\dimensiontypeface + \ifspaceddimensions + \ifdim\scratchdimen=\dimensionsignal\relax + \udimensionhalfspace + \else\ifdim\scratchdimen=\dimensionpowersignal\relax + \udimensionhalfspace + \fi + \fi + \fi + \fi + \umathematicstypeface\thedimensionprefix#1% + \ifx\thedimensionpower\empty + \else\ifsmashdimensionpower + \setbox\scratchbox=\hbox + {\iftextdimensions + \tx\thedimensionpower + \else + \normalstartimath + \scriptstyle\thedimensionpower + \normalstopimath + \fi}% + \ht\scratchbox=\zeropoint + \dodimensionpower{\box\scratchbox}% + \else + \dodimensionpower{\thedimensionpower}% + \fi\fi + \ustopmathmode + % otherwise nobreak before space in 2 \Milli \Meter\ blabla + \doifnotmode{atpragma}{\nobreak}% this was always \nobreak + % only test this at pragma + \ifx\thedimensionpower\empty + \hskip\dimensionsignal + \else + \hskip\dimensionpowersignal + \fi + \global\let\thedimensionprefix\empty + \global\let\thedimensionpower\empty} + +%D \macros +%D {dontbreakdimension, +%D dimensionprefix, dimensionaddfix, +%D dimensionnopfix, dimensionmidfix, +%D dimensionpower} +%D +%D Here are some auxilliary macros. + +\def\dontbreakdimension + {\scratchdimen\lastskip + \unskip + \nobreak + \hskip\scratchdimen + \nobreak} + +\def\dimensionprefix#1% + {\gdef\thedimensionprefix{#1}} + +\def\dimensionaddfix#1% + {\unskip + %\mathematics{\umathematicstypeface#1}% + \ustartmathmode\umathematicstypeface#1\ustopmathmode + \nobreak + \hskip\dimensionaddfixsignal} + +\def\dimensionnopfix#1% + {\dontbreakdimension + \ifdim\scratchdimen=\dimensionpowersignal\relax + \ustartmathmode + \else + \ustartmathmode + \udimensionhalfspace + \nobreak + \fi + \umathematicstypeface#1% + \ustopmathmode + \nobreak + \hskip\dimensionsignal} + +\def\dimensionmidfix#1% + {\dontbreakdimension + \ifdim\scratchdimen=\dimensionpowersignal\relax + \ustartmathmode + \udimensionbackspace + \nobreak + \else + \ustartmathmode + \fi + \umathematicstypeface#1% + \ustopmathmode + \nobreak + \hskip\dimensionmidfixsignal} + +\def\dimensionpower#1% + {\gdef\thedimensionpower{#1}} + +%D \macros +%D {SIunits, noSI, doSI} +%D +%D Some low level unit switching macros: + +\newif\ifSIunits \SIunitstrue + +\def\noSI#1{\begingroup\SIunitsfalse#1\endgroup} +\def\doSI#1{\begingroup\SIunitstrue #1\endgroup} + +%D \macros +%D {Degrees} +%D +%D We can fake the degrees symbol with: + +\def\Degrees{\dimensionaddfix{\mathematics{\normalsuperscript\circ}}} + +%D \macros +%D {Unit, NoUnit} +%D +%D When a dimension has no leading number, we can use \type +%D {\Unit}, and when no unit is appended, \type {\NoUnit} is +%D to be used, just to prevent the prefix migrating to the +%D next occasion. + +\def\Unit {\hskip\dimensionsignal} +\def\NoUnit {\dimension{}} + +%D The mechanism described at the top of this module, depends +%D on several dimensional components, like prefixes: + +\def\Atto {\dimensionprefix{a}} +\def\Femto {\dimensionprefix{f}} +\def\Pico {\dimensionprefix{p}} +\def\Nano {\dimensionprefix{n}} +\def\Micro {\dimensionprefix{\iftextdimensions u\else\mu\fi}} +\def\Milli {\dimensionprefix{m}} +\def\Centi {\dimensionprefix{c}} +\def\Deci {\dimensionprefix{d}} % 10^{01} +\def\Hecto {\dimensionprefix{h}} % 10^{02} +\def\Kilo {\dimensionprefix{k}} % 10^{03} +\def\Mega {\dimensionprefix{M}} % 10^{06} +\def\Giga {\dimensionprefix{G}} % 10^{09} +\def\Tera {\dimensionprefix{T}} % 10^{12} +\def\Peta {\dimensionprefix{P}} % 10^{15} +\def\Exa {\dimensionprefix{E}} % 10^{18} + +%def\Terra {\dimensionprefix{T}} % for old times sake + +\def\Kibi {\dimensionprefix{ki}} % 2^{10} +\def\Mebi {\dimensionprefix{Mi}} % 2^{20} +\def\Gibi {\dimensionprefix{Gi}} % 2^{30} +\def\Tebi {\dimensionprefix{Ti}} % 2^{40} +\def\Pebi {\dimensionprefix{Pi}} % 2^{50} + +%D and binary prefixes: + +\def\Kibi {\dimensionprefix{Ki}} +\def\Mebi {\dimensionprefix{Mi}} +\def\Gibi {\dimensionprefix{Gi}} +\def\Tebi {\dimensionprefix{Ti}} +\def\Pebi {\dimensionprefix{Pi}} +\def\Exbi {\dimensionprefix{Ei}} +\def\Zebi {\dimensionprefix{Zi}} +\def\Yobi {\dimensionprefix{Yi}} + +%D and operators: + +\def\Times {\dimensionnopfix{\iftextdimensions.\else\cdot\fi}} +\def\Solidus {\dimensionmidfix{/}} +\def\Per {\dimensionmidfix{/}} +\def\OutOf {\dimensionnopfix{:}} + +%D and suffixes: + +\def\Linear {\dimensionpower{1}} +\def\Square {\dimensionpower{2}} +\def\Cubic {\dimensionpower{3}} + +\def\Inverse {\dimensionpower{-1}} +\def\ILinear {\dimensionpower{-1}} +\def\ISquare {\dimensionpower{-2}} +\def\ICubic {\dimensionpower{-3}} + +%D Apart from these components, the units themselves are +%D defined using the synonym mechanism. First we define some +%D length and volume related units. + +\getvalue{\v!unit} [Meter] {m} {meter} +\getvalue{\v!unit} [pMeter] {\Pico \Meter} {picometer} +\getvalue{\v!unit} [nMeter] {\Nano \Meter} {nanometer} +\getvalue{\v!unit} [uMeter] {\Micro \Meter} {micrometer} +\getvalue{\v!unit} [mMeter] {\Milli \Meter} {millimeter} +\getvalue{\v!unit} [cMeter] {\Centi \Meter} {centimeter} +\getvalue{\v!unit} [dMeter] {\Deci \Meter} {decimeter} +\getvalue{\v!unit} [hMeter] {\Hecto \Meter} {hectometer} +\getvalue{\v!unit} [kMeter] {\Kilo \Meter} {kilometer} + +%D After some discussion on the \CONTEXT\ mailing list in +%D february 2002 it was decided to go from L to l for liters +%D (Karel Wesselings alternative: \mathematics{\ell}). + +\getvalue{\v!unit} [Liter] {l} {liter} +\getvalue{\v!unit} [mLiter] {\Milli \Liter} {milliliter} +\getvalue{\v!unit} [cLiter] {\Centi \Liter} {centiliter} +\getvalue{\v!unit} [dLiter] {\Deci \Liter} {deciliter} + +%D Next we define time related units (\type {\ifSI} still dutch only). + +\getvalue{\v!unit} [Sec] {s} {\labeltext{u:sec}} +\getvalue{\v!unit} [fSec] {\Femto \Sec} {\labeltext{u:fsec}} +\getvalue{\v!unit} [pSec] {\Pico \Sec} {\labeltext{u:psec}} +\getvalue{\v!unit} [nSec] {\Nano \Sec} {\labeltext{u:nsec}} +\getvalue{\v!unit} [uSec] {\Micro \Sec} {\labeltext{u:usec}} +\getvalue{\v!unit} [mSec] {\Milli \Sec} {\labeltext{u:msec}} +\getvalue{\v!unit} [Year] {\ifSIunits a \else j\fi} {\labeltext{u:year}} +\getvalue{\v!unit} [Month] {m} {\labeltext{u:month}} +\getvalue{\v!unit} [Week] {w} {\labeltext{u:week}} +\getvalue{\v!unit} [Day] {d} {\labeltext{u:day}} +\getvalue{\v!unit} [Hour] {\ifSIunits h \else u\fi} {\labeltext{u:hour}} +\getvalue{\v!unit} [Min] {min} {\labeltext{u:min}} + +\setuplabeltext + [\s!nl] + [u:sec=seconde, + u:psec=picoseconde, + u:fsec=femtoseconde, + u:nsec=nanoseconde, + u:usec=microseconde, + u:msec=milliseconde, + u:year=jaar, + u:month=maand, + u:week=week, + u:day=dag, + u:hour=uur, + u:min=minuten] + +\setuplabeltext + [\s!en] + [u:sec=second, + u:fsec=femtosecond, + u:psec=picosecond, + u:nsec=nanosecond, + u:usec=microsecond, + u:msec=millisecond, + u:year=year, + u:month=month, + u:week=week, + u:day=day, + u:hour=hour, + u:min=minutes] + +\setuplabeltext + [\s!de] + [u:sec=Sekunde, + u:fsec=Femtosekunde, + u:psec=Picosekunde, + u:nsec=Nanosekunde, + u:usec=Microsekunde, + u:msec=Millisekunde, + u:year=Jahr, + u:month=Monat, + u:week=Woche, + u:day=Tag, + u:hour=Stunde, + u:min=Minuten] + +\setuplabeltext + [\s!hr] + [u:sec=sekunda, + u:fsec=femtosekunda, + u:psec=pikosekunda, + u:nsec=nanosekunda, + u:usec=mikrosekunda, + u:msec=milisekunda, + u:year=godina, + u:month=mjesec, + u:week=tjedan, + u:day=dan, + u:hour=sat, + u:min=minuta] + +\setuplabeltext + [\s!it] + [u:sec=secondo, + u:fsec=femtosecondo, + u:psec=picosecondo, + u:nsec=nanosecondo, + u:usec=microsecondo, + u:msec=millisecondo, + u:year=anno, + u:month=mese, + u:week=settimana, + u:day=giorno, + u:hour=ora, + u:min=minuti] + +%D Then we define some angles. + +\getvalue{\v!unit} [Rad] {rad} {\labeltext{u:rad}} +\getvalue{\v!unit} [Deg] {{\mathematics{\normalsuperscript\circ}}} {\labeltext{u:deg}} + +\setuplabeltext + [\s!nl] + [u:rad=hoek radialen, + u:deg=hoek graden] + +\setuplabeltext + [\s!en] + [u:rad=angle radians, + u:deg=angle degrees] + +\setuplabeltext + [\s!de] + [u:rad=Bogenma\SS, + u:deg=Gradma\SS] + +\setuplabeltext + [\s!hr] + [u:rad=radijani, + u:deg=kutni stupnjevi] + +\setuplabeltext + [\s!it] + [u:rad=radianti, + u:deg=angoli sessagesimali] + +%D Rotation and frequency related units are defined by: + +\getvalue{\v!unit} [Hertz] {Hz} {Hertz} +\getvalue{\v!unit} [kHertz] {\Kilo \Hertz} {kilo Hertz} +\getvalue{\v!unit} [MHertz] {\Mega \Hertz} {mega Hertz} +\getvalue{\v!unit} [GHertz] {\Giga \Hertz} {giga Hertz} +\getvalue{\v!unit} [THertz] {\Tera \Hertz} {tera Hertz} +\getvalue{\v!unit} [mHertz] {\Milli \Hertz} {milli Hertz} + +\getvalue{\v!unit} [RevPerSec] {RPS} {\labeltext{u:rps}} +\getvalue{\v!unit} [RevPerMin] {RPM} {\labeltext{u:rpm}} + +\setuplabeltext + [\s!nl] + [u:rps=omwentelingen per seconde, + u:rpm=omwentelingen per minuut] + +\setuplabeltext + [\s!en] + [u:rps=revolutions per second, + u:rpm=revolutions per minute] + +\setuplabeltext + [\s!de] + [u:rps=Umdrehungen pro Sekunde, + u:rpm=Umdrehungen pro Minute] + +\setuplabeltext + [\s!hr] + [u:rps=okretaji po sekundi, + u:rpm=okretaji po minuti] + +\setuplabeltext + [\s!it] + [u:rps=giri al secondo, + u:rpm=giri al minuto] + +%D Mass and force: + +\getvalue{\v!unit} [Gram] {g} {gram} +\getvalue{\v!unit} [uGram] {\Micro \Gram} {microgram} +\getvalue{\v!unit} [mGram] {\Milli \Gram} {milligram} +\getvalue{\v!unit} [kGram] {\Kilo \Gram} {kilogram} +\getvalue{\v!unit} [Atom] {u} {\labeltext{u:u}} + +\getvalue{\v!unit} [Newton] {N} {Newton} +\getvalue{\v!unit} [kNewton] {\Kilo \Newton} {kilo Newton} + +\getvalue{\v!unit} [Pascal] {Pa} {Pascal} +\getvalue{\v!unit} [mPascal] {\Milli \Pascal} {milli Pascal} +\getvalue{\v!unit} [kPascal] {\Kilo \Pascal} {kilo Pascal} + +\setuplabeltext + [\s!nl] + [u:u=atomaire massa eenheid] + +\setuplabeltext + [\s!en] + [u:u=atom mass unit] + +\setuplabeltext + [\s!de] + [u:u=Atomare Masseneinheit] + +\setuplabeltext + [\s!hr] + [u:u=unificirana atomska jedinica mase] + +\setuplabeltext + [\s!it] + [u:u=unit\`a di massa atomica] + +%D Energy units comes in two alternatives: + +\getvalue{\v!unit} [Joule] {J} {Joule} +\getvalue{\v!unit} [mJoule] {\Milli \Joule} {milli Joule} +\getvalue{\v!unit} [kJoule] {\Kilo \Joule} {kilo Joule} +\getvalue{\v!unit} [MJoule] {\Mega \Joule} {mega Joule} +\getvalue{\v!unit} [GJoule] {\Giga \Joule} {giga Joule} + +\getvalue{\v!unit} [Watt] {W} {Watt} +\getvalue{\v!unit} [mWatt] {\Milli \Watt} {milli Watt} +\getvalue{\v!unit} [kWatt] {\Kilo \Watt} {kilo Watt} +\getvalue{\v!unit} [MWatt] {\Mega \Watt} {mega Watt} +\getvalue{\v!unit} [GWatt] {\Giga \Watt} {giga Watt} +\getvalue{\v!unit} [TWatt] {\Tera \Watt} {tera Watt} + +%D Although Celsius is no longer permitted, we define it by +%D saying: + +\getvalue{\v!unit} [Celsius] {C} {Celsius} +\getvalue{\v!unit} [Kelvin] {K} {Kelvin} +\getvalue{\v!unit} [Fahrenheit] {F} {Fahrenheit} + +%D Some chemic related units are: + +\getvalue{\v!unit} [Mol] {mol} {mol} +\getvalue{\v!unit} [mMol] {\Milli \Mol} {millimol} +\getvalue{\v!unit} [kMol] {\Kilo \Mol} {kilomol} +\getvalue{\v!unit} [Molair] {M} {molair (\Mol \Per \Liter)} +\getvalue{\v!unit} [Equivalent] {eq} {equivalent} +\getvalue{\v!unit} [mEquivalent] {\Milli \Equivalent} {milli equivalent} + +%D There are quite a lot units related to electricity and +%D magnetism: + +\getvalue{\v!unit} [Farad] {F} {Farad} +\getvalue{\v!unit} [pFarad] {\Pico \Farad} {pico Farad} +\getvalue{\v!unit} [nFarad] {\Nano \Farad} {nano Farad} +\getvalue{\v!unit} [uFarad] {\Micro \Farad} {micro Farad} +\getvalue{\v!unit} [mFarad] {\Milli \Farad} {milli Farad} + +\getvalue{\v!unit} [Ohm] {\Omega} {Ohm} +\getvalue{\v!unit} [kOhm] {\Kilo \Ohm} {kilo Ohm} + +\getvalue{\v!unit} [Siemens] {S} {Siemens} + +\getvalue{\v!unit} [Ampere] {A} {Amp\`ere} +\getvalue{\v!unit} [mAmpere] {\Milli \Ampere} {milli Amp\`ere} + +\getvalue{\v!unit} [Coulomb] {C} {Coulomb} + +\getvalue{\v!unit} [Volt] {V} {Volt} +\getvalue{\v!unit} [mVolt] {\Milli \Volt} {milli Volt} +\getvalue{\v!unit} [kVolt] {\Kilo \Volt} {kilo Volt} +\getvalue{\v!unit} [eVolt] {eV} {electronvolt} +\getvalue{\v!unit} [keVolt] {\Kilo \eVolt} {kilo electronvolt} +\getvalue{\v!unit} [MeVolt] {\Mega \eVolt} {mega electronvolt} + +\getvalue{\v!unit} [Tesla] {T} {Tesla} + +\getvalue{\v!unit} [VoltAC] {V\normalsubscript{\xbox{ac}}} {\labeltext{u:vac}} +\getvalue{\v!unit} [VoltDC] {V\normalsubscript{\xbox{dc}}} {\labeltext{u:vdc}} + +\setuplabeltext + [\s!nl] + [u:vac=wisselspanning, + u:vdc=gelijkspanning] + +\setuplabeltext + [\s!en] + [u:vac=alternating current, + u:vdc=direct current] + +\setuplabeltext + [\s!de] + [u:vac=Wechselspannung, + u:vdc=Gleichspannung] + +\setuplabeltext + [\s!hr] + [u:vac=izmjeni\ccaron ni napon, + u:vdc=istosmjerni napon] + +\setuplabeltext + [\s!it] + [u:vac=corrente alternata, + u:vdc=corrente continua] + +%D Network bandwidth is specified in Bits: + +\getvalue{\v!unit} [Bit] {bit} {\labeltext{u:bit}} +\getvalue{\v!unit} [Baud] {Bd} {Baud (Bit/s)} + +%D Computer memory size is specified in Bytes: + +\getvalue{\v!unit} [Byte] {B} {\labeltext{u:byte}} +\getvalue{\v!unit} [kByte] {\Kilo \Byte} {kilo Byte} +\getvalue{\v!unit} [MByte] {\Mega \Byte} {mega Byte} +\getvalue{\v!unit} [GByte] {\Giga \Byte} {giga Byte} +\getvalue{\v!unit} [TByte] {\Tera \Byte} {tera Byte} + +\setuplabeltext + [\s!en] + [u:bit=Bit, + u:byte=Byte] + +\setuplabeltext + [\s!hr] + [u:bit=bit, + u:byte=bajt] + +%D Telecommunication call density is specified in Erlangs: + +\getvalue{\v!unit} [Erlang] {E} {Erlang} + +%D Some radiation related units: + +\getvalue{\v!unit} [Bequerel] {Bq} {Bequerel} +\getvalue{\v!unit} [MBequerel] {\Mega \Bequerel} {Bequerel} +\getvalue{\v!unit} [Sievert] {Sv} {Sievert} +\getvalue{\v!unit} [mSievert] {\Milli \Sievert} {milli Sievert} + +%D Light: + +\getvalue{\v!unit} [Candela] {cd} {Candela} + +%D and some sound ones: + +\getvalue{\v!unit} [Bell] {B} {Bell} +\getvalue{\v!unit} [dBell] {\Deci \Bell} {decibel} + +%D We also define some non||regular, sometimes even forbidden, +%D units: + +\getvalue{\v!unit} [At] {at} {\labeltext{u:at}} +\getvalue{\v!unit} [Atm] {atm} {\labeltext{u:atm}} +\getvalue{\v!unit} [Bar] {bar} {bar (100 \Kilo \Pascal)} +\getvalue{\v!unit} [EVolt] {eV} {electronvolt} +\getvalue{\v!unit} [Foot] {ft} {\labeltext{u:ft}} +\getvalue{\v!unit} [Inch] {inch} {\labeltext{u:inch}} +\getvalue{\v!unit} [Cal] {cal} {\labeltext{u:cal}} +\getvalue{\v!unit} [Force] {f} {\labeltext{u:f}} +\getvalue{\v!unit} [kCal] {\Kilo \Cal} {\labeltext{u:kcal}} +\getvalue{\v!unit} [Lux] {lux} {lux} + + +\def\xPercent {\dimensionaddfix{\percent }} +\def\xPromille{\dimensionaddfix{\promille}} + +\getvalue{\v!unit} [Percent] {\xPercent } {percent} +\getvalue{\v!unit} [Permille] {\xPromille} {promille} +\getvalue{\v!unit} [Promille] {\xPromille} {promille} + +%D Some more, thanks to Tobias: + +\getvalue{\v!unit} [Gray] {Gr} {Gray} +\getvalue{\v!unit} [Weber] {Wb} {Weber} +\getvalue{\v!unit} [Henry] {H} {Henry} +\getvalue{\v!unit} [Sterant] {sr} {Sterant} +\getvalue{\v!unit} [Angstrom] {\hbox{\Aring}} {\Aring ngstr\"om} +\getvalue{\v!unit} [Gauss] {G} {Gauss} + +\setuplabeltext + [\s!nl] + [u:at=technische atmosfeer, + u:atm=fysische atmosfeer, + u:ft=voet, + u:cal=calorie, + u:f=kracht (force), + u:kcal=kilocalorie] + +\setuplabeltext + [\s!en] + [u:at=technical atmospheric pressure, + u:atm=physical atmospheric pressure, + u:ft=foot, + u:inch=inch, + u:cal=calory, + u:f=force, + u:kcal=kilocalory] + +\setuplabeltext + [\s!de] + [u:at=Technischer atmosph\"arischer Druck, + u:atm=physkalischer atmosph\"arischer Druck, + u:ft=Fu\SS, + u:cal=Kalorien, + u:f=Force, + u:kcal=Kilokalorien] + +\setuplabeltext + [\s!hr] + [u:at=tehni\ccaron ka atmosfera, + u:atm=standardna atmosfera, + u:ft=stopa, + u:inch=in\ccaron a, + u:cal=kalorija, + u:f=Force, + u:kcal=Kilokalorien] + +\setuplabeltext + [\s!it] + [u:at=pressione atmosferica tecnica, + u:atm=pressione atmosfera fisica, + u:ft=piede, + u:cal=caloria, + u:f=forza, + u:kcal=chilocaloria] + +%D Here are some old ones, still there for compatibility +%D reasons. These will probably be obsolete in a few years. + +\def\MeterTwee {\Square \Meter} +\def\mMeterTwee {\Square \Milli \Meter} +\def\cMeterTwee {\Square \Centi \Meter} +\def\dMeterTwee {\Square \Deci \Meter} +\def\kMeterTwee {\Square \Kilo \Meter} + +\def\MeterDrie {\Cubic \Meter} +\def\mMeterDrie {\Cubic \Milli \Meter} +\def\cMeterDrie {\Kubic \Centi \Meter} +\def\dMeterDrie {\Cubic \Deci \Meter} +\def\kMeterDrie {\Cubic \Kilo \Meter} + +\def\LiterTwee {\Square \Liter} +\def\SecTwee {\Square \Sec} +\def\SecMinEen {\Inverse \Sec} + +%D To make ourselves happy, we define some dutch specific +%D units: + +\startinterface dutch + + \getvalue{\v!unit} [PaardenKracht] {pk} {paardenkracht} + \getvalue{\v!unit} [Duits] {D} {duits} + \getvalue{\v!unit} [Kwik] {Hg} {kwikkolom} + \getvalue{\v!unit} [Hectare] {ha} {hectare} + \getvalue{\v!unit} [kGramForce] {\Kilo \Gram \Force} {kilogramforce} + \getvalue{\v!unit} [kWattUur] {\Kilo \Watt \Uur} {kilowattuur} + \getvalue{\v!unit} [MeterKwik] {\Meter \Kwik} {meter kwikkolom} + \getvalue{\v!unit} [Waterkolom] {WK} {waterkolom} + \getvalue{\v!unit} [MeterWater] {\Meter \Waterkolom} {meter waterkolom} + \getvalue{\v!unit} [DrogeStof] {ds} {droge stof} + \getvalue{\v!unit} [Normaal] {N} {normaal} + + \getvalue{\v!unit} [Ton] {t} {ton} + \getvalue{\v!unit} [kTon] {\Kilo \Ton} {kiloton} + + \let \OmwPerSec \RevPerSec + \let \OmwPerMin \RevPerMin + \let \Graden \Deg + \let \PaardeKracht \PaardenKracht + \let \Atoom \Atom + \let \Heure \Hour + \let \Jaar \Year + \let \Maand \Month + \let \Dag \Day + \let \Uur \Hour + +\stopinterface + +%D Finally we define some equivalents. By using \type {\let} +%D we can be sure that they don't end up double in the lists of +%D units. + +\let \Second \Sec +\let \Kubic \Cubic +\let \IKubic \ICubic + +%D Option: + +% \def\Micro{\dimensionprefix{\iftextdimensions\mathematics\mu \else\mu \fi}} +% \def\Times{\dimensionnopfix{\iftextdimensions\mathematics\cdot\else\cdot\fi}} + +\stopmodule + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-visual.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-visual.mkiv new file mode 100644 index 00000000000..01fae49e2b6 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-visual.mkiv @@ -0,0 +1,814 @@ +%D \module +%D [ file=m-visual, +%D version=2000.01.10, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Visualization and Faking, +%D author={Hans Hagen \& Ton Otten}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D Much will probably be replaced by \LUA\ based solutions which is +%D rather trivial and fun doing. + +%D This module collect a few more visual debugger features. I +%D needed them for manuals and styles. The macros are documented +%D in a my way document. + +\definecolor[fakerulecolor] [black] +\definecolor[fakebaselinecolor] [green] +\definecolor[fakeparindentcolor][blue] + +\newif\iffakebaseline \fakebaselinetrue +\newif\iffaketrigger \faketriggerfalse + +\unexpanded\def\fakerule#1% + {\strut + \begingroup + \directcolored[fakerulecolor]% + \iffakebaseline + \vrule\s!height1.25\exheight\s!depth-.05\exheight\s!width#1% + \kern-#1% + \vrule\s!height-.05\exheight\s!depth .25\exheight\s!width#1% + \else + \vrule\s!height1.25\exheight\s!depth .25\exheight\s!width#1% + \fi + \endgroup + \allowbreak} + +\unexpanded\def\dorandomrecurse#1% + {\getrandomcount\scratchcounter{1}{#1}% + \dorecurse\scratchcounter} + +% can be used in hbox, so %'s are really needed + +\unexpanded\def\fakelines#1#2% min max / 3 10 + {\fakeparindent + \scratchdimen\hsize + \ifindentation + \advance\scratchdimen -\parindent + \fi + \fakerule\scratchdimen\break + \getrandomcount\scratchcounter{\ifcase0#1 3\else#1\fi}{\ifcase0#2 10\else#2\fi}% + \dorecurse\scratchcounter{\fakerule\hsize}% + \getrandomdimen\scratchdimen{.25\hsize}\hsize + \fakerule\scratchdimen + \par} % indeed + +\unexpanded\def\fakewords + {\ifvmode\fakeparindent\fi\onlyfakewords} + +\definepalet + [fakerule] + [fr1c=darkred, + fr2c=darkgreen, + fr3c=darkblue, + fr4c=darkyellow, + fr5c=darkgray, + fr6c=darkmagenta, + fr7c=darkcyan, + fr8c=darkorange] + +\unexpanded\def\onlyfakewords#1#2% min max / 10 40 + {\getrandomcount\scratchcounter{\ifcase0#1 10\else#1\fi}{\ifcase0#2 40\else#2\fi}% + \dofakewords\scratchcounter + } % no \par + +\unexpanded\def\fakenwords#1#2% words seed + {\fakeparindent + \getrandomseed\fakedwordseed + \setrandomseed{\ifcase0#2 #1\else#2\fi}% + \dofakewords{#1}% + \setrandomseed\fakedwordseed + } % no \par + +\def\dofakewords#1% + {\bgroup + \dorecurse{#1} + {\iffaketrigger\signalcharacter\fi % so that e.g. line numbering works + \getrandomcount\scratchcounter{1}{5}% + \dorecurse\scratchcounter + {\getrandomdimen\scratchdimen{.5em}{1.25em}% + \fakerule\scratchdimen}% + \space}% + \removeunwantedspaces + \egroup} + +\def\doshowfakewords#1% + {\bgroup + \setuppalet[fakerule]% + \definecolor[fakerulecolor]% + \dorecurse{#1} + {\getrandomcount\scratchcounter{1}{5}% + \dorecurse\scratchcounter + {\getrandomdimen\scratchdimen{.5em}{1.25em}% + \color[fr\recurselevel c]{\fakerule\scratchdimen}}% + \space}% + \removeunwantedspaces + \egroup} + +\unexpanded\def\showfakewords + {\let\dofakewords\doshowfakewords} + +\unexpanded\def\fakeword + {\fakewords{1}{1}} % no \plusone + +\unexpanded\def\fakeparindent + {\noindent + \ifindentation + \ifx\dofakedroppedcaps\relax + {\fakeparindentcolor + \vrule + \s!height \strutheight % not longer .5ex + \s!depth \strutdepth % not longer 0pt + \s!width \parindent}% + \else + \dofakedroppedcaps \let\dofakedroppedcaps\relax + \fi +% \else +% \dontleavehmode + \fi} + +\let\dofakedroppedcaps\relax + +\unexpanded\def\fakedroppedcaps#1% + {\ifnum#1>0 + \def\dofakedroppedcaps + {\setbox\scratchbox\hpack + {\setbox\scratchbox\hpack{W}% + \scratchdimen#1\lineheight + \advance\scratchdimen -\lineheight + \advance\scratchdimen \dp\strutbox + \vrule + \s!width#1\wd\scratchbox + \s!height\ht\scratchbox + \s!depth\scratchdimen}% + \ht\scratchbox\ht\strutbox + \dp\scratchbox\dp\strutbox + \hangindent\wd\scratchbox + \advance\hangindent .5em + \wd\scratchbox\hangindent + \hangafter-#1\noindent + \llap{\fakeparindentcolor\box\scratchbox}}% + \fi} + +\unexpanded\def\fakefigure + {\dodoubleempty\dofakefigure} + +\def\dofakefigure[#1][#2]#3#4#5#6% [] [] minwidth maxwidth minheight maxheight + {\getvalue{\e!place\v!figure} + [#1][#2]% + {\freezerandomseed + \let\endstrut\relax + \let\begstrut\relax + \doifelseinset{#1}{\v!left,\v!right} + {\fakewords{2}{4}} + {\fakewords{4}{10}}}% + {\doifinset{#1}{\v!left,\v!right} + {\dimen0=.75\dimen0 + \ifdim\dimen0>.6\hsize \dimen0=.5\hsize\fi + \ifdim\dimen0<.3\hsize \dimen0=.3\hsize\fi}% + \framed + [\c!width=\dimen0, + \c!height=\dimen2, + \c!frame=\v!off, + \c!background=\v!color, + \c!backgroundcolor=fakeparindentcolor] + {\bf\white#1}}% + \defrostrandomseed} + +\unexpanded\def\fakeimage#1#2#3#4% + {\getrandomdimen{\dimen0}{#1}{#3}% + \getrandomdimen{\dimen2}{#2}{#4}% + \framed + [\c!width=\dimen0, + \c!height=\dimen2, + \c!frame=\v!off, + \c!background=\v!color, + \c!backgroundcolor=fakeparindentcolor] + {}} + +\unexpanded\def\fakeformula + {\dimen0\zeropoint + \getrandomcount\scratchcounter{3}{6}% + \dorecurse\scratchcounter + {\getrandomdimen\scratchdimen{0.5em}{1.5em}% + \mathord{\red\fakerule\scratchdimen}% + \ifnum\recurselevel<\scratchcounter+\fi + \advance\scratchdimen\dimen0}% + =\mathinner{\red\fakerule\scratchdimen}} + +\unexpanded\def\fakespacingformula + {\color[fakebaselinecolor]{\ruledbaseline}\fakeformula} + +%D test \type{\bodyfontgrid}\space test +%D test \type{\emexgrid} \space test + +\unexpanded\def\smashedgrid + {\dosingleempty\dosmashedgrid} + +\def\dosmashedgrid[#1]% + {\hsmashed + {\setbox\scratchbox=\hpack + {\basegrid + [\c!nx=10,\c!ny=10,\c!dx=1,\c!dy=1, + \c!unit=\bodyfontsize,#1]}% + \hpack to \zeropoint + {\hss\lower.5\ht\scratchbox\box\scratchbox\hss}% + \hpack to \zeropoint + {\hss + \black\vrule\s!width6\linewidth\s!height3\linewidth\s!depth3\linewidth + \hss}}} + +\unexpanded\def\bodyfontgrid + {\hpack + {{\linewidth.1pt\yellow\smashedgrid[\c!nx=30,\c!ny=30,\c!scale=.3333]}% + {\linewidth.2pt\green \smashedgrid[\c!nx=20,\c!ny=20,\c!scale=.5]}% + {\linewidth.3pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!scale=1]}}} + +\unexpanded\def\emexgrid + {\hpack + {{\linewidth.15pt\green\smashedgrid[\c!nx=20,\c!ny=20,\c!unit=ex]}% + {\linewidth.15pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!unit=em]}}} + +%D For Mojca: + +\unexpanded\def\simplethesis + {\setupsystem[random=1234] + \title{\fakewords{3}{4}} + \placelist[chapter,section] + \dorecurse{6} + {\chapter{\fakewords{5}{10}} + \dorecurse{5} + {\section{\fakewords{2}{5}} + \dorecurse{2} + {\dorecurse{3}{\fakewords{100}{200}\endgraf} + \placefigure{\fakewords{8}{15}}{\fakeimage{5cm}{3cm}{10cm}{5cm}} + \dorecurse{2}{\fakewords{100}{200}\endgraf}}}}} + +%D Moved code: + +%D \module +%D [ file=trac-vis, % was core-vis, +%D version=1996.06.01, +%D title=\CONTEXT\ Tracking Macros, +%D subtitle=Visualization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module adds some more visualization cues to the ones +%D supplied in the support module. +%D +%D %\everypar dual character, \the\everypar and \everypar= +%D %\hrule cannot be grabbed in advance, switches mode +%D %\vrule cannot be grabbed in advance, switches mode +%D % +%D %\indent only explicit ones +%D %\noindent only explicit ones +%D %\par only explicit ones +%D +%D %\leftskip only if explicit one +%D %\rightskip only if explicit one + +\writestatus{loading}{ConTeXt Tracking Macros / Visualization} + +\unprotect + +%D \macros +%D {indent, noindent, par} +%D +%D \TeX\ acts upon paragraphs. In mosts documents paragraphs +%D are separated by empty lines, which internally are handled as +%D \type{\par}. Paragraphs can be indented or not, depending on +%D the setting of \type{\parindent}, the first token of a +%D paragraph and/or user suppressed or forced indentation. +%D +%D Because the actual typesetting is based on both explicit +%D user and implicit system actions, visualization is only +%D possible for the user supplied \type{\indent}, +%D \type{\noindent}, and \type{\par}. Other +%D 'clever' tricks will quite certainly lead to more failures +%D than successes, so we only support these three explicit +%D primitives and one macro: + +\unexpanded\def\showparagraphcue#1#2#3#4#5% + {\bgroup + \scratchdimen#1\relax + \dontinterfere + \dontcomplain + %boxrulewidth5\testrulewidth + #3#4\relax + \setbox\scratchbox\normalhbox to \scratchdimen + {#2{\ruledhbox to \scratchdimen + {\vrule #5 20\testrulewidth \s!width \zeropoint + \normalhss}}}% + \smashbox\scratchbox + \normalpenalty\plustenthousand + \box\scratchbox + \egroup} + +\unexpanded\def\ruledhanging + {\ifdim\hangindent>\zeropoint + \ifnum\hangafter<\zerocount + \normalhbox + {%boxrulewidth5\testrulewidth + \setbox\scratchbox\ruledhbox to \hangindent + {\scratchdimen\strutht + \advance\scratchdimen \strutdp + \vrule + \s!width \zeropoint + \s!height \zeropoint + \s!depth -\hangafter\scratchdimen}% + \normalhskip-\hangindent + \smashbox\scratchbox + \raise\strutht\box\scratchbox}% + \fi + \fi} + +\unexpanded\def\ruledparagraphcues + {\bgroup + \dontcomplain + \normalhbox to \zeropoint + {\ifdim\leftskip>\zeropoint\relax + \showparagraphcue\leftskip\llap\relax\relax\!!depth + \normalhskip-\leftskip + \fi + \ruledhanging + \normalhskip\hsize + \ifdim\rightskip>\zeropoint\relax + \normalhskip-\rightskip + \showparagraphcue\rightskip\relax\relax\relax\!!depth + \fi}% + \egroup} + +\unexpanded\def\ruledpar + {\relax + \ifhmode + \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\s!height + \fi + \normalpar} + +\unexpanded\def\rulednoindent + {\relax + \normalnoindent + \ruledparagraphcues + \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\s!height} + +\unexpanded\def\ruledindent + {\relax + \normalnoindent + \ruledparagraphcues + \ifdim\parindent>\zeropoint + \showparagraphcue\parindent\relax\relax\relax\s!height + \else + \showparagraphcue{40\testrulewidth}\llap\relax\relax\s!height + \fi + \normalhskip\parindent} + +\unexpanded\def\dontshowimplicits + {\let\noindent \normalnoindent + \let\indent \normalindent + \let\par \normalpar} + +\unexpanded\def\showimplicits + {\testrulewidth \defaulttestrulewidth + \let\noindent \rulednoindent + \let\indent \ruledindent + \let\par \ruledpar} + +%D The next few||line examples show the four cues. Keep in +%D mind that we only see them when we explicitly open or close +%D a paragraph. +%D +%D \bgroup +%D \def\voorbeeld#1% +%D {#1Visualizing some \TeX\ primitives and Plain \TeX\ +%D macros can be very instructive, at least it is to me. +%D Here we see {\tt\string#1} and {\tt\string\ruledpar} in +%D action, while {\tt\string\parindent} equals +%D {\tt\the\parindent}.\ruledpar} +%D +%D \showimplicits +%D +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D +%D \parindent=60pt +%D +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D +%D \startnarrower +%D \voorbeeld \indent +%D \voorbeeld \noindent +%D \stopnarrower +%D \egroup +%D +%D These examples also demonstrate the visualization of +%D \type {\leftskip} and \type {\rightskip}. The macro +%D \type {\nofruledbaselines} determines the number of lines +%D shown. + +\newcounter\ruledbaselines + +\def\nofruledbaselines{3} + +\unexpanded\def\ruledbaseline + {\vrule \s!width \zeropoint + \bgroup + \dontinterfere + \doglobal\increment\ruledbaselines + \scratchdimen\nofruledbaselines\baselineskip + \setbox\scratchbox\normalvbox to 2\scratchdimen + {\leaders + \normalhbox + {\strut + \vrule + \s!height \testrulewidth + \s!depth \testrulewidth + \s!width 120\points} + \normalvfill}% + \smashbox\scratchbox + \advance\scratchdimen \strutheightfactor\baselineskip + \setbox\scratchbox\normalhbox + {\normalhskip -48\points + \normalhbox to 24\points + {\normalhss + {\ttxx\ruledbaselines}% + \normalhskip6\points}% + \raise\scratchdimen\box\scratchbox}% + \smashbox\scratchbox + \box\scratchbox + \egroup} + +\unexpanded\def\showbaselines + {\testrulewidth\defaulttestrulewidth + \EveryPar{\ruledbaseline}} + +%D \macros +%D {showpagebuilder} +%D +%D The next tracing option probaly is only of use to me and a +%D few \CONTEXT\ hackers. + +\unexpanded\def\showpagebuilder + {\EveryPar{\doshowpagebuilder}} + +\unexpanded\def\doshowpagebuilder + {\strut\llap + {\startcolor[blue]\vl + \high{\infofont v:\the\vsize }\vl + \high{\infofont g:\the\pagegoal }\vl + \high{\infofont t:\the\pagetotal}\vl + \stopcolor}} + +%D \macros +%D {colormarkbox,rastermarkbox} +%D +%D This macro is used in the pagebody routine. No other use +%D is advocated here. +%D +%D \starttyping +%D \colormarkbox0 +%D \stoptyping + +\def\colormarkoffset{\cutmarkoffset} +\def\colormarklength{\cutmarklength} + +\def\dodocolorrangeA#1% + {\fastcolored[#1]{\hrule\s!width3em\s!height\scratchdimen\s!depth\zeropoint}} + +\def\docolorrangeA#1 #2 % + {\vpack + {\hsize3em % \scratchdimen + \ifcase#1\or + \dodocolorrangeA{c=#2}\or + \dodocolorrangeA{m=#2}\or + \dodocolorrangeA{y=#2}\or + \dodocolorrangeA{m=#2,y=#2}\or + \dodocolorrangeA{c=#2,y=#2}\or + \dodocolorrangeA{c=#2,m=#2}\fi + \ifdim\scratchdimen>1ex + \vskip-\scratchdimen + \vpack to \scratchdimen + {\vss\hpack to 3em{\hss#2\hss}\vss}% + \fi}} + +\def\colorrangeA#1% + {\vpack + {\startcolor[\s!white]% + \scratchdimen\dimexpr(-\colormarklength*4+\tractempheight+\tractempdepth)/21\relax + \offinterlineskip + \docolorrangeA #1 1.00 \docolorrangeA #1 0.95 + \docolorrangeA #1 0.75 + \docolorrangeA #1 0.50 + \docolorrangeA #1 0.25 \docolorrangeA #1 0.05 + \docolorrangeA #1 0.00 + \stopcolor}} + +\def\docolorrangeB #1 #2 #3 #4 #5 % + {\fastcolored + [\c!c=#2,\c!m=#3,\c!y=#4,\c!k=#5] + {\vrule\s!width\scratchdimen\s!height\colormarklength\s!depth\zeropoint}% + \ifdim\scratchdimen>2em + \hskip-\scratchdimen + \vpack to \colormarklength + {\vss\hpack to \scratchdimen{\hss#1\hss}\vss}% + \fi} + +\def\colorrangeB + {\hpack + {\startcolor[\s!white]% + \scratchdimen\dimexpr(-\colormarklength*\plustwo+\tractempwidth)/11\relax + \docolorrangeB .5~C .5 0 0 0 + \docolorrangeB .5~M 0 .5 0 0 + \docolorrangeB .5~Y 0 0 .5 0 + \docolorrangeB .5~K 0 0 0 .5 + \docolorrangeB C 1 0 0 0 + \docolorrangeB G 1 0 1 0 + \docolorrangeB Y 0 0 1 0 + \docolorrangeB R 0 1 1 0 + \docolorrangeB M 0 1 0 0 + \docolorrangeB B 1 1 0 0 + \docolorrangeB K 0 0 0 1 + \stopcolor}} + +\def\docolorrangeC#1 % + {\fastcolored + [\c!s=#1]% + {\vrule\s!width\scratchdimen\s!height\colormarklength\s!depth\zeropoint}% + \ifdim\scratchdimen>2em + \hskip-\scratchdimen + \vpack to \colormarklength + {\vss\hpack to \scratchdimen{\hss#1\hss}\vss}% + \fi} + +\def\colorrangeC + {\hpack + {\startcolor[\s!white]% + \scratchdimen\dimexpr(-\colormarklength*2+\tractempwidth)/14\relax + \docolorrangeC 1 \docolorrangeC .95 + \docolorrangeC .9 \docolorrangeC .85 + \docolorrangeC .8 \docolorrangeC .75 + \docolorrangeC .7 + \docolorrangeC .6 + \docolorrangeC .5 + \docolorrangeC .4 + \docolorrangeC .3 + \docolorrangeC .2 + \docolorrangeC .1 + \docolorrangeC 0 + \stopcolor}} + +\def\docolormarkbox#1#2% + {\tractempheight\ht#2% + \tractempdepth \dp#2% + \tractempwidth \wd#2% + \setbox#2\hpack + {\scratchdimen\dimexpr\colormarklength/2\relax + \forgetall + \ssxx + \setbox\scratchbox\vpack + {\offinterlineskip + \vskip\dimexpr-\colormarkoffset\scratchdimen-2\scratchdimen\relax + \ifcase#1\relax + \vskip\dimexpr\colormarklength+\scratchdimen+\tractempheight\relax + \else + \hpack to \tractempwidth{\hss\hpack{\colorrangeB}\hss}% + \vskip\colormarkoffset\scratchdimen + \vpack to \tractempheight + {\vss + \hpack to \tractempwidth + {\llap{\colorrangeA1\hskip\colormarkoffset\scratchdimen}\hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA4}}% + \vss + \hpack to \tractempwidth + {\llap{\colorrangeA2\hskip\colormarkoffset\scratchdimen}\hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA5}}% + \vss + \hpack to \tractempwidth + {\llap{\colorrangeA3\hskip\colormarkoffset\scratchdimen}\hfill + \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA6}}% + \vss}% + \fi + \vskip\colormarkoffset\scratchdimen + \hpack to \tractempwidth + {\hss\lower\tractempdepth\hpack{\colorrangeC}\hss}}% + \ht\scratchbox\tractempheight + \dp\scratchbox\tractempdepth + \wd\scratchbox\zeropoint + \box\scratchbox + \box#2}% + \wd#2\tractempwidth + \ht#2\tractempheight + \dp#2\tractempdepth} + +\unexpanded\def\colormarkbox {\docolormarkbox\plusone } % #1 +\unexpanded\def\rastermarkbox{\docolormarkbox\zerocount} % #1 + +%D \macros +%D {showwhatsits, dontshowwhatsits} +%D +%D \TEX\ has three so called whatsits: \type {\mark}, \type +%D {\write} and \type {\special}. The first one keeps track of +%D the current state at page boundaries, the last two are used +%D to communicate to the outside world. Due to fact that +%D especially \type {\write} is often used in conjunction with +%D \type {\edef}, we can only savely support that one in \ETEX. +%D +%D \bgroup \showwhatsits \setupcolors[state=start] +%D +%D Whatsits show up \color[blue]{in color} and are +%D characterized bij their first character.\footnote [some note] +%D {So we may encounter \type {w}, \type {m} and \type{s}.} +%D They are \writestatus{dummy}{demo}\color[yellow]{stacked}. +%D +%D \egroup + +\newif\ifimmediatewrite + +\let\supernormalmark \normalmark % mark may already been superseded +\let\supernormalmarks \normalmarks % mark may already been superseded + +\unexpanded\def\showwhatsits + {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }% + \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}% + \protected\def\special {\visualwhatsit0100s\normalspecial }% + \protected\def\write {\visualwhatsit001-w\normalwrite }% + \let\immediate\immediatewhatsit + \appendtoks\dontshowwhatsits\to\everystoptext} + +\unexpanded\def\immediatewhatsit + {\bgroup\futurelet\next\doimmediatewhatsit} + +\unexpanded\def\doimmediatewhatsit + {\ifx\next\write + \egroup\immediatewritetrue + \else + \egroup\expandafter\normalimmediate + \fi} + +\unexpanded\def\dontshowwhatsits + {\let\immediate \normalimmediate + \let\normalmark\supernormalmark + \let\special \normalspecial + \let\write \normalwrite} + +\unexpanded\def\visualwhatsit#1#2#3#4#5% + {\bgroup + \pushwhatsit + \dontinterfere + \dontcomplain + \dontshowcomposition + \dontshowwhatsits + \ttx + \ifvmode\donetrue\else\donefalse\fi + \setbox\scratchbox\hpack + {\ifdone + \colored[r=#1,g=#2,b=#3]{#5}% temp hack + \else + \colored[s=0]{#5}% temp hack + \fi}% + \setbox\scratchbox\hpack + {\ifdone + \colored[r=#1,g=#2,b=#3]{\vrule\s!width\wd\scratchbox}% temp hack + \else + \colored[s=0]{\vrule\s!width\wd\scratchbox}% temp hack + \fi + \hskip-\wd\scratchbox\box\scratchbox}% + \scratchdimen1ex + \setbox\scratchbox\hpack + {\ifdone\hskip\else\raise#4\fi\scratchdimen\box\scratchbox}% + \smashbox\scratchbox + \ifdone\nointerlineskip\fi + \box\scratchbox + \ifvmode\nointerlineskip\fi + \popwhatsit + \egroup + \ifimmediatewrite + \immediatewritefalse + \expandafter\normalimmediate + \fi} + +\unexpanded\def\pushwhatsit + {\ifzeropt\lastskip + \ifcase\lastpenalty + \ifzeropt\lastkern + \ifhmode + \let\popwhatsit\relax + \else + \edef\popwhatsit{\prevdepth\the\prevdepth}% + \fi + \else + \ifhmode + \edef\popwhatsit{\kern\the\lastkern}\unkern + \else + \edef\popwhatsit{\kern\the\lastkern\prevdepth\the\prevdepth}% + \kern-\lastkern + \fi + \fi + \else + \ifhmode + \edef\popwhatsit{\the\lastpenalty}% + \unpenalty + \else + \edef\popwhatsit{\penalty\the\lastpenalty\prevdepth\the\prevdepth}% + %\nobreak + \fi + \fi + \else + \ifhmode + \edef\popwhatsit{\hskip\the\lastskip}\unskip + \else + \edef\popwhatsit{\vskip\the\lastskip\prevdepth\the\prevdepth}% + \vskip-\lastskip + \fi + \fi} + +%D The next macro can be used to keep track of classes of +%D boxes (handy for development cq.\ tracing). + +\def\dodotagbox#1#2#3% can be reimplemented + {\def\next##1##2##3##4% + {\vpack to \ht#2{##3\hpack to \wd#2{##1#3##2}##4}}% + \processaction + [#1] + [ l=>\next\relax\hfill\vfill\vfill, + r=>\next\hfill\relax\vfill\vfill, + t=>\next\hfill\hfill\relax\vfill, + b=>\next\hfill\hfill\vfill\relax, + lt=>\next\relax\hfill\relax\vfill, + lb=>\next\relax\hfill\vfill\relax, + rt=>\next\hfill\relax\relax\vfill, + rb=>\next\hfill\relax\vfill\relax, + tl=>\next\relax\hfill\relax\vfill, + bl=>\next\relax\hfill\vfill\relax, + tr=>\next\hfill\relax\relax\vfill, + br=>\next\hfill\relax\vfill\relax, + \s!default=>\next\hfill\hfill\vfill\vfill, + \s!unknown=>\next\hfill\hfill\vfill\vfill]} + +\def\dotagbox[#1]#2% + {\bgroup + \dowithnextbox + {\setbox\scratchbox\flushnextbox + \setbox\nextbox\ifhbox\nextbox\hpack\else\vpack\fi + \bgroup + \startoverlay + {\copy\scratchbox} + {\dodotagbox{#1}\scratchbox{\framed + [\c!background=\v!color,\c!backgroundcolor=\v!gray]{#2}}} + \stopoverlay + \egroup + \nextboxwd\the\wd\scratchbox + \nextboxht\the\ht\scratchbox + \nextboxdp\the\dp\scratchbox + \flushnextbox + \egroup}} + +\unexpanded\def\tagbox + {\dosingleempty\dotagbox} + +%D \macros +%D {coloredhbox,coloredvbox,coloredvtop, +%D coloredstrut} +%D +%D The following visualizations are used in some of the manuals: + +\definecolor[boxcolor:ht][r=.5,g=.75,b=.5] +\definecolor[boxcolor:dp][r=.5,g=.5,b=.75] +\definecolor[boxcolor:wd][r=.75,g=.5,b=.5] +\definecolor[strutcolor] [r=.5,g=.25,b=.25] + +\unexpanded\def\coloredbox#1% + {\dowithnextbox{#1{\hpack + {\blackrule[\c!width=\nextboxwd,\c!height=\nextboxht,\c!depth=\zeropoint,\c!color=boxcolor:ht]% + \hskip-\nextboxwd + \blackrule[\c!width=\nextboxwd,\c!height=\zeropoint,\c!depth=\nextboxdp,\c!color=boxcolor:dp]% + \hskip-\nextboxwd + \box\nextbox}}}#1} + +\unexpanded\def\coloredhbox{\coloredbox\hpack} +\unexpanded\def\coloredvbox{\coloredbox\vpack} +\unexpanded\def\coloredvtop{\coloredbox\tpack} + +\unexpanded\def\coloredstrut + {\color[strutcolor]{\def\strutwidth{2\points}\setstrut\strut}} + +\protect + +\continueifinputfile{m-visual.mkiv} + +\starttext + \simplethesis +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-zint.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-zint.mkiv new file mode 100644 index 00000000000..4957c846173 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-zint.mkiv @@ -0,0 +1,112 @@ +%D \module +%D [ file=m-zint, +%D version=2010.12.07, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Zint Barcode Generator, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Using \type {zint} seems to be the easiest way to generate +%D (PDF417) barcodes so therefore we now have this module. There +%D are proper (also windows) binaries at: +%D +%D \starttyping +%D http://www.zint.org.uk +%D \stoptyping +%D +%D There is a bit more code than needed as we want to be able to +%D feed names. + +\startluacode + +moduledata.zint = { } + +local format, lower, gsub = string.format, string.lower, string.gsub +local patterns = lpeg.patterns + +local zint = "zint" -- '"c:/program files/zint/zint.exe"' +local defaultcode = "PDF417" + +local whitespace = patterns.whitespace +local spaces = whitespace^0 +local key = (spaces / "") * patterns.digit^0 * (patterns.colon * spaces / "") +local value = (whitespace / "" + (1 - key))^1 +local pattern = lpeg.Cf(lpeg.Ct("") * (lpeg.Cg((lpeg.Cs(key) / tonumber) * (lpeg.Cs(value) / lower)) + patterns.anything)^0,rawset) + +local reverse + +local function cleancode(code) + if not code or code == "" then + code = defaultcode + end + return lower(gsub(code," ","")) +end + +local function numberofcode(code) + if not reverse then + local types = os.resultof(format("%s --types",zint)) or "" + local formats = lpeg.match(pattern,types) + if not formats or not next(formats) then + return code + end + reverse = table.swapped(formats) or { } + end + code = cleancode(code) + return reverse[code] or code +end + +function moduledata.zint.generate(code,data,suffix,options) + if not data or data == "" then + data = "unset" + end + local code = cleancode(code) + local base = format("zint-%s-%s",code,md5.hex(data)) + local name = file.addsuffix(base,suffix or "eps") + if not lfs.isfile(name) then + local temp = file.addsuffix(base,"tmp") + local code = numberofcode(code) + logs.simple("using 'zint' to generate '%s'",base) + io.savedata(temp,data) + os.execute(format('%s --barcode=%s --output="%s" --input="%s" %s',zint,code,name,temp,options or "")) + os.remove(temp) + end + return name +end + +\stopluacode + +\unprotect + +\unexpanded\def\barcode[#1]% [alternative=,text=] + {\bgroup + \getdummyparameters + [\c!alternative=,\c!text=,#1]% + \externalfigure + [\cldcontext{moduledata.zint.generate("\dummyparameter\c!alternative",\!!bs\dummyparameter\c!text\!!es)}]% + [#1,\c!alternative=,\c!text=]% + \egroup} + +\protect + +\continueifinputfile{m-zint.mkiv} + +\starttext + + \externalfigure[\cldcontext{moduledata.zint.generate("PDF417",[[Hans Hagen]])}] + \blank + \externalfigure[\cldcontext{moduledata.zint.generate("PDF417","Ton Otten")}] + \blank + \externalfigure[\cldcontext{moduledata.zint.generate("ISBN","9789490688011")}] + \blank + \barcode[text=Does It Work?,width=\textwidth] + \blank + \barcode[alternative=isbn,text=9789490688011,width=3cm] + +\stoptext + + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/ppchtex.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/ppchtex.mkiv new file mode 100644 index 00000000000..d1167d4143a --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/ppchtex.mkiv @@ -0,0 +1,3445 @@ +%D \module +%D [ file=ppchtex, +%D version=1997.03.19, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=\PPCHTEX\ (Plain Pictex Context cHemie \TEX), +%D author=Hans Hagen, +%D date=\currentdate, +%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten}, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\endinput + +% option=test => boxes +% dummy => file +% final => file / local run +% +% constante van phantom in definitie ONE: \setchemicaltextwidth 300 +% +% it would be interesting to rewrite this module with todays +% experiences and new context functionality, maybe ... + +% Deze module ondersteunt het zetten van chemische +% (structuur)formules. Hoewel de macro' zijn afgestemd op +% CONTEXT, zijn ze ook buiten deze zetomgeving te gebruiken. +% +% Dit is, afgezien van updates, de definitieve versie van +% PPCHTEX. Gebruikersgemak, eenvoud, flexibiliteit, en +% snelheid zijn inmiddels redelijk geoptimaliseerd. Dit neemt +% niet weg dat hier en daar nog verbetering mogelijk is. Dit +% zal dan ook nog gebeuren. +% +% Volgende versies zullen tenminste dezelfde functionaliteit +% hebben. We houden ons natuurlijk het recht voor de kwaliteit +% van de output te verbeteren. Daarnaast staan nog op het +% wensenlijstje: +% +% - optimaliseren in termen van proces-tijd +% - aanpassen naamgeving van interne macro's +% - toevoegen van functionaliteit +% - in \x!-vorm omzetten van GIVES, TB enz. +% +% De mix tussen engels en nederlands lijkt soms verwarrend. +% Meestal zijn verborgen macro's engels en zichtbare macro's +% nederlands. Het gebruik van [ ] en { } sluit aan op andere +% Context-macro's. Hetzelfde geldt voor instellingen en +% \start-\stop-constructies. +% +% De schijnbaar overbodige \bgroup-\egroup constructie +% garandeert aansluiting bij de Context-macro's voor het +% plaatsen van figuren, tabellen en andere floats. +% +% Binnen Context worden de macro's geladen met +% \gebruikextras[chemie]. Daarbij wordt een passende melding +% getoont. Buiten Context genereren we een melding: + +\doifundefined{usemodule} + {\writestatus{loading}{ConTeXt Chemical Macro's / 1996.3.1}} + +% Er kan gebruik worden gemaakt van PiCTeX of PStricks. Een +% van deze pakketten moet van te voren zijn geladen. +% +% \input prepictex.tex (i.g.v. LaTeX) +% \input pictex.tex +% \input postpictex.tex (i.g.v. LaTeX) +% +% of: +% +% \input multido.tex +% \input pstricks.tex +% \input pst-plot.tex +% +% In \CONTEXT\ kan men de modules m-pictex en m-pstricks +% gebruiken. De eerste module laad of efficiente wijze PiCTeX +% en de tweede module koppelt het PSTRICKS kleurmechanisme +% aan dat van \CONTEXT. + +% PSTricks: {-\chemicalangle} instead of {*0}, which produces +% faulty ps code when \chemicalangle=0 + +\startcommands dutch english german + + gotochemical: naarchemie gotochemical zurchemie + setupchemical: stelchemiein setupchemical stellechemieein + startchemical: startchemie startchemical startchemie + stopchemical: stopchemie stopchemical stopchemie + definechemical: definieerchemie definechemical definierechemie + chemical: chemie chemical chemie + toptext: boventekst toptext textueber + bottext: ondertekst bottext textunter + midtext: middentekst midtext textmitte + +\stopcommands + +\doifundefined{fiverm} % In the more recent LaTeX versions + {\font\fiverm=cmr5 } % \fiverm is no longer (pre)defined. + +\newconstant\chemicaldrawingmode + +\doifelsedefined{beginpicture} % PiCTeX + {\doifelsedefined{startMPdrawing} + {\chemicaldrawingmode\plustwo } % MetaPost + {\chemicaldrawingmode\zerocount}} % raw + {\doifelsedefined{psaxes} + {\chemicaldrawingmode\plusone } % PSTricks + {\chemicaldrawingmode\plusthree}} % unknown + +\ifcase\chemicaldrawingmode + \writestatus{ppchtex}{using PiCTeX} +\or + \writestatus{ppchtex}{using PSTricks (still experimental)} + \writestatus{ppchtex}{automatic sizing not (yet) supported} +\or + \writestatus{ppchtex}{using PiCTeX and MetaPost} +\else + \writestatus{ppchtex}{load PiCTeX (+pre/post) or PSTricks (+pst_plot) first} + \bgroup + \read16 to \exit + \egroup + \expandafter\endinput +\fi + +%I n=Chemie +%I c=\stelchemiein,\chemie +%I +%I Chemische formules kunnen worden gezet met behulp van de +%I onderstaande commando's: +%I +%I buiten $ en $$ : +%I +%I \chemie[segmenten][symbolen] +%I +%I \startchemie[instellingen] +%I \chemie... +%I \chemie... +%I \stopchemie +%I +%I en binnen $ en $$: +%I +%I \chemie{}{} +%I +%I Voor tekst, uitleg en voorbeelde verwijzen we vooralsnog +%I naar de handleiding. +%P +%I Het gedrag van de macro's kan worden ingesteld met: +%I +%I \stelchemiein[breedte=,hoogte=,links=,rechts=,boven=, +%I onder=,korps=,schaal=,status=,assenstelsel=,kader=, +%I variant=,optie=,formaat=,tekstformaat=,resolutie=, +%I offset=,letter=] +%I +%I Structuren kunnen worden voorgedefinieerd met het commando +%I +%I \definieerchemie[naam]{\chemie...} + +%S \startsetup +%S \command +%S [\!stelchemiein] +%S \type +%S [\c!vars!] +%S \variable +%S [\c!breedte] +%S [\c!number!,\v!passend] +%S [0] +%S \variable +%S [\c!hoogte] +%S [\c!number!,\v!passend] +%S [0] +%S \variable +%S [\c!links] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!rechts] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!boven] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!onder] +%S [\c!number!] +%S [0] +%S \variable +%S [\c!resolutie] +%S [\c!number!] +%S [\outputresolution] +%S \variable +%S [\c!korps] +%S [10pt,11pt,12pt] +%S [\bodyfontsize] +%S \variable +%S [\c!schaal] +%S [\v!klein,\v!middel,\v!groot] +%S [\v!middel] +%S \variable +%S [\c!formaat] +%S [\v!klein,\v!middel,\v!groot] +%S [\v!groot] +%S \variable +%S [\c!tekstformaat] +%S [\v!klein,\v!middel,\v!groot] +%S [\v!groot] +%S \variable +%S [\c!status] +%S [\v!start,\v!stop] +%S [\v!start] +%S \variable +%S [\c!kader] +%S [\v!aan,\v!uit] +%S [\v!uit] +%S \variable +%S [\c!assenstelsel] +%S [\v!aan,\v!uit] +%S [\v!uit] +%S \variable +%S [\c!optie] +%S [\v!test] +%S [] +%S \variable +%S [\c!variant] +%S [1,2] +%S [1] +%S \variable +%S [\c!offset] +%S [HIGH,LOW] +%S [LOW] +%S \variable +%S [\c!letter] +%S [\c!command!] +%S [\rm] +%S \stopsetup + +%S \startsetup +%S \command +%S [\v!startchemie] +%S \type +%S [\c!vars!\c!stp!] +%S \inheritvariable +%S [\v!stelchemiein] +%S [] +%S \stopsetup + +%S \startsetup +%S \command +%S [\v!chemie] +%S \type +%S [\c!vals!\c!vals!] +%S \value +%S [\c!list!] +%S [] +%S \value +%S [\c!list!] +%S [] +%S \stopsetup + +%S \startsetup +%S \command +%S [definieerchemie] +%S \type +%S [\c!val!\c!arg!] +%S \value +%S [\c!text!] +%S [] +%S \stopsetup + +\unprotect + +% Om te voorkomen dat sub- en superscripts botsen passen we +% wat fontdimen's aan (Knuth, The TeXBook, p179). Helaas +% kunnen deze instellingen niet lokaal worden gehouden door +% groeperen, vandaar dat een en ander moet worden geset ‚n +% gereset. +% +% Er dient een relatie te worden gelegd met de afmetingen +% van de letters. In een eerdere versie werden daartoe de +% \fontdimen's opgehoogd. Omdat dit problemen gaf bij +% scaled fonts, is bij nader inzien gekozen voor de +% onderstaande oplossing, waarbij de nieuwe waarden worden +% afgeleid van de x-height (\fontexheight). De factor 0.70 +% is min of meer experimenteel vastgesteld. Soms worden de +% regels iets verder uit elkaar gezet. Jammer. Italic fonts +% hebben grotere cijfers en vallen min of meer uit de boot. + +\newif\ifloweredsubscripts % this will be redone in the mkiv ways + +\def\setsubscripts + {\def\dosetsubscript##1##2##3% + {\dimen0=##3\fontexheight##2% + \setxvalue{@@\string##1\string##2}{\the##1##2\relax}% + ##1##2=\dimen0\relax}% + \def\dodosetsubscript##1##2% + {\dosetsubscript{##1}{\textfont 2}{##2}% + \dosetsubscript{##1}{\scriptfont 2}{##2}% + \dosetsubscript{##1}{\scriptscriptfont2}{##2}}% + %dodosetsubscript\mathsupnormal {?}% + \dodosetsubscript\mathsubnormal {.7}% + \dodosetsubscript\mathsubcombined{.7}% + \global\loweredsubscriptstrue} + +\def\resetsubscripts + {\ifloweredsubscripts + \def\doresetsubscript##1##2% + {\dimen0=\getvalue{@@\string##1\string##2}\relax + ##1##2=\dimen0}% + \def\dodoresetsubscript##1% + {\doresetsubscript{##1}{\textfont2}% + \doresetsubscript{##1}{\scriptfont2}% + \doresetsubscript{##1}{\scriptscriptfont2}}% + %dodoresetsubscript\mathsupnormal + \dodoresetsubscript\mathsubnormal + \dodoresetsubscript\mathsubcombined + \global\loweredsubscriptsfalse + \fi} + +\ifx\Umathchar\undefined \else + % for the moment we nil them, soon we will have a proper + % way to deal with this + \let\setsubscripts \relax + \let\resetsubscripts\relax +\fi + +\def\doresetsubscripts + {\resetsubscripts} + +\def\sethighsubscripts + {\resetsubscripts + \let\dosetsubscripts=\relax} + +\def\setlowsubscripts + {\def\dosetsubscripts{\setsubscripts}} + +\setlowsubscripts + +\newcount\horchemical % t.z.t. \newcounter +\newcount\verchemical % t.z.t. \newcounter +\newcount\txtchemical % t.z.t. \newcounter +\newcount\levchemical % t.z.t. \newcounter + +\newif\ifinchemical \inchemicalfalse +\newif\iffixedchemical \fixedchemicalfalse + +\newbox\chemicalsymbols + +% Eigenlijk moeten de constanten en variabelen in cont-nl.tex +% staan. Dit pakket is echter relatief onafhankelijk van CONTEXT. + +\definesystemvariable {chemical} + +\definesystemconstant {chemical} + +\definesystemconstant {translate} +\definesystemconstant {distance} +\definesystemconstant {mirror} +\definesystemconstant {rotate} +\definesystemconstant {substitute} +\definesystemconstant {angle} + +\definesystemconstant {executechemical} +\definesystemconstant {chemicaltextelement} +\definesystemconstant {chemicallinesegment} +\definesystemconstant {chemicalcircsegment} + +\def\chemicalspace {\quad} + +% begin van experiment: +% +% De onderstaande twee macro's kunnen worden gebruikt voor +% bijvoorbeeld een interactiemechanisme. +% +% \localgotochemical {verwijzing} {tekst} +% \localthisischemical {verwijzing} + +\def\dowithchemical% + {} + +\def\localgotochemical#1#2{\gotobox{#2}[#1]} +\def\localthisischemical#1{\pagereference[#1]} + +% eind van experiment + +\def\setchemicalmaximum #1 + {\def\maxchemical{#1}} + +\def\doifchemicalnumber#1#2#3% + {\doifelsenumber{#1} + {\ifnum#1>\maxchemical\relax + \writestatus{ppchtex}{number #1 is skipped}% + \else + #3% + \fi} + {\unknownchemical{#2}}}% + +\newif\ifsmallchemicaltext + +\let\@@localchemicalstyle\empty + +\unexpanded\def\setupchemicalformat[#1]% + {\processaction + [\getvalue{#1\c!size}] + [ \v!small=>\def\@@localchemicalformat{\scriptscriptstyle}, + \v!medium=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, + \v!big=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, + \s!unknown=>\def\@@localchemicalformat{\getvalue{#1\c!size}}]% + \processaction + [\getvalue{#1\c!textsize}] + [ \v!small=>\def\@@localchemicalstyle{\scriptscriptstyle}, + \v!medium=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi}, + \v!big=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi}, + \s!unknown=>\def\@@localchemicalstyle{\getvalue{#1\c!textsize}}]% + \processaction + [\getvalue{#1\c!scale}] + [ \v!small=>\def\@@localchemicalscale{500}, + \v!medium=>\def\@@localchemicalscale{625}, + \v!big=>\def\@@localchemicalscale{750}, + \s!unknown=>\def\@@localchemicalscale{\getvalue{#1\c!scale}}]} + +\def\@@currentchemicalformat + {\ifinchemical + \@@localchemicalformat + \else + \@@localchemicalstyle + \fi} + +\def\dosetupchemical[#1]% + {\getparameters[\??chemical\s!chemical][#1]% + \doifelse{\@@chemicalchemicaloffset}{LOW} + {\setlowsubscripts} + {\sethighsubscripts}% + \setupchemicalformat[\??chemical\s!chemical]% + \ignorespaces} + +\unexpanded\def\setupchemical + {\dosingleargument\dosetupchemical} + +\def\@@dochemicalstyle% % default mapping + {\@@chemicalstyle} + +\def\@@dochemicalcolor% % no mapping yet + {} + +\def\@@chemicalstyle % $inner-style$ % (overloaded) + {\@@chemicalchemicalstyle} % $$outer-style$$ + +\def\@@writechemicalstate#1#2% + {} + +\def\@@beginchemicallocalpicture + {\ifcase\chemicaldrawingmode + \beginpicture + \or + \pspicture(0,0)(0,0) % is this permitted ? + \or + \pushMPdrawing + \startMPdrawing + %prologues := 1 ; + %input mp-tool ; + u := 10*\@@chemicalunit; + bboxmargin := 0pt ; + pickup pencircle scaled 2u ; % ??? + \stopMPdrawing + \beginpicture + \fi} + +\def\@@endchemicallocalpicture#1#2% + {\ifcase\chemicaldrawingmode + \endpicture + \or + \endpspicture + \or + \resetchemicalcoordinates + \setbox2\hbox{\ignoreMPboxdepth\getMPdrawing}% + \wd2\zeropoint + \ht2\zeropoint + \dp2\zeropoint + \put {\box2} at 0 0 + \endpicture + \popMPdrawing + \fi} + +\def\@@beginchemicalpicture#1#2#3#4% + {\ifnum\chemicaldrawingmode=1 + \pspicture(#1,#3)(#2,#4)% + \def\account##1##2{}% + \psaxes[axesstyle=none,labels=none,ticks=none](#1,#3)(#2,#4)% + \else + \beginpicture + \setplotarea + x from {#1} to {#2}, + y from {#3} to {#4} + \iffixedchemical + \accountingon + \def\account##1##2% + {\put {} at {##1} {##2} }% + \else + \accountingoff + \def\account##1##2{}% + \fi + \fi + \ignorespaces} + +\def\@@endchemicalpicture% + {\ifcase\chemicaldrawingmode + \put {\box\chemicalsymbols} at 0 0 % elders + \endpicture + \or + \rput(0,0){\box\chemicalsymbols}% + \endpspicture + \or + \put {\box\chemicalsymbols} at 0 0 % elders + \ifMPdrawingdone + \resetchemicalcoordinates + \setbox2\hbox{\ignoreMPboxdepth\getMPdrawing}% + \wd2\zeropoint + \ht2\zeropoint + \dp2\zeropoint + \put {\box2} at 0 0 % + \fi + \endpicture + \fi} + +\def\@@setchemicalcoordinatesystem#1% + {\edef\@@chemicalunit{#1}% + \ifcase\chemicaldrawingmode + \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> % + \or + \psset{unit=\@@chemicalunit}% + \or + \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> % + \startMPdrawing + %input mp-tool ; + %prologues := 1 ; + u := 10*#1; + bboxmargin := 0pt ; + pickup pencircle scaled 2u ; % ??? + \stopMPdrawing + \fi} + +\ifx\MPdivten\undefined % hack to prevent overflows in mp + \def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} +\fi + +\def\@@setchemicalaxis#1#2#3#4% + {\ifcase\chemicaldrawingmode + \axis + bottom shiftedto y=0 + ticks from {#1} to {#2} by 500 / + \axis + left shiftedto x=0 + ticks from {#3} to {#4} by 500 / % + \or + \psaxes[labels=none,Dx=500,Dy=500](0,0)(#1,#3)(#2,#4)% + \or + \global\MPdrawingdonetrue + % we need to div beforehand because of mp limitations + \startMPdrawing + x1 := \MPdivten[#1]u ; x2 := \MPdivten[#2]u; + y1 := \MPdivten[#3]u ; y2 := \MPdivten[#4]u; + draw z1--(x2,y1)--z2--(x1,y2)--cycle ; + d := 50u ; dd := 10u ; + draw (x1,0)--(x2,0) ; + draw (0,y1)--(0,y2) ; + for i=d step -d until x1: draw (i,dd)--(i,-dd) ; endfor ; + for i=d step d until x2: draw (i,dd)--(i,-dd) ; endfor ; + for i=d step -d until y1: draw (-dd,i)--(dd,i) ; endfor ; + for i=d step d until y2: draw (-dd,i)--(dd,i) ; endfor ; + \stopMPdrawing + \fi} + +\def\@@setsecondchemicalplotsymbol% + {\ifcase\chemicaldrawingmode + \!!widtha=50.8mm + \divide\!!widtha by \@@chemicalresolution\relax + \plotsymbolspacing=\!!widtha + \setplotsymbol({\vrule\s!height\!!widtha\s!width\!!widtha})% + \fi} + +% Something for Dirk: + +\newcount \currentchemical + +%\newif \ifskipchemical + +\def\setchemicaldimensions#1#2#3% + {\bgroup + \global\advance\currentchemical by 1 + \dimen0=#1\relax + \dimen2=#2\relax + \dimen4=#3\relax + \setxvalue{chemical::\the\currentchemical}% + {\noexpand\docommand{\the\dimen0}{\the\dimen2}{\the\dimen4}}% + \egroup} + +\ifx\normalchemicalframe\undefined + \let\normalchemicalframe\hbox % hook for educational purposes +\fi + +\unexpanded\def\complexstartchemical[#1]% + {\copyparameters + [\??chemical][\??chemical\s!chemical] + [\c!width,\c!height,\c!left,\c!right,\c!top,\c!bottom, + \c!bodyfont,\c!size,\c!scale,\c!state,\c!frame,\c!axis,\c!factor, + \c!location,\c!option,\c!alternative,\c!resolution,\c!offset,\c!style, + \c!color,\c!rulecolor,\c!rulethickness]% + \getparameters + [\??chemical] + [#1]% + % + \setupchemicalformat[\??chemical]% + % + \ifnum\chemicaldrawingmode=2 + \resetMPdrawing + \fi + % + \doif{\@@chemicalalternative}{2} + {\@@setsecondchemicalplotsymbol}% + % + \doif{\@@chemicalaxis}\v!on + {\let\chemicalframe\hbox}% + % + \!!counta=250000 + \divide\!!counta by \@@localchemicalscale + \!!widtha=\@@chemicalbodyfont + \divide\!!widtha by \!!counta + \@@setchemicalcoordinatesystem{\the\!!widtha}% + % + % \!!counta = -x \!!countc = -y + % \!!countb = +x \!!countd = +y + % + \def\calculateaxis##1##2##3##4##5% + {##1=##3\relax + ##2=##4\relax + \ifnum##5=0 + \ifnum##3=0 + \ifnum##4=0 + ##1=2000 + ##2=2000 + \fi + \fi + \else + \ifnum##3=0 + \ifnum##4=0 + ##1=##5\relax + \divide##1 by 2 + ##2=##1\relax + \else + ##1=##5\relax + \advance##1 by -##2\relax + \fi + \else + \ifnum##4=0 + ##2=##5\relax + \advance##2 by -##1\relax + \fi + \fi + \fi}% + \fixedchemicalfalse + \doif\@@chemicalwidth\v!fit + {\edef\@@chemicalwidth + {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}% + \fixedchemicaltrue}% + \doif\@@chemicalheight\v!fit + {\edef\@@chemicalheight + {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}% + \fixedchemicaltrue}% + \doifelse\@@chemicallocation\v!intext + {\!!counta=0 \!!countb=0 + \!!counta=0 \!!countd=0 } + {\calculateaxis + \!!counta\!!countb + \@@chemicalleft\@@chemicalright\@@chemicalwidth + \calculateaxis + \!!countc\!!countd + \@@chemicalbottom\@@chemicaltop\@@chemicalheight}% + % + \edef\@@chemheight {\the\!!countc}% + \edef\@@chemdepth {\the\!!countd}% + \edef\@@chemicaltop {\the\!!countc}% + \edef\@@chemicalbottom{\the\!!countd}% + % + \doifelseinset\v!on{\@@chemicalframe,\@@chemicalaxis} + {\def\@@chemicalborder{\chemicalframe}} + {\def\@@chemicalborder{\normalchemicalframe}}% + % + \setbox0=\hbox\bgroup % this was a \vbox which took \hsize + % + \@@beginchemicalpicture + {-\the\!!counta}{\the\!!countb} + {-\the\!!countc}{\the\!!countd}% + \doif{\@@chemicalstate}\v!start + {\doif\@@chemicalaxis\v!on + {\@@setchemicalaxis + {-\the\!!counta}{\the\!!countb} + {-\the\!!countc}{\the\!!countd}}}% + \doifelse\@@chemicaloption\v!test + {\def\@@writechemicalstate##1##2% + {\convertargument##2\to\ascii + \writestatus{##1}{\ascii}}} + {\def\@@writechemicalstate##1##2{}}% + \ignorespaces} + +\def\dostartchemical% + {\catcode`\^=\superscriptcatcode% t.b.v. \enableduplication + \catcode`\_=\subscriptcatcode % t.b.v. de zekerheid + \begingroup + \inchemicaltrue + \def\toptext##1{\gdef\thetoptext{##1}\ignorespaces}\toptext{}% + \def\bottext##1{\gdef\thebottext{##1}\ignorespaces}\bottext{}% + \def\midtext##1{\gdef\themidtext{##1}\ignorespaces}\midtext{}% + \def\@@chemicalpostponed{}% + \complexorsimpleempty\startchemical} + +\unexpanded\def\startchemical + {\bgroup % t.b.v. ungrouped floats + \dostartchemical} + +\unexpanded\def\stopchemical + {\checkchemicalpicture + \@@endchemicalpicture + \egroup + \ifnum\chemicaldrawingmode=1 + \dimen0=\@@chemicalunit + \setbox0=\hbox{\lower\@@chemdepth\dimen0\box0}% + \ht0=\@@chemheight\dimen0 + \dp0=\@@chemdepth\dimen0 + \fi + \dimen0=\ht0 + \advance\dimen0 by \dp0 + \inchemicalfalse % enables \chemie{} in text + \setbox4=\alignedchemical\themidtext + \setbox6=\alignedchemical\thetoptext + \setbox8=\alignedchemical\thebottext + \setbox4=\hbox to \wd0 + {\strut\hss$\vcenter{\box4}$\hss}% + \setbox2=\vbox to \dimen0 + {\hbox to \wd0{\strut\hss\box6\hss} + \vfill + \hbox to \wd0{\strut\hss\box8\hss} + \vss}% disables the depth + \wd0=0pt \wd4=0pt + \ht2=\ht0 \dp2=\dp0 + \ht4=\ht0 \dp4=\dp0 + \@@chemicalborder{\box0\box4\box2}% text on top of chemicals + \endgroup + \ignorespaces + \egroup} % t.b.v. ungrouped floats + +\def\alignedchemical#1% + {\vtop + {\def\par{\egroup\hbox\bgroup\strut}% + \let\\=\par + \let\endgraf=\par + \hbox\bgroup\strut#1\egroup}} + +% \setchemicalcoordinates{#1}{#2} +% +% #1: verplaatsing in x-richting +% #2: verplaatsing in y-richting + +\newif\ifchemicaldirection + +\def\checkchemicaldirection#1#2% + {\ifchemicaldirection + \ifnum#1>0 \advance\horchemical -\chemicaldirection \fi + \ifnum#1<0 \advance\horchemical +\chemicaldirection \fi + \ifnum#2>0 \advance\verchemical -\chemicaldirection \fi + \ifnum#2<0 \advance\verchemical +\chemicaldirection \fi + \chemicaldirectionfalse + \fi} + +\def\processchemicaldirection% + {\chemicaldirectiontrue\processchemicaltranslate} + +\def\setchemicalcoordinates#1#2% + {\advance\horchemical #1\relax + \advance\verchemical #2\relax + \checkchemicaldirection{#1}{#2}% + \!!counta=-\horchemical\edef\chemicalxoffset{\the\!!counta}% + \!!countb=-\verchemical\edef\chemicalyoffset{\the\!!countb}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} + \fi} + +\def\resetchemicalcoordinates + {\horchemical=0 + \verchemical=0 + \edef\chemicalxoffset{0}% + \edef\chemicalyoffset{0}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at 0 0 + \fi} + +\def\restorechemicalcoordinates + {%\writestatus{ppchtex}{restoring \the\horchemical,\the\verchemical}% + \edef\chemicalxoffset{\the\horchemical}% + \edef\chemicalyoffset{\the\verchemical}% + \ifnum\chemicaldrawingmode=1 + % njet + \else + \setcoordinatesystem point at {\the\horchemical} {\the\verchemical} + \fi} + +\def\setchemicaltranslate #1 #2 #3 + {\setvalue{\s!translate#1}{\setchemicalcoordinates{#2}{#3}}} + +\def\processchemicaltranslate#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{MOV#1} + {\ifnum##1=0 + \def\chemicaloffset{0}% incompatible change + \resetchemicalcoordinates + \else + \getvalue{\s!translate##1}% + \dochemicaloffset{##1}% + \def\chemicaloffset{0}% + \fi}}% + \doprocess[#1]} + +\def\setchemicaldistance #1 + {\setvalue{\s!distance1}{\setchemicalcoordinates{-#1}{ 0}}% + \setvalue{\s!distance2}{\setchemicalcoordinates{ 0}{ #1}}% + \setvalue{\s!distance3}{\setchemicalcoordinates{ #1}{ 0}}% + \setvalue{\s!distance4}{\setchemicalcoordinates{ 0}{-#1}}} + +\def\setchemicaldirection #1 + {\def\chemicaldirection{#1}} + +\def\processchemicaldistance#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{ADJ#1} + {\ifnum##1=0 + \resetchemicalcoordinates + \else + \def\@@chemicalpostponed{\getvalue{\s!distance##1}}% + \@@chemicalpostponed + \fi}}% + \doprocess[#1]} + +\def\setchemicalsubstitute #1 + {\setvalue{\s!substitute1}{\setchemicalcoordinates{-#1}{ 0}}% + \setvalue{\s!substitute2}{\setchemicalcoordinates{ 0}{ #1}}% + \setvalue{\s!substitute3}{\setchemicalcoordinates{ #1}{ 0}}% + \setvalue{\s!substitute4}{\setchemicalcoordinates{ 0}{-#1}}} + +\def\processchemicalsubstitute#1% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{SUB#1} + {\ifnum##1=0 + \resetchemicalcoordinates + \else + \def\@@chemicalpostponed{\getvalue{\s!substitute##1}}% + \@@chemicalpostponed + \fi}}% + \doprocess[#1]} + +% Het is mogelijk een offset of move meerdere malen uit te +% voeren, door een nummer voor het commando te plaatsen. + +\def\chemicalrepeat {1} + +\def\redoprocesschemical[#1#2]% + {\doifelseinstring{#1}{0123456789.} + {\edef\chemicalrepeat{\chemicalrepeat#1}% + \redoprocesschemical[#2]} + {\processchemical[#1#2]% + \def\chemicalrepeat{1}}} + +\def\doprocesschemical[#1#2]#3% + {\doifelseinstring{#1}{0123456789.} + {\def\chemicalrepeat{#1}% + \redoprocesschemical[#2]} + {#3}} + +% \dochemicaloffset{#1} +% +% #1: binding + +\def\chemicaloffset{0} + +\def\processchemicaloffset#1% + {\dimen0=62500 sp % real calc on cardinals, funny number + \dimen0=\chemicalrepeat\dimen0 + \divide\dimen0 by \@@localchemicalscale + \!!counta=\dimen0 + \def\doprocess[##1##2]% + {\doifelseinstring{##1}{128} + {\edef\chemicaloffset{\the\!!counta}} + {\doifelseinstring{##1}{456} + {\edef\chemicaloffset{-\the\!!counta}} + {\doifelse{##1}{0} + {\edef\chemicaloffset{0}} + {\unknownchemical{OFF#1}}}}}% + \doprocess[#1]} + +\def\dochemicaloffset#1% + {\ifnum\chemicaloffset=0 + \def\undochemicaloffset{}% + \else + \setchemicalcoordinates{-\chemicaloffset}{0}% + \def\undochemicaloffset% + {\setchemicalcoordinates{\chemicaloffset}{0}% + \def\undochemicaloffset{}}% + \fi} + +\def\processchemicalphantom#1#2% + {\setbox0=\hbox + {\def\splitoff##1????{##1}% + $\@@dochemicalstyle{\@@localchemicalformat\splitoff#2}$}% + \dimen0=.25\wd0 + \divide\dimen0 by \@@localchemicalscale + \!!counta=\dimen0 + \doifelseinstring{#1}{128} + {\edef\chemicaloffset{\the\!!counta}} + {\doifelseinstring{#1}{456} + {\edef\chemicaloffset{-\the\!!counta}} + {\doifelse{#1}{0} + {\edef\chemicaloffset{0}} + {\unknownchemical{OF#1:#2}}}}} + +% \dosetchemicalrotation{#1}{#2} +% +% #1: cos(phi) +% #2: sin(phi) + +\def\chemicalrotation {1} +\def\chemicalangle {0} +\def\chemicalxoffset {0} +\def\chemicalyoffset {0} + +\def\setchemicalmirror#1% + {\setvalue{\s!mirror#1}{*}} + +\def\resetchemicalmirror#1% + {\resetvalue{\s!mirror#1}} + +\def\togglechemicalmirror#1% + {\doifelse{\getvalue{\s!mirror#1}}{*} + {\resetchemicalmirror{#1}} + {\setchemicalmirror{#1}}} + +\def\setchemicalrotation #1 #2 #3 #4 #5 #6 #7 #8 #9 + {\setvalue{\s!rotate1.#1}{\dosetchemicalrotation{#2}{#3}}% + \setvalue{\s!rotate2.#1}{\dosetchemicalrotation{#4}{#5}}% + \setvalue{\s!rotate3.#1}{\dosetchemicalrotation{#6}{#7}}% + \setvalue{\s!rotate4.#1}{\dosetchemicalrotation{#8}{#9}}} + +\def\setchemicalangle #1 #2 #3 #4 #5 + {\setvalue{\s!angle1.#1}{\dosetchemicalangle{#2}}% + \setvalue{\s!angle2.#1}{\dosetchemicalangle{#3}}% + \setvalue{\s!angle3.#1}{\dosetchemicalangle{#4}}% + \setvalue{\s!angle4.#1}{\dosetchemicalangle{#5}}} + +\def\chemicalrotate[#1]% + {\doifelsedefined{\s!mirror#1} + {\getvalue{\s!rotate\chemicalrotation.#1\getvalue{\s!mirror#1}}% + \getvalue{\s!angle\chemicalrotation.#1\getvalue{\s!mirror#1}}} + {\getvalue{\s!rotate\chemicalrotation.#1}% + \getvalue{\s!angle\chemicalrotation.#1}}} + +\def\dosetchemicalangle#1% zwak zie onder + {\def\chemicalangle{#1}} + +\def\dosetchemicalrotation#1#2% + {\ifnum\chemicaldrawingmode=1 + % njet + \else + \startrotation by {#1} {#2} %% \stoprotation (t.b.v. testen) + \fi} + +\def\doresetchemicalrotation + {\ifnum\chemicaldrawingmode=1 + % njet + \else + \stoprotation + \fi} + +\def\processchemicalrotation#1% + {\def\doprocess[##1##2]% + {\doifelsenumber{##1} + {\def\chemicalrotation{##1}} + {\unknownchemical{ROT#1}}}% + \doprocess[#1]} + +% \filtertextelement[#1][#2][#3][#4] +% +% #1: volgnummer +% #2: offset in uitlijningen +% #3: lijst met uitlijningen -> \chemicalloca +% #4: lijst met teksten -> \chemicaltext + +\def\setchemicallocation#1% + {\doifelse{#1}{} + {\edef\chemicalloca{c}} + {\edef\chemicalloca{#1}}} + +\newif\iffixedchemicaltext + +\def\filterchemicaltextelement[#1][#2][#3][#4]% + {\ifchemicaltextconstant + \def\chemicaltext{#4}% + \setchemicallocation{}% + \else + \ifnum#1=0\relax + \setchemicallocation{}% + \else + \iffixedchemicaltext + \!!counta#2 + \else + \!!counta=\chemicalrotation + \advance\!!counta -1 + \multiply\!!counta #2 + \advance\!!counta #1 + \fi + \getfromcommalist[#3][\the\!!counta]% + \setchemicallocation\commalistelement + \fi + \ifchemicalpicture + \let\chemicaltext\relax + \else + \advance\txtchemical 1 + \getfromcommalist[#4][\txtchemical]% + \let\chemicaltext\commalistelement + \fi + \fi + \fixedchemicaltextfalse} + +% \putchemicaltext{#1}{#2} +% +% #1 : x-coordinaat +% #2 : y-coordinaat +% +% \chemicaltext en \chemicalloca worden met \gettextelement +% opgehaald uit de tweede set bij \chemie +% +% Ten behoeve van testdoeleinden wordt gebruik gemaakt van +% \chemicalframe in plaats van het meer sjieke, maar tevens +% meer trage \framed. + +\ifx\ruledhbox\undefined + \def\chemicalframe#1% + {\hbox + {\vrule\hskip-.4pt + \vbox{\hrule\vskip-.4pt\hbox{#1}\vskip-.4pt\hrule}% + \hskip-.4pt\vrule}} +\else + \def\chemicalframe#1% + {\ruledhbox{#1}} +\fi + +\def\doputchemicaltext#1 [#2] at #3 #4 % + {\ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[#2]{\chemicalangle}(#3,#4){#1}}}% + \else + \put {#1} [#2] at {#3} {#4} % + \fi} + +\def\dodoifsinglelocation#1#2\\#3% + {\ifx#2\relax#3\fi} + +\def\doifelsesinglelocation#1% + {\expandafter\dodoifsinglelocationelse#1\relax\\} + +\let\doifsinglelocationelse\doifelsesinglelocation + +\def\putchemicaltext#1#2% + {\enablechemicalspecials + \ifchemicalpicture + \setchemicalpicture{#1}{#2}% + \else + \doifelse\@@chemicaloption\v!test + {\def\@@chemicalframe{\chemicalframe}} + {\def\@@chemicalframe{}}% + \dosetsubscripts + \setbox2=\hbox{\@@dochemicalcolor + $\@@dochemicalstyle{\@@localchemicalformat \chemicaltext}$}% + \setbox4=\hbox{$\@@dochemicalstyle{\@@localchemicalformat C\normalsubscript2\normapsuperscript2}$}% + \setbox6=\hbox{$\@@dochemicalstyle{\@@localchemicalformat O}$}% or C + \doresetsubscripts + \doifnot\@@chemicallocation\v!intext + {\ht2=\ht4 + \dp2=\dp4}% + \setbox2=\hbox{\@@chemicalframe{\box2}}% + \ifdim\wd2>\wd6 + \doifelse{#1}{0} + {\doifnot{#2}{0}{\wd2=\wd6}} + {%\doifsinglelocation\chemicalloca + {\doifinset{\chemicalloca}{t,b}{\wd2=\wd6}}}% common ? + \fi + \expanded + {\doputchemicaltext + {\noexpand\dowithchemical{\copy2}} % per se \copy2 i.p.v. \box2 + [\chemicalloca] at {#1} {#2} } + \nomoreaccounting + \fi + \disablechemicalspecials} + +\def\setchemicaltextelement #1 #2 #3 + {\setvalue{\s!chemicaltextelement#1}{\putchemicaltext{#2}{#3}}} + +\def\getchemicalfixedtextelement% + {\fixedchemicaltexttrue + \getchemicaltextelement} + +\def\getchemicaltextelement[#1][#2][#3][#4][#5]% + {\filterchemicaltextelement[#2][#3][#4][#5]% + \doifelse{#2}{0} + {\dochemicaloffset{#2}% % incompatible change + \putchemicaltext{0}{0}% + \undochemicaloffset} % incompatible change + {\chemicalrotate[#2]% + \dochemicaloffset{#2}% + \def\chemicaltextelementnumber{#2}% + \getvalue{\s!chemicaltextelement#1}% + \getvalue{\s!chemicaltextelement#11}% + \getvalue{\s!chemicaltextelement#12}% + \getvalue{\s!chemicaltextelement#13}% + \undochemicaloffset}} + +\def\processchemicaltextelement#1#2#3#4#5% + {\def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#1#2} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#1#2} + {\getchemicaltextelement[#1][##1][#4][#5][#3]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {\getchemicaltextelement[#1][##1][#4][#5][#3]% + \doifnot{##2}{?}{\doprocess[##2##3##4##5]}}}}}% + \doprocess[#2]% + \smallchemicaltextfalse} + +\def\processchemicalsmalltextelement% + {\smallchemicaltexttrue\processchemicaltextelement} + +\def\processchemicalsmalltextconstant% + {\smallchemicaltexttrue\processchemicaltextconstant} + +\def\processchemicalunrotatedtextelement#1#2#3#4#5#6% + {\bgroup + \xdef\@@xxx{0}% + \xdef\@@yyy{0}% + \def\putchemicaltext##1##2% + {\xdef\@@xxx{##1}% + \xdef\@@yyy{##2}}% + \getvalue{\s!chemicaltextelement#1}% + \egroup + \bgroup + \def\doputchemicaltext##1 [##2] at ##3 ##4 % + {\ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\rput{\chemicalangle}(\@@xxx,\@@yyy){\expanded{\rput[##2](##3,##4){##1}}}}% + \else + \put + {\stoprotation \setcoordinatesystem point at 0 0 + \expanded{\put {##1} [##2] at {##3} {##4} }} + at {\@@xxx} {\@@yyy} + \fi}% + \processchemicaltextelement{#2}{#3}{#4}{#5}{#6}% + \egroup} + +\newif\ifchemicaltextconstant + +\def\processchemicaltextconstant#1#2#3#4% + {\chemicaltextconstanttrue + \let\@@oldchemicalframe\@@chemicalframe + \let\@@chemicalframe\relax + \processchemicaltextelement{#1}{#2}{#3}{#4}{}% + \let\@@chemicalframe\@@oldchemicalframe + \chemicaltextconstantfalse} + +% \plotchemicalline{#1}{#2}{#3}{#4} +% +% #1: x-coordinaat beginpunt +% #2: y-coordinaat beginpunt +% #3: x-coordinaat eindpunt +% #4: y-coordinaat eindpunt + +\newconstant\chemicallinetype + +\def\doplotchemicalline + {\!!counte=\!!countc \advance\!!counte by -\!!counta + \!!countf=\!!countd \advance\!!countf by -\!!countb + \bgroup + \ifcase\chemicaldrawingmode + \ifcase\chemicallinetype + % 0 : normal line + \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /% + \or + % 1 : normal arrow + \arrow <5pt> [.2,.67] from {\!!counta} {\!!countb} to {\!!countc} {\!!countd} + \or + % 2 : reverse arrow + \arrow <5pt> [.2,.67] from {\!!countc} {\!!countd} to {\!!counta} {\!!countb} + \or + % 3 : unrotated line + \put {\stoprotation \setcoordinatesystem point at 0 0 + \plot 0 0 {\!!counte} {\!!countf} /} + [\chemicallineposition] at {\!!counta} {\!!countb} + \else + % 4 : dashed line + \findlength {\plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /}% + \setdashesnear <2pt> for <\totalarclength>% + \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /% + \fi + \or + \ifcase\chemicallinetype + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \or + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline{->}(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \or + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline{<-}(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \or + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[\chemicallineposition]{-\chemicalangle}% + (\!!counta,\!!countb){\psline(0,0)(\!!counte,\!!countf)}}}% + \else + \psset{linestyle=dashed}% + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}% + \fi + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + x3 := \MPdivten[\the\!!counte]u ; + y3 := \MPdivten[\the\!!countf]u ; + \ifcase\chemicallinetype + % 0 : normal line + draw ((z1--z2) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \or + % 1 : normal arrow + drawarrow ((z1--z2) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \or + % 2 : reverse arrow + drawarrow ((z2--z1) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \or + % 3 : unrotated line % nog \chemicalineposition: t/b + draw (origin--z3) + shifted (z1 rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \else + % 4 : dashed line + draw ((z1--z2) rotatedaround(origin,-\chemicalangle)) + shifted z0 dashed dashpattern(on 5.5u off 6u) ; + \fi + \stopMPdrawing + \fi + \egroup + \account\!!counta\!!countb + \account\!!countc\!!countd} + +\def\plotchemicalline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \doplotchemicalline} + +\def\plotchemicalfactorline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifdim\@@chemicalfactor\onepoint=\onepoint \else + \scratchdimen\!!counta\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!counta\scratchdimen + \scratchdimen\!!countc\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!countc\scratchdimen + \fi + \doplotchemicalline} + +\def\plotchemicalzline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + filldraw (( + \ifnum\chemicalangle>180 + z1--z2 + \else\ifnum\chemicalangle<90 + z1--(z2 shifted (-2u,+2u))--(z2 shifted (+2u,-2u)) + \else\ifnum\chemicalangle=90 + (z1 shifted (-2u,+2u))--(z1 shifted (+2u,-2u))-- + (z2 shifted (+2u,+2u))--(z2 shifted (-2u,-2u)) + \else + (z1 shifted (+2u,+2u))--(z1 shifted (-2u,-2u))--z2 + \fi\fi\fi + --cycle) rotatedaround(origin,-\chemicalangle)) shifted z0 ; + \stopMPdrawing + \else + \doplotchemicalline + \ifnum\chemicalangle>180 \else + \ifnum\chemicalangle=90 + \advance\!!counta by -20 \advance\!!countc by -20 + \doplotchemicalline + \advance\!!counta by 40 \advance\!!countc by 40 + \else\ifnum\chemicalangle<90 + \advance\!!countc by -20 \advance\!!countd by +20 + \doplotchemicalline + \advance\!!countc by +40 \advance\!!countd by -40 + \else + \advance\!!counta by 20 \advance\!!countb by 20 + \doplotchemicalline + \advance\!!counta by -40 \advance\!!countb by -40 + \fi\fi + \fi + \doplotchemicalline + \fi} + +\def\plotchemicaldeltaline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + filldraw ((z1--(z2 rotatedaround(z1,5))--(z2 rotatedaround(z1,-5)) + --cycle) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\setchemicallinesegment #1 #2 #3 #4 #5 + {\setvalue{\s!chemicallinesegment#1}{\plotchemicalline{#2}{#3}{#4}{#5}}} + +\def\setchemicalfactorlinesegment #1 #2 #3 #4 #5 + {\setvalue{\s!chemicallinesegment#1}{\plotchemicalfactorline{#2}{#3}{#4}{#5}}} + +\def\getchemicallinesegment[#1][#2]% + {\chemicalrotate[#1]% + \dochemicaloffset{#1}% + \getvalue{\s!chemicallinesegment#2}% + \getvalue{\s!chemicallinesegment#21}% + \getvalue{\s!chemicallinesegment#22}% + \undochemicaloffset} + +\def\getprivatechemicallinesegment[#1][#2]% + {\chemicalrotate[#1]% + \getvalue{\s!chemicallinesegment#2#1}} + +\def\doprocesschemicallinesegment#1#2#3#4#5% + {\chemicallinetype#1\relax + \def\chemicallineposition{#2}% + \def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#4#5} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#4#5} + {#3[##1][#4]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {#3[##1][#4]% + \doifnot{##2}{?} + {\doprocess[##2##3##4##5]}}}}}% + \doprocess[#5]} + +\def\processchemicallinesegment + {\doprocesschemicallinesegment0c\getchemicallinesegment} + +\def\processchemicalzlinesegment#1#2% + {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \bgroup + \def\plotchemicalline{\plotchemicalzline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicaldeltalinesegment#1#2% + {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \bgroup + \def\plotchemicalline{\plotchemicaldeltaline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processprivatechemicallinesegment% + {\doprocesschemicallinesegment0c\getprivatechemicallinesegment} + +\def\processchemicaldownarrowsegment% + {\doprocesschemicallinesegment1c\getchemicallinesegment} + +\def\processchemicaluparrowsegment% + {\doprocesschemicallinesegment2c\getchemicallinesegment} + +\def\processchemicalunrotatedlinesegment#1% + {\doprocesschemicallinesegment3{#1}\getchemicallinesegment} + +\def\processchemicaldashedlinesegment + {\doprocesschemicallinesegment4c\getchemicallinesegment} + +\def\plotchemicaldasheddeltaline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + z20 = z2 rotatedaround(z1,+5) ; + z21 = z2 rotatedaround(z1,-5) ; + draw (z1 rotatedaround(origin,-\chemicalangle)) shifted z0 ; + save n ; n := 5 ; + for i=1 upto n : + draw ((((z20--z21) shifted -z2) shifted (i/n)[z2,z1]) + rotatedaround(origin,-\chemicalangle)) shifted z0 ; + endfor + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\plotchemicalwavyline#1#2#3#4% + {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \ifnum\chemicaldrawingmode=2 + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + save d ; pair d ; + d := z2 rotatedaround(z1,+5) shifted -z2 ; + save n ; n := 4 ; + draw ((for i=0 upto n-1 : + ((i)/n)[z1,z2] .. + ((i+.25)/n)[z1,z2] shifted d .. + ((i+.50)/n)[z1,z2] .. + ((i+.75)/n)[z1,z2] shifted -d .. + endfor + z2) rotatedaround(origin,-\chemicalangle)) shifted z0 ; + \stopMPdrawing + \account{#1}{#2}% + \account{#3}{#4}% + \else + \doplotchemicalline + \advance\!!countc by 16 \advance\!!countd by -21 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -8 \advance\!!countd by 14 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \advance\!!countc by -4 \advance\!!countd by 7 + \doplotchemicalline + \fi} + +\def\processchemicaldasheddeltalinesegment#1#2% + {\bgroup + \def\plotchemicalline{\plotchemicaldasheddeltaline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicalwavylinesegment#1#2% + {\bgroup + \def\plotchemicalline{\plotchemicalwavyline}% + \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}% + \egroup} + +\def\processchemicalopenend#1#2% + {\doprocesschemicallinesegment0c\doprocesschemicalopenend{#1}{#2}} + +\def\doprocesschemicalopenend[#1][#2]% + {\chemicalrotate[#1]% + \dochemicaloffset{#1}% + \ifcase\chemicaldrawingmode + \beginpicture + \setquadratic\plot + 300 0 400 0 + 500 0 550 75 + 600 0 650 -75 + 700 0 750 75 + 800 0 850 -75 + 900 0 950 0 + 1050 0 / + \endpicture + \or + \rput{-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psline(300,0)(500,0)% + \rput(500,0){\psplot[yunit=75,plotstyle=curve]{0}{720}{x sin}}% + \psline(950,0)(1050,0)}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw + (((30.0u,0)--(50.0u,0){up}..(55.0u,7.5u).. + (60.0u,0)..(65.0u,-7.5u)..(70.0u,0).. + (75.0u,7.5u)..(80.0u,0)..(85.0u,-7.5u)..{up} + (90.0u,0)--(105.0u,0)) rotatedaround(origin,-\chemicalangle)) + shifted z0 ; + \stopMPdrawing + \fi + \undochemicaloffset} + +% \plotchemicalcircle{#1}{#2}{#3}{#4} +% +% #1: lengte van de boog in graden +% #2: x-coordinaat eindpunt +% #3: y-coordinaat eindpunt + +\newif\ifchemicaldotted + +\def\plotchemicalcircle#1#2#3#4#5#6% + {\bgroup + \ifcase\chemicaldrawingmode + \ifchemicaldotted + \findlength{\circulararc {#4} degrees from {#5} {#6} center at {0} {0} }% + \divide\totalarclength by 6 + \def\b{\the\totalarclength}% + \divide\totalarclength by 2 + \def\a{\the\totalarclength}% + \setdashpattern <\a,\b,\b,\b,\b,\b,\a> + \fi + \circulararc {#4} degrees from {#5} {#6} center at {0} {0} % + \or + \ifchemicaldotted + \psset{linestyle=dashed}% + \fi + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\psarc(0,0){#3}{#1}{#2}}% + \or + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + r := \MPdivten[#3]*2u; + x0 := \MPdivten[\chemicalxoffset]u ; + y0 := \MPdivten[\chemicalyoffset]u ; + draw ((subpath (#1/45,#2/45) of (fullcircle scaled (r))) + rotatedaround (origin,\chemicalangle+150)) + shifted z0 \ifchemicaldotted dashed withdots \fi ; + \stopMPdrawing + \fi + \egroup} + +\def\setchemicalcircsegment #1 #2 #3 #4 #5 #6 #7 + {\setvalue{\s!chemicalcircsegment#1}{\plotchemicalcircle{#2}{#3}{#4}{#5}{#6}{#7}}} + +\def\getchemicalcircsegment[#1][#2]% + {\chemicalrotate[#1]% + \getvalue{\s!chemicalcircsegment#2}} + +\def\doprocesschemicalcircsegment#1#2% + {\def\doprocess[##1##2##3##4##5]% + {\doifelse{##1}{?} + {\doprocess[1..\maxchemical ????]} + {\doifchemicalnumber{##1}{#1#2} + {\doifelse{##2##3}{..} + {\doifchemicalnumber{##4}{#1#2} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##1}{##4} + {\!!counta=##1\relax + \advance\!!counta by 1 + \edef\nextsegment{\the\!!counta}% + \doprocess[\nextsegment..##4##5]}}} + {\getchemicalcircsegment[##1][#1]% + \doifnot{##2}{?} + {\doprocess[##2##3##4##5]}}}}}% + \doprocess[#2]} + +\def\processchemicalcircsegment% + {\chemicaldottedfalse\doprocesschemicalcircsegment} + +\def\processchemicaldottsegment% + {\chemicaldottedtrue\doprocesschemicalcircsegment} + +\let\endchemicalpicture = \relax +\let\checkchemicalpicture = \relax +\let\nomoreaccounting = \relax + +\newif\ifchemicalpicture + +\def\beginchemicalpicture#1% NO PSTRICKS SUPPORT YET + {\checkchemicalpicture + \bgroup % DOES NOT HANDLE AUTOWIDTH/HEIGHT + \chemicalpicturetrue + \processchemical[#1]} + +\def\setchemicalpicture#1#2% + {\chemicalpicturefalse + \def\endchemicalpicture% + {\@@endchemicallocalpicture{#1}{#2}% + \egroup + \ifnum\chemicaldrawingmode=1 + \rput + {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)% + {\expanded{\rput[\chemicalloca]{\chemicalangle}(#1,#2){\box\nextbox}}}% + \else + \expanded{\put{\box\nextbox}[\chemicalloca] at {#1} {#2} } + \fi + \egroup}% + \def\checkchemicalpicture% + {\ifx\endchemicalpicture\relax \else + \writestatus{ppchtex}{missing end of picture (PE)}% + \endchemicalpicture + \fi}% + \setbox\nextbox=\hbox\bgroup + \@@beginchemicallocalpicture + % alternatief: gewoon accounting, en zelf l,r afhandelen + \ifnum\chemicaldrawingmode=1 + % njet + \else + \accountingon + \let\nomoreaccounting=\accountingoff + \fi} + +\def\doskipchemical[#1][#2]% + {{\tt[ppchtex]}} + +\def\skipchemical% + {\dodoubleargument\doskipchemical} + +\def\complexchemical% met \expandafter + {\ifinchemical + \expandafter\dochemical + \else + \writestatus{ppchtex}{the [][]-alternative is not permitted here}% + \expandafter\skipchemical + \fi} + +\newif\ifinnerchemical + +\def\dosimplechemical#1#2#3% + {\doifelsedefined{\??chemical\c!location} + {\writestatus{ppchtex}{the {}{}-alternative is not permitted here}} + {\ifinnerchemical + \let\chemicalsign = \chemicalinnersign + \let\chemicalmolecule = \chemicalinnermolecule + \let\chemicalsinglearrow = \chemicalsingleinnerarrow + \let\chemicaldoublearrow = \chemicaldoubleinnerarrow + \let\chemicaltwintiparrow = \chemicaltwintipinnerarrow + \else + \let\chemicalsign = \chemicaloutersign + \let\chemicalmolecule = \chemicaloutermolecule + \let\chemicalsinglearrow = \chemicalsingleouterarrow + \let\chemicaldoublearrow = \chemicaldoubleouterarrow + \let\chemicaltwintiparrow = \chemicaltwintipouterarrow + \fi + \disablechemicalspecials + \processallactionsinset + [#1] + [ HIGH=>\sethighsubscripts, + LOW=>\setlowsubscripts, + PLUS=>\chemicalsign{+}, + GIVES=>\chemicalsinglearrow{#2}{#3}, + EQUILIBRIUM=>\chemicaldoublearrow{#2}{#3}, + MESOMERIC=>\chemicaltwintiparrow{#2}{#3}, + SINGLE=>\singlechemicalbond, + DOUBLE=>\doublechemicalbond, + TRIPLE=>\triplechemicalbond, + +=>\chemicalsign{+}, + ->=>\chemicalsinglearrow{#2}{#3}, + <->=>\chemicaldoublearrow{#2}{#3}, + <>=>\chemicaltwintiparrow{#2}{#3}, + -=>\singlechemicalbond, + --=>\doublechemicalbond, + ---=>\triplechemicalbond, + \s!unknown=>\enablechemicalspecials + \chemicalmolecule{\commalistelement}{#2}{#3}]}} + +\def\dosimplechemicalA#1#2#3% % evt: {#1,\relax} + {\let\chemicalspace=\relax + \@EA\dosimplechemical\@EA{\@@chemicalchemicaloffset,#1}{#2}{#3}% + \egroup} + +\def\dosimplechemicalB#1#2#3% + {\dosimplechemical{#1}{#2}{#3}% + \egroup} + +\def\dosimplechemicalC#1#2#3% + {$\simplechemical{#1}{#2}{#3}$% + \egroup} % erbij + +\def\simplechemical + {\ifinner + \innerchemicaltrue + \else + \innerchemicalfalse + \fi + \bgroup + \catcode`\^=\superscriptcatcode % t.b.v. \enableduplication + \catcode`\_=\subscriptcatcode % t.b.v. de zekerheid + \ifmmode + \ifinnerchemical + \def\next{\dotriplegroupempty\dosimplechemicalA}% + \else + \def\next{\dotriplegroupempty\dosimplechemicalB}% + \fi + \else + \def\next{\dotriplegroupempty\dosimplechemicalC}% + \fi + \next} + +\definecomplexorsimple\chemical + +\def\dogotochemical#1#2% + {\def\dowithchemical% % experiment + {\localgotochemical{#1}}% % experiment + \chemical} % experiment + +\def\gotochemical% % experiment + {\dosingleargument\dogotochemical} % experiment + +\def\dododochemical#1[#2][#3]% % experiment + {\def\simpledododochemical% % experiment + {#1[#2][#3]}% % experiment + \def\complexdododochemical[##1]% % experiment + {\def\dowithchemical% % experiment + {\localthisischemical{#2}}% % experiment + #1[#3][##1]}% % experiment + \complexorsimple\dododochemical} % experiment + +\def\dodochemical[#1][#2]% + {\ignorespaces + \ifinchemical + \drawchemical[#1][#2]% + \ignorespaces + \else + \startchemical[\c!location=\v!intext]% + \drawchemical[#1][#2]% + \expandafter\stopchemical + \fi + \ignorespaces} + +\def\dochemical[#1]% + {\def\simpledochemical% + {\@@writechemicalstate{ppchtex}{[#1][]}% + \dodochemical[#1][]}% + % + \def\complexdochemical[##1]% + {\@@writechemicalstate{ppchtex}{[#1][##1]}% + \txtchemical=0% + \dodochemical[#1][##1]}% + % + \def\complexdochemical[##1]% % experiment + {\@@writechemicalstate{ppchtex}{[#1][##1]}% % experiment + \txtchemical=0% % experiment + \dododochemical\dodochemical[#1][##1]}% % experiment + % + \complexorsimple\dochemical} + +% \processlocalchemicals{#1} +% +% #1: commando's + +\def\dodoprocesschemical#1% + {\processchemical[#1????]} + +\def\processlocalchemicals#1% + {\processcommalist[#1]\dodoprocesschemical} + +% \drawchemical[#1][#2] +% +% #1: bindingen enz. +% #2: atomen enz. + +\def\localdodochemical[#1][#2]% + {\@@writechemicalstate{ppchtex}{[#1][#2]}% + %\bgroup % koppelen en afmetingen gaat fout, vandaar: + \advance\levchemical 1 + \letvalue{\??chemical\s!unknown\the\levchemical}\unknownchemical + \setevalue{\??chemical\c!text\the\levchemical}{\the\txtchemical}% + \txtchemical=0 + \dodochemical[#1][#2]% + % \@EA\txtchemical\@EA\csname\??chemical\c!text\the\levchemical\endcsname + \txtchemical\csname\??chemical\c!text\the\levchemical\endcsname + \@EA\let\@EA\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname + \advance\levchemical -1 + %\egroup + \ignorespaces} + +\def\drawchemical[#1][#2]% + {\ignorespaces + \def\dodochemical[##1][##2]% + {\drawchemical[##1][##2]% + \ignorespaces}% + \def\dochemical[##1]% + {\def\simpledochemical% + {\@@writechemicalstate{ppchtex}{[##1][#2]}% + \dodochemical[##1][#2]% + \ignorespaces}% + \def\complexdochemical[####1]% + {\dododochemical\localdodochemical[##1][####1,#2]}% + \complexorsimple\dochemical}% + \doif\@@chemicalstate\v!start + {\doifelse\chemicalname\s!unknown + {\getvalue{\s!executechemical\defaultchemical}[#2]} + {\getvalue{\s!executechemical\chemicalname}[#2]}% + \def\unknownchemical##1% + {\processunknownchemical[##1][#2]}% + \processcommalist[\@@chemicaloffset,#1]\dodoprocesschemical}% + \ignorespaces} + +\unexpanded\def\chemicaloxidation#1#2#3% + {\chemicaltop + {\ifnum#20=0 + 0% + \else + #1\expandafter\uppercase\expandafter{\romannumeral#2}% + \fi} + {#3}} + +\def\chemicaltfraction{\ifinchemical.60\else.8\fi} +\def\chemicalbfraction{\ifinchemical.45\else.6\fi} +\def\chemicallfraction{\ifinchemical.1\else.1\fi} +\def\chemicalrfraction{\ifinchemical.1\else.1\fi} + +\def\chemicaltighttext + {\def\chemicaltfraction{\ifinchemical.3\else.6\fi}% + \def\chemicalbfraction{\ifinchemical.2\else.4\fi}% + \def\chemicallfraction{\ifinchemical 0\else 0\fi}% + \def\chemicalrfraction{\ifinchemical 0\else 0\fi}} + +\def\dochemicaltop#1#2#3#4% + {\vbox + {\@@dochemicalcolor + \baselineskip=\chemicaltfraction\baselineskip \lineskip0pt + \halign + {#1###2\cr + $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr + $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr}}} + +\def\dochemicalbottom#1#2#3#4% + {\vtop + {\@@dochemicalcolor + \baselineskip=\chemicalbfraction\baselineskip \lineskip0pt + \halign + {#1###2\cr + $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr + $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr}}} + +\def\chemicalleft#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\scriptscriptstyle#1}$% + $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} + +\def\chemicalright#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% + $\@@dochemicalstyle{\scriptscriptstyle#1}$}} + +\def\chemicalcentered#1% + {\setbox0=\hbox{$\@@dochemicalstyle{\scriptscriptstyle#1}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \dimen0=.5\ht2 + \advance\dimen0 by -.5\ht0 + \advance\dimen0 by \dp0 + \hbox{\@@dochemicalcolor\raise\dimen0\box0}} + +\def\chemicalleftcentered#1#2% + {\hbox + {\@@dochemicalcolor + \chemicalcentered{#1}% + $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}} + +\def\chemicalrightcentered#1#2% + {\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$% + \chemicalcentered{#1}}} + +\def\chemicaltop {\dochemicaltop \hss \hss } +\def\chemicallefttop {\dochemicaltop \relax \hss } +\def\chemicalrighttop {\dochemicaltop \hss \relax} +\def\chemicalbottom {\dochemicalbottom \hss \hss } +\def\chemicalleftbottom {\dochemicalbottom \relax \hss } +\def\chemicalrightbottom {\dochemicalbottom \hss \relax} + +\def\chemicaltopleft #1{\chemicalleft {\chemicallefttop {#1}{}}} +\def\chemicalbottomleft #1{\chemicalleft {\chemicalleftbottom{#1}{}}} +\def\chemicaltopright #1{\chemicalright{\chemicallefttop {#1}{}}} +\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom{#1}{}}} + +\def\chemicalsmashedleft#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \wd2=\wd0 + \box2 + \egroup} + +\def\chemicalsmashedmiddle#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \hbox{\hskip-.5\wd2\hskip.5\wd0\box2} + \egroup} + +\def\chemicalsmashedright#1% + {\hbox\bgroup + \@@dochemicalcolor + \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}% + \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}% + \hbox to \wd0{\hskip-\wd2\hskip\wd0\box2}% + \egroup} + +\def\+{\tabalign} % is \long in Plain + +\def\chemicalforever#1#2% + {\bgroup + \setbox0=\hbox + {\@@dochemicalcolor + $\@@dochemicalstyle{\scriptscriptstyle\hskip-.15em#2}$}% + \wd0=0pt + \big#1\normapsubscript{\hskip.1em\box0}% + \egroup} + +\def\disablechemicalspecials% + {\def\+##1{##1}\def\-##1{##1}% + \def\[{[}\def\]{]}% + \def\1{}\def\2{}\def\3{}\def\4{}\def\5{}\def\6{}\def\7{}% + \def\X{}% + \def\T{}\def\B{}\def\L{}\def\R{}\def\LC{}\def\RC{}% + \def\TL{}\def\BL{}\def\TR{}\def\BR{}% + \def\LT{}\def\LB{}\def\RT{}\def\RB{}% + \def\SL{}\def\SM{}\def\SR{}} + +\def\enablechemicalspecials% + {\def\+{\dodoublegroupempty\chemicaloxidation{+}}% {} needed! + \def\-{\dodoublegroupempty\chemicaloxidation{-}}% {} needed! + \def\[{\dodoublegroupempty\chemicalforever {[}}% {} needed! + \def\]{\dodoublegroupempty\chemicalforever {]}}% {} needed! + \def\1{\chemicaloxidation\relax1}% + \def\2{\chemicaloxidation\relax2}% + \def\3{\chemicaloxidation\relax3}% + \def\4{\chemicaloxidation\relax4}% + \def\5{\chemicaloxidation\relax5}% + \def\6{\chemicaloxidation\relax6}% + \def\7{\chemicaloxidation\relax7}% + \def\X{\chemicaltighttext}% + \def\T{\chemicaltop}% + \def\B{\chemicalbottom}% + \def\L{\chemicalleft}% + \def\LC{\chemicalleftcentered}% + \def\R{\chemicalright}% + \def\RC{\chemicalrightcentered}% + \def\TL{\chemicaltopleft}% + \def\BL{\chemicalbottomleft}% + \def\TR{\chemicaltopright}% + \def\BR{\chemicalbottomright}% + \def\LT{\chemicallefttop}% + \def\LB{\chemicalleftbottom}% + \def\RT{\chemicalrighttop}% + \def\RB{\chemicalrightbottom}% + \def\SL{\chemicalsmashedleft}% + \def\SM{\chemicalsmashedmiddle}% + \def\SR{\chemicalsmashedright}} + +% \reversechemical#1#2#3 +% +% #1: prefix +% #2: volgnummer enz +% #3: tegengestelde volgnummers + +\def\reversechemical#1#2#3% + {\def\doprocess[##1##2]% + {\doifchemicalnumber{##1}{#1#2}% + {\getfromcommalist[#3][##1]% + \let\reversechemicalaction=\commalistelement + \processchemical[#1\reversechemicalaction##2]}}% + \doprocess[#2]} + +% \processunknownchemical[#1????][#2] +% +% #1: bindingen enz. +% #2: atomen enz. + +\def\defaultchemical% + {SIX} + +\def\processunknownchemical[#1????][#2]% + {\processaction + [#1] + [ SAVE=>\executechemicalSAVE, + RESTORE=>\executechemicalRESTORE, + HIGH=>\sethighsubscripts, + LOW=>\setlowsubscripts, + \s!default=>, + \s!unknown=>\doifelsedefined{\s!executechemical#1} + {\def\chemicalrotation{1}% + \def\chemicaloffset{0}% + \doifdefined{\s!executechemical#1} + {\getvalue{\s!executechemical#1}[#2]}% + \@@chemicalpostponed} + {\getpredefinedchemical{#1}}]} + +\newcount\chemicalstack + +\setvalue{\s!chemical\c!x1}{0} +\setvalue{\s!chemical\c!y1}{0} + +\def\executechemicalSAVE + {%\writestatus{ppchtex}{saving \the\horchemical,\the\verchemical}% + \advance\chemicalstack by 1 + \letvalue {\s!chemical n\the\chemicalstack}=\chemicalname + %\letvalue {\s!chemical p\the\chemicalstack}=\@@chemicalpostponed + \setevalue{\s!chemical x\the\chemicalstack}{\the\horchemical}% + \setevalue{\s!chemical y\the\chemicalstack}{\the\verchemical}} + +\def\restorechemicalvalues#1% + {\let\oldprocesschemical=\processchemical + \doifdefined{\s!executechemical#1}{\getvalue{\s!executechemical#1}[]}% + \let\processchemical=\oldprocesschemical} + +\def\executechemicalRESTORE + {\ifnum\chemicalstack=0\relax + \horchemical=\getvalue{\s!chemical x1}\relax + \verchemical=\getvalue{\s!chemical y1}\relax + \else + \restorechemicalvalues{\getvalue{\s!chemical n\the\chemicalstack}}% + %\@EA\let\@EA\@@chemicalpostponed\@EA=\csname\s!chemical p\the\chemicalstack\endcsname + \let\@@chemicalpostponed=\relax + \horchemical=\getvalue{\s!chemical x\the\chemicalstack}\relax + \verchemical=\getvalue{\s!chemical y\the\chemicalstack}\relax + \advance\chemicalstack by -1 + \fi + \restorechemicalcoordinates} + +% De onderstaande macro's zijn verantwoordelijk voor het zetten +% van de + en pijlen. De +, en dus ook de pijlen, worden omhoog +% gehaald. Dit oogt m.i. fraaier. + +\def\chemicalinnerclip#1% + {{\setbox0=\hbox{#1}\ht0\ht\strutbox\dp0\dp\strutbox\box0}} + +\def\chemicalraise#1#2% + {\chemicalinnerclip + {\setbox0=\hbox{$#1+$}% + \raise\dp0\hbox{$#1#2$}}} + +\def\chemicalinnersign#1% todo: \@@chemicaltextcolor + {\chemicalraise{\@@localchemicalstyle}{#1}} + +\def\chemicaloutersign#1% + {\chemicalraise{}{\@@dochemicalcolor#1}} + +\def\chemicalsingleinnerarrow#1#2% + {\chemicalraise{\@@localchemicalstyle}{\longrightarrow}} + +\def\chemicaldoubleinnerarrow#1#2% todo: \@@chemicaltextcolor + {\chemicalinnerclip + {\lower.2ex\hbox + {\setbox0=\hbox{$\@@localchemicalstyle\longrightarrow$}% + \setbox2=\hbox{$\@@localchemicalstyle\longleftarrow$}% + \wd0=0pt\raise\ht0\box0\box2}}} + +\def\chemicaltwintipinnerarrow#1#2% todo: \@@chemicaltextcolor + {\chemicalinnerclip + {\setbox0=\hbox{\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}% + \setbox2=\hbox{\chemicalraise{\@@localchemicalstyle}{\longleftarrow}}% + \wd0=0pt\box0\box2}} + +\def\dochemicalouterarrow#1#2#3% + {\bgroup + \setbox0=\hbox{$\longrightarrow$}% + \setbox2=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#2\quad}$}% + \setbox4=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#3\quad}$}% + \dimen2=\wd0 % \dimen0 is used elsewhere + \ifdim\wd2>\dimen2 \dimen0=\wd2 \fi + \ifdim\wd4>\dimen2 \dimen0=\wd4 \fi + \chemicaloutermolecule + {#1} + {\ifdim\ht2>\zeropoint\box2\fi} % expands to \empty in test + {\ifdim\ht4>\zeropoint\box4\fi}% % expands to \empty in test + \egroup} + +\def\chemicalsingleouterarrow + {\dochemicalouterarrow + {\hbox to \dimen2{\rightarrowfill}}} + +\def\chemicaldoubleouterarrow + {\dochemicalouterarrow + {\lower.5\ht0\vbox + {\offinterlineskip + \hbox to \dimen2{\rightarrowfill} + \hbox to \dimen2{\leftarrowfill}}}} + +\def\chemicaltwintipouterarrow + {\dochemicalouterarrow + {\hbox + {\hbox to \dimen2{\rightarrowfill}% + \hskip-\dimen2 + \hbox to \dimen2{\leftarrowfill}}}} + +\def\chemicalinnermolecule#1#2#3% no mathop here, can generate space + {\chemicalspace % todo: \@@chemicaltextcolor + \chemicalinnerclip + {\dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalstyle\strut#1}$% + \doresetsubscripts}% + \chemicalspace} + +\def\chemicaloutermolecule#1#2#3% + {\chemicalspace + \bgroup + \@@dochemicalcolor + \setbox0=\hbox % else the font is reset + {\dosetsubscripts + \hbox{$\@@dochemicalstyle{\strut#1}$}% + \doresetsubscripts}% + \mathop{\box0}% + \ifthirdargument + \doifnot{#2}{}{\normapsuperscript{\@@dochemicalstyle{\strut#2}}}% + \doifnot{#3}{}{\normapsubscript {\@@dochemicalstyle{\strut#3}}}% + \else + \doifnot{#2}{} + {\normapsubscript{\@@dochemicalstyle{\strut#2}}}% + \fi + \egroup + \chemicalspace} + +\def\chemicalsinglepicturearrow#1% + {\lower.5ex\hbox + {\@@dochemicalstyle + $\chemicalspace + \buildrel + \@@dochemicalstyle{\scriptstyle\quad#1\quad}% + \over{\overrightarrow + {\hphantom{\@chemicalstyle{\scriptstyle\quad#1\quad}}}}% + \chemicalspace$}} + +\def\chemicaldoublepicturearrow#1% + {\lower.5ex\hbox + {\@@dochemicalstyle + $\chemicalspace + \buildrel + \@@dochemicalstyle{\scriptstyle\quad#1\quad}% + \over{\overrightarrow{\overleftarrow + {\hphantom{\@@dochemicalstyle{\scriptstyle\quad#1\quad}}}}}% + \chemicalspace$}} + +% Bij de in-line bindingen wordt gebruik gemaakt van +% een \hrule. De maatvoering wordt bepaald door een +% kunstmatige em (\wd0). + +\def\somechemicalbond% + {\hrule width \wd0 height .4pt} + +\def\dochemicalbonds#1#2#3% todo: \@@chemicaltextstyle + {{\setbox0=\hbox + {${\@@localchemicalstyle M}$}% + \vbox to \ht0 + {\@@dochemicalcolor + \hsize\wd0 + \vskip.1\wd0#1\vfill#2\vfill#3\vskip.1\wd0}}} + +\def\singlechemicalbond% + {\dochemicalbonds{}{\somechemicalbond}{}} + +\def\doublechemicalbond% + {\dochemicalbonds{\somechemicalbond}{}{\somechemicalbond}} + +\def\triplechemicalbond% + {\dochemicalbonds{\somechemicalbond}{\somechemicalbond}{\somechemicalbond}} + +% In plaats van \def\naam{\chemie[...]...} kan beter gebruik +% worden gemaakt van het commando +% +% \definieerchemie[naam]{commando's} +% +% De naam krijgt, om problemen met bestaande macro's te +% voorkomen, een prefix. Bij het ophalen van een commando +% worden beide definities afgehandeld. + +\def\dodefinechemical[#1]#2% + {\doifdefined{\??chemical#1} + {\writestatus{ppchtex}{chemical definition #1 is redefined}}% + \setvalue{\??chemical#1}{#2}} + +\unexpanded\def\definechemical% + {\dosingleargument\dodefinechemical} + +\def\getpredefinedchemical#1% + {\doifelsedefined{\??chemical#1} + {\getvalue{\??chemical#1}} + {\doifelsedefined{#1} + {\getvalue{#1}} + {\writestatus{ppchtex}{unknown chemical definition #1}}}} + +% Hieronder zijn de definities van de structuren opgenomen. De +% naam van de structuur is als volgt opgebouwd: +% +% \executechemicalNUMBER[#1] +% +% waarbij [#1] betrekking heeft op de tekstelementen van \chemie, +% de [tweede lijst] dus. +% +% De aan \chemie[#1][#2] meegegeven lijst van segmenten wordt +% deels door de in \execute gedefinieerde macro's afgehandeld, +% deels door algemene macro's. Segmenten hebben de vorm: +% +% [+|-|]identifier[X|XYZ|X..Y] +% +% Voorbeelden van segmenten zijn: +% +% R1 +% R1..4 +% R135 +% -R1 +% +R35 + +\setchemicalmaximum 0 + +\def\processchemical[#1]% + {\unknownchemical{#1}} + +\def\setchemicalname#1 % + {\def\chemicalname{#1}} + +\let\chemicalname=\s!unknown + +% Vooruitlopend op een gedetailleerde documentatie, zijn hier +% vast enkele gebruikte afmetingen: +% +% lengte radikalen : 500 +% afstand radikalen : 100 +% afstand dubbele radikalen : 260 +% afstand substituenten : +125 + + + + +\def\executechemicalONE[#1]% + {\setchemicalname ONE + % + \setchemicalmaximum 8 + \setchemicaldistance 0 + \setchemicalsubstitute 625 + \setchemicaldirection 303 + % + \setchemicalrotation 1 1 0 1 0 1 0 1 0 + \setchemicalrotation 2 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 + \setchemicalrotation 3 0 -1 0 -1 0 -1 0 -1 + \setchemicalrotation 4 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 + \setchemicalrotation 5 -1 0 -1 0 -1 0 -1 0 + \setchemicalrotation 6 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 + \setchemicalrotation 7 0 1 0 1 0 1 0 1 + \setchemicalrotation 8 0.707 0.707 0.707 0.707 0.707 0.707 0.707 0.707 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 45 135 225 315 + \setchemicalangle 3 90 180 270 0 + \setchemicalangle 4 135 225 315 45 + \setchemicalangle 5 180 270 0 90 + \setchemicalangle 6 225 315 45 135 + \setchemicalangle 7 270 0 90 180 + \setchemicalangle 8 315 45 135 225 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 -1000 1000 + \setchemicaltranslate 3 0 1000 + \setchemicaltranslate 4 1000 1000 + \setchemicaltranslate 5 1000 0 + \setchemicaltranslate 6 1000 -1000 + \setchemicaltranslate 7 0 -1000 + \setchemicaltranslate 8 -1000 -1000 + % + \setchemicallinesegment SB 300 0 700 0 + \setchemicallinesegment DB1 300 50 700 50 + \setchemicallinesegment DB2 300 -50 700 -50 + % + %setchemicallinesegment EP 200 125 200 -125 + \setchemicalfactorlinesegment EP 200 125 200 -125 + % + \setchemicaltextelement ES 200 0 + \setchemicaltextelement ED1 200 50 + \setchemicaltextelement ED2 200 -50 + \setchemicaltextelement ET1 200 75 + \setchemicaltextelement ET2 200 0 + \setchemicaltextelement ET3 200 -75 + \setchemicaltextelement HB1 300 0 + \setchemicaltextelement HB2 475 0 + \setchemicaltextelement HB3 650 0 + % + \setchemicaltextelement Z 800 0 + \setchemicaltextelement RZ 950 0 + \setchemicaltextelement ZN 500 0 + \setchemicaltextelement ZTN 500 150 + \setchemicaltextelement ZBN 500 -150 + % + \def\processchemical[##1##2##3##4##5]% + {\doprocesschemical[##1##2##3##4##5] + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + DIR##4##5=>\processchemicaldirection{##4##5}, + OFF##4##5=>\processchemicaloffset{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, + LDD##4##5=>\processchemicaldashedlinesegment{DB1}{##4##5}% + \processchemicallinesegment{DB2}{##4##5}, + RDD##4##5=>\processchemicallinesegment{DB1}{##4##5}% + \processchemicaldashedlinesegment{DB2}{##4##5}, + OF##3:##5=>\processchemicalphantom{##3}{##5}, + OE##3##4##5=>\processchemicalopenend{OE}{##3##4##5}, + EP##3##4##5=>\processchemicallinesegment{EP}{##3##4##5}, + ES##3##4##5=>\processchemicaltextconstant{ES}{##3##4##5}{\hbox{$\cdot$}}{0}, + ED##3##4##5=>\processchemicaltextconstant{ED}{##3##4##5}{\hbox{$\cdot$}}{0}, + ET##3##4##5=>\processchemicaltextconstant{ET}{##3##4##5}{\hbox{$\cdot$}}{0}, + HB##3##4##5=>\processchemicaltextconstant{HB}{##3##4##5}{\hbox{$\cdot$}}{0}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + BB##3##4##5=>\processchemicaldeltalinesegment{SB}{##3##4##5}, + BD##3##4##5=>\processchemicaldasheddeltalinesegment{SB}{##3##4##5}, + BW##3##4##5=>\processchemicalwavylinesegment{SB}{##3##4##5}, + SD##3##4##5=>\processchemicaldashedlinesegment{SB}{##3##4##5}, + TB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}% + \processchemicallinesegment{DB}{##3##4##5}, + CZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{0}{}, + ZTN##4##5=>\processchemicalsmalltextconstant{ZTN}{##4##5}{\chemicaltextelementnumber}{0}, + ZTT##4##5=>\processchemicalsmalltextelement{ZTN}{##4##5}{#1}{0}{}, + ZBN##4##5=>\processchemicalsmalltextconstant{ZBN}{##4##5}{\chemicaltextelementnumber}{0}, + ZBT##4##5=>\processchemicalsmalltextelement{ZBN}{##4##5}{#1}{0}{}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0} + {l,l,t,r,r,r,b,l}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}} + +\def\executechemicalTHREE[#1]% + {\setchemicalname THREE + % + \setchemicalmaximum 3 + \setchemicaldistance 289 + \setchemicalsubstitute 952 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 3 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 120 210 300 30 + \setchemicalangle 3 240 330 60 150 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 577 0 -289 -500 + \setchemicallinesegment SB 352 -130 -64 -370 + \setchemicallinesegment -SB 352 -130 -289 -500 + \setchemicallinesegment +SB 577 0 -64 -370 + \setchemicallinesegment DB1 327 -87 -89 -327 + \setchemicallinesegment DB2 377 -172 -39 -413 + \setchemicallinesegment R 577 0 1077 0 + \setchemicallinesegment -R 577 0 1010 250 + \setchemicallinesegment +R 577 0 1010 -250 + \setchemicallinesegment ER1 577 50 1077 50 + \setchemicallinesegment ER2 577 -50 1077 -50 + \setchemicallinesegment SR 837 0 1077 0 + \setchemicallinesegment -SR 802 130 1010 250 + \setchemicallinesegment +SR 802 -130 1010 -250 + \setchemicallinesegment DR1 837 50 1077 50 + \setchemicallinesegment DR2 837 -50 1077 -50 + % + \setchemicaltextelement Z 577 0 + \setchemicaltextelement RZ 1177 0 + \setchemicaltextelement -RZ 1097 300 + \setchemicaltextelement +RZ 1097 -300 + \setchemicaltextelement CRZ 1077 0 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{3} + {l,t,r, l,r,l, r,b,l, r,l,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{3} + {l,r,b, r,r,l, r,l,t, l,l,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0} + {}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{3} + {l,r,r, t,r,l, r,l,l, b,l,r}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFOUR[#1]% + {\setchemicalname FOUR + % + \setchemicalmaximum 4 + \setchemicaldistance 500 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 4 0 1 1 0 0 -1 -1 0 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 180 270 0 90 + \setchemicalangle 4 270 0 90 180 + % + \setchemicaltranslate 1 -1000 0 + \setchemicaltranslate 2 0 1000 + \setchemicaltranslate 3 1000 0 + \setchemicaltranslate 4 0 -1000 + % + \setchemicallinesegment B 500 500 500 -500 + \setchemicallinesegment SB 500 240 500 -240 + \setchemicallinesegment -SB 500 240 500 -500 + \setchemicallinesegment +SB 500 500 500 -240 + \setchemicallinesegment DB1 450 240 450 -240 + \setchemicallinesegment DB2 550 240 550 -240 + \setchemicallinesegment EB 360 300 360 -300 + \setchemicallinesegment R 500 500 854 854 + \setchemicallinesegment -R 500 500 500 1000 + \setchemicallinesegment +R 500 500 1000 500 + \setchemicallinesegment ER1 465 535 819 889 + \setchemicallinesegment ER2 535 465 889 819 + \setchemicallinesegment SR 684 684 854 854 + \setchemicallinesegment -SR 500 760 500 1000 + \setchemicallinesegment +SR 760 500 1000 500 + \setchemicallinesegment DR1 649 719 819 889 + \setchemicallinesegment DR2 719 649 889 819 + % + \setchemicaltextelement Z 500 500 + \setchemicaltextelement RZ 925 925 + \setchemicaltextelement -RZ 500 1100 + \setchemicaltextelement +RZ 1100 500 + \setchemicaltextelement CRZ 1038 1038 + % + \setchemicaltextelement ZN 350 350 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{4} + {b,l,t,r, l,t,r,b, t,r,b,l, r,b,l,t}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{4} + {lb,lt,rt,rb, lt,rt,rb,lb, rt,rb,lb,lt, rb,lb,lt,rt}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalFIVE[#1]% + {\setchemicalname FIVE + % + \setchemicalmaximum 5 + \setchemicaldistance 688 + \setchemicalsubstitute 1226 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.309 -0.951 -0.951 -0.309 -0.309 0.940 0.951 0.309 + \setchemicalrotation 3 -0.809 -0.588 -0.588 0.809 0.809 0.588 0.588 -0.809 + \setchemicalrotation 4 -0.809 0.588 0.588 0.809 0.809 -0.588 -0.588 -0.809 + \setchemicalrotation 5 0.309 0.951 0.951 -0.309 -0.309 -0.951 -0.951 0.309 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 72 162 252 342 + \setchemicalangle 3 144 234 324 54 + \setchemicalangle 4 216 306 36 126 + \setchemicalangle 5 288 18 108 198 + % + \setchemicaltranslate 1 -1376 0 + \setchemicaltranslate 2 -425 1304 + \setchemicaltranslate 3 1113 809 + \setchemicaltranslate 4 1113 -809 + \setchemicaltranslate 5 -425 -1304 + % + \setchemicallinesegment A 1188 500 1188 -500 + \setchemicallinesegment B 688 500 688 -500 + \setchemicallinesegment S -263 808 688 -500 + \setchemicallinesegment SS -116 606 541 -298 + \setchemicallinesegment -SS -263 808 541 -298 + \setchemicallinesegment +SS -116 606 688 -500 + \setchemicallinesegment SB 688 240 688 -240 + \setchemicallinesegment -SB 688 240 688 -500 + \setchemicallinesegment +SB 688 500 688 -240 + \setchemicallinesegment DB1 638 240 638 -240 + \setchemicallinesegment DB2 738 240 738 -240 + \setchemicallinesegment EB 548 340 548 -340 + \setchemicallinesegment R 688 500 1093 794 + \setchemicallinesegment -R 688 500 688 1000 + \setchemicallinesegment +R 688 500 1163 345 + \setchemicallinesegment ER1 659 540 1064 834 + \setchemicallinesegment ER2 727 460 1122 754 + \setchemicallinesegment SR 898 653 1093 794 + \setchemicallinesegment -SR 688 760 688 1000 + \setchemicallinesegment +SR 935 420 1163 345 + \setchemicallinesegment DR1 869 693 1064 834 + \setchemicallinesegment DR2 927 613 1122 754 + % + \setchemicaltextelement Z 688 500 + \setchemicaltextelement RZ 1188 863 + \setchemicaltextelement -RZ 688 1100 + \setchemicaltextelement +RZ 1258 315 + \setchemicaltextelement CRZ 1323 947 + % + \setchemicalcircsegment C -36 36 590 72 475 -345 + \setchemicalcircsegment CC -72 0 590 72 182 -561 + % + \setchemicaltextelement ZN 468 350 + \setchemicaltextelement RN 860 625 % 1.25 Z + \setchemicaltextelement RTN 785 728 % .12 / 103 75 + \setchemicaltextelement RBN 935 522 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [ FRONT????=>{\executechemicalFIVEFRONT[#1]}, + PB:##4=>\beginchemicalpicture{##4}, + PE????=>\endchemicalpicture, + ROT##4=>\processchemicalrotation{##4}, + SUB##4=>\processchemicalsubstitute{##4}, + ADJ##4=>\processchemicaldistance{##4}, + MOV##4=>\processchemicaltranslate{##4}, + -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{5} + {b,l,t,r,r, l,t,r,r,l, t,r,r,l,l, r,b,l,t,r}, + +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{5} + {l,t,r,r,b, t,r,r,l,l, r,r,l,l,r, b,l,l,r,r}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + -SR##4=>\processchemicallinesegment{-SR}{##4}, + +SR##4=>\processchemicallinesegment{+SR}{##4}, + -RD##4=>\processchemicaldashedlinesegment{-R}{##4}, + +RD##4=>\processchemicaldashedlinesegment{+R}{##4}, + -RB##4=>\processchemicaldeltalinesegment{-R}{##4}, + +RB##4=>\processchemicaldeltalinesegment{+R}{##4}, + CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{}, + RTN##4=>\processchemicaltextconstant{RTN}{##4}{\chemicaltextelementnumber}{0}, + RTT##4=>\processchemicaltextelement{RTN}{##4}{#1}{0}{}, + RBN##4=>\processchemicaltextconstant{RBN}{##4}{\chemicaltextelementnumber}{0}, + RBT##4=>\processchemicaltextelement{RBN}{##4}{#1}{0}{}, + -SS##4=>\processchemicallinesegment{-SS}{##4}, + +SS##4=>\processchemicallinesegment{+SS}{##4}, + CCD##4=>\processchemicaldottsegment{CC}{##4}, + SS##3##4=>\processchemicallinesegment{SS}{##3##4}, + RD##3##4=>\processchemicaldashedlinesegment{R}{##3##4}, + RB##3##4=>\processchemicaldeltalinesegment{R}{##3##4}, + ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0}, + ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{}, + RN##3##4=>\processchemicaltextconstant{RN}{##3##4}{\chemicaltextelementnumber}{0}, + RT##3##4=>\processchemicaltextelement{RN}{##3##4}{#1}{0}{}, + AU##3##4=>\processchemicaluparrowsegment{A}{##3##4}, + AD##3##4=>\processchemicaldownarrowsegment{A}{##3##4}, + CC##3##4=>\processchemicalcircsegment{CC}{##3##4}, + CD##3##4=>\processchemicaldottsegment{C}{##3##4}, + DB##3##4=>\processchemicallinesegment{DB}{##3##4}, + DR##3##4=>\processchemicallinesegment{DR}{##3##4}, + EB##3##4=>\processchemicallinesegment{EB}{##3##4}, + ER##3##4=>\processchemicallinesegment{ER}{##3##4}, + RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{5} + {l,l,r,r,r, l,r,r,b,l, r,r,b,l,t, r,l,l,t,r}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + SR##3##4=>\processchemicallinesegment{SR}{##3##4}, + -R##3##4=>\processchemicallinesegment{-R}{##3##4}, + +R##3##4=>\processchemicallinesegment{+R}{##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + C##2##3##4=>\processchemicalcircsegment{C}{##2##3##4}, + R##2##3##4=>\processchemicallinesegment{R}{##2##3##4}, + S##2##3##4=>\processchemicallinesegment{S}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIX[#1]% + {\setchemicalname SIX + % + \setchemicalmaximum 6 + \setchemicalsubstitute 1375 + \setchemicaldistance 866 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 0.5 -0.866 -0.866 -0.5 -0.5 0.866 0.866 0.5 + \setchemicalrotation 3 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5 + \setchemicalrotation 4 -1 0 0 1 1 0 0 -1 + \setchemicalrotation 5 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5 + \setchemicalrotation 6 0.5 0.866 0.866 -0.5 -0.5 -0.866 -0.866 0.5 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 60 150 240 330 + \setchemicalangle 3 120 210 300 30 + \setchemicalangle 4 180 270 0 90 + \setchemicalangle 5 240 330 60 150 + \setchemicalangle 6 300 30 120 210 + % + \setchemicaltranslate 1 -1732 0 + \setchemicaltranslate 2 -866 1500 + \setchemicaltranslate 3 866 1500 + \setchemicaltranslate 4 1732 0 + \setchemicaltranslate 5 866 -1500 + \setchemicaltranslate 6 -866 -1500 + % + \setchemicallinesegment A 1386 500 1386 -500 + \setchemicallinesegment S 0 1000 866 -500 + \setchemicallinesegment SS 125 783 741 -283 + \setchemicallinesegment -SS 0 1000 741 -283 + \setchemicallinesegment +SS 125 783 866 -500 + \setchemicallinesegment B 866 500 866 -500 + \setchemicallinesegment SB 866 240 866 -240 + \setchemicallinesegment -SB 866 240 866 -500 + \setchemicallinesegment +SB 866 500 866 -240 + \setchemicallinesegment DB1 816 240 816 -240 + \setchemicallinesegment DB2 916 240 916 -240 + \setchemicallinesegment EB 726 340 726 -340 + \setchemicallinesegment R 866 500 1299 750 + \setchemicallinesegment -R 866 500 866 1000 + \setchemicallinesegment +R 866 500 1299 250 + \setchemicallinesegment ER1 841 543 1274 793 + \setchemicallinesegment ER2 891 457 1324 707 + \setchemicallinesegment SR 1091 630 1299 750 + \setchemicallinesegment -SR 866 740 866 1000 + \setchemicallinesegment +SR 1091 370 1299 250 + \setchemicallinesegment DR1 1066 673 1274 793 + \setchemicallinesegment DR2 1116 588 1324 707 + \setchemicallinesegment MID1 0 1000 -150 200 + \setchemicallinesegment MID2 0 -1000 -150 -200 + \setchemicallinesegment MIDS1 0 1000 -180 0 + \setchemicallinesegment MIDS2 0 -1000 -180 0 + % + \setchemicalcircsegment C -30 30 700 60 600 -346 + \setchemicalcircsegment CC -60 0 700 60 350 -606 + % + \setchemicaltextelement Z 866 500 + \setchemicaltextelement RZ 1386 800 + \setchemicaltextelement -RZ 866 1100 + \setchemicaltextelement +RZ 1386 200 + \setchemicaltextelement CRZ 1524 880 + \setchemicaltextelement MIDZ -150 0 + % + \setchemicaltextelement ZN 589 350 + \setchemicaltextelement RN 1083 625 % 1.25 Z + \setchemicaltextelement RTN 1008 755 % .12 / 130 75 + \setchemicaltextelement RBN 1158 495 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ FRONT????=>{\executechemicalSIXFRONT[#1]}, + MID????=>\processchemicallinesegment{MID}{1????}, + MIDS????=>\processchemicallinesegment{MIDS}{1????}, + MIDZ????=>\processchemicaltextelement{MIDZ}{1????}{#1}{0}{}, + PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + ROT##4##5=>\processchemicalrotation{##4##5}, + SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -RZ##4##5=>\processchemicaltextelement{-RZ}{##4##5}{#1}{6} + {b,l,l,t,r,r, l,l,r,r,r,l, t,r,r,b,l,l, r,r,l,l,l,r}, + +RZ##4##5=>\processchemicaltextelement{+RZ}{##4##5}{#1}{6} + {l,t,r,r,b,l, r,r,r,l,l,l, r,b,l,l,t,r, l,l,l,r,r,r}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + -SR##4##5=>\processchemicallinesegment{-SR}{##4##5}, + +SR##4##5=>\processchemicallinesegment{+SR}{##4##5}, + -RD##4##5=>\processchemicaldashedlinesegment{-R}{##4##5}, + +RD##4##5=>\processchemicaldashedlinesegment{+R}{##4##5}, + -RB##4##5=>\processchemicaldeltalinesegment{-R}{##4##5}, + +RB##4##5=>\processchemicaldeltalinesegment{+R}{##4##5}, + CRZ##4##5=>\processchemicaltextelement{CRZ}{##4##5}{#1}{0}{}, + -SS##4##5=>\processchemicallinesegment{-SS}{##4##5}, + +SS##4##5=>\processchemicallinesegment{+SS}{##4##5}, + CCD##4##5=>\processchemicaldottsegment{CC}{##4##5}, +RTN##4##5=>\processchemicaltextconstant{RTN}{##4##5}{\chemicaltextelementnumber}{0}, +RTT##4##5=>\processchemicaltextelement{RTN}{##4##5}{#1}{0}{}, +RBN##4##5=>\processchemicaltextconstant{RBN}{##4##5}{\chemicaltextelementnumber}{0}, +RBT##4##5=>\processchemicaltextelement{RBN}{##4##5}{#1}{0}{}, + SS##3##4##5=>\processchemicallinesegment{SS}{##3##4##5}, + RD##3##4##5=>\processchemicaldashedlinesegment{R}{##3##4##5}, + RB##3##4##5=>\processchemicaldeltalinesegment{R}{##3##4##5}, + ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0}, + ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{}, +RN##3##4##5=>\processchemicaltextconstant{RN}{##3##4##5}{\chemicaltextelementnumber}{0}, +RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{}, + AU##3##4##5=>\processchemicaluparrowsegment{A}{##3##4##5}, + AD##3##4##5=>\processchemicaldownarrowsegment{A}{##3##4##5}, + CD##3##4##5=>\processchemicaldottsegment{C}{##3##4##5}, + CC##3##4##5=>\processchemicalcircsegment{CC}{##3##4##5}, + DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5}, + EB##3##4##5=>\processchemicallinesegment{EB}{##3##4##5}, + ER##3##4##5=>\processchemicallinesegment{ER}{##3##4##5}, + RZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{6} + {l,l,t,r,r,b, l,r,r,r,l,l, r,r,b,l,l,t, r,l,l,l,r,r}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + SR##3##4##5=>\processchemicallinesegment{SR}{##3##4##5}, + DR##3##4##5=>\processchemicallinesegment{DR}{##3##4##5}, + -R##3##4##5=>\processchemicallinesegment{-R}{##3##4##5}, + +R##3##4##5=>\processchemicallinesegment{+R}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + C##2##3##4##5=>\processchemicalcircsegment{C}{##2##3##4##5}, + R##2##3##4##5=>\processchemicallinesegment{R}{##2##3##4##5}, + S##2##3##4##5=>\processchemicallinesegment{S}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalSEVEN[#1]% incomplete ! + {\setchemicalname SEVEN + % + \setchemicalmaximum 7 + \setchemicalsubstitute - + \setchemicaldistance 1038 + % + \setchemicalrotation 1 .623 .782 - - - - - - + \setchemicalrotation 2 -.223 .975 - - - - - - + \setchemicalrotation 3 -.901 .434 - - - - - - + \setchemicalrotation 4 -.901 -.434 - - - - - - + \setchemicalrotation 5 -.223 -.975 - - - - - - + \setchemicalrotation 6 .623 -.782 - - - - - - + \setchemicalrotation 7 1 0 - - - - - - + % + \setchemicalangle 1 0 - - - + \setchemicalangle 2 51.429 - - - + \setchemicalangle 3 102.857 - - - + \setchemicalangle 4 154.286 - - - + \setchemicalangle 5 205.714 - - - + \setchemicalangle 6 257.143 - - - + \setchemicalangle 7 308.571 - - - + % + \setchemicaltranslate 1 - - + \setchemicaltranslate 2 - - + \setchemicaltranslate 3 - - + \setchemicaltranslate 4 - - + \setchemicaltranslate 5 - - + \setchemicaltranslate 6 - - + \setchemicaltranslate 7 - - + % + \setchemicallinesegment B 1038 500 1038 -500 + \setchemicallinesegment SB 1038 240 1038 -240 + \setchemicallinesegment -SB 1038 240 1038 -500 + \setchemicallinesegment +SB 1038 500 1038 -240 + % + \setchemicaltextelement Z 1038 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %ROT##4##5=>\processchemicalrotation{##4}, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + %ADJ##4##5=>\processchemicaldistance{##4##5}, + %MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalEIGHT[#1]% incomplete ! + {\setchemicalname EIGHT + % + \setchemicalmaximum 8 + %\setchemicalsubstitute 1307 + \setchemicaldistance 1207 + % + \setchemicalrotation 1 .707 .707 - - - - - - + \setchemicalrotation 2 0 1 - - - - - - + \setchemicalrotation 3 -.707 .707 - - - - - - + \setchemicalrotation 4 -1 0 - - - - - - + \setchemicalrotation 5 -.707 -.707 - - - - - - + \setchemicalrotation 6 0 -1 - - - - - - + \setchemicalrotation 7 .707 -.707 - - - - - - + \setchemicalrotation 8 1 0 - - - - - - + % + \setchemicalangle 1 45 - - - + \setchemicalangle 2 90 - - - + \setchemicalangle 3 135 - - - + \setchemicalangle 4 180 - - - + \setchemicalangle 5 225 - - - + \setchemicalangle 6 270 - - - + \setchemicalangle 7 315 - - - + \setchemicalangle 8 0 - - - + % + \setchemicaltranslate 1 -2414 0 + \setchemicaltranslate 2 -1706 1706 + \setchemicaltranslate 3 0 2414 + \setchemicaltranslate 4 1706 1706 + \setchemicaltranslate 5 2414 0 + \setchemicaltranslate 6 1706 -1706 + \setchemicaltranslate 7 0 -2414 + \setchemicaltranslate 8 -1706 -1706 + % + \setchemicallinesegment B 1207 500 1207 -500 + \setchemicallinesegment SB 1207 240 1207 -240 + \setchemicallinesegment -SB 1207 240 1207 -500 + \setchemicallinesegment +SB 1207 500 1207 -240 + % + \setchemicaltextelement Z 1207 500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ PB:##4##5=>\beginchemicalpicture{##4##5}, + PE????=>\endchemicalpicture, + %SUB##4##5=>\processchemicalsubstitute{##4##5}, + ADJ##4##5=>\processchemicaldistance{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + -SB##4##5=>\processchemicallinesegment{-SB}{##4##5}, + +SB##4##5=>\processchemicallinesegment{+SB}{##4##5}, + SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}, + B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalFIVEFRONT[#1]% + {\executechemicalFIVE[]% + % + \setchemicalname FIVEFRONT + % + \setchemicallinesegment -R 688 500 688 100 + \setchemicallinesegment +R 688 500 688 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{5} + {,,,,, t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{5} + {,,,,, b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalSIXFRONT[#1]% + {\executechemicalSIX[]% + % + \setchemicalname SIXFRONT + % + \setchemicallinesegment -R 866 500 866 100 + \setchemicallinesegment +R 866 500 866 900 + % + \setchemicaltextelement -RZ 0 -1300 + \setchemicaltextelement +RZ 0 1300 + % + \def\processchemical[##1##2##3##4]% + {\def\chemicalrotation{2}% + \processaction + [##1##2##3##4] + [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{6} + {,,,,,, t,t,t,t,t,t}, + +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{6} + {,,,,,, b,b,b,b,b,b}, + -SB##4=>\processchemicallinesegment{-SB}{##4}, + +SB##4=>\processchemicallinesegment{+SB}{##4}, + SB##3##4=>\processchemicallinesegment{SB}{##3##4}, + -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4}, + +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4}, + BB##3##4=>\processchemicalzlinesegment{B}{##3##4}, + R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}% + \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4}, + B##2##3##4=>\processchemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{}, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +% 1 : 0 +% 2 : -115 +% 3* : -195 +% 3 : -165 +% 4 : -245 + +\def\executechemicalCARBON[#1]% + {\setchemicalname CARBON + % + \setchemicalmaximum 4 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \setchemicalrotation 1 1 0 0 -1 -1 0 0 1 + \setchemicalrotation 2 -0.423 -0.906 -0.906 0.423 0.423 0.906 0.906 -0.423 + \setchemicalrotation 3 -0.966 -0.259 -0.259 0.966 0.966 0.259 0.259 -0.966 + \setchemicalrotation 3* -0.966 0.259 0.259 0.966 0.966 -0.259 -0.259 -0.966 + \setchemicalrotation 4 -0.423 0.906 0.906 0.423 0.423 -0.906 -0.906 -0.423 + % + \setchemicalangle 1 0 90 180 270 + \setchemicalangle 2 115 205 295 25 + \setchemicalangle 3 165 255 345 75 + \setchemicalangle 3* 195 285 15 105 + \setchemicalangle 4 245 335 65 155 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 500 0 1000 0 + \setchemicallinesegment B2 300 0 1000 0 + \setchemicallinesegment B3 500 0 1000 0 + \setchemicallinesegment B4 300 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4##5]% + {\processaction + [##1##2##3##4##5] + [ MIR????=>\setchemicalmirror{3}, + -MIR????=>\resetchemicalmirror{3}, + *MIR????=>\togglechemicalmirror{3}, + CB????=>\processlocalchemicals{B,C,Z}, + C????=>\processchemicalcircsegment{C}{1????}, + -ROT##5=>\reversechemical{ROT}{##5}{3,4,1,2}, + ROT##4##5=>\processchemicalrotation{##4##5}, + MOV##4##5=>\processchemicaltranslate{##4##5}, + CB##3##4##5=>\processlocalchemicals + {ROT##3,C,B,Z2..4, + MOV##3,*MIR,-ROT##3,C,B,Z2..4}, + B##2##3##4##5=>\processprivatechemicallinesegment{B}{##2##3##4##5}, + Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{4} + {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +% 1: 45 2: -90 3: -225 +% 4: -45 5: -135 6: -270 + +\newif\ifNEWMANstagger \NEWMANstaggertrue + +\def\executechemicalNEWMANSTAGGER% + {\NEWMANstaggertrue\executechemicalNEWMAN} + +\def\executechemicalNEWMANECLIPSE% + {\NEWMANstaggerfalse\executechemicalNEWMAN} + +\def\executechemicalNEWMAN[#1]% + {\setchemicalname NEWMAN + % + \setchemicalmaximum 6 + \setchemicaldistance 0 + \setchemicalsubstitute 0 + % + \ifNEWMANstagger + \setchemicalrotation 1 0.707 0.707 0.707 -0.707 -0.707 -0.707 -0.707 0.707 + \setchemicalrotation 2 0 -1 -1 0 0 1 1 0 + \setchemicalrotation 3 -0.707 0.707 0.707 0.707 0.707 -0.707 -0.707 -0.707 + \else + \setchemicalrotation 1 .866 -.5 -.5 -.866 -.866 .5 .5 .866 + \setchemicalrotation 2 -.259 .966 .966 .259 .259 -.966 -.966 -.259 + \setchemicalrotation 3 -.5 -.866 -.866 .5 .5 .866 .866 -.5 + \fi + \setchemicalrotation 4 0.707 -0.707 -0.707 -0.707 -0.707 0.707 0.707 0.707 + \setchemicalrotation 5 -0.707 -0.707 -0.707 0.707 0.707 0.707 0.707 -0.707 + \setchemicalrotation 6 0 1 1 0 0 -1 -1 0 + % + \ifNEWMANstagger + \setchemicalangle 1 315 45 135 225 + \setchemicalangle 2 90 180 270 0 + \setchemicalangle 3 225 315 45 135 + \else + \setchemicalangle 1 30 120 210 300 + \setchemicalangle 2 255 345 75 165 + \setchemicalangle 3 120 210 300 30 + \fi + \setchemicalangle 4 45 135 225 315 + \setchemicalangle 5 135 225 315 45 + \setchemicalangle 6 270 0 90 180 + % + \setchemicaltranslate 1 -1500 0 + \setchemicaltranslate 2 0 1500 + \setchemicaltranslate 3 1500 0 + \setchemicaltranslate 4 0 -1500 + % + \setchemicallinesegment B1 0 0 1000 0 + \setchemicallinesegment B2 0 0 1000 0 + \setchemicallinesegment B3 0 0 1000 0 + \setchemicallinesegment B4 500 0 1000 0 + \setchemicallinesegment B5 500 0 1000 0 + \setchemicallinesegment B6 500 0 1000 0 + % + \setchemicaltextelement Z 1100 0 + % + \setchemicalcircsegment C 0 360 500 360 0 -500 + % + \def\processchemical[##1##2##3##4]% + {\processaction + [##1##2##3##4] + [STAGGER????=>{\executechemicalNEWMANSTAGGER[#1]}, + ECLIPSE????=>{\executechemicalNEWMANECLIPSE[#1]}, + B????=>\processlocalchemicals{B1..6}, + CB????=>\processlocalchemicals{B1..6,C,Z1..6}, + C????=>\processchemicalcircsegment{C}{1????}, + ROT##4=>\processchemicalrotation{##4}, + MOV##4=>\processchemicaltranslate{##4}, + B##2##3##4=>\processprivatechemicallinesegment{B}{##2##3##4}, + Z##2##3##4=>\ifNEWMANstagger + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,t,r,l,r,b, l,r,l,r,r,l, r,b,l,r,l,t, r,l,r,l,l,r}% + \else + \processchemicaltextelement{Z}{##2##3##4}{#1}{6} + {l,r,t,t,r,b, t,b,r,r,b,l, r,l,b,b,l,t, b,t,l,l,t,r}% + \fi, + \s!unknown=>\unknownchemical{##1##2##3##4}]}} + +\def\executechemicalCHAIR[#1]% smaller + {\setchemicalname CHAIR + % + \setchemicalmaximum 6 + % + \setchemicallinesegment B1 1600 800 2800 -800 + \setchemicallinesegment B2 2800 -800 800 0 + \setchemicallinesegment B3 800 0 -1600 -800 + \setchemicallinesegment B4 -1600 -800 -2800 800 + \setchemicallinesegment B5 -2800 800 -800 0 + \setchemicallinesegment B6 -800 0 1600 800 + % + \setchemicallinesegment +R1 1600 800 1600 1600 + \setchemicallinesegment +R2 2800 -800 2800 -1600 + \setchemicallinesegment +R3 800 0 800 800 + \setchemicallinesegment +R4 -1600 -800 -1600 -1600 + \setchemicallinesegment +R5 -2800 800 -2800 1600 + \setchemicallinesegment +R6 -800 0 -800 -800 + % + \setchemicallinesegment -R1 1600 800 2350 522 % 750 278 + \setchemicallinesegment -R2 2800 -800 3493 -400 + \setchemicallinesegment -R3 800 0 1329 -600 % 528 600 + \setchemicallinesegment -R4 -1600 -800 -2350 -522 % 750 278 + \setchemicallinesegment -R5 -2800 800 -3493 400 + \setchemicallinesegment -R6 -800 0 -1329 600 % 528 600 + % + \setchemicaltextelement +RZ1 1600 1800 + \setchemicaltextelement +RZ2 2800 -1800 + \setchemicaltextelement +RZ3 800 1000 + \setchemicaltextelement +RZ4 -1600 -1800 + \setchemicaltextelement +RZ5 -2800 1800 + \setchemicaltextelement +RZ6 -800 -1000 + % + \setchemicaltextelement -RZ1 2538 453 % 200 lang + \setchemicaltextelement -RZ2 3666 -300 + \setchemicaltextelement -RZ3 1460 -750 + \setchemicaltextelement -RZ4 -2538 -453 + \setchemicaltextelement -RZ5 -3666 300 + \setchemicaltextelement -RZ6 -1460 750 + % + \def\processchemical[##1##2##3##4##5]% + {\def\chemicalrotation{1}% + \processaction + [##1##2##3##4##5] + [ B????=>\processlocalchemicals{B1,B2,B3,B4,B5,B6}, + -R????=>\processlocalchemicals{-R1,-R2,-R3,-R4,-R5,-R6}, + +R????=>\processlocalchemicals{+R1,+R2,+R3,+R4,+R5,+R6}, + B##2????=>{\getchemicallinesegment[0][B##2]}, + -RZ##4????=>{\getchemicalfixedtextelement[-RZ##4][1][##4][l,l,tc,r,r,bc][#1]}, + +RZ##4????=>{\getchemicalfixedtextelement[+RZ##4][1][##4][c][#1]}, + -R##3????=>{\getchemicallinesegment[0][-R##3]}, + +R##3????=>{\getchemicallinesegment[0][+R##3]}, + \s!unknown=>\unknownchemical{##1##2##3##4##5}]}} + +\def\executechemicalarrow#1#2[#3]% + {\dogetcommalistelement1\from#3\to\toptext + \dogetcommalistelement2\from#3\to\bottext + \def\dochemicaltext##1% + {\dosetsubscripts% + $\@@dochemicalstyle{\@@localchemicalformat\strut##1}$% + \doresetsubscripts}% + \doifelse\@@chemicallocation\v!intext + {#1{\dochemicaltext\toptext}}% + {\setbox\chemicalsymbols=\hbox + {\box\chemicalsymbols + \vbox{\halign{##\cr + \hbox to 3em{\hss\dochemicaltext{\toptext}\hss}\cr + #2% + \hbox to 3em{\hss\dochemicaltext{\bottext}\hss}\cr}}}}} + +\def\executechemicalGIVES + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {\rightarrowfill\cr}} + +\def\executechemicalEQUILIBRIUM + {\executechemicalarrow + {\chemicaldoublepicturearrow}% nodig + {\rightarrowfill\cr\leftarrowfill\cr}} + +\def\executechemicalMESOMERIC + {\executechemicalarrow + {\chemicalsinglepicturearrow}% nodig + {$\leftarrow\hskip-1em$\rightarrowfill\cr}} + +\def\executechemicalsign#1[#2]% + {\doifelse\@@chemicallocation\v!intext + {\dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts} + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \dosetsubscripts + $\@@dochemicalstyle{\@@localchemicalformat#1}$% + \doresetsubscripts}}} + +\def\executechemicalPLUS + {\executechemicalsign{+}} + +\def\executechemicalMINUS + {\executechemicalsign{-}} + +\def\executechemicalEQUAL + {\executechemicalsign{=}} + +\def\executechemicalSPACE[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + \quad}}} + +\def\executechemicalCHEM[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols + $\@@dochemicalstyle{\@@localchemicalformat#1}$}}} + +\def\executechemicalTEXT[#1]% + {\doifnot\@@chemicallocation\v!intext + {\setbox\chemicalsymbols\hbox + {\box\chemicalsymbols#1}}} + +%\def\executechemicalLOW[#1]% +% {\setlowsubscripts} +% +%\def\executechemicalHIGH[#1]% +% {\sethighsubscripts} + +\def\putchemicalrule#1#2#3#4% + {\ifcase\chemicaldrawingmode + \putrule from {#1} {#2} to {#3} {#4} + \or + \psline(#1,#2)(#3,#4)% + \or + \bgroup + \!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax + \global\MPdrawingdonetrue + \setchemicalattributes + \startMPdrawing + x1 := \MPdivten[\the\!!counta]u ; + y1 := \MPdivten[\the\!!countb]u ; + x2 := \MPdivten[\the\!!countc]u ; + y2 := \MPdivten[\the\!!countd]u ; + draw z1--z2 ; + \stopMPdrawing + \egroup + \fi} + +\def\executechemicalcomplex#1% + {\bgroup + \putchemicalrule {0} {-\@@chemicalbottom} {0} {\@@chemicaltop}% + \putchemicalrule {0} {\@@chemicaltop} {#1150} {\@@chemicaltop}% + \putchemicalrule {0} {-\@@chemicalbottom} {#1150} {-\@@chemicalbottom}% + \egroup} + +\def\executechemicalOPENCOMPLEX[#1]% + {\executechemicalcomplex+\ignorespaces + \executechemicalSPACE[]} + +\def\executechemicalCLOSECOMPLEX[#1]% + {\executechemicalSPACE[]% + \executechemicalcomplex-\ignorespaces} + +% nog niet door midden as! + +\def\executechemicalverticalsymbol#1#2% + {\executechemicalTEXT + [$\left#1\relax + \dimen0=\@@chemicalunit + \scratchcounter=\@@chemicaltop + \advance\scratchcounter by \@@chemicalbottom + \dimen0=\scratchcounter\dimen0 + \vcenter to \dimen0{} + \dimen2=\@@chemicalunit + \dimen2=\@@chemicalright\dimen0 + \vcenter{\leftskip1em\hsize\dimen2\relax\strut#2\strut}% + \right.$]}% + +\def\executechemicalUPARROW[#1]% + {\executechemicalverticalsymbol\uparrow{#1}} + +\def\executechemicalDOWNARROW[#1]% + {\executechemicalverticalsymbol\downarrow{#1}} + +\def\executechemicalUPDOWNARROW[#1]% + {\executechemicalverticalsymbol\updownarrow{#1}} + +\let\setchemicalattributes\relax + +\setupchemical + [\c!width=0, + \c!height=0, + \c!left=0, + \c!right=0, + \c!top=0, + \c!bottom=0, + \c!bodyfont=\the\bodyfontsize, + \c!resolution=\outputresolution, + \c!scale=\v!medium, + \c!size=\v!medium, + \c!textsize=\v!big, + \c!frame=\v!off, + \c!axis=\v!off, + \c!state=\v!start, + \c!style=\rm, + \c!location=, + \c!option=, + \c!offset=LOW, + \c!alternative=1, + \c!color=, + \c!rulethickness=, + \c!rulecolor=, + \c!factor=1] + +% Tijdelijk plaatsen we deze extra macro's hier. +% +% mathontop: \mtop {} {} +% textontop: \ttop {} {} + +\def\putontop#1#2% + {\vbox + {\halign + {\strut\hss##\hss\cr + #1\cr + #2\cr}}} + +\def\ttop#1#2% + {\putontop{\tx#1}{#2}} + +\def\mtop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\scriptscriptstyle#1$\cr + \noalign{\vskip.5ex}% + $#2$\cr}}} + +\def\ctop#1#2% + {\vbox + {\offinterlineskip + \halign + {\hss##\hss\cr + $\@@dochemicalstyle{\@@localchemicalformat\scriptscriptstyle#1}$\cr + \noalign{\vskip.5ex}% + $\@@dochemicalstyle{\@@localchemicalformat#2}$\cr}}} + +%D Here are a couple of goodies: +%D +%D \startitemize +%D \item styles hooked into \CONTEXT\ style mechanism +%D \item support for color and rulethickness (mp mode only) +%D \item position tracking +%D \stopitemize + +\let\@@chemicalrulecolor\empty +\let\@@chemicalcolor \empty + +\def\setchemicalattributes + {\scratchdimen\@@chemicalrulethickness + \def\chemicalattributes + {withpen pencircle scaled \the\scratchdimen\space + withcolor }% + \doifelsenothing\@@chemicalrulecolor + {\edef\chemicalattributes{\chemicalattributes black}} + {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalrulecolor}}}% + \startMPdrawing + drawoptions (\chemicalattributes) ; + \stopMPdrawing} + +\unexpanded\def\@@dochemicalcolor + {\dousecolorparameter\@@chemicalcolor} + +\unexpanded\def\@@dochemicalstyle + {\dousestyleparameter\@@chemicalstyle} + +\setupchemical + [\c!rulethickness=\linewidth, + \c!rulecolor=, + \c!color=] + +\def\cpos#1#2% + {\iftrialtypesetting + #2% + \else + \bgroup + \globalpushmacro\dowithchemical + \gdef\dowithchemical##1{\hpos{#1}{##1}\globalpopmacro\dowithchemical}% + #2% + \egroup + \fi} + +\protect \endinput + +% \startchemical[axis=on,frame=yes] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=small,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=medium,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical + +% \startchemical[size=big,scale=big,axis=on,frame=yes,factor=1.5] +% \chemical[SIX,ROT2,B,R36,RZ6][CH_3] +% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H] +% \stopchemical diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-art-01.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-art-01.mkiv new file mode 100644 index 00000000000..601ee1adc80 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-art-01.mkiv @@ -0,0 +1,62 @@ +\unprotect + +\startmodule[art-01] + +\definemeasure [article:margin] [\paperheight/20] % was 15, see xtables-mkiv for results +\definemeasure [overview:margin] [\paperheight/30] + +\definelayout + [article] + [\c!topspace=\measure{article:margin}, + \c!bottomspace=\measure{article:margin}, + \c!backspace=\measure{article:margin}, + \c!header=\measure{article:margin}, + \c!footer=0pt, + \c!width=\v!middle, + \c!height=\v!middle] + + +\definelayout + [overview] + [\c!topspace=\measure{overview:margin}, + \c!bottomspace=\measure{overview:margin}, + \c!backspace=\measure{overview:margin}, + \c!header=\measure{overview:margin}, + \c!footer=0pt, + \c!width=\v!middle, + \c!height=\v!middle] + +\setuplayout + [article] + +\setupbodyfont + [dejavu,10pt] % 12pt is just to large and we use this for all kind of demos + +\setupwhitespace + [\v!big] + +\setuphead + [\v!chapter] + [\c!style=\bfc, + \c!headerstate=\v!high, + \c!interaction=\v!all] + +\setuphead + [\v!section] + [\c!style=\bfb] + +\setuphead + [\v!subsection] + [\c!style=\bfa] + +\setuphead + [\v!subsubsection] + [\c!style=\bf, + \c!after=] + +\setuplist + [\c!interaction=\v!all] + +\protect + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-def-01.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-def-01.mkiv new file mode 100644 index 00000000000..49e585bd018 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-def-01.mkiv @@ -0,0 +1,10 @@ +% yes or no + +\unprotect + +\startsetups defaults:frontpart:pagenumbers:roman + \defineconversionset[\c!frontpart:\c!pagenumber][][romannumerals] + \setupuserpagenumber[\c!way=\v!by\v!block] +\stopsetups + +\protect diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-figures-names.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-figures-names.mkiv new file mode 100644 index 00000000000..a2782efc95d --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-figures-names.mkiv @@ -0,0 +1,99 @@ +%D \module +%D [ file=s-figures-names.mkiv, +%D version=2017.07.17, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Figure Names, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Normally this module will be run someplace at the end of a document in some kind of tracing +%D mode. We could hook it into \type {\stoptext} but better leave it up to the user. Loading +%D this module upfront will not show anything useful. The main reason for making this module +%D was that we wanted to report weird figurenames: spaces, multiple hyphens in a row, mixed +%D hyphens and underscores, inconsistently mixed upper and lowercase, etc. +%D +%D If you only want info in the logfile, you can use: +%D +%D \starttyping +%D \enabletrackers[graphics.lognames] +%D \stoptyping +%D +%D This directive is persistent and can be issued any time before the end of the run. + +\startmodule[figures-names] + +\startluacode + +local context = context +local ctx_NC = context.NC +local ctx_NR = context.NR +local ctx_red = context.red +local ctx_starttabulate = context.starttabulate +local ctx_stoptabulate = context.stoptabulate +local ctx_hyphenatedname = context.hyphenatedfilename + +trackers.enable("graphics.lognames") + +context.start() + + context.switchtobodyfont { "tt,small" } + + local template = { "|Bl|p|" } + + for _, data in table.sortedhash(figures.found) do + ctx_starttabulate(template) + local badname = data.badname + local found = data.found + ctx_NC() + context("asked name") + ctx_NC() + if badname then + ctx_red() + end + context(data.askedname) + ctx_NC() ctx_NR() + if found then + ctx_NC() + context("format") + ctx_NC() + context(data.format) + ctx_NC() ctx_NR() + ctx_NC() + context("found file") + ctx_NC() + ctx_hyphenatedname(data.foundname) + -- context(data.foundname) + ctx_NC() ctx_NR() + ctx_NC() + context("used file") + ctx_NC() + ctx_hyphenatedname(data.fullname) + -- context(data.fullname) + ctx_NC() ctx_NR() + if badname then + ctx_NC() + context("comment") + ctx_NC() + context("bad name") + ctx_NC() ctx_NR() + end + else + ctx_NC() + context("comment") + ctx_NC() + context(data.comment or "not found") + ctx_NC() ctx_NR() + end + ctx_stoptabulate() + end + +context.stop() + +\stopluacode + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-10.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-10.mkiv new file mode 100644 index 00000000000..731c4be392f --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-10.mkiv @@ -0,0 +1,169 @@ +%D \module +%D [ file=s-fnt-01, +%D version=2006.10.10, % guess +%D title=\CONTEXT\ Style File, +%D subtitle=Listing Glyphs in Large Fonts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% sort of obsolete + +\startluacode +local fontdata = fonts.hashes.identifiers + +-- function fonts.tracers.show_all() +-- local tfmdata = fontdata[font.current()] +-- if tfmdata and tfmdata.shared then +-- local NC, NR, char = context.NC, context.NR, context.char +-- context.starttabulate { "|l|r|c|" } +-- for unicode, description in fonts.iterators.characters(tfmdata) do +-- NC() context(description.name) NC() context(unicode) NC() char(unicode) NC() NR() +-- end +-- context.stoptabulate() +-- end +-- end + +local context = context +local escaped = context.escaped + +function fonts.tracers.show_all() + local tfmdata = fontdata[font.current()] + if tfmdata then + local NC, NR, HL, char, bold, tttf = context.NC, context.NR, context.HL, context.char, context.bold, context.tttf + local descriptions = tfmdata.descriptions or { } + local data = characters.data + -- context.setuptabulate { header = "repeat" } + context.starttabulatehead() + NC() bold("unicode") + NC() bold("visual") + NC() bold("index") + NC() bold("glyph") + NC() bold("adobe") + NC() bold("context") + NC() NR() + context.stoptabulatehead() + context.starttabulate { "|l|c|l|p|p|p|" } + for unicode, chr in fonts.iterators.characters(tfmdata) do + local des, dat = descriptions[unicode], data[unicode] + local index = chr.index or 0 + local cname = (dat and dat.contextname) or "" + local aname = (dat and dat.adobename) or "" + local gname = (des and des.name) or "" + local mname = dat and dat.mathname + if type(mname) ~= "string" then + mname = "" + end + local mspec = dat and dat.mathspec + if mspec then + for m=1,#mspec do + local n = mspec[m].name + if n then + if mname == "" then + mname = n + else + mname = mname .. " " .. n + end + end + end + end + if mname ~= "" then + mname = "m: " .. mname + if cname ~= "" then + cname = cname .. " " .. mname + else + cname = mname + end + end + NC() tttf() context("U+%05X",unicode) + NC() char(unicode) + NC() tttf() context("%05X",index) + NC() if gname ~= "" then tttf() escaped(gname) end + NC() if aname ~= "" then tttf() context(aname) end + NC() if cname ~= "" then tttf() context(cname) end + NC() NR() + end + context.stoptabulate() + else + context("problems") + end +end + +function fonts.tracers.show_glyphs() + local tfmdata = fontdata[font.current()] + if tfmdata then + for unicode, chr in fonts.iterators.characters(tfmdata) do + context.showglyph(unicode) + end + end +end +\stopluacode + +\unexpanded\def\ShowCompleteFont#1#2#3% + {\bgroup + \page + \font\TestFont=#1 at #2 + \setuplayout[style=\TestFont] + \setupheadertexts[] + \setupfootertexts[#1 -- \pagenumber] + \setupfootertexts[pagenumber] + \setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm] + \TestFont + \nonknuthmode + \startcolumns[n=#3] + \TestFont + \ctxlua { fonts.tracers.show_all() } + \stopcolumns + \page + \egroup} + +\unexpanded\def\ShowAllGlyphs#1#2#3% + {\bgroup + \page + \def\showglyph##1{\dontleavehmode\strut\char##1\relax\par} + \font\TestFontA=#1 at 12pt + \font\TestFontB=#1 at #2 + \setuplayout[style=\TestFontA] + \setupheadertexts[] + \setupfootertexts[#1\space\endash\space\pagenumber] + \setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm,header=1cm,footer=2cm] + \TestFontB \setupinterlinespace[line=1.2\dimexpr#2\relax] \raggedcenter + \nonknuthmode + \startcolumns[n=#3] + \TestFontB + \ctxlua { fonts.tracers.show_glyphs() } + \stopcolumns + \page + \egroup} + +\continueifinputfile{s-fnt-10.mkiv} + +\starttext + +% \ShowCompleteFont{name:dejavusansmono}{10pt}{1} +% \ShowCompleteFont{name:dejavuserif}{10pt}{2} +% \ShowCompleteFont{name:officinasansbookitcregular}{10pt}{2} +% \ShowCompleteFont{name:officinaserifbookitcregular}{10pt}{2} +% \ShowCompleteFont{name:serpentineserifeflight}{10pt}{2} +\ShowCompleteFont{name:lmroman10-regular}{10pt}{1} +% \ShowCompleteFont{name:lmtypewriter10-regular}{10pt}{2} +% \ShowCompleteFont{lt55485}{10pt}{2} +% \ShowCompleteFont{lmr10}{10pt}{2} +% \ShowCompleteFont{lbr}{10pt}{2} +% \ShowCompleteFont{name:Cambria}{10pt}{2} +% \ShowCompleteFont{name:CambriaMath}{10pt}{2} +% \ShowCompleteFont{name:texgyrepagella-regular}{10pt}{2} +% \ShowCompleteFont{name:texgyrechorus-mediumitalic}{10pt}{2} +% \ShowAllGlyphs {name:texgyrepagella-regular} {48pt}{2} +% \ShowAllGlyphs {name:texgyrechorus-mediumitalic}{48pt}{2} +% \ShowCompleteFont{name:euler10-regular}{10pt}{2} + +% \ShowCompleteFont{name:palatinosansinformalcombold}{20pt}{2} +% \ShowCompleteFont{name:palatinonovaregular}{11pt}{2} +% \ShowCompleteFont{pirat.ttf}{12pt}{1} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-20.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-20.mkiv new file mode 100644 index 00000000000..5840430990f --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-20.mkiv @@ -0,0 +1,161 @@ +%D \module +%D [ file=s-fnt-20, +%D version=2009.01.10, +%D title=\CONTEXT\ Style File, +%D subtitle=Tracing Feature Application (1), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This file is used by Idris and me in the process of getting the +%D best arabic fonts getting rendered best. As such it might change. + +% \setvariables +% [otftracker] +% [title=Reverse Chaining, +% figure=test-003-volt.pdf, +% font=husayni, +% sample={ببب بببب ببببب بببببب}] + +\def\checkedotftrackerfeature #1{otftracker-\ifnum\featureattribute{otftracker-#1}=\zerocount default\else#1\fi} +\def\checkedotftrackerdirection#1{\csname otftracker-direction-\ifcsname otftracker-direction-#1\endcsname#1\else default\fi\endcsname} + +% we can consider adding a dir key to features + +\definefontfeature + [otftracker-default] + [default] + [mode=node] + +\definefontfeature + [otftracker-arabtype] + [mode=node,analyze=yes, + language=dflt,script=arab,ccmp=yes, + init=yes,medi=yes,fina=yes,isol=yes, + liga=yes,dlig=yes,rlig=yes,clig=yes, + mark=yes,mkmk=yes,kern=yes,curs=yes] + +% \definefontfeature +% [otftracker-husayni] +% [analyze=yes,mode=node, +% language=dflt,script=arab,ccmp=yes, +% init=yes,medi=yes,fina=yes,isol=yes, +% calt=yes, +% mark=yes,mkmk=yes,kern=yes,curs=yes] + +\definefontfeature + [otftracker-husayni] + [analyze=yes,mode=node, + language=dflt,script=arab, + init=yes,medi=yes,fina=yes, + rlig=yes, + ccmp=yes, + ss01=yes, % full Allah, Muhammad, Allahumma + ss05=yes, % full Jiim stacking + ss09=yes, % full Haa stacking + ss10=yes, % partial dipped Miim + ss13=yes, % full stacked Miim + ss15=yes, % full stacked Laam-on-Miim + ss17=yes, % full stacked Ayn-on-Miim + ss19=yes, % LM_im + ss24=yes, % BX specials + ss25=yes, % LH_im specials + ss26=yes, % full Yaa.final specials + ss27=yes, % partial thin Miim.final + ss31=yes, % partial Raa.final contexts + ss34=yes, % partial Raa.final contexts + ss35=yes, % full Kaaf contexts + ss36=yes, % full Laam contexts + ss37=yes, % Miim-Miim contexts + ss38=yes, % fancy thin Haa.medial-Miim.final + ss39=yes, % high and low Baa strings + ss40=yes, % diagonal entry + ss41=yes, % initial alternates + mark=yes,mkmk=yes,kern=yes,curs=yes] + +\definefontfeature + [otftracker-simplenaskhi] + [analyze=yes,mode=node, + language=dflt,script=arab, + init=yes,medi=yes,fina=yes,calt=yes, + rlig=yes,liga=yes,dlig=yes, + mark=yes,mkmk=yes,kern=yes,curs=yes] + +\setvalue{otftracker-direction-arabtype}{r2l} +\setvalue{otftracker-direction-husayni}{r2l} +\setvalue{otftracker-direction-simplenaskhi}{r2l} +\setvalue{otftracker-direction-default}{} + +\setvariables + [otftracker] + [font=Serif, + features=\checkedotftrackerfeature{\getvariable{otftracker}{font}}, + direction=\checkedotftrackerdirection{\getvariable{otftracker}{font}}, + size=48pt, + figure=, + title=Feature Check, + sample=no sample, + set=\setups{otftracker}] + +\setuplayout + [topspace=1.5cm, + backspace=1.5cm, + width=middle, + height=middle, + header=1.5cm, + footer=1.5cm] + +\setuphead + [chapter] + [header=high, + number=no] + +\setupfootertexts + [chapter] + +\setupalign + [flushleft] + +\setupcolors + [state=start] + +\startsetups otftracker + \setupbodyfont[tt,10pt] + \starttext + \normalexpanded{\startchapter[title={\getvariable{otftracker}{title}}]} + \doifsomething {\getvariable{otftracker}{figure}} { + \startlinecorrection + \externalfigure[\getvariable{otftracker}{figure}][maxwidth=\hsize,frame=on] + \stoplinecorrection + } + \showotfcomposition + {\getvariable{otftracker}{font}*\getvariable{otftracker}{features} at \getvariable{otftracker}{size}} + {\getvariable{otftracker}{direction}} + {\getvariable{otftracker}{sample}} + \stopchapter + \stoptext +\stopsetups + +\continueifinputfile{s-fnt-20.mkiv} + +\usemodule[art-01] + +\setupbodyfont +% [cambria] + [dejavu] + +\starttext + +\setvariables + [otftracker] + [font=Serif, + size=48pt, + figure=, + title=Feature Check, + sample={affiliation}] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-21.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-21.mkiv new file mode 100644 index 00000000000..10d5a462394 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-21.mkiv @@ -0,0 +1,64 @@ +%D \module +%D [ file=s-fnt-20, +%D version=2009.01.10, +%D title=\CONTEXT\ Style File, +%D subtitle=Tracing Feature Application (2), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module is related to: + +\usemodule[fnt-20] + +\setvariables + [otftracker] + [set=\setups{araball}] + +\startsetups araball + \begingroup + \setupcolors[state=start]% + \enabletrackers[otf.analyzing]% beware, kind of global + \ruledhbox \bgroup + \definedfont[\getvariable{otftracker}{font}*\getvariable{otftracker}{features} at \getvariable{otftracker}{size}]% + \ifnum\getvariable{otftracker}{direction}<0 \textdir TRT\else\ifnum\getvariable{otftracker}{direction}>0 \textdir TLT\fi\fi\relax + \getvariable{otftracker}{sample}% + \egroup + \disabletrackers[otf.analyzing]% + \endgroup +\stopsetups + +\unexpanded\def\ShowOtfTrackerSample#1% + {\doiffile{#1} + {\blank + \startlinecorrection + \vbox \bgroup + \forgetall + \setbox\scratchbox\hbox{\component #1 \relax} + \hbox{\copy\scratchbox\quad\lower\dp\scratchbox\hbox{\ruledhbox{\externalfigure[#1-volt.pdf][height=\htdp\scratchbox]}}} + \hbox{\strut\tttf#1}% + \egroup + \stoplinecorrection + \blank}} + +\endinput + +% \usemodule[fnt-21] +% +% \starttext +% +% \setvariables +% [otftracker] +% [direction=-1, +% sample=لا, +% title=Test, +% font=file:arabtype, +% % font=file:husayni, +% % font=file:scheherazaderegot, +% features=arabic] +% +% \stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-24.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-24.mkiv new file mode 100644 index 00000000000..2e6b9a59187 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fnt-24.mkiv @@ -0,0 +1,83 @@ +%D \module +%D [ file=s-fnt-24, +%D version=2009.02.06, +%D title=\CONTEXT\ Style File, +%D subtitle=CJK Glyph Combination Testing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\def\ShowChineseCombiChar#1#2#3#4% + {\blank[small] + \dontleavehmode + \hbox\bgroup + \dontcomplain + \setstrut + \hbox to 7em{\ruledhbox{\char#1}\hskip.25em\type{+}\hskip.25em\ruledhbox{\char#2}\hskip.25em\type{=}\hskip.25em\ruledhbox{\char#1\char#2}\hss}\relax + \ruledvtop{\hsize1em\char#1\char#2}\relax + \hskip2em + \ruledvtop{\hsize.625em\char#1\char#2}\relax + \hskip2em + \ruledvtop{\hsize1.5em\char#1\char#2}\relax + \hskip2em + \type{#3 + #4}\relax + \egroup + \blank[small]} + +\startluacode +local example = { + korean = 0x0AC00, + chinese = 0x04E55, + full_width_open = 0x03008, + full_width_close = 0x03009, + half_width_open = 0x02018, + half_width_close = 0x02019, + hyphen = 0x02026, + non_starter = 0x03005, + other = 0x0004D, -- M +} + +function fonts.analyzers.cjktest(first,second) + for k, v in next, example do + if (not first or first == "") or first == k then + for kk, vv in next, example do + if (not second or second == "") or second == kk then + context.ShowChineseCombiChar(v,vv,k,kk) + end + end + end + end +end +\stopluacode + +\unexpanded\def\ShowCombinationsKorean + {\dodoubleempty\doShowCombinationsKorean} + +\def\doShowCombinationsKorean[#1][#2]% + {\startpacked + \setscript[hangul] + \setupcolors[\c!state=\v!start] + \enabletrackers[cjk.analyzing] + \ctxlua{fonts.analyzers.cjktest("#1","#2")}\par % ! + \disabletrackers[cjk.analyzing] + \stoppacked} + +\unexpanded\def\ShowCombinationsChinese + {\dodoubleempty\doShowCombinationsChinese} + +\def\doShowCombinationsChinese[#1][#2]% + {\startpacked + \setscript[hanzi] + \setupcolors[\c!state=\v!start] + \enabletrackers[cjk.analyzing] + \ctxlua{fonts.analyzers.cjktest("#1","#2")}\par % ! + \disabletrackers[cjk.analyzing] + \stoppacked} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-charts.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-charts.mkiv new file mode 100644 index 00000000000..e94b52a2e76 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-charts.mkiv @@ -0,0 +1,204 @@ +%D \module +%D [ file=s-fonts-charts, +%D version=2015.08.08, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Fonts Charts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% begin info +% +% title : show unicode blocks +% +% comment : show charts of a given fgont +% +% end info + +\startmodule[fonts-charts] + +% \registerctxluafile{s-fonts-charts}{} +\starttexdefinition unexpanded FontChartSetSlot #1#2 + \dontleavehmode + \setbox\scratchbox\vbox to 1cm \bgroup + \vss + \hbox to 1cm \bgroup + \infofont \hss\raise.25mm\hbox{#2}\hss + \egroup + \egroup + \wd\scratchbox0mm + \ht\scratchbox5mm + \dp\scratchbox5mm + \box\scratchbox + \setbox\scratchbox\ruledhbox to 1cm \bgroup + \hss\char#1\hss + \egroup + \ht\scratchbox5mm + \dp\scratchbox5mm + \box\scratchbox +\stoptexdefinition + +\starttexdefinition unexpanded FontChartNoSlot + \dontleavehmode + \setbox\scratchbox\hbox to 1cm \bgroup + % empty + \egroup + \ht\scratchbox5mm + \dp\scratchbox5mm + \box\scratchbox +\stoptexdefinition + +\starttexdefinition unexpanded FontChartSetLegend #1 + \dontleavehmode + \setbox\scratchbox\hbox to 1cm \bgroup + \infofont\hss#1\hss + \egroup + \ht\scratchbox5mm + \dp\scratchbox5mm + \box\scratchbox +\stoptexdefinition + +\starttexdefinition unexpanded FontChartSetCaption #1#2 + \dontleavehmode + \setbox\scratchbox\hbox to 16cm \bgroup + \infofontbold\hskip1cm#1: #2\hss + \egroup + \ht\scratchbox7.5mm + \dp\scratchbox2.5mm + \box\scratchbox +\stoptexdefinition + +\starttexdefinition unexpanded FontChartGap + \kern .5mm +\stoptexdefinition + +\startluacode + local div, mod = math.div, math.mod + local formatters = string.formatters + + moduledata.fonts = moduledata.fonts or { } + moduledata.fonts.charts = moduledata.fonts.charts or { } + + function moduledata.fonts.charts.show(settings) + + local settings = utilities.parsers.settings_to_hash(settings) + + local filename = settings.filename or "" + local fontid = true + local newpage = settings.page == interfaces.variables.yes + + if filename ~= "" then + fontid = fonts.definers.internal({ name = filename, size = "10pt" },"chartfont") + end + + local ranges = { } + local data = fonts.hashes.identifiers[fontid] + local private = fonts.constructors.privateoffset + local chars = data.characters + + for u in table.sortedhash(chars) do + if u >= private then + break + else + ranges[div(u,0xFF)] = true + end + end + + local ctx_setlegend = context.FontChartSetLegend + local ctx_noslot = context.FontChartNoSlot + local ctx_setslot = context.FontChartSetSlot + local ctx_setcaption = context.FontChartSetCaption + local ctx_par = context.par + local ctx_gap = context.FontChartGap + + for r in table.sortedhash(ranges) do + if newpage then + context.page() + end + context.startframed { offset = "overlay", frame = "off", align = "normal" } + if filename ~= "" then + context.chartfont() + end + context.dontcomplain() + context.offinterlineskip() + ctx_noslot() + for i=0,0xF do + ctx_setlegend(formatters["%03X"](r*0x10+i)) + end + r = r * 0xFF + ctx_par() + for i=0,0xF do + ctx_setlegend(formatters["%0X"](i)) + ctx_gap() + for j=0,0xF do + local u = r + i*0x10 + j + local d = chars[u] + if d then + ctx_setslot(u,formatters["%04X"](u)) + else + ctx_noslot() + end + if j ~= 0xF then + ctx_gap() + end + end + ctx_par() + ctx_gap() + end + ctx_setcaption(formatters["%04X-%04X"](r,r+0xFF),file.basename(data.properties.filename)) + ctx_par() + context.stopframed() + if newpage then + context.page() + end + end + end +\stopluacode + +\installmodulecommandluasingle \showfontchart {moduledata.fonts.charts.show} + +\stopmodule + +\continueifinputfile{s-fonts-charts.mkiv} + +\usemodule[art-01] + +\starttext + + \showfontchart[filename=LucidaBrightOT.otf,page=yes] + \showfontchart[filename=LucidaBrightOT-Demi.otf,page=yes] + \showfontchart[filename=LucidaBrightOT-DemiItalic.otf,page=yes] + \showfontchart[filename=LucidaBrightOT-Italic.otf,page=yes] + + \showfontchart[filename=LucidaSansOT.otf,page=yes] + \showfontchart[filename=LucidaSansOT-Demi.otf,page=yes] + \showfontchart[filename=LucidaSansOT-DemiItalic.otf,page=yes] + \showfontchart[filename=LucidaSansOT-Italic.otf,page=yes] + + \showfontchart[filename=LucidaSansTypewriterOT.otf,page=yes] + \showfontchart[filename=LucidaSansTypewriterOT-Bold.otf,page=yes] + \showfontchart[filename=LucidaSansTypewriterOT-BoldOblique.otf,page=yes] + \showfontchart[filename=LucidaSansTypewriterOT-Oblique.otf,page=yes] + + \showfontchart[filename=LucidaConsoleDK.otf,page=yes] + \showfontchart[filename=LucidaConsoleDK-Bold.otf,page=yes] + \showfontchart[filename=LucidaConsoleDK-BoldItalic.otf,page=yes] + \showfontchart[filename=LucidaConsoleDK-Italic.otf,page=yes] + + \showfontchart[filename=LucidaGrandeMonoDK.otf,page=yes] + \showfontchart[filename=LucidaGrandeMonoDK-Bold.otf,page=yes] + \showfontchart[filename=LucidaGrandeMonoDK-BoldItalic.otf,page=yes] + \showfontchart[filename=LucidaGrandeMonoDK-Italic.otf,page=yes] + + \showfontchart[filename=LucidaBrightMathOT.otf,page=yes] + \showfontchart[filename=LucidaBrightMathOT-Demi.otf,page=yes] + + \showfontchart[filename=LucidaBlackletterOT.otf,page=yes] + \showfontchart[filename=LucidaCalligraphyOT.otf,page=yes] + \showfontchart[filename=LucidaHandwritingOT.otf,page=yes] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-coverage.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-coverage.lua new file mode 100644 index 00000000000..dd772d5f09b --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-coverage.lua @@ -0,0 +1,123 @@ +if not modules then modules = { } end modules ['s-fonts-coverage'] = { + version = 1.001, + comment = "companion to s-fonts-coverage.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.coverage = moduledata.fonts.coverage or { } + +local upper, format = string.upper, string.format +local lpegmatch = lpeg.match +local concat = table.concat + +local context = context +local NC, NR, HL = context.NC, context.NR, context.HL +local char, bold, getvalue = context.char, context.bold, context.getvalue + +local chardata = characters.data + +function moduledata.fonts.coverage.showcomparison(specification) + + specification = interfaces.checkedspecification(specification) + + local fontfiles = utilities.parsers.settings_to_array(specification.list or "") + local pattern = upper(specification.pattern or "") + + local present = { } + local names = { } + local files = { } + local chars = { } + + if not pattern then + -- skip + elseif pattern == "" then + pattern = nil + elseif tonumber(pattern) then + pattern = tonumber(pattern) + else + pattern = lpeg.oneof(utilities.parsers.settings_to_array(pattern)) + pattern = (1-pattern)^0 * pattern + end + + for i=1,#fontfiles do + local fontname = format("testfont-%s",i) + local fontfile = fontfiles[i] + local fontsize = tex.dimen.bodyfontsize + local id, fontdata = fonts.definers.define { + name = fontfile, + size = fontsize, + cs = fontname, + } + if id and fontdata then + for k, v in next, fontdata.characters do + present[k] = true + end + names[#names+1] = fontname + files[#files+1] = fontfile + chars[#names] = fontdata.characters + end + end + + local t = { } + + context.starttabulate { "|Tr" .. string.rep("|l",#names) .. "|" } + for i=1,#files do + local file = files[i] + t[#t+1] = i .. "=" .. file + NC() + context(i) + NC() + context(file) + NC() + NR() + end + context.stoptabulate() + + context.setupfootertexts { + table.concat(t," ") + } + + context.starttabulate { "|Tl" .. string.rep("|c",#names) .. "|Tl|" } + NC() + bold("unicode") + NC() + for i=1,#names do + bold(i) + NC() + end + bold("description") + NC() + NR() + HL() + for k, v in table.sortedpairs(present) do + if k <= 0 then + -- ignore + elseif k >= 0x110000 then + logs.report("warning","weird character %U",k) + else + local description = chardata[k].description + if not pattern or (pattern == k) or (description and lpegmatch(pattern,description)) then + NC() + context("%05X",k) + NC() + for i=1,#names do + getvalue(names[i]) + if chars[i][k] then + char(k) + else + -- missing + end + NC() + end + context(description) + NC() + NR() + end + end + end + context.stoptabulate() + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-coverage.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-coverage.mkiv new file mode 100644 index 00000000000..c09d943bcca --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-coverage.mkiv @@ -0,0 +1,131 @@ +%D \module +%D [ file=s-fonts-coverage, % s-fnt-31 +%D version=2011.01.02, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Fonts Coverage, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% begin info +% +% title : compare glyphs in fonts +% +% comment : show glyphs in several fonts alongside in order to to compare coverage +% status : experimental, used for luatex testing +% +% end info + +\startmodule[fonts-coverage] + +\registerctxluafile{s-fonts-coverage}{} + +\installmodulecommandluasingle \showfontcomparison {moduledata.fonts.coverage.showcomparison} + +\stopmodule + +\continueifinputfile{s-fonts-coverage.mkiv} + +\usemodule[art-01] + +\starttext + + \showfontcomparison + [list={texgyrepagella-regular.otf,texgyretermes-regular.otf,texgyrebonum-regular.otf}, + pattern=ogonek] + + \page + + % $e=mc²$ ${}²$ $²$ $x²ᶞ$ $xâ½Â²âºÂ²â¼Â²âºÂ²â¾$ $x²âºÂ²â¼Â²âºÂ²$ $x₅²$ $x²₅²$ + + % \startluacode + % moduledata.fonts.coverage.showcomparison { + % list = { + % "texgyrepagella-math.otf", + % "texgyretermes-math.otf", + % "texgyrebonum-math.otf", + % } + % } + % \stopluacode + + % \startluacode + % moduledata.fonts.coverage.showcomparison { + % list = "pirat.ttf", + % } + % \stopluacode + + % \startluacode + % moduledata.fonts.coverage.showcomparison { + % list = { + % "lucidabrightot.otf", + % "cambria.ttf", + % "iwona-regular.otf", + % "texgyrepagella-regular.otf", + % "texgyretermes-regular.otf", + % "texgyrebonum-regular.otf", + % "antpolt-regular.otf", + % }, + % pattern = "OGONEK" + % } + % \stopluacode + + % \loadfontgoodies[lucida-math] + % \loadfontgoodies[lm-math] + % + % \startluacode + % moduledata.fonts.coverage.showcomparison { + % list = { + % "LucidaBrightRegular.ttf", + % "LucidaBrightOne@lucida-math", + % "cambria.ttc(Cambria Math)", + % "xits-math.otf", + % "LMMath10-Regular@lmroman10-math", + % }, + % } + % \stopluacode + + % \loadfontgoodies[px-math] + % \loadfontgoodies[lm-math] + % + % \startluacode + % moduledata.fonts.coverage.showcomparison { + % list = { + % "cambria.ttc(Cambria Math)", + % "xits-math.otf", + % -- "stixmath-regular.otf", + % "latinmodern-math.otf", + % -- "lucidabrightmathot.otf", + % -- "lucidabrightmathot-demi.otf", + % "texgyrepagella-math.otf", + % "texgyretermes-math.otf", + % "texgyrebonum-math.otf", + % -- "LMMath10-Regular@lmroman10-math", + % -- "pxmath@px-math", + % -- "txmath@tx-math", + % }, + % } + % \stopluacode + + % \startluacode + % moduledata.fonts.coverage.showcomparison { + % list = { + % "dejavuserif.ttf", + % "dejavusans.ttf", + % "dejavusansmono.ttf", + % "lucidabrightot.otf", + % "cambria.ttf", + % "iwona-regular.otf", + % "texgyrepagella-regular.otf", + % "texgyretermes-regular.otf", + % "texgyrebonum-regular.otf", + % "antpolt-regular.otf", + % }, + % pattern = "CELSIUS,FAHRENHEIT" + % } + % \stopluacode + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-features.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-features.lua new file mode 100644 index 00000000000..0a7cf8b132c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-features.lua @@ -0,0 +1,161 @@ +if not modules then modules = { } end modules ['s-fonts-features'] = { + version = 1.001, + comment = "companion to s-fonts-features.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.features = moduledata.fonts.features or { } + +-- for the moment only otf + +local sortedhash = table.sortedhash + +local NC, NR, bold = context.NC, context.NR, context.bold + +function moduledata.fonts.features.showused(specification) + + specification = interfaces.checkedspecification(specification) + + -- local list = utilities.parsers.settings_to_set(specification.list or "all") + + context.starttabulate { "|T|T|T|T|T|" } + + context.HL() + + NC() bold("feature") + NC() + NC() bold("description") + NC() bold("value") + NC() bold("internal") + NC() NR() + + context.HL() + + local usedfeatures = fonts.handlers.otf.statistics.usedfeatures + local features = fonts.handlers.otf.tables.features + local descriptions = fonts.handlers.otf.features.descriptions + + for feature, keys in sortedhash(usedfeatures) do + -- if list.all or (list.otf and rawget(features,feature)) or (list.extra and rawget(descriptions,feature)) then + local done = false + for k, v in sortedhash(keys) do + if done then + NC() + NC() + NC() + elseif rawget(descriptions,feature) then + NC() context(feature) + NC() context("+") -- extra + NC() context(descriptions[feature]) + done = true + elseif rawget(features,feature) then + NC() context(feature) + NC() -- otf + NC() context(features[feature]) + done = true + else + NC() context(feature) + NC() context("-") -- unknown + NC() + done = true + end + NC() context(k) + NC() context(tostring(v)) + NC() NR() + end + -- end + end + + context.HL() + + context.stoptabulate() + +end + +local function collectkerns(tfmdata,feature) + local combinations = { } + local resources = tfmdata.resources + local characters = tfmdata.characters + local sequences = resources.sequences + local lookuphash = resources.lookuphash + local feature = feature or "kern" + if sequences then + for i=1,#sequences do + local sequence = sequences[i] + if sequence.features and sequence.features[feature] then + local lookuplist = sequence.subtables + if lookuplist then + for l=1,#lookuplist do + local lookupname = lookuplist[l] + local lookupdata = lookuphash[lookupname] + for unicode, data in next, lookupdata do + local kerns = combinations[unicode] + if not kerns then + kerns = { } + combinations[unicode] = kerns + end + for otherunicode, kern in next, data do + if not kerns[otherunicode] and kern ~= 0 then + kerns[otherunicode] = kern + end + end + end + end + end + end + end + end + return combinations +end + +local showkernpair = context.showkernpair + +function moduledata.fonts.features.showbasekerns(specification) + -- assumes that the font is loaded in base mode + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"<module:fonts:features:font>") + local tfmdata = fonts.hashes.identifiers[id] + local done = false + for unicode, character in sortedhash(tfmdata.characters) do + local kerns = character.kerns + if kerns then + context.par() + for othercode, kern in sortedhash(kerns) do + showkernpair(unicode,kern,othercode) + end + context.par() + done = true + end + end + if not done then + context("no kern pairs found") + context.par() + end +end + +function moduledata.fonts.features.showallkerns(specification) + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"<module:fonts:features:font>") + local tfmdata = fonts.hashes.identifiers[id] + local allkerns = collectkerns(tfmdata) + local characters = tfmdata.characters + if next(allkerns) then + for first, pairs in sortedhash(allkerns) do + context.par() + for second, kern in sortedhash(pairs) do + -- local kerns = characters[first].kerns + -- if not kerns and pairs[second] then + -- -- weird + -- end + showkernpair(first,kern,second,0) + end + context.par() + end + else + context("no kern pairs found") + context.par() + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-features.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-features.mkiv new file mode 100644 index 00000000000..b81b53a7176 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-features.mkiv @@ -0,0 +1,82 @@ +%D \module +%D [ file=s-fonts-features, % was s-fnt-41, s-fnt-27 +%D version=2012.11.27, % 2010.02.22 +%D title=\CONTEXT\ Style File, +%D subtitle=Features, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[fonts-features] + +\registerctxluafile{s-fonts-features}{} + +\installmodulecommandluasingle \showusedfeatures {moduledata.fonts.features.showused} +\installmodulecommandluasingle \showallkerns {moduledata.fonts.features.showallkerns} +\installmodulecommandluasingle \showbasekerns {moduledata.fonts.features.showbasekerns} + +\def\kernpairheight{\strutheight} +\def\kernpairdepth {\strutdepth} +\def\kernpairwidth {\onepoint} + +\unexpanded\def\showkernpair#1#2#3% first second kern + {\dontleavehmode + \hbox \bgroup + \scratchdimen#2\scaledpoint + \kern\fontcharwd\font#1\relax + \ifdim\scratchdimen>\zeropoint + \bgroup + \darkgreen + \vrule width \scratchdimen height \kernpairheight depth \kernpairdepth + \egroup + \kern-\scratchdimen + \else\ifdim\scratchdimen<\zeropoint + \kern\scratchdimen + \bgroup + \darkred + \vrule width -\scratchdimen height \kernpairheight depth \kernpairdepth + \egroup + \else + \kern-.5\dimexpr\kernpairwidth\relax + \bgroup + \darkblue + \vrule width \kernpairwidth height \kernpairheight depth \kernpairdepth + \egroup + \kern-.5\dimexpr\kernpairwidth\relax + \fi\fi + \kern-\fontcharwd\font#1\relax + \char#1\relax + \char#3\relax + \egroup + \space} + +\stopmodule + +\continueifinputfile{s-fonts-features.mkiv} + +\usemodule + [art-01] + +\starttext + + \showusedfeatures \page + + \definefontfeature[default-base][default][mode=base] + + \start + \definedfont[Serif*default-base] + \showbasekerns + \page + \stop + + \start + \bf + \showallkerns + \page + \stop + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-goodies.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-goodies.lua new file mode 100644 index 00000000000..381fc45eabf --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-goodies.lua @@ -0,0 +1,117 @@ +if not modules then modules = { } end modules['s-fonts-goodies'] = { + version = 1.001, + comment = "companion to s-fonts-goodies.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.goodies = moduledata.fonts.goodies or { } + +local NC, NR, HL = context.NC, context.NR, context.HL + +local function initialized(specification) + specification = interfaces.checkedspecification(specification) + local name = specification.name + if name then + local goodies = fonts.goodies.load(name) + if goodies then + return specification, goodies + end + end +end + +function moduledata.fonts.goodies.showstylistics(specification) + local specification, goodies = initialized(specification) + if goodies then + local stylistics = goodies.stylistics + if stylistics then + context.starttabulate { "|Tl|Tpl|" } + HL() + NC() context.bold("feature") + NC() context.bold("meaning") + NC() NR() + HL() + for feature, meaning in table.sortedpairs(stylistics) do + NC() context(feature) + NC() context(string.lower(meaning)) + NC() NR() + end + HL() + context.stoptabulate() + end + end +end + +function moduledata.fonts.goodies.showfeaturesets(specification) + local specification, goodies = initialized(specification) + if goodies then + local featuresets = goodies.featuresets + if featuresets then + context.starttabulate { "|Tl|Tpl|" } + HL() + NC() context.bold("featureset") + NC() context.bold("definitions") + NC() NR() + HL() + for featureset, definitions in table.sortedpairs(featuresets) do + NC() context.type(featureset) NC() + for k, v in table.sortedpairs(definitions) do + context("%s=%S",k,v) + context.quad() + end + NC() NR() + end + HL() + context.stoptabulate() + end + end +end + +function moduledata.fonts.goodies.showcolorschemes(specification) + local specification, goodies = initialized(specification) + if goodies then + local colorschemes = goodies.colorschemes + if colorschemes then + context.starttabulate { "|Tl|Tpl|" } + HL() + NC() context.bold("colorscheme") + NC() context.bold("numbers") + NC() NR() + HL() + for colorscheme, numbers in table.sortedpairs(colorschemes) do + NC() context.type(colorscheme) NC() + for i=1,#numbers do + context(i) + context.quad() + end + NC() NR() + end + HL() + context.stoptabulate() + end + end +end + +function moduledata.fonts.goodies.showfiles(specification) + local specification, goodies = initialized(specification) + if goodies then + local files = goodies.files + if files and files.list then + for filename, specification in table.sortedpairs(files.list) do + context.start() + context.dontleavehmode() + context.definedfont{ filename .. "*default" } + context("%s-%s-%s-%s-%s", + specification.name or files.name, + specification.weight or "normal", + specification.style or "normal", + specification.width or "normal", + specification.variant or "normal") + context.par() + context.stop() + end + end + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-goodies.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-goodies.mkiv new file mode 100644 index 00000000000..e596507afa9 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-goodies.mkiv @@ -0,0 +1,37 @@ +%D \module +%D [ file=s-fonts-goodies, % s-fnt-26, s-fnt-28 +%D version=2009.10.26, +%D title=\CONTEXT\ Style File, +%D subtitle=Goodies Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D More tables will follow here as we have many more goodies by now. + +\startmodule[fonts-goodies] + +\registerctxluafile{s-fonts-goodies}{} + +\installmodulecommandluasingle \showfontgoodiesstylistics {moduledata.fonts.goodies.showstylistics} +\installmodulecommandluasingle \showfontgoodiesfeaturesets {moduledata.fonts.goodies.showfeaturesets} +\installmodulecommandluasingle \showfontgoodiescolorschemes {moduledata.fonts.goodies.showcolorschemes} +\installmodulecommandluasingle \showfontgoodiesfiles {moduledata.fonts.goodies.showfiles} + +\stopmodule + +\continueifinputfile{s-fonts-goodies.mkiv} + +\starttext + + \showfontgoodiesstylistics [name=husayni] \page + \showfontgoodiesfeaturesets [name=husayni] \page + \showfontgoodiescolorschemes[name=husayni] \page + + \showfontgoodiesfiles [name=antykwapoltawskiego] \page + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-ligatures.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-ligatures.mkiv new file mode 100644 index 00000000000..fc49ec5c58b --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-ligatures.mkiv @@ -0,0 +1,209 @@ +%D \module +%D [ file=s-fonts-ligatures, +%D version=2014.12.14, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Fonts Ligatures, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% begin info +% +% title : show some ligature building in fonts +% +% comment : we trace some ligatures that have rather different implementations in fontss +% status : experimental, used for luatex testing +% +% end info + +\definefontfeature + [otfligaturetest] + [analyze=off, + ccmp=yes, % brill uses that .. not really ligatures ! + %clig=yes, + script=latn, + language=dflt] + +\hyphenation{xf-fi-a} +\hyphenation{xff-i-b} +\hyphenation{xffi-c} +\hyphenation{xffid} + +\registerhyphenationexception[xf-fi-a] +\registerhyphenationexception[xff-i-b] +\registerhyphenationexception[xffi-c] +\registerhyphenationexception[xffid] + +\starttexdefinition showotfligaturescaption #1 + \bTD [align={flushleft,lohi},nx=3] + \nohyphens + \ttbf + #1 + \eTD +\stoptexdefinition + +\starttexdefinition showotfligatureslegend #1 + \bTD [width=6em,align={flushleft,lohi}] + \nohyphens \ttxx original + \eTD + \bTD [width=6em,align={flushleft,lohi}] + \nohyphens \ttxx expanded + \eTD + \bTD [width=6em,align={flushleft,lohi}] + \nohyphens \ttxx traditional + \eTD +\stoptexdefinition + +\starttexdefinition showotfligaturesline #1#2 + \bTD[toffset=.5ex,frame=off] + \starthyphenation[#1] + \LigatureFont + \showfontkerns + \showdiscretionaries + \begstrut#2\endstrut + \par + \stophyphenation + \eTD +\stoptexdefinition + +\def\showotfligaturescells{3} +%def\showotfligaturesnx {12} +%def\showotfligatureswidth{18em} +\def\showotfligaturesnx {\the\numexpr 4*\showotfligaturescells} +\def\showotfligatureswidth{\the\dimexpr6em*\showotfligaturescells} + +\starttexdefinition showotfligaturesbanner #1 + \bTR[frame=off] + \bTD [nx=\showotfligaturesnx,xwidth=\showotfligatureswidth,align={middle,lohi},height=4ex] + \tttf #1 + \eTD + \eTR +\stoptexdefinition + +\starttexdefinition showotfligaturescaptions #1 + \bTR[height=3ex,align={middle,lohi},bottomframe=off] + \processcommalist[#1]\showotfligaturescaption + \eTR + \bTR[height=3ex,align={middle,lohi},topframe=off] + \processcommalist[#1]\showotfligatureslegend + \eTR +\stoptexdefinition + +\starttexdefinition showotfligatureslineset #1 + \showotfligaturesline{original} {#1} + \showotfligaturesline{expanded} {#1} + \showotfligaturesline{traditional}{#1} +\stoptexdefinition + + +\starttexdefinition showotfligaturesparagraphset #1 + \showotfligatureslineset { + \hsize \zeropoint + \lefthyphenmin \plustwo + \righthyphenmin\plustwo + #1 + } +\stoptexdefinition + +\starttexdefinition showotfligaturesextremeset #1 + \showotfligatureslineset { + \hsize \zeropoint + \lefthyphenmin \plusone + \righthyphenmin\plusone + #1 + } +\stoptexdefinition + +\starttexdefinition showotfligatureslines #1 + \bTR[height=4ex,bottomframe=off] + \processcommalist[#1]\showotfligatureslineset + \eTR +\stoptexdefinition + +\starttexdefinition showotfligaturesparagraphs #1 + \bTR[topframe=off] + \processcommalist[#1]\showotfligaturesparagraphset + \eTR +\stoptexdefinition + +\starttexdefinition showotfligaturesextremes #1 + \bTR[topframe=off] + \processcommalist[#1]\showotfligaturesextremeset + \eTR +\stoptexdefinition + +\starttexdefinition showotfligaturesdefaults + \bTR + \bTD [nx=\showotfligaturesnx,xwidth=\showotfligatureswidth,align=middle,height=4ex,frame=off] + \start \LigatureFont fb \stop \quad + \start \LigatureFont ff \stop \quad + \start \LigatureFont fi \stop \quad + \start \LigatureFont fk \stop \quad + \start \LigatureFont fl \stop \quad + \start \LigatureFont ft \stop \quad + \start \LigatureFont ffb \stop \quad + \start \LigatureFont fff \stop \quad + \start \LigatureFont ffi \stop \quad + \start \LigatureFont ffl \stop \quad + \start \LigatureFont ffk \stop \quad + \start \LigatureFont fft \stop + \eTD + \eTR +\stoptexdefinition + +\starttexdefinition showotfligaturesexample #1#2 + \ctxlua{document.currentdiscexpansion = fonts.getdiscexpansion()}% + \showotfligaturescaptions {#1} + \showotfligatureslines {#2} + \showotfligaturesparagraphs{#2} + \showotfligaturesextremes {#2} + \ctxlua{fonts.setdiscexpansion(document.currentdiscexpansion)}% +\stoptexdefinition + +% todo: n -> and split in lua + +\starttexdefinition showotfligaturesexamples + \showotfligaturesexample + {leafing,baffling,efficient,shifffahrt} + {leafing,baffling,efficient,shifffahrt} + \showotfligaturesexample + {offbeat,effect,ef-fective,ef\-fective} + {offbeat,effect,ef-fective,ef\-fective} + \showotfligaturesexample + {xf+fi+a,xff+i+b,xffi+c,xffid} + {xffia, xffib, xffic, xffid} +\stoptexdefinition + +\starttexdefinition showotfligatures [#1] + \begingroup + \getdummyparameters[font=Regular,features=default,#1] + \definefont[LigatureFont][\dummyparameter{font}*\dummyparameter{features},otfligaturetest ht 2ex] + \bTABLE[leftframe=off,rightframe=off] + \showotfligaturesbanner{\dummyparameter{font} * \dummyparameter{features}} + \showotfligaturesdefaults + \showotfligaturesexamples + \eTABLE + \endgroup +\stoptexdefinition + +\continueifinputfile{s-fonts-ligatures.mkiv} + +\starttext + + \definefontfeature[fonttest][default] [mode=node,language=dflt,script=latn,ccmp=yes,liga=yes,kern=yes,mark=yes,mkmk=yes] + \definefontfeature[capstest][smallcaps][mode=node,language=dflt,script=latn,ccmp=yes,liga=yes,kern=yes,mark=yes,mkmk=yes] + + \startTEXpage[offset=10pt] \showotfligatures[font=lmroman10-regular.otf, features=fonttest] \stopTEXpage + \startTEXpage[offset=10pt] \showotfligatures[font=dejavu-serif.ttf, features=fonttest] \stopTEXpage + \startTEXpage[offset=10pt] \showotfligatures[font=minionpro.otf, features=fonttest] \stopTEXpage + \startTEXpage[offset=10pt] \showotfligatures[font=minionpro.otf, features=capstest] \stopTEXpage + \startTEXpage[offset=10pt] \showotfligatures[font=brill.otf, features=fonttest] \stopTEXpage + \startTEXpage[offset=10pt] \showotfligatures[font=gentiumplus-r.ttf, features=fonttest] \stopTEXpage + \startTEXpage[offset=10pt] \showotfligatures[font=cambria, features=fonttest] \stopTEXpage + \startTEXpage[offset=10pt] \showotfligatures[font=ebgaramond12-regular.otf,features=fonttest] \stopTEXpage + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-missing.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-missing.lua new file mode 100644 index 00000000000..9a75676a908 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-missing.lua @@ -0,0 +1,91 @@ +if not modules then modules = { } end modules ['s-fonts-missing'] = { + version = 1.001, + comment = "companion to s-fonts-missing.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.missing = moduledata.fonts.missing or { } + +local function legend(id) + local c = fonts.hashes.identifiers[id] + local privates = c.properties.privates + if privates then + local categories = table.swapped(fonts.loggers.category_to_placeholder) + context.starttabulate { "|c|l|" } + context.HL() + context.NC() + context.bold("symbol") + context.NC() + context.bold("name") + context.NC() + context.NR() + context.HL() + for k, v in table.sortedhash(privates) do + local tag = characters.categorytags[categories[k]] + if tag and tag ~= "" then + context.NC() + context.dontleavehmode() + context.char(v) + context.NC() + context(k) + context.NC() + context.NR() + end + end + context.HL() + context.stoptabulate() + end +end + +function moduledata.fonts.missing.showlegend(specification) + specification = interfaces.checkedspecification(specification) + context.begingroup() + context.definedfont { "Mono*missing" } -- otherwise no privates added + context(function() legend(specification.id or font.current()) end) + context.endgroup() +end + +local function missings() + local collected = fonts.checkers.getmissing() + for filename, list in table.sortedhash(collected) do + if #list > 0 then + context.starttabulate { "|l|l|" } + context.NC() + context.bold("filename") + context.NC() + context(file.basename(filename)) + context.NC() + context.NR() + context.NC() + context.bold("missing") + context.NC() + context(#list) + context.NC() + context.NR() + context.stoptabulate() + context.starttabulate { "|l|c|l|" } + for i=1,#list do + local u = list[i] + context.NC() + context("%U",u) + context.NC() + context.char(u) + context.NC() + context(characters.data[u].description) + context.NC() + context.NR() + end + context.stoptabulate() + end + end +end + +function moduledata.fonts.missing.showcharacters(specification) + context.begingroup() + context.definedfont { "Mono*missing" } -- otherwise no privates added + context(function() missings() end) + context.endgroup() +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-missing.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-missing.mkiv new file mode 100644 index 00000000000..c566f4995d3 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-missing.mkiv @@ -0,0 +1,56 @@ +%D \module +%D [ file=s-fonts-missing, +%D version=2011.10.30, +%D title=\CONTEXT\ Style File, +%D subtitle=Some Missing Character Info, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[fonts-missing] + +\registerctxluafile{s-fonts-missing}{} + +\installmodulecommandluasingle \showmissingcharacterslegend {moduledata.fonts.missing.showlegend} +\installmodulecommandluasingle \showmissingcharacters {moduledata.fonts.missing.showcharacters} + +\stopmodule + +\continueifinputfile{s-fonts-missing.mkiv} + +% the sooner, the more efficient, see log for details + +\enabletrackers[fonts.missing=replace] + +% \definefontfeature[default][default][missing=yes] % automatically when enabled + +\starttext + + \page legend: \blank + + \showmissingcharacterslegend + + \page sample: \blank + + ½ â…“ ¼ â…• â…™ â…› {\bf ½ â…“ ¼ â…• â…™ â…›} \blank + + \startluacode + for i=1,1000 do + local c = characters.data[i] + if c then + context.char(c.unicodeslot) + context.space() + end + end + \stopluacode + + \page characters: \blank + + \showmissingcharacters + +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.lua new file mode 100644 index 00000000000..8f872e4bcc5 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.lua @@ -0,0 +1,326 @@ +if not modules then modules = { } end modules['s-fonts-shapes'] = { + version = 1.001, + comment = "companion to s-fonts-shapes.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.shapes = moduledata.fonts.shapes or { } + +local fontdata = fonts.hashes.identifiers + +local context = context +local NC, NR = context.NC, context.NR +local space, dontleavehmode, glyph, getvalue = context.space, context.dontleavehmode, context.glyph, context.getvalue +local formatters = string.formatters + +function char(id,k) + dontleavehmode() + glyph(id,k) +end + +local function special(id,specials) + if specials and #specials > 1 then + context("%s:",specials[1]) + if #specials > 5 then + space() char(id,specials[2]) + space() char(id,specials[3]) + space() context("...") + space() char(id,specials[#specials-1]) + space() char(id,specials[#specials]) + else + for i=2,#specials do + space() char(id,specials[i]) + end + end + end +end + +function moduledata.fonts.shapes.showlist(specification) -- todo: ranges + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>") + local chrs = fontdata[id].characters + context.begingroup() + context.tt() + context.starttabulate { "|l|c|c|c|c|l|l|" } + context.FL() + NC() context.bold("unicode") + NC() context.bold("glyph") + NC() context.bold("shape") + NC() context.bold("lower") + NC() context.bold("upper") + NC() context.bold("specials") + NC() context.bold("description") + NC() NR() + context.TL() + for k, v in next, characters.data do + if chrs[k] then + NC() context("0x%05X",k) + NC() char(id,k) -- getvalue(cs) context.char(k) + NC() char(id,v.shcode) + NC() char(id,v.lccode or k) + NC() char(id,v.uccode or k) + NC() special(id,v.specials) + NC() context.tx(v.description) + NC() NR() + end + end + context.stoptabulate() + context.endgroup() +end + +function moduledata.fonts.shapes.showlist(specification) -- todo: ranges + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>") + local chrs = fontdata[id].characters + context.begingroup() + context.tt() + context.starttabulate { "|l|c|c|c|c|l|l|" } + context.FL() + NC() context.bold("unicode") + NC() context.bold("glyph") + NC() context.bold("shape") + NC() context.bold("lower") + NC() context.bold("upper") + NC() context.bold("specials") + NC() context.bold("description") + NC() NR() + context.TL() + for k, v in next, characters.data do + if chrs[k] then + NC() context("0x%05X",k) + NC() char(id,k) + NC() char(id,v.shcode) + NC() char(id,v.lccode or k) + NC() char(id,v.uccode or k) + NC() special(id,v.specials) + NC() context.tx(v.description) + NC() NR() + end + end + context.stoptabulate() + context.endgroup() +end + +local descriptions = nil +local characters = nil + +local function showglyphshape(specification) + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>") + local tfmdata = fontdata[id] + local charnum = tonumber(specification.character) + if not charnum then + charnum = fonts.helpers.nametoslot(n) + end + context.start() + context.dontleavehmode() + context.obeyMPboxdepth() + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local parameters = tfmdata.parameters + local c = characters[charnum] + local d = descriptions[charnum] + if d then + local factor = (parameters.size/parameters.units)*((7200/7227)/65536) + local llx, lly, urx, ury = unpack(d.boundingbox) + llx, lly, urx, ury = llx*factor, lly*factor, urx*factor, ury*factor + local width, italic = (d.width or 0)*factor, (d.italic or 0)*factor + local top_accent, bot_accent = (d.top_accent or 0)*factor, (d.bot_accent or 0)*factor + local anchors, math = d.anchors, d.math + context.startMPcode() + context("numeric lw ; lw := .125bp ;") + context("pickup pencircle scaled lw ;") + context('picture p ; p := image(draw textext.drt("\\getuvalue{%s}\\gray\\char%s");); draw p ;',cs,charnum) + context('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury) + context('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0) + context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;') + context("defaultscale := 0.05 ; ") + -- inefficient but non critical + local function slant_1(v,dx,dy,txt,xsign,ysign,loc,labloc) + if #v > 0 then + local l = { } + for kk, vv in ipairs(v) do + local h, k = vv.height, vv.kern + if h and k then + l[#l+1] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) + end + end + context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1]) + context("draw laddered (%s) withcolor .5white ;",table.concat(l,"..")) + context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l]) + for k, v in ipairs(l) do + context("draw %s withcolor blue withpen pencircle scaled 2lw ;",v) + end + end + end + local function slant_2(v,dx,dy,txt,xsign,ysign,loc,labloc) + if #v > 0 then + local l = { } + for kk, vv in ipairs(v) do + local h, k = vv.height, vv.kern + if h and k then + l[#l+1] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) + end + end + if loc == "top" then + context('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[#l]) + else + context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1]) + end + for kk, vv in ipairs(v) do + local h, k = vv.height, vv.kern + if h and k then + context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[kk]) + end + end + end + end + if math then + local kerns = math.kerns + if kerns then + for _, slant in ipairs { slant_1, slant_2 } do + for k,v in pairs(kerns) do + if k == "top_right" then + slant(v,width+italic,0,k,1,1,"top","ulft") + elseif k == "bottom_right" then + slant(v,width,0,k,1,1,"bot","lrt") + elseif k == "top_left" then + slant(v,0,0,k,-1,1,"top","ulft") + elseif k == "bottom_left" then + slant(v,0,0,k,-1,1,"bot","lrt") + end + end + end + end + end + local function show(x,y,txt) + local xx, yy = x*factor, y*factor + context("draw (%s,%s) withcolor blue withpen pencircle scaled 2lw ;",xx,yy) + context('label.top("\\type{%s}",(%s,%s-2bp)) ;',txt,xx,yy) + context('label.bot("(%s,%s)",(%s,%s+2bp)) ;',x,y,xx,yy) + end + if anchors then + local a = anchors.baselig + if a then + for k, v in pairs(a) do + for kk, vv in ipairs(v) do + show(vv[1],vv[2],k .. ":" .. kk) + end + end + end + local a = anchors.mark + if a then + for k, v in pairs(a) do + show(v[1],v[2],k) + end + end + local a = anchors.basechar + if a then + for k, v in pairs(a) do + show(v[1],v[2],k) + end + end + local ba = anchors.centry + if a then + for k, v in pairs(a) do + show(v[1],v[2],k) + end + end + local a = anchors.cexit + if a then + for k, v in pairs(a) do + show(v[1],v[2],k) + end + end + end + if italic ~= 0 then + context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width,ury,width,ury) + context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width+italic,ury,width+italic,ury) + context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue ;',width,ury,width+italic,ury) + context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury) + context('label.rt("%s",(%s-2bp,%s-1bp));',d.italic,width+italic,ury) + end + if top_accent ~= 0 then + context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,ury) + context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,ury) + context('label.top("%s",(%s,%s-1bp));',d.top_accent,top_accent,ury) + end + if bot_accent ~= 0 then + context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,lly) + context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,ury) + context('label.bot("%s",(%s,%s+1bp));',d.bot_accent,bot_accent,lly) + end + context('draw origin withcolor red withpen pencircle scaled 2lw;') + context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;") + context("currentpicture := currentpicture scaled 8 ;") + context.stopMPcode() + -- elseif c then + -- lastdata, lastunicode = nil, nil + -- local factor = (7200/7227)/65536 + -- context.startMPcode() + -- context("pickup pencircle scaled .25bp ; ") + -- context('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum) + -- context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;') + -- context("defaultscale := 0.05 ; ") + -- local italic, top_accent, bot_accent = (c.italic or 0)*factor, (c.top_accent or 0)*factor, (c.bot_accent or 0)*factor + -- local width, height, depth = (c.width or 0)*factor, (c.height or 0)*factor, (c.depth or 0)*factor + -- local ury = height + -- if italic ~= 0 then + -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury) + -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury) + -- context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,height) + -- context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,height) + -- context('label.rt("%6.3f bp",(%s-2bp,%s-1bp));',italic,width+italic,height) + -- end + -- if top_accent ~= 0 then + -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,height) + -- context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,height) + -- context('label.top("%6.3f bp",(%s,%s-1bp));',top_accent,top_accent,height) + -- end + -- if bot_accent ~= 0 then + -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,height) + -- context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,height) + -- context('label.bot("%6.3f bp",(%s,%s+1bp));',bot_accent,bot_accent,height) + -- end + -- context('draw origin withcolor red withpen pencircle scaled 1bp;') + -- context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;") + -- context("currentpicture := currentpicture scaled 8 ;") + -- context.stopMPcode() + else + lastdata, lastunicode = nil, nil + context("no such shape: 0x%05X",charnum) + end + context.stop() +end + +moduledata.fonts.shapes.showglyphshape = showglyphshape + +function moduledata.fonts.shapes.showallglypshapes(specification) + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>") + local descriptions = fontdata[id].descriptions + for unicode, description in fonts.iterators.descriptions(tfmdata) do + if unicode >= 0x110000 then + break + end + context.modulefontsstartshowglyphshape(unicode,description.name or "",description.index or 0) + showglyphshape { number = id, character = unicode } + context.modulefontsstopshowglyphshape() + end +end + +function moduledata.fonts.shapes.showlastglyphshapefield(unicode,name) + if not descriptions then + -- bad news + elseif name == "unicode" then + context("U+%05X",descriptions.unicode) + else + local d = descriptions[name] + if d then + context(d) + end + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.mkiv new file mode 100644 index 00000000000..c1e9d61d2d6 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.mkiv @@ -0,0 +1,115 @@ +%D \module +%D [ file=s-fonts-shapes, % s-fnt-29, +%D version=2010.09.27, +%D title=\CONTEXT\ Style File, +%D subtitle=Tracing Shapes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[fonts-shapes] + +\registerctxluafile{s-fonts-shapes}{} + +\installmodulecommandluasingle \showfontshapes {moduledata.fonts.shapes.showlist} +\installmodulecommandluasingle \showglyphshape {moduledata.fonts.shapes.showglypshape} +\installmodulecommandluatwo \showlastglyphshapefield {moduledata.fonts.shapes.showlastglyphshapefield} +\installmodulecommandluasingle \showallglyphshapes {moduledata.fonts.shapes.showallglypshapes} + +\let\modulefontsstartshowglyphshape\gobblethreearguments +\let\modulefontsstopshowglyphshape \relax + +\unprotect + +\startsetups module:showallglyphshapes:start + + \unexpanded\def\modulefontsstartshowglyphshape##1##2##3{ + \startTEXpage[\c!offset=\exheight] + \edef\lastshownglyphshapefieldunicode{##1}% + \edef\lastshownglyphshapefieldname {##2}% + \edef\lastshownglyphshapefieldindex {##3}% + \raggedcenter + } + + \unexpanded\def\modulefontsstopshowglyphshape { + \par + \doifsomething {\lastshownglyphshapefieldunicode} { + \begingroup + \dontleavehmode + \tttf + \setstrut + \strut + 0x\uchexnumbers\lastshownglyphshapefieldunicode + \space:\space + \lastshownglyphshapefieldname + \space:\space + \lastshownglyphshapefieldindex + \par + \endgroup + } + \stopTEXpage + } + +\stopsetups + +\protect + +% downward compatibility: + +\unexpanded\def\ShowGlyphShape#1#2#3% name size glyph + {\ctxlua{moduledata.fonts.shapes.showglyphshape { name = "#1", size = "#2", character = "#3" } }} + +\stopmodule + +\continueifinputfile{s-fonts-shapes.mkiv} + +\setupbodyfont[dejavu,9pt] + +\setuplayout + [backspace=1cm, + topspace=1cm, + footer=1cm, + header=0cm, + height=middle, + width=middle] + +\setupfootertexts + [] + [\saveddefinedfontname\quad\pagenumber] + +\starttext + +% \savedefinedfont[Bold*default] +% \showfontshapes[number=\saveddefinedfontid] +% \page + +% \showfontshapes[name=BoldItalic*default] +% \page + + % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0x62A} \stopTEXpage + % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0x2004} \stopTEXpage + % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0xF0299} \stopTEXpage + % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{NameMe.1190} \stopTEXpage + +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x00066}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x1D453}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x1D43F}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D444}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D447}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x02112}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D432}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D43D}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D44A}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D45D}\stopTEXpage +% \page + + % \showallglyphshapes[name=name:cambria-math,size=100bp] +% \showallglyphshapes[name=name:dejavuserif,size=100bp] + +\showallglyphshapes[name=file:brill.otf,size=100bp] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-system.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-system.lua new file mode 100644 index 00000000000..5b58a4a533f --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-system.lua @@ -0,0 +1,69 @@ +if not modules then modules = { } end modules ['s-fonts-system'] = { + version = 1.001, + comment = "companion to s-fonts-system.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- ["zapfinoforteltpro"]={ +-- ["designsize"]=0, +-- ["filename"]="zapfinoforteltpro.otf", +-- ["fontname"]="zapfinoforteltpro", +-- ["fontweight"]="regular", +-- ["family"]="zapfinoforteltpro", +-- ["subfamily"]="regular", +-- ["familyname"]="zapfinoforteltpro", +-- ["subfamilyname"]="regular", +-- ["format"]="otf", +-- ["fullname"]="zapfinoforteltpro", +-- ["maxsize"]=0, +-- ["minsize"]=0, +-- ["modification"]=1105543074, +-- ["rawname"]="ZapfinoForteLTPro", +-- ["style"]="normal", +-- ["variant"]="normal", +-- ["weight"]="normal", +-- ["width"]="normal", +-- } + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.system = moduledata.fonts.system or { } + +local lower = string.lower + +local context = context +local NC, NR, HL = context.NC, context.NR, context.HL +local bold = context.bold + +function moduledata.fonts.system.showinstalled(specification) + specification = interfaces.checkedspecification(specification) + local pattern = lower(specification.pattern or "") + local list = fonts.names.list(pattern,false,true) + if list then + local files = { } + for k, v in next, list do + files[file.basename(string.lower(v.filename))] = v + end + context.starttabulate { "|Tl|Tl|Tl|Tl|Tl|Tl|" } + HL() + NC() bold("filename") + NC() bold("fontname") + NC() bold("subfamily") + NC() bold("variant") + NC() bold("weight") + NC() bold("width") + NC() NR() + HL() + for filename, data in table.sortedpairs(files) do + NC() context(filename) + NC() context(data.fontname) + NC() context(data.subfamily) + NC() context(data.variant) + NC() context(data.weight) + NC() context(data.width) + NC() NR() + end + context.stoptabulate() + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-system.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-system.mkiv new file mode 100644 index 00000000000..6d9082a6bdc --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-system.mkiv @@ -0,0 +1,39 @@ +%D \module +%D [ file=s-fonts0system, % s-fnt-11, +%D version=2006.02.01, % or so +%D title=\CONTEXT\ Style File, +%D subtitle=Listing Installed Fonts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This code usd to be in the kernel but since it's hardly used +%D it's now a module. +%D +%D \starttyping +%D \showinstalledfonts[pattern={officinasans.*}] +%D \showinstalledfonts[pattern={officinaserif.*}] +%D \showinstalledfonts[pattern={officina.*itc.*}] +%D \stoptyping + +\startmodule[fonts-system] + +\registerctxluafile{s-fonts-system}{} + +\installmodulecommandluasingle \showinstalledfonts {moduledata.fonts.system.showinstalled} + +\stopmodule + +\continueifinputfile{s-fonts-system.mkiv} + +\usemodule[art-01] \setuplayout[overview] \setupbodyfont[7pt] + +\starttext + + \showinstalledfonts + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-tables.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-tables.lua new file mode 100644 index 00000000000..c32f4628c17 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-tables.lua @@ -0,0 +1,363 @@ +if not modules then modules = { } end modules ['s-fonts-tables'] = { + version = 1.001, + comment = "companion to s-fonts-tables.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.tables = moduledata.fonts.tables or { } + +local setmetatableindex = table.setmetatableindex +local sortedhash = table.sortedhash +local sortedkeys = table.sortedkeys +local format = string.format +local concat = table.concat + +local tabletracers = moduledata.fonts.tables + +local context = context + +local digits = { + dflt = { + dflt = "1234567890 1/2", + }, + arab = { + dflt = "", + }, + latn = { + dflt = "1234567890 1/2", + } +} + +local punctuation = { + dflt = { + dflt = ". , : ; ? ! ‹ › « »", + }, +} + +local symbols = { + dflt = { + dflt = "@ # $ % & * () [] {} <> + - = / |", + }, +} + +local LATN = "abcdefghijklmnopqrstuvwxyz" + +local uppercase = { + latn = { + dflt = LATN, + fra = LATN .. " ÀÃÂÈÉÊÒÓÔÙÚÛÆÇ", + }, + grek = { + dftl = "ΑΒΓΔΕΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩ", + }, + cyrl= { + dflt = "ÐБВГДЕЖЗИІЙКЛМÐОПРСТУФХЦЧШЩЪЫЬѢÐЮЯѲ" + }, +} + +local latn = "abcdefghijklmnopqrstuvwxyz" + +local lowercase = { + latn = { + dftl = latn, + nld = latn .. " ïèéë", + deu = latn .. " äöüß", + fra = latn .. " à áâèéêòóôùúûæç", + }, + grek = { + dftl = "αβγδεηθικλμνξοπÏστυφχψω", + }, + cyrl= { + dflt = "абвгдежзиійклмнопрÑтуфхцчшщъыьѣÑÑŽÑѳ" + }, + arab = { + dflt = "ابجدهوزØطيكلمنسعÙصقرشتثخذضظغ" + }, +} + +local samples = { + digits = digits, + punctuation = punctuation, + symbols = symbols, + uppercase = uppercase, + lowercase = lowercase, +} + +tabletracers.samples = samples + +setmetatableindex(uppercase, function(t,k) return rawget(t,"latn") end) +setmetatableindex(lowercase, function(t,k) return rawget(t,"latn") end) +setmetatableindex(digits, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(symbols, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(punctuation, function(t,k) return rawget(t,"dflt") end) + +setmetatableindex(uppercase.latn, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(uppercase.grek, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(uppercase.cyrl, function(t,k) return rawget(t,"dflt") end) + +setmetatableindex(lowercase.latn, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(lowercase.grek, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(lowercase.cyrl, function(t,k) return rawget(t,"dflt") end) + +setmetatableindex(digits.dflt, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(symbols.dflt, function(t,k) return rawget(t,"dflt") end) +setmetatableindex(punctuation.dflt, function(t,k) return rawget(t,"dflt") end) + +local function typesettable(t,keys,synonyms,nesting,prefix) + if t then + if not prefix then + context.starttabulate { "|Tl|Tl|Tl|" } + end + for k, v in sortedhash(keys) do + if k == "synonyms" then + elseif type(v) ~= "table" then + context.NC() + if prefix then + context("%s.%s",prefix,k) + else + context(k) + end + context.NC() + local tk = t[k] + if v == "boolean" then + context(tostring(tk or false)) + elseif not tk then + context("<unset>") + elseif v == "filename" then + context(file.basename(tk)) + elseif v == "basepoints" then + context("%sbp",tk) + elseif v == "scaledpoints" then + context("%p",tk) + elseif v == "table" then + context("<table>") + else -- if v == "integerscale" then + context(tostring(tk)) + end + context.NC() + local synonym = (not prefix and synonyms[k]) or (prefix and synonyms[format("%s.%s",prefix,k)]) + if synonym then + context(format("(%s)",concat(synonym," "))) + end + context.NC() + context.NR() + elseif nesting == false then + context("<table>") + else -- true or nil + typesettable(t[k],v,synonyms,nesting,k) + end + end + if not prefix then + context.stoptabulate() + end + end +end + +local function typeset(t,keys,nesting,prefix) + local synonyms = keys.synonyms or { } + local collected = { } + for k, v in next, synonyms do + local c = collected[v] + if not c then + c = { } + collected[v] = c + end + c[#c+1] = k + end + for k, v in next, collected do + table.sort(v) + end + typesettable(t,keys,collected,nesting,prefix) +end + +tabletracers.typeset = typeset + +function tabletracers.showproperties(nesting) + local tfmdata = fonts.hashes.identifiers[font.current()] + typeset(tfmdata.properties,fonts.constructors.keys.properties,nesting) +end + +function tabletracers.showparameters(nesting) + local tfmdata = fonts.hashes.identifiers[font.current()] + typeset(tfmdata.parameters,fonts.constructors.keys.parameters,nesting) +end + +function tabletracers.showpositionings() + local tfmdata = fonts.hashes.resources[font.current()] + local resources = tfmdata.resources + if resources then + local features = resources.features + if features then + local gpos = features.gpos + if gpos and next(gpos) then + context.starttabulate { "|Tl|Tl|Tlp|" } + for feature, scripts in sortedhash(gpos) do + for script, languages in sortedhash(scripts) do + context.NC() + context(feature) + context.NC() + context(script) + context.NC() + context(concat(sortedkeys(languages)," ")) + context.NC() + context.NR() + end + end + context.stoptabulate() + else + context("no entries") + context.par() + end + end + end +end + +local dynamics = true + +function tabletracers.showsubstitutions() + local tfmdata = fonts.hashes.identifiers[font.current()] + local resources = tfmdata.resources + if resources then + local features = resources.features + if features then + local gsub = features.gsub + if gsub then + local makes_sense = { } + for feature, scripts in sortedhash(gsub) do + for script, languages in sortedhash(scripts) do + for language in sortedhash(languages) do + local tag = format("dummy-%s-%s-%s",feature,script,language) + local fnt = format("file:%s*%s",file.basename(tfmdata.properties.filename),tag) + context.definefontfeature ( + { tag }, + { + mode = "node", + script = script, + language = language, + [feature] = "yes" + } + ) + if not dynamics then + context.definefont( { fnt }, { fnt } ) + end + makes_sense[#makes_sense+1] = { + feature = feature, + tag = tag, + script = script, + language = language, + fontname = fnt, + } + end + end + end + if #makes_sense > 0 then + context.starttabulate { "|Tl|Tl|Tl|p|" } + for i=1,#makes_sense do + local data = makes_sense[i] + local script = data.script + local language = data.language + context.NC() + context(data.feature) + context.NC() + context(script) + context.NC() + context(language) + context.NC() + if not dynamics then + context.startfont { data.fontname } + else + context.addff(data.tag) + end + context.verbatim(samples.lowercase [script][language]) context.par() + context.verbatim(samples.uppercase [script][language]) context.par() + context.verbatim(samples.digits [script][language]) context.par() + context.verbatim(samples.punctuation[script][language]) context.quad() + context.verbatim(samples.symbols [script][language]) + if not dynamics then + context.stopfont() + end + context.NC() + context.NR() + end + context.stoptabulate() + else + context("no entries") + context.par() + end + end + end + end +end + +function tabletracers.showunicodevariants() + + local variants = fonts.hashes.variants[true] + + if variants then + context.starttabulate { "|c|c|c|c|c|c|c|" } + for selector, unicodes in sortedhash(variants) do + local done = false + for unicode, variant in sortedhash(unicodes) do + context.NC() + if not done then + context("%U",selector) + done = true + end + context.NC() + context("%U",unicode) + context.NC() + context("%c",unicode) + context.NC() + context("%U",variant) + context.NC() + context("%c",variant) + context.NC() + context("%c%c",unicode,selector) + context.NC() + context.startoverlay() + context("{\\color[trace:r]{%c}}{\\color[trace:ds]{%c}}",unicode,variant) + context.stopoverlay() + context.NC() + context.NR() + end + end + context.stoptabulate() + end + +end +function tabletracers.showall(specification) -- not interfaced + + specification = interfaces.checkedspecification(specification) + + if specification.title then + context.starttitle { title = specification.title } + end + + context.startsubject { title = "Properties" } + tabletracers.showproperties() + context.stopsubject() + + context.startsubject { title = "Parameters" } + tabletracers.showparameters() + context.stopsubject() + + context.startsubject { title = "Positioning features" } + tabletracers.showpositionings() + context.stopsubject() + + context.startsubject { title = "Substitution features" } + tabletracers.showsubstitutions() + context.stopsubject() + + context.startsubject { title = "Unicode variants" } + tabletracers.showunicodevariants() + context.stopsubject() + + if title then + context.stoptitle() + end + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-tables.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-tables.mkiv new file mode 100644 index 00000000000..64fe76f0e4b --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-tables.mkiv @@ -0,0 +1,38 @@ +%D \module +%D [ file=s-fonts-tables, +%D version=2011.10.10, +%D title=\CONTEXT\ Style File, +%D subtitle=Basic Font Data Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo: make a mtxrun --script font <name> option + +\startmodule[fonts-tables] + +\registerctxluafile{s-fonts-tables}{} + +\installmodulecommandluasingle \showfonttables {moduledata.fonts.tables.showall} +\installmodulecommandluasingle \showfontproperties {moduledata.fonts.tables.showproperties} +\installmodulecommandluasingle \showfontparameters {moduledata.fonts.tables.showparameters} +\installmodulecommandluasingle \showfontpositionings {moduledata.fonts.tables.showpositionings} +\installmodulecommandluasingle \showfontsubstitutions {moduledata.fonts.tables.showsubstitutions} +\installmodulecommandluasingle \showfontunicodevariants{moduledata.fonts.tables.showunicodevariants} + +\stopmodule + +\continueifinputfile{s-fonts-tables.mkiv} + +\usemodule[art-01] + +\setupbodyfont + [cambria] + +\starttext + \showfonttables[title=Cambria] +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-vectors.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-vectors.lua new file mode 100644 index 00000000000..af8042f8458 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-vectors.lua @@ -0,0 +1,104 @@ +if not modules then modules = { } end modules ['s-fonts-vectors'] = { + version = 1.001, + comment = "companion to s-fonts-vectors.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.protrusions = moduledata.fonts.protrusions or { } +moduledata.fonts.expansions = moduledata.fonts.expansions or { } + +local NC, NR = context.NC, context.NR + +local classes = fonts.protrusions.classes +local vectors = fonts.protrusions.vectors + +function moduledata.fonts.protrusions.showvector(specification) + specification = interfaces.checkedspecification(specification) + local vector = vectors[specification.name or "?"] + if vector then + context.blank() + context.startcolumns { n = specification.columns or 3, balance="yes" } + context.starttabulate { "|T||cw(.5em)||" } + for unicode, values in table.sortedhash(vector) do + NC() context("%U",unicode) + NC() context("%.02f",values[1]) + NC() context("%c",unicode) + NC() context("%.02f",values[2]) + NC() NR() + end + context.stoptabulate() + context.stopcolumns() + context.blank() + end +end + +function moduledata.fonts.protrusions.showclass(specification) + specification = interfaces.checkedspecification(specification) + local class = specification.name and classes[specification.name] + local classes = class and { class} or classes + context.starttabulate { "|l|l|r|r|r|" } + NC() context.bold("name") + NC() context.bold("vector") + NC() context.bold("factor") + NC() context.bold("left") + NC() context.bold("right") + NC() NR() + for name, class in table.sortedhash(classes) do + NC() context(name) + NC() context(class.vector) + NC() context("%.02f",class.factor) + NC() context("%.02f",class.left) + NC() context("%.02f",class.right) + NC() NR() + end + context.stoptabulate() +end + +local classes = fonts.expansions.classes +local vectors = fonts.expansions.vectors + +function moduledata.fonts.expansions.showvector(specification) + specification = interfaces.checkedspecification(specification) + local vector = vectors[specification.name or "?"] + if vector then + context.blank() + context.startcolumns { n = specification.columns or 3, balance="yes" } + context.starttabulate { "|T|cw(.5em)||" } + for unicode, value in table.sortedhash(vector) do + NC() context("%U",unicode) + NC() context("%c",unicode) + NC() context("%.02f",value) + NC() NR() + end + context.stoptabulate() + context.stopcolumns() + context.blank() + end +end + +function moduledata.fonts.expansions.showclass(specification) + specification = interfaces.checkedspecification(specification) + local class = specification.name and classes[specification.name] + local classes = class and { class} or classes + context.starttabulate { "|l|l|r|r|r|" } + NC() context.bold("name") + NC() context.bold("vector") + NC() context.bold("step") + NC() context.bold("factor") + NC() context.bold("stretch") + NC() context.bold("shrink") + NC() NR() + for name, class in table.sortedhash(classes) do + NC() context(name) + NC() context(class.vector) + NC() context("%.02f",class.step) + NC() context("%.02f",class.factor) + NC() context("% 2i",class.stretch) + NC() context("% 2i",class.shrink) + NC() NR() + end + context.stoptabulate() +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-vectors.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-vectors.mkiv new file mode 100644 index 00000000000..2605fe96403 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-vectors.mkiv @@ -0,0 +1,72 @@ +%D \module +%D [ file=s-fonts-vectors, % was s-fnt-51, +%D version=2012.11.27, +%D title=\CONTEXT\ Style File, +%D subtitle=Protrusion and Expansion, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This code is used in the \MKIV\ fonts manual. + +\startmodule[fonts-vectors] + +\registerctxluafile{s-fonts-vectors}{} + +\installmodulecommandluasingle \showprotrusionclass {moduledata.fonts.protrusions.showclass} +\installmodulecommandluasingle \showprotrusionvector {moduledata.fonts.protrusions.showvector} +\installmodulecommandluasingle \showexpansionclass {moduledata.fonts.expansions.showclass} +\installmodulecommandluasingle \showexpansionvector {moduledata.fonts.expansions.showvector} + +\stopmodule + +\continueifinputfile{s-fonts-vectors.mkiv} + +\usemodule[art-01] + +\starttext + + \startsubject[title=protrusion] + + \startsubsubject[title=class] + \showprotrusionclass + \stopsubsubject + + \startsubsubject[title=vector pure] + \showprotrusionvector[name=pure] + \stopsubsubject + + \startsubsubject[title=vector punctuation] + \showprotrusionvector[name=punctuation] + \stopsubsubject + + \startsubsubject[title=vector alpha] + \showprotrusionvector[name=alpha] + \stopsubsubject + + \startsubsubject[title=vector quality] + \showprotrusionvector[name=quality] + \stopsubsubject + + \stopsubject + + \page + + \startsubject[title=expansion] + + \startsubsubject[title=class] + \showprotrusionclass + \stopsubsubject + + \startsubsubject[title=vector quality] + \showprotrusionvector[name=quality] + \stopsubsubject + + \stopsubject + +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-inf-01.mkvi b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-01.mkvi new file mode 100644 index 00000000000..2c0c1681e12 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-01.mkvi @@ -0,0 +1,260 @@ +%D \module +%D [ file=s-inf-01, +%D version=2009.07.09, +%D title=\CONTEXT\ Style File, +%D subtitle=Information 1 (\MKII/\MKIV\ usage), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Some day I will generalize this table mechanism. This list is only +%D right when run in the minimals as my machine might have more files. +%D +%D Als, the remaining tex code can proably be lua also which is more +%D consistent. +%D +%D \starttyping +%D context auto:s-inf-01 +%D context auto:s-inf-01 --basepath=t:/texmf/tex/context/base +%D \stoptyping + +% \enabletrackers[context.*] + +\startluacode + local format, gsub, find, match = string.format, string.gsub, string.find, string.match + + local list, size, comp, used, nope = { }, { }, { }, { mkii = { }, mkiv = { }, mkvi = { } }, { 0, 0, 0, 0, 0 } + + local omit = { + "char%-def%.lua", + "mult%-def%.lua", "mult%-..%.mkii", "mult%-m..%.mkii", + } + local skip = { + "prag%-.*%.tex", "docs%-.*.tex", "list%-.*%.tex", "test%-.*%.tex", "demo%-.*%.tex", + "opti%-.*%.tex", "chrt%-.*%.tex", ".*%-old", ".*%-obs", ".*%-tst", "supp%-.*%.tex", + "colo%-pan.tex", ".*test.*" + } + local types = { + "tex", "mkii", "mkiv", "mkvi", "lua" + } + local patterns = { + "^([a-z][a-z][a-z][a-z])%-[a-z0-9%-]+%.[a-z]+", + "^([xms])%-[a-z0-9%-]+%.[a-z]+", + } + + local function collect(list,suffix,n) + local path = document.arguments.basepath or file.dirname(resolvers.find_file("context.mkiv"),".") + local pattern = path .. "/*." .. suffix .. "$" -- avoid bla.tex~ + local texfiles = dir.glob(pattern) + for i=1,#texfiles do + local name = texfiles[i] + local base = file.basename(name) + for p=1,#patterns do + local category = match(base,patterns[p]) + if category and lfs.isfile(name) then + local okay = true + for s=1,#skip do + if find(base,skip[s]) then + okay = false + break + end + end + if okay then + local lm, sm, cm = list[category], size[category], comp[category] + if not lm then + lm, sm, cm = { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } + list[category], size[category], comp[category] = lm, sm, cm + end + lm[n] = lm[n] + 1 + local done = true + for o=1,#omit do + if find(base,omit[o]) then + done = false + break + end + end + local data = io.loaddata(name) + if data then + if suffix == "lua" then + data = gsub(data,"%-%-%[%[.-%]%]%-%-","") + data = gsub(data,"%-%-.-[\n\r]","") + else + data = gsub(data,"%%.-[\n\r]","") + end + data = gsub(data,"%s","") + else + logs.report("error","unknown file %a",name) + data = "" + end + sm[n+5] = sm[n+5] + #data + if done then + sm[n] = sm[n] + #data + else + cm[n] = cm[n] + 1 + end + end + end + end + end + end + + local function prepare(what) + if next(list) then + -- already loaded + else + for i=1,#types do + collect(list,types[i],i) + end + for category in next, list do + pattern ="{"..category.."%-" + for suffix, t in next, used do + local data = io.loaddata(resolvers.find_file("context."..suffix)) + if data and find(data,pattern) then + t[category] = true + end + end + end + end + local max, what = 0, (what == "size" and size) or list + for k, v in table.sortedpairs(what) do + for i=1,5 do if v[i] > max then max = v[i] end end + end + return max, what, function(n) return (max == 0 and 0) or (n == 0 and 0) or n/max end + end + + local f_norm = string.formatters["%0.3f"] + + function document.context_state_1(what) + local max, what, norm = prepare(what) + context.starttabulate { "|Tl|T|T|T|T|T|" } + context.NC() + context(category) + context.NC() + for i=1,#types do + local n, m = 0, 0 + for k, v in next, list do + local nn, mm = what[k][i], what[k][i+5] + n = n + nn + m = m + (mm or nn) + end + context.Top(types[i],norm(max),n,m) + context.NC() + end + context.NC() + context.NR() + context.HL() + for k, v in table.sortedpairs(what) do + local c = what == size and comp[k] or nope + context.NC() + context("%s~%s~~%s~~%s", + (used.mkii[k] and "ii") or "~~", + (used.mkiv[k] and "iv") or "~~", + (used.mkvi[k] and "vi") or "~~", + k + ) + -- context("%s\\enspace %s\\quad %s\\quad %s", + -- (used.mkii[k] and "ii") or "\\quad", + -- (used.mkiv[k] and "iv") or "\\quad", + -- (used.mkvi[k] and "vi") or "\\quad", + -- k + -- ) + context.NC() + for i=1,#types do + context.Bar(types[i],v[i],c[i],f_norm(norm(v[i]))) + context.NC() + end + context.NR() + end + context.stoptabulate() + end + + function document.context_state_2(what) + local max, what, norm = prepare(what) + for k, v in table.sortedpairs(what) do + local c = (what == size and comp[k]) or nope + context.StartUp(k) + for i=1,#types do + context.Up(types[i],f_norm(norm(v[i]))) + end + context.StopUp() + end + end + +\stopluacode + +\definecolor[bar:tex] [middlegreen] +\definecolor[bar:mkii][middleblue] +\definecolor[bar:mkiv][middlered] +\definecolor[bar:mkvi][middleyellow] +\definecolor[bar:lua] [middlegray] + +\newcount\UpCounter + +\starttexdefinition Top #what#fraction#total#bigones + \hbox to 5em{\hss#total}% + \enspace + \hbox {#what\ifnum#total=#bigones\else~#bigones\rlap{~+}\fi\hss}% +\stoptexdefinition + +\starttexdefinition Bar #color#size#nobigones#fraction + \ifcase#size\else + \hbox to 5em{\hss\ifcase#nobigones\else\llap{-~}\fi#size}% + \enspace + \blackrule[color=bar:#color,width=#fraction\dimexpr 20em\relax,height=.8\strutht]% + \fi +\stoptexdefinition + +\starttexdefinition StartUp #name + \def\UpName{#name}% + \dontleavehmode\framed[frame=off,align={middle,low},height=18em]\bgroup +\stoptexdefinition + +\starttexdefinition StopUp + \par\nointerlineskip\blackrule[height=1pt,width=5em,depth=0pt,color=darkgray] + \par\tttf\strut\UpName\par + \egroup + \ifnum\UpCounter=17 + \par \UpCounter\zerocount + \else + \kern1em \advance\UpCounter\plusone + \fi +\stoptexdefinition + +\starttexdefinition Up #color#width + \scratchdimen#width\dimexpr 16em\relax + \ifdim\scratchdimen=\zeropoint + \kern1em + \else + \ifdim\scratchdimen<\onepoint \scratchdimen\onepoint \fi + \blackrule[color=bar:#color,height=\scratchdimen,width=1em]% + \fi +\stoptexdefinition + +\starttexdefinition Show #title#how#what + \startTEXpage[offset=1em,width=fit] + \hbox{\tttf\strut\currentdate~-~#title} + \par + \ctxlua{document.context_state_\number#how("#what")} + \stopTEXpage +\stoptexdefinition + +% \continueifinputfile{s-inf-01.mkvi} + +\starttext + \Show + {The number of files used in ConTeXt (base modules and styles).} + {1}{number} + \Show + {The size of (core) files used in ConTeXt (- indicates exclusion of large data files; + indicates inclusion of large data files; comment and spaces removed.)} + {1}{size} + \Show + {The relative number of files used in ConTeXt (tex, mkii, mkiv, mkvi, lua).} + {2}{number} + \Show + {The relative size of files used in ConTeXt (tex, mkii, mkiv, mkvi, lua).} + {2}{size} +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-inf-02.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-02.mkiv new file mode 100644 index 00000000000..cf8d572bca2 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-02.mkiv @@ -0,0 +1,27 @@ +%D \module +%D [ file=s-inf-02, +%D version=2009.11.25, +%D title=\CONTEXT\ Style File, +%D subtitle=Information 2 (filenames), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\starttext + +\starttabulate [|T|T|] + \NC \type{\jobname} \NC \jobname \NC \NR + \NC \type{\jobfilename} \NC \jobfilename \NC \NR + \NC \type{\jobfilesuffix} \NC \jobfilesuffix \NC \NR + \NC \type{\inputfilename} \NC \inputfilename \NC \NR + \NC \type{\inputfilebarename} \NC \inputfilebarename \NC \NR + \NC \type{\inputfilesuffix} \NC \inputfilesuffix \NC \NR + \NC \type{\outputfilename} \NC \outputfilename \NC \NR + \NC \type{\operatingsystem} \NC \operatingsystem \NC \NR +\stoptabulate + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-inf-03.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-03.mkiv new file mode 100644 index 00000000000..a253bed773c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-03.mkiv @@ -0,0 +1,372 @@ +% \nopdfcompression + +% \starttext +% There is a loop somewhere ... todo. +% \stoptext + +\enablemode[tablet] % whatever that means + +\setupbodyfont[dejavu] + +\doifelsemode {tablet} { + + \setuppapersize + [S6,landscape] + [S6,landscape] + + \definefont + [TitlePageFont] + [MonoBold at 15pt] + + \setupbodyfont + [tt,8pt] + +} { + + \definefont + [TitlePageFont] + [MonoBold at 18pt] + + \setupbodyfont + [tt] + +} + +\setuplayout + [header=0cm, + footer=1cm, + backspace=.5cm, + topspace=.5cm, + width=middle, + height=middle] + +\setuphead + [title] + [style=\ttc, + interaction=reference] + +\definehead + [xtitle] + [title] + +\setuphead + [xtitle] + [color=darkgreen] + +\setupfootertexts + [\llap{\goto{\hbox to 5cm{\hss previous}}[previouspage]}% + \quad\pagenumber\quad + \rlap{\goto{\hbox to 5cm{next\hss}}[nextpage]}] + +\setupinteraction + [state=start, + style=, + color=, + title={ConTeXt MkIV}, + subtitle={Lua modules and functions}, + author={Hans Hagen - automatically generated}, + contrastcolor=] + +\setupinteractionscreen + [option=bookmark] + +\placebookmarks + [title,xtitle] + [force=yes] + +\definecolor[darkyellow][r=.5,g=.5,b=0] +\definecolor[darkgray] [s=.15] + +\nonknuthmode + +\starttext + +\startbuffer +\startluacode +local basiclua = libraries.basiclua +local basictex = libraries.basictex +local extratex = libraries.extratex +local extralua = libraries.extralua +local obsolete = libraries.obsolete + +local find = string.find +local color, gotolocation = context.color, context["goto"] + +for k, v in table.sortedpairs(_G) do + if obsolete[k] or find(k,"_") or k == "arg" or k == "utf" then + -- + elseif basiclua[k] then + gotolocation(function() color( { "darkred" }, k) end, { k } ) + elseif extralua[k] then + gotolocation(function() color( { "darkgreen" }, k) end, { k } ) + elseif basictex[k] then + gotolocation(function() color( { "darkblue" }, k) end, { k } ) + elseif extratex[k] then + gotolocation(function() color( { "darkyellow" }, k) end, { k } ) + elseif type(v) == "table" then + gotolocation(function() color( { "white" }, k) end, { k } ) + end + context(" ") +end +\stopluacode +\stopbuffer + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=darkgray, + backgroundoffset=2mm] + +\startpagemakeup + \vfill + \pagereference[global] + \startnarrower[10mm] + \setupalign[nothyhenated,middle,broad] + \TitlePageFont \setupinterlinespace + \getbuffer % luabuffer + \par + \stopnarrower + \vfill + \vfill + \hskip10mm\scale[width=\dimexpr\paperwidth-20mm\relax]{\ttbf\white\ConTeXt\ MkIV} + \par + % \hskip10mm\scale[width=\dimexpr\paperwidth-20mm\relax]{\white \strut Lua infrastructure \emdash\ \currentdate} + \vfill +\stoppagemakeup + +\setupbackgrounds + [page] + [background=] + +\startluacode +local builtin = libraries.builtin +local globals = libraries.globals +local basiclua = libraries.basiclua +local basictex = libraries.basictex +local extratex = libraries.extratex +local extralua = libraries.extralua +local obsolete = libraries.obsolete + +local sortedkeys = table.sortedkeys +local mark = storage.mark +local marked = storage.marked +local gsub = string.gsub +local sub = string.sub +local byte = string.byte +local upper = string.upper + +local skipglobal = table.tohash { + "_G", "_M", "_ENV", "", + "context", "modules", "global", "arg", "utf", 1, + "_ptbs_", "_pcol_", "_plib_", "_clib_", "_tlib_", + "kpse", "commands", +} + +local skipkeys = table.tohash { + "_pcol_", "_plib_", "_clib_", "_tlib_", "_bpnf_", "_ptbs_", + "_cldf_", "_cldn_", "_cldo_", + "_clmb_", "_clme_", "_clmm_", "_clmn_", "_clma_", "_clmh_", + "_G", "_M", "_ENV", "", + -- "global", "shortcuts", + "_VERSION", "_COPYRIGHT", "_DESCRIPTION", "_NAME", "_PACKAGE", "__unload", +} + +local sameglobal = { + ["global"] = "_G", + -- ["commands"] = "cs", -- already gone +} + +-- -- -- -- -- -- -- -- -- -- -- -- -- +-- this should be done internally +-- -- -- -- -- -- -- -- -- -- -- -- -- + +for k,v in next, modules do + mark(v) +end + +mark(document.arguments) +mark(environment.arguments) +mark(environment.engineflags) +mark(characters.data) + +-- -- -- -- -- -- -- -- -- -- -- -- -- +-- -- -- -- -- -- -- -- -- -- -- -- -- + +local variant = 1 -- all parents +local variant = 2 -- parent name too +local variant = 3 -- no parents + +local done = { } + +local function childtables(key,tab,handler,depth) + depth = depth or 1 + local keys = sortedkeys(tab) -- no sorted_pairs + for i=1,#keys do + local k = keys[i] +-- if k ~= "_G" and k ~= "_M" and type(k) == "string" then + if not skipkeys[k] and type(k) == "string" then + local v = tab[k] + local t = type(v) + local s = k + if variant ~= 3 then + s = key and (key .. "." .. s) or s + end + if t == "table" then + if marked(v) then + t = "data" + handler(s,t,depth) + else +if done[v] then + -- logs.report("inf-03","key %a in %a already done",k,v) +else + done[v] = true + handler(s,t,depth) + if variant == 3 then + childtables(false,v,handler,depth+1) + elseif variant == 2 then + childtables(k,v,handler,depth+1) + else + childtables(s,v,handler,depth+1) + end + end +end + else + handler(s,t,depth) + end + end + end +end + +local NC, NR = context.NC, context.NR +local overstrike, rlap, bf = context.overstrike, context.rlap, context.bf +local color, gotolocation = context.color, context["goto"] + +local function cleanup(s) + return "\\char" ..byte(s) .. " " +end + +local function handler(k,t,depth) + k = gsub(k,"([~#$%%^&{}\\|])",cleanup) + NC() rlap("\\quad\\tx\\kern" .. (depth or 0).. "em" .. upper(sub(t,1,1)) .. " ".. k) NC() NC() NR() +end + +local function show(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete) + -- todo: table as argument +-- print(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete) + local keys = sortedkeys(t) -- no sorted_pairs + if #keys > 0 then + local fulltitle = title + if subtitle and subtitle ~= "" then + fulltitle = fulltitle .. " (" .. subtitle .. ")" + end + if alias and alias ~= "" then + fulltitle = fulltitle .. " (alias: " .. alias .. ")" + end + if builtin then + context.startxtitle { reference = title, title = fulltitle, backreference = "global" } + else + context.starttitle { reference = title, title = fulltitle, backreference = "global" } + end + context.startcolumns { n = 2 } + context.starttabulate { "|||" } + local t_obsolete = t.obsolete + if type(t_obsolete) ~= "table" then + t_obsolete = nil + end + for i=1,#keys do + local k = keys[i] + local v = t[k] + if k and k ~= "obsolete" and not skipkeys[k] and (not obsolete or not obsolete[k]) then + local inlib = lib and lib[k] + local inglo = glo and glo[k] + local t = type(v) + local kstr, tstr = k, t + local obs = t_obsolete and t_obsolete[k] + if obs then + tstr = function() overstrike(t) end + kstr = function() overstrike(k) end + end + local marked = marked(v) + if marked then + tstr = "data table" + end + if t == "table" then + local m = getmetatable(v) + if m and m.__call then + tstr = "function" + end + end + if not mark then + -- + elseif inlib and tostring(inlib) ~= tostring(v) then + tstr = "overloaded ".. tstr + elseif inglo and tostring(inglo) ~= tostring(v) then + tstr = "overloaded ".. tstr + end + NC() bf() + if inlib then + if not mark and t == "table" then + gotolocation(function() color( { libcolor }, kstr) end, { k } ) + else + color( { libcolor }, kstr) + end + elseif inglo then + if not mark and t == "table" then + gotolocation(function() color( { glocolor }, kstr) end, { k } ) + else + color( { glocolor }, kstr) + end + else + if not mark and t == "table" then + gotolocation(k, { kstr } ) + else + context(kstr) + end + end + NC() + if inlib then + color( { libcolor }, tstr) + elseif inglo then + color( { glocolor }, tstr) + else + context(tstr) + end + NC() NR() + if mark and t == "table" and title ~= "libraries" and title ~= "package" and not marked then + childtables(false,v,handler) -- (k,v,handler) + end + end + end + context.stoptabulate() + context.stopcolumns() + if builtin then + context.stopxtitle() + else + context.stoptitle() + end + end +end + +show("global","",sameglobal.global,false,_G,builtin,"darkgreen",globals,"darkblue",false,obsolete) + +-- inspect(table.sortedkeys(context)) + +for k, v in table.sortedpairs(_G) do + if not skipglobal[k] and not obsolete[k] and type(v) == "table" and not marked(v) then + + -- local mt = getmetatable(v) + -- print("!!!!!!!!!!",k,v,mt,mt and mt.__index) + + if basiclua[k] then show(k,"basic lua",sameglobal[k],basiclua[k],v,builtin[k],"darkred", false,false,true) + elseif extralua[k] then show(k,"extra lua",sameglobal[k],extralua[k],v,builtin[k],"darkred", false,false,true) + elseif basictex[k] then show(k,"basic tex",sameglobal[k],basictex[k],v,builtin[k],"darkred", false,false,true) + elseif extratex[k] then show(k,"extra tex",sameglobal[k],extratex[k],v,builtin[k],"darkred", false,false,true) + else + show(k,"context", sameglobal[k],false, v,builtin[k],"darkyellow",false,false,true) + end + end +end + +\stopluacode + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-inf-04.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-04.mkiv new file mode 100644 index 00000000000..862bed72f29 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-inf-04.mkiv @@ -0,0 +1,48 @@ +\usemodule[art-01] + +\setupbodyfont[10pt] + +\starttext + + \startluacode + + context.subject("Configuration files") + + local configurations = resolvers.instance.specification + + context.starttabulate { "|Tl|Tl|" } + for i=1,#configurations do + context.NC() + context(i) + context.NC() + context.verbatim(resolvers.resolve(configurations[i])) + context.NC() + context.NR() + end + context.stoptabulate() + + local list = resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec)) + + context.subject("Configuration paths") + + -- context.verbatim(resolvers.luacnfspec) + + context.starttabulate { "|Tl|Tl|" } + for i=1,#list do + local li = resolvers.resolve(list[i]) + context.NC() + if lfs.isdir(li) then + context("-") + else + context("+") + end + context.NC() + context.verbatim(li) + context.NC() + context.NR() + end + context.stoptabulate() + + \stopluacode + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-counters.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-counters.lua new file mode 100644 index 00000000000..45d68be8dfd --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-counters.lua @@ -0,0 +1,52 @@ +if not modules then modules = { } end modules ['s-languages-counters'] = { + version = 1.001, + comment = "companion to s-languages-counters.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.languages = moduledata.languages or { } +moduledata.languages.counters = moduledata.languages.counters or { } + +local data = converters.verbose.data + +function moduledata.languages.counters.showverbose(specification) + specification = interfaces.checkedspecification(specification) + local list = utilities.parsers.settings_to_array(specification.language or "") + if #list == 0 then + return + end + local used = { } + local words = { } + for i=1,#list do + local ai = list[i] + local di = data[ai] + if di and di.words then + used[#used+1] = ai + table.merge(words,di.words) + end + end + context.starttabulate { string.rep("|l",#used) .. "|r|" } + context.HL() + context.NC() + for i=1,#used do + context.bold(used[i]) + context.NC() + end + context.bold("number") + context.NC() + context.NR() + context.HL() + for k, v in table.sortedhash(words) do + context.NC() + for i=1,#used do + context(data[used[i]].words[k] or "") + context.NC() + end + context(k) + context.NC() + context.NR() + end + context.stoptabulate() +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-counters.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-counters.mkiv new file mode 100644 index 00000000000..fa938d65a87 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-counters.mkiv @@ -0,0 +1,30 @@ +%D \module +%D [ file=s-languages-counters, % s-lan-05, +%D version=2011.05.01, % older +%D title=\CONTEXT\ Style File, +%D subtitle=Language Counters, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[languages-counters] + +\registerctxluafile{s-languages-counters}{} + +\installmodulecommandluasingle \showverbosecounters {moduledata.languages.counters.showverbose} + +\stopmodule + +\continueifinputfile{s-languages-counters.mkiv} + +\usemodule[art-01] + +\starttext + + \showverbosecounters[language={en,es}] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-frequencies.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-frequencies.lua new file mode 100644 index 00000000000..16213a41271 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-frequencies.lua @@ -0,0 +1,33 @@ +if not modules then modules = { } end modules ['s-languages-frequencies'] = { + version = 1.001, + comment = "companion to s-languages-frequencies.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.languages = moduledata.languages or { } +moduledata.languages.frequencies = moduledata.languages.frequencies or { } + +function moduledata.languages.frequencies.showlist(specification) + specification = interfaces.checkedspecification(specification) + local t = languages.frequencies.getdata(specification.language or languages.current()) + context.starttabulate { "|lT|cw(2em)|r|" } + context.NC() + context.formatted.rlap("%s: %p",t.language,languages.frequencies.averagecharwidth(t.language)) + context.NC() + context.NC() + context.NR() + context.HL() + for k, v in table.sortedhash(t.frequencies) do + context.NC() + context("%U",k) + context.NC() + context("%c",k) + context.NC() + context("%0.3f",v) + context.NC() + context.NR() + end + context.stoptabulate() +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-frequencies.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-frequencies.mkiv new file mode 100644 index 00000000000..01a1f5682e2 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-frequencies.mkiv @@ -0,0 +1,38 @@ +%D \module +%D [ file=s-languages-frequencies, % s-lan-06, +%D version=2013.03.22, +%D title=\CONTEXT\ Style File, +%D subtitle=Language Frequencies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[languages-frequencies] + +\registerctxluafile{s-languages-frequencies}{} + +\installmodulecommandluasingle \showfrequencies {moduledata.languages.frequencies.showlist} + +\stopmodule + +\continueifinputfile{s-languages-frequencies.mkiv} + +\usemodule[art-01] + +\starttext + + \hsize65\averagecharwidth \the\hsize: \input ward \par + + \showfrequencies \page + + \mainlanguage[de] + + \hsize65\averagecharwidth \the\hsize: \input ward \par + + \showfrequencies \page + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-hyphenation.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-hyphenation.lua new file mode 100644 index 00000000000..c5a4f91f1e9 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-hyphenation.lua @@ -0,0 +1,135 @@ +if not modules then modules = { } end modules ['s-languages-hyphenation'] = { + version = 1.001, + comment = "companion to s-languages-hyphenation.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.languages = moduledata.languages or { } +moduledata.languages.hyphenation = moduledata.languages.hyphenation or { } + +local a_colormodel = attributes.private('colormodel') + +local nodecodes = nodes.nodecodes +local nodepool = nodes.pool +local disc_code = nodecodes.disc +local glyph_code = nodecodes.glyph +local emwidths = fonts.hashes.emwidths +local exheights = fonts.hashes.exheights +local newkern = nodepool.kern +local newrule = nodepool.rule +local newglue = nodepool.glue + +local insert_node_after = node.insert_after +local traverse_by_id = node.traverse_id +local hyphenate = languages.hyphenators.handler -- lang.hyphenate +local find_tail = node.tail +local remove_node = nodes.remove + +local tracers = nodes.tracers +local colortracers = tracers and tracers.colors +local setnodecolor = colortracers.set + +local function identify(head,marked) + local current, prev = head, nil + while current do + local id = current.id + local next = current.next + if id == disc_code then + if prev and next then -- and next.id == glyph_code then -- catch other usage of disc + marked[#marked+1] = prev + end + elseif id == glyph_code then + prev = current + end + current = next + end +end + +local function strip(head,marked) + for i=1,#marked do + local prev = marked[i] + remove_node(head,prev.next,true) + end +end + +local function mark(head,marked,w,h,d,how) + for i=1,#marked do + local prev = marked[i] + local font = prev.font + local em = emwidths[font] + local ex = exheights[font] + local width = w*em + local rule = newrule(width,h*ex,d*ex) + head, prev = insert_node_after(head,prev,newkern(-width/2)) + head, prev = insert_node_after(head,prev,rule) + head, prev = insert_node_after(head,prev,newkern(-width/2)) + head, prev = insert_node_after(head,prev,newglue(0)) + setnodecolor(rule,how,prev[a_colormodel]) + end +end + +local langs, tags, noflanguages = { }, { }, 0 + +local colorbytag = false + +function moduledata.languages.hyphenation.showhyphens(head) + if noflanguages > 0 then + local marked = { } + for i=1,noflanguages do + local m = { } + local l = langs[i] + marked[i] = m + for n in traverse_by_id(glyph_code,head) do + n.lang = l + end + languages.hyphenators.methods.original(head) + identify(head,m) + strip(head,m) + end + for i=noflanguages,1,-1 do + local l = noflanguages - i + 1 + mark(head,marked[i],1/16,l/2,l/4,"hyphenation:"..(colorbytag and tags[i] or i)) + end + return head, true + else + return head, false + end +end + +local savedlanguage + +function moduledata.languages.hyphenation.startcomparepatterns(list) + if list and list ~= "" then + tags = utilities.parsers.settings_to_array(list) + end + savedlanguage = tex.language + tex.language = 0 + noflanguages = #tags + for i=1,noflanguages do + langs[i] = tags[i] and languages.getnumber(tags[i]) + end + nodes.tasks.enableaction("processors","moduledata.languages.hyphenation.showhyphens") +end + +function moduledata.languages.hyphenation.stopcomparepatterns() + noflanguages = 0 + tex.language = savedlanguage or tex.language + nodes.tasks.disableaction("processors","moduledata.languages.hyphenation.showhyphens") +end + +function moduledata.languages.hyphenation.showcomparelegend(list) + if list and list ~= "" then + tags = utilities.parsers.settings_to_array(list) + end + for i=1,#tags do + if i > 1 then + context.enspace() + end + context.color( { "hyphenation:"..(colorbytag and tags[i] or i) }, tags[i]) + end +end + +nodes.tasks.appendaction("processors","before","moduledata.languages.hyphenation.showhyphens") +nodes.tasks.disableaction("processors","moduledata.languages.hyphenation.showhyphens") diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-hyphenation.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-hyphenation.mkiv new file mode 100644 index 00000000000..6662dbf2f32 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-hyphenation.mkiv @@ -0,0 +1,77 @@ +%D \module +%D [ file=s-languages-hyphenation, % s-lan-04, +%D version=2011.05.01, +%D title=\CONTEXT\ Style File, +%D subtitle=Language Hyphenation, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D For Mojca. + +\startmodule[languages-hyphenation] + +\registerctxluafile{s-languages-hyphenation}{} + +\unprotect + +\unexpanded\def\startcomparepatterns + {\dosingleempty\module_languages_hyphenation_start} + +\unexpanded\def\module_languages_hyphenation_start[#1]% + {\begingroup + \par + % \language\zerocount + % \setupalign[\v!nothyphenated]% + \ctxlua{moduledata.languages.hyphenation.startcomparepatterns("#1")}} + +\unexpanded\def\stopcomparepatterns + {\par + \ctxlua{moduledata.languages.hyphenation.stopcomparepatterns()}% + \endgroup} + +\installmodulecommandluasingle \showcomparepatternslegend {moduledata.languages.hyphenation.showcomparelegend} + +\protect + +\definecolor[hyphenation:1] [r=.8] +\definecolor[hyphenation:2] [g=.8] +\definecolor[hyphenation:3] [b=.8] +\definecolor[hyphenation:4] [r=.4,g=.4] + +\definecolor[hyphenation:en] [hyphenation:1] +\definecolor[hyphenation:de] [hyphenation:2] +\definecolor[hyphenation:nl] [hyphenation:3] +\definecolor[hyphenation:fr] [hyphenation:4] + +\stopmodule + +\continueifinputfile{s-languages-hyphenation.mkiv} + +\usemodule[art-01] + +\starttext + +\def|#1|{-} + + \startsubject{Normal text} + \input tufte + \stopsubject + + \startsubject{Compare hyphenation points of \showcomparepatternslegend[en,de]} + \startcomparepatterns + \input tufte \quad (\showcomparepatternslegend) + \stopcomparepatterns + \stopsubject + + \startsubject{Compare hyphenation points} + \startcomparepatterns[de,nl,en,fr] + \input tufte \quad (\showcomparepatternslegend) + \stopcomparepatterns + \stopsubject + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-sorting.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-sorting.lua new file mode 100644 index 00000000000..82a0827bbd2 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-sorting.lua @@ -0,0 +1,118 @@ +if not modules then modules = { } end modules ['s-languages-system'] = { + version = 1.001, + comment = "companion to s-languages-system.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.languages = moduledata.languages or { } +moduledata.languages.sorting = moduledata.languages.sorting or { } + +local formatters = string.formatters +local utfbyte, utfcharacters = utf.byte, utf.characters +local sortedpairs = table.sortedpairs + +local definitions = sorters.definitions +local constants = sorters.constants +local replacementoffset = constants.replacementoffset + +local currentfont = font.current +local fontchars = fonts.hashes.characters + +local c_darkblue = { "darkblue" } +local c_darkred = { "darkred" } +local f_chr = formatters["\\tttf%H"] + +local function chr(str,done) + if done then + context.space() + end + local c = fontchars[currentfont()] + for s in utfcharacters(str) do + local u = utfbyte(s) + if c[u] then + context(s) + elseif u > replacementoffset then + context.color(c_darkblue, f_chr(u)) + else + context.color(c_darkred, f_chr(u)) + end + end + return true +end + +local function map(a,b,done) + if done then + context.space() + end + -- context.tttf() + chr(a) + context("=") + chr(b) + return true +end + +local function nop() + -- context.tttf() + context("none") +end + +local function key(data,field) + context.NC() + context(field) + context.NC() + context(data[field]) + context.NC() + context.NR() +end + +function moduledata.languages.sorting.showinstalled(tag) + if not tag or tag == "" or tag == interfaces.variables.all then + for tag, data in sortedpairs(definitions) do + moduledata.languages.sorting.showinstalled (tag) + end + else + sorters.update() -- syncs data + local data = definitions[tag] + if data then + context.starttabulate { "|lB|pl|" } + key(data,"language") + key(data,"parent") + key(data,"method") + context.NC() + context("replacements") + context.NC() + local replacements = data.replacements + if #replacements == 0 then + nop() + else + for i=1,#replacements do + local r = replacements[i] + map(r[1],r[2],i > 1) + end + end + context.NC() + context.NR() + context.NC() + context("order") + context.NC() + local orders = data.orders + for i=1,#orders do + chr(orders[i],i > 1) + end + context.NC() + context.NR() + context.NC() + context("entries") + context.NC() + local done = false + for k, e in sortedpairs(data.entries) do + done = map(k,e,done) + end + context.NC() + context.NR() + context.stoptabulate() + end + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-sorting.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-sorting.mkiv new file mode 100644 index 00000000000..67acda6f972 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-sorting.mkiv @@ -0,0 +1,30 @@ +%D \module +%D [ file=s-languages-sorting, % s-lan-02.mkiv +%D version=2010.09.21, +%D title=\CONTEXT\ Style File, +%D subtitle=Language Sorting, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[languages-sorting] + +\registerctxluafile{s-languages-sorting}{} + +\installmodulecommandluasingle \showinstalledsorting {moduledata.languages.sorting.showinstalled} + +\stopmodule + +\continueifinputfile{s-languages-sorting.mkiv} + +\usemodule[art-01] + +\starttext + + \showinstalledsorting + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-system.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-system.lua new file mode 100644 index 00000000000..3b422db9f2e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-system.lua @@ -0,0 +1,62 @@ +if not modules then modules = { } end modules ['s-languages-system'] = { + version = 1.001, + comment = "companion to s-languages-system.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.languages = moduledata.languages or { } +moduledata.languages.system = moduledata.languages.system or { } + +local NC, NR, HL = context.NC, context.NR, context.HL +local sortedhash = table.sortedhash +local registered = languages.registered +local context = context +local ctx_NC = context.NC +local ctx_NR = context.NR +local ctx_bold = context.bold + +function moduledata.languages.system.loadinstalled() + context.start() + for k, v in table.sortedhash(registered) do + context.language{ k } + end + context.stop() +end + +function moduledata.languages.system.showinstalled() + -- + context.starttabulate { "|l|r|l|l|p(7em)|r|p|" } + context.FL() + ctx_NC() ctx_bold("tag") + ctx_NC() ctx_bold("n") + ctx_NC() ctx_bold("parent") + ctx_NC() ctx_bold("file") + ctx_NC() ctx_bold("synonyms") + ctx_NC() ctx_bold("patterns") + ctx_NC() ctx_bold("characters") + ctx_NC() ctx_NR() + context.FL() + for k, v in sortedhash(registered) do + local parent = v.parent + local resources = v.resources + local patterns = resources and resources.patterns + ctx_NC() context(k) + ctx_NC() context(v.number) + ctx_NC() context(v.parent) + ctx_NC() context(v.patterns) + ctx_NC() for k, v in sortedhash(v.synonyms) do context("%s\\par",k) end + if patterns then + ctx_NC() context(patterns.n) + ctx_NC() context("% t",utf.split(patterns.characters)) + else + ctx_NC() + ctx_NC() + end + ctx_NC() ctx_NR() + end + context.LL() + context.stoptabulate() + -- +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-system.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-system.mkiv new file mode 100644 index 00000000000..22991f264f8 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-system.mkiv @@ -0,0 +1,32 @@ +%D \module +%D [ file=s-languages-system, % moved from local s-lan-01 +%D version=2013.05.19, +%D title=\CONTEXT\ Style File, +%D subtitle=Installed Languages, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[languages-system] + +\registerctxluafile{s-languages-system}{} + +\installmodulecommandluasingle \showinstalledlanguages {moduledata.languages.system.showinstalled} +\installmodulecommandluasingle \loadinstalledlanguages {moduledata.languages.system.loadinstalled} + +\stopmodule + +\continueifinputfile{s-languages-system.mkiv} + +\usemodule[art-01] + +\starttext + + \loadinstalledlanguages + \showinstalledlanguages + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-words.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-words.lua new file mode 100644 index 00000000000..ea7aee87bcd --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-words.lua @@ -0,0 +1,32 @@ +if not modules then modules = { } end modules ['s-languages-words'] = { + version = 1.001, + comment = "companion to s-languages-words.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.languages = moduledata.languages or { } +moduledata.languages.words = moduledata.languages.words or { } + +function moduledata.languages.words.showwords(specification) + local filename = specification.filename or file.addsuffix(tex.jobname,"words") + if lfs.isfile(filename) then + local w = dofile(filename) + if w then + -- table.print(w) + for cname, category in table.sortedpairs(w.categories) do + for lname, language in table.sortedpairs(category.languages) do + context.bold(string.format("category: %s, language: %s, total: %s, unique: %s:", + cname, lname, language.total or 0, language.unique or 0) + ) + for word, n in table.sortedpairs(language.list) do + context(" %s (%s)",word,n) + end + context.par() + end + end + end + end +end + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-languages-words.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-words.mkiv new file mode 100644 index 00000000000..4e350bf34d2 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-languages-words.mkiv @@ -0,0 +1,22 @@ +%D \module +%D [ file=s-languages-words, +%D version=2010.10.21, +%D title=\CONTEXT\ Style File, +%D subtitle=Language Environment 3, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is used in the test suite. + +\startmodule[languages-words] + +\registerctxluafile{s-languages-words}{} + +\installmodulecommandluasingle \showwords {moduledata.languages.words.showwords} + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-lingual-de.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-lingual-de.mkiv new file mode 100644 index 00000000000..d5436e1e2f0 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-lingual-de.mkiv @@ -0,0 +1,49 @@ +%D \module +%D [ file=s-lingual-de, +%D version=2016.04.17, +%D title=\CONTEXT\ Linguistic File, +%D subtitle=German TWeaks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startluacode + fonts.handlers.otf.addfeature { + name = "sz", + type = "multiple", + data = { + ["ẞ"] = { "S", "S" } + } + } +\stopluacode + +\definefontfeature[sz][sz=yes] + +\unexpanded\def\enableuppercasesharps {\overloaduppercase{0xDF}{0x1E9E}} +\unexpanded\def\disableuppercasesharps{\overloaduppercase{0xDF}{0x53,0x53}} + +\installtexdirective + {fonts.uppercasesharps} + \enableuppercasesharps + \disableuppercasesharps + +\continueifinputfile{s-lingual-de.mkiv} + +\setupbodyfont[libertine] + +\starttext + \def\TestString{Buße Busse BUẞE BUSSE \WORD{Buße Busse}} + %\definefontfeature[default][default][sz=yes] + \dorecurse{5} { + \disableuppercasesharps + \TestString\par + \enableuppercasesharps + \TestString\par + {\addfeature{sz}\TestString}\par + } +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-map-10.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-map-10.mkiv new file mode 100644 index 00000000000..c7541babc81 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-map-10.mkiv @@ -0,0 +1,494 @@ +%D \module +%D [file=s-map-10.mkiv, +%D version=2012.06.06, +%D title=\CONTEXT\ Style File, +%D subtitle=\MAPS\ journal style, +%D author={Hans Hagen, Taco Hoekwater and Siep Kroonenberg}, +%D date=\currentdate, +%D copyright=NTG/MAPS] + +% This module implements the MAPS style for use with the Context +% macro package. The original MAPS layout was designed and +% implemented in LaTeX by Taco Hoekwater and Siep Kroonenberg. + +% - three layouts: +% 1. two columns +% 2. one column, with wide outer margins (option onecolumn) +% 3. one column, with wide left margin (option asym) +% - font sizes deviate from TeX's usual geometric progression +% - use of sans-serif for headers and various details +% - option realfonts uses Linux Libertine, Euler Math and Inconsolata. +% This is used for final typesetting. +% The default font setup, intended for authors, uses Computer +% Modern Math instead of Euler Math (which is still in beta), +% and LM Mono instead of Inconsolata. + +% A mode nosubsub defines only two levels of sectioning. If you +% don't need more and use the two-column layout, then this option +% will probably improve the looks of your paper. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newif\ifMapsInColumns +\doifmode{asym}{\enablemode[onecolumn]} % implies onecolumn +\doifnotmode{onecolumn}{\MapsInColumnstrue} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% fonts + +%%%%%%%%% first, font sizes +\definebodyfontenvironment [7pt][% LaTeX: scriptsize + interlinespace=8pt, + big=8pt, + small=6pt% +] + +\definebodyfontenvironment [8pt][% LaTeX: footnotesize + interlinespace=9pt, + big=9pt, + small=7pt, + x=6pt% +] + +\definebodyfontenvironment [9pt][% LaTeX: small + interlinespace=10pt, + big=10pt, + small=8pt,% + x=7pt,% + script=6pt% +] + +\definebodyfontenvironment [10pt][% LaTeX: normalsize + interlinespace=11pt, + big=11pt, + a=11pt, + small=9pt,% + x=8pt,% + script=7pt% +] + +\definebodyfontenvironment [11pt][% LaTeX: large + interlinespace=11pt, + big=11pt, + small=10pt,% + x=9pt,% + script=8pt% +] + +\definebodyfontenvironment [14pt][% + interlinespace=14pt, + big=18pt, + small=11pt, + x=10pt% +] + +\definebodyfontenvironment [18pt][% + interlinespace=18pt, + big=24pt, + small=14pt, + x=10pt% +] + +\definebodyfontenvironment [24pt][% + interlinespace=24pt, + big=24pt, + small=18pt, + x=11pt% +] + +%%% font families + +\starttypescript [maps] +\definetypeface [maps] [rm] [serif] [modern] [default] [rscale=0.95] +\definetypeface [maps] [mm] [math] [modern] [latin-modern] +\definetypeface [maps] [tt] [mono] [modern] [default] [rscale=0.90] +\definetypeface [maps] [ss] [sans] [modern] [default] [rscale=0.95] +\stoptypescript + +\startmode[realfonts] +\usetypescriptfile[type-libertine] + +\usetypescriptfile[type-inconsolata] + +\starttypescript [maps] +\definetypeface [maps] [rm] [serif] [libertine] [default] +\definetypeface [maps] [mm] [math] [euler] [default] [rscale=0.9] +\definetypeface [maps] [tt] [mono] [inconsolata] [default] [rscale=0.92] +\definetypeface [maps] [ss] [sans] [modern] [default] [rscale=0.95] +\stoptypescript +\stopmode + +\setupbodyfont[maps,10pt,rm] + +% activate protruding +\setupinterlinespace[line=11pt] + +\setupfontsynonym[handling=pure] + +\setupalign[hanging] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% additional general typographic details + +\setupindenting [yes,next,11pt] % indenting after enumerations etc. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% 3 versions of layout with matching headers + +\definepapersize + [maps] + [width=21cm,height=26.5cm] + +\setuppapersize + [maps][maps] + +\setuplayout[ + [topspace=40pt, + height=688pt, + header=33pt, + margin=106pt, + leftmargindistance=11pt, + rightmargindistance=11pt] + +\setupblank[5.5pt] + +\setuppagenumbering [location=] + +\definetyping [widetyping] + +\setupheader [style=\ss] +\setupfooter [style=\ss] + +\def\AuHead{\MapsRunningAuthor} +\def\TiHead{\ifnum\pageno=\MapsPage \relax \MapsRunningAuthor \else \MapsRunningTitle\fi} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% sectioning + +\setupheads[sectionnumber=no, align=right] + +\def\hfonti{\ssbfa} +\def\hfontii{\ssbf} +\def\hfontiii{\rm\it} + +\doifelsemode{nosubsub}{% +\setuphead [section][% + style=\hfontii, + before={\blank[line]}, + after={}% +] +\setuphead [subsection][% + style=\hfontiii, + alternative=text, + distance=6pt, + before={\blank[halfline]}% +]}{% +\setuphead [section][% + style=\hfonti, + before={\blank[line]}, + after={\blank[halfline]}% +] +\setuphead [subsection][% + style=\hfontii, + before={\blank[halfline]}, + after={}% +] +\setuphead [subsubsection][% + style=\hfontiii, + distance=6pt, + alternative=text, + before={\blank[halfline]}% +]} + +\doifelsemode{nosubsub}{% +\setuphead [subject][% + style=\hfontii, + before={\blank[halfline]}, + after={}% +] +\setuphead [subsubject][% + style=\hfontiii, + alternative=text, + before={\blank[halfline]}% +]}{% +\setuphead [subject][% + style=\hfonti, + before={\blank}, + after={\blank[halfline]}% +] +\setuphead [subsubject][% + style=\hfontii, + before={\blank[halfline]}, + after={}% +] +\setuphead [subsubsubject][% + style=\hfontiii, + alternative=text, + before={\blank[halfline]}% +]} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% floats + +\setupfloats [location=center, before={\ss}] +\setupcaptions [headstyle={\ssbf},style={\ssx}, + suffix=.,distance=6pt, + inbetween={\blank[halfline]}] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% various document elements + +\definesymbol [1][\getnamedglyphdirect{file:stmary10}{boxempty}] + +\setupitemize[1][packed] + +\setupitemize [each][% + indentnext=no, + align=right, + width=1em, + distance=0pt% +] + +% an outer form of itemize that does not indent +% the paragraph. + +\definecomplexorsimpleempty\startouteritemize +\def\complexstartouteritemize[#1]{\begingroup + \startitemize[width=1sp,#1] + \let\doitem\item + \def\item{\doitem[]\hbox{}\kern12pt\rightskip=0pt}% +} + +\def\stopouteritemize{\stopitemize\endgroup} + + +\setupenumerations [indentnext=no] + +\setupdescriptions [indentnext=no] + +\unexpanded\def\smalltyping{% + \switchtobodyfont[tt]% + \parindent=0pt +} + +% typing: +% - prettyverbatim is NOT the default +% - smaller size + +\unexpanded\def + \XeTeX{X\lower.5ex\hbox{\kern-.1em\mirror{E}}\kern-.1667em\TeX} + +\setuptyping [% + style={\smalltyping}, + option=none, + indentnext=no% +] + +\def\footnum#1{#1.} + +\setupnotation + [footnote] + [alternative=serried, + before=, + after=, + location=none, + width=\textwidth, + before={\blank}, + numbercommand=, + command=\footnum, + distance=0.5em] + +\setuptabulate + [before=\blank, + inner=\ss, + after=\blank] + +\def\startIntroEntry#1% + {\startlinecorrection + \bgroup + \setupalign[right] + \setuptolerance[verytolerant] + \setupindenting[no] + \noindent + \switchtobodyfont[9pt]% + \setuplocalinterlinespace[line=10pt]% + %\hyphenpenalty10000 + \parfillskip 0pt plus 1fill + \rightskip6pt plus 1fill + \ss + \bgroup\bf #1\par\egroup + \ignorespaces } + +\def\stopIntroEntry + {\par\egroup \stoplinecorrection + \blank[line] } + +\def\defineIntroEntry[#1][#2][#3]% + {\setvalue{start#1}{\startIntroEntry{#2}}% + \setvalue {stop#1}{\stopIntroEntry#3}} + +\defineIntroEntry[Keywords][Keywords][] +\defineIntroEntry[Abstract][Abstract][] + +% article parameters (other fields and defaults) +\def\MapsBibData[#1]% + {\getparameters [Maps] + [SubTitle=, + RunningAuthor=, + RunningTitle=, + Email=, + Address=, + Page=1, + Title=, + Author=, + Period=, + Number=, + Year=, + #1]% + \doifnothing{\MapsPeriod}{% + \ifnum \normalmonth<6 \gdef\MapsPeriod{VOORJAAR}\else \gdef\MapsPeriod{NAJAAR}\fi} + \doifelseinstring{oorjaar}{\MapsPeriod}{\gdef\MapsPeriod{VOORJAAR}}{}% + \doifelseinstring{pring}{\MapsPeriod}{\gdef\MapsPeriod{VOORJAAR}}{}% + \doifelseinstring{ajaar}{\MapsPeriod}{\gdef\MapsPeriod{NAJAAR}}{}% + \doifelseinstring{utumn}{\MapsPeriod}{\gdef\MapsPeriod{NAJAAR}}{}% + \doifnothing{\MapsYear}{\gdef\MapsYear{\the\year}}% + \doifnothing{\MapsNumber}{% + \ifnum \normalmonth<6 + \xdef\MapsNumber{\the\numexpr (\the\year-1990)*2\relax}% + \else + \xdef\MapsNumber{\the\numexpr (\the\year-1990)*2+1\relax}% + \fi }% + \doifnothing\MapsRunningAuthor + {\global\let\MapsRunningAuthor\MapsAuthor}% + \doifnothing\MapsRunningTitle + {\global\let\MapsRunningTitle\MapsTitle}}% + +\def\dostartArticle[#1]{% + \MapsBibData[#1] + \pageno=\MapsPage + \setupuserpagenumber[start=\MapsPage] + \startbaselinecorrection + \bgroup + \hsize = 457pt + \let\\\crlf + \blank[35pt,force] + \switchtobodyfont[24pt] + \setupalign[right] + {\noindent\bf\MapsTitle\par} + \ifx\MapsSubTitle\empty + \blank[30pt] + \else + \bgroup + \blank[12pt] + \switchtobodyfont[18pt]\noindent \it + \advance \rightskip 0pt plus 2em + \MapsSubTitle\par + \egroup + \blank[30pt] + \fi + \egroup + \setupalign[width] + \switchtobodyfont[rm,10pt] + \stopbaselinecorrection + \ifMapsInColumns + \startcolumns\hyphenpenalty1000 + \else + \clubpenalty10000 + \widowpenalty10000 + \fi +} + +\def\startArticle{\dosingleempty\dostartArticle} + +\def\signArticle{% + \blank\let\\\crlf + \noindent\switchtobodyfont[ss,9pt]% + \MapsAuthor + \doifsomething{\MapsAddress}{\\\MapsAddress}% + \doifsomething{\MapsEmail}{\\\MapsEmail}% + \switchtobodyfont[10pt]% + \def\signArticle{}% +} + +\def\stopArticle{% + \par\signArticle + \ifMapsInColumns \stopcolumns \fi + \page +} + +\installpagebreakmethod{last}{} + +%%% `logos' %%%%%%%%%%%%%%%%%%%%%%%%%% + +\unexpanded\def\LaTeX % requested by erik frambach + {{\setbox\scratchbox\hbox{L}% + \scratchdimen\ht\scratchbox + \setbox\scratchbox\hbox{\switchtobodyfont[script]A}% + L\kern-.55\wd\scratchbox + \raise\scratchdimen\hbox{\lower\ht\scratchbox\copy\scratchbox}% + \kern-.2\wd\scratchbox\TeX}} + + +\def\CONTEXT{Con{\TeX}t} +\def\ConTeXt{Con{\TeX}t} +\def\METAFONT{Metafont} +\def\METAPOST{MetaPost} +\def\POSTSCRIPT{PostScript} + +\def\acro#1{{\switchtobodyfont[9pt]#1}} + + +%%%%%%%%%%% + +\doifelsemode{onecolumn}{% + \setuplayout[width=340pt] + \doifelsemode{asym}{% one col, asymmetric + \setuplayout[backspace=187.3pt]% + \setuptyping [widetyping][oddmargin=-117pt] + \setuppagenumbering [alternative={singlesided,doublesided}] + \setupheadertexts + [{\hbox{}\hskip-117pt\TiHead}] + [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-30pt\hbox{}}] + [{\hbox{}\hskip-147pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}] + [\AuHead] + \setupfootertexts + }{% one col, symmetric + \setuplayout[backspace=70.3pt] + \setuppagenumbering [alternative=doublesided] + \setuptyping[blank=halfline] + \setupheadertexts + [\TiHead] + [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-147pt\hbox{}}] + [{\hbox{}\hskip-147pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}] + [\AuHead] + \setupfootertexts +}}{% two col + \setuplayout[width=457pt] + \setupcolumns[n=2,tolerance=verytolerant,distance=11pt] + \setuplayout[backspace=70.3pt,grid=yes] + \setuppagenumbering [alternative=doublesided] + \setuptyping[blank=halfline] + \setupheadertexts + [\TiHead] + [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-30pt\hbox{}}] + [{\hbox{}\hskip-30pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}] + [\AuHead] + \setupfootertexts +} + +\def\fulltextwidth{457pt} + +\def\startdescription + {\blank + \bgroup + \def\sym##1{\par\noindent\hbox{\bf\kern -16pt ##1}\hskip 12pt} + \startnarrower[left] + } +\def\stopdescription + {\par \stopnarrower \egroup \blank \noindentation } + +\frenchspacing +\setuptolerance[tolerant] + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-characters.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-math-characters.lua new file mode 100644 index 00000000000..8ff3a8660df --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-characters.lua @@ -0,0 +1,242 @@ +if not modules then modules = { } end modules['s-math-characters'] = { + version = 1.001, + comment = "companion to s-math-characters.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is one of the oldest cld files but I'm not going to clean it up. + +moduledata.math = moduledata.math or { } +moduledata.math.characters = moduledata.math.characters or { } + +local concat = table.concat +local lower = string.lower +local utfchar = utf.char +local round = math.round + +local fontdata = fonts.hashes.identifiers +local chardata = characters.data +local blocks = characters.blocks + +local no_description = "no description, private to font" + +local limited = true +local fillinthegaps = true +local upperlimit = 0x0007F +local upperlimit = 0xF0000 + +local f_unicode = string.formatters["%U"] +local f_slot = string.formatters["%s/%0X"] + +function moduledata.math.characters.showlist(specification) + specification = interfaces.checkedspecification(specification) + local id = specification.number -- or specification.id + local list = specification.list + local showvirtual = specification.virtual == "all" + local check = specification.check == "yes" + if not id then + id = font.current() + end + if list == "" then + list = nil + end + local tfmdata = fontdata[id] + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local resources = tfmdata.resources + local lookuptypes = resources.lookuptypes + local virtual = tfmdata.properties.virtualized + local names = { } + local gaps = mathematics.gaps + local sorted = { } + if type(list) == "string" then + sorted = utilities.parsers.settings_to_array(list) + elseif type(list) == "table" then + sorted = list + elseif fillinthegaps then + sorted = table.keys(characters) + for k, v in next, gaps do + if characters[v] then + sorted[#sorted+1] = k + end + end + table.sort(sorted) + else + sorted = table.sortedkeys(characters) + end + if virtual then + for k, v in ipairs(tfmdata.fonts) do + local id = v.id + local name = fontdata[id].properties.name + names[k] = (name and file.basename(name)) or id + end + end + if check then + for k, v in table.sortedhash(blocks) do + if v.math then + local first = v.first + local last = v.last + local f, l = 0, 0 + if first and last then + for unicode=first,last do + local code = gaps[unicode] or unicode + local char = characters[code] + if char and not (char.commands and not showvirtual) then + f = unicode + break + end + end + for unicode=last,first,-1 do + local code = gaps[unicode] or unicode + local char = characters[code] + if char and not (char.commands and not showvirtual) then + l = unicode + break + end + end + context.showmathcharacterssetrange(k,f,l) + end + end + end + else + context.showmathcharactersstart() + for _, unicode in next, sorted do + if not limited or unicode < upperlimit then + local code = gaps[unicode] or unicode + local char = characters[code] + local desc = descriptions[code] + local info = chardata[code] + if char then + local commands = char.commands + if commands and not showvirtual then + -- skip + else + local next_sizes = char.next + local v_variants = char.vert_variants + local h_variants = char.horiz_variants + local slookups = desc and desc.slookups + local mlookups = desc and desc.mlookups + local mathclass = info.mathclass + local mathspec = info.mathspec + local mathsymbol = info.mathsymbol + local description = info.description or no_description + context.showmathcharactersstartentry() + context.showmathcharactersreference(f_unicode(unicode)) + context.showmathcharactersentryhexdectit(f_unicode(code),code,lower(description)) + context.showmathcharactersentrywdhtdpic(round(char.width or 0),round(char.height or 0),round(char.depth or 0),round(char.italic or 0)) + if virtual and commands then + local t = { } + for i=1,#commands do + local ci = commands[i] + if ci[1] == "slot" then + local fnt, idx = ci[2], ci[3] + t[#t+1] = f_slot(names[fnt] or fnt,idx) + end + end + if #t > 0 then + context.showmathcharactersentryresource(concat(t,", ")) + end + end + if mathclass or mathspec then + context.showmathcharactersstartentryclassspec() + if mathclass then + context.showmathcharactersentryclassname(mathclass,info.mathname or "no name") + end + if mathspec then + for i=1,#mathspec do + local mi = mathspec[i] + context.showmathcharactersentryclassname(mi.class,mi.name or "no name") + end + end + context.showmathcharactersstopentryclassspec() + end + if mathsymbol then + context.showmathcharactersentrysymbol(f_unicode(mathsymbol),mathsymbol) + end + if next_sizes then + local n, done = 0, { } + context.showmathcharactersstartnext() + while next_sizes do + n = n + 1 + if done[next_sizes] then + context.showmathcharactersnextcycle(n) + break + else + done[next_sizes] = true + context.showmathcharactersnextentry(n,f_unicode(next_sizes),next_sizes) + next_sizes = characters[next_sizes] + v_variants = next_sizes.vert_variants or v_variants + h_variants = next_sizes.horiz_variants or h_variants + if next_sizes then + next_sizes = next_sizes.next + end + end + end + context.showmathcharactersstopnext() + if h_variants or v_variants then + context.showmathcharactersbetweennextandvariants() + end + end + if h_variants then + context.showmathcharactersstarthvariants() + for i=1,#h_variants do -- we might go top-down in the original + local vi = h_variants[i] + context.showmathcharactershvariantsentry(i,f_unicode(vi.glyph),vi.glyph) + end + context.showmathcharactersstophvariants() + elseif v_variants then + context.showmathcharactersstartvvariants() + for i=1,#v_variants do + local vi = v_variants[#v_variants-i+1] + context.showmathcharactersvvariantsentry(i,f_unicode(vi.glyph),vi.glyph) + end + context.showmathcharactersstopvvariants() + end + if slookups or mlookups then + local variants = { } + if slookups then + for lookupname, lookupdata in next, slookups do + local lookuptype = lookuptypes[lookupname] + if lookuptype == "substitution" then + variants[lookupdata] = "sub" + elseif lookuptype == "alternate" then + for i=1,#lookupdata do + variants[lookupdata[i]] = "alt" + end + end + end + end + if mlookups then + for lookupname, lookuplist in next, mlookups do + local lookuptype = lookuptypes[lookupname] + for i=1,#lookuplist do + local lookupdata = lookuplist[i] + local lookuptype = lookuptypes[lookupname] + if lookuptype == "substitution" then + variants[lookupdata] = "sub" + elseif lookuptype == "alternate" then + for i=1,#lookupdata do + variants[lookupdata[i]] = "alt" + end + end + end + end + end + context.showmathcharactersstartlookupvariants() + local i = 0 + for variant, lookuptype in table.sortedpairs(variants) do + i = i + 1 + context.showmathcharacterslookupvariant(i,f_unicode(variant),variant,lookuptype) + end + context.showmathcharactersstoplookupvariants() + end + context.showmathcharactersstopentry() + end + end + end + end + context.showmathcharactersstop() + end +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-characters.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-math-characters.mkiv new file mode 100644 index 00000000000..3b273cb6c21 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-characters.mkiv @@ -0,0 +1,193 @@ +%D \module +%D [ file=s-math-characters.mkiv, % was: s-fnt-25 and later s-mat-10 +%D version=2009.01.25, +%D title=\CONTEXT\ Style File, +%D subtitle=Math Glyph Checking, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[math-characters] + +\registerctxluafile{s-math-characters}{} + +% context --jit --global --bodyfont=cambria --result=math-characters-cambria s-math-characters.mkiv +% context --jit --global --bodyfont=modern --result=math-characters-modern s-math-characters.mkiv + +\startsetups s-math-characters:reset + + \let\showmathcharactersstart \relax + \let\showmathcharactersstop \relax + \let\showmathcharactersreference \gobbleoneargument + \let\showmathcharactersstartentry \relax + \let\showmathcharactersstopentry \relax + \let\showmathcharactersentryhexdectit \gobblethreearguments + \let\showmathcharactersentrywdhtdpic \gobblefourarguments + \let\showmathcharactersentryresource \gobbleoneargument + \let\showmathcharactersstartnext \relax + \let\showmathcharactersnextentry \gobblethreearguments + \let\showmathcharactersnextcycle \gobbleonearguments + \let\showmathcharactersstopnext \relax + \let\showmathcharactersstarthvariants \relax + \let\showmathcharactershvariantsentry \gobblethreearguments + \let\showmathcharactersstophvariants \relax + \let\showmathcharactersstartvvariants \showmathcharactersstarthvariants + \let\showmathcharactersvvariantsentry \showmathcharactershvariantsentry + \let\showmathcharactersstopvvariants \showmathcharactersstophvariants + \let\showmathcharactersbetweennextandvariants\relax + \let\showmathcharactersstartentryclassspec \relax + \let\showmathcharactersstopentryclassspec \relax + \let\showmathcharactersentryclassname \gobbletwoarguments + \let\showmathcharactersentrysymbol \gobbletwoarguments + \let\showmathcharactersstartlookupvariants \relax + \let\showmathcharacterslookupvariant \gobblefourarguments + \let\showmathcharactersstoplookupvariants \relax + \let\showmathcharacterssetrange \gobblethreearguments + +\stopsetups + +\directsetup{s-math-characters:reset} + +\startsetups s-math-characters:default + + \directsetup{s-math-characters:reset} + + \unexpanded\def\showmathcharactersstartentry {\blank\begingroup\raggedright} + \unexpanded\def\showmathcharactersstopentry {\endgroup\blank} + + \def\showmathcharactersentryhexdectit##1##2##3% + {##1:\space{\char##2}\space\ruledhbox{\char##2}\space##3\par + \advance\leftskip\emwidth\relax} + + \def\showmathcharactersentrywdhtdpic##1##2##3##4% + {width:\space##1,\space height:\space##2,\space depth:\space##3,\space italic:\space##4\par} + + \def\showmathcharactersentryresource##1% + {virtual:\space##1\par} + + \def\showmathcharactersstartnext + {\par\begingroup\hangindent\emwidth\hangafter-\plushundred\hskip-\emwidth + next:\space} + + \def\showmathcharactersnextentry##1##2##3% + {\ifnum##1>\plusone \space=>\space\fi##2~\ruledhbox{\char##3}} + + \def\showmathcharactersnextcycle##1% + {\ifnum##1>\plusone \space=>\space\fi cycle} + + \def\showmathcharactersstopnext + {\par\endgroup} + + \def\showmathcharactersstarthvariants + {\par\begingroup\hangindent\emwidth\hangafter-\plushundred\hskip-\emwidth + variants:\space} + + \def\showmathcharactershvariantsentry##1##2##3% + {\ifnum##1>\plusone \space=>\space\fi##2~\ruledhbox{\char##3}} + + \def\showmathcharactersstophvariants + {\par\endgroup} + + \let\showmathcharactersstartvvariants\showmathcharactersstarthvariants + \let\showmathcharactersvvariantsentry\showmathcharactershvariantsentry + \let\showmathcharactersstopvvariants \showmathcharactersstophvariants + + \def\showmathcharactersbetweennextandvariants + {}% \space=>\space} + + \def\showmathcharactersentryclassname##1##2% + {mathclass:\space##1,\space mathname:\space##2\par} + + \def\showmathcharactersentrysymbol##1##2% + {mathsymbol:\space##1~\ruledhbox{\char##2}\par} + + \def\showmathcharactersstartlookupvariants + {\par\begingroup\hangindent\emwidth\hangafter-\plushundred\hskip-\emwidth + lookupvariants:\space} + + \def\showmathcharacterslookupvariant##1##2##3##4% + {\ifnum##1>\plusone,\space\fi##2:~{\char##3}\space(##4)} + + \def\showmathcharactersstoplookupvariants + {\par\endgroup} + +\stopsetups + +\unprotect + +\unexpanded\def\enableshowmathfontvirtual + {\ctxlua{fonts.constructors.autocleanup=false}} + +\unexpanded\def\showmathfontcharacters + {\dosingleempty\module_math_characters_show} + +\def\module_math_characters_show[#1]% + {\begingroup + \getdummyparameters + [\c!bodyfont=, + \c!list=, + \c!check=, + \c!alternative=default, + \c!option=\v!all, + #1]% + \directsetup{s-math-characters:\dummyparameter\c!alternative}% + \doifelsenothing{\dummyparameter\c!bodyfont} + {\definedfont[MathRoman*math-text]} + {\definedfont[\dummyparameter\c!bodyfont]}% + \dontcomplain + \ctxlua{moduledata.math.characters.showlist { + number = false, + check = "\dummyparameter\c!check", + list = "\dummyparameter\c!list", + option = "\dummyparameter\c!option", + }}% + \endgroup} + +\protect + +\stopmodule + +\continueifinputfile{s-math-characters.mkiv} + +\setuplayout + [width=middle, + height=middle, + topspace=15mm, + backspace=15mm, + bottomspace=15mm, + header=1cm, + headerdistance=0.5cm, + footer=0pt] + +\starttext + + \doifelse {\getdocumentargument{bodyfont}} {} { + + \setupbodyfont[cambria, 12pt] + % \setupbodyfont[modern, 12pt] + % \setupbodyfont[lmvirtual, 12pt] + % \setupbodyfont[pxvirtual, 12pt] + % \setupbodyfont[txvirtual, 12pt] + % \setupbodyfont[palatino, 10pt] + % \setupbodyfont[mathtimes, 12pt] + % \setupbodyfont[stix, 12pt] + % \setupbodyfont[xits, 12pt] + % \setupbodyfont[lucida, 12pt] + % \setupbodyfont[lucidanova,12pt] + % \setupbodyfont[pagella, 12pt] + % \setupbodyfont[bonum, 12pt] + + } { + + \normalexpanded{\setupbodyfont[\getdocumentargument{bodyfont},12pt]} + + } + + \showmathfontcharacters + +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-coverage.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-math-coverage.lua new file mode 100644 index 00000000000..3c6080dc36e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-coverage.lua @@ -0,0 +1,197 @@ +if not modules then modules = { } end modules ['s-math-coverage'] = { + version = 1.001, + comment = "companion to s-math-coverage.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local utfchar, utfbyte = utf.char, utf.byte +local formatters, lower = string.formatters, string.lower +local concat = table.concat +local sortedhash = table.sortedhash + +moduledata.math = moduledata.math or { } +moduledata.math.coverage = moduledata.math.coverage or { } + +local context = context + +local ctx_NC = context.NC +local ctx_NR = context.NR +local ctx_HL = context.HL + +local ctx_startmixedcolumns = context.startmixedcolumns +local ctx_stopmixedcolumns = context.stopmixedcolumns +local ctx_setupalign = context.setupalign +local ctx_starttabulate = context.starttabulate +local ctx_stoptabulate = context.stoptabulate +local ctx_rawmathematics = context.formatted.rawmathematics +local ctx_mathematics = context.formatted.mathematics +local ctx_startimath = context.startimath +local ctx_stopimath = context.stopimath +local ctx_setmathattribute = context.setmathattribute +local ctx_underbar = context.underbar +local ctx_getglyph = context.getglyph + +local styles = mathematics.styles +local alternatives = mathematics.alternatives +local charactersets = mathematics.charactersets + +local getboth = mathematics.getboth +local remapalphabets = mathematics.remapalphabets + +local chardata = characters.data +local superscripts = characters.superscripts +local subscripts = characters.subscripts + +context.writestatus("math coverage","underline: not remapped") + +function moduledata.math.coverage.showalphabets() + ctx_starttabulate { "|lT|l|Tl|" } + for i=1,#styles do + local style = styles[i] + for i=1,#alternatives do + local alternative = alternatives[i] + for _, alphabet in sortedhash(charactersets) do + ctx_NC() + if i == 1 then + context("%s %s",style,alternative) + end + ctx_NC() + ctx_startimath() + ctx_setmathattribute(style,alternative) + for i=1,#alphabet do + local letter = alphabet[i] + local id = getboth(style,alternative) + local unicode = remapalphabets(letter,id) + if not unicode then + ctx_underbar(utfchar(letter)) + elseif unicode == letter then + context(utfchar(unicode)) + else + context(utfchar(unicode)) + end + end + ctx_stopimath() + ctx_NC() + local first = alphabet[1] + local last = alphabet[#alphabet] + local id = getboth(style,alternative) + local f_unicode = remapalphabets(first,id) or utfbyte(first) + local l_unicode = remapalphabets(last,id) or utfbyte(last) + context("%05X - %05X",f_unicode,l_unicode) + ctx_NC() + ctx_NR() + end + end + end + ctx_stoptabulate() +end + +function moduledata.math.coverage.showcharacters() + ctx_startmixedcolumns { balance = "yes" } + ctx_setupalign { "nothyphenated" } + ctx_starttabulate { "|T|i2|Tpl|" } + for u, d in sortedhash(chardata) do + local mathclass = d.mathclass + local mathspec = d.mathspec + if mathclass or mathspec then + ctx_NC() + context("%05X",u) + ctx_NC() + ctx_getglyph("MathRoman",u) + ctx_NC() + if mathspec then + local t = { } + for i=1,#mathspec do + t[mathspec[i].class] = true + end + t = table.sortedkeys(t) + context("% t",t) + else + context(mathclass) + end + ctx_NC() + ctx_NR() + end + end + ctx_stoptabulate() + ctx_stopmixedcolumns() +end + +-- This is a somewhat tricky table as we need to bypass the math machinery. + +function moduledata.math.coverage.showscripts() + ctx_starttabulate { "|cT|c|cT|c|c|c|l|" } + for k, v in sortedhash(table.merged(superscripts,subscripts)) do + local ck = utfchar(k) + local cv = utfchar(v) + local ss = superscripts[k] and "^" or "_" + ctx_NC() context("%05X",k) + ctx_NC() context(ck) + ctx_NC() context("%05X",v) + ctx_NC() context(cv) + ctx_NC() ctx_rawmathematics("x%s = x%s%s",ck,ss,cv) + ctx_NC() ctx_mathematics("x%s = x%s%s",ck,ss,cv) + ctx_NC() context(lower(chardata[k].description)) + ctx_NC() ctx_NR() + end + ctx_stoptabulate() +end + +-- Handy too. + +function moduledata.math.coverage.showbold() + ctx_starttabulate { "|lT|cm|lT|cm|lT|" } + for k, v in sortedhash(mathematics.boldmap) do + ctx_NC() context("%U",k) + ctx_NC() context("%c",k) + ctx_NC() context("%U",v) + ctx_NC() context("%c",v) + ctx_NC() context(chardata[k].description) + ctx_NC() ctx_NR() + end + ctx_stoptabulate() +end + +-- function moduledata.math.coverage.showentities() +-- ctx_startmixedcolumns { balance = "yes" } +-- ctx_starttabulate { "|Tl|c|Tl|" } +-- for k, v in sortedhash(characters.entities) do +-- local b = utf.byte(v) +-- local d = chardata[b] +-- local m = d.mathname +-- local c = d.contextname +-- local s = ((m and "\\"..m) or (c and "\\".. c) or v) .. "{}{}{}" +-- ctx_NC() +-- context("%U",b) +-- ctx_NC() +-- ctx_mathematics(s) +-- ctx_NC() +-- context(k) +-- ctx_NC() +-- ctx_NR() +-- end +-- ctx_stoptabulate() +-- ctx_stopmixedcolumns() +-- end + +function moduledata.math.coverage.showentities() + ctx_startmixedcolumns { balance = "yes" } + ctx_starttabulate { "|T||T|T|" } + for k, v in sortedhash(characters.entities) do + local d = chardata[v] + if d then + local m = d.mathclass or d.mathspec + local u = d.unicodeslot + ctx_NC() context(m and "m" or "t") + ctx_NC() ctx_getglyph("MathRoman",u) + ctx_NC() context("%05X",u) + ctx_NC() context(k) + ctx_NC() ctx_NR() + end + end + ctx_stoptabulate() + ctx_stopmixedcolumns() +end + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-coverage.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-math-coverage.mkiv new file mode 100644 index 00000000000..e318c9effdd --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-coverage.mkiv @@ -0,0 +1,38 @@ +%D \module +%D [ file=s-math-coverage, % s-fnt-33, s-fnt-32 +%D version=2011.05.10, % and older +%D title=\CONTEXT\ Style File, +%D subtitle=Show Math Coverage, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[math-coverage] + +\registerctxluafile{s-math-coverage}{} + +\installmodulecommandluasingle \showmathalphabets {moduledata.math.coverage.showalphabets} +\installmodulecommandluasingle \showmathcharacters{moduledata.math.coverage.showcharacters} +\installmodulecommandluasingle \showmathscripts {moduledata.math.coverage.showscripts} +\installmodulecommandluasingle \showmathbold {moduledata.math.coverage.showbold} +\installmodulecommandluasingle \showmathentities {moduledata.math.coverage.showentities} + +\stopmodule + +\continueifinputfile{s-math-coverage.mkiv} + +\usemodule[art-01] + +\starttext + + \showmathalphabets \page + \showmathcharacters \page + \showmathscripts \page + \showmathbold \page + \showmathentities \page + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-extensibles.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-math-extensibles.mkiv new file mode 100644 index 00000000000..f9ff8547ae1 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-extensibles.mkiv @@ -0,0 +1,145 @@ +%D \module +%D [ file=s-math-extensibles.mkiv, +%D version=2013.02.03, +%D title=\CONTEXT\ Style File, +%D subtitle=Math Stackers Checking, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This module provides a macro that will typeset a table of (horizontal) +%D extensibles including some tracing. You can set up the \type {demo} +%D stacker category to tweak things. +%D +%D \starttyping +%D \showmathextensibles[alternative=a|b] +%D \stoptyping + +\startmodule[math-extensibles] + +\unprotect + +\definemathstackers + [demo] + [math] + [\c!offset=\v!max] + +\installcorenamespace{modulemathextensibles} +\installcorenamespace{modulemathextensiblesalternative} + +\installdirectsetuphandler \??modulemathextensibles {modulemathextensibles} + +\setupmodulemathextensibles + [\c!alternative=\v!a] + +\unexpanded\def\showmathextensibles + {\dosingleempty\module_math_extensibles_show_all} + +\def\module_math_extensibles_show_all[#1]% + {\begingroup + \setupcurrentmodulemathextensibles[#1]% + \expandnamespacevalue\??modulemathextensiblesalternative\c!alternative\v!a + \endgroup} + +\def\modulemathextensiblesalternativea#1#2#3% + {\NC U+#1 + \NC \filledhboxm{\math{\char"#1}} + \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{bottom}}} + \NC \hbox{\math{\mathextensible[demo]{"#1}{}{bottom}}} + \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{}}} + \NC \nohyphens \veryraggedright #2 + \NC\NR} + +\setvalue{\??modulemathextensiblesalternative\v!a}% + {\enabletrackers[math.stackers.texts] + \starttabulate[|Tl|l|l|l|l|Tp|] + \ctxlua { moduledata.math.extensibles.show { + command = "modulemathextensiblesalternativea", + } } + \stoptabulate + \disabletrackers[math.stackers.texts]} + +\def\modulemathextensiblesalternativeb#1#2#3% + {\NC U+#1 + \NC \math{\char"#1} + \NC \nohyphens \veryraggedright #3 + \NC \NR} + +\setvalue{\??modulemathextensiblesalternative\v!b}% + {\enabletrackers[math.stackers.texts] + \starttabulate[|Tl|l|Tp|] + \ctxlua { moduledata.math.extensibles.show { + command = "modulemathextensiblesalternativeb", + sparse = true, + } } + \stoptabulate + \disabletrackers[math.stackers.texts]} + +\startluacode + moduledata.math = moduledata.math or { } + moduledata.math.extensibles = moduledata.math.extensibles or { } + + function moduledata.math.extensibles.show(settings) + local command = settings.command + local sparse = settings.sparse + for k, v in table.sortedhash(characters.data) do + local mathextensible = v.mathextensible + if mathextensible == "r" or mathextensible == "l" or mathextensible == "h" then + local names = { } + local mathname = v.mathname + if mathname then + names[#names+1] = v.mathclass .. ":" .. mathname + end + local mathspec = v.mathspec + if mathspec then + for i=1,#mathspec do + local v = mathspec[i] + names[#names+1] = v.class .. ":" .. v.name + end + end + local mathfiller = v.mathfiller + if mathfiller then + names[#names+1] = "filler:" .. mathfiller + end + if not sparse or #names > 0 then + context[command](string.format("%04X",k),v.description,table.concat(names," ")) + end + end + end + end +\stopluacode + +\protect + +\stopmodule + +\continueifinputfile{s-math-extensibles.mkiv} + +\setuplayout + [width=middle, + height=middle, + footer=0cm, + backspace=1.5cm, + topspace=1.5cm] + +\setuphead[chapter][style=\bfc] +\setuphead[section][style=\bfa] + +\starttext + + \dowith {a,b} { + + \page \title {Latin Modern} \showmathextensibles[alternative=#1] + \page \setupbodyfont[pagella] \title {Pagella} \showmathextensibles[alternative=#1] + \page \setupbodyfont[termes] \title {Termes} \showmathextensibles[alternative=#1] + \page \setupbodyfont[dejavu] \title {Xits} \showmathextensibles[alternative=#1] + \page \setupbodyfont[cambria] \title {Cambria} \showmathextensibles[alternative=#1] + \page \setupbodyfont[lucidaot] \title {Lucida} \showmathextensibles[alternative=#1] + + } + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-parameters.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-math-parameters.lua new file mode 100644 index 00000000000..8e8c15a2d37 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-parameters.lua @@ -0,0 +1,135 @@ +if not modules then modules = { } end modules ['s-math-coverage'] = { + version = 1.001, + comment = "companion to s-math-coverage.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.math = moduledata.math or { } +moduledata.math.parameters = moduledata.math.parameters or { } + +local tables = utilities.tables.definedtable("math","tracing","spacing","tables") + +tables.styleaxis = { + "ord", "op", "bin", "rel", "open", "close", "punct", "inner", +} + +tables.parameters = { + "quad", "axis", "operatorsize", + "overbarkern", "overbarrule", "overbarvgap", + "underbarkern", "underbarrule", "underbarvgap", + "radicalkern", "radicalrule", "radicalvgap", + "radicaldegreebefore", "radicaldegreeafter", "radicaldegreeraise", + "stackvgap", "stacknumup", "stackdenomdown", + "fractionrule", "fractionnumvgap", "fractionnumup", + "fractiondenomvgap", "fractiondenomdown", "fractiondelsize", + "limitabovevgap", "limitabovebgap", "limitabovekern", + "limitbelowvgap", "limitbelowbgap", "limitbelowkern", + "underdelimitervgap", "underdelimiterbgap", + "overdelimitervgap", "overdelimiterbgap", + "subshiftdrop", "supshiftdrop", "subshiftdown", + "subsupshiftdown", "subtopmax", "supshiftup", + "supbottommin", "supsubbottommax", "subsupvgap", + "spaceafterscript", "connectoroverlapmin", +} + +tables.styles = { + "display", + "text", + "script", + "scriptscript", +} + +function tables.stripmu(str) + str = string.gsub(str,"mu","") + str = string.gsub(str," ","") + str = string.gsub(str,"plus","+") + str = string.gsub(str,"minus","-") + return str +end + +function tables.strippt(old) + local new = string.gsub(old,"pt","") + if new ~= old then + new = string.format("%0.4f",tonumber(new)) + end + return new +end + +function moduledata.math.parameters.showspacing() + + local styles = tables.styles + local styleaxis = tables.styleaxis + + context.starttabulate { "|Tl|Tl|" .. string.rep("Tc|",(#styles*2)) } + context.HL() + context.NC() + context.NC() + context.NC() + for i=1,#styles do + context.bold(styles[i]) + context.NC() + context.bold("(cramped)") + context.NC() + end + context.NR() + context.HL() + for i=1,#styleaxis do + -- print(key,tex.getmath(key,"text")) + local one = styleaxis[i] + for j=1,#styleaxis do + local two = styleaxis[j] + context.NC() + if j == 1 then + context.bold(one) + end + context.NC() + context.bold(two) + context.NC() + for i=1,#styles do + context("\\ctxlua{context(math.tracing.spacing.tables.stripmu('\\the\\Umath%s%sspacing\\%sstyle'))}",one,two,styles[i]) + context.NC() + context("\\ctxlua{context(math.tracing.spacing.tables.stripmu('\\the\\Umath%s%sspacing\\cramped%sstyle'))}",one,two,styles[i]) + context.NC() + end + context.NR() + end + end + context.stoptabulate() +end + +function moduledata.math.parameters.showparameters() + + local styles = tables.styles + local parameters = tables.parameters + + context.starttabulate { "|l|" .. string.rep("Tc|",(#styles*2)) } + context.HL() + context.NC() + context.NC() + for i=1,#styles do + context.bold(styles[i]) + context.NC() + context.bold("(cramped)") + context.NC() + end + context.NR() + context.HL() + for i=1,#parameters do + local parameter = parameters[i] + -- print(parameter,tex.getmath(parameter,"text")) + context.NC() + context.type(parameter) + context.NC() + for i=1,#styles do + context("\\ctxlua{context(math.tracing.spacing.tables.strippt('\\the\\Umath%s\\%sstyle'))}",parameter,styles[i]) + context.NC() + context("\\ctxlua{context(math.tracing.spacing.tables.strippt('\\the\\Umath%s\\cramped%sstyle'))}",parameter,styles[i]) + context.NC() + end + context.NR() + end + context.stoptabulate() + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-parameters.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-math-parameters.mkiv new file mode 100644 index 00000000000..f2fde5d8384 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-parameters.mkiv @@ -0,0 +1,41 @@ +%D \module +%D [ file=s-math-parameters.mkiv, +%D version=2012.12.05, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Math Parameters, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[math-parameters] + +\registerctxluafile{s-math-parameters}{} + +\installmodulecommandluasingle \showmathspacing {moduledata.math.parameters.showspacing} +\installmodulecommandluasingle \showmathparameters {moduledata.math.parameters.showparameters} + +\stopmodule + +\continueifinputfile{s-math-parameters.mkiv} + +\setuplayout + [width=middle, + height=middle, + backspace=1cm, + topspace=1cm, + footer=0pt, + header=0pt] + +\setupbodyfont + [dejavu,8pt] + +\starttext + + \showmathspacing \page + \showmathparameters \page + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-math-repertoire.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-math-repertoire.mkiv new file mode 100644 index 00000000000..230eb513ebe --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-math-repertoire.mkiv @@ -0,0 +1,487 @@ +%D \module +%D [ file=s-math-parameters.mkiv, % was s-mat-12.mkiv +%D version=2012.06.06, % whatever, probably a bit earlier +%D title=\CONTEXT\ Style File, +%D subtitle=Show Math Character Repertoire, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[s][math-characters] + +% context --jit --global --bodyfont=lucidanova --result=math-repertoire-lucidanova s-math-repertoire.mkiv +% context --jit --global --bodyfont=cambria --result=math-repertoire-cambria s-math-repertoire.mkiv +% context --jit --global --bodyfont=xits --result=math-repertoire-xits s-math-repertoire.mkiv +% context --jit --global --bodyfont=modern --result=math-repertoire-modern s-math-repertoire.mkiv +% context --jit --global --bodyfont=pagella --result=math-repertoire-pagella s-math-repertoire.mkiv +% context --jit --global --bodyfont=termes --result=math-repertoire-termes s-math-repertoire.mkiv +% context --jit --global --bodyfont=bonum --result=math-repertoire-bonum s-math-repertoire.mkiv + +\startmodule[math-repertoire] + +% layout + +\definecolor[backgroundcolor] [r=.6,g=.6] +\definecolor[backgroundcolorx][r=.6] +\definecolor[backgroundcolory][g=.6] +\definecolor[baselinecolor] [a=1,t=.5,s=.6] +\definecolor[charactercolor] [b=.6] +\definecolor[pagecolor] [s=.1] +\definecolor[nonecolor] [s=.5] +\definecolor[textcolor] [s=.9] + +% \setuppapersize[HD] +% +% \setuplayout +% [page] + +\setuppapersize + [HD+] + +\setuplayout + [backspace=0pt, + topspace=0pt, + bottomspace=120pt, %1200-1080 + bottom=24pt, + bottomdistance=5mm, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\definelayer + [page] + +\setuplayer + [page] + [width=\textwidth, + height=\textheight] + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=pagecolor] + +\setupbackgrounds + [text][text] + [bottomframe=on, + framecolor=textcolor, + rulethickness=0.025ex] + +\setupmakeup + [standard] + [pagestate=start] + +\setupinteraction + [state=start, + menu=on] + +\defineinteractionmenu + [ALPHABETS] + [bottom] + +\defineinteractionmenu + [alphabets] + [bottom] + +\defineinteractionmenu + [symbols] + [bottom] + +\setupinteractionmenu + [bottom] + [before=\vfill, + after=\vfill, + left=\hfill, + right=\hfill, + style=\tt\bf, + distance=0pt, + color=textcolor, + contrastcolor=nonecolor] + +\def\showmathcharacterssetrange#1#2#3% + {\writestatus{range}{#1: \unihex{#2} - \unihex{#3}}% + \ifcase#2\relax + \definereference[#1][notpresent]% + \else\ifcase#3\relax + \definereference[#1][notpresent]% + \else + \normalexpanded{\definereference[#1][\unihex{#2}]}% + \fi\fi} + +\startinteractionmenu[bottom] + \startgot [firstpage] first \stopgot \quad + \startgot [deltapage(-100)] -100 \stopgot \quad + \startgot [deltapage(-10)] -10 \stopgot \quad + \startgot [previouspage] previous \stopgot \quad + \startgot [nextpage] next \stopgot \quad + \startgot [deltapage(+10)] +10 \stopgot \quad + \startgot [deltapage(+100)] +100 \stopgot \quad + \startgot [lastpage] last \stopgot +\stopinteractionmenu + +\startinteractionmenu[ALPHABETS] + \startgot [U+00041] NORMAL \stopgot \quad + \startgot [U+1D400] BOLD \stopgot \quad + \startgot [U+1D434] ITALIC \stopgot \quad + \startgot [U+1D468] BOLDITALIC \stopgot \quad + \startgot [U+1D49C] SCRIPT \stopgot \quad + \startgot [U+1D4D0] BOLDSCRIPT \stopgot \quad + \startgot [U+1D504] FRAKTUR \stopgot \quad + \startgot [U+1D538] DOUBLESTRUCK \stopgot \quad + \startgot [U+1D56C] BOLDFRAKTUR \stopgot \quad + \startgot [U+1D5A0] SS NORMAL \stopgot \quad + \startgot [U+1D5D4] SS BOLD \stopgot \quad + \startgot [U+1D608] SS ITALIC \stopgot \quad + \startgot [U+1D63C] SS BOLDITALIC \stopgot \quad + \startgot [U+1D670] MONOSPACE \stopgot \quad + \startgot [U+00391] GRK NORMAL \stopgot \quad + \startgot [U+1D6A8] GRK BOLD \stopgot \quad + \startgot [U+1D6E2] GRK ITALIC \stopgot \quad + \startgot [U+1D71C] GRK BOLDITALIC \stopgot \quad + \startgot [U+1D756] GRK SS BOLD \stopgot \quad + \startgot [U+1D790] GRK SS BOLDITALIC \stopgot +\stopinteractionmenu + +\startinteractionmenu[alphabets] + \startgot [U+00061] normal \stopgot \quad + \startgot [U+1D41A] bold \stopgot \quad + \startgot [U+1D44E] italic \stopgot \quad + \startgot [U+1D482] bolditalic \stopgot \quad + \startgot [U+1D4B6] script \stopgot \quad + \startgot [U+1D4EA] boldscript \stopgot \quad + \startgot [U+1D51E] fraktur \stopgot \quad + \startgot [U+1D552] doublestruck \stopgot \quad + \startgot [U+1D586] boldfraktur \stopgot \quad + \startgot [U+1D5BA] ss normal \stopgot \quad + \startgot [U+1D5EE] ss bold \stopgot \quad + \startgot [U+1D622] ss italic \stopgot \quad + \startgot [U+1D656] ss bolditalic \stopgot \quad + \startgot [U+1D68A] monospace \stopgot \quad + \startgot [U+003B1] grk normal \stopgot \quad + \startgot [U+1D6C2] grk bold \stopgot \quad + \startgot [U+1D6FC] grk italic \stopgot \quad + \startgot [U+1D736] grk bolditalic \stopgot \quad + \startgot [U+1D770] grk ss bold \stopgot \quad + \startgot [U+1D7AA] grk ss bolditalic \stopgot +\stopinteractionmenu + +% \startinteractionmenu[symbols] +% \startgot [U+00030] dig normal \stopgot \quad +% \startgot [U+1D7CE] dig bold \stopgot \quad +% \startgot [U+1D7D8] dig doublestruck \stopgot \quad +% \startgot [U+1D7E2] dig ss normal \stopgot \quad +% \startgot [U+1D7EC] dig ss bold \stopgot \quad +% \startgot [U+1D7F6] dig monospace \stopgot \quad +% \startgot [U+02200] operators \stopgot \quad +% \startgot [U+02701] symbols a \stopgot \quad +% \startgot [U+02901] symbols b \stopgot \quad +% \startgot [U+02A00] supplemental \stopgot \quad +% \startgot [U+027F0] arrows a \stopgot \quad +% \startgot [U+02900] arrows b \stopgot \quad +% \startgot [U+1F800] arrows c \stopgot +% \stopinteractionmenu + +\startinteractionmenu[symbols] + \startgot [U+00030] dig normal \stopgot \quad + \startgot [U+1D7CE] dig bold \stopgot \quad + \startgot [U+1D7D8] dig doublestruck \stopgot \quad + \startgot [U+1D7E2] dig ss normal \stopgot \quad + \startgot [U+1D7EC] dig ss bold \stopgot \quad + \startgot [U+1D7F6] dig monospace \stopgot \quad + \startgot [U+02200] operators \stopgot \quad + \startgot [miscellaneousmathematicalsymbolsa] symbols a \stopgot \quad + \startgot [miscellaneousmathematicalsymbolsb] symbols b \stopgot \quad + \startgot [supplementalmathematicaloperators] supplemental \stopgot \quad + \startgot [supplementalarrowsa] arrows a \stopgot \quad + \startgot [supplementalarrowsb] arrows b \stopgot \quad + \startgot [supplementalarrowsc] arrows c \stopgot \quad + \removeunwantedspaces +\stopinteractionmenu + +\defineframed + [somedata] + [background=color, + backgroundcolor=textcolor, + %framecolor=charactercolor, + %rulethickness=1pt, + frame=off, + offset=1ex] + +% helpers + +\unexpanded\def\showmathcharacterstxt#1% + {{\tttf#1}} + +\unexpanded\def\showmathcharacterschr#1#2% + {\iffontchar\font#2\relax + \scale + [sx=#1,sy=#1] + {\dontleavehmode + \begingroup + \setbox\scratchbox\hbox{\charactercolor\char#2}% + \scratchdimen\wd\scratchbox + \ifdim\scratchdimen>\zeropoint + \backgroundline[backgroundcolor]{\box\scratchbox}% + \else\ifdim\scratchdimen<\zeropoint + \scratchdimen-\scratchdimen + \setbox\scratchbox\hbox to \scratchdimen{\hss\charactercolor\char#2}% + \backgroundline[backgroundcolorx]{\box\scratchbox}% + \else + \setbox\scratchbox\hbox to 1em{\hss\charactercolor\char#2}% + \scratchdimen\wd\scratchbox + \backgroundline[backgroundcolory]{\box\scratchbox}% + \fi\fi + \hskip-\scratchdimen + \baselinecolor\vrule width \scratchdimen height .05ex depth .05ex + \endgroup}% + \fi} + +\unexpanded\def\showmathcharactersmth#1#2% + {\setbox\scratchbox\hbox{\showmathcharacterschr{#1}{#2}}% + \ht\scratchbox\strutht + \dp\scratchbox\strutdp + \box\scratchbox} + +\let\showmathcharactersbodyfonts\empty + +\unexpanded\def\showmathcharactersbodyfontentry#1#2% + {\somedata + [align={none,middle},background=,height=5cm] + {\begingroup + \switchtobodyfont[#2,12pt]% + \definedfont[MathRoman*math-text]% + \showmathcharactersmth{10}{#1}% + \endgroup + \vfilll + \doifelsemode{crosslink} + {\goto{\strut\textcolor\showmathcharacterstxt{#2}}[#2::#1]}% + {\strut\textcolor\showmathcharacterstxt{#2}}}% + \hskip1ex} + +\unexpanded\def\showmathcharacterssetbodyfonts#1% + {\edef\showmathcharactersbodyfonts{#1}% + \def\doshowmathcharacterssetbodyfonts##1{\setupbodyfont[##1,12pt]}% + \processcommacommand[\showmathcharactersbodyfonts]\doshowmathcharacterssetbodyfonts} + +\unexpanded\def\showmathcharactersbodyfontschars#1% + {\processcommacommand[\showmathcharactersbodyfonts]{\showmathcharactersbodyfontentry{#1}}} + +% main + +\unexpanded\def\showmathcharactersstart + {\starttext + \startstandardmakeup % we use baselinecolor so that we have a transparency on page 1 + \setupalign[middle] + \vfil + \dontleavehmode \scale[height=.3\textheight]{\strut\color[textcolor]{\fontclass}} + \vfil + \dontleavehmode \scale[height=.1\textheight]{\strut\color[baselinecolor]{\currentdate}} + \vfil + \vfil + \stopstandardmakeup} + +\unexpanded\def\showmathcharactersstop + {\stoptext} + +% entry + +\unexpanded\def\showmathcharactersstartentry + {\startstandardmakeup} + +\unexpanded\def\showmathcharactersstopentry + {\tightlayer[page] + \stopstandardmakeup} + +\unexpanded\def\showmathcharactersreference#1% + {\setlayer[page]{\pagereference[#1]}} + +\unexpanded\def\showmathcharactersentryhexdectit#1#2#3% + {\setlayer + [page] + [preset=middletop,voffset=5mm] + {\somedata[height=1cm]{\showmathcharacterstxt{#1}}} + \setlayer + [page] + [preset=middle,y=2cm] + {\showmathcharactersmth{25}{#2}} + \setlayer + [page] + [preset=righttop,offset=5mm] + {\somedata[height=1cm]{\showmathcharacterstxt{#3}}} + \doifsomething\showmathcharactersbodyfonts + {\setlayer + [page] + [preset=middlebottom,voffset=5mm] + {\showmathcharactersbodyfontschars{#2}}}} + +% dimensions + +\unexpanded\def\showmathcharactersentrywdhtdpic#1#2#3#4% + {\setlayer + [page] + [preset=leftbottom,offset=5mm] + {\somedata[align=normal,width=5cm] + {\strut width \hfill \the\dimexpr#1sp\par + \strut height\hfill \the\dimexpr#2sp\par + \strut depth \hfill \the\dimexpr#3sp\par + \strut italic\hfill \the\dimexpr#4sp}}} + +\unexpanded\def\showmathcharactersentryresource#1% + {} % {virtual: #1\par} + +% next + +\unexpanded\def\showmathcharactersstartnext + {\setlayer + [page] + [preset=middleleft,hoffset=5mm] + \bgroup\vbox\bgroup} + +\unexpanded\def\showmathcharactersstopnext + {\egroup\egroup} + +\unexpanded\def\showmathcharactersnextentry#1#2#3% + {\ifnum#1>1 \vskip1ex \fi + \dontleavehmode\somedata + [align=normal,width=4cm] + {\strut\showmathcharacterstxt{#2}\hfill\showmathcharacterschr{2}{#3}}\par} + +\unexpanded\def\showmathcharactersnextcycle#1% + {\ifnum#1>1 \vskip1ex \fi + \dontleavehmode\somedata + [align=normal,width=4cm] + {\strut\showmathcharacterstxt{cycle}}\par} + +% variants + +\unexpanded\def\showmathcharactersstartvvariants + {\setlayer + [page] + [preset=lefttop,offset=5mm] + \bgroup\vbox\bgroup} + +\unexpanded\def\showmathcharactersstarthvariants + {\setlayer + [page] + [preset=lefttop,offset=5mm] + \bgroup\hbox\bgroup} + +\unexpanded\def\showmathcharactersvvariantsentry#1#2#3% + {\ifnum#1>1 \vskip1ex \fi + \dontleavehmode\somedata + [align=middle,width=4cm] + {\strut\showmathcharacterstxt{#2}\hfilll\showmathcharacterschr{2}{#3}}} + +\unexpanded\def\showmathcharactershvariantsentry#1#2#3% + {\ifnum#1>1 \hskip1ex \else \dontleavehmode \fi + \somedata + [align={none,middle},height=2cm] + {\strut\showmathcharacterstxt{#2}\vfilll\showmathcharacterschr{2}{#3}}} + +\unexpanded\def\showmathcharactersstopvvariants + {\egroup\egroup} + +\unexpanded\def\showmathcharactersstophvariants + {\egroup\egroup} + +\unexpanded\def\showmathcharactersbetweennextandvariants + {} + +% classes + +\unexpanded\def\showmathcharactersstartentryclassspec + {\setlayer + [page] + [preset=rightbottom,offset=5mm] + \bgroup\somedata[align=normal,width=8cm]\bgroup} + +\unexpanded\def\showmathcharactersstopentryclassspec + {\egroup\egroup} + +\unexpanded\def\showmathcharactersentryclassname#1#2% + {\strut{\showmathcharacterstxt#1}\hfill\showmathcharacterstxt{#2}\par} + +% symbols + +\unexpanded\def\showmathcharactersentrysymbol#1#2% + {\setlayer + [page] + [preset=leftbottom,hoffset=5mm,voffset=50mm] + {\somedata + [align=normal,width=5cm] + {\showmathcharacterstxt{#1}\hfill\showmathcharacterschr{4}{#2}}}} + +% alternates + +\unexpanded\def\showmathcharactersstartlookupvariants + {\setlayer + [page] + [preset=middleright,hoffset=5mm] + \bgroup\vbox\bgroup} + +\unexpanded\def\showmathcharactersstoplookupvariants + {\egroup\egroup} + +\unexpanded\def\showmathcharacterslookupvariant#1#2#3#4% + {\ifnum#1>1 \vskip1ex \fi + \somedata + [align=normal,width=7cm] + {\showmathcharacterstxt{#4:} \showmathcharacterstxt{#2}\hfill\showmathcharacterschr{4}{#3}}} + +% main + +% this is a one-run style so we can forget about an alternative +% just assume that the previous definitions are global + +\unprotect + +\unexpanded\def\showmathfontrepertoire + {\dosingleempty\module_math_repertoire_show} + +\def\module_math_repertoire_show[#1]% + {\showmathfontcharacters[alternative=,option=,check=yes,#1] + \showmathfontcharacters[alternative=,option=,#1]} + +\protect + +\stopmodule + +\continueifinputfile{s-math-repertoire.mkiv} + +\showmathcharacterssetbodyfonts{lucidaot,cambria,xits,modern,pagella,termes,bonum,schola,dejavu} + +\starttext + + \doifelse {\getdocumentargument{bodyfont}} {} { + + % \setupbodyfont[cambria, 12pt] + % \setupbodyfont[modern, 12pt] + % \setupbodyfont[lmvirtual, 12pt] + % \setupbodyfont[pxvirtual, 12pt] + % \setupbodyfont[txvirtual, 12pt] + % \setupbodyfont[palatino, 10pt] + % \setupbodyfont[mathtimes, 12pt] + % \setupbodyfont[stix, 12pt] + % \setupbodyfont[xits, 12pt] + % \setupbodyfont[lucida, 12pt] + % \setupbodyfont[lucidaot, 12pt] + % \setupbodyfont[pagella, 12pt] + % \setupbodyfont[bonum, 12pt] + % \setupbodyfont[schola, 12pt] + \setupbodyfont[dejavu, 12pt] + + } { + + \normalexpanded{\setupbodyfont[\getdocumentargument{bodyfont},12pt]} + + } + + \showmathfontrepertoire + +\stoptext + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-mod-00.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-mod-00.mkiv new file mode 100644 index 00000000000..7af56dc2de9 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-mod-00.mkiv @@ -0,0 +1,24 @@ +%D \module +%D [ file=s-mod-00, +%D version=very-old, +%D title=\CONTEXT\ Style File, +%D subtitle=Documentation Base Environment, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\startmode[nocode] + + % \definieerbuffer[definition] % ignore + + \def\startdefinition#1\stopdefinition{} + +\stopmode + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-mod-01.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-mod-01.mkiv new file mode 100644 index 00000000000..6946bef691c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-mod-01.mkiv @@ -0,0 +1,390 @@ +%D \module +%D [ file=s-mod-01, +%D version=very-old, +%D title=\CONTEXT\ Style File, +%D subtitle=Module Documentation, +%D author={Hans Hagen \& Luigi Scarso}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +%D Usage: +%D +%D \starttyping +%D context --ctx=s-mod somefile.mkiv +%D \stoptyping +%D +%D In due time there will be a \type {mtx-context-module} as well. +%D +%D Luigi Scarso coordinates the processing of modules so best contact +%D him when you run into problems. Bugs in this style can be sent to +%D Hans. + +\usemodule + [abr-00] + +\setvariables + [document] + [ file=\jobname, + type=unknown, + version={\currentdate[\v!year,{.},\v!month,{.},\v!day]}, + system=\CONTEXT, + title=Unknown Title, + subtitle=, + author=Unknown Author, + date=\currentdate, + copyright=Unknown Copyright, + suggestions=] + +\let\module\setupdocument + +\definepalet [module:unknown] [localone=black,localtwo=white] + +\definepalet [module:tex] [localone=blue,localtwo=green] +\definepalet [module:mkii] [localone=blue,localtwo=green] +\definepalet [module:mkiv] [localone=blue,localtwo=green] +\definepalet [module:mkvi] [localone=blue,localtwo=green] + +\definepalet [module:lua] [localone=red,localtwo=green] +\definepalet [module:cld] [localone=red,localtwo=green] + +\definepalet [module:mp] [localone=red,localtwo=blue] +\definepalet [module:mpii] [localone=red,localtwo=blue] +\definepalet [module:mpiv] [localone=red,localtwo=blue] +\definepalet [module:metapost][localone=red,localtwo=blue] + +\setuppalet + [module:unknown] + +\startuseMPgraphic{page} + + StartPage ; + + color local_white ; local_white := .8white ; + color local_one ; local_one := \MPcolor{localone} randomized (.6,.8) ; + color local_two ; local_two := \MPcolor{localtwo} randomized (.3,.4) ; + + color local_one ; local_one := .75[\MPcolor{localone},white] ; + color local_two ; local_two := .75[\MPcolor{localtwo},white] ; + + numeric width ; width := bbwidth Page ; + numeric height ; height := bbheight Page ; + + u := width/400 ; + + def a_module (expr dx, dy) = + picture p ; p := image ( + ddy := 0 ; sx := 60u ; + for i=1 upto (4 randomized 2) : + sy := 7u randomized 3u ; + fill unitsquare xyscaled(sx,sy) shifted (0,ddy) withcolor local_two ; + ddy := ddy + sy + 4u ; + endfor ; + ) ; + p := p shifted (dx,dy) shifted - center p ; + fill boundingbox p enlarged 8u withcolor local_white ; + fill boundingbox p enlarged 4u withcolor local_one ; + draw p ; + enddef ; + + set_grid(width, height, width/15, height/15) ; + + forever: + if new_on_grid(uniformdeviate width,uniformdeviate height): + a_module(dx,dy) ; + fi ; + exitif grid_full ; + endfor ; + + picture p ; + + draw image ( + draw anchored.urt(textext("\bf\strut\documentvariable{system}") ysized 5.0cm,urcorner Page shifted (-1cm,- 1cm)) ; + draw anchored.urt(textext("\bf\strut\documentvariable{title}") ysized 1.5cm,urcorner Page shifted (-1cm,- 8cm)) ; + draw anchored.urt(textext("\bf\strut\documentvariable{subtitle}") ysized 1.5cm,urcorner Page shifted (-1cm,-10cm)) ; + draw anchored.urt(textext("\bf\strut\documentvariable{author}") ysized 1.5cm,lrcorner Page shifted (-1cm, 5cm)) ; + draw anchored.urt(textext("\bf\strut\currentdate") ysized 1.5cm,lrcorner Page shifted (-1cm, 3cm)) ; + ) withcolor .25white ; + + StopPage ; + +\stopuseMPgraphic + +\startsetups[document:start] + + \setuppalet + [module:\documentvariable{type}] + + \startTEXpage + \useMPgraphic{page} + \stopTEXpage + + \page[right] + +\stopsetups + +\startsetups[document:stop] + + \page + + \placeregister + [\v!index] + [\c!balance=\v!yes, + \c!indicator=\v!no, + \c!criterium=\v!text] + +\stopsetups + +% In order to be able to typeset this one too, we need to avoid +% direct backslashed names. + +\starttexdefinition startmoduledocumentation + \starttext + \page + \begingroup + \startdocument +\stoptexdefinition + +\starttexdefinition stopmoduledocumentation + \stopdocument + \page + \endgroup + \stoptext +\stoptexdefinition + +\starttexdefinition startdocumentation + \par + \bgroup +\stoptexdefinition + +\starttexdefinition stopdocumentation + \par + \egroup +\stoptexdefinition + +\definetyping + [definition] + +\starttexdefinition startcompressdefinitions + \blank + \begingroup + \setuptyping[definition][bodyfont=small] +\stoptexdefinition + +\starttexdefinition stopcompressdefinitions + \blank + \endgroup +\stoptexdefinition + +\definetyping [PL] [\c!option=PL] +\definetyping [JV] [\c!option=JV] +\definetyping [MP] [\c!option=MP] +\definetyping [TEX] [\c!option=TEX] +\definetyping [LUA] [\c!option=LUA] + +\setuptyping [\v!typing] [\c!margin=\v!standard] +\setuptyping [\v!file] [\c!margin=\v!standard] +\setuptyping [definition] [\c!margin=0pt,\c!numbering=\v!line,\c!continue=\v!yes] % this continue wins + +\setuplinenumbering + [definition] + [\c!style=\ttx, + \c!distance=\leftmargindistance, + \c!align=\v!flushright] + +% This will be cleaned up. + +\unexpanded\def\domodulemarginstuff#1#2% + {\marginstuff + {\ifx#1\relax + \index{#2}% + \else + \index{#1{#2}}% + \fi + #1{\doboundtext{#2}{\leftmarginwidth}{..}}}} + +\unexpanded\def\modulemarginstuff#1#2% to be renamed + {\processcommalist[#2]{\domodulemarginstuff#1}} + +\definemargindata + [marginstuff] + [left] + [stack=yes, + hoffset=2em, + style=\ttxx] + +\unexpanded\def\macros {\modulemarginstuff\tex } +\unexpanded\def\extras {\modulemarginstuff\relax} +\unexpanded\def\elements{\modulemarginstuff\someelement} + +\unexpanded\def\someelement#1{\type{<#1>}} + +% [index]{command} + +% \macros{a,b} +% \macros{a,b}{b} +% \macros[a]{a,b}{b} + +% weg ermee (indeed): +% +% \defineparagraphs [interface] [\c!n=2] +% \setupparagraphs [interface] [1] [\c!width=4cm] + +\starttexdefinition startexample + \par + \startnarrower +\stoptexdefinition + +\starttexdefinition stopexample + \stopnarrower +\stoptexdefinition + +%D Command references: + +\usemodule[int-load] \loadsetups + +\let\showsetup\setup + +\setupframedtexts + [setuptext] + [\c!background=\v!screen, + \c!frame=\v!off] + +% style (we use dejavu as it supports more characters) + +\switchtobodyfont + [dejavu-condensed,10pt] % preload + +\setupbodyfont + [dejavu,10pt] % main font + +\mainlanguage + [en] + +\setuptyping + [\v!typing] + [\c!bodyfont=dejavu-condensed] + +\setupwhitespace + [\v!big] + +\setuptolerance + [\v!verytolerant,\v!stretch] + +\setuplayout + [\c!backspace=3.5cm, + \c!leftmargin=1.75cm, + \c!rightmargin=0cm, + \c!margindistance=.5cm, + \c!leftedgedistance=.25cm, + \c!rightedgedistance=.5cm, + \c!edge=1.5cm, + \c!width=15.55333cm, % 13.998cm at 9pt => 15.55333 at 10pt + \c!topspace=2cm, + \c!header=1.25cm, + \c!footer=1.25cm, + \c!height=middle, + \c!style=\ss] + +\setuppagenumbering + [\c!location=] + +\setuppagenumbering + [\c!alternative={\v!doublesided,\v!singlesided}] + +\setupfootertexts + [\v!edge] + [][\pagenumber] + +\setupfootertexts + [\v!margin] + [\filename{\documentvariable{file}}][] + [\filename{\documentvariable{file}}][] + +\setupfootertexts + [\v!text] + [\CONTEXT] + [\documentvariable{title}] + +\setupheadertexts + [\v!text] + [] + [\documentvariable{subtitle}] + +\setupinmargin + [\c!location=\v!left] + +\setupheads + [\c!alternative=\v!inmargin] + +\setuphead + [\v!chapter] + [\c!style=\bfc, + \c!page=\v!right, + \c!header=\v!empty] + +\setuphead + [\v!section] + [\c!style=\bfb, + \c!page=\v!right] + +\setuphead + [\v!subsection] + [\c!style=\bfa] + +\setuplist + [\v!chapter] + [\c!style=\v!bold, + \c!after=\blank] + +\setupcombinedlist + [\v!content] + [\c!width=3em, + \c!aligntitle=\v!yes] + +\setupregister + [\v!index] + [\c!balance=\v!yes, + \c!indicator=\v!no] + +\setupinteraction + [\c!state=\v!start, + \c!color=, + \c!contrastcolor=, + \c!style=] + +% modes + +\doifmode {nocolor} { + + \setupcolors + [\c!conversion=\v!always] + +} + +\doifmode {singlesided} { + + \setuppagenumbering + [\c!alternative=\v!singlesided] + + \setupfootertexts + [\v!margin] + [\filename{\documentvariable{file}}][] + +} + +% bonus + +\usemodule + [abr-02] + +% another one + +\dontcomplain + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-mod-02.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-mod-02.mkiv new file mode 100644 index 00000000000..37e3d2f143e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-mod-02.mkiv @@ -0,0 +1,24 @@ +%D \module +%D [ file=s-mod-02, +%D version=very-old, +%D title=\CONTEXT\ Style File, +%D subtitle=Documentation Screen Environment, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\startmode[nocode] + + % \definieerbuffer[definition] % ignore + + \def\startdefinition#1\stopdefinition{} + +\stopmode + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pages-statistics.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-pages-statistics.mkiv new file mode 100644 index 00000000000..375dd9949f2 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pages-statistics.mkiv @@ -0,0 +1,134 @@ +%D \module +%D [ file=s-pages-statistics, % s-otr-01, +%D version=2012.02.02, +%D title=\CONTEXT\ Style File, +%D subtitle=Page Statistics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\defineframed + [otrstatistics] + [\c!offset=\bodyfontsize, + \c!background=\v!color, + \c!strut=\v!no, + \c!backgroundcolor=white, + \c!frame=\v!off, + \c!align=\v!middle] + +\definecombination + [otrstatistics] + [\c!nx=2, + \c!ny=2, + \c!location=\v!top] + +% expansion is neeed because tabulate sets some penalties + +\startsetups system:page:otr:statistics + \normalexpanded { + \startcombination[otrstatistics] { + \otrstatistics { + \starttabulate[|Tw(10em)|Trw(8em)|] + \NC \string\textwidth \NC \the\textwidth \NC \NR + \NC \string\textheight \NC \the\textheight \NC \NR + \NC \string\lineheight \NC \the\lineheight \NC \NR + \NC \string\strutheight \NC \strutheight \NC \NR + \NC \string\strutdepth \NC \strutdepth \NC \NR + % \NC \string\vsize \NC \the\vsize \NC \NR + \NC \string\topskip \NC \the\topskip \NC \NR + \stoptabulate + } + } {} + { + \otrstatistics { + \starttabulate[|Tw(10em)|Trw(8em)|] + \NC \string\pagegoal \NC \the\pagegoal \NC \NR + \NC \string\pagetotal \NC \the\pagetotal \NC \NR + \NC \string\pagedepth \NC \the\pagedepth \NC \NR + \NC \string\pageshrink \NC \the\pageshrink \NC \NR + \NC \string\pagestretch \NC \the\pagestretch \NC \NR + \NC \string\pagefilstretch \NC \the\pagefilstretch \NC \NR + \NC \string\pagefillstretch \NC \the\pagefillstretch \NC \NR + \NC \string\pagefilllstretch \NC \the\pagefilllstretch \NC \NR + \stoptabulate + } + } {} + { + \otrstatistics { + \starttabulate[|Tw(10em)|Trw(8em)|] + \NC \string\widowpenalty \NC \the\widowpenalty \NC \NR + \NC \string\clubpenalty \NC \the\clubpenalty \NC \NR + \NC \string\displaywidowpenalty \NC \the\displaywidowpenalty \NC \NR + \NC \string\brokenpenalty \NC \the\brokenpenalty \NC \NR + \NC \string\interlinepenalty \NC \the\interlinepenalty \NC \NR + \stoptabulate + } + } {} + { + \otrstatistics[\c!foregroundcolor=darkred] { + \starttabulate[|Tw(10em)|Trw(8em)|] + \NC page \NC \the\realpageno \NC \NR + \NC delta \NC \the\dimexpr\pagegoal-\pagetotal\relax \NC \NR + \stoptabulate + } + } {} + \stopcombination + } +\stopsetups + +\defineoverlay + [system:page:otr:statistics] + [{\framed + [\c!offset=\bodyfontsize, + \c!background=\v!color, + \c!strut=\v!no, + %\c!frame=\v!off, + \c!framecolor=white, + \c!frameoffset=\onepoint, + \c!rulethickness=2\onepoint, + \c!backgroundcolor=darkblue, + \c!align=\v!middle] + {\forgetall + \insidefloattrue + \setups{system:page:otr:statistics}}}] + +\unexpanded\def\page_one_command_package_show_state_indeed + {\scratchheight\ht\b_page_one_contents + \scratchdepth \dp\b_page_one_contents + \setbox\b_page_one_contents\vbox\framed + [\c!offset=\v!overlay, + \c!framecolor=darkred, + \c!rulethickness=\onepoint, + \c!background={\v!foreground,system:page:otr:statistics}] + {\lower\scratchdepth\box\b_page_one_contents}% + \ht\b_page_one_contents\scratchheight + \dp\b_page_one_contents\scratchdepth} + +\let\page_one_command_package_show_state\relax + +\unexpanded\def\showpageproperties + {\let\page_one_command_package_show_state\page_one_command_package_show_state_indeed} + +\protect + +\continueifinputfile{s-pages-statistics.mkiv} + +\setupbodyfont[dejavu,11pt] \dontcomplain \showpageproperties + +\starttext + +\dorecurse {100} { \input tufte + + \startitemize[packed,intro] + \startitem test \stopitem \startitem test \stopitem + \startitem test \stopitem \startitem test \stopitem + \stopitemize +} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-physics-units.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-physics-units.mkiv new file mode 100644 index 00000000000..50adc801431 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-physics-units.mkiv @@ -0,0 +1,30 @@ +%D \module +%D [ file=s-physics-units, % s-phy-01, +%D version=2011-11-24, +%D title=\CONTEXT\ Modules, +%D subtitle=Physics Units, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[physics-units] + +\registerctxluafile{s-physics-units}{} + +\installmodulecommandluasingle \showunits {moduledata.physics.units.showlist} + +\stopmodule + +\continueifinputfile{s-physics-units.mkiv} + +\usemodule[art-01] + +\starttext + + \showunits + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pre-17.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-17.mkiv new file mode 100644 index 00000000000..9c46b4ed7a4 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-17.mkiv @@ -0,0 +1,408 @@ +%D \module +%D [ file=s-pre-17, +%D version=1999.08.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 17, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setupbodyfont + [dejavu,11pt,ss] + +\setupsystem + [random=medium] + +\setupbackgrounds + [state=repeat] + +\setupbackgrounds + [page] + [background={page,forward}] + +\setupbackgrounds + [text][text] + [background=blowdown] + +\setupinteraction + [state=start, +% click=off, + color=TitleColor, + contrastcolor=TitleColor] + +\setupinteractionscreen + [option=max] + +\setuptolerance + [verytolerant,stretch] + +\definecolor [BackColor] [s=.30] +\definecolor [PageColor] [g=1] +\definecolor [FrameColor] [r=1] +\definecolor [TitleColor] [y=1] +\definecolor [ArrowColor] [b=1] + +\defineoverlay [title] [\useMPgraphic{title}] +\defineoverlay [page] [\useMPgraphic{page}] +\defineoverlay [blowup] [{\hboxreference[whatever:\CurrentBlaBla]{\overlaybutton{whatever:\CurrentBlaBla}}}] +\defineoverlay [blowdown] [{\hboxreference[page:\realfolio]{\overlaybutton{page:\realfolio}}}] +\defineoverlay [forward] [\overlaybutton{forward}] + +\startMPinclusions + input "mp-abck.mpiv" ; +\stopMPinclusions + +\startMPpositiongraphic{mppos:connection} + path pa, pb, pc ; pair ca, cb ; + initialize_box(\MPpos{\MPvar{self}}) ; pa := pxy ; ca := cxy ; + initialize_box(\MPpos{\MPvar{prev}}) ; pb := pxy ; cb := cxy ; + pickup pencircle scaled .5pt ; + pa := pa enlarged 10pt ; + pb := pb enlarged 10pt ; + for i=1 upto 10 : + draw pa randomized 20pt withcolor \MPcolor{FrameColor} ; + endfor ; + if \MPp{\MPvar{prev}} > 0 : + pair a, b, c, d ; + for i=1 upto 25 : + a := .5[ulcorner pa,urcorner pa] randomized (10pt,10pt) ; + b := .5[llcorner pb,lrcorner pb] randomized (20pt,10pt) ; + c := .5[a,b] rotatedaround(a,-25) randomized (5pt,5pt) ; + d := .5[a,b] rotatedaround(a,+25) randomized (5pt,5pt) ; + draw (a--b) withcolor \MPcolor{ArrowColor} ; + draw (d--a--c) withcolor \MPcolor{ArrowColor} ; + endfor ; + fi ; + anchor_box(\MPanchor{\MPvar{self}}) ; +\stopMPpositiongraphic + +\startuseMPgraphic{title} + pickup pencircle scaled .5pt ; + for i=1 upto 10 : + draw fullsquare + xyscaled(OverlayWidth,OverlayHeight) + enlarged 10pt randomized 20pt + withcolor \MPcolor{TitleColor} ; + endfor ; +\stopuseMPgraphic + +\startuseMPgraphic{page} + StartPage ; + pickup pencircle scaled .5pt ; + fill Page withcolor \MPcolor{BackColor} ; + for i=1 upto 20 : + draw Page enlarged -50pt randomized 50pt withcolor \MPcolor{PageColor} ; + endfor ; + StopPage ; +\stopuseMPgraphic + +\newcounter\CurrentBlaBla + +\defineframedtext + [ZoomText] + [before=, + after=, + width=fit, + align=flushleft, + frame=off, + foregroundcolor=white] + +\starttexdefinition StartText + \begingroup + \getrandomdimen\scratchdimen{250pt}{350pt} + \edef\TextWidth{\the\scratchdimen} + \setbox\scratchbox\hbox\bgroup + \hsize\TextWidth + \ZoomText\bgroup +\stoptexdefinition + +\starttexdefinition StartTextSimple + \begingroup + \setbox\scratchbox\hbox\bgroup + \framed [ + frame=off, + foregroundcolor=white + ] + \bgroup +\stoptexdefinition + +\starttexdefinition StopTextSimple + \StopText +\stoptexdefinition + +\starttexdefinition StopText + \egroup + \egroup + \doglobal\increment\CurrentBlaBla + \let\PrevBlaBla\CurrentBlaBla \doglobal\decrement\PrevBlaBla + \let\NextBlaBla\CurrentBlaBla \doglobal\increment\NextBlaBla + \setMPpositiongraphic { + connection:\CurrentBlaBla + }{ + mppos:connection + }{ + seed=\CurrentBlaBla, + prev=connection:\PrevBlaBla, + next=connection:\NextBlaBla + } + \hbox to 600pt \bgroup + \setupinteraction[focus=fitr] + \getrandomdimen\scratchdimen{50pt}{75pt} + \hskip0pt plus \scratchdimen minus \scratchdimen + \hpos { + connection:\CurrentBlaBla + }{ + \framed [ + frame=off, + offset=overlay, + backgroundoffset=50pt, + background=blowup + ] { + \box\scratchbox + } + } + \getrandomdimen\scratchdimen{50pt}{75pt} + \hskip0pt plus \scratchdimen minus \scratchdimen + \egroup + \getrandomdimen\scratchdimen{75pt}{125pt} + \vskip\scratchdimen + \endgroup +\stoptexdefinition + +\dontcomplain + +\disablemode[SpreadPage] + +\starttexdefinition StartPage #1 + \doglobal\increment(\CurrentBlaBla,100)% + \setvariables[StartPage][title={#1}] + \setbox\scratchbox\hbox\bgroup + \valign\bgroup + \ignorespaces + \alignmark\alignmark + \vss + \cr +\stoptexdefinition + +\starttexdefinition StopPage + \cr + \egroup + \egroup + \setbox\scratchbox\vbox\bgroup + \vskip100pt + \doifelsemode {SpreadPage} { + \hbox spread 200pt + } { + \hbox to \wd\scratchbox + } + \bgroup + \setupinteraction[focus=fitr] + \hss + \switchtobodyfont[big]% + \bfd + \doglobal\increment\CurrentBlaBla + \setupinterlinespace + \hpos { + title:\realfolio + }{ + \framed [ + frame=off, + offset=overlay, + backgroundoffset=50pt, + background=blowup + ] { + \framed [ + frame=off, + align=middle, + foregroundcolor=white, + background=title + ] { + \getvariable{StartPage}{title} + } + } + } + \hss + \egroup + \vskip100pt + \box\scratchbox + \egroup + \normalexpanded { + \definepapersize [ + MasterPage + ] [ + width=\the\dimexpr\wd\scratchbox+100pt\relax, + height=\the\dimexpr\ht\scratchbox+\dp\scratchbox+100pt\relax + ] + } + \setuppapersize + [MasterPage] + [MasterPage] + \setuplayout [ + topspace=25pt, + backspace=25pt, + width=middle, + header=0pt, + footer=0pt, + height=middle + ] + \centerbox { + \box\scratchbox + } + \page +\stoptexdefinition + +\starttexdefinition StartTopic #1 + \removeunwantedspaces + \cr + \doglobal\increment(\CurrentBlaBla,100)% + \vbox\bgroup + \vskip100pt + \bgroup + \definecolor[FrameColor][TitleColor] + \switchtobodyfont[big] + \bfd + \setupinterlinespace + \StartTextSimple + \ignorespaces + #1 + \removeunwantedspaces + \StopTextSimple + \vskip25pt + \egroup +\stoptexdefinition + +\starttexdefinition StopTopic + \vskip-\lastskip + \vskip100pt + \egroup + \ignorespaces +\stoptexdefinition + +\starttexdefinition TitlePage #1 + \begingroup + \def\\{\vskip1ex\bfc\def\\{\vskip1ex\bfb}} + \enablemode[SpreadPage] + \StartPage{#1} + \StopPage + \endgroup +\stoptexdefinition + +\continueifinputfile{s-pre-17.mkiv} + +\starttext + +\nopdfcompression + +\TitlePage{About Text\\Today's Talk\\Hans Hagen} + +\StartPage{The First Page} + + \StartTopic{Some Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input knuth \StopText + \StopTopic + + \StartTopic{Another Text} + \StartText \input tufte \StopText + \StartText \input zapf \StopText + \StartText \input knuth \StopText + \StopTopic + + \StartTopic{Some More Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StopTopic + + \StartTopic{Some Text Again} + \StartText \input tufte \StopText + \StartText \input zapf \StopText + \StartText \input knuth \StopText + \StartText \input tufte \StopText + \StopTopic + +\StopPage + +\StartPage{The Second Page} + + \StartTopic{Some Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StopTopic + + \StartTopic{Another Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StopTopic + + \StartTopic{Some Nice Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input tufte \StopText + \StopTopic + + \StartTopic{Some Funny Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StopTopic + + \StartTopic{Quite Some Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StopTopic + + \StartTopic{Even More Text} + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StopTopic + +\StopPage + +\StartPage{The Third Page} + + \StartTopic{Some Short Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StopTopic + + \StartTopic{Some Minimal Text} + \StartText \input tufte \StopText + \StartText \input zapf \StopText + \StopTopic + + \StartTopic{Some More Text} + \StartText \input tufte \StopText + \StartText \input knuth \StopText + \StartText \input zapf \StopText + \StartText \input tufte \StopText + \StartText \input tufte \StopText + \StopTopic + +\StopPage + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pre-30.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-30.mkiv new file mode 100644 index 00000000000..1be85d02b1c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-30.mkiv @@ -0,0 +1,257 @@ +%D \module +%D [ file=s-pre-30, +%D version=2006.04.25, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 30, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[streams] + +\setuppapersize + [S6] [S6] + +\setupbodyfont + [12pt,tt] + +\definemeasure[bleed][6pt] + +\definecolor[maincolor-3][r=.5,g=.2,b=.2] +\definecolor[maincolor-1][r=.2,g=.5,b=.2] +\definecolor[maincolor-2][r=.2,g=.2,b=.5] + +\definecolor[pagecolor] [s=.5] +\definecolor[resultcolor][s=1,t=.85,a=1] +\definecolor[maincolor] [maincolor-3] + +\definecolorgroup + [maingroup] + [.5:.2:.2, + .2:.5:.2, + .2:.2:.5] + +\definecolorgroup + [resultgroup] + [1:.85:.85, + .85:1:.85, + .85:.85:1] + +\def\CurrentColor{1} + +\definecolor[maincolor] [maingroup:\CurrentColor] +\definecolor[resultcolor][resultgroup:\CurrentColor] + +\def\NextColor{\ifnum\CurrentColor=3 \def\CurrentColor{1}\else\doglobal\increment\CurrentColor\fi} + +\setuplayout + [backspace=\measure{bleed}, + topspace=30pt, + bottomdistance=\measure{bleed}, + bottom=\dimexpr30pt-\measure{bleed}\relax, + header=0pt, + footer=0pt, + topdistance=\measure{bleed}, + top=\dimexpr30pt-\measure{bleed}\relax, + width=middle, + height=middle] + +\setuptop + [before=\vfill, + after=\vfill, + strut=yes] + +\setupbackgrounds + [text] + [backgroundoffset=\measure{bleed}, + background=color, + backgroundcolor=maincolor] + +\setupbackgrounds + [page] + [background=color, + backgroundcolor=pagecolor] + +\setupcolors + [state=start, + textcolor=white] + +\setuphead + [chapter] + [style=\ttd] + +\setuphead + [section] + [style=\ttd] + +\defineviewerlayer + [result] + [state=stop] + +\definelayer + [result] + +\setuplayer + [result] + [width=\textwidth, + height=\textheight] + +\setupbackgrounds + [text] + [background={color,toggle,foreground,result}] + +\setupinteraction + [state=start, + click=no, + menu=on, + color=white, + contrastcolor=white, + closepageaction=HideLayer{result}, + openpageaction=HideLayer{result}] + +% We add a dummy color switch so that each page has at least one +% transparency; else acrobat will render the pages differently +% bug in 6 and 7). + +\startinteractionmenu[bottom] +% \color[resultcolor]{ }% + \hfill + \got [content] content \\ + \got [previouspage] previous \\ + \got [nextpage] next \\ + \got [ToggleLayer{result}] result \\ + \got [CloseDocument] close \\ +\stopinteractionmenu + +\setuphead + [section] + [placehead=no, + incrementnumber=list] + +\setuplist + [section] + [alternative=f] + +\defineoverlay + [toggle] + [\overlaybutton{ToggleLayer{result}}] + +\definestreamlayer + [resultstream] + +\startsetups streamlayer:resultstream:flush + \setlayer + [result] + [preset=middlebottom, + hoffset=\measure{bleed}, +% voffset=-\measure{bleed}] + voffset=\measure{bleed}] + {\startviewerlayer[result]% +% \framed +% [offset=overlay, +% frame=off, +% background=color, +% backgroundoffset=1\dimexpr\measure{bleed}\relax, +% backgroundcolor=maincolor] + {\framed + [offset=overlay, + frame=off, + foregroundcolor=maincolor, + background=color, + backgroundoffset=1\dimexpr\measure{bleed}\relax, + backgroundcolor=resultcolor] + {\tightlayer[\currentstreamlayer]}} + \stopviewerlayer} +\stopsetups + +\startsetups show-definition + \subject{definition} + \typebuffer + \getbuffer + \page +\stopsetups + +\startsetups show-result + \startstreamlayer[resultstream] + \subject{result} + \getbuffer + \stopstreamlayer + \placestreamlayer[resultstream] + \page +\stopsetups + +\startsetups show-usage + \subject{usage} + \typebuffer + \startstreamlayer[resultstream] + \subject{result} + \getbuffer + \stopstreamlayer + \placestreamlayer[resultstream] + \page +\stopsetups + +\startsetups show-usage-lines + \subject{usage} + \typebuffer + \startstreamlayer[resultstream] + \subject{result} + \startlines + \getbuffer + \stoplines + \stopstreamlayer + \placestreamlayer[resultstream] + \page +\stopsetups + +\startsetups show-contents + \startcolumns[n=3] + \placelist[section][criterium=text] + \stopcolumns + \pagereference[content] + \page + \NextColor +\stopsetups + +\def\TitlePage#1% + {\title{#1} + \setups{show-contents}} + +\def\StartSample#1% + {\starttext + \page + \section{#1} + \setuptoptexts[][\processedfile\enspace:\enspace\lowercase{#1}]} + +\def\StopSample + {\page + \setuptoptexts[][] + \stoptext + \NextColor} + +\endinput + +\usemodule[pre-30] + +% \TitlePage{Howling to the moon} + +\StartSample{Basics} + +\startbuffer +\lua{a = 1.5 ; b = 1.8 ; c = a*b ; context(c) ;} + +\startlua + a = 1 + b = 2 + c = a*b + context(c) +\stoplua +\stopbuffer + +\setups{show-usage} + +\StopSample diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pre-60.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-60.mkiv new file mode 100644 index 00000000000..70f8978b02c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-60.mkiv @@ -0,0 +1,212 @@ +%D \module +%D [ file=s-pre-60, +%D version=2004.03.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 60, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% use lua instead of global mess + +\unprotect + +\startmode[paper,print] + \let\StartSteps\relax + \let\StopSteps \relax + \let\FlushStep \relax + \let\ResetStep \relax + \let\StartBusy \relax + \let\StopBusy \relax + \endinput +\stopmode + +\newcount\c_module_pre_steps_current +\newcount\c_module_pre_steps_maximum +\newcount\c_module_pre_steps_nesting_step +\newcount\c_module_pre_steps_nesting_steps +\newcount\c_module_pre_steps_nesting_busy + +\def\StepCounter {\the\c_module_pre_steps_current} +\def\StepMaximum {\the\c_module_pre_steps_maximum} +\def\StepLayer {step:\the\c_module_pre_steps_current} +\def\NextStepLayer {step:\the\numexpr\c_module_pre_steps_current+\plusone\relax} +\def\FirstStepLayer{step:1} + +\useJSscripts[stp] + +\startsetups[set-stepper] + + \ifnum\getvariable{stepper}{nofsteps}>\c_module_pre_steps_maximum + + \dostepwiserecurse {\numexpr\c_module_pre_steps_maximum+\plusone\relax} {\getvariable{stepper}{nofsteps}} {1} { + \doifnotmode{nosteps,nostep} { + \expanded{\defineviewerlayer[step:\recurselevel][state=stop,scope=global]} + } + } + + \global\c_module_pre_steps_maximum\getvariable{stepper}{nofsteps}\relax + + \fi + +\stopsetups + +\setvariables + [stepper] + [set=\setups{set-stepper}, + nofsteps=50] + +\defineviewerlayer[step:busy][state=start] + +\definereference [SetupStepper] [JS(SetupStepper{step,\StepMaximum})] +\definereference [ResetStepper] [JS(ResetStepper)] +\definereference [CheckStepper] [JS(CheckStepper{\StepCounter})] +\definereference [InvokeStepper] [JS(InvokeStepper)] + +% todo: roll back blank + +\unexpanded\def\ResetStep + {\iftrialtypesetting\else + \global\c_module_pre_steps_current\zerocount + \fi} + +\unexpanded\def\NextStep + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_current\plusone + \fi} + +\unexpanded\def\PrevStep + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_current\minusone + \fi} + +\unexpanded\def\FlushStep + {\iftrialtypesetting\else + \StopStep + \NextStep + \StartStep + \fi} + +\unexpanded\def\StartStep + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_nesting_step\plusone + \ifcase\c_module_pre_steps_nesting_step\or + \startviewerlayer[\StepLayer]% + \fi + \fi + \ignorespaces} + +\unexpanded\def\StopStep + {\removeunwantedspaces + \iftrialtypesetting\else + \ifcase\c_module_pre_steps_nesting_step\or + \stopviewerlayer + \fi + \global\advance\c_module_pre_steps_nesting_step\minusone + \fi} + +\unexpanded\def\StartSteps + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_nesting_steps\plusone + \ifcase\c_module_pre_steps_nesting_steps\or + \ResetStep + \NextStep + \StartStep + \fi + \fi} + +\unexpanded\def\StopSteps + {\iftrialtypesetting\else + \ifcase\c_module_pre_steps_nesting_steps\or + \StopStep + \PrevStep + \fi + \global\advance\c_module_pre_steps_nesting_steps\minusone + \fi} + +\unexpanded\def\StartBusy + {\iftrialtypesetting\else + \global\advance\c_module_pre_steps_nesting_busy\plusone + \ifcase\c_module_pre_steps_nesting_busy\or + \startviewerlayer[step:busy] + \fi + \fi + \ignorespaces} + +\unexpanded\def\StopBusy + {\removeunwantedspaces + \iftrialtypesetting\else + \ifcase\c_module_pre_steps_nesting_busy\or + \stopviewerlayer + \fi + \global\advance\c_module_pre_steps_nesting_busy\minusone + \fi} + +%D Handy: + +\unexpanded\def\StartLocalSteps + {\ResetStep} + +\unexpanded\def\StopLocalSteps + {} + +\unexpanded\def\StartLocalStep + {\NextStep + \StartStep} + +\unexpanded\def\StopLocalStep + {\StopStep} + +\appendtoks + \ResetStep +\to \everyaftershipout + +\setupinteraction + [%openaction=SetupStepper, + closeaction=ResetStepper, + openpageaction=CheckStepper, + closepageaction=ResetStepper] + +\defineoverlay[invoke][\overlaybutton{InvokeStepper}] + +\setupbackgrounds + [text] + [background=invoke] + +% bonus + +\useMPlibrary[nav] + +\definepalet + [navplus] + [attach=interactioncolor, + comment=interactioncolor] + +\setupcomment + [symbol={comment-normal,comment-down}, + textlayer=\StepLayer, + option=buffer, + height=\textheight, + width=\textwidth, + margin=0pt] + +\setupattachments + [symbol={attach-normal,attach-down}, + textlayer=\StepLayer] + +%D used as (given some definitions): +%D +%D \starttyping +%D \StartLocalSteps +%D \startcombination[both] +%D {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {} +%D {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {} +%D \stopcombination +%D \StopLocalSteps +%D \stoptyping + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pre-69.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-69.mkiv new file mode 100644 index 00000000000..cc6af9ad38f --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-69.mkiv @@ -0,0 +1,336 @@ +%D \module +%D [ file=s-pre-69, +%D version=2010.04.28, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 69, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\setuppapersize[S6][S6] +\setuppapersize[SM][SM] + +\usemodule + [abr-01,pre-60] + +\setupinteraction + [state=start, + contrastcolor=white, + color=white, + click=no] + +\setuplayout + [location=middle, + topspace=60pt, + bottomspace=80pt, + backspace=80pt, + header=0pt, + footer=0pt, + width=middle, + height=middle] + +\setupcolors + [textcolor=white] + +\setupbodyfont[euler] + +\definecolor[maincolor] [blue] +\definecolor[extracolor][green] + +% \definecolor[maincolor] [red] +% \definecolor[extracolor][blue] + +\startMPinitializations + if unknown MyColor[1] : + color MyColor[] ; + MyColor[1] := transparent(1,.25,\MPcolor{maincolor}) ; + MyColor[2] := transparent(1,.25,\MPcolor{extracolor}) ; + + picture MySoFar ; MySoFar := nullpicture ; + path MyLastOne ; MyLastOne := origin -- cycle ; + color MyPageColor ; MyPageColor := MyColor[1] ; + path MyLeftSteps, MyRightSteps ; + boolean MyPageDone ; MyPageDone := false ; + + vardef MySmallShape(expr parent) = + path p ; p := boundingbox parent ; + p := boundingbox parent ; + numeric w, h ; w := bbwidth(p) ; h := bbheight(p) ; + urcorner p shifted (-uniformdeviate w/4,0) -- + lrcorner p shifted (0,uniformdeviate h/4) -- + llcorner p shifted (uniformdeviate w/4,0) -- + ulcorner p shifted (0,-uniformdeviate h/4) -- cycle + enddef ; + + vardef MyShape(expr parent) = + path p ; p := boundingbox parent ; + if MyPageDone : + MyPageDone := false ; + urcorner p shifted (-EmWidth + -uniformdeviate CutSpace/2,0) -- + lrcorner p shifted (0,EmWidth + uniformdeviate BottomSpace/2) -- + llcorner p shifted (EmWidth + uniformdeviate BackSpace/2,0) -- + ulcorner p shifted (0,-EmWidth + -uniformdeviate TopSpace/2) -- cycle + else : + MyPageDone := true ; + urcorner p shifted (0,-EmWidth + -uniformdeviate TopSpace/2) -- + lrcorner p shifted (-EmWidth + -uniformdeviate CutSpace/2,0) -- + llcorner p shifted (0,EmWidth + uniformdeviate BottomSpace/2) -- + ulcorner p shifted (EmWidth + uniformdeviate BackSpace/2,0) -- cycle + fi + enddef ; + + vardef MyMakeOne = + MyLastOne := MyShape(Page) ; + enddef ; + + vardef MyAddOne = + addto MySoFar also image(fill MyLastOne withcolor MyPageColor ; ) ; + enddef ; + + vardef MyDrawOne = + fill MyLastOne withcolor black ; + fill MyLastOne withcolor MyPageColor ; + enddef ; + + vardef MyDrawPage = + draw MySoFar ; + enddef ; + + vardef MySetSteps = + path l, r ; numeric s ; path ll[], rr[] ; path t ; + l := point 2 of MyLastOne -- point 3 of MyLastOne ; + r := point 0 of MyLastOne -- point 1 of MyLastOne ; + t := topboundary Field[Text][Text] rightenlarged TextWidth leftenlarged TextWidth ; + s := bbheight(Field[Text][Text])/LineHeight + 2 ; + t := t shifted (0,-TopSkip) ; + for i=1 upto s : + ll[i] := t intersectionpoint l ; + rr[i] := t intersectionpoint r ; + t := t shifted (0,-LineHeight) ; + endfor ; + MyLeftSteps := for i=1 upto s : ll[i] -- endfor cycle ; + MyRightSteps := for i=1 upto s : rr[i] -- endfor cycle ; + enddef ; + + vardef MyDrawText(expr txt) = + pair a ; a := (point 1 of MyLastOne) - (point 2 of MyLastOne) ; + picture p ; p := txt ; + p := p + shifted (-EmWidth,EmWidth) + shifted ulcorner txt + shifted point 1 of MyLastOne ; + p := p rotatedaround(lrcorner p, radian * tan(ypart a/xpart a)) ; + setbounds p to origin -- cycle ; + draw p ; + enddef ; + + vardef MyDrawTitle(expr txt) = + % pair a ; a := (point 2 of MyLastOne) - (point 3 of MyLastOne) ; + pair a ; a := (point 3 of MyLastOne) - (point 4 of MyLastOne) ; + picture p ; + if bbheight(txt) > bbwidth(txt) : + p := txt ysized(0.8*TextHeight) ; + else : + p := txt xsized(0.8*TextWidth) ; + fi ; + numeric d ; d := arclength(point 2 of MyLastOne -- point 3 of MyLastOne) - bbheight(p) ; + p := p + shifted (BackSpace,-d/2) + shifted -ulcorner p + shifted point 3 of MyLastOne ; + % p := p rotatedaround(ulcorner p, - radian * tan(xpart a/ypart a)) ; + % p := p rotatedaround(ulcorner p, radian * tan(ypart a/xpart a)) ; + setbounds p to origin -- cycle ; + draw p ; + enddef ; + + vardef MyDrawSteps = + s := bbheight(Field[Text][Text])/LineHeight + 2 ; + for i=1 upto s : + draw ll[i] withpen pencircle scaled 1mm ; + draw rr[i] withpen pencircle scaled 1mm ; + draw ll[i] -- rr[i] ; + endfor ; + draw Field[Text][Text] ; + enddef ; + + fi ; +\stopMPinitializations + +\startuseMPgraphic{initialization} + StartPage ; + MySoFar := image(fill Page enlarged 12pt withcolor MyPageColor) ; + MyMakeOne ; + MySetSteps ; + StopPage ; +\stopuseMPgraphic + +\appendtoks + \startnointerference + \useMPgraphic{initialization} + \stopnointerference +\to \everystarttext + +\startuseMPgraphic{page} + StartPage ; + MyDrawPage ; + MyDrawOne ; + MySetSteps ; + MyDrawTitle(textext("\getvariable{document}{title}")) ; + MyDrawText(textext("\getvariable{document}{topic}")) ; + % + % we have multiple runs when we have text + % +% MyDrawSteps ; +% MyMakeOne ; +% MySetSteps ; + StopPage ; +\stopuseMPgraphic + +\appendtoks + \startnointerference + \startMPcode + MyAddOne ; + MyMakeOne ; + MySetSteps ; + \stopMPcode + \stopnointerference +\to \everyshipout + +\defineoverlay[page][\useMPgraphic{page}] + +\startuseMPgraphic{symbol} + color cc ; cc := MyColor[2] ; + path p ; p := MySmallShape(unitsquare scaled (.6*LineHeight)) ; + fill p withcolor white ; + fill p withcolor cc ; +\stopuseMPgraphic + +\definesymbol[mysymbol][\struttedbox{\useMPgraphic{symbol}}] + +\setupitemgroup[itemize][1][symbol=mysymbol] + +\setupbackgrounds + [page] + [background=page] + +\startluacode + local texdimen = tex.dimen + function document.SetParShape() + local leftpath = metapost.getclippath("metafun","metafun","clip currentpicture to MyLeftSteps ;") + local rightpath = metapost.getclippath("metafun","metafun","clip currentpicture to MyRightSteps ;") + local shape = { } + for i=1,#leftpath do + local left = leftpath[i].x_coord + local right = rightpath[i].x_coord + local hsize = right - left - (texdimen.backspace + texdimen.cutspace)*number.dimenfactors.bp + shape[#shape+1] = string.format("%sbp %sbp",left,hsize) + end + -- print(table.serialize(shape)) + -- context.parshape(string.format("%s %s ",#shape,table.concat(shape," "))) + context("\\parshape %s %s ",#shape,table.concat(shape," ")) + end +\stopluacode + +\nopenalties \dontcomplain + +\setupwhitespace[none] + +\def\StartText#1#2% + {\starttext + \setvariable{document}{title}{\framed[frame=off,offset=0pt,align=flushleft,foregroundstyle=\tfd\setupinterlinespace]{\begstrut#1\endstrut}} + \setvariable{document}{topic}{\tfb#2} + \startstandardmakeup + % dummy page + \stopstandardmakeup + \setvariable{document}{title}{} + \setvariable{document}{topic}{}} + +\def\StopText + {\stoptext} + +\def\StartItems#1% + {\setvariable{document}{topic}{\tfb#1} + \startstandardmakeup[top=,bottom=\vss] + \startelement[items][title={#1}]% + \ctxlua{document.SetParShape()} + \StartSteps} + +\def\StopItems + {\StopSteps + \stopelement + \stopstandardmakeup} + +\def\StartItem + {\dontleavehmode + \startelement[item]% + \llap{\symbol[mysymbol]\quad}% graphic + \ignorespaces} + +\def\StopItem + {\removeunwantedspaces + \nobreak + \crlf + \stopelement + \crlf + \FlushStep} + +\def\ShapeParagraph + {\ctxlua{document.SetParShape()}} + +% no parshape yet + +\def\StartParagraphs#1% + {\setvariable{document}{topic}{\tfb#1} + \startstandardmakeup[top=,bottom=\vss] + %\ctxlua{document.SetParShape()} + \startelement[paragraphs]% + \StartSteps} + +\def\StopParagraphs + {\StopSteps + \stopelement + \stopstandardmakeup} + +\def\StartParagraph + {\startelement[paragraph]} + +\def\StopParagraph + {\par + \stopelement + \FlushStep} + +% experiment .. likely to change + +\setelementexporttag[items] [nature][display] +\setelementexporttag[item] [nature][mixed] +\setelementexporttag[paragraphs][nature][display] +\setelementexporttag[paragraph] [nature][mixed] + +\continueifinputfile{s-pre-69.mkiv} + +% finetuning: \StartText{\TEX\ and Reality\vskip2exClashing Mindsets?\vskip1ex}{Bacho\TEX, May 1, 2010} + +\StartText{Just\\A Demo}{Bacho\TEX, May 1, 2010} + +\StartItems{Quote from Tufte and Ward} + \StartItem + \input tufte + \StopItem + \StartItem + \input ward + \StopItem +\StopItems + +% \dorecurse{20}{ +% \ctxlua{document.SetParShape()} +% \input tufte +% \page +% } + +\StopText + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pre-70.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-70.mkiv new file mode 100644 index 00000000000..2c8bb2d2648 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-70.mkiv @@ -0,0 +1,176 @@ +%D \module +%D [ file=s-pre-70, +%D version=2008.04.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 70, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D At the cost of more runtime and a larger output file, we +%D turn on randomization. The instances are cached in the +%D MkIV cache, so successive runs use the same shapes. + +% \usemodule[punk] \usetypescript[punk] \setupbodyfont[punk,20pt] +% +% \EnableRandomPunk + +\setupbodyfont[punknova,20pt] % we now use the opentype variant + +%D We use the regular screen size paper and layout setup. + +\setuppapersize + [S6][S6] + +\setuplayout + [topspace=30pt, + backspace=30pt, + width=middle, + height=fit, + header=0pt, + footer=0pt, + bottomdistance=24pt, + bottom=30pt, + bottom=18pt, + top=0pt] + +\setupinterlinespace + [top=height, + line=1.25\bodyfontsize] + +\setupcolors + [state=start, + textcolor=white] + +\setupinteraction + [state=start, + %click=off, + menu=on] + +%D We predefine a few palets. Of course you can define more. + +\definecolor[punkblue] [r=.4,b=.8,g=.4] +\definecolor[punkgreen] [r=.4,b=.4,g=.8] +\definecolor[punkred] [r=.8,b=.4,g=.4] +\definecolor[punkyellow][r=.6,g=.6,b=.2] + +\definepalet [punk-one] [textcolor=punkblue,pagecolor=punkgreen] +\definepalet [punk-two] [textcolor=punkred,pagecolor=punkyellow] +\definepalet [punk-three] [textcolor=punkblue,pagecolor=punkyellow] +\definepalet [punk-one-reverse] [textcolor=punkgreen,pagecolor=punkblue] +\definepalet [punk-two-reverse] [textcolor=punkyellow,pagecolor=punkred] +\definepalet [punk-three-reverse] [textcolor=punkyellow,pagecolor=punkblue] + +\setuppalet[punk-one] + +%D We use a few backgrounds. The hyperlink that invokes the +%D stepper is hooked into the text background. + +\definelayer + [page] + [width=\paperwidth, + height=\paperheight] + +\setupbackgrounds + [page] + [background={color,page}, + backgroundcolor=pagecolor, + setups=pagestuff] + +\setupbackgrounds + [text] + [background={color,invoke}, + backgroundoffset=12pt, + backgroundcolor=textcolor] + +%D We need different symbols for itemized lists. + +\definesymbol[1][\hbox{\lower1ex\hbox{*}}] +\definesymbol[2][\endash] +\definesymbol[3][\letterhash] +\definesymbol[3][>] + +%D We don't want these reversed clicked areas in Acrobat. + +\setupinteraction + [click=no, + color=white, % pagecolor, + contrastcolor=white] % pagecolor, + +%D We define a rather simple navigational panel at the +%D bottom + +\setupinteractionmenu + [bottom] + [color=white, % pagecolor, + contrastcolor=white, % pagecolor, + background=color, + backgroundcolor=textcolor, + frame=off, + height=24pt, + left=\hfill, + middle=\hskip12pt] + +\setupsubpagenumber + [state=start] + +\startinteractionmenu[bottom] + \starttxt + \interactionbar + [alternative=d, + symbol=yes, + color=white, + contrastcolor=textcolor] + \stoptxt + \hfilll + \startbut [previouspage] < < < \stopbut + \startbut [nextpage] > > > \stopbut +\stopinteractionmenu + +%D Instead of the normal symbols we use more punky ones. + +\startsymbolset [punk] + \definesymbol[previous] [\string<\string<] + \definesymbol[somewhere] [\string^\string^] + \definesymbol[next] [\string>\string>] +\stopsymbolset + +\setupinteraction[symbolset=punk] + +%D Because the font is rather large, we use less whitespace. + +\setuphead + [chapter] + [after={\blank[big]}] + +%D Run this file with the command: \type {context --mode=demo s-pre-70} +%D in order to get an example. + +\continueifinputfile{s-pre-70.mkiv} + +\usemodule[pre-60] % use the stepper + +\starttext + +\title {Punk for dummies} + +\dorecurse{10} { + + \title{Just a few dummy pages} + + \StartSteps + \startitemize[packed] + \startitem bla \FlushStep \stopitem + \startitem bla bla \FlushStep \stopitem + \startitem bla bla bla \FlushStep \stopitem + \startitem bla bla bla bla \FlushStep \stopitem + \stopitemize + \StopSteps + +} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pre-71.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-71.lua new file mode 100644 index 00000000000..bfa45a70578 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-71.lua @@ -0,0 +1,63 @@ +if not modules then modules = { } end modules ['steps'] = { + version = 1.001, + comment = "companion to steps.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.steps = moduledata.steps or { } +local steps = moduledata.steps + +local locations = { + 'lefttop', + 'middletop', + 'righttop', + 'middleleft', + 'middle', + 'middleright', + 'leftbottom', + 'middlebottom', + 'rightbottom', +} + +local done, current, previous, n + +function steps.reset_locations() + done, current, previous, n = table.tohash(locations,false), 0, 0, 0 +end + +function steps.next_location(loc) + previous = current + n = n + 1 + loc = loc and loc ~= "" and tonumber(loc) + while true do + current = loc or math.random(1,#locations) + if not done[current] then + done[current] = true + break + end + end +end + +function steps.current_location() + context(locations[current] or "") +end + +function steps.previous_location() + context(locations[previous] or "") +end + +function steps.current_n() + context(current) +end + +function steps.previous_n() + context(previous) +end + +function steps.step() + context(n) +end + +steps.reset_locations() diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-pre-71.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-71.mkiv new file mode 100644 index 00000000000..38dae61dfa5 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-pre-71.mkiv @@ -0,0 +1,170 @@ +% engine=luatex + +%D \module +%D [ file=s-pre-71, +%D version=2008.08.05, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment 71, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D I might improve this module so consider it experimental. + +% \enablemode[numbers] +% \enablemode[paper] + +\usemodule[pre-60,abr-02] + +\registerctxluafile{s-pre-71}{} + +\setupinteraction[state=start,click=off] + +\definepapersize[wide][width=900pt,height=600pt] + +\setuppapersize[wide][wide] + +\setuplayout[page] + +% \setupbodyfont[15pt] + +\usetypescriptfile[type-hgz] +\usetypescript[palatino-informal] +\setupbodyfont[palatino-informal,15pt] + +\setupsorting[logo][style=] + +\startnotmode[paper] + \setupbackgrounds[page][background=color,backgroundcolor=black] +\stopnotmode + +\TransparencyHack + +\definelayer[page][width=\paperwidth,height=\paperheight] + +\definecolor[TopicColor-1][r=.3,g=.4,b=.5] +\definecolor[TopicColor-2][r=.3,g=.5,b=.4] +\definecolor[TopicColor-3][r=.4,g=.3,b=.5] +\definecolor[TopicColor-4][r=.4,g=.5,b=.3] +\definecolor[TopicColor-5][r=.5,g=.3,b=.4] +\definecolor[TopicColor-6][r=.5,g=.4,b=.3] +\definecolor[TopicColor-7][r=.35,g=.35,b=.6] +\definecolor[TopicColor-8][r=.6,g=.35,b=.35] +\definecolor[TopicColor-9][r=.35,g=.6,b=.35] + +\definecolor[TopicColor-0][t=.5,a=1,s=.5] +\definecolor[TopicColor] [s=1] + +\setupcolors[state=start] +\setupcolors[textcolor=TopicColor] + +\def\StartTopics + {\startstandardmakeup + \ctxlua{moduledata.steps.reset_locations()} + \doifnotmode{paper}{\StartLocalSteps}} + +\def\StopTopics + {\doifnotmode{paper}{\StopLocalSteps} + \flushlayer[page] + \stopstandardmakeup} + +\def\StartTopic + {\dosingleempty\doStartTopic} + +\def\doStartTopic[#1]% + {\doifnotmode{paper}{\NextStep} + \ctxlua{moduledata.steps.next_location("#1")} + \startnotmode[paper] + \doifnothing{#1} + {\ifcase\ctxlua{moduledata.steps.previous_n()}\else + \setlayer + [page] + [preset=\ctxlua{moduledata.steps.previous_location()}] + \bgroup + \doifnotmode{paper}{\startviewerlayer[\StepLayer]}% + \framed + [offset=20pt, + strut=no, + align=normal, + frame=off, + height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + background=color, + backgroundcolor=TopicColor-0] + {}% + \doifnotmode{paper}{\stopviewerlayer}% + \egroup + \fi} + \stopnotmode + \setlayer + [page] + [preset=\ctxlua{moduledata.steps.current_location()}] + \bgroup + \doifnotmode{paper}{\startviewerlayer[\StepLayer]}% + \framed + [offset=20pt, + strut=no, + align=\expdoifelse{#1}{}{normal}{middle,lohi}, + align=\expdoifelse{#1}{}{flushleft,verytolerant}{middle,lohi}, + frame=off, + height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + background=color, + backgroundcolor=TopicColor-\ctxlua{moduledata.steps.current_n()}] + \bgroup + \ignorespaces} + +\def\StopTopic + {\removeunwantedspaces + \egroup + \doifnotmode{paper}{\stopviewerlayer}% + \egroup + \startmode[numbers] + \setlayerframed + [page] + [preset=\ctxlua{moduledata.steps.current_location()}] + [height=\dimexpr\paperheight/3\relax, + width=\dimexpr\paperwidth/3\relax, + frame=off, + foregroundstyle=\bfa, + align={flushright,low}] + {\doifnotmode{paper}{\startviewerlayer[\StepLayer]}% + \ctxlua{moduledata.steps.step()}\kern\strutdepth + \doifnotmode{paper}{\stopviewerlayer}} + \stopmode} + +\logo [METAPOST] {MetaPost} + +\definefont[TitleFont][SansBold at 60pt] +\definefont[TempFont] [SansBold at 12pt] + +\let\StartText\starttext +\let\StopText \stoptext + +\continueifinputfile{s-pre-71.mkiv} + +\starttext + +\StartTopics + \StartTopic[1] A \StopTopic + \StartTopic[5] B \StopTopic + \StartTopic[9] C \StopTopic +\StopTopics + +\StartTopics + \StartTopic A \StopTopic + \StartTopic B \StopTopic + \StartTopic C \StopTopic + \StartTopic D \StopTopic + \StartTopic E \StopTopic + \StartTopic F \StopTopic + \StartTopic G \StopTopic + \StartTopic H \StopTopic + \StartTopic I \StopTopic +\StopTopics + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-present-tiles.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-present-tiles.mkiv new file mode 100644 index 00000000000..b68a34ef42b --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-present-tiles.mkiv @@ -0,0 +1,318 @@ +%D \module +%D [ file=s-present-tiles, % was s-pre-41 +%D version=2013.03.24, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Tiles, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The Bacho\TeX\ 2013 style. + +\setupbodyfont[pagella,14.4pt] + +\setuppapersize[S6][S6] + +\definecolor[primarycolor] [.50(darkblue,darkgreen)] +\definecolor[secondarycolor][.25(darkblue,darkyellow)] +\definecolor[mixedcolor] [s=.35] + +\setupcolors + [textcolor=white] + +\setupalign + [flushleft,nothyphenated] + +\definemeasure[layoutunit][\dimexpr\paperheight/25] + +\setuplayout + [backspace=\measured{layoutunit}, + topspace=\measured{layoutunit}, + width=middle, + height=middle, + header=0pt, + footer=0pt] + +\definelayout + [content] + [backspace=.5\measured{layoutunit}, + topspace=.5\measured{layoutunit}] + +\definemeasure [topiclistwidth] [ + (\textwidth+\backspace)/ + \ifcase\numexpr\structurelistsize\relax 1 % 0 + \or1\or1\or1\or2\or1\or3\or3\or3\or3 % 1 - 9 + \or3\or3\or3\or3\or3\or3\or4 % 10 - 16 + \or4\or4\or4\or4\or % 17 - 20 + \else5 % 21 - 25 + \fi + -\backspace +] + +\definemeasure [topiclistheight] [ + (\textheight+\topspace)/ + \ifcase\numexpr\structurelistsize\relax 1 % 0 + \or1\or2\or3\or2\or5\or2\or3\or3\or3 % 1 - 9 + \or4\or4\or4\or4\or4\or4\or4 % 10 - 16 + \or5\or5\or5\or5\or5 % 17 - 20 + \else5 % 21 - 25 + \fi + -\topspace +] + +\definemeasure [topiclistfontsize] [ + \ifcase\numexpr\structurelistsize\relax 2.5 % 0 + \or1.4\or1.4\or1.4\or1.4\or1.4\or1.4\or1.4\or1.4\or1.4 % 1 - 9 + \or1.3\or1.3\or1.3\or1.3\or1.3\or1.3\or1.3 % 10 - 16 + \or1.2\or1.2\or1.2\or1.2\or1.2 % 17 - 20 + \else1 % 21 - 25 + \fi + \bodyfontsize +] + +\definemeasure [topiclistfont] [\measured{topiclistfontsize}] +\definemeasure [topictitlefont] [1.2\measured{layoutunit}] +\definemeasure [titlepagefont] [2\measured{layoutunit}] + +\predefinefont[MyTopicTitleFont][SerifBold*default at \measure{topictitlefont}] +\predefinefont[MyTopicListFont] [SerifBold*default at \measure{topiclistfont}] + +\defineframed + [topiclistentry] + [width=\measure{topiclistwidth}, + height=\measure{topiclistheight}, + background=color, + frame=off, + foregroundstyle=MyTopicListFont, + backgroundcolor=primarycolor, + foregroundcolor=white] + +\setupwhitespace + [big] + +\setupblank + [big] + +\setupinteraction + [state=start, + color=, + contrastcolor=, + click=off] + +\definemakeup + [topic] + [standard] + [top=,bottom=] + +\definemakeup + [content] + [standard] + [top=,bottom=] + +\startsetups[topic:start] + \starttopicmakeup +\stopsetups + +\startsetups[topic:stop] + \vfill + \stoptopicmakeup +\stopsetups + +\definehead + [topic] + [chapter] + [before=, + style=MyTopicTitleFont, + page=, + number=off, + interaction=list, + beforesection=\directsetup{topic:start}, + aftersection=\directsetup{topic:stop}] + +\setuplist + [topic] + [alternative=topic, + interaction=all] + +\definelistalternative + [topic] + [alternative=horizontal, + renderingsetup=topic:list] + +\startsetups[topic:list] + \dontleavehmode + \startcurrentlistentrywrapper + \topiclistentry{\currentlistentrytitle} + \stopcurrentlistentrywrapper + \blankspace +\stopsetups + +\defineoverlay[nextpage][\overlaybutton{nextpage}] +\defineoverlay[prevpage][\overlaybutton{prevpage}] +\defineoverlay[menupage][\overlaybutton{menupage}] +\defineoverlay[homepage][\overlaybutton{homepage}] + +\setupbackgrounds + [text] + [backgroundoffset=.5\measured{layoutunit}] + +% begin of buttons + +\defineframed + [bb] + [width=\dimexpr\overlaywidth/10, + height=\dimexpr\overlayheight/10, + background=color, + foregroundstyle=\bfa, + frame=off] + +\defineframed[nb] [bb] [empty=yes] +\defineframed[rb] [bb] [backgroundcolor=white,foregroundcolor=secondarycolor] +\defineframed[db] [bb] [backgroundcolor=mixedcolor,foregroundcolor=white] + +\definepushbutton [prev] +\definepushbutton [next] +\definepushbutton [menu] +\definepushbutton [home] + +\definepushsymbol [prev] [n] [\nb{prev}] +\definepushsymbol [prev] [r] [\rb{prev}] +\definepushsymbol [prev] [d] [\db{prev}] + +\definepushsymbol [next] [n] [\nb{next}] +\definepushsymbol [next] [r] [\rb{next}] +\definepushsymbol [next] [d] [\db{next}] + +\definepushsymbol [menu] [n] [\nb{menu}] +\definepushsymbol [menu] [r] [\rb{menu}] +\definepushsymbol [menu] [d] [\db{menu}] + +\definepushsymbol [home] [n] [\nb{home}] +\definepushsymbol [home] [r] [\rb{home}] +\definepushsymbol [home] [d] [\db{home}] + +\definelayer + [buttons] + [width=\dimexpr\textwidth+\measured{layoutunit}\relax, + height=\dimexpr\textheight+\measured{layoutunit}\relax] % a setups + +\startsetups [document:buttons] + + \setlayer + [buttons] + [preset=leftbottom,offset=-.25\measured{layoutunit}] + {\pushbutton[prev][previouspage]} + + \setlayer + [buttons] + [preset=rightbottom,offset=-.25\measured{layoutunit}] + {\pushbutton[next][nextpage]} + + \setlayer + [buttons] + [preset=lefttop,offset=-.25\measured{layoutunit}] + {\pushbutton[home][homepage]} + + \setlayer + [buttons] + [preset=righttop,offset=-.25\measured{layoutunit}] + {\pushbutton[menu][menupage]} + +\stopsetups + +\defineoverlay[setbuttons][\directsetup{document:buttons}] + +% end of buttons + +\defineframed + [conclusion] + [location=low, + width=max, + align={flushleft,lohi}, + background=color, + backgroundcolor=white, + foregroundcolor=secondarycolor] + +\startsetups [document:titlepage] + + \definebodyfontenvironment + [\measure{titlepagefont}] + + \setupbackgrounds + [page] + [background={color,menupage}, + backgroundcolor=secondarycolor] + + \setupbackgrounds + [text] + [background={color,menupage}, + backgroundcolor=secondarycolor] + + \starttopicmakeup[reference=homepage] + + \switchtobodyfont[\measure{titlepagefont}] + + \let\\=\crlf + + \startalignment[flushleft] + \bf + \setupinterlinespace + \begstrut\getvariable{document}{title}\endstrut\par + \stopalignment + + \vfill + + \startalignment[flushright] + \bf + \setupinterlinespace + \begstrut\getvariable{document}{subtitle}\endstrut\par + \stopalignment + + \stoptopicmakeup + + \setupbackgrounds + [page] + [background={color,homepage}, + backgroundcolor=secondarycolor] + + \setupbackgrounds + [text] + [background={color,menupage}, + backgroundcolor=secondarycolor] + + \startcontentmakeup[reference=menupage] + + \setupalign[tolerant,stretch,paragraph] + \flexiblebaselines + \placelist[topic][criterium=text] + + \stopcontentmakeup + + \setupbackgrounds + [page] + % [background={color,menupage}, + [background={color,invoke}, + backgroundcolor=primarycolor] + + \setupbackgrounds + [text] + % [background={color,nextpage,setbuttons,buttons}, + [background={color,setbuttons,buttons}, + backgroundcolor=secondarycolor] + +\stopsetups + +\setupdocument + [before=\directsetup{document:titlepage}] + +\continueifinputfile{s-present-tiles.mkiv} + +\startdocument[title=Whatever We\\Want Here,subtitle=Whatever We\\Want There] + + \dorecurse{12}{\starttopic[title=Topic #1]\input tufte \stoptopic} + +\stopdocument diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-references-show.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-references-show.mkiv new file mode 100644 index 00000000000..72cccce54f1 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-references-show.mkiv @@ -0,0 +1,132 @@ +%D \module +%D [ file=s-references-show.mkiv, +%D version=2015.04.13, +%D title=\CONTEXT\ Style File, +%D subtitle=Reference Checking, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[references-show] + +\unprotect + +% \enabletrackers[nodes.references,nodes.destinations] % also shows areas + +\enabletrackers[nodes.references.show,nodes.destinations.show] + +\enablehiddenbackground % trick + +\edef\hiddenbackgroundlist{\hiddenbackgroundlist,trace-references} + +\defineoverlay + [trace-references] + [\directsetup{trace:references:onpage}] + +\startluacode + local pagelist = structures.references.tracedpages + + function commands.getreferencesonpage(n) + n = tonumber(n) + if n then + local pagedata = pagelist[n] + if pagedata then + context("%s references",#pagedata) + context.blank() + for i=1,#pagedata do + local details = pagedata[i] + local prefix = details[1] + local reference = details[2] + -- local internal = details[3] + -- context("%04i = %s : %s",internal,prefix == "" and "-" or prefix,reference) + context("%s : %s",prefix == "" and "-" or prefix,reference) + context.par() + end + else + context("no references") + end + else + context("no valid page") + end + end + +\stopluacode + +\definecolor + [trace:references:onpage] + [b=.5,a=1,t=.25] + +\defineframed + [trace:references:onpage] + [\c!offset=2\exheight, + %\c!foregroundstyle=\infofont, + \c!frame=\v!off, + \c!background=\v!color, + \c!backgroundcolor=trace:references:onpage, + \c!align=\v!normal] + +\startsetups trace:references:onpage + \vbox to \vsize \bgroup + \infofont + \vskip\dimexpr-\topspace-\headerheight+2\exheight\relax + \hbox to \hsize \bgroup + \doifoddpageelse\hss{\hskip\dimexpr-\cutspace+2\exheight\relax}% + \directlocalframed [ + trace:references:onpage + ] { + \ctxcommand{getreferencesonpage(\the\realpageno)} + } + \doifoddpageelse{\hskip\dimexpr-\cutspace+2\exheight\relax}\hss + \egroup + \vss + \egroup +\stopsetups + +\protect + +\continueifinputfile{s-references-show.mkiv} + +\usemodule[art-01] + +\setupinteraction + [state=start] + +\setuppagenumbering + [alternative=doublesided] + +\starttext + +\title {Contents} + +\placelist[chapter] + +\setupreferenceprefix[zero] + +\chapter[crap]{foo} + +\setupreferenceprefix[one] + +test \pagereference[whatever] + +\dorecurse{5}{ + \placefigure + [here][bar 1.#1] + {xx}{\framed{xx #1}} +} + +\setupreferenceprefix[two] + +\dorecurse{5}{ + \placefigure + [here][bar 2.#1] + {xx}{\framed{xx #1}} +} + +\in{checked}[bar 1.1] +\in{checked}[bar 2.1] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-reg-01.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-reg-01.mkiv new file mode 100644 index 00000000000..36434c30c19 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-reg-01.mkiv @@ -0,0 +1,60 @@ +%D \module +%D [ file=s-reg-01, +%D version=2005.04.25, +%D title=\CONTEXT\ Style File, +%D subtitle=Extra Regime Support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D \macros +%D {showregime} +%D +%D This code is moved from the kernel to here. (We could make it +%D auto-loadable). + +\startluacode +--[[ldx-- +<p>The following code is rather <l n='context'/> specific.</p> +--ldx]]-- + +function regimes.show(regime) + regime = regimes.synonyms[regime] or regime + local r = regimes.data[regime] + if r then + local chardata = characters.data + context.starttabulate { "|rT|T|rT|lT|lT|lT|" } + for k, v in ipairs(r) do + local chr = chardata[v] + if chr then + context.NC() context(k) + context.NC() context.getvalue(chr.contextname]) + context.NC() context("%U+05X",v) + context.NC() context(chr.contextname) + context.NC() context(chr.category) + context.NC() context(chr.description) + context.NC() context.NR() + else + -- can't happen + end + end + context.stoptabulate() + else + context("unknown regime %s",regime) + end +end +\stopluacode + +\unprotect + +\def\showregime + {\dosingleempty\doshowregime} + +\def\doshowregime[#1]% + {\ctxlua{regimes.show("#1")}} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-setups-missing.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-setups-missing.mkiv new file mode 100644 index 00000000000..53037a78db4 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-setups-missing.mkiv @@ -0,0 +1,118 @@ +% show missing translations + +\startluacode +function interfaces.show_missing(whatinterfaces) + whatinterfaces = whatinterfaces or interfaces.interfaces + local list = dofile(resolvers.find_file("mult-def.lua")) + local NC, NR, HL = context.NC, context.NR, context.HL + for k,v in table.sortedhash(list) do + context.title(k) + context.starttabulate { string.rep("|",#whatinterfaces+1) } + for i=1,#whatinterfaces do + NC() + context(whatinterfaces[i]) + end + NC() NR() HL() + for kk, vv in next, v do + if not string.find(kk,"subsub") then + local okay = true + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + if not str or (int ~= "en" and str == vv.en) then + okay = false + break + end + end + if not okay then + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + context.NC() + if not str then + -- nothing + elseif int == "en" then + context.color( { "darkgreen" }, str ) + elseif str == vv.en then + context.color( { "darkred" }, str ) + elseif int == "pe" then + context("\\righttoleft " .. str) + else + context(str) + end + end + NC() NR() + end + end + end + context.stoptabulate() + end +end + +function interfaces.show_missing_messages(whatinterfaces) + whatinterfaces = whatinterfaces or interfaces.interfaces + local list = dofile(resolvers.find_file("mult-mes.lua")) + local NC, NR, HL = context.NC, context.NR, context.HL + for k,v in table.sortedhash(list) do + context.title("message: " .. k) + context.starttabulate { "|l|" .. string.rep("pl|",#whatinterfaces) } + NC() + for i=1,#whatinterfaces do + NC() + context(whatinterfaces[i]) + end + NC() NR() HL() + local sorted = table.sortedkeys(v) + for i=1,#sorted do + local kk = sorted[i] + local vv = v[kk] + if kk ~= "files" then + local okay = true + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + if not str or (int ~= "en" and str == vv.en) then + okay = false + break + end + end + if not okay then + context.NC() + context(kk) + for i=1,#whatinterfaces do + local int = whatinterfaces[i] + local str = vv[int] + NC() + if not str then + -- nothing + elseif int == "en" then + context.color( { "darkgreen" }, str ) + elseif str == vv.en then + context.color( { "darkred" }, str ) + elseif int == "pe" then + context("\\righttoleft " .. str) + else + context(str) + end + end + NC() NR() + end + end + end + context.stoptabulate() + end +end +\stopluacode + +\starttext + +\setupbodyfont[dejavu,7pt,tt] +\setuppapersize[A4,landscape][A4,landscape] +\setuplayout[backspace=.5cm,width=middle,topspace=.5cm,height=middle,header=1cm,footer=0cm] + +\startluacode + interfaces.show_missing() -- { "en","nl" } + interfaces.show_missing_messages() -- { "en","nl" } +\stopluacode + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-sql-tables.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-sql-tables.lua new file mode 100644 index 00000000000..43410354134 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-sql-tables.lua @@ -0,0 +1,152 @@ +if not modules then modules = { } end modules ['s-languages-counters'] = { + version = 1.001, + comment = "companion to s-languages-counters.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +require("util-tpl") +require("util-sql") +require("util-sql-tracers") + +moduledata = moduledata or { } +moduledata.sql = moduledata.sql or { } +moduledata.sql.tables = moduledata.sql.tables or { } + +local context = context + +function moduledata.sql.showfields(specification) -- not that sql specific + local data = specification.data + if data and #data > 0 then + local keys = specification.order or table.sortedkeys(data[1]) + local align = specification.align + local template = "|" + if type(align) == "table" then + for i=1,#keys do + template = template .. (align[keys[i]] or "c") .. "|" + end + else + template = template .. string.rep((align or "c").. "|",#keys) + end + context.starttabulate { template } + context.NC() + for i=1,#keys do + context(keys[i]) + context.NC() + end + context.NR() + context.HL() + for i=specification.first or 1,specification.last or #data do + local d = data[i] + context.NC() + for i=1,#keys do + context(d[keys[i]]) + context.NC() + end + context.NR() + end + context.stoptabulate() + end +end + +function moduledata.sql.validpresets(presets) + local okay = true + if presets.database == "" then + context("No database given.") + context.blank() + okay = false + end + if presets.password == "" then + context("No password given") + context.blank() + okay = false + end + return okay +end + +function moduledata.sql.tables.showdefined(presets) -- key=value string | { presets = "name" } | { presets } + + if type(presets) == "string" then + local specification = interfaces.checkedspecification(presets) + if specification.presets then + presets = table.load(specification.presets) or { } + end + end + + if type(presets.presets) == "string" then + presets = table.load(presets.presets) or { } + end + + if not moduledata.sql.validpresets(presets) then + return + end + + local sql_tables = utilities.sql.tracers.gettables(presets) + + context.starttitle { title = presets.database } + + for name, fields in table.sortedhash(sql_tables) do + + context.startsubject { title = name } + + context.starttabulate { format = "|l|l|l|l|l|p|" } + context.FL() + context.NC() context.bold("field") + context.NC() context.bold("type") + context.NC() context.bold("default") + context.NC() context.bold("null") + context.NC() context.bold("key") + context.NC() context.bold("extra") + context.NC() context.NR() + context.TL() + for i=1,#fields do + local field = fields[i] + context.NC() context(field.field) + context.NC() context(field.type) + context.NC() context(field.default) + context.NC() context(field.null) + context.NC() context(field.key) + context.NC() context(field.extra) + context.NC() context.NR() + end + context.LL() + context.stoptabulate() + + context.stopsubject() + end + + context.stoptitle() + +end + +function moduledata.sql.tables.showconstants(list) + + context.starttitle { title = "Constants" } + + for name, fields in table.sortedhash(list) do + + if type(fields) == "table" and #fields > 0 then + + context.startsubject { title = name } + + context.starttabulate { format = "|l|l|" } + for i=0,#fields do + local field = fields[i] + if field then + context.NC() context(i) + context.NC() context(field) + context.NC() context.NR() + end + end + context.stoptabulate() + + context.stopsubject() + + end + + end + + context.stoptitle() + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-sql-tables.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-sql-tables.mkiv new file mode 100644 index 00000000000..4c8bcddac50 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-sql-tables.mkiv @@ -0,0 +1,30 @@ +%D \module +%D [ file=s-sql-tables, +%D version=2012.07.12, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=SQL, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[sql-tables] + +\registerctxluafile{s-sql-tables}{} + +\doifsomething {\currentmoduleparameter{method}}{ + \ctxlua{utilities.sql.setmethod("\currentmoduleparameter{method}")} +} + +\doifsomething {\currentmoduleparameter{server}} { + \ctxlua{utilities.sql.setserver("\currentmoduleparameter{server}")} +} + +\installmodulecommandluasingle \showdefinedsqltables {moduledata.sql.tables.showdefined} + +\stopmodule + + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-structure-sections.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-structure-sections.mkiv new file mode 100644 index 00000000000..daaab5abcd0 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-structure-sections.mkiv @@ -0,0 +1,80 @@ +%D \module +%D [ file=s-structure-sections, +%D version=2015.02.02, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Structure Sections, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\startluacode + local context = context + local ctx_NC, ctx_NR = context.NC, context.NR + local ctx_bold = context.bold + + structures.tracers = structures.tracers or { } + + function structures.tracers.showsections() + + local list = structures.sections.registered + local keys = table.keys(list) + table.sort(keys,function(a,b) + local la, lb = list[a].level, list[b].level + if la == lb then + return a < b + else + return la < lb + end + end) + context.start() + context.switchtobodyfont { "tt" } + context.starttabulate { "||c||||" } + context.FL() + ctx_NC() ctx_bold("name") + ctx_NC() ctx_bold("level") + ctx_NC() ctx_bold("parent") + ctx_NC() ctx_bold("section") + ctx_NC() ctx_bold("coupling") + ctx_NC() context.NR() + context.ML() + for i=1,#keys do + local k = keys[i] + local v = list[k] + ctx_NC() ctx_bold(k) + ctx_NC() context(v.level) + ctx_NC() context(v.parent) + ctx_NC() context(v.section) + ctx_NC() context(v.coupling) + ctx_NC() context.NR() + end + context.LL() + context.stoptabulate() + context.stop() + + end +\stopluacode + + +\starttexdefinition showstructuresections + + % no settings yet + + \ctxlua{structures.tracers.showsections()} + +\stoptexdefinition + +\protect + +\continueifinputfile{s-structure-sections.mkiv} + +\starttext + + \showstructuresections + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-syntax.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-syntax.mkiv new file mode 100644 index 00000000000..96312f77179 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-syntax.mkiv @@ -0,0 +1,96 @@ +%D \module +%D [ file=s-syntax, % was: s-syn-01, +%D version=0000.00.00, +%D title=\CONTEXT\ Style File, +%D subtitle=Preliminary Syntax Stuff, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is needed for the \METAFUN\ manual: quite old code that I would do +%D differently nowadays. + +\unprotect + +\unexpanded\def\module_syntax_Indent #1{\ifvmode\noindent\hbox to 2em{\hss#1}\else#1\fi} +\unexpanded\def\module_syntax_Sugar #1{\removeunwantedspaces\kern.25em{#1}\kern.25em\ignorespaces} +\unexpanded\def\module_syntax_Something #1{\Sugar{\mathematics{\langle\hbox{#1}\rangle}}} +\unexpanded\def\module_syntax_Lbrace {\Sugar{\tttf\leftargument}} +\unexpanded\def\module_syntax_Rbrace {\Sugar{\tttf\rightargument}} +\unexpanded\def\module_syntax_Lparent {\Sugar{\tttf(}} +\unexpanded\def\module_syntax_Rparent {\Sugar{\tttf)}} +\unexpanded\def\module_syntax_Lbracket {\Sugar{\tttf[}} +\unexpanded\def\module_syntax_Rbracket {\Sugar{\tttf]}} +\unexpanded\def\module_syntax_Or {\Sugar{\mathematics{\vert}}} +\unexpanded\def\module_syntax_Optional #1{\Sugar{\mathematics{[\hbox{#1}]}}} +\unexpanded\def\module_syntax_Means {\Sugar{\mathematics{\rightarrow}}} +\unexpanded\def\module_syntax_Tex #1{\Sugar{\type{#1}}} +\unexpanded\def\module_syntax_Literal #1{\Sugar{\type{#1}}} +\unexpanded\def\module_syntax_Syntax #1{\strut\kern-.25em{#1}\kern-.25em} +\unexpanded\def\module_syntax_Next {\crlf\hbox to 2em{}\nobreak} +\unexpanded\def\module_syntax_Whatever #1{\Sugar{\mathematics{(\hbox{#1})}}} +\unexpanded\def\module_syntax_Quote #1{\Sugar{\quote{#1}}} +\unexpanded\def\module_syntax_Or {\Sugar{\module_syntax_Indent{\mathematics{\vert}}}} +\unexpanded\def\module_syntax_Means {\Sugar{\module_syntax_Indent{\mathematics{\rightarrow}}}} +\unexpanded\def\module_syntax_FlaggedLiteral #1{\color[darkred]{\module_syntax_Literal{#1}}} +\unexpanded\def\module_syntax_FlaggedSomething#1{\module_syntax_Something{\color[darkred]{#1}}} + +\unexpanded\def\StartSyntax + {\startlines + % formatters + \let\Indent \module_syntax_Indent + \let\Sugar \module_syntax_Sugar + \let\Something \module_syntax_Something + \let\Lbrace \module_syntax_Lbrace + \let\Rbrace \module_syntax_Rbrace + \let\Lparent \module_syntax_Lparent + \let\Rparent \module_syntax_Rparent + \let\Lbracket \module_syntax_Lbracket + \let\Rbracket \module_syntax_Rbracket + \let\Or \module_syntax_Or + \let\Optional \module_syntax_Optional + \let\Means \module_syntax_Means + \let\Tex \module_syntax_Tex + \let\Literal \module_syntax_Literal + \let\Syntax \module_syntax_Syntax + \let\Next \module_syntax_Next + \let\Whatever \module_syntax_Whatever + \let\Quote \module_syntax_Quote + \let\Or \module_syntax_Or + \let\Means \module_syntax_Means + \let\FlaggedLiteral \module_syntax_FlaggedLiteral + \let\FlaggedSomething\module_syntax_FlaggedSomething + % shortcuts + \let\FL \module_syntax_FlaggedLiteral + \let\FS \module_syntax_FlaggedSomething + \let\L \module_syntax_Literal + \let\S \module_syntax_Something + \let\M \module_syntax_Means + \let\O \module_syntax_Or + \let\Q \module_syntax_Quote + \let\LB \module_syntax_Lbrace + \let\RB \module_syntax_Rbrace + \let\LP \module_syntax_Lparent + \let\RP \module_syntax_Rparent + \let\LS \module_syntax_Lbracket + \let\RS \module_syntax_Rbracket + \let\{ \module_syntax_Lbrace + \let\} \module_syntax_Rbrace + \let\( \module_syntax_Lparent + \let\) \module_syntax_Rparent + \let\[ \module_syntax_Lbracket + \let\] \module_syntax_Rbracket + % precaution + \catcode`\#\othercatcode} + +\unexpanded\def\StopSyntax + {\stoplines} + +\unexpanded\def\SyntaxCommand#1% + {\csname module_syntax_#1\endcsname} + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-tugboat-columns.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-tugboat-columns.mkiv new file mode 100644 index 00000000000..f8cace1e98e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-tugboat-columns.mkiv @@ -0,0 +1,556 @@ +%D \module +%D [ file=t-tugboat +%D version=$Id: t-tugboat.tex 91 2011-08-14 16:48:04Z karl $ +%D title=\CONTEXT\ Style File, +%D subtitle=\TUGBOAT\ base style, +%D author={Hans Hagen, Aditya Mahajan, \unknown}, +%D date=\currentdate, +%D copyright=Public Domain] + +%D This file is derived t-tugboat by Aditya Mahajan which in turn is derived +%D from older files. Here we use columnsets. + +\usemodule[newcolumnsets] + +%D We store the information about the article in variables. + + +\setvariables + [tugboat] + [type=article, + % + year=1900, + volume=0, + number=0, + page=1001, + % + title=ConTeXt style for TUGboat, + subtitle=, + keywords=, + author=T. Boat, + address={Harbour Master KB \\ Harbour St. 1 \\ 8061GH Hasselt NL}, + email={tugboat@tug.org}] + +%D \TUGBOAT\ uses slightly different interline space than the default. So we change +%D the interline space. + +\definebodyfontenvironment [8pt] [interlinespace=9.5pt, big=9pt, small=7pt] +\definebodyfontenvironment [9pt] [interlinespace=11pt, big=10pt, small=8pt] +\definebodyfontenvironment [10pt] [interlinespace=12pt, big=12pt, small=9pt] +\definebodyfontenvironment [12pt] [interlinespace=14pt, big=14.4pt,small=10pt] +\definebodyfontenvironment [14.4pt] [interlinespace=18pt, big=14.4pt,small=12pt] + +%D We us e italic rather than slanted for emphasis. + +\setupbodyfontenvironment + [default] + [em=italic] + +%D \TUGBOAT\ uses Computer Modern fonts, and \CONTEXT\ uses Latin Modern by default. +%D So, we just specify the font size. + +\setupbodyfont + [10pt] + +%D We break after these chars in urls, not before. + +\sethyphenatedurlafter / +\sethyphenatedurlafter . +\sethyphenatedurlafter _ + +%D The original layout used in the \LATEX\ style for \TUGBOAT\ is a bit ambiguous. +%D It uses low|-|level \TEX\ syntax, rather than changing the layout in a human +%D understandable way (for example, by using the \mono{geometry} package. I have +%D tried to translate it to \CONTEXT\ as far as I understand. + +\setuppapersize + [letter] + [letter] + +\setuplayout + [topspace=3.8pc,% was 3.5pc + header=1pc, + headerdistance=1.5pc, + height=middle, + footerdistance=2pc, + footer=1pc, + bottomspace=3pc, + % + backspace=6pc, + width=middle, + cutspace=6pc, + % + margin=4pc, + margindistance=1pc] + +\setupcolumnset + [distance=1.5pc] + +\setuppagenumbering + [location=, + alternative=doublesided] + +%D In \TUGBOAT\ different articles are glued together to form the final journal, so +%D we do not want each article to occupy even number of pages. + +\installpagebreakhandler {last} {} + +%D We use automatic indentation control, that is: no indentation after titles and +%D skips. + +\setupindenting + [20pt,yes] + +%D We do not want indentation after lists. + +\setupenumerations [indentnext=no] +\setupdescriptions [indentnext=no] + +%D And these. We typeset itemizations ragged right. + +\setupitemgroup + [itemize] + [indentnext=no, + align=right] + +%D We align them at the paragraph indentation and pack them by default. + +\setupitemgroup + [itemize] + [each] + [margin=1pc, + width=1em, + distance=0pt] + +\setupitemgroup + [itemize] + [1] + [packed] + +%D We follow the \TUGBOAT\ style for sections. I do not know if \type {align=right} +%D also disables hyphenation. Lets wait and see on this. Rest all is straight +%D forward. It took me a while to realize that in \LATEX\ \type {\@startsection} the +%D absolute value of before skip (fourth argument) is important and not the sign. + +\setuphead + [section,subsection,subsubsection, + subject,subsubject,subsubsubject] + [style=bold, + align=right, + before={\blank[8pt]}, + after={\blank[4pt]}] + +%D We define a logical skip. This is equal to the \tex{topsep} in the normal style, +%D and most environments should have this skip. + +\definevspacingamount[tugsmallamount] [3pt plus 1pt minus 1pt][.5\lineheight] +\definevspacingamount[tugmediumamount][9pt plus 3pt minus 3pt][.5\lineheight] +\definevspacingamount[tuglargeamount] [10pt plus 4pt minus 4pt][\lineheight] + +\defineblank[tugblank] [tugsmallamount] +\defineblank[tugsmall] [tugsmallamount] +\defineblank[tugmedium][tugmediumamount] +\defineblank[tuglarge] [tuglargeamount] +\defineblank[tughalf] [halfline] + +\setupblank + [tugblank] + +\setupitemize + [1] + [before={\blank[tugblank]}, + after={\blank[tugblank]}, + inbetween={\blank[tugblank]}] + +\setuplines + [before={\blank[tugblank]}, + after={\blank[tugblank]}, + inbetween={\blank[tugblank]}] + +%D \TUGBOAT\ uses a smaller font size for verbatim typesetting. + +\setuptyping + [option=none, + before={\blank[tugblank]\switchtobodyfont[small]}, + after={\blank[tugblank]}] + +%D Not entirely a la \TUGBOAT: + +\unexpanded\def\MyFootNoteRule + {\hrule width 5pc height .4pt depth 0pt\relax \kern \strutdepth} + +\setupfootnotes + [bodyfont=8pt, + location=columns, + rule=on, + rulecommand=\MyFootNoteRule] + +\setupnotations + [location=joinedup, + width=fit, + headstyle=normal, + distance=.5em] + +%D We define a standard description and enumeration environment. + +\definedescription + [description] + [location=hanging, + width=broad, + before={\blank[tugblank]}, + after={\blank[tugblank]}] + +\defineenumeration + [enumeration] + [location=hanging, + width=broad, + before={\blank[tugblank]}, + after={\blank[tugblank]}] + +%D The bib does not handle urls nicely. So we provide a stop gap solution. + +\definereferenceformat + [cite] + [left={[}, + right={]}] + +\defineitemgroup + [bibliography] + [levels=1] + +\setupitemgroup + [bibliography] + [symbol=n, + left={[}, + right={]}, + width=1.5em, + stopper=, + itemalign=flushright, + inbetween={\blank[small]}] + +%D Instead of color, we use weighted gray scales: + +\setupcolors + [conversion=always] + +%D English it is. + +\mainlanguage + [en] + +%D We define some logical skips + +\defineblank [tugbefore] [big] +\defineblank [tuginbetween][big] +\defineblank [tugafter] [tugbefore] + +%D Some real macros: + +\unexpanded\def\StartAbstract + {\dostartbuffer[abstract][StartAbstract][StopAbstract]} + +\startsetups tugboat:abstract:setup + + \setuptolerance + [horizontal, tolerant] + + \setupnarrower + [before={\blank[tughalf]}, + after={\blank[tuglarge]}, + middle=4.875pc] + +\stopsetups + +%D Headers and footers are different for normal issues and proceedings. + +\startsetups tugboat:banner:text:article + +% {\sl TUGboat},\space +% Volume \getvariable{tugboat}{volume}\space +% (\getvariable{tugboat}{year}),\space +% No.\space\getvariable{tugboat}{number} + +\stopsetups + +\def\postissno{Proceedings of the \tubyear\ Annual Meeting} + +\startsetups tugboat:banner:text:proceedings + + \setups[tugboat:banner:text:article] + \thinspace\emdash\thinspace + \postissno + +\stopsetups + +\startsetups tugboat:banner:setup:article + + \setupheadertexts + [\setups{tugboat:banner:text:article}] + [pagenumber] + +% There are no footers in regular articles +% +% \setupfootertexts +% [][\getvariable{tugboat}{author}] +% [\getvariable{tugboat}{title}][] + +\stopsetups + +\startsetups tugboat:banner:setup:proceedings + + \setupheadertexts + [][\getvariable{tugboat}{title}] + [\getvariable{tugboat}{author}][] + + \setupfootertexts + [\setups{tugboat:banner:text:proceedings}] + [pagenumber] + +\stopsetups + +%D Article is default so, + +\setups[tugboat:banner:setup:article] + +%D It all starts here: + +\unexpanded\def\StartArticle{\directsetup{tugboat:\getvariable{tugboat}{type}:start}} +\unexpanded\def\StopArticle {\directsetup{tugboat:article:stop}} + +\startsetups tugboat:introduction:article + + \start + \unexpanded\def\\{\unskip\space\&\space\ignorespaces} + \hbox{\indent\getvariable{tugboat}{author}} + \par + \stop + +\stopsetups + +\startsetups tugboat:introduction:proceedings + + \blank[20pt] + + \start + \switchtobodyfont[12pt] + \def\\{\unskip\space\&\space\ignorespaces} + \getvariable{tugboat}{author} + \par + \stop + + \start + \switchtobodyfont[9pt] + \unexpanded\def\\{\unskip,\space\ignorespaces} + \getvariable{tugboat}{address} + \par + \start + \tt + \getvariable{tugboat}{email} + \stop + \par + \stop + +\stopsetups + +\startsetups tugboat:columns:presets + + % balancing data (heights) + +\stopsetups + +\startsetups tugboat:article:start + + \starttext + + \setups{tugboat:columns:presets} + + \setups{tugboat:banner:setup:\getvariable{tugboat}{type}} + + \startcolumnset + + \setupheadertexts + [\setups{tugboat:banner:text:article}] + [pagenumber] + + \setuppagenumber + [number=\getvariable{tugboat}{page}] + + \snaptogrid \vbox \bgroup + \forgetall + \hrule height .6pt + \blank[halfline] + \start + \let\\=\par + \start + \bf + \getvariable{tugboat}{title} + \stop + \par + \blank[halfline] + \hskip20pt\getvariable{tugboat}{author} + \stop + + \blank[line] + + \doiftext {\getbuffer[abstract]} { + \let\\=\endgraf + \setups[tugboat:abstract:setup] + \startsubject[title={Abstract}] + \getbuffer[abstract] + \stopsubject + } + \egroup + +\stopsetups + +\startsetups tugboat:proceedings:start + + \starttext + + \setups{tugboat:banner:setup:\getvariable{tugboat}{type}} + + \setupheader + [state=empty] + + \setuppagenumber + [number=\getvariable{tugboat}{page}] + + \snaptogrid \vbox \bgroup + + \forgetall + + \start + \switchtobodyfont[14.4pt] + \let\\=\par + \getvariable{tugboat}{title} + \par + \stop + + \setups{tugboat:introduction:\getvariable{tugboat}{type}} + + \blank[tugmedium] + + \let\\=\par + + \setups[tugboat:abstract:setup] + + \midaligned{\bf Abstract} + + \startnarrower[middle] + \getbuffer[abstract] + \stopnarrower + + \egroup + + \startcolumnset + +\stopsetups + +\def\signaturewidth{13pc} + +\startsetups tugboat:affiliation:article + + \blank[line] + + \snaptogrid \vbox \bgroup + + \forgetall + + \leftskip=\dimexpr\textwidth-\signaturewidth\relax + + \let\\=\par + + \dontleavehmode\llap { + $\diamond$\enspace + } + \getvariable{tugboat}{author} + \par + + \getvariable{tugboat}{address} + \par + + {\tt\getvariable{tugboat}{email}} + + \egroup + +\stopsetups + +\startsetups tugboat:affiliation:proceedings + + % nothing fancy at the end + +\stopsetups + +\startsetups tugboat:article:stop + + \setups{tugboat:affiliation:\getvariable{tugboat}{type}} + + \blank[line] + + \startpacked + \placenote[endnotes] + \stoppacked + + \stopcolumnset + + \page + + \stoptext + +\stopsetups + +%D Normal word spacing, really? + +\setuptolerance + [strict] + +%D Use this in documents: + +% \setuptolerance +% [verytolerant,stretch] + +%D Logos, abbreviations (load a local file if needed). + +\usemodule[abr-03] + +% \unexpanded\def\Dash {\unskip\thinspace\emdash\thinspace\ignorespaces} +% \unexpanded\def\slash{/\penalty\zerocount\hskip\zeropoint\relax} % |/| + +%D Language stuff. + +\hyphenation{Post-Script data-base data-bases} + +\setuplanguage + [lefthyphenmin=2, + rightthyphenmin=3] + +%D A hack to read tugboat.dates settings. + +\newcount\issueseqno + +\def\tubyear{1234} +\def\tubvol {5} +\def\tubnum {6} + +\def\issyear #1.{\def\tubyear{#1}} +\def\vol #1, #2.{\def\tubvol {#1}% + \def\tubnum {#2}} + +%D Good bye. + +\continueifinputfile{s-tugboat-columns.mkiv} + +\StartArticle + + \StartAbstract + \input bryson + \StopAbstract + + \dorecurse{30}{\input ward \par} \page + + \startitemize + \startitem \input ward \stopitem + \startitem \input ward \stopitem + \stopitemize + +\StopArticle diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-typesetting-kerning.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-typesetting-kerning.mkiv new file mode 100644 index 00000000000..48d81ce3602 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-typesetting-kerning.mkiv @@ -0,0 +1,209 @@ +%D \module +%D [ file=s-typesetting-kerning, +%D version=2014.12.14, +%D title=\CONTEXT\ Style File, +%D subtitle=Show Character Kerning, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\unprotect + +\definecharacterkerning + [typesetting-kerning-demo] + [factor=.5] + +\startbuffer[showcharacterkerning:boxes] + \starttextrule{boxes} + \showfontkerns + \dontcomplain + \startlines + test \hbox{!} test + test\hbox{!} test + test \hbox{!}test + test:$x$ test + \setcharacterkerning[typesetting-kerning-demo] + test \hbox{!} test + test\hbox{!} test + test \hbox{!}test + test:$x$ test + \stoplines + \stoptextrule +\stopbuffer + +\startbuffer[showcharacterkerning:ligatures] + \starttextrule{ligatures} + \dontcomplain + \startlines + effe flink effectief efficient fietsen + \blank + \setcharacterkerning[typesetting-kerning-demo] + effe flink effectief efficient fietsen + \blank \hsize\zeropoint + effe + flink + effectief + efficient + fietsen + \stoplines + \stoptextrule +\stopbuffer + +\startbuffer[showcharacterkerning:discretionaries] + \starttextrule{discretionary} + \dontcomplain + \startlines + \hbox{\samplediscretionary} + \hbox{xxx\samplediscretionary} + \hbox{\samplediscretionary xxx} + \hbox{xxx\samplediscretionary xxx} + \blank + \setcharacterkerning[typesetting-kerning-demo] + \hbox{\samplediscretionary} + \hbox{xxx\samplediscretionary} + \hbox{\samplediscretionary xxx} + \hbox{xxx\samplediscretionary xxx} + \blank \hsize\zeropoint + \samplediscretionary + xxx\samplediscretionary + \samplediscretionary xxx + xxx\samplediscretionary xxx + \stoplines + \stoptextrule +\stopbuffer + +\startbuffer[showcharacterkerning:explicits] + \starttextrule{explicits} + \exhyphenchar \hyphenasciicode + \preexhyphenchar \lessthanasciicode + \postexhyphenchar\morethanasciicode + \def\TestDisc + {\discretionary + {\kern\emwidth<}% + {>\kern\emwidth}% + {\kern\emwidth=\kern\emwidth}% + } + \dontcomplain + \startlines + \hbox{super-charged} + \hbox{super\-charged} + \hbox{super\TestDisc charged} + \hbox{super\discretionary{[}{]}{[]}charged} + \blank + \setcharacterkerning[typesetting-kerning-demo] + \hbox{super-charged} + \hbox{super\-charged} + \hbox{super\TestDisc charged} + \hbox{super\discretionary{[}{]}{[]}charged} + \blank \hsize\zeropoint + super-charged + super\-charged + super\TestDisc charged + super\discretionary{[}{]}{[]}charged + \stoplines + \stoptextrule +\stopbuffer + +\starttexdefinition unexpanded showcharacterkerning + \getbuffer[showcharacterkerning:boxes] + \getbuffer[showcharacterkerning:ligatures] + \getbuffer[showcharacterkerning:discretionaries] + \getbuffer[showcharacterkerning:explicits] +\stoptexdefinition + + +\starttexdefinition showcharacterkerningstepscompared #1 + \definecharacterkerning[crap][factor=\KerningStepFactor]% + \setbox0=\ruledhbox{\color[color-1]{#1}\hss} + \setbox2=\ruledhbox{\setcharacterkerning[crap]\color[color-2]{#1}} + \setbox4=\ruledhbox{\setcharacterkerning[crap]\showfontkerns\showglyphs#1} + \xdef\KerningStepPercentage{\ctxlua{context("\letterpercent 0.2f",(1-\number\wd0/\number\wd2)*100)}} + \scratchwidth\wd0 + \vtop\bgroup + \hbox{\box0\hskip-\scratchwidth\box2} + \par + \box4 + \egroup +\stoptexdefinition + +\starttexdefinition showcharacterkerningsteps [#1] + + \start + + \getdummyparameters + [\s!font=Regular, + \c!sample={Wat een bende, rommelen met het font design!}, + \c!text={rommelen}, + \c!first=00, + \c!last=95, + \c!step=05, + \c!option=, % \v!page + #1] + + \doif{\dummyparameter\c!option}\v!page { + \startTEXpage[\c!offset=1ex] + } + + \definecolor[color-1][r=1,t=.5,a=1] + \definecolor[color-2][b=1,t=.5,a=1] + + \definedfont[\dummyparameter\s!font*default sa 1] + + \doif {\dummyparameter\c!option}\v!page { + \begingroup + \tttf \dummyparameter\s!font\space @ default + \endgroup + \blank + } + + \starttabulate[|cT|l|cT|l|cT|] + + \NC \tt\bf factor \NC \tt\bf sample \NC \tt\bf \letterpercent \NC \tt\bf text \NC \tt\bf \letterpercent \NC \NR \HL + + \dostepwiserecurse {\dummyparameter\c!first} {\dummyparameter\c!last} {\dummyparameter\c!step} { + \NC + \xdef\KerningStepFactor{\ctxlua{context("\letterpercent 0.3f",####1/1000)}} + \KerningStepFactor + \NC + \showcharacterkerningstepscompared{\dummyparameter\c!sample} + \NC + \KerningStepPercentage + \NC + \showcharacterkerningstepscompared{\dummyparameter\c!text} + \NC + \KerningStepPercentage + \NC \NR + } + + \stoptabulate + + \doif{\dummyparameter\c!option}\v!page { + \stopTEXpage + } + + \stop + +\stoptexdefinition + +\protect + +\continueifinputfile{s-typesetting-kerning.mkiv} + +\starttext + + % \showcharacterkerning + + \showcharacterkerningsteps[font=file:FuturaStd-Book.otf,option=page] + \showcharacterkerningsteps[font=file:FuturaStd-Medium.otf,option=page] + \showcharacterkerningsteps[font=file:FuturaStd-Bold.otf,option=page] + \showcharacterkerningsteps[font=file:FuturaStd-heavy.otf,option=page] + +\stoptext + +% {\hsize1mm efficient\discretionary{\kern1pt!\kern1pt}{\kern1pt!\kern1pt}{\kern1pt!\kern1pt}efficient\par} +% {\hsize1mm\definedfont[Regular]\setcharacterkerning[typesetting-kerning-demo]efficient\-efficient\par} + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-xml-analyzers.lua b/Master/texmf-dist/tex/context/modules/mkiv/s-xml-analyzers.lua new file mode 100644 index 00000000000..9de6471d148 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-xml-analyzers.lua @@ -0,0 +1,172 @@ +if not modules then modules = { } end modules ['s-xml-analyzers'] = { + version = 1.001, + comment = "companion to s-xml-analyzers.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.xml = moduledata.xml or { } +moduledata.xml.analyzers = moduledata.xml.analyzers or { } + +local next, type = next, type +local utfvalues = string.utfvalues +local context = context +local NC, NR, HL, FL, LL, SL, TB = context.NC, context.NR, context.HL, context.TB, context.FL, context.LL, context.SL +local sortedhash, sortedkeys, concat, sequenced = table.sortedhash, table.sortedkeys, table.concat, table.sequenced + +local chardata = characters.data + +local tags = { } +local char = { } +local attr = { } +local name = nil + +local function analyze(filename) + + if type(filename) == "string" then + filename = { filename } + end + + table.sort(filename) + + local hash = concat(filename,"|") + + if hash == name then + return + end + + name = hash + tags = { } + char = { } + attr = { } + + table.setmetatableindex(tags,function(t,k) + local v = { + n = 0, + attributes = { }, + children = { }, + } + t[k] = v + return v + end) + + table.setmetatableindex(char,function(t,k) + t[k] = 0 + return 0 + end) + + table.setmetatableindex(attr,function(t,k) + char[k] = char[k] or 0 + t[k] = 0 + return 0 + end) + + local function collect(e,parent) + local dt = e.dt + if e.special then + if dt then + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + collect(d,tg) + end + end + end + else + local at = e.at + local tg = e.tg + local tag = tags[tg] + tag.n = tag.n + 1 + if at then + local attributes = tag.attributes + for k, v in next, at do + local a = attributes[k] + if a then + a[v] = (a[v] or 0) + 1 + else + attributes[k] = { [v] = 1 } + end + for s in utfvalues(v) do + attr[s] = attr[s] + 1 + end + end + end + if parent then + local children = tags[parent].children + children[tg] = (children[tg] or 0) + 1 + end + if dt then + for i=1,#dt do + local d = dt[i] + if type(d) == "table" then + collect(d,tg) + else + for s in utfvalues(d) do + char[s] = char[s] + 1 + end + end + end + end + end + end + + for i=1,#filename do + collect(xml.load(filename[i])) + end + + table.setmetatableindex(tags,nil) + table.setmetatableindex(char,nil) + table.setmetatableindex(attr,nil) + +end + +moduledata.xml.analyzers.maxnofattributes = 100 + +function moduledata.xml.analyzers.structure(filename) + analyze(filename) + local done = false + local maxnofattributes = tonumber(moduledata.xml.analyzers.maxnofattributes) or 100 + context.starttabulate { "|l|pA{nothyphenated,flushleft,verytolerant,stretch,broad}|" } + for name, data in table.sortedhash(tags) do + if done then + context.TB() + else + done = true + end + local children = data.children + local attributes = data.attributes + NC() context.bold("element") NC() context.darkred(name) NC() NR() + NC() context.bold("frequency") NC() context(data.n) NC() NR() + if next(children) then + NC() context.bold("children") NC() context.puretext(sequenced(children)) NC() NR() + end + if next(attributes) then + NC() context.bold("attributes") NC() context.puretext.darkgreen(concat(sortedkeys(attributes)," ")) NC() NR() + for attribute, values in sortedhash(attributes) do + local n = table.count(values) + if attribute == "id" or attribute == "xml:id" or n > maxnofattributes then + NC() context(attribute) NC() context("%s different values",n) NC() NR() + else + NC() context(attribute) NC() context.puretext(sequenced(values)) NC() NR() + end + end + end + end + context.stoptabulate() +end + +function moduledata.xml.analyzers.characters(filename) + analyze(filename) + context.starttabulate { "|r|r|l|c|l|" } + for c, n in table.sortedhash(char) do + NC() context.darkred("%s",n) + NC() context.darkgreen("%s",attr[c]) + NC() context("%U",c) + NC() context.char(c) + NC() context("%s",chardata[c].description) + NC() NR() + end + context.stoptabulate() +end + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-xml-analyzers.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-xml-analyzers.mkiv new file mode 100644 index 00000000000..ed033bcfadf --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-xml-analyzers.mkiv @@ -0,0 +1,37 @@ +%D \module +%D [ file=s-xml-analyzers, +%D version=2013.05.28, +%D title=\CONTEXT\ Style File, +%D subtitle=Analyze XML Content, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[xml-analyzers] + +\registerctxluafile{s-xml-analyzers}{} + +\installmodulecommandluasingle \showxmlstructure {moduledata.xml.analyzers.structure} +\installmodulecommandluasingle \showxmlcharacters {moduledata.xml.analyzers.characters} + +\stopmodule + +\continueifinputfile{s-xml-analyzers.mkiv} + +\usemodule[art-01] + +\setupbodyfont[tt,10pt] + +\edef\FileName{\cldcontext{resolvers.findfile("music-collection.xml")}} + +\setupheadertexts[\FileName\space\emdash\space\pagenumber] + +\starttext + + \showxmlcharacters[\FileName] + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/s-youless.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/s-youless.mkiv new file mode 100644 index 00000000000..e15973b9c63 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/s-youless.mkiv @@ -0,0 +1,171 @@ +%D \module +%D [ file=s-youless, +%D version=2013.11.12, +%D title=\CONTEXT\ Style File, +%D subtitle=Youless Graphics, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is experimental code. When I have collected enough data I will make the +%D graphics nicer and provide some more. +%D +%D The Jouless can serve web pages but there is not much detail in them. They also are +%D somewhat bad \HTML, like unquoted attributes and so. We don't need this anyway as we +%D can also fetch data directly. The data is collected using a dedicated helper script +%D (of course we could just call it as module too). The data is fetched from the Jouless +%D device using queries (currently we use json, but a more direct parsing of data might +%D be more efficient). The data is converted into a proper \LUA\ table and saved (merged). + +% in cronjob on one of the servers: +% +% mtxrun --script youless --collect --host=192.168.2.50 --watt youless-watt.lua +% mtxrun --script youless --collect --host=192.168.2.50 --kwk youless-kwh.lua + +\startluacode + + require("util-you") + + moduledata.youless = { } + + function moduledata.youless.kwh(specification) + -- todo + end + + function moduledata.youless.watt(specification) + + local year = tonumber(specification.year) or os.today().year + local data = table.load(specification.filename or "youless-watt.lua") + + if not data or data.variant ~= "watt" then + context("invalid variant") + return + end + + utilities.youless.analyze(data) + + -- for the moment no specific font scaling + + local years = data.years + + if not years then + context("no years") + return + end + + for y=year,year do + + local year = years[y] + local scale = 20 + local mark = 3 + local maxwatt = specification.maxwatt or year.maxwatt + + for m=1,12 do + local month = year.months[m] + if month then + context.startMPpage { offset = "10pt" } + context("linecap := butt; pickup pencircle scaled .5") + + for i=0,(math.div(maxwatt,1000)+1)*1000,100 do + context("draw (%s,%s) -- (%s,%s) withcolor .6white ;",0,i/scale,31 * 24,i/scale) + end + + context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(on 6 off 6) withcolor darkgreen withpen pencircle scaled 1 ;",year.watt /scale,year.watt /scale) + context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(off 6 on 6) withcolor darkred withpen pencircle scaled 1 ;",month.watt/scale,month.watt/scale) + + local days = month.days + if days then + local nd = os.nofdays(y,m) + for d=1,nd do + local day = days[d] + local xoffset = (d-1) * 24 + local wd = os.weekday(d,m,y) + local weekend = wd == 1 or wd == 7 + if not weekend then + -- okay + elseif mark == 1 then + context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -17.5,xoffset, -32.5) + context("draw (%s,%s) -- (%s,%s) ; ",xoffset+24,-17.5,xoffset+24,-32.5) + elseif mark == 2 then + context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -17.5,xoffset+24,-17.5) + context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -32.5,xoffset+24,-32.5) + elseif mark == 3 then + context("draw unitsquare xysized (%s,%s) shifted (%s,%s) ; ",24,15,xoffset,-32.5) + end + context([[draw textext("%s") shifted (%s,%s) ; ]],d,xoffset + 12,-25) + if day then + for h=0,23 do + local hours = day.hours + if hours then + local hour = hours[h] + if hour then + local dx = xoffset + h + local dy = hour.watt/scale + local dm = hour.maxwatt/scale + context("draw (%s,%s) -- (%s,%s) withcolor %s ; ",dx, 0,dx,dy,weekend and "darkmagenta" or "darkblue") + context("draw (%s,%s) -- (%s,%s) withcolor %s ; ",dx,dy,dx,dm,"darkgray") + end + end + end + end + end + for d=0,30 do + local xoffset = d * 24 + context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+ 0,0,xoffset+ 0,-10) + context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+ 6,0,xoffset+ 6,-2.5) + context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+12,0,xoffset+12,-5) + context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+18,0,xoffset+18,-2.5) + end + local xoffset = 31 * 24 + context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset,0,xoffset,-10) + end + + local max = (math.div(maxwatt,1000)+1) + + for i=0,max*1000,1000 do + context([[draw textext.lft("%s") shifted (%s,%s) ; ]],i,-10,i/scale) + context("draw (%s,%s) -- (%s,%s) withcolor .2white ;",0,i/scale,31 * 24,i/scale) + end + + context([[draw textext("\strut\month{%s}\enspace%s") shifted (%s,%s) ; ]],m, y, 31 * 24 / 2, -50) + context([[draw textext.lft("watt") shifted (%s,%s) ; ]],-10,-25) + + context.stopMPpage() + else + -- maybe placeholder + end + end + + end + + end + +\stopluacode + +\continueifinputfile{s-youless.mkiv} + +\setupbodyfont[dejavu] % smaller sizes also look ok + +% printer (oce) : > 3000 W startup (900 W idle, 2000 W printing) +% coffeemaker : 1500 W when heating + +% baseline day : 2250 W (servers, airco, workstations, routers, switches, heating, etc) +% baseline night : 1750 W + +\starttext + + \startluacode + + -- os.execute([[mtxrun --script youless --collect --watt "c:/data/system/youless/data/youless-watt.lua"]]) + -- os.execute([[mtxrun --script youless --collect --watt --nobackup "c:/data/system/youless/data/youless-watt.lua"]]) + -- moduledata.youless.watt { year = 2013, filename = "c:/data/system/youless/data/youless-watt.lua" } + + moduledata.youless.watt { year = 2013, filename = "youless-watt.lua" } + + \stopluacode + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.lua new file mode 100644 index 00000000000..e0a4a714b03 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.lua @@ -0,0 +1,2209 @@ +if not modules then modules = { } end modules ['x-asciimath'] = { + version = 1.001, + comment = "companion to x-asciimath.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>Some backgrounds are discussed in <t>x-asciimath.mkiv</t>. This is a third version. I first +tried a to make a proper expression parser but it's not that easy. First we have to avoid left +recursion, which is not that trivial (maybe a future version of lpeg will provide that), and +second there is not really a syntax but a mix of expressions and sequences with some fuzzy logic +applied. Most problematic are fractions and we also need to handle incomplete expressions. So, +instead we (sort of) tokenize the string and then do some passes over the result. Yes, it's real +ugly and unsatisfying code mess down here. Don't take this as an example.</p> +--ldx]]-- + +-- todo: spaces around all elements in cleanup? +-- todo: filter from files listed in tuc file + +local trace_mapping = false if trackers then trackers.register("modules.asciimath.mapping", function(v) trace_mapping = v end) end +local trace_detail = false if trackers then trackers.register("modules.asciimath.detail", function(v) trace_detail = v end) end +local trace_digits = false if trackers then trackers.register("modules.asciimath.digits", function(v) trace_digits = v end) end + +local report_asciimath = logs.reporter("mathematics","asciimath") + +local asciimath = { } +local moduledata = moduledata or { } +moduledata.asciimath = asciimath + +if not characters then + require("char-def") + require("char-ini") + require("char-ent") +end + +local type, rawget = type, rawget +local concat, insert, remove = table.concat, table.insert, table.remove +local rep, gmatch, gsub, find = string.rep, string.gmatch, string.gsub, string.find +local utfchar, utfbyte = utf.char, utf.byte + +local lpegmatch, patterns = lpeg.match, lpeg.patterns +local S, P, R, C, V, Cc, Ct, Cs, Carg = lpeg.S, lpeg.P, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Ct, lpeg.Cs, lpeg.Carg + +local sortedhash = table.sortedhash +local sortedkeys = table.sortedkeys +local formatters = string.formatters + +local entities = characters.entities or { } + +local xmltext = xml.text +local xmlinclusion = xml.inclusion +local xmlcollected = xml.collected + +-- todo: use private unicodes as temporary slots ... easier to compare + +local s_lparent = "\\left\\lparent" +local s_lbrace = "\\left\\lbrace" +local s_lbracket = "\\left\\lbracket" +local s_langle = "\\left\\langle" +local s_lfloor = "\\left\\lfloor" +local s_lceil = "\\left\\lceil" +local s_left = "\\left." + +local s_rparent = "\\right\\rparent" +local s_rbrace = "\\right\\rbrace" +local s_rbracket = "\\right\\rbracket" +local s_rangle = "\\right\\rangle" +local s_rfloor = "\\right\\rfloor" +local s_rceil = "\\right\\rceil" +local s_right = "\\right." + +local s_mslash = "\\middle/" + +local s_lbar = "\\left\\|" +local s_mbar = "\\middle\\|" +local s_rbar = "\\right\\|" + +local s_lnothing = "\\left ." -- space fools checker +local s_rnothing = "\\right ." -- space fools checker + +local reserved = { + + ["prod"] = { false, "\\prod" }, + ["sinh"] = { false, "\\sinh" }, + ["cosh"] = { false, "\\cosh" }, + ["tanh"] = { false, "\\tanh" }, + ["sum"] = { false, "\\sum" }, + ["int"] = { false, "\\int" }, + ["sin"] = { false, "\\sin" }, + ["cos"] = { false, "\\cos" }, + ["tan"] = { false, "\\tan" }, + ["csc"] = { false, "\\csc" }, + ["sec"] = { false, "\\sec" }, + ["cot"] = { false, "\\cot" }, + ["log"] = { false, "\\log" }, + ["det"] = { false, "\\det" }, + ["lim"] = { false, "\\lim" }, + ["mod"] = { false, "\\mod" }, + ["gcd"] = { false, "\\gcd" }, + ["min"] = { false, "\\min" }, + ["max"] = { false, "\\max" }, + ["ln"] = { false, "\\ln" }, + + ["atan"] = { false, "\\atan" }, -- extra + ["acos"] = { false, "\\acos" }, -- extra + ["asin"] = { false, "\\asin" }, -- extra + + ["arctan"] = { false, "\\arctan" }, -- extra + ["arccos"] = { false, "\\arccos" }, -- extra + ["arcsin"] = { false, "\\arcsin" }, -- extra + + ["and"] = { false, "\\text{and}" }, + ["or"] = { false, "\\text{or}" }, + ["if"] = { false, "\\text{if}" }, + + ["sqrt"] = { false, "\\asciimathsqrt", "unary" }, + ["root"] = { false, "\\asciimathroot", "binary" }, + -- ["\\frac"] = { false, "\\frac", "binary" }, + ["frac"] = { false, "\\frac", "binary" }, + ["stackrel"] = { false, "\\asciimathstackrel", "binary" }, + ["hat"] = { false, "\\widehat", "unary" }, + ["bar"] = { false, "\\overbar", "unary" }, + ["overbar"] = { false, "\\overbar", "unary" }, + ["underline"] = { false, "\\underline", "unary" }, + ["ul"] = { false, "\\underline", "unary" }, + ["vec"] = { false, "\\overrightarrow", "unary" }, + ["dot"] = { false, "\\dot", "unary" }, -- 0x2D9 + ["ddot"] = { false, "\\ddot", "unary" }, -- 0xA8 + + -- binary operators + + ["+"] = { true, "+" }, + ["-"] = { true, "-" }, + ["*"] = { true, "â‹…" }, + ["**"] = { true, "⋆" }, + ["//"] = { true, "â„" }, -- \slash + ["\\"] = { true, "\\" }, + ["xx"] = { true, "×" }, + ["times"] = { true, "×" }, + ["-:"] = { true, "÷" }, + ["@"] = { true, "∘" }, + ["circ"] = { true, "∘" }, + ["o+"] = { true, "⊕" }, + ["ox"] = { true, "⊗" }, + ["o."] = { true, "⊙" }, + ["^^"] = { true, "∧" }, + ["vv"] = { true, "∨" }, + ["nn"] = { true, "∩" }, + ["uu"] = { true, "∪" }, + + -- big operators + + ["^^^"] = { true, "â‹€" }, + ["vvv"] = { true, "â‹" }, + ["nnn"] = { true, "â‹‚" }, + ["uuu"] = { true, "⋃" }, + ["int"] = { true, "∫" }, + ["oint"] = { true, "∮" }, + + -- brackets + + ["("] = { true, "(" }, + [")"] = { true, ")" }, + ["["] = { true, "[" }, + ["]"] = { true, "]" }, + ["{"] = { true, "{" }, + ["}"] = { true, "}" }, + + -- binary relations + + ["="] = { true, "=" }, + ["eq"] = { true, "=" }, + ["!="] = { true, "≠" }, + ["ne"] = { true, "≠" }, + ["neq"] = { true, "≠" }, + ["<"] = { true, "<" }, + ["lt"] = { true, "<" }, + [">"] = { true, ">" }, + ["gt"] = { true, ">" }, + ["<="] = { true, "≤" }, + ["le"] = { true, "≤" }, + ["leq"] = { true, "≤" }, + [">="] = { true, "≥" }, + ["ge"] = { true, "≥" }, + ["geq"] = { true, "≥" }, + ["-<"] = { true, "≺" }, + [">-"] = { true, "≻" }, + ["in"] = { true, "∈" }, + ["!in"] = { true, "∉" }, + ["sub"] = { true, "⊂" }, + ["sup"] = { true, "⊃" }, + ["sube"] = { true, "⊆" }, + ["supe"] = { true, "⊇" }, + ["-="] = { true, "≡" }, + ["~="] = { true, "≅" }, + ["~~"] = { true, "≈" }, + ["prop"] = { true, "âˆ" }, + + -- arrows + + ["rarr"] = { true, "→" }, + ["->"] = { true, "→" }, + ["larr"] = { true, "â†" }, + ["harr"] = { true, "↔" }, + ["uarr"] = { true, "↑" }, + ["darr"] = { true, "↓" }, + ["rArr"] = { true, "⇒" }, + ["lArr"] = { true, "â‡" }, + ["hArr"] = { true, "⇔" }, + ["|->"] = { true, "↦" }, + + -- logical + + ["not"] = { true, "¬" }, + ["=>"] = { true, "⇒" }, + ["iff"] = { true, "⇔" }, + ["AA"] = { true, "∀" }, + ["EE"] = { true, "∃" }, + ["_|_"] = { true, "⊥" }, + ["TT"] = { true, "⊤" }, + ["|--"] = { true, "⊢" }, + ["|=="] = { true, "⊨" }, + + -- miscellaneous + + ["del"] = { true, "∂" }, + ["grad"] = { true, "∇" }, + ["+-"] = { true, "±" }, + ["O/"] = { true, "∅" }, + ["oo"] = { true, "∞" }, + ["aleph"] = { true, "ℵ" }, + ["angle"] = { true, "∠" }, + ["/_"] = { true, "∠" }, + [":."] = { true, "∴" }, + ["..."] = { true, "..." }, -- ldots + ["ldots"] = { true, "..." }, -- ldots + ["cdots"] = { true, "⋯" }, + ["vdots"] = { true, "â‹®" }, + ["ddots"] = { true, "⋱" }, + ["diamond"] = { true, "â‹„" }, + ["square"] = { true, "â–¡" }, + ["|__"] = { true, "⌊" }, + ["__|"] = { true, "⌋" }, + ["|~"] = { true, "⌈" }, + ["~|"] = { true, "⌉" }, + + -- more + + ["_="] = { true, "≡" }, + + -- bonus + + ["prime"] = { true, "′" }, -- bonus + ["'"] = { true, "′" }, -- bonus + ["''"] = { true, "″" }, -- bonus + ["'''"] = { true, "‴" }, -- bonus + + -- special + + ["%"] = { false, "\\mathpercent" }, + ["&"] = { false, "\\mathampersand" }, + ["#"] = { false, "\\mathhash" }, + ["$"] = { false, "\\mathdollar" }, + + -- blackboard + + ["CC"] = { true, "â„‚" }, + ["NN"] = { true, "â„•" }, + ["QQ"] = { true, "â„š" }, + ["RR"] = { true, "â„" }, + ["ZZ"] = { true, "ℤ" }, + + -- greek lowercase + + ["alpha"] = { true, "α" }, + ["beta"] = { true, "β" }, + ["gamma"] = { true, "γ" }, + ["delta"] = { true, "δ" }, + ["epsilon"] = { true, "ε" }, + ["varepsilon"] = { true, "É›" }, + ["zeta"] = { true, "ζ" }, + ["eta"] = { true, "η" }, + ["theta"] = { true, "θ" }, + ["vartheta"] = { true, "Ï‘" }, + ["iota"] = { true, "ι" }, + ["kappa"] = { true, "κ" }, + ["lambda"] = { true, "λ" }, + ["mu"] = { true, "μ" }, + ["nu"] = { true, "ν" }, + ["xi"] = { true, "ξ" }, + ["pi"] = { true, "Ï€" }, + ["rho"] = { true, "Ï" }, + ["sigma"] = { true, "σ" }, + ["tau"] = { true, "Ï„" }, + ["upsilon"] = { true, "Ï…" }, + ["phi"] = { true, "φ" }, + ["varphi"] = { true, "Ï•" }, + ["chi"] = { true, "χ" }, + ["psi"] = { true, "ψ" }, + ["omega"] = { true, "ω" }, + + -- greek uppercase + + ["Gamma"] = { true, "Γ" }, + ["Delta"] = { true, "Δ" }, + ["Theta"] = { true, "Θ" }, + ["Lambda"] = { true, "Λ" }, + ["Xi"] = { true, "Ξ" }, + ["Pi"] = { true, "Î " }, + ["Sigma"] = { true, "Σ" }, + ["Phi"] = { true, "Φ" }, + ["Psi"] = { true, "Ψ" }, + ["Omega"] = { true, "Ω" }, + + -- blackboard + + ["bbb a"] = { true, "ð•’" }, + ["bbb b"] = { true, "ð•“" }, + ["bbb c"] = { true, "ð•”" }, + ["bbb d"] = { true, "ð••" }, + ["bbb e"] = { true, "ð•–" }, + ["bbb f"] = { true, "ð•—" }, + ["bbb g"] = { true, "ð•˜" }, + ["bbb h"] = { true, "ð•™" }, + ["bbb i"] = { true, "ð•š" }, + ["bbb j"] = { true, "ð•›" }, + ["bbb k"] = { true, "ð•œ" }, + ["bbb l"] = { true, "ð•" }, + ["bbb m"] = { true, "ð•ž" }, + ["bbb n"] = { true, "ð•Ÿ" }, + ["bbb o"] = { true, "ð• " }, + ["bbb p"] = { true, "ð•¡" }, + ["bbb q"] = { true, "ð•¢" }, + ["bbb r"] = { true, "ð•£" }, + ["bbb s"] = { true, "ð•¤" }, + ["bbb t"] = { true, "ð•¥" }, + ["bbb u"] = { true, "ð•¦" }, + ["bbb v"] = { true, "ð•§" }, + ["bbb w"] = { true, "ð•¨" }, + ["bbb x"] = { true, "ð•©" }, + ["bbb y"] = { true, "ð•ª" }, + ["bbb z"] = { true, "ð•«" }, + + ["bbb A"] = { true, "ð”¸" }, + ["bbb B"] = { true, "ð”¹" }, + ["bbb C"] = { true, "â„‚" }, + ["bbb D"] = { true, "ð”»" }, + ["bbb E"] = { true, "ð”¼" }, + ["bbb F"] = { true, "ð”½" }, + ["bbb G"] = { true, "ð”¾" }, + ["bbb H"] = { true, "â„" }, + ["bbb I"] = { true, "ð•€" }, + ["bbb J"] = { true, "ð•" }, + ["bbb K"] = { true, "ð•‚" }, + ["bbb L"] = { true, "ð•ƒ" }, + ["bbb M"] = { true, "ð•„" }, + ["bbb N"] = { true, "â„•" }, + ["bbb O"] = { true, "ð•†" }, + ["bbb P"] = { true, "â„™" }, + ["bbb Q"] = { true, "â„š" }, + ["bbb R"] = { true, "â„" }, + ["bbb S"] = { true, "ð•Š" }, + ["bbb T"] = { true, "ð•‹" }, + ["bbb U"] = { true, "ð•Œ" }, + ["bbb V"] = { true, "ð•" }, + ["bbb W"] = { true, "ð•Ž" }, + ["bbb X"] = { true, "ð•" }, + ["bbb Y"] = { true, "ð•" }, + ["bbb Z"] = { true, "ℤ" }, + + -- fraktur + + ["fr a"] = { true, "ð”ž" }, + ["fr b"] = { true, "ð”Ÿ" }, + ["fr c"] = { true, "ð” " }, + ["fr d"] = { true, "ð”¡" }, + ["fr e"] = { true, "ð”¢" }, + ["fr f"] = { true, "ð”£" }, + ["fr g"] = { true, "ð”¤" }, + ["fr h"] = { true, "ð”¥" }, + ["fr i"] = { true, "ð”¦" }, + ["fr j"] = { true, "ð”§" }, + ["fr k"] = { true, "ð”¨" }, + ["fr l"] = { true, "ð”©" }, + ["fr m"] = { true, "ð”ª" }, + ["fr n"] = { true, "ð”«" }, + ["fr o"] = { true, "ð”¬" }, + ["fr p"] = { true, "ð”" }, + ["fr q"] = { true, "ð”®" }, + ["fr r"] = { true, "ð”¯" }, + ["fr s"] = { true, "ð”°" }, + ["fr t"] = { true, "ð”±" }, + ["fr u"] = { true, "ð”²" }, + ["fr v"] = { true, "ð”³" }, + ["fr w"] = { true, "ð”´" }, + ["fr x"] = { true, "ð”µ" }, + ["fr y"] = { true, "ð”¶" }, + ["fr z"] = { true, "ð”·" }, + + ["fr A"] = { true, "ð”„" }, + ["fr B"] = { true, "ð”…" }, + ["fr C"] = { true, "â„" }, + ["fr D"] = { true, "ð”‡" }, + ["fr E"] = { true, "ð”ˆ" }, + ["fr F"] = { true, "ð”‰" }, + ["fr G"] = { true, "ð”Š" }, + ["fr H"] = { true, "â„Œ" }, + ["fr I"] = { true, "â„‘" }, + ["fr J"] = { true, "ð”" }, + ["fr K"] = { true, "ð”Ž" }, + ["fr L"] = { true, "ð”" }, + ["fr M"] = { true, "ð”" }, + ["fr N"] = { true, "ð”‘" }, + ["fr O"] = { true, "ð”’" }, + ["fr P"] = { true, "ð”“" }, + ["fr Q"] = { true, "ð””" }, + ["fr R"] = { true, "â„œ" }, + ["fr S"] = { true, "ð”–" }, + ["fr T"] = { true, "ð”—" }, + ["fr U"] = { true, "ð”˜" }, + ["fr V"] = { true, "ð”™" }, + ["fr W"] = { true, "ð”š" }, + ["fr X"] = { true, "ð”›" }, + ["fr Y"] = { true, "ð”œ" }, + ["fr Z"] = { true, "ℨ" }, + + -- script + + ["cc a"] = { true, "ð’¶" }, + ["cc b"] = { true, "ð’·" }, + ["cc c"] = { true, "ð’¸" }, + ["cc d"] = { true, "ð’¹" }, + ["cc e"] = { true, "ℯ" }, + ["cc f"] = { true, "ð’»" }, + ["cc g"] = { true, "â„Š" }, + ["cc h"] = { true, "ð’½" }, + ["cc i"] = { true, "ð’¾" }, + ["cc j"] = { true, "ð’¿" }, + ["cc k"] = { true, "ð“€" }, + ["cc l"] = { true, "ð“" }, + ["cc m"] = { true, "ð“‚" }, + ["cc n"] = { true, "ð“ƒ" }, + ["cc o"] = { true, "â„´" }, + ["cc p"] = { true, "ð“…" }, + ["cc q"] = { true, "ð“†" }, + ["cc r"] = { true, "ð“‡" }, + ["cc s"] = { true, "ð“ˆ" }, + ["cc t"] = { true, "ð“‰" }, + ["cc u"] = { true, "ð“Š" }, + ["cc v"] = { true, "ð“‹" }, + ["cc w"] = { true, "ð“Œ" }, + ["cc x"] = { true, "ð“" }, + ["cc y"] = { true, "ð“Ž" }, + ["cc z"] = { true, "ð“" }, + + ["cc A"] = { true, "ð’œ" }, + ["cc B"] = { true, "ℬ" }, + ["cc C"] = { true, "ð’ž" }, + ["cc D"] = { true, "ð’Ÿ" }, + ["cc E"] = { true, "â„°" }, + ["cc F"] = { true, "ℱ" }, + ["cc G"] = { true, "ð’¢" }, + ["cc H"] = { true, "â„‹" }, + ["cc I"] = { true, "â„" }, + ["cc J"] = { true, "ð’¥" }, + ["cc K"] = { true, "ð’¦" }, + ["cc L"] = { true, "â„’" }, + ["cc M"] = { true, "ℳ" }, + ["cc N"] = { true, "ð’©" }, + ["cc O"] = { true, "ð’ª" }, + ["cc P"] = { true, "ð’«" }, + ["cc Q"] = { true, "ð’¬" }, + ["cc R"] = { true, "â„›" }, + ["cc S"] = { true, "ð’®" }, + ["cc T"] = { true, "ð’¯" }, + ["cc U"] = { true, "ð’°" }, + ["cc V"] = { true, "ð’±" }, + ["cc W"] = { true, "ð’²" }, + ["cc X"] = { true, "ð’³" }, + ["cc Y"] = { true, "ð’´" }, + ["cc Z"] = { true, "ð’µ" }, + + -- bold + + ["bb a"] = { true, "ð’‚" }, + ["bb b"] = { true, "ð’ƒ" }, + ["bb c"] = { true, "ð’„" }, + ["bb d"] = { true, "ð’…" }, + ["bb e"] = { true, "ð’†" }, + ["bb f"] = { true, "ð’‡" }, + ["bb g"] = { true, "ð’ˆ" }, + ["bb h"] = { true, "ð’‰" }, + ["bb i"] = { true, "ð’Š" }, + ["bb j"] = { true, "ð’‹" }, + ["bb k"] = { true, "ð’Œ" }, + ["bb l"] = { true, "ð’" }, + ["bb m"] = { true, "ð’Ž" }, + ["bb n"] = { true, "ð’" }, + ["bb o"] = { true, "ð’" }, + ["bb p"] = { true, "ð’‘" }, + ["bb q"] = { true, "ð’’" }, + ["bb r"] = { true, "ð’“" }, + ["bb s"] = { true, "ð’”" }, + ["bb t"] = { true, "ð’•" }, + ["bb u"] = { true, "ð’–" }, + ["bb v"] = { true, "ð’—" }, + ["bb w"] = { true, "ð’˜" }, + ["bb x"] = { true, "ð’™" }, + ["bb y"] = { true, "ð’š" }, + ["bb z"] = { true, "ð’›" }, + + ["bb A"] = { true, "ð‘¨" }, + ["bb B"] = { true, "ð‘©" }, + ["bb C"] = { true, "ð‘ª" }, + ["bb D"] = { true, "ð‘«" }, + ["bb E"] = { true, "ð‘¬" }, + ["bb F"] = { true, "ð‘" }, + ["bb G"] = { true, "ð‘®" }, + ["bb H"] = { true, "ð‘¯" }, + ["bb I"] = { true, "ð‘°" }, + ["bb J"] = { true, "ð‘±" }, + ["bb K"] = { true, "ð‘²" }, + ["bb L"] = { true, "ð‘³" }, + ["bb M"] = { true, "ð‘´" }, + ["bb N"] = { true, "ð‘µ" }, + ["bb O"] = { true, "ð‘¶" }, + ["bb P"] = { true, "ð‘·" }, + ["bb Q"] = { true, "ð‘¸" }, + ["bb R"] = { true, "ð‘¹" }, + ["bb S"] = { true, "ð‘º" }, + ["bb T"] = { true, "ð‘»" }, + ["bb U"] = { true, "ð‘¼" }, + ["bb V"] = { true, "ð‘½" }, + ["bb W"] = { true, "ð‘¾" }, + ["bb X"] = { true, "ð‘¿" }, + ["bb Y"] = { true, "ð’€" }, + ["bb Z"] = { true, "ð’" }, + + -- sans + + ["sf a"] = { true, "ð–º" }, + ["sf b"] = { true, "ð–»" }, + ["sf c"] = { true, "ð–¼" }, + ["sf d"] = { true, "ð–½" }, + ["sf e"] = { true, "ð–¾" }, + ["sf f"] = { true, "ð–¿" }, + ["sf g"] = { true, "ð—€" }, + ["sf h"] = { true, "ð—" }, + ["sf i"] = { true, "ð—‚" }, + ["sf j"] = { true, "ð—ƒ" }, + ["sf k"] = { true, "ð—„" }, + ["sf l"] = { true, "ð—…" }, + ["sf m"] = { true, "ð—†" }, + ["sf n"] = { true, "ð—‡" }, + ["sf o"] = { true, "ð—ˆ" }, + ["sf p"] = { true, "ð—‰" }, + ["sf q"] = { true, "ð—Š" }, + ["sf r"] = { true, "ð—‹" }, + ["sf s"] = { true, "ð—Œ" }, + ["sf t"] = { true, "ð—" }, + ["sf u"] = { true, "ð—Ž" }, + ["sf v"] = { true, "ð—" }, + ["sf w"] = { true, "ð—" }, + ["sf x"] = { true, "ð—‘" }, + ["sf y"] = { true, "ð—’" }, + ["sf z"] = { true, "ð—“" }, + + ["sf A"] = { true, "ð– " }, + ["sf B"] = { true, "ð–¡" }, + ["sf C"] = { true, "ð–¢" }, + ["sf D"] = { true, "ð–£" }, + ["sf E"] = { true, "ð–¤" }, + ["sf F"] = { true, "ð–¥" }, + ["sf G"] = { true, "ð–¦" }, + ["sf H"] = { true, "ð–§" }, + ["sf I"] = { true, "ð–¨" }, + ["sf J"] = { true, "ð–©" }, + ["sf K"] = { true, "ð–ª" }, + ["sf L"] = { true, "ð–«" }, + ["sf M"] = { true, "ð–¬" }, + ["sf N"] = { true, "ð–" }, + ["sf O"] = { true, "ð–®" }, + ["sf P"] = { true, "ð–¯" }, + ["sf Q"] = { true, "ð–°" }, + ["sf R"] = { true, "ð–±" }, + ["sf S"] = { true, "ð–²" }, + ["sf T"] = { true, "ð–³" }, + ["sf U"] = { true, "ð–´" }, + ["sf V"] = { true, "ð–µ" }, + ["sf W"] = { true, "ð–¶" }, + ["sf X"] = { true, "ð–·" }, + ["sf Y"] = { true, "ð–¸" }, + ["sf Z"] = { true, "ð–¹" }, + + -- monospace + + ["tt a"] = { true, "ðšŠ" }, + ["tt b"] = { true, "ðš‹" }, + ["tt c"] = { true, "ðšŒ" }, + ["tt d"] = { true, "ðš" }, + ["tt e"] = { true, "ðšŽ" }, + ["tt f"] = { true, "ðš" }, + ["tt g"] = { true, "ðš" }, + ["tt h"] = { true, "ðš‘" }, + ["tt i"] = { true, "ðš’" }, + ["tt j"] = { true, "ðš“" }, + ["tt k"] = { true, "ðš”" }, + ["tt l"] = { true, "ðš•" }, + ["tt m"] = { true, "ðš–" }, + ["tt n"] = { true, "ðš—" }, + ["tt o"] = { true, "ðš˜" }, + ["tt p"] = { true, "ðš™" }, + ["tt q"] = { true, "ðšš" }, + ["tt r"] = { true, "ðš›" }, + ["tt s"] = { true, "ðšœ" }, + ["tt t"] = { true, "ðš" }, + ["tt u"] = { true, "ðšž" }, + ["tt v"] = { true, "ðšŸ" }, + ["tt w"] = { true, "ðš " }, + ["tt x"] = { true, "ðš¡" }, + ["tt y"] = { true, "ðš¢" }, + ["tt z"] = { true, "ðš£" }, + + ["tt A"] = { true, "ð™°" }, + ["tt B"] = { true, "ð™±" }, + ["tt C"] = { true, "ð™²" }, + ["tt D"] = { true, "ð™³" }, + ["tt E"] = { true, "ð™´" }, + ["tt F"] = { true, "ð™µ" }, + ["tt G"] = { true, "ð™¶" }, + ["tt H"] = { true, "ð™·" }, + ["tt I"] = { true, "ð™¸" }, + ["tt J"] = { true, "ð™¹" }, + ["tt K"] = { true, "ð™º" }, + ["tt L"] = { true, "ð™»" }, + ["tt M"] = { true, "ð™¼" }, + ["tt N"] = { true, "ð™½" }, + ["tt O"] = { true, "ð™¾" }, + ["tt P"] = { true, "ð™¿" }, + ["tt Q"] = { true, "ðš€" }, + ["tt R"] = { true, "ðš" }, + ["tt S"] = { true, "ðš‚" }, + ["tt T"] = { true, "ðšƒ" }, + ["tt U"] = { true, "ðš„" }, + ["tt V"] = { true, "ðš…" }, + ["tt W"] = { true, "ðš†" }, + ["tt X"] = { true, "ðš‡" }, + ["tt Y"] = { true, "ðšˆ" }, + ["tt Z"] = { true, "ðš‰" }, + + -- some more undocumented + + ["dx"] = { false, { "d", "x" } }, -- "{dx}" "\\left(dx\\right)" + ["dy"] = { false, { "d", "y" } }, -- "{dy}" "\\left(dy\\right)" + ["dz"] = { false, { "d", "z" } }, -- "{dz}" "\\left(dz\\right)" + + -- fences + + ["(:"] = { true, "(:" }, + ["{:"] = { true, "{:" }, + ["[:"] = { true, "[:" }, + ["("] = { true, "(" }, + ["["] = { true, "[" }, + ["{"] = { true, "{" }, + ["<<"] = { true, "⟨" }, -- why not <: + ["|_"] = { true, "⌊" }, + ["|~"] = { true, "⌈" }, + ["⟨"] = { true, "⟨" }, + ["〈"] = { true, "⟨" }, + ["〈"] = { true, "⟨" }, + + [":)"] = { true, ":)" }, + [":}"] = { true, ":}" }, + [":]"] = { true, ":]" }, + [")"] = { true, ")" }, + ["]"] = { true, "]" }, + ["}"] = { true, "}" }, + [">>"] = { true, "⟩" }, -- why not :> + ["~|"] = { true, "⌉" }, + ["_|"] = { true, "⌋" }, + ["⟩"] = { true, "⟩" }, + ["〉"] = { true, "⟩" }, + ["〉"] = { true, "⟩" }, + + ["lparent"] = { true, "(" }, + ["lbracket"] = { true, "[" }, + ["lbrace"] = { true, "{" }, + ["langle"] = { true, "⟨" }, + ["lfloor"] = { true, "⌊" }, + ["lceil"] = { true, "⌈" }, + + ["rparent"] = { true, ")" }, + ["rbracket"] = { true, "]" }, + ["rbrace"] = { true, "}" }, + ["rangle"] = { true, "⟩" }, + ["rfloor"] = { true, "⌋" }, + ["rceil"] = { true, "⌉" }, + + -- a bit special: + +-- ["\\frac"] = { true, "frac" }, + + -- now it gets real crazy, only these two: + + [">"] = { true, ">" }, + ["<"] = { true, "<" }, + + -- extra: + + -- also, invisible times + + ["dd"] = { false, "{\\tf d}" }, + ["ee"] = { false, "{\\tf e}" }, + ["xxx"] = { true, utfchar(0x2063) }, -- invisible times + +} + +-- a..z A..Z : allemaal op italic alphabet +-- en dan default naar upright "upr a" + +for k, v in next, characters.data do + local name = v.mathname + if name and not reserved[name] then + local char = { true, utfchar(k) } + reserved[ name] = char + -- reserved["\\" .. name] = char + end + -- local spec = v.mathspec + -- if spec then + -- for i=1,#spec do + -- local name = spec[i].name + -- if name and not reserved[name] then + -- reserved[name] = { true, utfchar(k) } + -- end + -- end + -- end +end + +reserved.P = nil +reserved.S = nil + +local isbinary = { + ["\\frac"] = true, + ["\\root"] = true, + ["\\asciimathroot"] = true, + ["\\asciimathstackrel"] = true, +} + +local isunary = { -- can be taken from reserved + ["\\sqrt"] = true, + ["\\asciimathsqrt"] = true, + ["\\text"] = true, -- mathoptext + ["\\mathoptext"] = true, -- mathoptext + ["\\asciimathoptext"] = true, -- mathoptext + ["\\hat"] = true, -- widehat + ["\\widehat"] = true, -- widehat + ["\\bar"] = true, -- + ["\\overbar"] = true, -- + ["\\underline"] = true, -- + ["\\vec"] = true, -- overrightarrow + ["\\overrightarrow"] = true, -- overrightarrow + ["\\dot"] = true, -- + ["\\ddot"] = true, -- + +} + +local isfunny = { + ["\\sin"] = true, +} + +local isinfix = { + ["^"] = true, + ["_"] = true, +} + +local isstupid = { + ["\\prod"] = true, + ["\\sinh"] = true, + ["\\cosh"] = true, + ["\\tanh"] = true, + ["\\sum"] = true, + ["\\int"] = true, + ["\\sin"] = true, + ["\\cos"] = true, + ["\\tan"] = true, + ["\\csc"] = true, + ["\\sec"] = true, + ["\\cot"] = true, + ["\\log"] = true, + ["\\det"] = true, + ["\\lim"] = true, + ["\\mod"] = true, + ["\\gcd"] = true, + ["\\min"] = true, + ["\\max"] = true, + ["\\ln"] = true, + + ["\\atan"] = true, + ["\\acos"] = true, + ["\\asin"] = true, + true, + ["\\arctan"] = true, + ["\\arccos"] = true, + ["\\arcsin"] = true, + + ["f"] = true, + ["g"] = true, +} + +local isleft = { + [s_lparent] = true, + [s_lbrace] = true, + [s_lbracket] = true, + [s_langle] = true, + [s_lfloor] = true, + [s_lceil] = true, + [s_left] = true, +} + +local isright = { + [s_rparent] = true, + [s_rbrace] = true, + [s_rbracket] = true, + [s_rangle] = true, + [s_rfloor] = true, + [s_rceil] = true, + [s_right] = true, +} + +local issimplified = { +} + +-- + +-- special mess + +local d_one = R("09") +local d_two = d_one * d_one +local d_three = d_two * d_one +local d_four = d_three * d_one +local d_split = P(-1) + Carg(2) * (S(".") /"") + +local d_spaced = (Carg(1) * d_three)^1 + +local digitized_1 = Cs ( ( + d_three * d_spaced * d_split + + d_two * d_spaced * d_split + + d_one * d_spaced * d_split + + P(1) + )^1 ) + +local p_fourbefore = d_four * d_split +local p_fourafter = d_four * P(-1) + +local p_beforecomma = d_three * d_spaced^0 * d_split + + d_two * d_spaced^0 * d_split + + d_one * d_spaced^0 * d_split + + d_one * d_split + +local p_aftercomma = p_fourafter + + d_three * d_spaced + + d_two * d_spaced + + d_one * d_spaced + +local digitized_2 = Cs ( + p_fourbefore * (p_aftercomma^0) + + p_beforecomma * ((p_aftercomma + d_one^1)^0) + ) + +local p_fourbefore = d_four * d_split +local p_fourafter = d_four +local d_spaced = (Carg(1) * (d_three + d_two + d_one))^1 +local p_aftercomma = p_fourafter * P(-1) + + d_three * d_spaced * P(1)^0 + + d_one^1 + +-- local digitized_3 = Cs ( +-- p_fourbefore * p_aftercomma^0 + +-- p_beforecomma * p_aftercomma^0 +-- ) + +local digitized_3 = Cs((p_fourbefore + p_beforecomma) * p_aftercomma^0) + +local splitmethods = { + digitized_1, + digitized_2, + digitized_3, +} + +local splitmethod = nil +local symbolmethod = nil +local digitseparator = utfchar(0x2008) +local digitsymbol = "." + +function asciimath.setup(settings) + splitmethod = splitmethods[tonumber(settings.splitmethod) or 0] + if splitmethod then + digitsymbol = settings.symbol + if not digitsymbol or digitsymbol == "" then + digitsymbol = "." + end + local separator = settings.separator + if separator == true or not interfaces or interfaces.variables.yes then + digitseparator = utfchar(0x2008) + elseif type(separator) == "string" and separator ~= "" then + digitseparator = separator + else + splitmethod = nil + end + if digitsymbol ~= "." then + symbolmethod = lpeg.replacer(".",digitsymbol) + else + symbolmethod = nil + end + end +end + +local collected_digits = { } +local collected_filename = "asciimath-digits.lua" + +function numbermess(s) + if splitmethod then + local d = lpegmatch(splitmethod,s,1,digitseparator,digitsymbol) + if not d and symbolmethod then + d = lpegmatch(symbolmethod,s) + end + if d then + if trace_digits and s ~= d then + collected_digits[s] = d + end + return d + end + end + return s +end + +-- asciimath.setup { splitmethod = 3, symbol = "," } +-- local t = { +-- "0.00002", +-- "1", "12", "123", "1234", "12345", "123456", "1234567", "12345678", "123456789", +-- "1.1", +-- "12.12", +-- "123.123", +-- "1234.123", +-- "1234.1234", +-- "12345.1234", +-- "1234.12345", +-- "12345.12345", +-- "123456.123456", +-- "1234567.1234567", +-- "12345678.12345678", +-- "123456789.123456789", +-- "0.1234", +-- "1234.0", +-- "1234.00", +-- "0.123456789", +-- "100.00005", +-- "0.80018", +-- "10.80018", +-- "100.80018", +-- "1000.80018", +-- "10000.80018", +-- } +-- for i=1,#t do print(formatters["%-20s : [%s]"](t[i],numbermess(t[i]))) end + +statistics.register("asciimath",function() + if trace_digits then + local n = table.count(collected_digits) + if n > 0 then + table.save(collected_filename,collected_digits) + return string.format("%s digit conversions saved in %s",n,collected_filename) + else + os.remove(collected_filename) + end + end +end) + +local p_number_base = patterns.cpnumber or patterns.cnumber or patterns.number +local p_number = C(p_number_base) +----- p_number = p_number_base +local p_spaces = patterns.whitespace + +local p_utf_base = patterns.utf8character +local p_utf = C(p_utf_base) +-- local p_entity = (P("&") * C((1-P(";"))^2) * P(";"))/ entities + +-- entities["gt"] = ">" +-- entities["lt"] = "<" +-- entities["amp"] = "&" +-- entities["dquot"] = '"' +-- entities["quot"] = "'" + +local p_onechar = p_utf_base * P(-1) + +----- p_number = Cs((patterns.cpnumber or patterns.cnumber or patterns.number)/function(s) return (gsub(s,",","{,}")) end) + +local sign = P("-")^-1 +local digits = R("09")^1 +local integer = sign * digits +local real = digits * (S(".") * digits)^-1 +local float = real * (P("E") * integer)^-1 + +-- local number = C(float + integer) +-- local p_number = C(float) +local p_number = float / numbermess + +local k_reserved = sortedkeys(reserved) +local k_commands = { } +local k_unicode = { } + +asciimath.keys = { + reserved = k_reserved +} + +local k_reserved_different = { } +local k_reserved_words = { } + +for k, v in sortedhash(reserved) do + local replacement = v[2] + if v[1] then + k_unicode[k] = replacement + else + k_unicode[k] = k -- keep them ... later we remap these + if k ~= replacement then + k_reserved_different[#k_reserved_different+1] = k + end + end + if find(k,"^[a-zA-Z]+$") then + k_unicode["\\"..k] = replacement + else + k_unicode["\\"..k] = k -- dirty trick, no real unicode (still needed ?) + end + if not find(k,"[^a-zA-Z]") then + k_reserved_words[#k_reserved_words+1] = k + end + k_commands[k] = replacement +end + +local p_reserved = + lpeg.utfchartabletopattern(k_reserved_different) / k_commands + +local p_unicode = +-- lpeg.utfchartabletopattern(table.keys(k_unicode)) / k_unicode + lpeg.utfchartabletopattern(k_unicode) / k_unicode + +local p_texescape = patterns.texescape + +local function texescaped(s) + return lpegmatch(p_texescape,s) or s +end + +local p_text = + P("text") + * p_spaces^0 + * Cc("\\asciimathoptext") + * ( -- maybe balanced + Cs( P("{") * ((1-P("}"))^0/texescaped) * P("}") ) + + Cs((P("(")/"{") * ((1-P(")"))^0/texescaped) * (P(")")/"}")) + ) + + Cc("\\asciimathoptext") * Cs(Cc("{") * (C(patterns.undouble)/texescaped) * Cc("}")) + +local m_left = { + ["(:"] = s_langle, + ["{:"] = s_left, + ["[:"] = s_left, + ["("] = s_lparent, + ["["] = s_lbracket, + ["{"] = s_lbrace, + ["⟨"] = s_langle, + ["⌈"] = s_lceil, + ["⌊"] = s_lfloor, + + -- ["<<"] = s_langle, -- why not <: + -- ["|_"] = s_lfloor, + -- ["|~"] = s_lceil, + -- ["〈"] = s_langle, + -- ["〈"] = s_langle, + + -- ["lparent"] = s_lparent, + -- ["lbracket"] = s_lbracket, + -- ["lbrace"] = s_lbrace, + -- ["langle"] = s_langle, + -- ["lfloor"] = s_lfloor, + -- ["lceil"] = s_lceil, +} + +local m_right = { + [":)"] = s_rangle, + [":}"] = s_right, + [":]"] = s_right, + [")"] = s_rparent, + ["]"] = s_rbracket, + ["}"] = s_rbrace, + ["⟩"] = s_rangle, + ["⌉"] = s_rceil, + ["⌋"] = s_rfloor, + + -- [">>"] = s_rangle, -- why not :> + -- ["~|"] = s_rceil, + -- ["_|"] = s_rfloor, + -- ["〉"] = s_rangle, + -- ["〉"] = s_rangle, + + -- ["rparent"] = s_rparent, + -- ["rbracket"] = s_rbracket, + -- ["rbrace"] = s_rbrace, + -- ["rangle"] = s_rangle, + -- ["rfloor"] = s_rfloor, + -- ["rceil"] = s_rceil, +} + +local islimits = { + ["\\sum"] = true, + -- ["∑"] = true, + ["\\prod"] = true, + -- ["âˆ"] = true, + ["\\lim"] = true, +} + +local p_left = + lpeg.utfchartabletopattern(m_left) / m_left +local p_right = + lpeg.utfchartabletopattern(m_right) / m_right + +-- special cases + +-- local p_special = +-- C("/") +-- + P("\\ ") * Cc("{}") * p_spaces^0 * C(S("^_")) +-- + P("\\ ") * Cc("\\space") +-- + P("\\\\") * Cc("\\backslash") +-- + P("\\") * (R("az","AZ")^1/entities) +-- + P("|") * Cc("\\|") +-- +-- faster bug also uglier: + +local p_special = + P("|") * Cc("\\|") -- s_mbar -- maybe always add left / right as in mml ? + + P("\\") * ( + ( + P(" ") * ( + Cc("{}") * p_spaces^0 * C(S("^_")) + + Cc("\\space") + ) + ) + + P("\\") * Cc("\\backslash") + -- + (R("az","AZ")^1/entities) + + C(R("az","AZ")^1) + ) + +-- open | close :: {: | :} + +local u_parser = Cs ( ( + patterns.doublequoted + + P("text") * p_spaces^0 * P("(") * (1-P(")"))^0 * P(")") + -- -- todo: balanced + P("\\frac") / "frac" + -- bah + p_unicode + + p_utf_base +)^0 ) + +local a_parser = Ct { "tokenizer", + tokenizer = ( + p_spaces + + p_number + + p_text + -- + Ct(p_open * V("tokenizer") * p_close) -- {: (a+b,=,1),(a+b,=,7) :} + -- + Ct(p_open * V("tokenizer") * p_close_right) -- { (a+b,=,1),(a+b,=,7) :} + -- + Ct(p_open_left * V("tokenizer") * p_right) -- {: (a+b,=,1),(a+b,=,7) } + + Ct(p_left * V("tokenizer") * p_right) -- { (a+b,=,1),(a+b,=,7) } + + p_special + + p_reserved + -- + p_utf - p_close - p_right + + (p_utf - p_right) + )^1, +} + +local collapse = nil +local serialize = table.serialize +local f_state = formatters["level %s : %s : intermediate"] + +local function show_state(t,level,state) + report_asciimath(serialize(t,f_state(level,state))) +end + +local function show_result(original,unicoded,texcoded) + report_asciimath("original > %s",original) + report_asciimath("unicoded > %s",unicoded) + report_asciimath("texcoded > %s",texcoded) +end + +local function collapse_matrices(t) + local n = #t + if n > 4 and t[3] == "," then + local l1 = t[1] + local r1 = t[n] + if isleft[l1] and isright[r1] then + local l2 = t[2] + local r2 = t[n-1] + if type(l2) == "table" and type(r2) == "table" then + -- we have a matrix + local valid = true + for i=3,n-2,2 do + if t[i] ~= "," then + valid = false + break + end + end + if valid then + for i=2,n-1,2 do + local ti = t[i] + local tl = ti[1] + local tr = ti[#ti] + if isleft[tl] and isright[tr] then + -- ok + else + valid = false + break + end + end + if valid then + local omit = l1 == s_left and r1 == s_right + if omit then + t[1] = "\\startmatrix" + else + t[1] = l1 .. "\\startmatrix" + end + for i=2,n-1 do + if t[i] == "," then + t[i] = "\\NR" + else + local ti = t[i] + ti[1] = "\\NC" + for i=2,#ti-1 do + if ti[i] == "," then + ti[i] = "\\NC" + end + end + ti[#ti] = nil + end + end + if omit then + t[n] = "\\NR\\stopmatrix" + else + t[n] = "\\NR\\stopmatrix" .. r1 + end + end + end + end + end + end + return t +end + +local function collapse_bars(t) + local n, i, l, m = #t, 1, false, 0 + while i <= n do + local current = t[i] + if current == "\\|" then + if l then + m = m + 1 + t[l] = s_lbar + t[i] = s_rbar + t[m] = { unpack(t,l,i) } + l = false + else + l = i + end + elseif not l then + m = m + 1 + t[m] = current + end + i = i + 1 + end + if l then + local tt = { s_lnothing } -- space fools final checker + local tm = 1 + for i=1,m do + tm = tm + 1 + tt[tm] = t[i] + end + tm = tm + 1 + tt[tm] = s_mbar + for i=l+1,n do + tm = tm + 1 + tt[tm] = t[i] + end + tm = tm + 1 + tt[tm] = s_rnothing -- space fools final checker + m = tm + t = tt + elseif m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_pairs(t) + local n, i = #t, 1 + while i < n do + local current = t[i] + if current == "/" and i > 1 then + local tl = t[i-1] + local tr = t[i+1] + local tn = t[i+2] + if type(tl) == "table" then + if isleft[tl[1]] and isright[tl[#tl]] then + tl[1] = "" -- todo: remove + tl[#tl] = nil + end + end + if type(tr) == "table" then + if tn == "^" then + -- brr 1/(1+x)^2 + elseif isleft[tr[1]] and isright[tr[#tr]] then + tr[1] = "" -- todo: remove + tr[#tr] = nil + end + end + i = i + 2 + elseif current == "," or current == ";" then + -- t[i] = current .. "\\thinspace" -- look sbad in (a,b) + i = i + 1 + else + i = i + 1 + end + end + return t +end + +local function collapse_parentheses(t) + local n, i = #t, 1 + if n > 2 then + while i < n do + local current = t[i] + if type(current) == "table" and isleft[t[i-1]] and isright[t[i+1]] then + local c = #current + if c > 2 and isleft[current[1]] and isright[current[c]] then + remove(current,c) + remove(current,1) + end + i = i + 3 + else + i = i + 1 + end + end + end + return t +end + +local function collapse_stupids(t) + local n, m, i = #t, 0, 1 + while i <= n do + m = m + 1 + local current = t[i] + if isstupid[current] then + local one = t[i+1] + if type(one) == "table" then + one = collapse(one,level) + t[m] = current .. "{" .. one .. "}" + i = i + 2 + else + t[m] = current + i = i + 1 + end + else + t[m] = current + i = i + 1 + end + end + if i == n then -- yes? + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_signs(t) + local n, m, i = #t, 0, 1 + while i <= n do + m = m + 1 + local current = t[i] + if isunary[current] then + local one = t[i+1] + if not one then +-- m = m + 1 + t[m] = current .. "{}" -- error + return t +-- break + end + if type(one) == "table" then + if isleft[one[1]] and isright[one[#one]] then + remove(one,#one) + remove(one,1) + end + one = collapse(one,level) + elseif one == "-" and i + 2 <= n then -- or another sign ? or unary ? + local t2 = t[i+2] + if type(t2) == "string" then + one = one .. t2 + i = i + 1 + end + end + t[m] = current .. "{" .. one .. "}" + i = i + 2 + elseif i + 2 <= n and isfunny[current] then + local one = t[i+1] + if isinfix[one] then + local two = t[i+2] + if two == "-" then -- or another sign ? or unary ? + local three = t[i+3] + if three then + if type(three) == "table" then + three = collapse(three,level) + end + t[m] = current .. one .. "{" .. two .. three .. "}" + i = i + 4 + else + t[m] = current + i = i + 1 + end + else + t[m] = current + i = i + 1 + end + else + t[m] = current + i = i + 1 + end + else + t[m] = current + i = i + 1 + end + end + if i == n then -- yes? + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_binaries(t) + local n, m, i = #t, 0, 1 + while i <= n do + m = m + 1 + local current = t[i] + if isbinary[current] then + local one = t[i+1] + local two = t[i+2] + if not one then + t[m] = current .. "{}{}" -- error +return t +-- break + end + if type(one) == "table" then + if isleft[one[1]] and isright[one[#one]] then + remove(one,#one) + remove(one,1) + end + one = collapse(one,level) + end + if not two then + t[m] = current .. "{" .. one .. "}{}" +return t +-- break + end + if type(two) == "table" then + if isleft[two[1]] and isright[two[#two]] then + remove(two,#two) + remove(two,1) + end + two = collapse(two,level) + end + t[m] = current .. "{" .. one .. "}{" .. two .. "}" + i = i + 3 + else + t[m] = current + i = i + 1 + end + end + if i == n then -- yes? + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_infixes_1(t) + local n, i = #t, 1 + while i <= n do + local current = t[i] + if isinfix[current] then + local what = t[i+1] + if what then + if type(what) == "table" then + local f, l = what[1], what[#what] + if isleft[f] and isright[l] then + remove(what,#what) + remove(what,1) + end + t[i+1] = collapse(what,level) -- collapse ? + end + i = i + 2 + else + break + end + else + i = i + 1 + end + end + return t +end + +function collapse_limits(t) + local n, m, i = #t, 0, 1 + while i <= n do + m = m + 1 + local current = t[i] + if islimits[current] then + local one, two, first, second = nil, nil, t[i+1], t[i+3] + if first and isinfix[first] then + one = t[i+2] + if one then + -- if type(one) == "table" then + -- if isleft[one[1]] and isright[one[#one]] then + -- remove(one,#one) + -- remove(one,1) + -- end + -- one = collapse(one,level) + -- end + if second and isinfix[second] then + two = t[i+4] + -- if type(two) == "table" then + -- if isleft[two[1]] and isright[two[#two]] then + -- remove(two,#two) + -- remove(two,1) + -- end + -- two = collapse(two,level) + -- end + end + if two then + t[m] = current .. "\\limits" .. first .. "{" .. one .. "}" .. second .. "{" .. two .. "}" + i = i + 5 + else + t[m] = current .. "\\limits" .. first .. "{" .. one .. "}" + i = i + 3 + end + else + t[m] = current + i = i + 1 + end + else + t[m] = current + i = i + 1 + end + else + t[m] = current + i = i + 1 + end + end + if i == n then -- yes? + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_tables(t) + local n, m, i = #t, 0, 1 + while i <= n do + m = m + 1 + local current = t[i] + if type(current) == "table" then + if current[1] == "\\NC" then + t[m] = collapse(current,level) + else + t[m] = "{" .. collapse(current,level) .. "}" + end + i = i + 1 + else + t[m] = current + i = i + 1 + end + end + if i == n then -- yes? + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_infixes_2(t) + local n, m, i = #t, 0, 1 + while i < n do + local current = t[i] + if isinfix[current] and i > 1 then + local tl = t[i-1] + local tr = t[i+1] + local ti = t[i+2] + local tn = t[i+3] + if ti and tn and isinfix[ti] then + t[m] = tl .. current .. "{" .. tr .. "}" .. ti .. "{" .. tn .. "}" + i = i + 4 + else + t[m] = tl .. current .. "{" .. tr .. "}" + i = i + 2 + end + else + m = m + 1 + t[m] = current + i = i + 1 + end + end + if i == n then + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_fractions_1(t) + local n, m, i = #t, 0, 1 + while i < n do + local current = t[i] + if current == "/" and i > 1 then + local tl = t[i-1] + local tr = t[i+1] + t[m] = "\\frac{" .. tl .. "}{" .. tr .. "}" + i = i + 2 + if i < n then + m = m + 1 + t[m] = t[i] + i = i + 1 + end + else + m = m + 1 + t[m] = current + i = i + 1 + end + end + if i == n then + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_fractions_2(t) + local n, m, i = #t, 0, 1 + while i < n do + local current = t[i] + if current == "â„" and i > 1 then -- \slash + t[m] = "{" .. s_left .. t[i-1] .. s_mslash .. t[i+1] .. s_right .. "}" + i = i + 2 + if i < n then + m = m + 1 + t[m] = t[i] + i = i + 1 + end + else + m = m + 1 + t[m] = current + i = i + 1 + end + end + if i == n then + m = m + 1 + t[m] = t[n] + end + if m < n then + for i=n,m+1,-1 do + t[i] = nil + end + end + return t +end + +local function collapse_result(t) + local n = #t + if t[1] == s_left and t[n] == s_right then -- see bar .. space needed there + return concat(t," ",2,n-1) + else + return concat(t," ") + end +end + +collapse = function(t,level) + -- check + if not t then + return "" + end + -- tracing + if trace_detail then + if level then + level = level + 1 + else + level = 1 + end + show_state(t,level,"parsed") + end + -- steps + t = collapse_matrices (t) if trace_detail then show_state(t,level,"matrices") end + t = collapse_bars (t) if trace_detail then show_state(t,level,"bars") end +t = collapse_stupids (t) if trace_detail then show_state(t,level,"stupids") end + t = collapse_pairs (t) if trace_detail then show_state(t,level,"pairs") end + t = collapse_parentheses(t) if trace_detail then show_state(t,level,"parentheses") end + t = collapse_signs (t) if trace_detail then show_state(t,level,"signs") end + t = collapse_binaries (t) if trace_detail then show_state(t,level,"binaries") end + t = collapse_infixes_1 (t) if trace_detail then show_state(t,level,"infixes (1)") end + t = collapse_limits (t) if trace_detail then show_state(t,level,"limits") end + t = collapse_tables (t) if trace_detail then show_state(t,level,"tables") end + t = collapse_infixes_2 (t) if trace_detail then show_state(t,level,"infixes (2)") end + t = collapse_fractions_1(t) if trace_detail then show_state(t,level,"fractions (1)") end + t = collapse_fractions_2(t) if trace_detail then show_state(t,level,"fractions (2)") end + -- done + return collapse_result(t) +end + +-- todo: cache simple ones, say #str < 10, maybe weak + +local context = context +local ctx_mathematics = context and context.mathematics or report_asciimath +local ctx_type = context and context.type or function() end +local ctx_inleft = context and context.inleft or function() end + +local function convert(str,totex) + local unicoded = lpegmatch(u_parser,str) or str + local texcoded = collapse(lpegmatch(a_parser,unicoded)) + if trace_mapping then + show_result(str,unicoded,texcoded) + end + if totex then + ctx_mathematics(texcoded) + else + return texcoded + end +end + +local n = 0 +local p = ( + (S("{[(") + P("\\left" )) / function() n = n + 1 end + + (S("}])") + P("\\right")) / function() n = n - 1 end + + p_utf_base +)^0 + +local function invalidtex(str) + n = 0 + lpegmatch(p,str) + if n == 0 then + return false + elseif n < 0 then + return formatters["too many left fences: %s"](-n) + elseif n > 0 then + return formatters["not enough right fences: %s"](n) + end +end + +local collected = { } +local indexed = { } + +-- bonus + +local p_reserved_spaced = + C(lpeg.utfchartabletopattern(k_reserved_words)) / " %1 " + +local p_text = + C(P("text")) / " %1 " + * p_spaces^0 + * ( -- maybe balanced + (P("{") * (1-P("}"))^0 * P("}")) + + (P("(") * (1-P(")"))^0 * P(")")) + ) + + patterns.doublequoted + +local p_expand = Cs((p_text + p_reserved_spaced + p_utf_base)^0) +local p_compress = patterns.collapser + +local function cleanedup(str) + return lpegmatch(p_compress,lpegmatch(p_expand,str)) or str +end + +-- so far + +local function register(s,cleanedup,collected,shortname) + local c = cleanedup(s) + local f = collected[c] + if f then + f.count = f.count + 1 + f.files[shortname] = (f.files[shortname] or 0) + 1 + if s ~= c then + f.cleanedup = f.cleanedup + 1 + end + f.dirty[s] = (f.dirty[s] or 0) + 1 + else + local texcoded = convert(s) + local message = invalidtex(texcoded) + if message then + report_asciimath("%s: %s : %s",message,s,texcoded) + end + collected[c] = { + count = 1, + files = { [shortname] = 1 }, + texcoded = texcoded, + message = message, + cleanedup = s ~= c and 1 or 0, + dirty = { [s] = 1 } + } + end +end + +local function wrapup(collected,indexed) + local n = 0 + for k, v in sortedhash(collected) do + n = n + 1 + v.n= n + indexed[n] = k + end +end + +function collect(fpattern,element,collected,indexed) + local element = element or "am" + local mpattern = formatters["<%s>(.-)</%s>"](element,element) + local filenames = resolvers.findtexfile(fpattern) + if filenames and filenames ~= "" then + filenames = { filenames } + else + filenames = dir.glob(fpattern) + end + local cfpattern = gsub(fpattern,"^%./",lfs.currentdir()) + local cfpattern = gsub(cfpattern,"\\","/") + local wildcard = string.split(cfpattern,"*")[1] + if not collected then + collected = { } + indexed = { } + end + for i=1,#filenames do + filename = gsub(filenames[i],"\\","/") + local splitname = (wildcard and wildcard ~= "" and string.split(filename,wildcard)[2]) or filename + local shortname = gsub(splitname or file.basename(filename),"^%./","") + if shortname == "" then + shortname = filename + end + local fullname = resolvers.findtexfile(filename) or filename + if fullname ~= "" then + for s in gmatch(io.loaddata(fullname),mpattern) do + register(s,cleanedup,collected,shortname) + end + end + end + wrapup(collected,indexed) + return collected, indexed +end + +function filter(root,pattern,collected,indexed) + if not pattern or pattern == "" then + pattern = "am" + end + if not collected then + collected = { } + indexed = { } + end + for c in xmlcollected(root,pattern) do + register(xmltext(c),cleanedup,collected,xmlinclusion(c) or "" ) + end + wrapup(collected,indexed) + return collected, indexed +end + +asciimath.convert = convert +asciimath.reserved = reserved +asciimath.collect = collect +asciimath.filter = filter +asciimath.invalidtex = invalidtex +asciimath.cleanedup = cleanedup + +-- sin(x) = 1 : 3.3 uncached 1.2 cached , so no real gain (better optimize the converter then) + +local uncrapped = { + ["%"] = "\\mathpercent", + ["&"] = "\\mathampersand", + ["#"] = "\\mathhash", + ["$"] = "\\mathdollar", + ["^"] = "\\Hat{\\enspace}", -- terrible hack ... tex really does it sbest to turn any ^ into a superscript + ["_"] = "\\underline{\\enspace}", +} + +local function convert(str,nowrap) + if #str > 0 then + local unicoded = lpegmatch(u_parser,str) or str + if lpegmatch(p_onechar,unicoded) then + ctx_mathematics(uncrapped[unicoded] or unicoded) + else + local texcoded = collapse(lpegmatch(a_parser,unicoded)) + if trace_mapping then + show_result(str,unicoded,texcoded) + end + if #texcoded == 0 then + report_asciimath("error in asciimath: %s",str) + else + local message = invalidtex(texcoded) + if message then + report_asciimath("%s: %s : %s",message,str,texcoded) + ctx_type(formatters["<%s>"](message)) + elseif nowrap then + context(texcoded) + else + ctx_mathematics(texcoded) + end + end + end + end +end + +local context = context + +if not context then + +-- trace_mapping = true +-- trace_detail = true + +-- report_asciimath(cleanedup([[ac+sinx+xsqrtx+sinsqrtx+sinsqrt(x)]])) +-- report_asciimath(cleanedup([[a "αsinsqrtx" b]])) +-- convert([[a "αsinsqrtx" b]]) +-- report_asciimath(cleanedup([[a "α" b]])) +-- report_asciimath(cleanedup([[//4]])) + +-- convert("leq\\leq") +-- convert([[\^{1/5}log]]) +-- convert("sqrt") +-- convert("^") + +-- convert[[\frac{a}{b}]] +-- convert[[frac{a}{b}]] + +-- convert("frac{a}{b}") +-- convert("\\sin{a}{b}") +-- convert("sin{a}{b}") +-- convert("1: rightarrow") +-- convert("2: \\rightarrow") + +-- convert("((1,2,3),(4,5,6),(7,8,9))") + +-- convert("1/(t+x)^2") + +-- convert("AA a > 0 ^^ b > 0 | {:log_g:} a + {:log_g:} b") +-- convert("AA a > 0 ^^ b > 0 | {:log_g:} a + {:log_g:} b") + +-- convert("10000,00001") +-- convert("4/18*100text(%)~~22,2") +-- convert("4/18*100text(%)≈22,2") +-- convert("62541/(197,6)≈316,05") + +-- convert([[sum x]]) +-- convert([[sum^(1)_(2) x]]) +-- convert([[lim_(1)^(2) x]]) +-- convert([[lim_(1) x]]) +-- convert([[lim^(2) x]]) + +-- convert([[{: rangle]]) +-- convert([[\langle\larr]]) +-- convert([[langlelarr]]) +-- convert([[D_f=[0 ,→〉]]) +-- convert([[ac+sinx+xsqrtx]]) +-- convert([[ac+\alpha x+xsqrtx-cc b*pi**psi-3alephx / bb X]]) +-- convert([[ac+\ ^ x+xsqrtx]]) +-- convert([[d/dx(x^2+1)]]) +-- convert([[a "αsinsqrtx" b]]) +-- convert([[a "α" b]]) +-- convert([[//4]]) +-- convert([[ {(a+b,=,1),(a+b,=,7)) ]]) + +-- convert([[ 2/a // 5/b = (2 b) / ( a b) // ( 5 a ) / ( a b ) = (2 b ) / ( 5 a ) ]]) +-- convert([[ (2+x)/a // 5/b ]]) + +-- convert([[ ( 2/a ) // ( 5/b ) = ( (2 b) / ( a b) ) // ( ( 5 a ) / ( a b ) ) = (2 b ) / ( 5 a ) ]]) + +-- convert([[ (x/y)^3 = x^3/y^3 ]]) + +-- convert([[ {: (1,2) :} ]]) +-- convert([[ {: (a+b,=,1),(a+b,=,7) :} ]]) +-- convert([[ { (a+b,=,1),(a+b,=,7) :} ]]) +-- convert([[ {: (a+b,=,1),(a+b,=,7) } ]]) +-- convert([[ { (a+b,=,1),(a+b,=,7) } ]]) + +-- convert([[(1,5 ±sqrt(1,25 ),0 )]]) +-- convert([[1//2]]) +-- convert([[(p)/sqrt(p)]]) +-- convert([[u_tot]]) +-- convert([[u_tot=4,4 L+0,054 T]]) + +-- convert([[ [â†;0,2] ]]) +-- convert([[ [â†;0,2⟩ ]]) +-- convert([[ ⟨â†;0,2 ) ]]) +-- convert([[ ⟨â†;0,2 ] ]]) +-- convert([[ ⟨â†;0,2⟩ ]]) + +-- convert([[ x^2(x-1/16)=0 ]]) +-- convert([[ y = ax + 3 - 3a ]]) +-- convert([[ y= ((1/4)) ^x ]]) +-- convert([[ x=\ ^ (1/4) log(0 ,002 )= log(0,002) / (log(1/4) ]]) +-- convert([[ x=\ ^glog(y) ]]) +-- convert([[ x^ (-1 1/2) =1/x^ (1 1/2)=1/ (x^1*x^ (1/2)) =1/ (xsqrt(x)) ]]) +-- convert([[ x^2(10 -x)>2 x^2 ]]) +-- convert([[ x^4>x ]]) + + return + +end + +interfaces.implement { + name = "asciimath", + actions = convert, + arguments = "string" +} + +interfaces.implement { + name = "justasciimath", + actions = convert, + arguments = { "string", true }, +} + +local ctx_typebuffer = context.typebuffer +local ctx_mathematics = context.mathematics +local ctx_color = context.color + +local sequenced = table.sequenced +local assign_buffer = buffers.assign + +local show = { } +asciimath.show = show + +local collected, indexed, ignored = { }, { }, { } + +local color = { "darkred" } + +function show.ignore(n) + if type(n) == "string" then + local c = collected[n] + n = c and c.n + end + if n then + ignored[n] = true + end +end + +function show.count(n,showcleanedup) + local v = collected[indexed[n]] + local count = v.count + local cleanedup = v.cleanedup + if not showcleanedup or cleanedup == 0 then + context(count) + elseif count == cleanedup then + ctx_color(color,count) + else + context("%s+",count-cleanedup) + ctx_color(color,cleanedup) + end +end + +local h = { } +local am = { "am" } + +function show.nofdirty(n) + local k = indexed[n] + local v = collected[k] + local n = v.cleanedup + h = { } + if n > 0 then + for d, n in sortedhash(v.dirty) do + if d ~= k then + h[#h+1] = { d, n } + end + end + end + context(#h) +end + +function show.dirty(m,wrapped) + local d = h[m] + if d then + ctx_inleft(d[2]) + if wrapped then + assign_buffer("am",'"' .. d[1] .. '"') + else + assign_buffer("am",d[1]) + end + ctx_typebuffer(am) + end +end + +function show.files(n) + context(sequenced(collected[indexed[n]].files," ")) +end + +function show.input(n,wrapped) + if wrapped then + assign_buffer("am",'"' .. indexed[n] .. '"') + else + assign_buffer("am",indexed[n]) + end + ctx_typebuffer(am) +end + +function show.result(n) + local v = collected[indexed[n]] + if ignored[n] then + context("ignored") + elseif v.message then + ctx_color(color, v.message) + else + ctx_mathematics(v.texcoded) + end +end + +function show.load(str,element) + collected, indexed, ignored = { }, { }, { } + local t = utilities.parsers.settings_to_array(str) + for i=1,#t do + asciimath.collect(t[i],element or "am",collected,indexed) + end +end + +function show.filter(id,element) + collected, indexed, ignored = { }, { }, { } + asciimath.filter(lxml.getid(id),element or "am",collected,indexed) +end + +function show.max() + context(#indexed) +end + +function show.statistics() + local usedfiles = { } + local noffiles = 0 + local nofokay = 0 + local nofbad = 0 + local nofcleanedup = 0 + for k, v in next, collected do + if ignored[v.n] then + nofbad = nofbad + v.count + elseif v.message then + nofbad = nofbad + v.count + else + nofokay = nofokay + v.count + end + nofcleanedup = nofcleanedup + v.cleanedup + for k, v in next, v.files do + local u = usedfiles[k] + if u then + usedfiles[k] = u + 1 + else + noffiles = noffiles + 1 + usedfiles[k] = 1 + end + end + end + local NC = context.NC + local NR = context.NR + local EQ = context.EQ + context.starttabulate { "|B||" } + NC() context("files") EQ() context(noffiles) NC() NR() + NC() context("formulas") EQ() context(nofokay+nofbad) NC() NR() + NC() context("uniques") EQ() context(#indexed) NC() NR() + NC() context("cleanedup") EQ() context(nofcleanedup) NC() NR() + NC() context("errors") EQ() context(nofbad) NC() NR() + context.stoptabulate() +end + +function show.save(name) + table.save(name ~= "" and name or "dummy.lua",collected) +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.mkiv new file mode 100644 index 00000000000..d3a629c810e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.mkiv @@ -0,0 +1,436 @@ +%D \module +%D [ file=x-asciimath, +%D version=2014.06.01, % 2006.04.24, % 1999.11.06, +%D title=\CONTEXT\ Modules, +%D subtitle=AsciiMath, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\registerctxluafile{x-asciimath}{} + +%D When the Math4All project started, we immediately started using content \MATHML. +%D Because in school math there is often a reference to calculator input, we also +%D provided what we called \quote {calcmath}: a predictable expression based way +%D entering math. At some point \OPENMATH\ was also used but that was later +%D abandoned because editing is more cumbersome. +%D +%D Due to limitations in the web variant (which is independent of rendering for +%D paper but often determines the coding of document, not seldom for the worse) the +%D switch was made to presentational \MATHML. But even that proved to be too complex +%D for rendering on the web, so it got converted to so called \ASCIIMATH\ which +%D can be rendered using some \JAVASCRIPT\ magic. However, all the formulas (and +%D we're talking of tens of thousands of them) were very precisely coded by the main +%D author. Because in intermediate stages of the editing (by additional authors) a +%D mixture of \MATHML\ and \ASCIIMATH\ was used, we wrote the first version of this +%D module. As reference we took \url +%D {http://www1.chapman.edu/~jipsen/mathml/asciimath.html} and. The idea was to +%D stick to \MATHML\ as reference and if needed use \ASCIIMATH\ as annotation. +%D +%D Eventually we ended up with supporting several math encodings in \CONTEXT\ that +%D could be used mixed: content \MATHML\ (preferred), presentation \MATHML\ (often +%D messy), \OPENMATH\ (somewhat minimalistic) calcmath (handy for students who are +%D accustomed to calculators), \ASCIIMATH\ (to make web support easier) and of +%D course \TEX. +%D +%D The first version had some limitations as we didn't want to support all quirks of +%D \ASCIIMATH\ and also because I was not really in the mood to write a complex parser +%D when a bit of sane coding can work equally well. Some comments from that version: +%D +%D \startnarrower +%D \startitemize +%D \item We support only the syntactically clear variants and as long as lpeg does +%D not support left recursion this is as far as we want to go. +%D \item The parser is rather insensitive for spaces but yet the advice is to avoid +%D weird coding like \type {d/dxf(x)} but use \type {d/dx f(x)} instead. After +%D all we're not in a compact coding cq.\ parser challenge. +%D \item We also don't support the somewhat confusing \type {sqrt sqrt 2} nor \type +%D {root3x} (although the second one kind of works). A bit of defensive coding +%D does not hurt. +%D \item We can process \type {a/b/c/d} but it's not compatible with the default +%D behaviour of \ASCIIMATH. Use grouping instead. Yes, we do support the somewhat +%D nonstandard grouping token mix. +%D \item You should use explicit \type {text(..)} directives as one can never be sure +%D what is a reserved word and not. +%D \stopitemize +%D +%D Actually, as the only parsing sensitive elements of \TEX\ are fractions (\type {\over} +%D and friends, a restricted use of \TEX\ coding is probably as comprehensive and +%D parsable. The webpage with examples served as starting point so anything beyond +%D what can be found there isn't supported. +%D \stopnarrower +%D +%D Then in 2014 something bad happened. Following the fashion of minimal encoding +%D (which of course means messy encoding of complex cases and which can make authors +%D sloppy too) the web based support workflow of the mentioned project ran into some +%D limitations and magically one day all carefully coded \MATHML\ was converted into +%D \ASCIIMATH. As there was no way to recover the original thousands of files and +%D tens of thousands of formulas we were suddenly stuck with \ASCIIMATH. Because the +%D conversion had be done automagically, we also saw numerous errors and were forced +%D to come up with some methods to check formulas. Because \MATHML\ poses some +%D restrictions it has predictable rendering; \ASCIIMATH\ on the other hand enforces +%D no structure. Also, because \MATHML\ has to be valid \XML\ it always processes. +%D Of course, during the decade that the project had run we also had to built in +%D some catches for abuse but at least we had a relatively stable and configurable +%D subsystem. So, in order to deal with less predictable cases as well as extensive +%D checking, a new \ASCIIMATH\ parser was written, one that could also be used to +%D trace bad coding. +%D +%D Because the formal description is incomplete, and because some links to resources +%D are broken, and because some testing on the web showed that sequences of characters +%D are interpreted that were not mentioned anywhere (visible), and because we noticed +%D that the parser was dangerously tolerant, the new code is quite different from the +%D old code. +%D +%D One need to keep in mind that because spaces are optional, the only robust way to +%D edit \ASCIIMATH\ is to use a \WYSIWYG\ editor and hope that the parser doesn't +%D change ever. Keys are picked up from spaceless sequences and when not recognized +%D a (sequence) of characters is considered to be variables. So, \type {xsqrtx} is +%D valid and renders as \type {$x\sqrt{x}$}, \type {xx} becomes \type {×} (times) +%D but \type {ac} becomes \type {$a c$} (a times c). We're lucky that \type {AC} is +%D not turned into Alternating Current, but who knows what happens a few years from +%D now. So, we do support this spaceless mess, but users are warned: best use a +%D spacy sequence. The extra amount of spaces (at one byte each) an author has to +%D include in his|/|her active writing time probably stays below the size of one +%D holiday picture. Another complication is that numbers (in Dutch) use commas instead +%D of periods, but vectors use commas as well. We also hav esome different names for +%D functions which then can conflict with the expectations about collapsed variables. +%D +%D It must be noted that simplified encodings (that seem to be the fashion today) +%D can demand from applications to apply fuzzy logic to make something work out +%D well. Because we have sequential data that gets rendered, sometimes wrong input +%D gets obscured simply by the rendering: like the comma's in numbers as well as +%D for separators (depending on space usage), or plain wrong symbols that somehow +%D get a representation anyway. This in itself is more a side effect of trying to +%D use the simplified encoding without applying rules (in the input) or to use it +%D beyong its intended usage, which then of course can lead to adapted parsers and +%D catches that themselves trigger further abuse. Imagine that instead of developing +%D new cars, planes, space ships, mobile phones, computers we would have adapted +%D horse cars, kites, firework, old fashioned phones and mechanical calculators in a +%D similar way: patch upon patch of traditional means for sure would not have +%D worked. So, when you use \ASCIIMATH\ best check immediately how it gets rendered +%D in the browser as well as on paper. And be prepared to check the more complex +%D code in the future again. We don't offer any guarantees but of course will try to +%D keep up. +%D +%D In retrospect I sometimes wonder if the energy put into constantly adapting to +%D the fashion of the day pays off. Probably not. It definitely doesn't pay of. +%D +%D More complex crap: +%D +%D 1: $x + \stackrel{comment}{\stackrel{\utfchar{"23DE}}{yyyyyyyy}} = y$ \blank +%D 2: \asciimath{x + stackrel{\utfchar{"23DE}}{yyyyyyyy} = y} \blank +%D 3: \asciimath{x + stackrel{yyyyyyyy}{\utfchar{"23DE}} = y} \blank +%D 4: \asciimath{x + stackrel{"comment"}{stackrel{\utfchar{"23DE}}{yyyyyyyy}} = y} \blank + +\usemodule[mathml-basics] + +\startmodule[asciimath] + +\unprotect + +\writestatus{asciimath}{beware, this is an experimental (m4all only) module} + +%D Hacks: + +\unexpanded\def\asciimathoptext #1{\ifmmode\mathoptext{#1}\else#1\fi} +\unexpanded\def\asciimathoptexttraced #1{\ifmmode\mathoptext{\color[darkgreen]{#1}}\else\color[darkgreen]{#1}\fi} +\unexpanded\def\asciimathstackrel #1#2{\mathematics{\mathop{\let\limits\relax\mover{#2}{#1}}}} +\unexpanded\def\asciimathroot #1#2{\sqrt[#1]{#2}} +\unexpanded\def\asciimathsqrt #1{\sqrt{#1}} + +%D The core commands: + +% if we need to set + +\installsetuponlycommandhandler {asciimath} {asciimath} + +\appendtoks + \ctxlua{moduledata.asciimath.setup { + splitmethod = "\asciimathparameter\c!splitmethod", + separator = "\asciimathparameter\c!separator", + symbol = "\asciimathparameter\c!symbol", + }}% +\to \everysetupasciimath + +\newtoks\everyasciimath + +% \appendtoks +% \ignorediscretionaries +% \to \everyasciimath + +\appendtoks + \enableautofences +\to \everyasciimath + +\unexpanded\def\asciimath + {\doifnextoptionalelse\asciimath_yes\asciimath_nop} + +\def\asciimath_yes[#1]#2% + {\mathematics + [#1]% + {\the\everyasciimath% + \clf_justasciimath{\detokenize\expandafter{\normalexpanded{#2}}}}} + +\def\asciimath_nop#1% + {\mathematics + {\the\everyasciimath + \clf_justasciimath{\detokenize\expandafter{\normalexpanded{#1}}}}} + +\unexpanded\def\ctxmoduleasciimath#1% + {\ctxlua{moduledata.asciimath.#1}} + +%D Some tracing commands. Using tex commands is 10\% slower that directly piping +%D from \LUA, but this is non|-|critical code. + +\unexpanded\def\ShowAsciiMathLoad [#1]{\ctxlua{moduledata.asciimath.show.load("#1")}} +\unexpanded\def\ShowAsciiMathIgnore[#1]{\ctxlua{moduledata.asciimath.show.ignore("#1")}} +\unexpanded\def\ShowAsciiMathXML #1#2{\ctxlua{moduledata.asciimath.show.filter("#1","#2")}} +\unexpanded\def\ShowAsciiMathStats {\ctxlua{moduledata.asciimath.show.statistics()}} +\unexpanded\def\ShowAsciiMathMax {\ctxlua{moduledata.asciimath.show.max()}} + +\unexpanded\def\ShowAsciiMathResult#1% + {\begingroup + \blank + % if we are in vmode, we don't get positions i.e. a smaller tuc file + \inleft{\ttbf#1\hfill\ctxlua{moduledata.asciimath.show.count(#1,true)}}% + \dontleavehmode + \begingroup + \ttbf + \ctxlua{moduledata.asciimath.show.files(#1)} + \endgroup + \blank[medium,samepage] + \startcolor[darkblue] + \ctxlua{moduledata.asciimath.show.input(#1,true)} + \stopcolor + \blank[medium,samepage] + \doifmode{asciimath:show:dirty} { + \dorecurse{\ctxlua{moduledata.asciimath.show.nofdirty(#1)}} { + \ctxlua{moduledata.asciimath.show.dirty(\recurselevel,true)} + \blank[medium,samepage] + } + } + \ctxlua{moduledata.asciimath.show.result(#1)} + \blank + \endgroup} + +\unexpanded\def\ShowAsciiMathStart + {\begingroup + \let\asciimathoptext\asciimathoptexttraced + \setuptyping[\v!buffer][\c!before=,\c!after=] + \setupmargindata[\v!left][\c!style=]} + +\unexpanded\def\ShowAsciiMathStop + {\endgroup} + +\unexpanded\def\ShowAsciiMath + {\dodoubleempty\doShowAsciiMath} + +\unexpanded\def\doShowAsciiMath[#1][#2]% + {\iffirstargument + \ShowAsciiMathStart + \ShowAsciiMathLoad[#1] + \ifsecondargument + \ShowAsciiMathIgnore[#2] + \fi + \dorecurse{\ShowAsciiMathMax}{\ShowAsciiMathResult\recurselevel} + \page + \ShowAsciiMathStats + \ShowAsciiMathStop + \fi} + +\unexpanded\def\xmlShowAsciiMath#1#2% + {\iffirstargument + \ShowAsciiMathStart + \ShowAsciiMathXML{#1}{#2}% + \dorecurse{\ShowAsciiMathMax}{\ShowAsciiMathResult\recurselevel} + \page + \ShowAsciiMathStats + \ShowAsciiMathStop + \fi} + +\unexpanded\def\ShowAsciiMathSave + {\dosingleempty\doShowAsciiMathSave} + +\unexpanded\def\doShowAsciiMathSave[#1]% + {\ctxlua{moduledata.asciimath.show.save("#1")}} + +\protect + +\startsetups asciimath:layout + + \setupbodyfont + % [pagella,10pt] + [dejavu,10pt] + + \setuplayout + [backspace=35mm, + leftmargin=20mm, + rightmargindistance=0pt, + leftmargindistance=5mm, + cutspace=1cm, + topspace=1cm, + bottomspace=1cm, + width=middle, + height=middle, + header=0cm, + footer=1cm] + + \setupheadertexts + [] + + \setupfootertexts + [\currentdate][\pagenumber] + + \setupalign + [flushleft,verytolerant,stretch] + + \dontcomplain + +\stopsetups + +\stopmodule + +\continueifinputfile{x-asciimath.mkiv} + +%D This will become an extra. + +\showframe + +\setups[asciimath:layout] + +% \enabletrackers[modules.asciimath.mapping] +% \enabletrackers[modules.asciimath.detail] + +% \starttext +% \enablemode[asciimath:show:dirty] +% \ShowAsciiMath[e:/temporary/asciimath/*.xml] +% % \ShowAsciiMathSave[e:/temporary/asciimath/asciimath.lua] +% \stoptext + +\starttext +\unexpanded\def\MyAsciiMath#1{\startformula\asciimath{#1}\stopformula} +\startlines +\MyAsciiMath{x^2 / 10 // z_12^34 / 20} +% \MyAsciiMath{{:{:x^2:} / 10:} // {:{:z_12^34 :} / 20:}} +% \MyAsciiMath{x^2+y_1+z_12^34} +% \MyAsciiMath{sin^-1(x)} +% \MyAsciiMath{d/dx f(x)=lim_(h->0) (f(x+h)-f(x))/h} +% \MyAsciiMath{f(x)=sum_(n=0)^oo(f^((n))(a))/(n!)(x-a)^n} +% \MyAsciiMath{int_0^1 f(x)dx} +% \MyAsciiMath{int^1_0 f(x)dx} +% \MyAsciiMath{a//b} +% \MyAsciiMath{a//\alpha} +% \MyAsciiMath{(a/b)/(d/c)} +% \MyAsciiMath{((a*b))/(d/c)} +% \MyAsciiMath{[[a,b],[c,d]]((n),(k))} +% \MyAsciiMath{1/x={(1,text{if } x!=0),(text{undefined},if x=0):}} +% \MyAsciiMath{{ (1,2), (x,(x + text(x))) }} +% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,text(x))}} +% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,x text(x))}} +% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,x text(xyz))}} +% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,text(xyz)+1+text(hans))}} +% \MyAsciiMath{<<a,b>> text{and} {:(x,y),(u,v):}} +% \MyAsciiMath{(a,b] = {x text(in) RR | a < x <= b}} +% \MyAsciiMath{a/b / c/d = (a * d) / (b * d) / (b * c) / (b * d) = (a * d) / (b * c)} +% \MyAsciiMath{ (a/b) // (c/d) = ( (a * d) / (b * d) ) // ( (b * c) / (b * d) ) = (a * d) / (b * c)} +% \MyAsciiMath{sin(x+1)_3^2/b / c/d} +% \MyAsciiMath{{:{:sin(x+1)_3^2:}/b:} / {:c/d:}} +% \MyAsciiMath{cos(a) + sin(x+1)_3^2/b / c/d = (a * d) / (b * d) / (b * c) / (b * d) = (a * d) / (b * c)} +% \MyAsciiMath{S_(11)} +% \MyAsciiMath{f(x)} +% \MyAsciiMath{sin(x)} +% \MyAsciiMath{sin(x+1)} +% \MyAsciiMath{sin^-1(x)} +% \MyAsciiMath{sin(2x)} +% \MyAsciiMath{a_2^2} +% \MyAsciiMath{( (S_(11),S_(12),S_(1n)),(vdots,ddots,vdots),(S_(m1),S_(m2),S_(mn)) ]} +% \MyAsciiMath{frac a b} +% \MyAsciiMath{sin(x)/2 // cos(x)/pi} +% \MyAsciiMath{a/13 // c/d} +% \MyAsciiMath{a/b // c/d} +% \MyAsciiMath{x} +% \MyAsciiMath{x^2} +% \MyAsciiMath{sqrt x} +% \MyAsciiMath{sqrt (x)} +% \MyAsciiMath{root 2 x} +% \MyAsciiMath{x+x} +% \MyAsciiMath{x/3} +% \MyAsciiMath{x^2 / 10} +% \MyAsciiMath{x^2 / 10 // z_12^34 / 20} +% \MyAsciiMath{a^23} +% \MyAsciiMath{a^{:b^23:}+3x} +% \MyAsciiMath{a/b / c/d} +% \MyAsciiMath{sin(x)/b / c/d} +% \MyAsciiMath{sin(x)/b // c/d} +% \MyAsciiMath{a/b / c/d = (a * d) / (b * d) / (b * c) / (b * d) = (a * d) / (b * c) } +% \MyAsciiMath{{:{:x^2:} / 10:} // {:{:z_12^34 :} / 20:}} +% \MyAsciiMath{x^2+y_1+z_12^34} +% \MyAsciiMath{sin^-1(x)} +% \MyAsciiMath{d/dx f(x)=lim_(h->0) (f(x+h)-f(x))/h} +% \MyAsciiMath{f(x)=sum_(n=0)^oo(f^((n))(a))/(n!)(x-a)^n} +% \MyAsciiMath{int_0^1 f(x)dx} +% \MyAsciiMath{int^1_0 f(x)dx} +% \MyAsciiMath{2x} +% \MyAsciiMath{a//b} +% \MyAsciiMath{a//\alpha} +% \MyAsciiMath{(a/b)/(d/c)} +% \MyAsciiMath{((a*b))/(d/c)} +% \MyAsciiMath{[[a,b],[c,d]]((n),(k))} +% \MyAsciiMath{1/x={(1,text{if } x!=0),(text{undefined},if x=0):}} +% \MyAsciiMath{{ (1,2), (x,(x + text(x))) }} +% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,text(x))}} +% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,x text(x))}} +% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,x text(xyz))}} +% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,text(xyz)+1+text(hans))}} +% \MyAsciiMath{<<a,b>> text{and} {:(x,y),(u,v):}} +% \MyAsciiMath{(a,b] = {x text(in) RR | a < x <= b}} +% \MyAsciiMath{x^-2} +% \MyAsciiMath{x^2(x-1/16)=0} +% \MyAsciiMath{y= ((1/4)) ^x} +% \MyAsciiMath{log (0,002) / (log(1/4))} +% \MyAsciiMath{x=ax+b \ oeps} +% \MyAsciiMath{x=\ ^ (1/4) log(x)} +% \MyAsciiMath{x=\ ^ (1/4) log(0 ,002 )= log(0,002) / (log(1/4))} +% \MyAsciiMath{x^ (-1 1/2) =1/x^ (1 1/2)=1/ (x^1*x^ (1/2)) =1/ (xsqrt(x))} +% \MyAsciiMath{x^2(10 -x)>2 x^2} +% \MyAsciiMath{x^4>x} +\stoplines + +\setupasciimath[splitmethod=3,symbol={{,}}] + +\startlines +\asciimath{sqrt 1} +\asciimath{sqrt 1.2} +\asciimath{sqrt 1.2} +\asciimath{1} +\asciimath{12} +\asciimath{123} +\asciimath{1234} +\asciimath{12345} +\asciimath{123456} +\asciimath{1234567} +\asciimath{12345678} +\asciimath{123456789} +\asciimath{1.1} +\asciimath{12.12} +\asciimath{1234.123} +\asciimath{1234.1234} +\asciimath{12345.1234} +\asciimath{1234.12345} +\asciimath{12345.12345} +\asciimath{123456.123456} +\asciimath{1234567.1234567} +\asciimath{12345678.12345678} +\asciimath{123456789.123456789} +\asciimath{0.1234} +\asciimath{1234.0} +\asciimath{1234.00} +\asciimath{0.123456789} +\stoplines + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-calcmath.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-calcmath.lua new file mode 100644 index 00000000000..c96d8d0ac51 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-calcmath.lua @@ -0,0 +1,363 @@ +if not modules then modules = { } end modules ['x-calcmath'] = { + version = 1.001, + comment = "companion to x-calcmath.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- this really needs to be redone + +local format, lower, upper, gsub, sub = string.format, string.lower, string.upper, string.gsub, string.sub +local concat = table.concat +local lpegmatch = lpeg.match + +local calcmath = { } +local moduledata = moduledata or { } +moduledata.calcmath = calcmath + +local context = context + +local list_1 = { + "median", "min", "max", "round", "ln", "log", + "sin", "cos", "tan", "sinh", "cosh", "tanh" +} +local list_2 = { + "int", "sum", "prod" +} +local list_3 = { + "f", "g" +} +local list_4 = { + "pi", "inf" +} + +local list_1_1 = { } +local list_2_1 = { } +local list_2_2 = { } +local list_2_3 = { } +local list_4_1 = { } + +local frozen = false + +local function freeze() + for k=1,#list_1 do + local v = list_1[k] + list_1_1[v] = "\\".. upper(v) .." " + end + for k=1,#list_2 do + local v = list_2[k] + list_2_1[v .. "%((.-),(.-),(.-)%)"] = "\\" .. upper(v) .. "^{%1}_{%2}{%3}" + list_2_2[v .. "%((.-),(.-)%)"] = "\\" .. upper(v) .. "^{%1}{%2}" + list_2_3[v .. "%((.-)%)"] = "\\" .. upper(v) .. "{%1}" + end + for k=1,#list_4 do + local v = list_4[k] + list_4_1[v] = "\\" .. upper(v) + end + frozen = true +end + +local entities = { + ['gt'] = '>', + ['lt'] = '<', +} + +local symbols = { + ["<="] = "\\LE ", + [">="] = "\\GE ", + ["=<"] = "\\LE ", + ["=>"] = "\\GE ", + ["=="] = "\\EQ ", + ["<" ] = "\\LT ", + [">" ] = "\\GT ", + ["="] = "\\EQ ", +} + +local function nsub(str,tag,pre,post) + return (gsub(str,tag .. "(%b())", function(body) + return pre .. nsub(sub(body,2,-2),tag,pre,post) .. post + end)) +end + +local function totex(str,mode) + if not frozen then freeze() end + local n = 0 + -- crap + str = gsub(str,"%s+",' ') + -- xml + str = gsub(str,"&(.-);",entities) + -- ...E... + str = gsub(str,"([%-%+]?[%d%.%+%-]+)E([%-%+]?[%d%.]+)", "{\\SCINOT{%1}{%2}}") + -- ^-.. + str = gsub(str,"%^([%-%+]*%d+)", "^{%1}") + -- ^(...) + str = nsub(str,"%^", "^{", "}") + -- 1/x^2 + repeat + str, n = gsub(str,"([%d%w%.]+)/([%d%w%.]+%^{[%d%w%.]+})", "\\frac{%1}{%2}") + until n == 0 + -- todo: autoparenthesis + -- int(a,b,c) + for k, v in next, list_2_1 do + repeat str, n = gsub(str,k,v) until n == 0 + end + -- int(a,b) + for k, v in next, list_2_2 do + repeat str, n = gsub(str,k,v) until n == 0 + end + -- int(a) + for k, v in next, list_2_3 do + repeat str, n = gsub(str,k,v) until n == 0 + end + -- sin(x) => {\\sin(x)} + for k, v in next, list_1_1 do + repeat str, n = gsub(str,k,v) until n == 0 + end + -- mean + str = nsub(str, "mean", "\\OVERLINE{", "}") + -- (1+x)/(1+x) => \\FRAC{1+x}{1+x} + repeat + str, n = gsub(str,"(%b())/(%b())", function(a,b) + return "\\FRAC{" .. sub(a,2,-2) .. "}{" .. sub(b,2,-2) .. "}" + end ) + until n == 0 + -- (1+x)/x => \\FRAC{1+x}{x} + repeat + str, n = gsub(str,"(%b())/([%+%-]?[%.%d%w]+)", function(a,b) + return "\\FRAC{" .. sub(a,2,-2) .. "}{" .. b .. "}" + end ) + until n == 0 + -- 1/(1+x) => \\FRAC{1}{1+x} + repeat + str, n = gsub(str,"([%.%d%w]+)/(%b())", function(a,b) + return "\\FRAC{" .. a .. "}{" .. sub(b,2,-2) .. "}" + end ) + until n == 0 + -- 1/x => \\FRAC{1}{x} + repeat + str, n = gsub(str,"([%.%d%w]+)/([%+%-]?[%.%d%w]+)", "\\FRAC{%1}{%2}") + until n == 0 + -- times + str = gsub(str,"%*", " ") + -- symbols -- we can use a table substitution here + str = gsub(str,"([<>=][<>=]*)", symbols) + -- functions + str = nsub(str,"sqrt", "\\SQRT{", "}") + str = nsub(str,"exp", "e^{", "}") + str = nsub(str,"abs", "\\left|", "\\right|") + -- d/D + str = nsub(str,"D", "{\\FRAC{\\MBOX{d}}{\\MBOX{d}x}{(", ")}}") + str = gsub(str,"D([xy])", "\\FRAC{{\\RM d}%1}{{\\RM d}x}") + -- f/g + for k,v in next, list_3 do -- todo : prepare k,v + str = nsub(str,"D"..v,"{\\RM "..v.."}^{\\PRIME}(",")") + str = nsub(str,v,"{\\RM "..v.."}(",")") + end + -- more symbols + for k,v in next, list_4_1 do + str = gsub(str,k,v) + end + -- parenthesis (optional) + if mode == 2 then + str = gsub(str,"%(", "\\left(") + str = gsub(str,"%)", "\\right)") + end + -- csnames + str = gsub(str,"(\\[A-Z]+)", lower) + -- report + return str +end + +calcmath.totex = totex + +function calcmath.tex(str,mode) + context(totex(str)) +end + +function calcmath.xml(id,mode) + context(totex(lxml.id(id).dt[1],mode)) +end + +-- work in progress ... lpeg variant + +if false then + + -- todo: + + -- maybe rewrite to current lpeg, i.e. string replacement and no Cc's + + -- table approach we have now is less efficient but more flexible + + -- D \frac {\rm d} {{\rm d}x} + -- Dx Dy \frac {{\rm d}y} {{\rm d}x} + -- Df Dg {\rm f}^{\prime} + -- f() g() {\rm f}() + + -- valid utf8 + + local S, P, R, C, V, Cc, Ct = lpeg.S, lpeg.P, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Ct + + local space = S(" \n\r\t")^0 + local integer = P("-")^-1 * R("09")^1 + local realpart = P("-")^-1 * R("09")^1 * S(".")^1 * R("09")^1 + local number = Cc("number") * C(integer) * space + local real = Cc("real") * C(realpart) * space + local float = Cc("float") * C(realpart) * lpeg.P("E") * lpeg.C(integer) * space + local identifier = Cc("identifier") * C(R("az","AZ")) * space + local compareop = Cc("compare") * C(P("<") + P("=") + P(">") + P(">=") + P("<=") + P(">") + P("<")) * space + local factorop = Cc("factor") * C(S("+-^_,")) * space + local termop = Cc("term") * C(S("*/")) * space + local constant = Cc("constant") * C(P("pi") + lpeg.P("inf")) * space + local functionop = Cc("function") * C(R("az")^1) * space + local open = P("(") * space + local close = P(")") * space + + local grammar = P { + "expression", + expression = Ct(V("factor") * ((factorop+compareop) * V("factor"))^0), + factor = Ct(V("term") * (termop * V("term"))^0), + term = Ct( + float + real + number + + (open * V("expression") * close) + + (functionop * open * (V("expression") * (P(",") * V("expression"))^0) * close) + + (functionop * V("term")) + + constant + identifier + ), + } + + local parser = space * grammar * -1 + + local function has_factor(t) + for i=1,#t do + if t[i] == "factor" then + return true + end + end + end + + -- can be sped up if needed ... + + function totex(t) + if t then + local one = t[1] + if type(one) == "string" then + local two, three = t[2], t[3] + if one == "number" then + context(two) + elseif one == "real" then + context(two) + elseif one == "float" then + context("\\scinot{",two,"}{",three,"}") + elseif one == "identifier" then + context(two) + elseif one == "constant" then + context("\\"..two) + elseif one == "function" then + if two == "sqrt" then + context("\\sqrt{") + totex(three) + context("}") + elseif two == "exp" then + context(" e^{") + totex(three) + context("}") + elseif two == "abs" then + context("\\left|") + totex(three) + context("\\right|") + elseif two == "mean" then + context("\\overline{") + totex(three) + context("}") + elseif two == "int" or two == "prod" or two == "sum" then + local four, five = t[4], t[5] + if five then + context("\\"..two.."^{") -- context[two]("{") + totex(three) + context("}_{") + totex(four) + context("}") + totex(five) + elseif four then + context("\\"..two.."^{") + totex(three) + context("}") + totex(four) + elseif three then + context("\\"..two.." ") -- " " not needed + totex(three) + else + context("\\"..two) + end + else + context("\\"..two.."(") + totex(three) + context(")") + end + end + else + local nt = #t + local hasfactor = has_factor(t) + if hasfactor then + context("\\left(") + end + totex(one) + for i=2,nt,3 do + local what, how, rest = t[i], t[i+1], t[i+2] + if what == "factor" then + if how == '^' or how == "_" then + context(how) + context("{") + totex(rest) + context("}") + else + context(how) + totex(rest) + end + elseif what == "term" then + if how == '/' then + context("\\frac{") + totex(rest) + context("}{") + totex(t[i+3] or "") + context("}") + elseif how == '*' then + context("\\times") + totex(rest) + else + context(how) + totex(three) + end + elseif what == "compare" then + if two == ">=" then + context("\\ge") + elseif two == "<=" then + context("\\le") + elseif two == ">" then + context(">") + elseif two == "<" then + context("<") + end + totex(three) + end + end + if hasfactor then + context("\\right)") + end + end + end + end + + calcmath = { } + + function calcmath.parse(str) + return lpegmatch(parser,str) + end + + function calcmath.tex(str) + str = totex(lpegmatch(parser,str)) + return (str == "" and "[error]") or str + end + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-calcmath.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-calcmath.mkiv new file mode 100644 index 00000000000..dda88bb3ee5 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-calcmath.mkiv @@ -0,0 +1,80 @@ +%D \module +%D [ file=m-calcmath, +%D version=2006.04.24, % 1999.11.06, +%D title=\CONTEXT\ Modules, +%D subtitle=Calculator Math, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Lua code. + +\registerctxluafile{x-calcmath}{} + +\def\ctxmodulecalcmath#1{\ctxlua{moduledata.calcmath.#1}} + +%D Interface: + +\unprotect + +\unexpanded\def\inlinecalcmath #1{\mathematics{\ctxmodulecalcmath{tex("#1",1)}}} +\unexpanded\def\displaycalcmath#1{\startformula\ctxmodulecalcmath{tex("#1",2)}\stopformula} + +\let\calcmath\inlinecalcmath + +\let\icm\inlinecalcmath +\let\dcm\displaycalcmath + +\startxmlsetups xml:cam:define + \xmlsetsetup {\xmldocument} {cam:*} {*} + \xmlsetsetup {\xmldocument} {(icm|dcm)} {cam:*} +\stopxmlsetups + +\xmlregisterns{cam}{calcmath} + +\xmlregistersetup{xml:cam:define} + +% tex -> lua -> tex -> lua -> tex +% \mathematics{\ctxmodulecalcmath{xml(\!!bs\xmlflush{#1}\!!es,1)}} +% tex -> lua -> tex +% \mathematics{\ctxmodulecalcmath{xml("#1",1)}}% + +\startxmlsetups cam:i + \mathematics{\ctxmodulecalcmath{xml("#1",1)}}% +\stopxmlsetups + +\startxmlsetups cam:d + \startformula\ctxmodulecalcmath{xml("#1",2)}\stopformula +\stopxmlsetups + +\startxmlsetups cam:icm + \mathematics{\ctxmodulecalcmath{xml("#1",1)}} +\stopxmlsetups + +\startxmlsetups cam:dcm + \startformula\ctxmodulecalcmath{xml("#1",2)}\stopformula +\stopxmlsetups + +\protect \endinput + +\starttext + +% \calcmath{sin(x) + x^2 + x^(1+x) + 1/x^2 + mean(x+mean(y))} +% \calcmath{int(a,b,c)} +% \calcmath{(1+x)/(1+x) + (1+x)/(1+(1+x)/(1+x))} +% \calcmath{10E-2} +% \calcmath{(1+x)/x} +% \calcmath{(1+x)/12} +% \calcmath{(1+x)/-12} +% \calcmath{1/-12} +% \calcmath{12x/(1+x)} +% \calcmath{exp(x+exp(x+1))} +% \calcmath{abs(x+abs(x+1)) + pi + inf} +% \calcmath{Dx Dy} +% \calcmath{D(x+D(y))} +% \calcmath{Df(x)} +% \calcmath{g(x)} diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-cals.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-cals.lua new file mode 100644 index 00000000000..3af6106d803 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-cals.lua @@ -0,0 +1,221 @@ +if not modules then modules = { } end modules ['x-cals'] = { + version = 1.001, + comment = "companion to x-cals.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next = next +local format, lower = string.format, string.lower +local xmlsprint, xmlcprint, xmlcollected, xmlelements = xml.sprint, xml.cprint, xml.collected, xml.elements +local n_todimen, s_todimen = number.todimen, string.todimen + +-- there is room for speedups as well as cleanup (using context functions) + +local cals = { } +moduledata.cals = cals +lxml.mathml = cals -- for the moment + +cals.ignore_widths = false +cals.shrink_widths = false +cals.stretch_widths = false + +-- the following flags only apply to columns that have a specified width +-- +-- proportional : shrink or stretch proportionally to the width +-- equal : shrink or stretch equaly distributed +-- n < 1 : shrink or stretch proportionally to the width but multiplied by n +-- +-- more clever things, e.g. the same but applied to unspecified widths +-- has to happen at the core-ntb level (todo) + +local halignments = { + left = "flushleft", + right = "flushright", + center = "middle", + centre = "middle", + justify = "normal", +} + +local valignments = { + top = "high", + bottom = "low", + middle = "lohi", +} + +local function adapt(widths,b,w,delta,sum,n,what) + if b == "equal" then + delta = delta/n + for k, v in next, w do + widths[k] = n_todimen(v - delta) + end + elseif b == "proportional" then + delta = delta/sum + for k, v in next, w do + widths[k] = n_todimen(v - v*delta) + end + elseif type(b) == "number" and b < 1 then + delta = b*delta/sum + for k, v in next, w do + widths[k] = n_todimen(v - v*delta) + end + end +end + +local function getspecs(root, pattern, names, widths) + -- here, but actually we need this in core-ntb.tex + -- but ideally we need an mkiv enhanced core-ntb.tex + local ignore_widths = cals.ignore_widths +-- local shrink_widths = at.option == "shrink" or cals.shrink_widths +-- local stretch_widths = at.option == "stretch" or cals.stretch_widths + local shrink_widths = cals.shrink_widths + local stretch_widths = cals.stretch_widths + for e in xmlcollected(root,pattern) do + local at = e.at + local column = at.colnum + if column then + if not ignore_widths then + local width = at.colwidth + if width then + widths[tonumber(column)] = lower(width) + end + end + local name = at.colname + if name then + names[name] = tonumber(column) + end + end + end + if ignore_width then + -- forget about it + elseif shrink_widths or stretch_widths then + local sum, n, w = 0, 0, { } + for _, v in next, widths do + n = n + 1 + v = (type(v) == "string" and s_todimen(v)) or v + if v then + w[n] = v + sum = sum + v + end + end + local hsize = tex.hsize + if type(hsize) == "string" then + hsize = s_todimen(hsize) + end + local delta = sum - hsize + if shrink_widths and delta > 0 then + adapt(widths,shrink_widths,w,delta,sum,n,"shrink") + elseif stretch_widths and delta < 0 then + adapt(widths,stretch_widths,w,delta,sum,n,"stretch") + end + end +end + +local function getspans(root, pattern, names, spans) + for e in xmlcollected(root,pattern) do + local at = e.at + local name, namest, nameend = at.colname, names[at.namest or "?"], names[at.nameend or "?"] + if name and namest and nameend then + spans[name] = tonumber(nameend) - tonumber(namest) + 1 + end + end +end + +local bTR, eTR, bTD, eTD = context.bTR, context.eTR, context.bTD, context.eTD + +function cals.table(root,namespace) + + local prefix = (namespace or "cals") .. ":" + + local prefix = namespace and namespace ~= "" and (namespace .. ":") or "" + local p = "/" .. prefix + + local tgroupspec = p .. "tgroup" + local colspec = p .. "colspec" + local spanspec = p .. "spanspec" + local hcolspec = p .. "thead" .. p .. "colspec" + local bcolspec = p .. "tbody" .. p .. "colspec" + local fcolspec = p .. "tfoot" .. p .. "colspec" + local entryspec = p .. "entry" .. "|" .. prefix .. "entrytbl" -- shouldn't that be p ? + local hrowspec = p .. "thead" .. p .. "row" + local browspec = p .. "tbody" .. p .. "row" + local frowspec = p .. "tfoot" .. p .. "row" + + local function tablepart(root, xcolspec, xrowspec, before, after) -- move this one outside + before() + local at = root.at + local pphalign, ppvalign = at.align, at.valign + local names, widths, spans = { }, { }, { } + getspecs(root, colspec , names, widths) + getspecs(root, xcolspec, names, widths) + getspans(root, spanspec, names, spans) + for r, d, k in xmlelements(root,xrowspec) do + bTR() + local dk = d[k] + local at = dk.at + local phalign, pvalign = at.align or pphalign, at.valign or ppvalign -- todo: __p__ test + local col = 1 + for rr, dd, kk in xmlelements(dk,entryspec) do + local dk = dd[kk] + if dk.tg == "entrytbl" then + -- bTD(function() cals.table(dk) end) + bTD() + context("{") + cals.table(dk) + context("}") + eTD() + col = col + 1 + else + local at = dk.at + local b, e, s, m = names[at.namest or "?"], names[at.nameend or "?"], spans[at.spanname or "?"], at.morerows + local halign, valign = at.align or phalign, at.valign or pvalign + if b and e then + s = e - b + 1 + end + if halign then + halign = halignments[halign] + end + if valign then + valign = valignments[valign] + end + local width = widths[col] + if s or m or halign or valign or width then -- currently only english interface ! + bTD { + nx = s or 1, + ny = (m or 0) + 1, + align = format("{%s,%s}",halign or "flushleft",valign or "high"), + width = width or "fit", + } + else + bTD { + align = "{flushleft,high}", + width = "fit", -- else problems with vertical material + } + end + xmlcprint(dk) + eTD() + col = col + (s or 1) + end + end + eTR() + end + after() + end + + for tgroup in lxml.collected(root,tgroupspec) do + context.directsetup("cals:table:before") + lxml.directives.before(root,"cdx") -- "cals:table" + context.bgroup() + lxml.directives.setup(root,"cdx") -- "cals:table" + context.bTABLE() + tablepart(tgroup, hcolspec, hrowspec, context.bTABLEhead, context.eTABLEhead) + tablepart(tgroup, bcolspec, browspec, context.bTABLEbody, context.eTABLEbody) + tablepart(tgroup, fcolspec, frowspec, context.bTABLEfoot, context.eTABLEfoot) + context.eTABLE() + context.egroup() + lxml.directives.after(root,"cdx") -- "cals:table" + context.directsetup("cals:table:after") + end + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-cals.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-cals.mkiv new file mode 100644 index 00000000000..31ba2d213a9 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-cals.mkiv @@ -0,0 +1,45 @@ +%D \module +%D [ file=x-cals, +%D version=2007.09.05, +%D title=\CONTEXT\ XML Modules, +%D subtitle=Cals table renderer, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt XML Macros / Cals Tables} + +\startmodule [cals] + +\registerctxluafile{x-cals}{} + +% \startxmlsetups xml:cals:process +% \xmlsetsetup {#1} {cals:table} {*} +% \stopxmlsetups +% \startxmlsetups cals:table +% \ctxlua{moduledata.cals.table("#1")} +% \stopxmlsetups +% \xmlregistersetup{xml:cals:process} + +\startxmlsetups xml:cals:process +% \xmlsetfunction {\xmldocument} {cals:table} {moduledata.cals.table} + \xmlsetfunction {#1} {cals:table} {moduledata.cals.table} +\stopxmlsetups + +\startxmlsetups xml:cals:nonamespace +% \xmlsetfunction {\xmldocument} {table} {moduledata.cals.table} + \xmlsetfunction {#1} {table} {moduledata.cals.table} +\stopxmlsetups + +\xmlregistersetup{xml:cals:process} + +\xmlregisterns{cals}{cals} + +%D One can register the nonamespace variant for cases where the cals +%D model is embedded in the parent DTD. + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-chemml.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-chemml.lua new file mode 100644 index 00000000000..79c1d9525ce --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-chemml.lua @@ -0,0 +1,51 @@ +if not modules then modules = { } end modules ['x-chemml'] = { + version = 1.001, + comment = "companion to x-chemml.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- not yet acceptable cld + +local format, lower, upper, gsub, sub, match = string.format, string.lower, string.upper, string.gsub, string.sub, string.match +local concat = table.concat + +local chemml = { } +local moduledata = moduledata or { } +moduledata.chemml = chemml + +function chemml.pi(id) + local str = xml.content(lxml.id(id)) + local _, class, key, value = match(str,"^(%S+)%s+(%S+)%s+(%S+)%s+(%S+)%s*$") + if key and value then + context("\\setupCMLappearance[%s][%s=%s]",class, key, value) + end +end + +function chemml.do_graphic(id) + local t = { } + for r, d, k in xml.elements(lxml.id(id),"cml:graphic") do + t[#t+1] = xml.tostring(d[k].dt) + end + context(concat(t,",")) +end + +function chemml.no_graphic(id) + local t = { } + for r, d, k in xml.elements(lxml.id(id),"cml:text|cml:oxidation|cml:annotation") do + local dk = d[k] + if dk.tg == "oxidation" then + t[#t+1] = format("\\chemicaloxidation{%s}{%s}{%s}",r.at.sign or "",r.at.n or 1,xml.tostring(dk.dt)) + elseif dk.tg == "annotation" then + local location = r.at.location or "r" + local caption = xml.content(xml.first(dk,"cml:caption")) + local text = xml.content(xml.first(dk,"cml:text")) + t[#t+1] = format("\\doCMLannotation{%s}{%s}{%s}",location,caption,text) + else + t[#t+1] = xml.tostring(dk.dt) or "" + end + end + context(concat(t,",")) +end + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-chemml.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-chemml.mkiv new file mode 100644 index 00000000000..f0511206e8b --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-chemml.mkiv @@ -0,0 +1,234 @@ +%D \module +%D [ file=x-cml, +%D version=2007.09.03, % reimplementation +%D title=\CONTEXT\ XML Modules, +%D subtitle=MkIV ChemML renderer, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% This needs an update! + +\writestatus{loading}{ConTeXt XML Macros / Chemistry} + +\registerctxluafile{x-chemml}{} + +\def\ctxmodulechemml#1{\ctxlua{moduledata.chemml.#1}} + +%D The following code assumes a load||flush approach to \XML. + +\unprotect + +\startxmlsetups xml:cml:process + \xmlstrip {#1} {cml:chem|cml:ichem|cml:dchem|cml:reaction|cml:molecule|cml:ion|cml:structure} + \xmlsetsetup {#1} {cml:*} {cml:*} + \xmlsetsetup {#1} {cml:gives|cml:equilibrium|cml:mesomeric} {cml:arrow} + \xmlsetsetup {#1} {cml:plus|cml:minus|cml:equal} {cml:operator} + \xmlsetsetup {#1} {cml:bond|cml:singlebond|cml:doublebound|cml:triplebond} {cml:bond} + \xmlsetsetup {#1} {pi::chemml} {cml:pi} +\stopxmlsetups + +\xmlregistersetup{xml:cml:process} + +\xmlregisterns{cml}{chemml} + +\unexpanded\def\setupCMLappearance[#1]{\dodoubleargument\getparameters[@@CML#1]} % old stuff + +\setupCMLappearance [ion] [\c!alternative=\v!a] + +\def\doifelseCMLvariable#1#2#3% id key value + {\doifelse{\xmlatt{#1}{#2}}{#3} + \firstoftwoarguments + {\doifelse{\getvalue{@@CML\xmltag{#1}#2}}{#3} + \firstoftwoarguments + \secondoftwoarguments}} + +\startxmlsetups cml:pi + \ctxmodulechemml{pi(#1)} +\stopxmlsetups + +\startxmlsetups cml:chem + \automathematics{\xmlflush{#1}} +\stopxmlsetups +\startxmlsetups cml:ichem + \inlinemathematics{\xmlflush{#1}} +\stopxmlsetups +\startxmlsetups cml:dchem + \displaymathematics{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups cml:reaction + \xmlflush{#1} +\stopxmlsetups + +\unexpanded\def\doCMLtext#1#2#3% main top bot + {\setbox0\hbox{\doifsomething{#2}{\txx\setstrut\strut\ignorespaces#2\unskip}}% + \setbox2\hbox{\ignorespaces\strut#1\unskip}% + \setbox4\hbox{\doifsomething{#3}{\txx\setstrut\strut\ignorespaces#3\unskip}}% + \scratchdimen=\wd2\advance\scratchdimen-.5em + \ifdim\wd0>\scratchdimen + \setbox0\hbox spread .5em{\hss\box0\hss}% + \fi + \ifdim\wd4>\scratchdimen + \setbox4\hbox spread .5em{\hss\box4\hss}% + \fi + \setbox6=\vbox + {\offinterlineskip\halign{\hss##\hss\cr\copy0\cr\copy2\cr\copy4\cr}}% + \hbox{\lower\ht4\hbox{\lower\dp2\box6}}} + +\def\doCMLamount#1% + {\scratchcounter0\xmlatt{#1}{n}\relax + \ifnum\scratchcounter>0 \number\scratchcounter \fi} + +\startxmlsetups cml:molecule + \doCMLtext + {\doCMLamount{#1} + \xmlall{#1}{cml:atom|cml:bond|cml:singlebond|cml:doublebond|cml:triplebond}} + {\xmlindex{#1}{cml:caption}{2}} + {\xmlindex{#1}{cml:caption}{1}} +\stopxmlsetups + +\startxmlsetups cml:atom + \doCMLtext { + \lohi { + \normalstartimath + \tfxx\xmlatt{#1}{protons}% + \normalstopimath + } { + \normalstartimath + \tfxx\xmlatt{#1}{weight}% + \normalstopimath + } + \xmlflush{#1} + \lohi { + \normalstartimath + \tfxx\xmlatt{#1}{n}% + \normalstopimath + } { + \normalstartimath + \tfxx\xmlatt{#1}{charge}% + \normalstopimath + } + } + {\xmlindex{#1}{cml:caption}{2}} + {\xmlindex{#1}{cml:caption}{1}} +\stopxmlsetups + +\startxmlsetups cml:ion + \doifelseCMLvariable{#1}{alternative}{b} { + \left[ + \doCMLtext + {\doCMLamount{#1} + \xmlall{#1}{cml:atom}} + {\xmlindex{#1}{cml:caption}{2}} + {\xmlindex{#1}{cml:caption}{1}} + \right] + } { + \doCMLtext + {\doCMLamount{#1} + \xmlall{#1}{cml:atom}} + {\xmlindex{#1}{cml:caption}{2}} + {\xmlindex{#1}{cml:caption}{1}} + } + \high {\xmlatt{#1}{charge}} +\stopxmlsetups + +\def\doCMLgives {\xrightarrow} +\def\doCMLequilibrium{\xleftrightarrow} +\def\doCMLmesomeric {\xrightoverleftarrow} +\def\doCMLplus {+} +\def\doCMLminus {-} +\def\doCMLequal {=} + +\startxmlsetups cml:arrow + \quad + \executeifdefined{doCML\xmlname{#1}}\doCMLgives{\tf\xmlindex{#1}{cml:caption}{2}}{\tf\xmlindex{#1}{cml:caption}{1}} + \quad +\stopxmlsetups + +\startxmlsetups cml:operator + \quad + \mathop{\executeifdefined{doCML\xmlname{#1}}\doCMLplus} + \quad +\stopxmlsetups + +\startxmlsetups cml:bond + \executeifdefined{doCML\xmlname{#1}} { + \ifcase0\xmlatt{#1}{n}\relax + \doCMLsinglebond + \or + \doCMLdoublebond + \or + \doCMLtriplebond + \fi + } +\stopxmlsetups + +\def\doCMLbond + {\hrule\s!width\hsize\s!height.1ex\relax} + +\def\dodoCMLbond#1#2#3% + {\begingroup + \setbox\scratchbox\hbox{\normalstartimath M\normalstopimath}% + \vbox to \ht\scratchbox + {\hsize\wd\scratchbox + \vskip.1\wd\scratchbox + #1\vfill#2\vfill#3% + \vskip.1\wd\scratchbox}% + \endgroup} + +\def\doCMLsinglebond{\dodoCMLbond\relax \doCMLbond\relax } +\def\doCMLdoublebond{\dodoCMLbond\doCMLbond\relax \doCMLbond} +\def\doCMLtriplebond{\dodoCMLbond\doCMLbond\doCMLbond\doCMLbond} + +\startxmlsetups cml:structure + \startchemical + \xmlall{#1}{cml:component} + \stopchemical +\stopxmlsetups + +% It makes not much sense to adapt ppchtex to accept different input. Maybe some day. + +\startxmlsetups cml:component + \expanded { + \chemical + [\ctxmodulechemml{do_graphic("#1")}] + [\ctxmodulechemml{no_graphic("#1")}] + } +\stopxmlsetups + +\unexpanded\def\doCMLannotation#1% #2#3% loc caption text + {\xmlval{cml:a:l}{#1}{\chemicalright}}% {#2}{#3}} + +\xmlmapvalue {cml:a:l} {t} {\chemicaltop} +\xmlmapvalue {cml:a:l} {b} {\chemicalbottom} +\xmlmapvalue {cml:a:l} {l} {\chemicalleft} +\xmlmapvalue {cml:a:l} {r} {\chemicalright} +\xmlmapvalue {cml:a:l} {lc} {\chemicalleftcentered} % \xmlmapvalue {cml:a:l} {cl} {\chemicalleftcentered} +\xmlmapvalue {cml:a:l} {rc} {\chemicalrightcentered} % \xmlmapvalue {cml:a:l} {cr} {\chemicalrightcentered} +\xmlmapvalue {cml:a:l} {tl} {\chemicaltopleft} % \xmlmapvalue {cml:a:l} {lt} {\chemicaltopleft} +\xmlmapvalue {cml:a:l} {bl} {\chemicalbottomleft} % \xmlmapvalue {cml:a:l} {lb} {\chemicalbottomleft} +\xmlmapvalue {cml:a:l} {tr} {\chemicaltopright} % \xmlmapvalue {cml:a:l} {rt} {\chemicaltopright} +\xmlmapvalue {cml:a:l} {br} {\chemicalbottomright} % \xmlmapvalue {cml:a:l} {rb} {\chemicalbottomright} +\xmlmapvalue {cml:a:l} {lt} {\chemicallefttop} % \xmlmapvalue {cml:a:l} {tl} {\chemicallefttop} +\xmlmapvalue {cml:a:l} {lb} {\chemicalleftbottom} % \xmlmapvalue {cml:a:l} {bl} {\chemicalleftbottom} +\xmlmapvalue {cml:a:l} {rt} {\chemicalrighttop} % \xmlmapvalue {cml:a:l} {tr} {\chemicalrighttop} +\xmlmapvalue {cml:a:l} {rb} {\chemicalrightbottom} % \xmlmapvalue {cml:a:l} {br} {\chemicalrightbottom} +\xmlmapvalue {cml:a:l} {x} {\chemicaltighttext} +\xmlmapvalue {cml:a:l} {sl} {\chemicalsmashedleft} % \xmlmapvalue {cml:a:l} {ls} {\chemicalsmashedleft} +\xmlmapvalue {cml:a:l} {sm} {\chemicalsmashedmiddle} % \xmlmapvalue {cml:a:l} {ms} {\chemicalsmashedmiddle} +\xmlmapvalue {cml:a:l} {sr} {\chemicalsmashedright} % \xmlmapvalue {cml:a:l} {rs} {\chemicalsmashedright} + +\startxmlsetups cml:forever + \left[\xmlflush{#1}\right] +\stopxmlsetups + +% \starttext +% \xmlprocess{main}{cmltest.xml}{xml:process} +% \stoptext + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-ct.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-ct.lua new file mode 100644 index 00000000000..9c647e8e790 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-ct.lua @@ -0,0 +1,167 @@ +if not modules then modules = { } end modules ['x-ct'] = { + version = 1.001, + comment = "companion to x-ct.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- needs testing + +local xmlsprint, xmlcprint, xmlfilter, xmlcollected = xml.sprint, xml.cprint, xml.filter, xml.collected +local format, concat, rep, find = string.format, table.concat, string.rep, string.find + +moduledata.ct = moduledata.ct or { } + +local halignments = { + left = 'l', + flushleft = 'l', + right = 'r', + flushright = 'r', + center = 'c', + middle = 'c', + centre = 'c', + justify = '', +} + +local templates = { } + +function moduledata.ct.registertabulatetemplate(name,str) + templates[name] = str +end + +local function roottemplate(root) + local rt = root.at.template + if rt then + local template = templates[rt] + if template then + return template + else + if not find(rt,"|") then + rt = gsub(rt,",","|") + end + if not find(rt,"^|") then rt = "|" .. rt end + if not find(rt,"|$") then rt = rt .. "|" end + return rt + end + end +end + +local function specifiedtemplate(root,templatespec) + local template = { } + for e in xmlcollected(root,templatespec) do + local at = e.at + local tm = halignments[at.align] or "" + if toboolean(at.paragraph) then + tm = tm .. "p" + end + template[#template+1] = tm + end + if #template > 0 then + return "|" .. concat(template,"|") .. "|" + else + return nil + end +end + +local function autotemplate(root,rowspec,cellspec) + local max = 0 + for e in xmlcollected(root,rowspec) do + local n = xml.count(e,cellspec) + if n > max then max = n end + end + if max == 2 then + return "|l|p|" + elseif max > 0 then + return "|" .. rep("p|",max) + else + return nil + end +end + +local defaulttemplate = "|l|p|" + +function moduledata.ct.tabulate(root,namespace) + if not root then + return + else + root = lxml.id(root) + end + + local prefix = (namespace or "context") .. ":" + + local templatespec = "/" .. prefix .. "template" .. "/" .. prefix .. "column" + local bodyrowspec = "/" .. prefix .. "body" .. "/" .. prefix .. "row" + local cellspec = "/" .. prefix .. "cell" + + local template = + roottemplate (root) or + specifiedtemplate (root,templatespec) or + autotemplate (root,bodyrowspec,cellspec) or + defaulttemplate + + -- todo: head and foot + + local NC, NR = context.NC, context.NR + + lxml.directives.before(root,'cdx') + context.bgroup() + lxml.directives.setup(root,'cdx') + context.starttabulate { template } + for e in xmlcollected(root,bodyrowspec) do + NC() + for e in xmlcollected(e,cellspec) do + xmlcprint(e) + NC() + end + NR() + end + context.stoptabulate() + context.egroup() + lxml.directives.after(root,'cdx') + +end + +-- todo: use content and caption + +function moduledata.ct.combination(root,namespace) + + if not root then + return + else + root = lxml.id(root) + end + + local prefix = (namespace or "context") .. ":" + + local pairspec = "/" .. prefix .. "pair" + local contentspec = "/" .. prefix .. "content" .. "/text()" + local captionspec = "/" .. prefix .. "caption" .. "/text()" + + local nx, ny = root.at.nx, root.at.ny + + if not (nx or ny) then + nx = xml.count(root,pairspec) or 2 + end + local template = format("%s*%s", nx or 1, ny or 1) + + lxml.directives.before(root,'cdx') + context.bgroup() + lxml.directives.setup(root,'cdx') + context.startcombination { template } + for e in xmlcollected(root,pairspec) do + -- context.combination( + -- function() xmlfilter(e,contentspec) end, + -- function() xmlfilter(e,captionspec) end + -- ) + context("{") + xmlfilter(e,contentspec) + context("}{") + xmlfilter(e,captionspec) + context("}") + end + context.stopcombination() + context.egroup() + lxml.directives.after(root,'cdx') + +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-ct.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-ct.mkiv new file mode 100644 index 00000000000..6a6352f0359 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-ct.mkiv @@ -0,0 +1,29 @@ +%D \module +%D [ file=x-cals, +%D version=2007.09.05, +%D title=\CONTEXT\ XML Modules, +%D subtitle=\CONTEXT\ Structures, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt XML Macros / Basics} + +\startmodule [ct] + +\registerctxluafile{x-ct}{} + +\startxmlsetups xml:context:process + \xmlsetfunction {\xmldocument} {context:tabulate} {moduledata.ct.tabulate} + \xmlsetfunction {\xmldocument} {context:combination} {moduledata.ct.combination} +\stopxmlsetups + +\xmlregistersetup{xml:context:process} + +\xmlregisterns{context}{context} + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-entities.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-entities.mkiv new file mode 100644 index 00000000000..3dd02118adf --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-entities.mkiv @@ -0,0 +1,18 @@ +%D \module +%D [ file=x-entities, +%D version=2008.05.29, +%D title=\CONTEXT\ XML Modules, +%D subtitle=\HTML\ entities, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt XML Macros / HTML entities} + +\ctxlua{characters.registerentities()} + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-foxet.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-foxet.mkiv new file mode 100644 index 00000000000..80fe7e500ca --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-foxet.mkiv @@ -0,0 +1,29 @@ +%D \module +%D [ file=x-foxet, +%D version=2004.03.12, % based on earlier experiments +%D title=\FOXET, +%D subtitle=Formatting Objects, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Nota bene: I will reimplement formatting object in proper +%D \MKIV\ code. + +\writestatus{foxet}{the mkiv variant is under construction} + +%D This module is just a shortcut for: + +% fo = basic formatting objects +% fe = basic formatting extensions +% fx = extra formatting objects +% fu = user formatting objects +% fs = setup + +% \usemodule[fo,fe,fx,fu,fs,mathml] + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-html.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-html.mkiv new file mode 100644 index 00000000000..e1806eb9eb0 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-html.mkiv @@ -0,0 +1,379 @@ +%D \module +%D [ file=x-html, +%D version=2011.02.03, % adapted 2014.11.08 +%D title=\CONTEXT\ Modules, +%D subtitle=HTML, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\startmodule[html] + +%D Usage: +%D +%D \starttyping +%D \xmlregistersetup{xml:html:basics} +%D \xmlregistersetup{xml:html:tables} +%D \stoptyping + +% \xmlsetsetup{#1}{(p|span)[@lang]}{xml:html:lang} +% +% \startxmlsetups xml:html:lang +% \begingroup +% \language[\xmlatt{#1}{lang}] +% \xmlsetup{#1}{xml:html:\xmltag{#1}} +% \endgroup +% \stopxmlsetups + +\unprotect + +\definehighlight[b] [\c!command=\v!no,\c!style=\v!bold] +\definehighlight[i] [\c!command=\v!no,\c!style=\v!italic] +\definehighlight[bi] [\c!command=\v!no,\c!style=\v!bolditalic] +\definehighlight[em] [\c!command=\v!no,\c!style=\em] +\definehighlight[tt] [\c!command=\v!no,\c!style=\v!mono] +\definehighlight[strong][\c!command=\v!no,\c!style=\v!bold] +\definehighlight[u] [\c!command=\v!no,\c!style=\directsetbar{\v!underbar}] +\definehighlight[code] [\c!command=\v!no,\c!style=\v!mono] +\definehighlight[pre] [\c!command=\v!no] + +\protect + +% todo: pre + +\startxmlsetups xml:html:basics + \xmlsetsetup{#1}{p|br|b|i|u|em|tt|strong|ul|ol|li|table|thead|tbody|tfoot|tr|td|th|span|img}{xml:html:*} + \xmlsetsetup{#1}{b/i}{xml:html:bi} + \xmlsetsetup{#1}{i/b}{xml:html:bi} + \xmlstripanywhere{#1}{!pre} +\stopxmlsetups + +\startxmlsetups xml:html:tables + \xmlsetsetup{#1}{table|thead|tbody|tfoot|tr|td|th}{xml:html:*} +\stopxmlsetups + +\startxmlsetups xml:html:p + \xmldoifnotselfempty {#1} { + \dontleavehmode + \ignorespaces + \xmlflush{#1} + \removeunwantedspaces + } + \par +\stopxmlsetups + +\startxmlsetups xml:html:br + \crlf +\stopxmlsetups + +\startxmlsetups xml:html:b + \directhighlight{b}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:i + \directhighlight{i}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:bi + \directhighlight{bi}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:em + \directhighlight{em}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:tt + \directhighlight{tt}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:strong + \directhighlight{strong}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:u + \directhighlight{u}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:ul + \startitemize[packed] + \xmlflush{#1} + \stopitemize +\stopxmlsetups + +\startxmlsetups xml:html:ol + \startitemize[packed,n] + \xmlflush{#1} + \stopitemize +\stopxmlsetups + +\startxmlsetups xml:html:li + \startitem + \xmlflush{#1} + \stopitem +\stopxmlsetups + +\startxmlsetups xml:html:code + \directhighlight{code}{\xmlflushspacewise{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:pre + \directhighlight{pre}{\xmlflushspacewise{#1}} +\stopxmlsetups + +\startxmlsetups xml:html:span + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:html:img + \ifhmode + \dontleavehmode + \externalfigure[\xmlatt{#1}{src}] + \else + \startlinecorrection + \externalfigure[\xmlatt{#1}{src}] + \stoplinecorrection + \fi +\stopxmlsetups + +% tables, maybe we need a generic html table module +% +% todo: align + +% beware, the padding code is somewhat experimental, eventually the +% table will be done in cld code +% +% we can also use \xmlmap for border etc + +\starttexdefinition cssgetsinglepadding #1 + \ctxlua { + context((moduledata.css.padding( + "#1", + \number\dimexpr0.1ex, + \number\dimexpr0.01\hsize, + \number\dimexpr1ex, + \number\dimexpr1em + ))) % returns 4 values therefore () + }sp +\stoptexdefinition + +\startxmlsetups xml:html:table + \edef\CellPadding{\xmlatt{#1}{cellpadding}} + \ifx\CellPadding\empty + \edef\CellPadding{.25ex} + \else + \edef\CellPadding{\cssgetsinglepadding\CellPadding} + \fi + \startlinecorrection[blank] + \doifelse {\xmlatt{#1}{border}} {0} { + \bTABLE[frame=off,offset=\CellPadding] + \xmlflush{#1} + \eTABLE + } { + \bTABLE[offset=\CellPadding] + \xmlflush{#1} + \eTABLE + } + \stoplinecorrection +\stopxmlsetups + +\startxmlsetups xml:html:thead + \bTABLEhead + \xmlflush{#1} + \eTABLEhead +\stopxmlsetups + +\startxmlsetups xml:html:tbody + \bTABLEbody + \xmlflush{#1} + \eTABLEbody +\stopxmlsetups + +\startxmlsetups xml:html:tfoot + \bTABLEfoot + \xmlflush{#1} + \eTABLEfoot +\stopxmlsetups + +\startxmlsetups xml:html:tr + \bTR[ny=\xmlattdef{#1}{rowspan}{1}] + \xmlflush{#1} + \eTR +\stopxmlsetups + +\startxmlsetups xml:html:td + \bTD[nx=\xmlattdef{#1}{colspan}{1}] + \xmlflush{#1} + \eTD +\stopxmlsetups + +\startxmlsetups xml:html:th + \bTH[nx=\xmlattdef{#1}{colspan}{1}] + \xmlflush{#1} + \eTH +\stopxmlsetups + +% \xmlregistersetup{xml:html:basics} + +%D For old times sake: + +\startxmlsetups xml:setups:common + \xmlsetup{#1}{xml:html:basics} + \xmlsetup{#1}{xml:html:tables} +% \ifconditional\qmlcleanuptwo +% \xmlsetsetup{#1}{html/br[index() == 1]}{xml:noppes:1} +% \xmlsetsetup{#1}{html/p[index() == lastindex()]/br[index() == lastindex()]}{xml:noppes:2} +% \xmlsetsetup{#1}{html/br[index() == lastindex()]}{xml:noppes:3} +% \xmlsetsetup{#1}{br[name(1) == 'img']}{xml:noppes} +% \xmlsetsetup{#1}{br[name(1) == 'br' and name(2) == 'img']}{xml:noppes} +% % \xmlsetsetup{#1}{br/following-sibling::img[position()==1]}{xml:noppes} +% \fi +\stopxmlsetups + +\stopmodule + +\continueifinputfile{x-html.mkiv} + +\xmlregistersetup{xml:html:basics} +\xmlregistersetup{xml:html:tables} + +\startxmlsetups xml:whatever + \xmlsetsetup {#1} { + html|body + } {xml:html:*} +\stopxmlsetups + +\xmlregisterdocumentsetup{main}{xml:whatever} + +\startxmlsetups xml:html:html + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:html:body + \xmlflush{#1} +\stopxmlsetups + +\setuphead[subject][page=yes,style=\bfa] + +\starttexdefinition ShowExample#1 + \startsubject[title=#1] + \typebuffer[#1] + \starttextrule{result} + \xmlprocessbuffer{main}{#1}{} + \stoptextrule + \stopsubject +\stoptexdefinition + +\starttext + +\startbuffer[test 1] +<html><body> +<p>test</p> +<p/> +<p>test</p> +</body></html> +\stopbuffer + +\startbuffer[test 2] +<html><body> +<p>test (hierna een lf) +test</p> +</body></html> +\stopbuffer + +\startbuffer[test 3] +<html><body> +<p>test (hierna een lf met lege regel) + +test</p> +</body></html> +\stopbuffer + +\startbuffer[test 4] +<html><body> +<p>test (hierna een lf met twee lege regels) + + +test</p> +</body></html> +\stopbuffer + +\startbuffer[test 5] +<html><body> +<p>test (hierna br geen lf)<br/> test</p> +</body></html> +\stopbuffer + +\startbuffer[test 6] +<html><body> +<p>test (hierna br met lf)<br/> +test</p> +</body></html> +\stopbuffer + +\startbuffer[test 7] +<html><body> +<p>test (hierna br met lf en lege regel)<br/> + +test</p> +</body></html> +\stopbuffer + +\startbuffer[test 8] +<html><body> +<p>test (hierna br met lf en twee lege regels)<br/> + + +test</p> +</body></html> +\stopbuffer + +\startbuffer[test 9] +<html><body> +<p>test (hierna bold) <b>bold</b> test</p> +</body></html> +\stopbuffer + +\startbuffer[test 10] +<html><body> +<p>test (hierna lf met bold) +<b>bold <u>underlined</u></b> test</p> +</body></html> +\stopbuffer + +\startbuffer[test 11] +<html><body> +<p>test (hierna lf met lege regel en bold) + +<b>bold</b> test</p> +</body></html> +\stopbuffer + +\startbuffer[test 12] +<html><body> +<p>test (hierna lf met lege regel en lf in bold) + +<b> +bold +</b> test</p> +</body></html> +\stopbuffer + +\startbuffer[test 13] +<html><body> +<p>test (hierna lf met lege regel en lf en lege regel in bold) + +<b> + +bold + +</b> test</p> +</body></html> +\stopbuffer + +\dorecurse{13}{\ShowExample{test #1}} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.ctx b/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.ctx new file mode 100644 index 00000000000..edbffc2854c --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.ctx @@ -0,0 +1,23 @@ +<?xml version='1.0' standalone='yes'?> + +<ctx:job> + <ctx:message>Lua Documentation Generator</ctx:message> + <ctx:preprocess> + <ctx:processors> + <ctx:processor name='ldx'>mtxrun --script x-ldx.lua <ctx:value name='old'/> <ctx:value name='new'/></ctx:processor> + </ctx:processors> + <ctx:files> + <ctx:file processor='ldx'><ctx:value name='old'/></ctx:file> + </ctx:files> + </ctx:preprocess> + <ctx:flags> + <ctx:flag>purge</ctx:flag> + <ctx:flag>forcexml</ctx:flag> + </ctx:flags> + <ctx:process> + <ctx:resources> + <ctx:environment>x-ldx.mkiv</ctx:environment> + </ctx:resources> + </ctx:process> +</ctx:job> + diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.lua new file mode 100644 index 00000000000..31cbebf1392 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.lua @@ -0,0 +1,341 @@ +if not modules then modules = { } end modules ['x-ldx'] = { + version = 1.001, + comment = "companion to x-ldx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- --[[ldx-- +-- <topic>Introduction</topic> +-- --ldx]]-- + +--[[ldx-- +<source>Lua Documentation Module</source> + +This file is part of the <logo label='context'/> documentation suite and +itself serves as an example of using <logo label='lua'/> in combination +with <logo label='tex'/>. + +I will rewrite this using lpeg. On the other hand, we cannot expect proper +<logo label='tex'/> and for educational purposed the syntax might be wrong. +--ldx]]-- + +-- there is a nice parser on from http://lua-users.org/wiki/LpegRecipes (by +-- Patrick Donnelly) but lua crashes when I apply functions to some of the +-- matches + +banner = "version 1.0.1 - 2007+ - PRAGMA ADE / CONTEXT" + +--[[ +This script needs a few libraries. Instead of merging the code here +we can use + +<typing> +mtxrun --internal x-ldx.lua +</typing> + +That way, the libraries included in the runner will be used. +]]-- + +-- libraries l-string.lua l-table.lua l-io.lua l-file.lua + +-- begin library merge +-- end library merge + +local gsub, find, sub = string.gsub, string.find, string.sub +local splitstring, emptystring = string.split, string.is_empty +local concat = table.concat + +--[[ +Just a demo comment line. We will handle such multiline comments but +only when they start and end at the beginning of a line. More rich +comments are tagged differently. +]]-- + +--[[ldx-- +First we define a proper namespace for this module. The <q>l</q> stands for +<logo label='lua'/>, the <q>d</q> for documentation and the <q>x</q> for +<logo label='xml'/>. +--ldx]]-- + +if not ldx then ldx = { } end + +--[[ldx-- +We load the lua file into a table. The entries in this table themselves are +tables and have keys like <t>code</t> and <t>comment</t>. +--ldx]]-- + +function ldx.load(filename) + local data = file.readdata(filename) + local expr = "%s*%-%-%[%[ldx%-*%s*(.-)%s*%-%-ldx%]%]%-*%s*" + local i, j, t = 0, 0, { } + while true do + local comment, ni + ni, j, comment = find(data, expr, j) + if not ni then break end + t[#t+1] = { code = sub(data, i, ni-1) } + t[#t+1] = { comment = comment } + i = j + 1 + end + local str = sub(data, i, #data) + str = gsub(str, "^%s*(.-)%s*$", "%1") + if #str > 0 then + t[#t+1] = { code = str } + end + return t +end + +--[[ldx-- +We will tag keywords so that we can higlight them using a special font +or color. Users can extend this list when needed. +--ldx]]-- + +ldx.keywords = { } + +--[[ldx-- +Here come the reserved words: +--ldx]]-- + +ldx.keywords.reserved = { + ["and"] = 1, + ["break"] = 1, + ["do"] = 1, + ["else"] = 1, + ["elseif"] = 1, + ["end"] = 1, + ["false"] = 1, + ["for"] = 1, + ["function"] = 1, + ["if"] = 1, + ["in"] = 1, + ["local"] = 1, + ["nil"] = 1, + ["not"] = 1, + ["or"] = 1, + ["repeat"] = 1, + ["return"] = 1, + ["then"] = 1, + ["true"] = 1, + ["until"] = 1, + ["while"] = 1 +} + +--[[ldx-- +We need to escape a few tokens. We keep the hash local to the +definition but set it up only once, hence the <key>do</key> +construction. +--ldx]]-- + +do + local e = { [">"] = ">", ["<"] = "<", ["&"] = "&" } + function ldx.escape(str) + return (gsub(str, "([><&])",e)) + end +end + +--[[ldx-- +Enhancing the code is a bit tricky due to the fact that we have to +deal with strings and escaped quotes within these strings. Before we +mess around with the code, we hide the strings, and after that we +insert them again. Single and double quoted strings are tagged so +that we can use a different font to highlight them. +--ldx]]-- + +ldx.make_index = true + +function ldx.enhance(data) -- i need to use lpeg and then we can properly autoindent -) + local e = ldx.escape + for k=1,#data do + local v = data[k] + if v.code then + local dqs, sqs, com, cmt, cod = { }, { }, { }, { }, e(v.code) + cod = gsub(cod, '\\"', "##d##") + cod = gsub(cod, "\\'", "##s##") + cod = gsub(cod, "%-%-%[%[.-%]%]%-%-", function(s) + cmt[#cmt+1] = s + return "<l<<<".. #cmt ..">>>l>" + end) + cod = gsub(cod, "%-%-([^\n]*)", function(s) + com[#com+1] = s + return "<c<<<".. #com ..">>>c>" + end) + cod = gsub(cod, "(%b\"\")", function(s) + dqs[#dqs+1] = sub(s,2,-2) or "" + return "<d<<<".. #dqs ..">>>d>" + end) + cod = gsub(cod, "(%b\'\')", function(s) + sqs[#sqs+1] = sub(s,2,-2) or "" + return "<s<<<".. #sqs ..">>>s>" + end) + cod = gsub(cod, "(%a+)",function(key) + local class = ldx.keywords.reserved[key] + if class then + return "<key class='" .. class .. "'>" .. key .. "</key>" + else + return key + end + end) + cod = gsub(cod, "<s<<<(%d+)>>>s>", function(s) + return "<sqs>" .. sqs[tonumber(s)] .. "</sqs>" + end) + cod = gsub(cod, "<d<<<(%d+)>>>d>", function(s) + return "<dqs>" .. dqs[tonumber(s)] .. "</dqs>" + end) + cod = gsub(cod, "<c<<<(%d+)>>>c>", function(s) + return "<com>" .. com[tonumber(s)] .. "</com>" + end) + cod = gsub(cod, "<l<<<(%d+)>>>l>", function(s) + return cmt[tonumber(s)] + end) + cod = gsub(cod, "##d##", "\\\"") + cod = gsub(cod, "##s##", "\\\'") + if ldx.make_index then + local lines = splitstring(cod,"\n") + local f = "(<key class='1'>function</key>)%s+([%w%.]+)%s*%(" + for k=1,#lines do + local v = lines[k] + -- functies + v = gsub(v,f,function(key, str) + return "<function>" .. str .. "</function>(" + end) + -- variables + v = gsub(v,"^([%w][%w%,%s]-)(=[^=])",function(str, rest) + local t = splitstring(str,",%s*") + for k=1,#t do + t[k] = "<variable>" .. t[k] .. "</variable>" + end + return concat(t,", ") .. rest + end) + -- so far + lines[k] = v + end + v.code = concat(lines,"\n") + else + v.code = cod + end + end + end +end + +--[[ldx-- +We're now ready to save the file in <logo label='xml'/> format. This boils +down to wrapping the code and comment as well as the whole document. We tag +lines in the code as such so that we don't need messy <t>CDATA</t> constructs +and by calculating the indentation we also avoid space troubles. It also makes +it possible to change the indentation afterwards. +--ldx]]-- + +function ldx.as_xml(data) -- ldx: not needed + local t, cmode = { }, false + t[#t+1] = "<?xml version='1.0' standalone='yes'?>\n" + t[#t+1] = "\n<document xmlns:ldx='http://www.pragma-ade.com/schemas/ldx.rng' xmlns='http://www.pragma-ade.com/schemas/ldx.rng'>\n" + for k=1,#data do + local v = data[k] + if v.code and not emptystring(v.code) then + t[#t+1] = "\n<code>\n" + local split = splitstring(v.code,"\n") + for k=1,#split do -- make this faster + local v = split[k] + local a, b = find(v,"^(%s+)") + if v then v = gsub(v,"[\n\r ]+$","") end + if a and b then + v = sub(v,b+1,#v) + if cmode then + t[#t+1] = "<line comment='yes' n='" .. b .. "'>" .. v .. "</line>\n" + else + t[#t+1] = "<line n='" .. b .. "'>" .. v .. "</line>\n" + end + elseif emptystring(v) then + if cmode then + t[#t+1] = "<line comment='yes'/>\n" + else + t[#t+1] = "<line/>\n" + end + elseif find(v,"^%-%-%[%[") then + t[#t+1] = "<line comment='yes'>" .. v .. "</line>\n" + cmode= true + elseif find(v,"^%]%]%-%-") then + t[#t+1] = "<line comment='yes'>" .. v .. "</line>\n" + cmode= false + elseif cmode then + t[#t+1] = "<line comment='yes'>" .. v .. "</line>\n" + else + t[#t+1] = "<line>" .. v .. "</line>\n" + end + end + t[#t+1] = "</code>\n" + elseif v.comment then + t[#t+1] = "\n<comment>\n" .. v.comment .. "\n</comment>\n" + else + -- cannot happen + end + end + t[#t+1] = "\n</document>\n" + return concat(t,"") +end + +--[[ldx-- +Saving the result is a trivial effort. +--ldx]]-- + +function ldx.save(filename,data) + file.savedata(filename,ldx.as_xml(data)) +end + +--[[ldx-- +The next function wraps it all in one call: +--ldx]]-- + +function ldx.convert(luaname,ldxname) + if not file.is_readable(luaname) then + luaname = luaname .. ".lua" + end + if file.is_readable(luaname) then + if not ldxname then + ldxname = file.replacesuffix(luaname,"ldx") + end + local data = ldx.load(luaname) + if data then + ldx.enhance(data) + if ldxname ~= luaname then + ldx.save(ldxname,data) + end + end + end +end + +--[[ldx-- +This module can be used directly: + +<typing> +mtxrun --internal x-ldx somefile.lua +</typing> + +will produce an ldx file that can be processed with <logo label='context'/> +by running: + +<typing> +context --use=x-ldx --forcexml somefile.ldx +</typing> + +You can do this in one step by saying: + +<typing> +context --ctx=x-ldx somefile.lua +</typing> + +This will trigger <logo label='context'/> into loading the mentioned +<logo label='ctx'/> file. That file describes the conversion as well +as the module to be used. + +The main conversion call is: +--ldx]]-- + +-- todo: assume usage of "mtxrun --script x-ldx", maybe make it mtx-ldx + +if environment.files and environment.files[1] then + ldx.convert(environment.files[1],environment.files[2]) +end + +--~ exit(1) diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.mkiv new file mode 100644 index 00000000000..0156f2c5569 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-ldx.mkiv @@ -0,0 +1,196 @@ +%D \module +%D [ file=x-ldx, +%D version=2008.06.03, +%D title=\CONTEXT\ Modules, +%D subtitle=Lua Source Pretty Printing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% this will become an extra + +\setupxml[default=hidden] + +\usemodule[x][mathml] +\usemodule[abr-02] + +\xmlregistersetup{xml:mml:define} +\xmlregistersetup{xml:ldx:define} + +\xmlregisterns{ldx}{ldx} + +\startxmlsetups xml:ldx:define + \xmlsetsetup {#1} {ldx:*} {ldx:*} +\stopxmlsetups + +% % % + +\startxmlsetups ldx:p + \xmlflush{#1}\par +\stopxmlsetups + +\startxmlsetups ldx:source + \source{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:key + \dontleavehmode{\bf\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:variable + \xmlflush{#1} +% \expanded{\variable{\xmlflush{#1}}} +\stopxmlsetups + +\startxmlsetups ldx:function + \dontleavehmode{\bf function}\space\xmlflush{#1} +% \expanded{\function{\xmlflush{#1}}} +\stopxmlsetups + +\startxmlsetups ldx:com + \dontleavehmode{\tt--\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:document + \page + \xmlflush{#1} + \determineregistercharacteristics[function] + \startmode[*register] + \testpage[4] + \extra{Functions} + \placeregister[function] + \stopmode + \determineregistercharacteristics[variable] + \startmode[*register] + \testpage[4] + \extra{Variables} + \placeregister[variable] + \stopmode +\stopxmlsetups + +\newcounter\CommentCounter + +\startxmlsetups ldx:comment + \blank + \doglobal\increment\CommentCounter + \margintitle{\bf\CommentCounter} + \xmlflush{#1} + \blank +\stopxmlsetups + +\startxmlsetups ldx:dqs + \dontleavehmode\bgroup\tt"\xmlflush{#1}"\egroup +\stopxmlsetups + +\startxmlsetups ldx:sqs + \dontleavehmode\bgroup\tt'\xmlflush{#1}'\egroup +\stopxmlsetups + +\startxmlsetups ldx:code + \startpacked + \xmlflush{#1}\relax + \stoppacked +\stopxmlsetups + +\startxmlsetups ldx:lines + \startpacked + \xmlflush{#1} + \stoppacked +\stopxmlsetups + +\startxmlsetups ldx:line + \doifelsenothing {\xmlflush{#1}} { + \xmlflush{#1}\crlf + } { + \dontleavehmode \hbox to \hsize \bgroup + \strut + \hskip.25\dimexpr\xmlattdef{#1}{n}{0}em\relax\relax % extra relax needed ! + \doif {\xmlatt{#1}{comment}} {yes} {\tt} + \xmlflush{#1} + \hss + \egroup + \endgraf + } +\stopxmlsetups + +\startxmlsetups ldx:logo + \uppercasestring\xmlatt{#1}{label}\xmlatt{#1}{name}\to\ascii + \ifx\ascii\empty\else\getvalue{\ascii}\fi +\stopxmlsetups + +\startxmlsetups ldx:l + \uppercasestring\xmlatt{#1}{l}\xmlatt{#1}{n}\to\ascii + \ifx\ascii\empty\else\getvalue{\ascii}\fi +\stopxmlsetups + +\startxmlsetups ldx:typing + \blank + \startpacked \tt + \xmlverbatim{#1} + \stoppacked + \blank +\stopxmlsetups + +\startxmlsetups ldx:type + \dontleavehmode{\tt\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups ldx:t + \dontleavehmode{\tt\xmlflush{#1}} +\stopxmlsetups + +% key -> kw +% dqs -> dq +% sqs -> sq +% line -> ln +% code -> cd +% comment -> tx (text) + +\definetypeface[mainfacenormal] [ss][sans] [iwona] [default] +\definetypeface[mainfacenormal] [rm][serif][palatino] [default] +\definetypeface[mainfacenormal] [tt][mono] [modern] [default][rscale=1] % 1.1 +\definetypeface[mainfacenormal] [mm][math] [iwona] [default][encoding=default] + +\definetypeface[mainfacemedium] [ss][sans] [iwona-medium][default] +\definetypeface[mainfacenormal] [rm][serif][palatino] [default] +\definetypeface[mainfacemedium] [tt][mono] [modern] [default][rscale=1] % 1.1 +\definetypeface[mainfacemedium] [mm][math] [iwona-medium][default][encoding=default] + +\definetypeface[mainfacenarrowtt][tt][mono] [modern-cond] [default][rscale=1] % 1.1 + +\setupbodyfont + [mainfacenormal,11pt] + +\setupwhitespace + [big] + +\defineregister[function][functions] +\defineregister[variable][variables] + +\definehead[source][subject] +\definehead[extra] [subsubject] +\definehead[topic] [subsubsubject] + +\setuphead + [source] + [style=\bfb] + +\setuphead + [extra] + [style=\bfa] + +\setuphead + [topic] + [style=\bf] + +\setuplayout + [width=middle, + height=middle, + backspace=2cm, + topspace=2cm] + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-math-svg.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-math-svg.lua new file mode 100644 index 00000000000..8a628816773 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-math-svg.lua @@ -0,0 +1,176 @@ +if not modules then modules = { } end modules ['x-math-svg'] = { + version = 1.001, + comment = "companion to x-math-svg.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tostring, type, next = tostring, type, next +local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs + +local xmlfirst = xml.first +local xmlconvert = xml.convert +local xmlload = xml.load +local xmlsave = xml.save +local xmlcollected = xml.collected +local xmldelete = xml.delete + +local loadtable = table.load +local savetable = table.save + +local replacesuffix = file.replacesuffix +local addsuffix = file.addsuffix +local removefile = os.remove +local isfile = lfs.isfile + +local formatters = string.formatters + +moduledata = moduledata or table.setmetatableindex("table") +local svgmath = moduledata.svgmath -- autodefined + +local namedata = { } +local pagedata = { } + +local statusname = "x-math-svg-status.lua" +local pdfname = "x-math-svg.pdf" + +local pdftosvg = os.which("mudraw") + +local f_make_tex = formatters[ [[context --global kpse:x-math-svg.mkvi --inputfile="%s" --svgstyle="%s" --batch --noconsole --once --purgeall]] ] +local f_make_svg = formatters[ [[mudraw -o "math-%%d.svg" "%s" 1-9999]] ] + +----- f_inline = formatters[ [[<div class='math-inline' style='vertical-align:%p'></div>]] ] +local f_inline = formatters[ [[<div class='math-inline'></div>]] ] +local f_display = formatters[ [[<div class='math-display'></div>]] ] +local f_style = formatters[ [[vertical-align:%p]] ] + +local f_math_tmp = formatters[ [[math-%i]] ] + +function svgmath.process(filename) + if not filename then + -- no filename given + return + elseif not isfile(filename) then + -- invalid filename + return + end + local index = 0 + local page = 0 + local blobs = { } + local root = xmlload(filename) + for mth in xmlcollected(root,"math") do + index = index + 1 + local blob = tostring(mth) + if blobs[blob] then + context.ReuseSVGMath(index,blobs[blob]) + else + page = page + 1 + buffers.assign(f_math_tmp(page),blob) + context.MakeSVGMath(index,page,mth.at.display) + blobs[blob] = page + end + end + context(function() + -- for tracing purposes: + for mathdata, pagenumber in next, blobs do + local p = pagedata[pagenumber] + p.mathml = mathdata + p.number = pagenumber + end + -- + savetable(statusname, { + pagedata = pagedata, + namedata = namedata, + }) + end) +end + +function svgmath.register(index,page,specification) + if specification then + pagedata[page] = specification + end + namedata[index] = page +end + +function svgmath.convert(filename,svgstyle) + if not filename then + -- no filename given + return false, "no filename" + elseif not isfile(filename) then + -- invalid filename + return false, "invalid filename" + elseif not pdftosvg then + return false, "mudraw is not installed" + end + + os.execute(f_make_tex(filename,svgstyle)) + + local data = loadtable(statusname) + if not data then + -- invalid tex run + return false, "invalid tex run" + elseif not next(data) then + return false, "no converson needed" + end + + local pagedata = data.pagedata + local namedata = data.namedata + + os.execute(f_make_svg(pdfname)) + + local root = xmlload(filename) + local index = 0 + local done = { } + local unique = 0 + + local between = (1-P("<"))^1/"" + local strip = Cs(( + (P("<text") * ((1-P("</text>"))^1) * P("</text>")) * between^0 / "" + + P(">") * between + + P(1) + )^1) + + for mth in xmlcollected(root,"m:math") do + index = index + 1 + local page = namedata[index] + if done[page] then + mth.__p__.dt[mth.ni] = done[page] + else + local info = pagedata[page] + local depth = info.depth + local mode = info.mode + local svgname = addsuffix(f_math_tmp(page),"svg") + local action = mode == "inline" and f_inline or f_display + -- local x_div = xmlfirst(xmlconvert(action(-depth)),"/div") + local x_div = xmlfirst(xmlconvert(action()),"/div") + local svgdata = io.loaddata(svgname) + if not svgdata or svgdata == "" then + print("error in:",svgname,tostring(mth)) + else + -- svgdata = string.gsub(svgdata,">%s<","") + svgdata = lpegmatch(strip,svgdata) + local x_svg = xmlfirst(xmlconvert(svgdata),"/svg") + -- xmldelete(x_svg,"text") +if mode == "inline" then + x_svg.at.style = f_style(-depth) +end + + x_div.dt = { x_svg } + mth.__p__.dt[mth.ni] = x_div -- use helper + end + done[page] = x_div + unique = unique + 1 + end + end + +-- for k, v in next, data do +-- removefile(addsuffix(k,"svg")) +-- end +-- removefile(statusname) +-- removefile(pdfname) + + xmlsave(root,filename) + + return true, index, unique +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-mathml-basics.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml-basics.mkiv new file mode 100644 index 00000000000..e166995b0c8 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml-basics.mkiv @@ -0,0 +1,276 @@ +% macros=mkvi + +% makes sense (but rel vs op ...): + +% \unexpanded\def\stackrel#1#2{\mathematics{\mathop{\let\limits\relax\mover{#2}{#1}}}} + +% this can become a core helper + +% bwe could do all of them in lua + +\startluacode +local find = string.find +local lpegmatch = lpeg.match + +local splitter = lpeg.Ct(lpeg.C(lpeg.patterns.nestedbraces + lpeg.patterns.utf8character)^1) + +function commands.xmfenced(left,middle,right,content) + local l = left ~= "" and left or "(" + local r = right ~= "" and right or ")" + local m = middle ~= "" and middle and lpegmatch(splitter,middle) or { "," } + local c = find(content,"{") and lpegmatch(splitter,content) or { content } + local n = #c + if n > 1 then + context("\\left%s",l) + for i=1,n do + if i > 1 then + context("%s %s",m[i] or m[#m],c[i]) + else + context(c[i]) + end + end + context("\\right%s",r) + else + context("\\left%s %s \\right%s",l,content,r) + end +end + +\stopluacode + +\unprotect + +\unexpanded\def\mexecuteifdefined#1% + {\ifx#1\empty + \expandafter\secondoftwoarguments + \else\ifcsname#1\endcsname + \doubleexpandafter\firstoftwoarguments + \else + \doubleexpandafter\secondoftwoarguments + \fi\fi + {\csname#1\endcsname}} + +% mrow + +\let\mrow\mathematics + +% msub msup msubsup + +\starttexdefinition msub #1#2 + \mathematics { + #1_{#2} + } +\stoptexdefinition + +\starttexdefinition msup #1#2 + \mathematics { + #1^{#2} + } +\stoptexdefinition + +\starttexdefinition msubsup #1#2#3 + \mathematics { + #1_{#2}^{#3} + } +\stoptexdefinition + +% mn mo mi + +\let\mn\mathematics +\let\mo\mathematics +\let\mi\mathematics + +% ms mtext + +\starttexdefinition ms #1 + \text { + "#1" + } +\stoptexdefinition + +\starttexdefinition mtext #1 + \text { + #1 + } +\stoptexdefinition + +% mover + +\starttexdefinition unexpanded moverabove #1 + \edef\movercommand{\utfmathfiller\movertoken} + \mexecuteifdefined\movercommand {#1} \relax +\stoptexdefinition +\starttexdefinition unexpanded moverbase #1 + \edef\mbasecommand{\utfmathfiller\mbasetoken} + \mexecuteifdefined\mbasecommand {#1} + \relax +\stoptexdefinition +\starttexdefinition unexpanded moverbasefiller #1#2 + \edef\mbasecommand{e\utfmathcommandfiller\mbasetoken} + \mexecuteifdefined\mbasecommand \relax {#2} {} +\stoptexdefinition +\starttexdefinition unexpanded moveraccent #1#2 + \edef\movercommand{\utfmathcommandabove\movertoken} + \mexecuteifdefined\movercommand \relax {#1} +\stoptexdefinition +\starttexdefinition unexpanded movertext #1#2 + % \mathtriplet {\mathstylehbox{#1}} {#2} {} + \mathtriplet {\mathematics{#1}} {#2} {} +\stoptexdefinition +\starttexdefinition unexpanded moveraccentchecker #1#2 + \edef\movertoken{\tochar{#2}} + \doifelseutfmathabove\movertoken \moveraccent \movertext {#1}{#2} +\stoptexdefinition + +\starttexdefinition unexpanded mover #1#2 + \mathematics { + \edef\mbasetoken{\tochar{#1}} + \doifelseutfmathfiller\mbasetoken \moverbasefiller \moveraccentchecker {#1}{#2} + } +\stoptexdefinition + +% munder + +\starttexdefinition unexpanded munderbelow #1 + \edef\mundercommand{\utfmathfiller\mundertoken} + \mexecuteifdefined\mundercommand {#1} \relax +\stoptexdefinition +\starttexdefinition unexpanded munderbase #1 + \edef\mbasecommand{\utfmathfiller\mbasetoken} + \mexecuteifdefined\mbasecommand {#1} + \relax +\stoptexdefinition +\starttexdefinition unexpanded munderbasefiller #1#2 + \edef\mbasecommand{e\utfmathcommandfiller\mbasetoken} + \mexecuteifdefined\mbasecommand \relax {#2} {} +\stoptexdefinition +\starttexdefinition unexpanded munderaccent #1#2 + \edef\mundercommand{\utfmathcommandbelow\mundertoken} + \mexecuteifdefined\mundercommand \relax {#1} +\stoptexdefinition +\starttexdefinition unexpanded mundertext #1#2 + % \mathtriplet {\mathstylehbox{#1}} {} {#2} + \mathtriplet {\mathematics{#1}} {} {#2} +\stoptexdefinition +\starttexdefinition unexpanded munderaccentchecker #1#2 + \edef\mundertoken{\tochar{#2}} + \doifelseutfmathbelow\mundertoken \munderaccent \mundertext {#1}{#2} +\stoptexdefinition + +\starttexdefinition unexpanded munder #1#2 + \mathematics { + \edef\mbasetoken{\tochar{#1}} + \doifelseutfmathfiller\mbasetoken \munderbasefiller \munderaccentchecker {#1}{#2} + } +\stoptexdefinition + +% munderover + +% mfenced + +% \mfenced{x,y} +% \mfenced{{x}{y}} +% \mfenced[separators]{{x}{y}} +% \mfenced[left][right]{{x}{y}} +% \mfenced[left][separators][right]{{x}{y}} + +\starttexdefinition unexpanded mfenced + \dotripleempty\do_mfenced +\stoptexdefinition + +\starttexdefinition unexpanded do_mfenced [#1][#2][#3]#4 + \mathematics { + \ctxcommand{xmfenced( + \ifthirdargument "#1","#2","#3"\else + \ifsecondargument "#1",",","#2"\else + \iffirstargument "(","#1",")"\else + "(",",",")"\fi\fi\fi + ,"#4")} + } +\stoptexdefinition + +% mfrac + +\starttexdefinition unexpanded mfrac #1#2 + \mathematics { + \frac{#1}{#2} + } +\stoptexdefinition + +% mroot msqrt + +\starttexdefinition unexpanded mroot #1#2 + \mathematics { + \sqrt[#1]{#2} + } +\stoptexdefinition + +\starttexdefinition unexpanded msqrt #1 + \mathematics { + \sqrt{#1} + } +\stoptexdefinition + +% menclose + +% merror + +% mglyph + +% mmultiscripts + +% mpadded + +% mphantom + +% mspace + +% mstyle + +% mtable mtr mlabeledtr mtd + +% maction + +% semantics + +\protect + +\continueifinputfile{x-mathml-basics.mkiv} + +\starttext + +$\mfenced{1+a}$\par +$\mfenced[,]{1+a}$\par +$\mfenced[,]{{1+a}{1+b}}$\par + +% $\mover{â†}{test}$\par +% $\mover{\utfchar{"2190}}{test}$\par +% $\mover{e:leftarrow}{test}$\par +% $\mover{x:2190}{test}$\par + +% $\mover{test}{âž}$\par +% $\mover{test}{\utfchar{"23DE}}$\par +% $\mover{test}{e:overbrace}$\par +% $\mover{test}{x:23DE}$\par +% $\mover{test}{over}$\par + +% \mover{test}{âž}\par +% \mover{test}{\utfchar{"23DE}}\par +% \mover{test}{e:overbrace}\par +% \mover{test}{x:23DE}\par + +% $\munder{â†}{test}$\par +% $\munder{\utfchar{"2190}}{test}$\par +% $\munder{e:leftarrow}{test}$\par +% $\munder{x:2190}{test}$\par + +% $\munder{test}{âŸ}$\par +% $\munder{test}{\utfchar{"23DF}}$\par +% $\munder{test}{e:underbrace}$\par +% $\munder{test}{x:23DF}$\par +% $\munder{test}{under}$\par + +% \math{{\msup{x}{2}\mo{+}\mn{2}\mi{x}\mo{+}\mi{b}}} + +% \mrow{\msup{x}{2}\mo{+}\mn{2}\mi{x}\mo{+}\mi{b}} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-mathml-html.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml-html.mkiv new file mode 100644 index 00000000000..2ac7d3cba87 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml-html.mkiv @@ -0,0 +1,40 @@ +%D \modul +%D [ file=x-mathml, +%D version=2014.05.18, +%D title=\CONTEXT\ XML Modules, +%D subtitle=\MATHML\ embedded HTML, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% maybe some more + +\startmodule [mathml-html] + +\startxmlsetups mml:html:b + \bold{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:html:i + \italic{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:html:tt + \mono{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:html:em + \emphasized{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:html + \xmlsetsetup{#1}{mml:b|mml:i|mml:tt|mml:em}{mml:html:*} +\stopxmlsetups + +\xmlregistersetup{mml:html} + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.lua b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.lua new file mode 100644 index 00000000000..7d0b42d2108 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.lua @@ -0,0 +1,898 @@ +if not modules then modules = { } end modules ['x-mathml'] = { + version = 1.001, + comment = "companion to x-mathml.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This needs an upgrade to the latest greatest mechanisms. But ... it +-- probably doesn't pay back as no mathml support ever did. + +local type, next = type, next +local formatters, lower, find, gsub, match = string.formatters, string.lower, string.find, string.gsub, string.match +local strip = string.strip +local xmlsprint, xmlcprint, xmltext, xmlcontent, xmlempty = xml.sprint, xml.cprint, xml.text, xml.content, xml.empty +local lxmlcollected, lxmlfilter = lxml.collected, lxml.filter +local getid = lxml.getid +local utfchar, utfcharacters, utfvalues, utfsplit, utflen = utf.char, utf.characters, utf.values, utf.split, utf.len +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local P, Cs = lpeg.P, lpeg.Cs + +local mathml = { } +moduledata.mathml = mathml +lxml.mathml = mathml -- for the moment + +local context = context + +local ctx_enabledelimiter = context.enabledelimiter +local ctx_disabledelimiter = context.disabledelimiter +local ctx_xmlflush = context.xmlflush -- better xmlsprint + +local ctx_halign = context.halign +local ctx_noalign = context.noalign +local ctx_bgroup = context.bgroup +local ctx_egroup = context.egroup +local ctx_crcr = context.crcr + +local ctx_bTABLE = context.bTABLE +local ctx_eTABLE = context.eTABLE +local ctx_bTR = context.bTR +local ctx_eTR = context.eTR +local ctx_bTD = context.bTD +local ctx_eTD = context.eTD + +local ctx_mn = context.mn +local ctx_mi = context.mi +local ctx_mo = context.mo +local ctx_startimath = context.startimath +local ctx_ignorespaces = context.ignorespaces +local ctx_removeunwantedspaces = context.removeunwantedspaces +local ctx_stopimath = context.stopimath + +local ctx_mmlapplycsymbol = context.mmlapplycsymbol + +local ctx_mathopnolimits = context.mathopnolimits +local ctx_left = context.left +local ctx_right = context.right + +-- an alternative is to remap to private codes, where we can have +-- different properties .. to be done; this will move and become +-- generic; we can then make the private ones active in math mode + +-- todo: handle opening/closing mo's here ... presentation mml is such a mess ... + +-- characters.registerentities() + +local doublebar = utfchar(0x2016) + +local n_replacements = { +-- [" "] = utfchar(0x2002), -- "&textspace;" -> tricky, no &; in mkiv + ["."] = "{.}", + [","] = "{,}", + [" "] = "", +} + +local l_replacements = { -- in main table + ["|"] = "\\mmlleftdelimiter\\vert", + ["{"] = "\\mmlleftdelimiter\\lbrace", + ["("] = "\\mmlleftdelimiter(", + ["["] = "\\mmlleftdelimiter[", + ["<"] = "\\mmlleftdelimiter<", + [doublebar] = "\\mmlleftdelimiter\\Vert", +} +local r_replacements = { -- in main table + ["|"] = "\\mmlrightdelimiter\\vert", + ["}"] = "\\mmlrightdelimiter\\rbrace", + [")"] = "\\mmlrightdelimiter)", + ["]"] = "\\mmlrightdelimiter]", + [">"] = "\\mmlrightdelimiter>", + [doublebar] = "\\mmlrightdelimiter\\Vert", +} + +-- todo: play with asciimode and avoid mmlchar + +-- we can use the proper names now! todo + +local o_replacements = { -- in main table + ["@l"] = "\\mmlleftdelimiter.", + ["@r"] = "\\mmlrightdelimiter.", + ["{"] = "\\mmlleftdelimiter \\lbrace", + ["}"] = "\\mmlrightdelimiter\\rbrace", + ["|"] = "\\mmlleftorrightdelimiter\\vert", + -- ["."] = "\\mmlleftorrightdelimiter.", + ["/"] = "\\mmlleftorrightdelimiter\\solidus", + [doublebar] = "\\mmlleftorrightdelimiter\\Vert", + ["("] = "\\mmlleftdelimiter(", + [")"] = "\\mmlrightdelimiter)", + ["["] = "\\mmlleftdelimiter[", + ["]"] = "\\mmlrightdelimiter]", + -- ["<"] = "\\mmlleftdelimiter<", + -- [">"] = "\\mmlrightdelimiter>", + ["#"] = "\\mmlchar{35}", + ["$"] = "\\mmlchar{36}", -- $ + ["%"] = "\\mmlchar{37}", + ["&"] = "\\mmlchar{38}", + ["^"] = "\\mmlchar{94}{}", -- strange, sometimes luatex math sees the char instead of \char + ["_"] = "\\mmlchar{95}{}", -- so we need the {} + ["~"] = "\\mmlchar{126}", + [" "] = "", + ["°"] = "^\\circ", -- hack + + -- [utfchar(0xF103C)] = "\\mmlleftdelimiter<", + [utfchar(0xF1026)] = "\\mmlchar{38}", + [utfchar(0x02061)] = "", -- function applicator sometimes shows up in font + -- [utfchar(0xF103E)] = "\\mmlleftdelimiter>", + -- [utfchar(0x000AF)] = '\\mmlchar{"203E}', -- 0x203E +} + +local simpleoperatorremapper = utf.remapper(o_replacements) + +--~ languages.data.labels.functions + +local i_replacements = { + ["sin"] = "\\sin", + ["cos"] = "\\cos", + ["abs"] = "\\abs", + ["arg"] = "\\arg", + ["codomain"] = "\\codomain", + ["curl"] = "\\curl", + ["determinant"] = "\\det", + ["divergence"] = "\\div", + ["domain"] = "\\domain", + ["gcd"] = "\\gcd", + ["grad"] = "\\grad", + ["identity"] = "\\id", + ["image"] = "\\image", + ["lcm"] = "\\lcm", + ["lim"] = "\\lim", + ["max"] = "\\max", + ["median"] = "\\median", + ["min"] = "\\min", + ["mode"] = "\\mode", + ["mod"] = "\\mod", + ["polar"] = "\\Polar", + ["exp"] = "\\exp", + ["ln"] = "\\ln", + ["log"] = "\\log", + ["sin"] = "\\sin", + ["arcsin"] = "\\arcsin", + ["sinh"] = "\\sinh", + ["arcsinh"] = "\\arcsinh", + ["cos"] = "\\cos", + ["arccos"] = "\\arccos", + ["cosh"] = "\\cosh", + ["arccosh"] = "\\arccosh", + ["tan"] = "\\tan", + ["arctan"] = "\\arctan", + ["tanh"] = "\\tanh", + ["arctanh"] = "\\arctanh", + ["cot"] = "\\cot", + ["arccot"] = "\\arccot", + ["coth"] = "\\coth", + ["arccoth"] = "\\arccoth", + ["csc"] = "\\csc", + ["arccsc"] = "\\arccsc", + ["csch"] = "\\csch", + ["arccsch"] = "\\arccsch", + ["sec"] = "\\sec", + ["arcsec"] = "\\arcsec", + ["sech"] = "\\sech", + ["arcsech"] = "\\arcsech", + [" "] = "", + + ["false"] = "{\\mathrm false}", + ["notanumber"] = "{\\mathrm NaN}", + ["otherwise"] = "{\\mathrm otherwise}", + ["true"] = "{\\mathrm true}", + ["declare"] = "{\\mathrm declare}", + ["as"] = "{\\mathrm as}", +} + +-- we could use a metatable or when accessing fallback on the +-- key but at least we now have an overview + +local csymbols = { + arith1 = { + lcm = "lcm", + big_lcm = "lcm", + gcd = "gcd", + big_gcd = "big_gcd", + plus = "plus", + unary_minus = "minus", + minus = "minus", + times = "times", + divide = "divide", + power = "power", + abs = "abs", + root = "root", + sum = "sum", + product = "product", + }, + fns = { + domain = "domain", + range = "codomain", + image = "image", + identity = "ident", + -- left_inverse = "", + -- right_inverse = "", + inverse = "inverse", + left_compose = "compose", + lambda = "labmda", + }, + linalg1 = { + vectorproduct = "vectorproduct", + scalarproduct = "scalarproduct", + outerproduct = "outerproduct", + transpose = "transpose", + determinant = "determinant", + vector_selector = "selector", + -- matrix_selector = "matrix_selector", + }, + logic1 = { + equivalent = "equivalent", + ["not"] = "not", + ["and"] = "and", + -- big_and = "", + ["xor"] = "xor", + -- big_xor = "", + ["or"] = "or", + -- big-or = "", + implies = "implies", + ["true"] = "true", + ["false"] = "false", + }, + nums1 = { + -- based_integer = "based_integer" + rational = "rational", + inifinity = "infinity", + e = "expenonentiale", + i = "imaginaryi", + pi = "pi", + gamma = "gamma", + NaN = "NaN", + }, + relation1 = { + eq = "eq", + lt = "lt", + gt = "gt", + neq = "neq", + leq = "leq", + geq = "geq", + approx = "approx", + }, + set1 = { + cartesian_product = "cartesianproduct", + empty_set = "emptyset", + map = "map", + size = "card", + -- suchthat = "suchthat", + set = "set", + intersect = "intersect", + -- big_intersect = "", + union = "union", + -- big_union = "", + setdiff = "setdiff", + subset = "subset", + ["in"] = "in", + notin = "notin", + prsubset = "prsubset", + notsubset = "notsubset", + notprsubset = "notprsubset", + }, + veccalc1 = { + divergence = "divergence", + grad = "grad", + curl = "curl", + laplacian = "laplacian", + Laplacian = "laplacian", + }, + calculus1 = { + diff = "diff", + -- nthdiff = "", + partialdiff = "partialdiff", + int = "int", + -- defint = "defint", + }, + integer1 = { + factorof = "factorof", + factorial = "factorial", + quotient = "quotient", + remainder = "rem", + }, + linalg2 = { + vector = "vector", + matrix = "matrix", + matrixrow = "matrixrow", + }, + mathmkeys = { + -- equiv = "", + -- contentequiv = "", + -- contentequiv_strict = "", + }, + rounding1 = { + ceiling = "ceiling", + floor = "floor", + -- trunc = "trunc", + -- round = "round", + }, + setname1 = { + P = "primes", + N = "naturalnumbers", + Z = "integers", + rationals = "rationals", + R = "reals", + complexes = "complexes", + }, + complex1 = { + -- complex_cartesian = "complex_cartesian", -- ci ? + real = "real", + imaginary = "imaginary", + -- complex_polar = "complex_polar", -- ci ? + argument = "arg", + conjugate = "conjugate", + }, + interval1 = { -- not an apply + -- integer_interval = "integer_interval", + interval = "interval", + interval_oo = { tag = "interval", closure = "open" }, + interval_cc = { tag = "interval", closure = "closed" }, + interval_oc = { tag = "interval", closure = "open-closed" }, + interval_co = { tag = "interval", closure = "closed-open" }, + }, + linalg3 = { + -- vector = "vector.column", + -- matrixcolumn = "matrixcolumn", + -- matrix = "matrix.column", + }, + minmax1 = { + min = "min", + -- big_min = "", + max = "max", + -- big_max = "", + }, + piece1 = { + piecewise = "piecewise", + piece = "piece", + otherwise = "otherwise", + }, + error1 = { + -- unhandled_symbol = "", + -- unexpected_symbol = "", + -- unsupported_CD = "", + }, + limit1 = { + -- limit = "limit", + -- both_sides = "both_sides", + -- above = "above", + -- below = "below", + -- null = "null", + tendsto = "tendsto", + }, + list1 = { + -- map = "", + -- suchthat = "", + -- list = "list", + }, + multiset1 = { + size = { tag = "card", type = "multiset" }, + cartesian_product = { tag = "cartesianproduct", type = "multiset" }, + empty_set = { tag = "emptyset", type = "multiset" }, + -- multi_set = { tag = "multiset", type = "multiset" }, + intersect = { tag = "intersect", type = "multiset" }, + -- big_intersect = "", + union = { tag = "union", type = "multiset" }, + -- big_union = "", + setdiff = { tag = "setdiff", type = "multiset" }, + subset = { tag = "subset", type = "multiset" }, + ["in"] = { tag = "in", type = "multiset" }, + notin = { tag = "notin", type = "multiset" }, + prsubset = { tag = "prsubset", type = "multiset" }, + notsubset = { tag = "notsubset", type = "multiset" }, + notprsubset = { tag = "notprsubset", type = "multiset" }, + }, + quant1 = { + forall = "forall", + exists = "exists", + }, + s_dist = { + -- mean = "mean.dist", + -- sdev = "sdev.dist", + -- variance = "variance.dist", + -- moment = "moment.dist", + }, + s_data = { + mean = "mean", + sdev = "sdev", + variance = "vriance", + mode = "mode", + median = "median", + moment = "moment", + }, + transc1 = { + log = "log", + ln = "ln", + exp = "exp", + sin = "sin", + cos = "cos", + tan = "tan", + sec = "sec", + csc = "csc", + cot = "cot", + sinh = "sinh", + cosh = "cosh", + tanh = "tanh", + sech = "sech", + csch = "cscs", + coth = "coth", + arcsin = "arcsin", + arccos = "arccos", + arctan = "arctan", + arcsec = "arcsec", + arcscs = "arccsc", + arccot = "arccot", + arcsinh = "arcsinh", + arccosh = "arccosh", + arctanh = "arstanh", + arcsech = "arcsech", + arccsch = "arccsch", + arccoth = "arccoth", + }, +} + +function xml.functions.remapmmlcsymbol(e) + local at = e.at + local cd = at.cd + if cd then + cd = csymbols[cd] + if cd then + local tx = e.dt[1] + if tx and tx ~= "" then + local tg = cd[tx] + if tg then + at.cd = nil + at.cdbase = nil + e.dt = { } + if type(tg) == "table" then + for k, v in next, tg do + if k == "tag" then + e.tg = v + else + at[k] = v + end + end + else + e.tg = tg + end + end + end + end + end +end + +function xml.functions.remapmmlbind(e) + e.tg = "apply" +end + +function xml.functions.remapopenmath(e) + local tg = e.tg + if tg == "OMOBJ" then + e.tg = "math" + elseif tg == "OMA" then + e.tg = "apply" + elseif tg == "OMB" then + e.tg = "apply" + elseif tg == "OMS" then + local at = e.at + e.tg = "csymbol" + e.dt = { at.name or "unknown" } + at.name = nil + elseif tg == "OMV" then + local at = e.at + e.tg = "ci" + e.dt = { at.name or "unknown" } + at.name = nil + elseif tg == "OMI" then + e.tg = "ci" + end + e.rn = "mml" +end + +function mathml.checked_operator(str) + context(simpleoperatorremapper(str)) +end + +function mathml.stripped(str) + context(strip(str)) +end + +local p_entity = (P("&") * ((1-P(";"))^0) * P(";")) +local p_utfchar = lpegpatterns.utf8character +local p_spacing = lpegpatterns.whitespace^1 + +local p_mn = Cs((p_entity/"" + p_spacing/utfchar(0x205F) + p_utfchar/n_replacements)^0) +local p_strip = Cs((p_entity/"" + p_utfchar )^0) +local p_mi = Cs((p_entity/"" + p_utfchar/i_replacements)^0) + +-- function mathml.mn(id,pattern) +-- -- maybe at some point we need to interpret the number, but +-- -- currently we assume an upright font +-- local str = xmlcontent(getid(id)) or "" +-- local rep = gsub(str,"&.-;","") +-- local rep = gsub(rep,"(%s+)",utfchar(0x205F)) -- medspace e.g.: twenty one (nbsp is not seen) +-- local rep = gsub(rep,".",n_replacements) +-- ctx_mn(rep) +-- end + +function mathml.mn(id,pattern) + -- maybe at some point we need to interpret the number, but + -- currently we assume an upright font + ctx_mn(lpegmatch(p_mn,xmlcontent(getid(id)) or "")) +end + +-- function mathml.mo(id) +-- local str = xmlcontent(getid(id)) or "" +-- local rep = gsub(str,"&.-;","") -- todo +-- context(simpleoperatorremapper(rep) or rep) +-- end + +function mathml.mo(id) + local str = lpegmatch(p_strip,xmlcontent(getid(id)) or "") + context(simpleoperatorremapper(str) or str) +end + +function mathml.mi(id) + -- we need to strip comments etc .. todo when reading in tree + local e = getid(id) + local str = e.dt + if type(str) == "table" then + local n = #str + if n == 0 then + -- nothing to do + elseif n == 1 then + local first = str[1] + if type(first) == "string" then + -- local str = gsub(first,"&.-;","") -- bah + -- local rep = i_replacements[str] + -- if not rep then + -- rep = gsub(str,".",i_replacements) + -- end + local str = lpegmatch(p_strip,first) + local rep = i_replacements[str] or lpegmatch(p_mi,str) + context(rep) + -- ctx_mi(rep) + else + ctx_xmlflush(id) -- xmlsprint or so + end + else + ctx_xmlflush(id) -- xmlsprint or so + end + else + ctx_xmlflush(id) -- xmlsprint or so + end +end + +function mathml.mfenced(id) -- multiple separators + id = getid(id) + local at = id.at + local left = at.open or "(" + local right = at.close or ")" + local separators = at.separators or "," + local l = l_replacements[left] + local r = r_replacements[right] + ctx_enabledelimiter() + if l then + context(l_replacements[left] or o_replacements[left] or "") + else + context(o_replacements["@l"]) + context(left) + end + ctx_disabledelimiter() + local collected = lxmlfilter(id,"/*") -- check the * + if collected then + local n = #collected + if n == 0 then + -- skip + elseif n == 1 then + xmlsprint(collected[1]) -- to be checked + else + local t = utfsplit(separators,true) + for i=1,n do + xmlsprint(collected[i]) -- to be checked + if i < n then + local m = t[i] or t[#t] or "" + if m == "|" then + m = "\\enabledelimiter\\middle|\\relax\\disabledelimiter" + elseif m == doublebar then + m = "\\enabledelimiter\\middle|\\relax\\disabledelimiter" + elseif m == "{" then + m = "\\{" + elseif m == "}" then + m = "\\}" + end + context(m) + end + end + end + end + ctx_enabledelimiter() + if r then + context(r_replacements[right] or o_replacements[right] or "") + else + context(right) + context(o_replacements["@r"]) + end + ctx_disabledelimiter() +end + +local function flush(e,tag,toggle) + if tag == "none" then + -- if not toggle then + context("{}") -- {} starts a new ^_ set + -- end + elseif toggle then + context("^{") + xmlsprint(e.dt) + context("}{}") -- {} starts a new ^_ set + else + context("_{") + xmlsprint(e.dt) + context("}") + end + return not toggle +end + +function mathml.mmultiscripts(id) + local done, toggle = false, false + for e in lxmlcollected(id,"/*") do + local tag = e.tg + if tag == "mprescripts" then + context("{}") + done = true + elseif done then + toggle = flush(e,tag,toggle) + end + end + local done, toggle = false, false + for e in lxmlcollected(id,"/*") do + local tag = e.tg + if tag == "mprescripts" then + break + elseif done then + toggle = flush(e,tag,toggle) + else + xmlsprint(e) + done = true + end + end +end + +local columnalignments = { + left = "flushleft", + right = "flushright", + center = "middle", +} + +local rowalignments = { + top = "high", + bottom = "low", + center = "lohi", + baseline = "top", + axis = "lohi", +} + +local frametypes = { + none = "off", + solid = "on", + dashed = "on", +} + +-- crazy element ... should be a proper structure instead of such a mess + +function mathml.mcolumn(root) + root = getid(root) + local matrix, numbers = { }, 0 + local function collect(m,e) + local tag = e.tg + if tag == "mi" or tag == "mn" or tag == "mo" or tag == "mtext" then + local str = xmltext(e) + str = lpegmatch(p_strip,str) + for s in utfcharacters(str) do + m[#m+1] = { tag, s } + end + if tag == "mn" then + local n = utflen(str) + if n > numbers then + numbers = n + end + end + elseif tag == "mspace" or tag == "mline" then + local str = e.at.spacing or "" + for s in utfcharacters(str) do + m[#m+1] = { tag, s } + end + -- elseif tag == "mline" then + -- m[#m+1] = { tag, e } + end + end + for e in lxmlcollected(root,"/*") do + local m = { } + matrix[#matrix+1] = m + if e.tg == "mrow" then + -- only one level + for e in lxmlcollected(e,"/*") do + collect(m,e) + end + else + collect(m,e) + end + end + ctx_halign() + ctx_bgroup() + context([[\hss\startimath\alignmark\stopimath\aligntab\startimath\alignmark\stopimath\cr]]) + for i=1,#matrix do + local m = matrix[i] + local mline = true + for j=1,#m do + if m[j][1] ~= "mline" then + mline = false + break + end + end + if mline then + ctx_noalign([[\obeydepth\nointerlineskip]]) + end + for j=1,#m do + local mm = m[j] + local tag, chr = mm[1], mm[2] + if tag == "mline" then + -- This code is under construction ... I need some real motivation + -- to deal with this kind of crap. +--~ local n, p = true, true +--~ for c=1,#matrix do +--~ local mc = matrix[c][j] +--~ if mc then +--~ mc = mc[2] +--~ if type(mc) ~= "string" then +--~ n, p = false, false +--~ break +--~ elseif find(mc,"^[%d ]$") then -- rangecheck is faster +--~ -- digit +--~ elseif not find(mc,"^[%.%,]$") then -- rangecheck is faster +--~ -- punctuation +--~ else +--~ n = false +--~ break +--~ end +--~ end +--~ end +--~ if n then +--~ chr = "\\mmlmcolumndigitrule" +--~ elseif p then +--~ chr = "\\mmlmcolumnpunctuationrule" +--~ else +--~ chr = "\\mmlmcolumnsymbolrule" -- should be widest char +--~ end + chr = "\\hrulefill" + elseif tag == "mspace" then + chr = "\\mmlmcolumndigitspace" -- utfchar(0x2007) + end + if j == numbers + 1 then + context("\\aligntab") + end + local nchr = n_replacements[chr] + context(nchr or chr) + end + ctx_crcr() + end + ctx_egroup() +end + +local spacesplitter = lpeg.tsplitat(" ") + +function mathml.mtable(root) + -- todo: align, rowspacing, columnspacing, rowlines, columnlines + root = getid(root) + local at = root.at + local rowalign = at.rowalign + local columnalign = at.columnalign + local frame = at.frame + local rowaligns = rowalign and lpegmatch(spacesplitter,rowalign) + local columnaligns = columnalign and lpegmatch(spacesplitter,columnalign) + local frames = frame and lpegmatch(spacesplitter,frame) + local framespacing = at.framespacing or "0pt" + local framespacing = at.framespacing or "-\\ruledlinewidth" -- make this an option + + ctx_bTABLE { frame = frametypes[frame or "none"] or "off", offset = framespacing, background = "" } -- todo: use xtables and definextable + for e in lxmlcollected(root,"/(mml:mtr|mml:mlabeledtr)") do + ctx_bTR() + local at = e.at + local col = 0 + local rfr = at.frame or (frames and frames [#frames]) + local rra = at.rowalign or (rowaligns and rowaligns [#rowaligns]) + local rca = at.columnalign or (columnaligns and columnaligns[#columnaligns]) + local ignorelabel = e.tg == "mlabeledtr" + for e in lxmlcollected(e,"/mml:mtd") do -- nested we can use xml.collected + col = col + 1 + if ignorelabel and col == 1 then + -- get rid of label, should happen at the document level + else + local at = e.at + local rowspan = at.rowspan or 1 + local columnspan = at.columnspan or 1 + local cra = rowalignments [at.rowalign or (rowaligns and rowaligns [col]) or rra or "center"] or "lohi" + local cca = columnalignments[at.columnalign or (columnaligns and columnaligns[col]) or rca or "center"] or "middle" + local cfr = frametypes [at.frame or (frames and frames [col]) or rfr or "none" ] or "off" + ctx_bTD { align = formatters["{%s,%s}"](cra,cca), frame = cfr, nx = columnspan, ny = rowspan } + if xmlempty(e,".") then + -- nothing, else hsize max + else + ctx_startimath() + -- ctx_ignorespaces() + xmlcprint(e) + -- ctx_removeunwantedspaces() + ctx_stopimath() + end + ctx_eTD() + end + end + -- if e.tg == "mlabeledtr" then + -- ctx_bTD() + -- xmlcprint(xml.first(e,"/!mml:mtd")) + -- ctx_eTD() + -- end + ctx_eTR() + end + ctx_eTABLE() +end + +function mathml.csymbol(root) + root = getid(root) + local at = root.at + local encoding = at.encoding or "" + local hash = url.hashed(lower(at.definitionUrl or "")) + local full = hash.original or "" + local base = hash.path or "" + local text = strip(xmltext(root) or "") + ctx_mmlapplycsymbol(full,base,encoding,text) +end + +local p = lpeg.Cs(((1-lpegpatterns.whitespace)^1 / "mml:enclose:%0" + (lpegpatterns.whitespace^1)/",")^1) + +function mathml.menclosepattern(root) + root = getid(root) + local a = root.at.notation + if a and a ~= "" then + context(lpegmatch(p,a)) + end +end + +function xml.is_element(e,name) + return type(e) == "table" and (not name or e.tg == name) +end + +function mathml.cpolar_a(root) + root = getid(root) + local dt = root.dt + ctx_mathopnolimits("Polar") + ctx_left(false,"(") + for k=1,#dt do + local dk = dt[k] + if xml.is_element(dk,"sep") then + context(",") + else + xmlsprint(dk) + end + end + ctx_right(false,")") +end + +-- crap .. maybe in char-def a mathml overload + +local mathmleq = { + [utfchar(0x00AF)] = utfchar(0x203E), +} + +function mathml.extensible(chr) + context(mathmleq[chr] or chr) +end diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.mkiv new file mode 100644 index 00000000000..a5be5ddb09e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-mathml.mkiv @@ -0,0 +1,2607 @@ +%D \module +%D [ file=x-mathml, +%D version=2008.05.29, +%D title=\CONTEXT\ XML Modules, +%D subtitle=\MATHML, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% \xmlfilter{#1}{/*/name()} -> \xmltag + +% This module is under construction and will be cleaned up. We use a funny mix of +% xml, tex and lua. I could rewrite the lot but it also shows how context evolves. +% +% I might end up with a lua-only implementation some day. I must find a good reason +% to spend time on it. In fact, it might even be more messy. +% +% no m:text strip (needs checking, maybe nbsp is mandate +% +% todo: more will be moved to lua (less hassle) +% todo: move left/right to the lua end +% +% this implememation looks like a hack ... this is because we deal with all weird cases we +% ran into, including abuse that was supposed to render ok (even if it didn't in other +% renderers) .. it was simply expected to work that way. + +\writestatus{loading}{ConTeXt XML Macros / MathML Renderer} + +\unprotect + +\usemodule[x][calcmath] +%usemodule[x][asciimath] + +\startmodule [mathml] + +\registerctxluafile{x-mathml}{} + +\setupxml[\c!entities=\v!yes] % load big entities table + +\def\ctxmodulemathml#1{\ctxlua{moduledata.mathml.#1}} + +\startxmlsetups xml:mml:define + \xmlsetsetup{#1} {(formula|subformula)} {mml:formula} + \xmlfilter {#1} {omt:*/function(remapopenmath)} + \xmlfilter {#1} {mml:bind/function(remapmmlbind)} + \xmlfilter {#1} {mml:csymbol/function(remapmmlcsymbol)} + \xmlsetsetup{#1} {mml:*} {mml:*} + \xmlsetsetup{#1} {mml:apply/mml:apply/mml:inverse/../..} {mml:apply:inverse} + \xmlstrip {#1} {(mml:mi|mml:mo|mml:mn|mml:csymbol)} +\stopxmlsetups + +\xmlregisterns{omt}{openmath} +\xmlregisterns{mml}{mathml} + +\xmlregistersetup{xml:mml:define} + +% \unexpanded\def\MMLhack % no longer needed +% {\let\MMLpar\par +% \let\par\relax +% \everyvbox{\let\par\MMLpar}} + +\xmlmapvalue {mml:math:mode} {display} {\displaymathematics} % we had this already +\xmlmapvalue {mml:math:mode} {inline} {\inlinemathematics } + +\xmlmapvalue {mml:math:display} {block} {\displaymathematics} % before this showed up +\xmlmapvalue {mml:math:display} {inline} {\inlinemathematics } + +\xmlmapvalue {mml:math:dir} {ltr} {\setfalse\c_math_right_to_left\math_basics_synchronize_direction} +\xmlmapvalue {mml:math:dir} {rtl} {\settrue \c_math_right_to_left\math_basics_synchronize_direction} + +\startxmlsetups mml:math + \begingroup + \enableautofences + \xmlval {mml:math:dir} {\xmlatt{#1}{dir}} {} + \xmlval {mml:math:display} {\xmlatt{#1}{display}} { + \xmlval {mml:math:mode} {\xmlatt{#1}{mode}} { + \automathematics + } + } + { + %\math_fences_checked_start + %\MMLhack + \xmlflush{#1} + %\math_fences_checked_stop + } + \endgroup +\stopxmlsetups + +\startxmlsetups mml:imath + \inlinemathematics { + \enableautofences + %\math_fences_checked_start + %\MMLhack + \xmlflush{#1} + %\math_fences_checked_stop + } +\stopxmlsetups + +\startxmlsetups mml:dmath + \displaymathematics { + \enableautofences + %\math_fences_checked_start + %\MMLhack + \xmlflush{#1} + %\math_fences_checked_stop + } +\stopxmlsetups + +%D First we define some general formula elements. + +\startxmlsetups mml:formula + \edef\mmlformulalabel {\xmlatt{#1}{label}\xmlatt{#1}{id}} + \edef\mmlformulasublabel{\xmlatt{#1}{sublabel}\xmlatt{#1}{id}} + \doifsomething\mmlformulalabel{\placeformula[\mmlformulalabel]{\mmlformulasublabel}} + \startformula + %\MMLhack + \xmlfirst{#1}{/mml:math} + \stopformula +\stopxmlsetups + +% old delimiter hacks +% +% \setfalse\mmlignoredelimiter +% \settrue \mmlsomeleftdelimiter +% +% \def\MMLleftorright +% {\ifconditional\mmlsomeleftdelimiter +% \setfalse\mmlsomeleftdelimiter\expandafter\MMLleft +% \else +% \settrue \mmlsomeleftdelimiter\expandafter\MMLright +% \fi} +% +% \ifx\MMLleft \undefined \let\MMLleft \firstofoneargument \fi +% \ifx\MMLright \undefined \let\MMLright \firstofoneargument \fi +% \ifx\MMLmiddle\undefined \let\MMLmiddle\firstofoneargument \fi +% +% \def\mmlleftdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLleft #1}\fi} +% \def\mmlrightdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLright #1}\fi} +% \def\mmlmiddledelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLmiddle #1}\fi} +% \def\mmlleftorrightdelimiter#1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLleftorright#1}\fi} + +% new delimiter hacks (assumes wrapping) +% +% \math_fences_checked_start +% \math_fences_checked_stop +% +% \math_fences_checked_left +% \math_fences_checked_middle +% \math_fences_checked_right +% \math_fences_checked_left_or_right + +\setfalse\mmlignoredelimiter % alternatively we could turn it on/off inside the start/stop and ignore \left\right\middle otherwise + +% \def\mmlleftdelimiter {\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_left \fi} +% \def\mmlrightdelimiter {\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_right \fi} +% \def\mmlmiddledelimiter {\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_middle \fi} +% \def\mmlleftorrightdelimiter{\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_left_or_right\fi} + +\let\mmlleftdelimiter \autofenceopen +\let\mmlmiddledelimiter \autofencemiddle +\let\mmlrightdelimiter \autofenceclose +\let\mmlleftorrightdelimiter\autofenceboth + +% end of delimiter mess + +\def\mmlchar#1{\char#1 } % used in lua code + +% \newcount\delimiternesting \appendtoks \delimiternesting\zerocount \to \everymathematics + +% \def\mmlleftdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{% +% \advance\delimiternesting\plusone \MMLleft #1}\fi} +% \def\mmlrightdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{% +% \advance\delimiternesting\plusone \MMLright#1}\fi} +% \def\mmlmiddledelimiter#1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{% +% \ifcase\delimiternesting\MMLleft\else\MMLmiddle\fi#1}\fi} + +%D Remark: from now on this is a module and no longer an xtag +%D filter. There is an intermediate cleaner module but it has +%D some namespace limitations. Here we do it the \MKIV\ way. + +%D The rendering macros: + +\def\MMLrm{\mr} + +\def\MMLseparator#1{\removeunwantedspaces{#1}\ignorespaces} % nils space after separator +\def\MMLseparator#1{,} % todo, for europe we need to block the space + +%D Since I only had the draft of MathML 2 and later 3 as example of +%D rendering, there are probably a lot of omissions and +%D misinterpretations. At least I learned some bits and +%D pieces of math rendering. +%D +%D The main complications were not so much the math, but to +%D find the most efficient way to handle elements without +%D spacing beging messed up. The first implementation was +%D aimed at getting reasonable output, this second +%D implementation is already better in terms of handling +%D nesting, and I will definitely need a third one that has +%D more efficient and less ugly code. +%D +%D The \TEX\ part is not that complicated and once the +%D preprocessor was okay, the rest way just a lot of keying +%D and testing. It all comes down to gobbling, redefining, +%D and not so much to parsing. +%D +%D The second implementation expanded the whole math sequence +%D into an internal \TEX\ representation. This is a rather clean +%D and fast process. Filtering and testing takes place by +%D redefining teh internal representation macros. +%D +%D The third implementation may look a bit more messy in some +%D respects. This is because in \TEX\ it's not that trivial to +%D implement a tree handler. We use a stack for the \type {apply} +%D element and other sequential content. Occasionally we need to +%D peek into child elements which involves messy code. This +%D implementation is closer to the normal \XML\ handling in +%D \CONTEXT. + +%D We start with the parent elements and the option handler. + +\unexpanded\def\xmlmathmldirective#1{\dosetvalue{MML#1}} + +\xmlinstalldirective{mathml}{xmlmathmldirective} + +%def\xmlmathmldirective#1#2#3{[#1][#2][#3]\dosetvalue{MML#1}{#2}{#3}} + +%D In the styles, options can be set with: + +\unexpanded\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[MML#1]} % no @@ because passed to lua + +%D We will apply inner math to all bits and pieces made up by an +%D \type {apply}. + +\def\MMLmathinner + {\ifinner + \expandafter\firstofoneargument + \else + \expandafter\mathinner + \fi} + +%D Auxiliary MathML macros: (to be generalized) + +\def\mmlfirst #1{\xmlelement{#1}{1}} % we can move these inline if needed +\def\mmlsecond #1{\xmlelement{#1}{2}} +\def\mmlthird #1{\xmlelement{#1}{3}} +\def\mmlprelast#1{\xmlelement{#1}{-2}} +\def\mmllast #1{\xmlelement{#1}{-1}} + +\unexpanded\def\mmlunexpandedfirst #1{\xmlelement{#1}{1}} % we can move these inline if needed +\unexpanded\def\mmlunexpandedsecond #1{\xmlelement{#1}{2}} +\unexpanded\def\mmlunexpandedthird #1{\xmlelement{#1}{3}} + +\starttexdefinition doifelsemmlfunction #1 + \xmldoifelse {#1} {/mml:fn} { + \firstoftwoarguments + } { + \xmldoifelse {#1} {/mml:apply/mml:fn} { + \firstoftwoarguments + } { + \xmldoifelse {#1} {/mml:ci[@type=='fn']} { + \firstoftwoarguments + } { + \secondoftwoarguments + } + } + } +\stoptexdefinition + +%D A couple of lists: + +\convertargument + mml:times|mml:divide|mml:power|% + mml:lt|mml:gt|mml:eq|mml:leq|mml:geq|% + mml:in|mml:inverse|% + mml:fn|% + mml:floor|mml:ceiling|% + mml:mean|% + mml:selector|% + mml:abs|mml:int|mml:limit|mml:sum|mml:product|% + mml:outerproduct|mml:innerproduct|mml:scalarproduct% +\to \MMLcmainresetlist + +\convertargument + mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|% + mml:cos|mml:arccos|mml:cosh|mml:arccosh|% + mml:tan|mml:arctan|mml:tanh|mml:arctanh|% + mml:cot|mml:arccot|mml:coth|mml:arccoth|% + mml:csc|mml:arccsc|mml:csch|mml:arccsch|% + mml:sec|mml:arcsec|mml:sech|mml:arcsech|% + mml:ln|mml:exp|mml:log|% + mml:abs|mml:int|mml:limit|mml:sum|mml:product|% + mml:fn% +\to \MMLcfunctionlist + +\convertargument + mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|% + mml:cos|mml:arccos|mml:cosh|mml:arccosh|% + mml:tan|mml:arctan|mml:tanh|mml:arctanh|% + mml:cot|mml:arccot|mml:coth|mml:arccoth|% + mml:csc|mml:arccsc|mml:csch|mml:arccsch|% + mml:sec|mml:arcsec|mml:sech|mml:arcsech|% + mml:ln|mml:exp|mml:log|% + mml:abs% +\to \MMLcpurefunctionlist + +\convertargument + mml:diff|mml:partialdiff|mml:root% +\to \MMLcconstructlist + +%D We use inner and grouping (begin/end and no b/e) else we +%D get problems with 1/2(1+2) and alike (todo: ask taco). +%D +%D The problem with apply is that we need to take care of +%D several situations, like: +%D +%D \starttyping +%D <apply> <.../> ... +%D <apply> <fn> ... +%D <apply> <apply> <ci> ... +%D <apply> <apply> <fn> <ci> ... +%D \stoptyping +%D +%D Because we translated version 2 of this renderer into +%D version 3 the following definitions may be sub optimal or +%D more complex than actually needed. + +%D We will more more to lua ... + +% simple version + +\newcount\@MMLlevel \def\MMLcreset{\@MMLlevel\zerocount} + +\let\MMLctempresetlist\empty \def\setMMLcreset{\edef\MMLctempresetlist} + +\let\MMLdoL\donothing +\let\MMLdoR\donothing + +\newcount\mmlapplydepth \def\MMLcreset{\mmlapplydepth\zerocount} + +% \newtoks \@@postponedMMLactions \setfalse \somepostponedMMLactions +% +% \def\postponeMMLactions#1% +% {\global\settrue\somepostponedMMLactions +% \global\@@postponedMMLactions\expandafter{\the\@@postponedMMLactions#1}} +% +% \def\postponedMMLactions +% {\global\setfalse\somepostponedMMLactions +% \@EA\global\@EA\@@postponedMMLactions\@EA\emptytoks +% \the\@@postponedMMLactions} + +\startxmlsetups mml:apply + \MMLmathinner { + \xmldoif {#1} {/(\MMLcmainresetlist\string|\MMLctempresetlist)} { + % \MMLcreset + } + \edef\mmlapplyopentoken {\xmlatt{#1}{open}} + \edef\mmlapplyclosetoken{\xmlatt{#1}{close}} + \ifcase\mmlapplydepth \else + \ifx\mmlapplyopentoken\empty + \def\mmlapplyopentoken {(} + \def\mmlapplyclosetoken{)} + \fi + \fi + \advance\mmlapplydepth\plusone + \begingroup + \ifx\mmlapplyopentoken\empty + \let\MMLdoL\donothing + \let\MMLdoR\donothing + \else + \edef\MMLdoL{\noexpand\left \mmlapplyopentoken } + \edef\MMLdoR{\noexpand\right\mmlapplyclosetoken} + \fi + \let\MMLctempresetlist\empty + \xmldoifelse {#1} {/mml:apply} { +% % <apply> <apply> ... </apply> <ci> .. </ci> </apply> +% \xmldoifelse {#1} {/mml:apply(mml:plus|mml:minus)} {% [a] +% % yet incomplete and rather untested +% % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply> + } {% [b] +% \MMLcreset + } +% \MMLdoL +% \mmlfirst{#1} +% \ifconditional\somepostponedMMLactions +% \postponedMMLactions +% \else +% \left(\MMLcreset\mmlsecond{#1}\right) +% \fi +% \MMLdoR +% } { + \edef\mmlapplyaction{\xmlfilter{#1}{/*/name()}} + \doifelsesetups {mml:apply:mml:\mmlapplyaction} { + \xmlsetup{#1}{mml:apply:mml:\mmlapplyaction} + } { +% \MMLdoL + \xmlsetup{#1}{mml:\xmlfilter{#1}{/*/name()}} +% \MMLdoR + } +% } + \endgroup + \advance\mmlapplydepth\minusone + } +\stopxmlsetups + +\startxmlsetups mml:apply:mml:apply + \xmlflush{#1} + \xmlall{#1}{../[position()>1]} +\stopxmlsetups + +\startxmlsetups mml:apply:mml:fn + \xmldoifelse {#1} {/mml:fn/mml:ci} { + \edef\mmlfnci{\xmlstripped{#1}{/mml:fn/mml:ci}}% was xmlcontent + \doifelsesetups{mmc:fn:\mmlfnci} { % was mmc:fn:... + \xmlsetup{#1}{mmc:fn:\mmlfnci} % \MMLdoL/MMLdoR to be handled in plugin + } { + \MMLcreset + \MMLdoL + \mmlfirst{#1} + \ifnum\xmlcount{#1}{/*}>\plusone + \negthinspace % not enough + \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right) + \fi + \MMLdoR + } + } { + \MMLcreset + \MMLdoL + \xmlall{#1}{/*} + \MMLdoR + } +\stopxmlsetups + +\startxmlsetups mml:apply:mml:csymbol + \xmlsetup{#1}{mml:csymbol}% \MMLdoL/MMLdoR to be handled in plugin +\stopxmlsetups + +\startxmlsetups mml:apply:mml:ci + \xmlfirst{#1}{/mml:ci} + \ifnum\xmlcount{#1}{/*}>\plusone + \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right) + \fi +\stopxmlsetups + +% reln + +\startxmlsetups mml:reln + \writestatus{XML}{MathML element "reln" is obsolete} +\stopxmlsetups + +% fn + +% plusminus ± + +\startxmlsetups mmc:fn:\utfchar{"00B1} + \MMLdoL + \xmlconcat{#1}{/[position()>1]}{\utfchar{"00B1}} + \MMLdoR +\stopxmlsetups + +% minusplus + +\startxmlsetups mmc:fn:\utfchar{"2213} + \MMLdoL + \xmlconcat{#1}{/[position()>1]}{\utfchar{"2213}} + \MMLdoR +\stopxmlsetups + +\startxmlsetups mmc:fn + \begingroup + \edef\mmlnoffn{\xmlcount{#1}{/*}} + \ifnum\mmlnoffn>\plustwo + \def\MMCfnleft {\left(} + \def\MMCfnright{\right)} + \else + \let\MMCfnleft \relax + \let\MMCfnright\relax + \fi + \xmldoifelse {#1} {/mml:ci} { % first + \edef\mmlfnci{\xmltext{#1}{/mml:ci}}% was xmlcontent + \doifelsesetups{mmc:fn:\mmlfnci} { % was mmc:fn:... + \xmlsetup{#1}{mmc:fn:\mmlfnci} % \MMLdoL/MMLdoR to be handled in plugin + } { + \MMLcreset + \mmlfirst{#1} + } + } { + \xmldoifelse {#1} {/mml:apply} { % first + \xmldoifelse {#1} {/(mml:plus\string|mml:minus)} { + \left(\mmlfirst{#1}\right) + } { + \mmlfirst{#1} + } + \ifnum\mmlnoffn>\plusone + \left(\xmlall{#1}{/!mml:apply}\right) + \fi + } { + \MMLcreset + \negthinspace + \MMCfnleft + \ifnum\mmlnoffn=\plustwo,\fi + \xmlconcat{#1}{/*}{2}{}{\MMLseparator,} + \MMCfnright + } + } + \endgroup +\stopxmlsetups + +\startxmlsetups mmc:fn:apply % where used? + \xmldoifelse {#1} {/mml:ci} { % first + \edef\mmlfnci{\xmltext{#1}{/mml:ci}}% was xmlcontent + \doifelsesetups{mmc:fn:\mmlfnci} { % was mmc:fn:... + \xmlsetup{#1}{mmc:fn:\mmlfnci} % \MMLdoL/MMLdoR to be handled in plugin + } { + \MMLcreset + \mmlfirst{#1} + \ifnum\xmlcount{#1}{/*}>\plusone + \negthinspace + \left(\MMLcreset\xmlconcat{#1}{2}{}{\MMLseparator,}\right) + \fi + } + } { + \endgroup + \MMLcreset + \mmlfirst{#1} + } +\stopxmlsetups + +%D The next definition provide a kind of plug-in mechanism (see +%D the open math extension module). + +% http://www.publishers.com/somename +% +% called at the lua end + +\starttexdefinition mmlapplycsymbol #1#2#3#4 + % #1=full url, #2=name, #3=encoding, #4=text + \doifelse {#3} {text} { + \text{#4} + } { + \doifelsesetups {mml:csymbol:#1} { + % full url + \fastsetup{mml:csymbol:#1} + } { + % somename (fallback) + \doifelsesetups {mml:csymbol:#2} { + \fastsetup{mml:csymbol:#2} + } { + \xmlval{mmc:cs}{#3}{}% todo + } + } + } +\stoptexdefinition + +\startxmlsetups mml:csymbol + \ctxmodulemathml{csymbol("#1")} +\stopxmlsetups + +\startxmlsetups mml:csymbol:cdots + \cdots +\stopxmlsetups + +% \startxmlsetups mml:csymbol:<url> \stopxmlsetups + +%D Alternative b will convert periods into comma's: + +\setupMMLappearance[cn] [\c!alternative=\v!a] +\setupMMLappearance[polar] [\c!alternative=\v!a] % a|b|c +\setupMMLappearance[float] [\c!symbol=\v!no] % \v!yes|dot +\setupMMLappearance[enotation][\c!symbol=\v!no] % \v!yes|dot +\setupMMLappearance[base] [\c!symbol=\v!numbers] % digits|characters|text|no + +\startxmlsetups mml:cs \xmlcommand{#1}{/}{mml:cs:\xmlattdef{#1}{type}{default}} \stopxmlsetups +\startxmlsetups mml:ci \xmlcommand{#1}{/}{mml:ci:\xmlattdef{#1}{type}{default}} \stopxmlsetups +\startxmlsetups mml:cn \xmlcommand{#1}{/}{mml:cn:\xmlattdef{#1}{type}{default}} \stopxmlsetups + +% helpers cn / todo: \mn{...} + +\startxmlsetups mml:cn:default + \mathopnolimits{\xmlflush{#1}} +\stopxmlsetups + +% helpers ci + +\startxmlsetups mml:ci:default + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups mml:ci:set + {\blackboard{\xmlflush{#1}}} % todo +\stopxmlsetups + +\startxmlsetups mml:ci:vector + \overrightarrow{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:ci:matrix + {\bi\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:ci:function + \xmlflush{#1}% \negthinspace +\stopxmlsetups + +\startxmlsetups mml:ci:fn + \xmlsetup{#1}{mml:ci:function} +\stopxmlsetups + +\startxmlsetups mml:ci:complex-cartesian + \xmlsetup{#1}{mml:cn:complex} +\stopxmlsetups + +\startxmlsetups mml:ci:complex + \xmlsetup{#1}{mml:cn:complex} +\stopxmlsetups + +\startxmlsetups mml:ci:complex-polar + \xmlsetup{#1}{mml:cn:polar} +\stopxmlsetups + +\startxmlsetups mml:ci:polar + \xmlsetup{#1}{mml:cn:polar} +\stopxmlsetups + +% helpers ci + +\startxmlsetups mml:cn:default + \xmlflush{#1} +\stopxmlsetups + +\startxmlsetups mml:cn:integer + \edef\mmlintegerbase{\xmlattdef{#1}{base}{}} + \ifx\mmlintegerbase\empty + \xmlflush{#1} + \else + \doifelse \MMLbasesymbol \v!no { + \MMLcCNbasedata{\xmlflush{#1}} + } { + \MMLcCNbasedata{\xmlflush{#1}}\normalsubscript{ + \hbox {\startimath + \mr + \scriptscriptstyle + \processaction + [\MMLbasesymbol] + [\v!characters=>\MMLcCNbasestring BODH, + \v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX}, + \s!unknown=>\mmlintegerbase] + \stopimath} + } + } + \fi +\stopxmlsetups + +\def\MMLcCNbasedata#1% + {\ifnum\mmlintegerbase>10 \relax{\mr#1}\else#1\fi} + +\def\MMLcCNbasestring#1#2#3#4% + {\ifnum\mmlintegerbase= 2 #1\else + \ifnum\mmlintegerbase= 8 #2\else + \ifnum\mmlintegerbase=10 #3\else + \ifnum\mmlintegerbase=16 #4\else + \mmlintegerbase \fi\fi\fi\fi} + +\startxmlsetups mml:cn:polar + \xmlsetup{#1}{mml:cn:polar:\MMLpolaralternative} +\stopxmlsetups + +\startxmlsetups mml:cn:polar:a + \ctxmodulemathml{cpolar_a("#1")} +\stopxmlsetups + +\startxmlsetups mml:cn:polar:b + {\mr e}\normalsuperscript{\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}} +\stopxmlsetups + +\startxmlsetups mml:cn:polar:c + \exp\left(\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}\right) +\stopxmlsetups + +\startxmlsetups mml:cn:complex-polar + \xmlsetup{#1}{mml:cn:polar} +\stopxmlsetups + +\startxmlsetups mml:cn:complex % todo ( ) + \left(\xmlsnippet{#1}{1} + \xmlsnippet{#1}{3}\thinspace{\mr i}\right) +\stopxmlsetups + +\startxmlsetups mml:cn:complex-cartesian + \xmlsetup{#1}{mml:cn:complex} +\stopxmlsetups + +\startxmlsetups mml:cn:float + \doifelse \MMLfloatsymbol \v!no { + % make sure that e shows up ok + \mathopnolimits{\xmlflush{#1}} + } { + % we should ignore \entities ! + \edef\mmlfloatstring{\xmlflush{#1}} + \splitstring\mmlfloatstring\at e\to\first\and\last + \ifx\first\empty + \mmlfloatstring + \else\ifx\last\empty + \mmlfloatstring + \else + \first + \doifelse \MMLfloatsymbol {dot} \cdot \times + 10\normalsuperscript{\last} + \fi \fi + } +\stopxmlsetups + +\startxmlsetups mml:cn:real + \xmlsetup{#1}{mml:cn:float} +\stopxmlsetups + +\startxmlsetups mml:cn:e-notation + \doifelse \MMLenotationsymbol \v!no { + \xmlsnippet{#1}{1} + \unskip\mathopnolimits{e}\ignorespaces + \xmlsnippet{#1}{3} + } { + \xmlsnippet{#1}{1} + \doifelse \MMLenotationsymbol {dot} \cdot + \times10\normalsuperscript{\xmlsnippet{#1}{3}} + } +\stopxmlsetups + +\startxmlsetups mml:cn:logical + \mathopnolimits{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:cn:rational + \xmldoifelse {#1} {/mml:sep} { + \mmlfrac + {\xmlsnippet{#1}{1}} + {\xmlsnippet{#1}{3}} + } { + \xmlflush{#1} + } +\stopxmlsetups + +% interval + +\setupMMLappearance[interval][\c!alternative=\v!a,\c!separator={,}] + +% when empty element, then it's an apply + +\startxmlsetups mml:interval + \doifelse {\xmltag{#1}} {apply} { + % #1 == apply + \let\mmlintervalfirst \mmlsecond + \let\mmlintervalsecond\mmlthird + \xmlsetup{#1}{mml:interval:\xmlattributedef{#1}{/mml:interval}{closure}{closed}} + } { + % #1 == interval + \let\mmlintervalfirst \mmlfirst + \let\mmlintervalsecond\mmlsecond + \xmlsetup{#1}{mml:interval:\xmlattdef{#1}{closure}{closed}} + } +\stopxmlsetups + +\startxmlsetups mml:interval:closed + \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right] +\stopxmlsetups + +\startxmlsetups mml:interval:open-closed + \doifelse \MMLintervalalternative \v!b { + \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right] + } { + \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right] + } +\stopxmlsetups + +\startxmlsetups mml:interval:closed-open + \doifelse \MMLintervalalternative \v!b { + \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right> + } { + \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right) + } +\stopxmlsetups + +\startxmlsetups mml:interval:open + \doifelse \MMLintervalalternative \v!b { + \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right> + } { + \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right) + } +\stopxmlsetups + +% inverse + +\setfalse\xmlinversefunction + +\startxmlsetups mml:apply:inverse + \settrue\xmlinversefunction + \xmlsetup{#1}{mml:\xmlfilter{#1}{/mml:apply/*[2]/name()}} +\stopxmlsetups + +% condition + +% maybe a fast \xmlnonfirst + +% instead of the following we could do \xmlcontent{#1}{/mml:bvar} etc + +\startxmlsetups mml:bvar \xmlflush{#1} \stopxmlsetups +\startxmlsetups mml:lowlimit \xmlflush{#1} \stopxmlsetups +\startxmlsetups mml:uplimit \xmlflush{#1} \stopxmlsetups +\startxmlsetups mml:degree \xmlflush{#1} \stopxmlsetups +\startxmlsetups mml:logbase \xmlflush{#1} \stopxmlsetups +\startxmlsetups mml:fn \xmlflush{#1} \stopxmlsetups + +\startxmlsetups mml:condition +% \xmldoif {#1} {/mml:bvar} { +% \xmlfirst{#1}{/mml:bvar}\mid +% } + \xmlall{#1}{/!(mml:condition\string|mml:bvar)} +\stopxmlsetups + +% declare + +\setupMMLappearance[declare][\c!state=\v!start] + +\startxmlsetups mml:declare + \doif \MMLdeclarestate \v!start { + \mathopnolimits{declare} + \mmlfirst{#1} + \ifnum\xmlcount{#1}{/*}>\plusone + \thickspace + \mathopnolimits{as} + \thickspace + \fi + \mmlsecond{#1} + } +\stopxmlsetups + +% lambda + +\setupMMLappearance[lambda][\c!alternative=b] + +\startxmlsetups mml:lambda + \begingroup + \doifelse \MMLlambdaalternative \v!a { + \lambda\left(\xmlconcat{#1}{/!mml:lambda}{\MMLseparator,}\right) + } { + \ifnum\xmlcount{#1}{/mml:bvar}>\plusone + \left(\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}\right) + \else + \xmlfirst{#1}{/mml:bvar} + \fi + \mapsto + \MMLcreset + \xmlall{#1}{/!(mml:bvar|mml:lambda)} + } + \endgroup +\stopxmlsetups + +% compose + +\startxmlsetups mml:compose + \begingroup + \MMLcreset +% \let\MMLcCIfunction\firstofoneargument % brrr ? ? ? + \doifelsemmlfunction {#1} { + \left(\xmlconcat{#1}{/!mml:compose}{\circ}\right) + } { + \xmlconcat{#1}{/!mml:compose}{\circ} + } + \endgroup +\stopxmlsetups + +\startxmlsetups mml:image + \mathopnolimits{image} \left( {\mr\xmlfilter{#1}{/!mml:image/tag()}} \right) +\stopxmlsetups + +\setupMMLappearance[piece][\c!separator=] + +\startxmlsetups mml:piecewise + \processaction + [\MMLpieceseparator] + [ \v!yes=>\def\theMMLpieceseparator{,&}, + \v!no=>\def\theMMLpieceseparator{&}, + \s!default=>\def\theMMLpieceseparator{&}, + \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\MMLpieceseparator}\,\,}] + \cases{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:piece + \mmlfirst{#1}\theMMLpieceseparator\mathematics{\mmlsecond{#1}}\crcr +\stopxmlsetups + +\startxmlsetups mml:otherwise +% \xmlflush{#1}\MMLcPIECEseparator&{\mr otherwise}\crcr + \xmlflush{#1}&{\mr otherwise}\crcr +\stopxmlsetups + +% end of piece + +\startxmlsetups mml:quotient + \lfloor\mmlsecond{#1}/\mmlthird{#1}\rfloor +\stopxmlsetups + +\startxmlsetups mml:factorial + \xmlall{#1}{/!factorial}! +\stopxmlsetups + +\setupMMLappearance [divide] [\c!level=\!!maxcard,\c!alternative=\v!a] + +\newcount\mmldividelevel + +\startxmlsetups mml:divide + \advance\mmldividelevel\plusone + \doifelse \MMLdividealternative \v!b { + \mmlsecond{#1}/\mmlthird{#1} + } { + \ifnum \mmldividelevel > \MMLdividelevel \relax % threshold + \mmlsecond{#1}/\mmlthird{#1} + \else + \MMLcreset + \mmlfrac{\MMLcreset\mmlsecond{#1}}{\MMLcreset\mmlthird{#1}} + \fi + } + \advance\mmldividelevel\minusone +\stopxmlsetups + +% min max + +\startxmlsetups mml:min \mathopnolimits{min} \xmlsetup{#1}{mml:minmax} \stopxmlsetups +\startxmlsetups mml:max \mathopnolimits{max} \xmlsetup{#1}{mml:minmax} \stopxmlsetups + +\startxmlsetups mml:minmax + \xmldoif {#1} {/mml:bvar} { + {}\normalsubscript{\xmlfirst{#1}{/mml:bvar}} + } + \left\{ + \xmlconcat{#1}{/!(mml:bvar\string|mml:max\string|mml:min)}{\MMLseparator,} + \right\} +\stopxmlsetups + +% minus plus + +\setupMMLappearance [plus] [\c!alternative=\v!a] % b = no sign -> 3 1/4 +\setupMMLappearance [sign] [\c!reduction=\v!yes] + +% alternative b -> geen sign + +% branch needed, else (a-b) + (c-d) goes wrong +% reset check in case of (-x) + 37 +% reset check in case of (-x) + 37 + +\newcount\mmlpluscounter + +\startxmlsetups mml:plus + \doifelse \MMLsignreduction \v!yes { + \MMLdoL + \xmlsetup{#1}{mml:plus:reset} + \xmlcommand{#1}{/!mml:plus}{mml:plus:body} + \MMLdoR + } { + \ifnum\xmlcount{#1}{/!mml:plus}=\plusone + +\xmlfirst{#1}{/!mml:plus} + \else + \MMLdoL + \xmlconcat{#1}{/!mml:plus}{+} + \MMLdoR + \fi + } +\stopxmlsetups + +\startxmlsetups mml:plus:reset + \mmlpluscounter\zerocount +\stopxmlsetups + +\startxmlsetups mml:plus:body + \advance\mmlpluscounter\plusone + \ifnum\mmlpluscounter>\plusone + \xmldoifelse{#1}{/mml:minus} { + \ifnum\xmlcount{#1}{/!mml:minus}>\plusone + + + \fi + } { + \doifelse {\xmlatt{#1}{type}} {rational} { + % fraction + } { + + + } + } + \fi + \xmldirect{#1} +\stopxmlsetups + +\newcount\mmlminuscounter + +\startsetups mml:minus + \doifelse \MMLsignreduction \v!yes { + \ifnum\xmlcount{#1}{/!mml:minus}=\plusone + -\xmlfirst{#1}{/!mml:minus} + \else + \MMLdoL + \xmlsetup{#1}{mml:minus:reset} + \xmlcommand{#1}{/!mml:minus}{mml:minus:body} + \MMLdoR + \fi + } { + \left( % \MMLdoL + \ifnum\xmlcount{#1}{/!mml:minus}=\plusone + -\xmlfirst{#1}{/!mml:minus} + \else + \xmlsetup{#1}{mml:minus:reset} + \xmlcommand{#1}{/!mml:minus}{mml:minus:body} + \fi + \right) % \MMLdoR + } +\stopsetups + +\startxmlsetups mml:minus:reset + \mmlminuscounter\zerocount +\stopxmlsetups + +\startxmlsetups mml:minus:body + % we can also use concat here + \advance\mmlminuscounter\plusone + \ifnum\mmlminuscounter>\plusone + - + \fi + \xmldirect{#1} +\stopxmlsetups + +% power + +\setupMMLappearance[power][\c!reduction=\v!yes] + +\let\MMLpowerelement\empty + +\startxmlsetups mml:power + \xmldoifelse {#1} {/mml:apply} { + \doifelse \MMLpowerreduction \v!yes { + \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist)} { + \gdef\MMLpowerelement{\mmlthird{#1}}% postpone, no xdef + \MMLcreset\mmlsecond{#1} + } { + \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}} + } + } { + \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}} + } + } { + \mmlsecond{#1}\normalsuperscript{\MMLcreset\mmlthird{#1}} + } +\stopxmlsetups + +% rem + +\startxmlsetups mml:rem + \xmlconcat{#1}{/!mml:rem}{\mathopnolimits{mod}} +\stopxmlsetups + +\setupMMLappearance [times] [\c!symbol=\v!no,\c!auto=\v!yes] % new, auto catches cn cn cn + +\startxmlsetups mml:times + \setMMLcreset{\MMLcfunctionlist\string|\MMLcconstructlist}% + \doifelse\MMLtimesauto\v!no { + \let\MMLtimes@@symbol\MMLtimessymbol + } { + \xmldoifelse {#1} {/mml:cn[name(1) == 'mml:cn']} {% name(1) is next one + \doifelseinset\MMLtimessymbol{\v!yes,\v!no} { + \let\MMLtimes@@symbol\v!yes + } { + \let\MMLtimes@@symbol\MMLtimessymbol + } + } { + \let\MMLtimes@@symbol\MMLtimessymbol + } + } + \doifelse\MMLtimes@@symbol\v!yes { + \xmlconcat{#1}{/!mml:times}{\times} + } { + \doifelse\MMLtimes@@symbol{dot} { + \xmlconcat{#1}{/!mml:times}{\cdot} + } { + \doifelse\MMLtimes@@symbol{times} { + \xmlconcat{#1}{/!mml:times}{\times} + } { + \xmlall{#1}{/!mml:times} + } + } + } +\stopxmlsetups + +\setupMMLappearance[root][\c!symbol=\v!yes] + +\startxmlsetups mml:root + \xmldoifelse {#1} {/mml:degree} { + \root + \doifnot\MMLrootsymbol\v!no{\MMLcreset\xmltext{#1}{/mml:degree}} + \of + } { + \sqrt + } + {\MMLcreset\xmlall{#1}{/!(mml:degree\string|mml:root)}} +\stopxmlsetups + +% gcd + +\startxmlsetups mml:gcd + \begingroup + \gcd\left(\MMLcreset\xmlconcat{#1}{/!mml:gcd}{\MMLseparator,}\right) + \endgroup +\stopxmlsetups + +% and or xor implies, not + +\startxmlsetups mml:and \xmlconcat{#1}{/!mml:and} {\wedge} \stopxmlsetups +\startxmlsetups mml:or \xmlconcat{#1}{/!mml:or} {\vee} \stopxmlsetups +\startxmlsetups mml:xor \xmlconcat{#1}{/!mml:xor} {\mathopnolimits{xor}} \stopxmlsetups +\startxmlsetups mml:implies \xmlconcat{#1}{/!mml:implies}{\Rightarrow} \stopxmlsetups +\startxmlsetups mml:not \neg \xmlall {#1}{/!mml:not} \stopxmlsetups + +% forall exists + +%D We need to shift left below rotated A. + +\startxmlsetups mml:forall + \forall \negthinspace \xmlsetup{#1}{mml:forallexists} +\stopxmlsetups + +\startxmlsetups mml:exists + \exists \xmlsetup{#1}{mml:forallexists} +\stopxmlsetups + +\def\mmlforallexistslist{mml:bvar\string|mml:forall\string|mml:exists\string|mml:condition} + +\startxmlsetups mml:forallexists + \normalsubscript{\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}} + \xmldoifelse {#1} {/mml:condition} { + \thickspace + \begingroup + \xmlfirst{#1}{/mml:condition} + \endgroup + \ifcase\xmlcount{#1}{/!(\mmlforallexistslist)}\relax + % nothing + \or + % == snelle volgende + \left\vert + \MMLcreset \medspace \xmlconcat{#1}{/!(\mmlforallexistslist)}{} + \right. + \else + % special case + \left\vert + \matrix { + \xmlconcat{#1}{/!(\mmlforallexistslist)}{\hfill\crcr} + } + \right. + \fi + } { + :\xmlfirst{#1}{/!(\mmlforallexistslist)} + } +\stopxmlsetups + +\startxmlsetups mml:abs + \left\vert \MMLcreset\xmlall{#1}{/!mml:abs} \right\vert +\stopxmlsetups + +\startxmlsetups mml:conjugate % watch extra {} + {\overline{\MMLcreset\xmlall{#1}{/!mml:conjugate}}} +\stopxmlsetups + +\startxmlsetups mml:arg + \mathopnolimits{arg} \left( \MMLcreset\xmlall{#1}{/!mml:arg} \right) +\stopxmlsetups + +\startxmlsetups mml:real + \Re \left( \MMLcreset \xmlall{#1}{/!mml:real} \right) +\stopxmlsetups + +\startxmlsetups mml:imaginary + \Im \ left( \MMLcreset \xmlall{#1}{/!mml:imaginary} \right) +\stopxmlsetups + +\startxmlsetups mml:lcm + \mathopnolimits{lcm} \left( \xmlconcat{#1}{/!mml:lcm}{\MMLseparator,} \right) +\stopxmlsetups + +\startxmlsetups mml:floor + \lfloor \xmlall{#1}{/!mml:floor} \rfloor +\stopxmlsetups + +\startxmlsetups mml:ceiling + \lceiling \xmlall{#1}{/!mml:ceiling} \rceiling +\stopxmlsetups + +% relations + +% apply attr or eq + +\setupMMLappearance[relation][\c!align=\v!no] + +\xmlmapvalue {mml:relation} {eq} {=} +\xmlmapvalue {mml:relation} {neq} {\neq} +\xmlmapvalue {mml:relation} {gt} {>} +\xmlmapvalue {mml:relation} {lt} {<} +\xmlmapvalue {mml:relation} {geq} {\geq} +\xmlmapvalue {mml:relation} {leq} {\leq} +\xmlmapvalue {mml:relation} {equivalent} {\equiv} +\xmlmapvalue {mml:relation} {approx} {\approx} +\xmlmapvalue {mml:relation} {factorof} {\mid} + +\startxmlsetups mml:eq \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:neq \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:gt \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:lt \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:geq \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:leq \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:equivalent \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:approx \xmlsetup{#1}{mml:relation} \stopxmlsetups +\startxmlsetups mml:factorof \xmlsetup{#1}{mml:relation} \stopxmlsetups + +\startxmlsetups mml:relation + \edef\mmlapplyaction{\xmlfilter{#1}{/*/name()}} + \MMLcreset \xmlsetup{#1}{mml:relation:\xmlattdef{#1}{align}{\MMLrelationalign}} +\stopxmlsetups + +\startxmlsetups mml:relation:default + \xmlconcatrange{#1}{/*}{2}{}{\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}} +\stopxmlsetups +\startxmlsetups mml:relation:last + \eqalign { + \xmlconcatrange{#1}{/*}{2}{-2}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr} + \mmlprelast{#1}&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}\mmllast{#1} + } +\stopxmlsetups +\startxmlsetups mml:relation:first + \eqalign { + \mmlsecond{#1}\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{} + &\xmlconcatrange{#1}{/*}{3}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&} + } +\stopxmlsetups +\startxmlsetups mml:relation:left + \eqalign { + \xmlconcatrange{#1}{/*}{2}{}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr} + } +\stopxmlsetups +\startxmlsetups mml:relation:right + \eqalign { + &\xmlconcatrange{#1}{/*}{2}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&} + } +\stopxmlsetups +\startxmlsetups mml:relation:no + \xmlsetup{#1}{mml:relation:default} +\stopxmlsetups +\startxmlsetups mml:relation:yes + \xmlsetup{#1}{mml:relation:left} +\stopxmlsetups + +% personal goody: + +\edef\MMLcmainresetlist{\MMLcmainresetlist\string|becomes} + +\xmlmapvalue {mml:relation} {mml:becomes} {:=} + +\startxmlsetups mml:becomes \xmlsetup{#1}{mml:relation} \stopxmlsetups + +% calculus and vector calculus + +\startxmlsetups mml:domainofapplication + \xmlall{#1}{/!mml:domainofapplication} +\stopxmlsetups + +\setupMMLappearance[int][\c!location=\v!top] + +\def\doMMLlimits#1{\doifelsevalue{MML#1\c!location}\v!top\limits\nolimits} + +\startxmlsetups mml:int + \MMLcreset + \xmldoifelse {#1} {/mml:domainofapplication} { + \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:domainofapplication}}\relax + } { + \xmldoifelse {#1} {/mml:condition} { + \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:condition}}\relax + } { + \xmldoifelse {#1} {/mml:lowlimit} { + \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:lowlimit}}\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}} + } { + % funny, why do we have lowlimit/uplimit then + \xmldoifelse {#1} {/mml:apply/mml:interval} { + \int \doMMLlimits{int}\normalsubscript{\xmlindex{#1}{/mml:apply}{2}}\normalsuperscript{\xmlindex{#1}{/mml:apply}{3}} + } { + \int + } + } + } + } + \MMLcreset + \xmldoifelse {#1} {/mml:apply} { + \doifelsemmlfunction {#1} { % todo test + \xmlfirst{#1}{/mml:apply} + } { + % if there are too many () now, we need to be more clever + \left( \xmlfirst{#1}{/mml:apply} \right) + } + } { + \xmlfirst{#1}{/mml:ci} + } + \xmldoifelse {#1} {/mml:bvar} { + \thinspace {\mr d} \xmlfirst{#1}{/mml:bvar} + } { + % nothing + } +\stopxmlsetups + +\setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a] + +\startxmlsetups mml:diff + \MMLcreset + \doifelse \MMLdiffalternative \v!a { + \xmldoifelse {#1} {/mml:lambda} { + % a special case (mathadore/openmath) + \mmlfrac { + d + \normalsuperscript + {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}} + {\xmlfirst{#1}{/mml:lambda}\xmlfirst{#1}{/mml:ci}} + } { + d + {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:ci}} + \normalsuperscript + {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}} + } + } { + \xmldoifelse {#1} {/mml:bvar} { + \mmlfrac { + {\mr d}{ + \xmldoifelse {#1} {/mml:degree} { + \normalsuperscript{\xmlconcat{#1}{/mml:degree}\empty} + } { + \xmldoif {#1} {/mml:bvar/mml:degree} { + \normalsuperscript{\xmlconcat{#1}{/mml:bvar/mml:degree}+} + } + } + } + \doif \MMLdifflocation \v!top { + \xmldoifelse {#1} {/mml:ci} { + \xmlfirst{#1}{/mml:ci} + } { + \MMLcreset + \ifnum\xmlcount{#1}{/mml:apply/*}>\plustwo % hack + \left(\xmlfirst{#1}{/mml:apply}\right) + \else + \xmlfirst{#1}{/mml:apply} + \fi + } + } + } { + {\mr d} + \xmlfirst{#1}{/mml:bvar/!mml:degree} + \xmldoif {#1} {/mml:bvar/mml:degree} { + \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}} + } + } + \doifnot \MMLdifflocation \v!top { + \left(\MMLcreset\xmlfirst{#1}{/(mml:apply\string|mml:ci)}\right) + } + } { + % beware, the second {} is needed for the superscript + \xmlconcatrange{#1}{/*}{2}{}{}\normalsuperscript\prime + } + } + } { + \MMLcreset + \xmlfirst{#1}{/(mml:apply\string|mml:ci)} + % there can be problems with nested diff's: \normalsuperscript\normalsuperscript{} error + % so we add an empty group here + {}\normalsuperscript + { + \xmldoifelse {#1} {/mml:degree} { + \edef\mmldegree{\xmlfirst{#1}{/mml:degree/mml:cn}} + \ifx\mmldegree\empty + % what to do here + \else + \dorecurse\mmldegree\prime + \fi + } { + \prime + } + } + } +\stopxmlsetups + +\startxmlsetups mml:partialdiff + \xmldoifelse {#1} {/mml:list} { + {\mr D}\normalsubscript{ + \begingroup + \setfalse\mmllistdelimiters + \xmlall{#1}{/mml:list} + \endgroup + } + \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)} + } { + \xmldoifelse {#1} {/mml:bvar} { + \mmlfrac { + {\mr d}\normalsuperscript{ + \xmldoifelse {#1} {/mml:degree} { + \xmlconcat{#1}{/mml:degree}\empty + } { + \xmlconcat{#1}{/mml:bvar/mml:degree}+ + } + } + \MMLcreset + \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)} + } { + \xmldoif {#1}{/mml:bvar/!mml:degree} { + \xmlfirst{#1}{/mml:bvar/!mml:degree} \, + } + {\mr d}\xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)} + \xmldoif {#1} {/mml:bvar/mml:degree} { + \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}} + } + } + } { + \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)} + } + } +\stopxmlsetups + +\startxmlsetups mml:divergence \mathopnolimits{div} \xmlall{#1}{/!mml:divergence} \stopxmlsetups +\startxmlsetups mml:grad \mathopnolimits{grad} \xmlall{#1}{/!mml:grad} \stopxmlsetups +\startxmlsetups mml:curl \mathopnolimits{curl} \xmlall{#1}{/!mml:curl} \stopxmlsetups +\startxmlsetups mml:laplacian \nabla\normalsuperscript2 \xmlall{#1}{/!mml:laplacian} \stopxmlsetups +\startxmlsetups mml:ident \mathopnolimits{identity} \xmlall{#1}{/!mml:ident} \stopxmlsetups + +\setupMMLappearance[domain] [symbol=] +\setupMMLappearance[codomain][symbol=] + +\startxmlsetups mml:domain + \doifelsenothing \MMLdomainsymbol { + \mathopnolimits{domain}\MMLcreset\xmlall{#1}{/!mml:domain} + } { + \MMLdomainsymbol\normalsubscript{\xmlall{#1}{/!mml:domain}} + } +\stopxmlsetups + +\startxmlsetups mml:codomain + \doifelsenothing \MMLcodomainsymbol { + \mathopnolimits{codomain}\MMLcreset\xmlall{#1}{/!mml:codomain} + } { + \MMLcodomainsymbol\normalsubscript{\xmlall{#1}{/!mml:codomain}} + } +\stopxmlsetups + +% theory of sets + +\startxmlsetups mml:set + \left\{ + \xmldoifelse {#1} {/mml:condition} { + \xmlfirst{#1}{/mml:bvar}\,\middle\vert\,\xmlfirst{#1}{/mml:condition} + } { + \xmlconcat{#1}{/!mml:set}{\MMLseparator,} + } + \right\} + \relax % needed +\stopxmlsetups + +\settrue\mmllistdelimiters + +\startxmlsetups mml:list + \begingroup + \ifconditional\mmllistdelimiters\left [\fi + \begingroup + \settrue\mmllistdelimiters + \xmlconcat{#1}{/!mml:list}{\MMLseparator,} + \endgroup + \ifconditional\mmllistdelimiters\right]\fi + \endgroup +\stopxmlsetups + +\startxmlsetups mml:union \mmlsecond{#1} \cup \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:intersect \mmlsecond{#1} \cap \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:in \mmlsecond{#1} \in \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:notin \mmlsecond{#1} {\not\in} \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:subset \mmlsecond{#1} \subset \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:prsubset \mmlsecond{#1} \subseteq \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:notsubset \mmlsecond{#1} {\not\subset} \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:notprsubset \mmlsecond{#1} {\not\subseteq} \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:setdiff \mmlsecond{#1} \setminus \mmlthird{#1} \stopxmlsetups + +\startxmlsetups mml:card + \left\vert \xmlall{#1}{/!mml:card} \right\vert +\stopxmlsetups + +\startxmlsetups mml:cartesianproduct + \xmlconcat{#1}{/!mml:cartesianproduct}{\times} +\stopxmlsetups + +% sequences and series + +\setupMMLappearance[sum] [\c!location=\v!top] +\setupMMLappearance[product][\c!location=\v!top] + +\xmlmapvalue {mml:sumprod} {sum} {\sum} +\xmlmapvalue {mml:sumprod} {product} {\prod} + +\startxmlsetups mml:sum \edef\mmlsumprodname{sum} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups +\startxmlsetups mml:product \edef\mmlsumprodname{product} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups + +\def\mmlstackedsubscripts#1% + {\vbox + {\baselineskip\zeropoint % hack, taco vragen + \halign{\startimath\scriptstyle\hss\alignmark\alignmark\hss\stopimath\cr#1\crcr}}} + +% unfinished + +\startxmlsetups mml:sumprod + \begingroup + \xmldoifelse {#1} {/(mml:condition\string|mml:bvar\string|mml:lowlimit)} { + \def\mmlsumprodlower{ + \normalsubscript{ + \xmldoifelse {#1} {/mml:condition} { + \mmlstackedsubscripts{\xmlconcat{#1}{/mml:condition}{\crcr}} + } { + \xmldoif {#1} {/mml:bvar} { + \xmlfirst{#1}{/mml:bvar} + \xmldoif{#1}{/mml:lowlimit}{=} + } + \xmlfirst{#1}{/mml:lowlimit} + } + } + } + } { + \let\mmlsumprodlower\empty + } + \xmldoifelse {#1} {/mml:uplimit} { + \def\mmlsumprodupper{\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}}} + } { + \let\mmlsumprodupper\empty + } + \xmldoif {#1} {/mml:interval} { % open math converter gives this + \edef\mmlintervalfrom{\xmlindex{#1}{/mml:interval}{1}} + \edef\mmlintervalto {\xmlindex{#1}{/mml:interval}{2}} + \ifx \mmlintervalfrom \empty \else + \def\mmlsumprodlower{\normalsubscript{\xmldoif{#1}{/mml:bvar}{\xmlfirst{#1}{/mml:bvar}{=}}\mmlintervalfrom}} + \fi + \ifx \mmlintervalto \empty \else + \def\mmlsumprodupper{\normalsuperscript{\mmlintervalto}} + \fi + } + \MMLcreset + \xmlval{mml:sumprod}{\mmlsumprodname}{}\doMMLlimits\mmlsumprodname\mmlsumprodupper\mmlsumprodlower + \MMLcreset + \xmldoifelse {#1} {/mml:lambda/mml:apply} { + \xmlfirst{#1}{/mml:lambda/mml:apply}% a bit of open math conversion mess + } { + \xmlfirst{#1}{/(mml:apply\string|mml:lambda\string|mml:ci)}% + } + \endgroup +\stopxmlsetups + +\setupMMLappearance[limit][\c!location=\v!top] + +\startxmlsetups mml:limit + \MMLcreset \lim + \doMMLlimits {limit}\normalsubscript{ + \MMLcreset + \xmldoifelse {#1} {/mml:condition} { + \xmlfirst{#1}{/mml:condition} + } { + \xmldoif {#1} {/mml:bvar} { + \xmlfirst{#1}{/mml:bvar}\rightarrow + } + \xmlfirst{#1}{/mml:lowlimit} + } + } + \begingroup + % a bit of open math conversion mess, lambda needed for openmath, ok? + \MMLcreset + \xmlfirst{#1}{/mml:lambda/mml:apply} + \xmlfirst{#1}{/(mml:apply\string|mml:lambda)} + \endgroup +\stopxmlsetups + +% consider a faster index + +\startxmlsetups mml:tendsto + \MMLcreset \mmlsecond{#1} + \xmlval {mml:tendsto:type} {\xmlattdef{#1}{type}{default}} {\rightarrow} + \MMLcreset \mmlthird{#1} +\stopxmlsetups + +\xmlmapvalue {mml:tendsto:type} {above} {\downarrow} +\xmlmapvalue {mml:tendsto:type} {below} {\uparrow} +\xmlmapvalue {mml:tendsto:type} {default} {\rightarrow} + +% elementary classical functions + +\setupMMLappearance[log][\c!location=\v!right] + +\startxmlsetups mml:exp +% {\mr e}\normalsuperscript{\xmlfirst{#1}{/mml:apply\string|mml:reln\string|mml:ci\string|mml:cn}} + {\mr e}\normalsuperscript{\xmlfirst{#1}{/!mml:exp}} +\stopxmlsetups + +\startxmlsetups mml:log + \xmldoifelse {#1} {/mml:logbase} { + \doifelse \MMLloglocation \v!left { + \mathop { + {}\normalsuperscript{\xmlfirst{#1}{/mml:logbase}}\negthinspace\mathopnolimits{log} + } + } { + \mathopnolimits{log}\normalsubscript{\xmlfirst{#1}{/mml:logbase}} + } +% \MMLcreset + \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)} +% \xmlsetup{#1}{mml:function} % todo, we start elsewhere +% \mmlthird{#1} + } { + \mathopnolimits{log} +% \MMLcreset +% \xmlsetup{#1}{mml:function} % todo, we start elsewhere + \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)} +% \mmlsecond{#1} + } +\stopxmlsetups + +\startxmlsetups mml:ln + \mathopnolimits{ln} + \xmlsetup{#1}{mml:function} +\stopxmlsetups + +% statistics + +\startxmlsetups mml:mean \overline {\mmlsecond{#1}} \stopxmlsetups +\startxmlsetups mml:sdev \sigma \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups +\startxmlsetups mml:variance \sigma \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript2 \stopxmlsetups +\startxmlsetups mml:median \mathopnolimits{median}\left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups +\startxmlsetups mml:mode \mathopnolimits{mode} \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups + +% moments + +\startxmlsetups mml:moment + \left\langle + \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}\normalsuperscript{\xmlfirst{#1}{/mml:degree}} + \right\rangle + \xmldoif {#1} {mml:momentabout} { + \normalsubscript{\xmlfirst{#1}{mml:momentabout}} + } +\stopxmlsetups + +% linear algebra + +\setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}] + +\startxmlsetups mml:vector + \begingroup + \ifnum\xmlcount{#1}{/*}>\plusone + \doifelse\MMLvectordirection\v!horizontal { + \left(\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}\right) + } { + \MMLcreset\left(\matrix{\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}}\right) + } + \else + \overrightarrow{\charhtstrut\mmlfirst{#1}} + \fi + \endgroup +\stopxmlsetups + +\settrue\MMCdelmatrix % ( ) when true + +\startxmlsetups mml:matrix + \begingroup + \MMLcreset + \ifconditional\MMCdelmatrix + \left(\matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}\right) + \else + \settrue\MMCdelmatrix + \matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}} + \fi + \endgroup +\stopxmlsetups + +\startxmlsetups mml:matrixrow + \begingroup + \MMLcreset + \left(\xmlsetup{#1}{mml:matrixrow:do}\right) + \endgroup +\stopxmlsetups + +\startxmlsetups mml:matrixrow:do + \xmlconcat{#1}{/*}{&}\crcr +\stopxmlsetups + +\startxmlsetups mml:determinant + \begingroup + \setfalse\MMCdelmatrix + \left|\mmlsecond{#1}\right| + \endgroup +\stopxmlsetups + +\startxmlsetups mml:transpose + \mmlsecond{#1}\normalsuperscript{\mathopnolimits{T}} +\stopxmlsetups + +\startxmlsetups mml:selector + \MMLmathinner{\mmlsecond{#1}\normalsubscript{\MMLcreset\xmlconcatrange{#1}{/*}{3}{}{\MMLseparator,}}} +\stopxmlsetups + +\startxmlsetups mml:vectorproduct \mmlsecond{#1}\times \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:scalarproduct \mmlsecond{#1}\cdot \mmlthird{#1} \stopxmlsetups +\startxmlsetups mml:outerproduct \mmlsecond{#1}\otimes\mmlthird{#1} \stopxmlsetups + +% semantic mapping elements + +\setupMMLappearance[semantics][\c!state=\v!start] + +\startxmlsetups mml:semantics + \doifelse\MMLsemanticsstate\v!start { + \xmlall{#1}{/mml:annotation} + } { + \xmlall{#1}{/!mml:annotation} + } +\stopxmlsetups + +\startxmlsetups mml:annotation + \xmldoifelse {#1} {.[oneof(@encoding,'TeX','tex','application/x-tex','TEX','ConTeXt','context','CONTEXT','ctx')]} { + \xmlflushcontext{#1} + } { + \xmldoifelse {#1} {.[oneof(@encoding,'calcmath','cm')]} { + \expanded{\calcmath{\xmlflush{#1}}} + } { + \xmldoifelse {#1} {.[oneof(@encoding,'asciimath','am')]} { + \ifdefined\asciimath + \expanded{\asciimath{\xmlflushpure{#1}}} + \else + \hbox{\tt no am loaded} + \fi + } { + \xmlall{#1}{../!mml:annotation} + } + } + } +\stopxmlsetups + +\startxmlsetups mml:annotation-xml + % maybe diagnostics +\stopxmlsetups + +% misc + +\startxmlsetups mml:integers \integers \stopxmlsetups +\startxmlsetups mml:reals \reals \stopxmlsetups +\startxmlsetups mml:rationals \rationals \stopxmlsetups +\startxmlsetups mml:naturalnumbers \naturalnumbers \stopxmlsetups +\startxmlsetups mml:complexes \complexes \stopxmlsetups +\startxmlsetups mml:primes \primes \stopxmlsetups +\startxmlsetups mml:exponentiale \mathopnolimits{e} \stopxmlsetups +\startxmlsetups mml:imaginaryi \mathopnolimits{i} \stopxmlsetups +\startxmlsetups mml:notanumber \mathopnolimits{NaN} \stopxmlsetups +\startxmlsetups mml:true \mathopnolimits{true} \stopxmlsetups +\startxmlsetups mml:false \mathopnolimits{false} \stopxmlsetups +\startxmlsetups mml:emptyset \mathopnolimits{Ø} \stopxmlsetups +\startxmlsetups mml:pi \pi \stopxmlsetups +\startxmlsetups mml:eulergamma \gamma \stopxmlsetups +\startxmlsetups mml:infinity \infty \stopxmlsetups + +% gonio functions + +\setupMMLappearance[function][\c!reduction=\v!yes] + +% todo: \mfunction which adapts itself when registered as command + +% todo: \def\mmlcfunction#1#2{\mathopnolimits{#2}\xmlsetup{#1}{mml:function}} + +\startxmlsetups mml:sin \mathcommand {sin}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:sinh \mathcommand {sinh}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:cos \mathcommand {cos}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:cosh \mathcommand {cosh}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:tan \mathcommand {tan}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:tanh \mathcommand {tanh}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:cot \mathcommand {cot}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:coth \mathcommand {coth}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:csc \mathcommand {csc}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:csch \mathcommand {csch}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:sec \mathcommand {sec}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:sech \mathcommand {sech}\xmlsetup{#1}{mml:function} \stopxmlsetups + +\startxmlsetups mml:arcsin \mathcommand {arcsin}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arcsinh \mathcommand{arcsinh}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arccos \mathcommand {arccos}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arccosh \mathcommand{arccosh}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arctan \mathcommand {arctan}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arctanh \mathcommand{arctanh}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arccot \mathcommand {arccot}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arccoth \mathcommand{arccoth}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arccsc \mathcommand {arccsc}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arccsch \mathcommand{arccsch}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arcsec \mathcommand {arcsec}\xmlsetup{#1}{mml:function} \stopxmlsetups +\startxmlsetups mml:arcsech \mathcommand{arcsech}\xmlsetup{#1}{mml:function} \stopxmlsetups + +\startxmlsetups mml:function + \ifx\MMLpowerelement\empty + \ifconditional\xmlinversefunction\normalsuperscript{-1}\fi + \setfalse\xmlinversefunction + \else + \normalsuperscript{\ifconditional\xmlinversefunction-\fi\MMLpowerelement} + \setfalse\xmlinversefunction + \glet\MMLpowerelement\empty + \fi + \xmlsetup{#1}{mml:function:argument} +\stopxmlsetups + +\startxmlsetups mml:function:argument + \doifelse \MMLfunctionreduction \v!yes { + \xmldoifelse {#1} {/mml:apply} { + \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist\string|mml:divide)} + \donefalse + \donetrue + } { + \donefalse + } + } { + \donetrue + } + % beware, we still flush from 2 up + \ifdone + \left( + \MMLcreset + \xmlall{#1}{/[position()>1]}% \xmlconcatrange{#1}{/*}{2}{}\empty + \right) + \else + \MMLcreset + \xmlall{#1}{/[position()>1]} + \fi +\stopxmlsetups + +% PRESENTATION MATHML + +% helpers: maybe we can need a setting for the uprights + +\xmlmapvalue {mml:s} {normal} {\mathupright} % {\mathtf} +\xmlmapvalue {mml:s} {double-struck} {\mathblackboard} +\xmlmapvalue {mml:s} {italic} {\mathit} +\xmlmapvalue {mml:s} {fraktur} {\mathfraktur} +\xmlmapvalue {mml:s} {script} {\mathscript} +\xmlmapvalue {mml:s} {bold} {\mb} % {\mathbf} +\xmlmapvalue {mml:s} {bold-italic} {\mathbi} +\xmlmapvalue {mml:s} {bold-fraktur} {\mathfraktur\mathbf} +\xmlmapvalue {mml:s} {bold-script} {\mathscript\mathbf} +\xmlmapvalue {mml:s} {sans-serif} {\mathss} +\xmlmapvalue {mml:s} {bold-sans-serif} {\mathss\mathbf} +\xmlmapvalue {mml:s} {sans-serif-italic} {\mathss\mathit} +\xmlmapvalue {mml:s} {sans-serif-bold-italic} {\mathss\mathbi} +\xmlmapvalue {mml:s} {monospace} {\mathtt} + +\xmlmapvalue {mml:l} {-} {\let\mmlfrac\tfrac} + \let\mmlfrac\frac +\xmlmapvalue {mml:l} {+} {\let\mmlfrac\sfrac} + +% todo: displaystyle=true/false (or whatever else shows up) + +\starttexdefinition setmmlmathstyle #1 + \xmlval{mml:s}{\xmlatt{#1}{mathvariant}}\empty % was: \mmmr +\stoptexdefinition + +\starttexdefinition setmmlscriptlevel #1 + \xmlval{mml:l}{\xmlatt{#1}{scriptlevel}}{\let\mmlfrac\frac} +\stoptexdefinition + +\starttexdefinition applymmlmathcolor #1#2 + \edef\mmlmathcolor{\xmlatt{#1}{mathcolor}} + \ifx \mmlmathcolor \empty + #2 + \else + \color[\mmlmathcolor]{#2} + \fi +\stoptexdefinition + +% todo: textbackgrounds + +\starttexdefinition applymmlmathbackground #1#2 + \edef\mmlmathbackground{\xmlatt{#1}{mathbackground}} + \ifx \mmlmathbackground \empty + #2 + \else + \backgroundline[\mmlmathbackground]{#2} + \fi +\stoptexdefinition + +\newsignal\mmltextsignal % not used + +\starttexdefinition applymmlsometext #1#2 + \applymmlmathbackground {#1} { + \applymmlmathcolor {#1} { + \setmmlmathstyle {#1} + #2 + } + } +\stoptexdefinition + +% probably bugged: + +\starttexdefinition doMMLfiller #1 + \pushmacro\doMMLfiller + \let\doMMLfiller\gobbleoneargument + \gdef\dodoMMLfiller{% where used + \disablefiller + \mathematics{#1} + } + \hbox { + \def\normalorfiller##1##2{ + \gdef\dodoMMLfiller{\enablefiller#1}% + \let\normalorfiller\gobbletwoarguments + } + \mathematics{#1} + } + \popmacro\doMMLfiller +\stoptexdefinition + +% setups + +\startxmlsetups mml:mi % todo: mathsize (unlikely) mathcolor (easy) mathbackground (easy) + \begingroup + \pushmathstyle + \setmmlmathstyle{#1} + \setmmlscriptlevel{#1} + \ctxmodulemathml{mi("#1")} + \popmathstyle + \endgroup +\stopxmlsetups + +\startxmlsetups mml:mn + \ctxmodulemathml{mn("#1")}% no \hbox, would be ok for . , but spoils rest +\stopxmlsetups + +% <m:mo>-</m:mo><m:mn>2</m:mn> and <m:mn>1</m:mn><m:mo>-</m:mo><m:mn>2</m:mn> +% +% spacing between - and 2 is taken care of by tex itself + +\startxmlsetups mml:mo + \doif {\xmlatt{#1}{maxsize}} {1} {\settrue\mmlignoredelimiter} + \doif {\xmlatt{#1}{stretchy}} {false} {\settrue\mmlignoredelimiter} + \ctxmodulemathml{mo("#1")} + \setfalse\mmlignoredelimiter +\stopxmlsetups + +% \startxmlsetups mml:mfenced % {} around separator is needed for spacing +% \def\MMLleft {\left }% weird +% \def\MMLright {\right} +% \def\MMLmiddle{\middle} +% \ctxmodulemathml{mfenced("#1")} +% \stopxmlsetups + +\startxmlsetups mml:mfenced % {} around separator is needed for spacing + %\math_fences_checked_start + \ctxmodulemathml{mfenced("#1")} + %\math_fences_checked_stop +\stopxmlsetups + + +\defineoverlay [mml:enclose:box] [\useMPgraphic{mml:enclose:box}] +\defineoverlay [mml:enclose:roundedbox] [\useMPgraphic{mml:enclose:roundedbox}] +\defineoverlay [mml:enclose:circle] [\useMPgraphic{mml:enclose:circle}] +\defineoverlay [mml:enclose:left] [\useMPgraphic{mml:enclose:left}] +\defineoverlay [mml:enclose:right] [\useMPgraphic{mml:enclose:right}] +\defineoverlay [mml:enclose:top] [\useMPgraphic{mml:enclose:top}] +\defineoverlay [mml:enclose:bottom] [\useMPgraphic{mml:enclose:bottom}] +\defineoverlay [mml:enclose:updiagonalstrike] [\useMPgraphic{mml:enclose:updiagonalstrike}] +\defineoverlay [mml:enclose:downdiagonalstrike] [\useMPgraphic{mml:enclose:downdiagonalstrike}] +\defineoverlay [mml:enclose:horizontalstrike] [\useMPgraphic{mml:enclose:horizontalstrike}] +\defineoverlay [mml:enclose:verticalstrike] [\useMPgraphic{mml:enclose:verticalstrike}] + +\startuseMPgraphic{mml:enclose:box} + draw OverlayBox withpen pencircle scaled (ExHeight/10) ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:roundedbox} + draw OverlayBox cornered .5ExHeight withpen pencircle scaled (ExHeight/10) ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:circle} + draw fullcircle xysized(bbwidth(OverlayBox),bbheight(OverlayBox)) withpen pencircle scaled (ExHeight/10) ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:left} + draw leftboundary OverlayBox withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:right} + draw rightboundary OverlayBox withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:top} + draw topboundary OverlayBox withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:bottom} + draw bottomboundary OverlayBox withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:updiagonalstrike} + path p ; p := OverlayBox enlarged -.25ExHeight ; + draw llcorner p -- urcorner p withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:downdiagonalstrike} + path p ; p := OverlayBox enlarged -.25ExHeight ; + draw ulcorner p -- lrcorner p withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:horizontalstrike} + path p ; p := OverlayBox enlarged -.25ExHeight ; + draw .5[llcorner p,ulcorner p] -- .5[lrcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic +\startuseMPgraphic{mml:enclose:verticalstrike} + path p ; p := OverlayBox enlarged -.25ExHeight ; + draw .5[llcorner p,lrcorner p] -- .5[ulcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ; + setbounds currentpicture to OverlayBox ; +\stopuseMPgraphic + +\startxmlsetups mml:menclose + \edef\mmlmenclosenotation{\ctxmodulemathml{menclosepattern("#1")}} + \ifx\mmlmenclosenotation\empty + \xmlflush{#1} + \else + \doifelse \mmlmenclosenotation {mml:enclose:longdiv} { + \overline{\left)\strut\xmlflush{#1}\right.} + } { + \doifelse \mmlmenclosenotation {mml:enclose:actuarial} { + \overline{\left.\strut\xmlflush{#1}\right\vert} + } { + \doifelse \mmlmenclosenotation {mml:enclose:radical} { + \sqrt{\xmlflush{#1}} + } { + % todo: no framed when longdiv, actuarial or radical ? spec ? + \vcenter { + \framed + [frame=off,strut=no,background={\mmlmenclosenotation}] % offset is kind of undefined + {\startimath + \expanded{\doifelseinset {mml:enclose:longdiv} {\mmlmenclosenotation}} { + \overline{\left)\strut\xmlflush{#1}\right.} + } { + \expanded{\doifelseinset {mml:enclose:actuarial} {\mmlmenclosenotation}} { + \overline{\left.\strut\xmlflush{#1}\right\vert} + } { + \expanded{\doifelseinset {mml:enclose:radical} {\mmlmenclosenotation}} { + \sqrt{\xmlflush{#1}} + } { + \xmlflush{#1} + } + } + } + \stopimath} + } + } + } + } + \fi +\stopxmlsetups + +\xmlmapvalue {mml:mfrac:linethickness} {thin} {.2pt} +\xmlmapvalue {mml:mfrac:linethickness} {medium} {.4pt} +\xmlmapvalue {mml:mfrac:linethickness} {thick} {.8pt} +\xmlmapvalue {mml:mfrac:linethickness} {0} {0pt} + +\startxmlsetups mml:mfrac % dodo: handle linethickness in lua + unit + \begingroup + \edef\mmlfraclinethickness{\xmlatt{#1}{linethickness}} + \ifx\mmlfraclinethickness\empty + \doifelse{\xmlatt{#1}{bevelled}}{true} { + \left.\mmlfirst{#1}\middle/\mmlsecond{#1}\right.% \thinspace\middle/\thinspace + } { + \mmlfrac{\mmlfirst{#1}}{\mmlsecond{#1}} + } + \else + \doifelse {\xmlval{mml:mfrac:linethickness}{\mmlfraclinethickness}{}} {} { + \scratchdimen\xmlval{mml:mfrac:linethickness}\mmlfraclinethickness{.4pt} + } { + % probably not yet ok + \setdimensionwithunit\scratchdimen\mmlfraclinethickness{pt} + } + { + {\mmlfirst{#1}} + \above\scratchdimen + {\mmlsecond{#1}} + } + \fi + \endgroup +\stopxmlsetups + +\startxmlsetups mml:ms + \hbox { + \tf % else encoding problems + \edef\mmllquote{\xmlatt{#1}{lquote}} + \edef\mmlrquote{\xmlatt{#1}{rquote}} + \ifx\mmllquote\empty\symbol[leftquotation]\else\mmllquote\fi + \applymmlsometext{#1}{\xmlflush{#1}} + \ifx\mmlrquote\empty\symbol[rightquotation]\else\mmlrquote\fi + } +\stopxmlsetups + +\startxmlsetups mml:mstyle + \begingroup + \pushmathstyle + \setmmlmathstyle{#1} + \setmmlscriptlevel{#1} + \xmlflush{#1} + \popmathstyle + \endgroup +\stopxmlsetups + +\setupMMLappearance[text][\c!alternative=\v!b] % a=normal, b=keep spaces + +\startxmlsetups mml:mtext + \text { + \applymmlsometext{#1}{ + \doifelse \MMLtextalternative \v!a { + %\ctxmodulemathml{stripped(\!!bs\xmlflush{#1}\!!es)} + \ignorespaces + \xmlflush{#1} + \removeunwantedspaces + } { + \xmlflush{#1} + } + } + } +\stopxmlsetups + +\startxmlsetups mml:merror + \hbox{\startimath\displaystyle\xmlflush{#1}\stopimath} +\stopxmlsetups + +\startxmlsetups mml:mphantom +% \phantom{\ignorespaces{}\xmlflush{#1}\unskip} % watch spacing {} hack +% \phantom{\mathstyle{\ignorespaces{}\xmlflush{#1}\unskip}}% + \phantom{\triggermathstyle\normalmathstyle\ignorespaces\xmlflush{#1}\removeunwantedspaces} +% \mktriggereffect\v!hidden +% \ignorespaces{}\xmlflush{#1}\unskip % no attributes in math yet +% \mktriggereffect\v!normal +\stopxmlsetups + +\startxmlsetups mml:mpadded % todo + \xmlflush{#1} +\stopxmlsetups + +% mrow / option: no fenced + +\startxmlsetups mml:maction + \xmlflush{#1} +\stopxmlsetups + +% \startxmlsetups mml:mrow +% \begingroup +% \edef\nofmmlrows{\xmlcount{#1}{/mml:mo}}% +% \ifnum\nofmmlrows=\plustwo +% \xmldoifelse {#1} {/mml:mo[position()==1 or position()==\nofmmlrows]} {% we need a {} +% \def\MMLleft {\left } +% \def\MMLright {\right} +% \def\MMLmiddle{\middle} +% \enabledelimiter +% \checkdelimiters{\xmlall{#1}{/mml:mo}} +% \fakeleftdelimiter +% \xmlflush{#1} +% \fakerightdelimiter +% \disabledelimiter +% } { +% \xmlflush{#1} +% } +% \else +% \xmlflush{#1} +% \fi +% \endgroup +% \stopxmlsetups +% +% fails on { ... so we need + +% \startxmlsetups mml:mrow +% \begingroup +% \xmldoifelse {#1} {/mml:mo[first() or last()]} {% we need a {} +% \def\MMLleft {\left } +% \def\MMLright {\right} +% \def\MMLmiddle{\middle} +% \enabledelimiter +% \checkdelimiters{\xmlall{#1}{/mml:mo}} +% \fakeleftdelimiter +% \xmlflush{#1} +% \fakerightdelimiter +% \disabledelimiter +% } { +% \xmlflush{#1} +% } +% \endgroup +% \stopxmlsetups +% +% more modern: + +\startxmlsetups mml:mrow + \begingroup + %\xmldoifelse {#1} {/mml:mo[first() or last()]} {% we need a {} + % % \math_fences_checked_start + % \xmlflush{#1} + % \math_fences_checked_stop + %} { + \xmlflush{#1} + %} + \endgroup +\stopxmlsetups + +\startxmlsetups mml:msqrt + \sqrt{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups mml:mroot + \root{\mmlsecond{#1}}\of{\mmlfirst{#1}} +\stopxmlsetups + +\setupMMLappearance[scripts][\c!alternative=\v!a] % {} rond base + +% brrr no { } when limop .. todo: better in lua +% speed up with ifx and setups or just in lua + +\let\mmlnucleus\relax + +\startxmlsetups mml:msub + \edef\mmlnucleus{\xmlraw{#1}{/mml:*[1]}} + \doifelse {\utfmathclass\mmlnucleus} {limop} { + \mmlfirst{#1} \normalsubscript{\mmlsecond{#1}} + } { + \doifelse\MMLscriptsalternative\v!a { + {\mmlfirst{#1}}\normalsubscript{\mmlsecond{#1}} + } { + \mmlfirst{#1} \normalsubscript{\mmlsecond{#1}} + } + } +\stopxmlsetups + +\startxmlsetups mml:msup + \edef\mmlnucleus{\xmlraw{#1}{/mml:*[1]}} + \doifelse {\utfmathclass\mmlnucleus} {limop} { + \mmlfirst{#1} \normalsuperscript{\mmlsecond{#1}} + } { + \doifelse\MMLscriptsalternative\v!a { + {\mmlfirst{#1}}\normalsuperscript{\mmlsecond{#1}} + } { + \mmlfirst{#1} \normalsuperscript{\mmlsecond{#1}} + } + } +\stopxmlsetups + +\startxmlsetups mml:msubsup + \edef\mmlnucleus{\xmlraw{#1}{/mml:*[1]}} + \doifelse {\utfmathclass\mmlnucleus} {limop} { + \mmlfirst{#1}\normalsubscript{\mmlsecond{#1}}\normalsuperscript{\mmlthird{#1}} + } { + \doifelse\MMLscriptsalternative\v!a { + {\mmlfirst{#1}}\normalsubscript{\mmlsecond{#1}}\normalsuperscript{\mmlthird{#1}} + } { + \mmlfirst{#1}\normalsubscript{\mmlsecond{#1}}\normalsuperscript{\mmlthird{#1}} + } + } +\stopxmlsetups + +% helpers + +\unexpanded\def\mmlexecuteifdefined#1% + {\ifx#1\empty + \expandafter\secondoftwoarguments + \else\ifcsname#1\endcsname + \doubleexpandafter\firstoftwoarguments + \else + \doubleexpandafter\secondoftwoarguments + \fi\fi + {\csname#1\endcsname}} + +\def\mmlextensible#1{\ctxmodulemathml{extensible(\!!bs#1\!!es)}} + +\definemathtriplet [\v!mathematics] [mmlovertriplet] % or will we use a special instance +\definemathtriplet [\v!mathematics] [mmlundertriplet] % or will we use a special instance +\definemathtriplet [\v!mathematics] [mmldoubletriplet] % or will we use a special instance + +% common to munder/mover/munderover : will become core helper (speed up too) + +\starttexdefinition unexpanded mmlfencedfirst #1 + %\math_fences_checked_start + \mmlunexpandedfirst{#1} + %\math_fences_checked_stop +\stoptexdefinition +\starttexdefinition unexpanded mmlfencedsecond #1 + %\math_fences_checked_start + \mmlunexpandedsecond{#1} + %\math_fences_checked_stop +\stoptexdefinition +\starttexdefinition unexpanded mmlfencedthird #1 + %\math_fences_checked_start + \mmlunexpandedthird{#1} + %\math_fences_checked_stop +\stoptexdefinition + +% mover + +\starttexdefinition unexpanded mmloverabove #1 + \edef\mmlovercommand{\utfmathfiller\mmlovertoken} + \mmlexecuteifdefined\mmlovercommand {\mmlfencedsecond{#1}} \relax +\stoptexdefinition +\starttexdefinition unexpanded mmloverbase #1 + \edef\mmlbasecommand{\utfmathfiller\mmlbasetoken} + \mmlexecuteifdefined\mmlbasecommand {\mmlfencedfirst{#1}} + \relax +\stoptexdefinition +\starttexdefinition unexpanded mmloverbasefiller #1 + \edef\mmlbasecommand{e\utfmathcommandfiller\mmlbasetoken} + \mmlexecuteifdefined\mmlbasecommand \relax {\mmlfencedsecond{#1}} {} +\stoptexdefinition +\starttexdefinition unexpanded mmloveraccent #1 + \edef\mmlovercommand{\utfmathcommandabove\mmlovertoken} + \mmlexecuteifdefined\mmlovercommand \relax {\mmlfencedfirst{#1}} +\stoptexdefinition +\starttexdefinition unexpanded mmlovertext #1 + \mmlovertriplet {\mmloverbase{#1}} {\mmloverabove{#1}} {} +\stoptexdefinition +\starttexdefinition unexpanded mmloveraccentchecker #1 + \edef\mmlovertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text() + \doifelseutfmathabove\mmlovertoken \mmloveraccent \mmlovertext {#1} +\stoptexdefinition + +\startxmlsetups mml:mover + \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text() + \doifelseutfmathfiller\mmlbasetoken \mmloverbasefiller \mmloveraccentchecker {#1} +\stopxmlsetups + +% munder + +\starttexdefinition unexpanded mmlunderbelow #1 + \edef\mmlundercommand{\utfmathfiller\mmlundertoken} + \mmlexecuteifdefined\mmlundercommand {\mmlfencedsecond{#1}} \relax +\stoptexdefinition +\starttexdefinition unexpanded mmlunderbase #1 + \edef\mmlbasecommand{\utfmathfiller\mmlbasetoken} + \mmlexecuteifdefined\mmlbasecommand {\mmlfencedfirst{#1}} + \relax +\stoptexdefinition +\starttexdefinition unexpanded mmlunderbasefiller #1 + \edef\mmlbasecommand{e\utfmathcommandfiller\mmlbasetoken}% + \mmlexecuteifdefined\mmlbasecommand \relax {} {\mmlfencedsecond{#1}} +\stoptexdefinition +\starttexdefinition unexpanded mmlunderaccent #1 + \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken} + \mmlexecuteifdefined\mmlundercommand \relax {\mmlfencedfirst{#1}} +\stoptexdefinition +\starttexdefinition unexpanded mmlundertext #1 + \mmlundertriplet {\mmlunderbase{#1}} {} {\mmlunderbelow{#1}} +\stoptexdefinition +\starttexdefinition unexpanded mmlunderaccentchecker #1 + \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text() + \doifelseutfmathbelow\mmlundertoken \mmlunderaccent \mmlundertext {#1} +\stoptexdefinition + +\startxmlsetups mml:munder + \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text() + \doifelseutfmathfiller\mmlbasetoken \mmlunderbasefiller \mmlunderaccentchecker {#1} +\stopxmlsetups + +% munderover + +\starttexdefinition unexpanded mmlunderoveraccentcheckerUO #1 + \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken} + \edef\mmlovercommand {\utfmathcommandabove\mmlovertoken} + \edef\mmlbasecommand {\mmlovercommand\mmlundercommand} + \ifcsname\mmlbasecommand\endcsname + \lastnamedcs {\mmlfencedfirst{#1}} + \else\ifcsname\mmlundercommand\endcsname + \ifcsname\mmlovercommand\endcsname + \lastnamedcs {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} + \else + \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}\mmlfencedthird{#1}} {} + \fi + \else\ifcsname\mmlovercommand\endcsname + \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}} + \else + \mmlunderoveraccentcheckerTT {#1} + \fi\fi\fi +\stoptexdefinition +\starttexdefinition unexpanded mmlunderoveraccentcheckerUT #1 + \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken} + \edef\mmlbasecommand {\mmlundercommand text} + \ifcsname\mmlbasecommand\endcsname + \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}} + \else\ifcsname\mmlundercommand\endcsname + \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}} {} + \else + \mmlunderoveraccentcheckerTT {#1} + \fi\fi +\stoptexdefinition +\starttexdefinition unexpanded mmlunderoveraccentcheckerOT #1 + \edef\mmlovercommand{\utfmathcommandabove\mmlovertoken} + \edef\mmlbasecommand{\mmlovercommand text} + \ifcsname\mmlbasecommand\endcsname + \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedsecond{#1}} + \else\ifcsname\mmlovercommand\endcsname + \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}} + \else + \mmlunderoveraccentcheckerTT {#1} + \fi\fi +\stoptexdefinition +\starttexdefinition unexpanded mmlunderoveraccentcheckerTT #1 + \mmldoubletriplet {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}} \relax +\stoptexdefinition +\starttexdefinition unexpanded mmlunderoveraccentchecker #1 + \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text() + \edef\mmlovertoken {\mmlextensible{\xmlraw{#1}{/mml:*[3]}}}% /text() + \doifelseutfmathbelow\mmlundertoken { + \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerUO \mmlunderoveraccentcheckerUT {#1} + } { + \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerOT \mmlunderoveraccentcheckerTT {#1} + } +\stoptexdefinition +\starttexdefinition unexpanded mmlunderoverbasefiller #1 + \edef\mmlbasecommand{e\utfmathcommandfiller\mmlbasetoken}% + \mmlexecuteifdefined\mmlbasecommand \relax {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}} +\stoptexdefinition +\startxmlsetups mml:munderover + \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text() + \doifelseutfmathfiller\mmlbasetoken \mmlunderoverbasefiller \mmlunderoveraccentchecker {#1} +\stopxmlsetups + +% tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd) + +\startxmlsetups mml:mtable % some more attributes need to be supported + \vcenter { + \hbox {% needed because otherwise positions makr the vcenter wide + \ctxmodulemathml{mtable("#1")} + } + } +\stopxmlsetups + +\startxmlsetups mml:mcolumn + \ctxmodulemathml{mcolumn("#1")} +\stopxmlsetups + +\def\mmlsetfakewidth#1{\setbox\scratchbox\hbox{#1}\scratchdimen\wd\scratchbox} + +\def\mmlmcolumndigitspace {\mmlsetfakewidth {0}\kern\scratchdimen} +\def\mmlmcolumndigitrule {\mmlsetfakewidth {0}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax} +\def\mmlmcolumnsymbolrule {\mmlsetfakewidth{\times}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax} +\def\mmlmcolumnpunctuationrule{\mmlsetfakewidth {.}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax} + +\setupMMLappearance[mspace][\c!option=] % \v!test + +\startxmlsetups mml:mspace + \begingroup + \edef\mmlspacetext{\xmlatt{#1}{spacing}} + \ifx\mmlspacetext\empty + \scratchwidth \xmlattdef{#1}{width} \!!zeropoint % must be string + \scratchheight\xmlattdef{#1}{height}\!!zeropoint + \scratchdepth \xmlattdef{#1}{depth} \!!zeropoint + \ifdim\scratchheight=\zeropoint + \ifdim\scratchdepth=\zeropoint\else + \hbox{\vrule\s!depth\scratchdepth\s!height\zeropoint\s!width\zeropoint}% + \fi + \else + \hbox{\vrule\s!depth\zeropoint\s!height\scratchheight\s!width\zeropoint}% + \fi + \ifdim\scratchwidth=\zeropoint\else + \ifx\MMLmspaceoption\v!test + \hbox to \scratchwidth{\showstruts\strut\hss\lower2\exheight\hbox{\infofont\xmlattdef{#1}{width}}\hss\strut} + \else + \hskip\scratchwidth + \fi + \fi + \else + \ifx\MMLmspaceoption\v!test + \hbox{\showstruts\strut\phantom{\triggermathstyle\normalmathstyle\mmlspacetext}\strut} + \else + \phantom{\triggermathstyle\normalmathstyle\mmlspacetext} + \fi + \fi + \endgroup +\stopxmlsetups + +% later we can do a better job by manipulating node lists + +% \startxmlsetups mml:mline +% % new, rather undefined, we need to capture a few keywords +% \edef\mmllinewidth {\xmlatt{#1}{linethickness}} +% \edef\mmllinetext {\xmlatt{#1}{spacing}} +% \edef\mmllinelength{\xmlattdef{#1}{length}\!!zeropoint} +% \ifx\mmllinewidth\empty +% \!!deptha.5\linewidth +% \else +% \!!deptha.5\dimexpr\mmllinewidth\relax +% \fi +% \!!heighta\!!deptha +% \ifx\mmllinetext\empty +% \ifx\mmllinelength\empty +% \!!widtha\zeropoint +% \else +% \!!widtha\mmllinelength +% \fi +% \else +% \setbox\scratchbox\hbox{\mathematics{\mathstyle{\mmllinetext}}}% not ok +% \!!widtha\wd\scratchbox +% \fi +% \hbox{\vrule\s!width\!!widtha\s!depth\!!deptha\s!height\!!heighta} +% \stopxmlsetups + +\startxmlsetups mml:mglyph % probably never ok (hbox is needed in order to switch to normal font) + \begingroup + \edef\mmlglyphfontfamily{\xmlatt {#1}{fontfamily}} + \edef\mmlglyphalt {\xmlattdef{#1}{alt}{unknown}} + \edef\mmlglyphindex {\xmlatt {#1}{index}} + \ifx \mmlglyphfontfamily \empty + \hbox{\tttf[no fontfamily specified for \mmlglyphalt]} + \else\ifx\mmlglyphindex\empty + \hbox{\tttf[no index specified for \mmlglyphalt]} + \else + \hbox{\getglyph\mmlglyphfontfamily\mmlglyphindex} + \fi\fi + \endgroup +\stopxmlsetups + +\startxmlsetups mml:maligngroup \stopxmlsetups % will be done when needed +\startxmlsetups mml:malignmark \stopxmlsetups % will be done when needed + +\startxmlsetups mml:none \stopxmlsetups +\startxmlsetups mml:mprescripts \stopxmlsetups + +\startxmlsetups mml:mmultiscripts + \ctxmodulemathml{mmultiscripts("#1")} +\stopxmlsetups + +% goodie + +\definebuffer[mml] + +\def\stopmml{\xmlprocessbuffer{@mml@}{\thedefinedbuffer{mml}}{}} + +\stopmodule + +\protect \endinput + +% TODO: +% +% <apply><divide/> +% <apply><minus/> +% <apply><minus/><ci>b</ci></apply> +% <apply><minus/><ci>b</ci></apply> +% <apply><root/> <ci>a</ci></apply> +% </apply> +% <apply><minus/> +% <apply><minus/><ci>b</ci><ci>b</ci></apply> +% <apply><minus/><ci>b</ci></apply> +% <apply><root/> <ci>a</ci></apply> +% </apply> +% </apply> + +% \startmoduletestsection +% +% \def\xflushXMLstackwith#1#2#3#4% num bgroup egroup whatever +% {\dostepwiserecurse{#1}\XMLstacklevel\plusone +% {#2\relax +% \ifnum\recurselevel>#1\relax#4\fi +% \getXMLstackdata\recurselevel +% #3}} +% +% \def\xflushXMLstackfrom#1#2#3% +% {\dostepwiserecurse{#1}\XMLstacklevel\plusone +% {#2\getXMLstackdata\recurselevel#3}} +% +% \startxmlsetups mml:minus +% \doif \MMLsignreduction \v!yes { +% \setMMLcreset{fn,\MMLcfunctionlist} +% } +% \ifcase\XMLstacklevel +% \or +% % self +% \or +% -\getXMLstackdata\plustwo +% \else +% \dostepwiserecurse \plustwo \XMLstacklevel \plusone { +% \begingroup +% \doifelse {\getXMLstackname\recurselevel} {apply} { +% \ifnum\recurselevel=\plustwo +% \begingroup +% \dodoifelseMMCfunctioninapply \recurselevel {minus} { +% \ifnum\XMLstacklevel>\plustwo +% \endgroup +% \else +% \endgroup +% \MMLcreset +% \fi +% } { +% \endgroup +% } +% \else +% \doifelseMMCfunctioninapply \recurselevel {\MMLcfunctionlist,\MMLcconstructlist} { +% \MMLcreset +% } { +% } +% \fi +% } { +% } +% \getXMLstackdata\recurselevel +% \ifnum\recurselevel<\XMLstacklevel\relax +% - +% \fi +% \endgroup +% } +% \fi +% \stopxmlsetups +% +% \stopmoduletestsection diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-newmml.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-newmml.mkiv new file mode 100644 index 00000000000..4c12daeeeb3 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-newmml.mkiv @@ -0,0 +1,16 @@ +%D \module +%D [ file=x-newmml, +%D version=2008.05.28, +%D title=\CONTEXT\ XML Modules, +%D subtitle=MathML Renderer, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\input x-mathml.mkiv + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-pfs-01.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-pfs-01.mkiv new file mode 100644 index 00000000000..8b06bd873ff --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-pfs-01.mkiv @@ -0,0 +1,399 @@ +% pfsense status info, work in progress +% +% usage: +% +% context --environment=x-pfs-01 filename.xml +% +% or +% +% <?context-directive job ctxfile x-pfsense.ctx ?> + +\setupbodyfont + [dejavu,10pt] + +\setuplayout + [topspace=1cm, + backspace=1cm, + footer=0pt, + header=1cm, + width=middle, + height=middle] + +\setupheader + [style=bold] + +\setuphead + [section] + [style=\bfb] + +\setuphead + [subsection] + [style=\bfa] + +\setuppagenumbering + [location=] + +\dontcomplain + +% todo: show all values and map keys onto longer names via labels + +\startxmlsetups xml:system + + \startsection[title={System}] + + \startsubsection[title={Properties}] + + \starttabulate[|B|T|] + \NC hostname \NC \xmlfirst{#1}{hostname} \NC \NR + \NC domain \NC \xmlfirst{#1}{domain} \NC \NR + \NC timezone \NC \xmlfirst{#1}{timezone} \NC \NR + \NC timeservers \NC \xmlfirst{#1}{timeservers} \NC \NR + \NC dnsserver \NC \xmlfirst{#1}{dnsserver} \NC \NR + \stoptabulate + + \stopsubsection + + \startsubsection[title={Groups}] + \xmlfilter{#1}{group/command(xml:system:group)} + \stopsubsection + + \startsubsection[title={Users}] + \xmlfilter{#1}{user/command(xml:system:user)} + \stopsubsection + + \stopsection + +\stopxmlsetups + +\startxmlsetups xml:system:group + + \starttabulate[|B|T|] + \NC name \NC \xmlfirst{#1}{/name} \NC \NR + \NC description \NC \xmlfirst{#1}{/descr} \NC \NR + \NC scope \NC \xmlfirst{#1}{/scope} \NC \NR + \NC gid \NC \xmlfirst{#1}{/gid} \NC \NR + \NC privilege \NC \xmlfirst{#1}{/priv} \NC \NR + \NC members \NC \xmlconcat{#1}{/member}{ } \NC \NR + \stoptabulate + +\stopxmlsetups + +\startxmlsetups xml:system:user + + \starttabulate[|B|T|] + \NC name \NC \xmlfirst{#1}{/name} \NC \NR + \NC description \NC \xmlfirst{#1}{/descr} \NC \NR + \NC scope \NC \xmlfirst{#1}{/scope} \NC \NR + \NC uid \NC \xmlfirst{#1}{/uid} \NC \NR + \NC group \NC \xmlfirst{#1}{/groupname} \NC \NR + \NC privilege \NC \xmlfirst{#1}{/priv} \NC \NR + \NC password \NC \xmldoifelsetext{#1}{/password}{set}{unset} \NC \NR + \NC ipsec psk \NC \xmldoifelsetext{#1}{/ipsecpsk}{set}{unset} \NC \NR + \NC certificate \NC \xmldoifelsetext{#1}{/cert} {set}{unset} \NC \NR + \stoptabulate + +\stopxmlsetups + +\startxmlsetups xml:interfaces + + \startsection[title={Interfaces}] + + \xmlfilter{#1}{*/command(xml:interfaces:network)} + + \stopsection + +\stopxmlsetups + +\startxmlsetups xml:interfaces:network + + \startsubsection[title={\xmltag{#1}}] + + % <blockpriv/> <blockbogons/> <spoofmac/> <enable/> + + \starttabulate[|B|T|] + \NC interface \NC \xmlfirst{#1}{/if} \NC \NR + \NC block private \NC \xmldoifelse{#1}{/blockpriv} {yes}{no} \NC \NR + \NC block bogons \NC \xmldoifelse{#1}{/blockbogons}{yes}{no} \NC \NR + \NC spoof mac address \NC \xmldoifelse{#1}{/spoofmac} {yes}{no} \NC \NR + \NC enable interface \NC \xmldoifelse{#1}{/enable} {yes}{no} \NC \NR + \NC ipaddress \NC \xmlfirst{#1}{/ipaddr} \NC \NR + \NC subnet \NC \xmlfirst{#1}{/subnet} \NC \NR + \NC gateway \NC \xmlfirst{#1}{/gateway} \NC \NR + \NC description \NC \xmlfirst{#1}{/descr} \NC \NR + \stoptabulate + + \stopsubsection + +\stopxmlsetups + +\startxmlsetups xml:gateways + + \startsection[title={Gateways}] + + \xmlfilter{#1}{*/command(xml:gateways:entry)} + + \stopsection + +\stopxmlsetups + +\startxmlsetups xml:gateways:entry + + \starttabulate[|B|T|] + \NC interface \NC \xmlfirst{#1}{/interface} \NC \NR + \NC gateway \NC \xmlfirst{#1}{/gateway} \NC \NR + \NC name \NC \xmlfirst{#1}{/name} \NC \NR + \NC weight \NC \xmlfirst{#1}{/weight} \NC \NR + \NC interval \NC \xmlfirst{#1}{/interval} \NC \NR + \NC description \NC \xmlfirst{#1}{/descr} \NC \NR + \NC disable monitor \NC \xmlfirst{#1}{/monitor_disable} \NC \NR + \NC default gateway \NC \xmlfirst{#1}{/defaultgw} \NC \NR + \stoptabulate + +\stopxmlsetups + +\startxmlsetups xml:virtualips + + \startsection[title={Virtual ipadresses}] + + \xmlfilter{#1}{*/command(xml:virtualips:entry)} + + \stopsection + +\stopxmlsetups + +\startxmlsetups xml:virtualips:entry + + \starttabulate[|B|T|] + \NC interface \NC \xmlfirst{#1}{/interface} \NC \NR + \NC type \NC \xmlfirst{#1}{/type} \NC \NR + \NC mode \NC \xmlfirst{#1}{/mode} \NC \NR + \NC subnet \NC \xmlfirst{#1}{/subnet} + /\xmlfirst{#1}{/subnet_bits} \NC \NR + \NC description \NC \xmlfirst{#1}{/descr} \NC \NR + \stoptabulate + +\stopxmlsetups + +\startxmlsetups xml:dhcp + + \startsection[title={DHCP}] + + \xmlfilter{#1}{*/command(xml:dhcp:network)} + + \stopsection + +\stopxmlsetups + +\startxmlsetups xml:dhcp:network + + \startsubsection[title={\xmltag{#1}}] + + \starttabulate[|B|T|] + \NC range \NC \xmlfirst{#1}{/range/from} \endash\ \xmlfirst{#1}{/range/to} \NC \NR + \NC domain \NC \xmlfirst{#1}{/domain} \NC \NR + \NC dnsserver \NC \xmlfirst{#1}{/dnsserver} \NC \NR + \NC gateway \NC \xmlfirst{#1}{/gateway} \NC \NR + \NC ddnsdomain \NC \xmlfirst{#1}{/ddnsdomain} \NC \NR + \stoptabulate + + \xmldoif {#1} {/staticmap} { + + \starttabulate[|T|T|T|p|] + \NC \rm\bf macaddress + \NC \rm\bf ipaddress + \NC \rm\bf hostname + \NC \rm\bf description + \NC \NR + \HL + \xmlfilter{#1}{/staticmap/command(xml:dhcp:network:entry)} + \stoptabulate + + } + + \stopsubsection + +\stopxmlsetups + +\startxmlsetups xml:dhcp:network:entry + + \NC \xmlfirst{#1}{/mac} + \NC \xmlfirst{#1}{/ipaddr} + \NC \xmlfirst{#1}{/hostname} + \NC \xmlfirst{#1}{/descr} + \NC \NR + +\stopxmlsetups + +\startxmlsetups xml:dnsmasq + + \startsection[title={DNS MASQ}] + + \starttabulate[|T|T|T|p|] + \NC \rm\bf host + \NC \rm\bf domain + \NC \rm\bf ipaddress + \NC \rm\bf description + \NC \NR + \HL + \xmlfilter{#1}{/hosts/command(xml:dnsmasq:hosts)} + \stoptabulate + + \stopsection + +\stopxmlsetups + + +\startxmlsetups xml:dnsmasq:hosts + + \NC \xmlfirst{#1}{/host} + \NC \xmlfirst{#1}{/domain} + \NC \xmlfirst{#1}{/ip} + \NC \xmlfirst{#1}{/descr} + \NC \NR + +\stopxmlsetups + +\startxmlsetups xml:nat + + \startsection[title={NAT}] + + \startsubsection[title={Rules}] + + \starttabulate[|T|T|T|T|T|p|] + \NC \rm\bf interface + \NC \rm\bf protocol + \NC \rm\bf source + \NC \rm\bf destination + \NC \rm\bf target + \NC \rm\bf description + \NC \NR + \HL + \xmlfilter{#1}{/rule/command(xml:nat:rule)} + \stoptabulate + + \stopsubsection + + \startsubsection[title={One to one}] + + \starttabulate[|T|T|T|T|T|p|] + \NC \rm\bf interface + \NC \rm\bf protocol + \NC \rm\bf source + \NC \rm\bf destination + \NC \rm\bf external + \NC \rm\bf description + \NC \NR + \HL + \xmlfilter{#1}{/onetoone/command(xml:nat:onetoone)} + \stoptabulate + + \stopsubsection + +\stopsection + +\stopxmlsetups + +\startxmlsetups xml:nat:rule + + \NC \xmlfilter{#1}{/interface/command(xml:checked)} + \NC \xmlfilter{#1}{/protocol/command(xml:checked)} + \NC \xmlfilter{#1}{/source/command(xml:checked)} + \NC \xmlfilter{#1}{/destination/(address|any)/command(xml:checked)} + :\xmlfilter{#1}{/destination/port/command(xml:checked)} + \NC \xmlfilter{#1}{/target/command(xml:checked)} + :\xmlfilter{#1}{/local-port/command(xml:checked)} + \NC \xmlfirst {#1}{/descr} + \NC \NR + +\stopxmlsetups + +\startxmlsetups xml:nat:onetoone + + \NC \xmlfilter{#1}{/interface/command(xml:checked)} + \NC \xmlfilter{#1}{/protocol/command(xml:checked)} + \NC \xmlfilter{#1}{/source/command(xml:checked)} + \NC \xmlfilter{#1}{/destination/(address|any)/command(xml:checked)} + :\xmlfilter{#1}{/destination/port/command(xml:checked)} + \NC \xmlfilter{#1}{/external/command(xml:checked)} + :\xmlfilter{#1}{/local-port/command(xml:checked)} + \NC \xmlfirst {#1}{/descr} + \NC \NR + +\stopxmlsetups + +\startxmlsetups xml:checked + \xmldoifelse {#1} {/any} { + * + } { + \xmldoifelsetext {#1} {.} { + \xmlflush{#1} + } { + * + } + } +\stopxmlsetups + +\startxmlsetups xml:filter + + \startsection[title={Filter}] + + \startsubsection[title={Rules}] + + \starttabulate[|T|T|T|T|T|p|] + \NC \rm\bf type + \NC \rm\bf interface + \NC \rm\bf protocol + \NC \rm\bf source + \NC \rm\bf destination + \NC \rm\bf description + \NC \NR + \HL + \xmlfilter{#1}{/rule/command(xml:filter:rule)} + \stoptabulate + + \stopsubsection + + \stopsubsection + +\stopxmlsetups + +\startxmlsetups xml:filter:rule + + \NC \xmlfilter{#1}{/type/command(xml:checked)} + \NC \xmlfilter{#1}{/interface/command(xml:checked)} + \NC \xmlfilter{#1}{/protocol/command(xml:checked)} + \NC \xmlfilter{#1}{/source/(address|any)/command(xml:checked)}: + :\xmlfilter{#1}{/source/port/command(xml:checked)} + \NC \xmlfilter{#1}{/destination/(address|any)/command(xml:checked)} + :\xmlfilter{#1}{/destination/port/command(xml:checked)} + \NC \xmlfirst {#1}{/descr} + \NC \NR + +\stopxmlsetups + +\starttext + + \doifelse {\inputfilename} {x-pfs-01.mkiv} { + + \xmlloadonly{main}{router.xml}{} + + \setupheadertexts[router.xml][\pagenumber] + + } { + + \xmlloadonly{main}{\inputfilename}{} + + \setupheadertexts[\inputfilename][\pagenumber] + + } + + \xmlfilter{main}{/pfsense/system/command(xml:system)} + \xmlfilter{main}{/pfsense/interfaces/command(xml:interfaces)} + \xmlfilter{main}{/pfsense/gateways/command(xml:gateways)} + \xmlfilter{main}{/pfsense/virtualip/command(xml:virtualips)} + \xmlfilter{main}{/pfsense/dhcpd/command(xml:dhcp)} + \xmlfilter{main}{/pfsense/dnsmasq/command(xml:dnsmasq)} + \xmlfilter{main}{/pfsense/nat/command(xml:nat)} + \xmlfilter{main}{/pfsense/filter/command(xml:filter)} + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-pfsense.ctx b/Master/texmf-dist/tex/context/modules/mkiv/x-pfsense.ctx new file mode 100644 index 00000000000..8d7087cf222 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-pfsense.ctx @@ -0,0 +1,15 @@ +<?xml version='1.0' standalone='yes'?> + +<!-- this is also a demo of using the xml interface --> + +<ctx:job> + <ctx:message>pfsense configuration listing</ctx:message> + <ctx:process> + <ctx:flags> + <ctx:flag>purge</ctx:flag> + </ctx:flags> + <ctx:resources> + <ctx:environment>x-pfs-01.mkiv</ctx:environment> + </ctx:resources> + </ctx:process> +</ctx:job> diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-physml.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-physml.mkiv new file mode 100644 index 00000000000..dd9a164dd19 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-physml.mkiv @@ -0,0 +1,16 @@ +%D \module +%D [ file=m-physml, +%D version=2001.09.04, +%D title=\CONTEXT\ XML Modules, +%D subtitle=Loading PHYSML Filters, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-res-01.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-res-01.mkiv new file mode 100644 index 00000000000..36070c61599 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-res-01.mkiv @@ -0,0 +1,427 @@ +%D \module +%D [ file=x-fig-01, +%D version=2001.03.21, +%D title=\CONTEXT\ Style File, +%D subtitle=Figure Base Generation, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D See \type {x-fig-00.tex} and \type {x-fig-04.tex} for more +%D information on how to use and generate figure databases. +%D This file loads the file named \type {\jobfilename} +%D (\TEXEXEC\ will set this variable). You can apply this +%D style to a database by saying: +%D +%D \starttyping +%D context --input=d-res-01.xml auto:x-res-01.mkiv +%D \stoptyping +%D +%D The following modes are supported (not all yet in mkiv): +%D +%D \starttabulate[|lT|l|] +%D \NC letter \NC map the preview on letter size \NC \NR +%D \NC compact \NC use an alternative presentation \NC \NR +%D \NC clipgrid-distance \NC add a copy with grid overlayed \NC \NR +%D \NC clipgrid-steps \NC add a copy with grid overlayed \NC \NR +%D \NC previewpage-A4 \NC show graphic relative to A4 \NC \NR +%D \NC previewpage-letter \NC show graphic relative to letter \NC \NR +%D \NC previewpage-S6 \NC show graphic relative to S6 \NC \NR +%D \stoptabulate +%D +%D The resulting file has the following characteristics: +%D +%D \startitemize[packed] +%D \startitem the document is split into three sections: first each +%D figure is shown at its own page, then an overview of figures is +%D shown with some data alongside, and finally an index and table of +%D contents shows up \stopitem +%D \startitem there is no title page, which means that one can access +%D a figure by page number without offset \stopitem +%D \startitem the document is opened at the first overview page, that +%D is, when the viewer supports it \stopitem +%D \startitem the graphic is shown 3~times: on a page of its own, +%D scaled to a fixed dimension, and relative to a4 or letter paper +%D size \stopitem +%D \startitem the labels can be accessed in an index and list at the +%D end of the document \stopitem +%D \stopitemize + +\defineregister + [figureindex] + +\setupregister + [figureindex] + [criterium=text, + interaction=text, + pagenumber=no, + indicator=no] + +\setuptolerance + [verytolerant] + +\setupbuttons + [offset=10pt, + width=broad, + strut=no, + rulethickness=1pt, + framecolor=darkred] + +\setuplayout + [topspace=15pt, + backspace=15pt, + header=0pt, + footer=0pt, + bottom=20pt, + bottomdistance=10pt, + width=middle, + height=fit] + +\setupbackgrounds + [page] + [background=, + backgroundcolor=gray] + +\setupinteractionscreen + [width=max, + height=max] + +\setupinteraction + [style=, + color=, + contrastcolor=, + state=start] + +\setuphead + [section] + [style=bfb] + +\setupinteractionmenu + [bottom] + [left=\hfill, + middle=\hskip10pt, + frame=off, + style=bold, + background=color, + backgroundcolor=darkred, + foregroundcolor=white] + +\startinteractionmenu[bottom] + \but [begin] begin \\ + \but [index] index \\ + \but [list] list \\ + \but [CloseDocument] close \\ + \but [PreviousJump] go back \\ +\stopinteractionmenu + +\setupinteraction + [openaction=begin] + +\setuppapersize + [S6][S6] + +\setupbackgrounds + [page] + [background=color] + +\setupinteraction + [menu=on] + +\setupbodyfont + [tt,10pt] + +\definesymbol [attachment] [{\strut\bf\color[darkred]{\inputfilename}}] % jobname.xml}}] +\setupattachments [symbol=attachment,alternative=,location=text] +\useattachment [datafile] [\inputfilename] + +\xmlloadonly{main}{\inputfilename}{} + +\mainlanguage[\xmlattributedef{main}{/rlx:library}{language}{en}] + +\startxmlsetups xml:resource:asis + \startTEXpage[pagestate=start] + \xmldoifelsetext{#1}{/rlx:label} { + \edef\CurrentLabel{\xmltext{#1}{rlx:label}} + } { + \edef\CurrentLabel{\xmltext{#1}{rlx:file}} + } + \pagereference [ + asis:\CurrentLabel + ] + \gotobox { + \externalfigure[\xmltext{#1}{/rlx:file}] + }[% tricky no space before [ + data:\CurrentLabel + ] + \stopTEXpage +\stopxmlsetups + +\definemeasure[figure:width] [210mm] +\definemeasure[figure:height][297mm] + +\startmode[letter] + \enablemode[previewpage-letter] +\stopmode + +\startmode[previewpage-A4] + \definemeasure[figure:width] [210mm] + \definemeasure[figure:height][297mm] +\stopmode + +\startmode[previewpage-letter] + \definemeasure[figure:width] [8.5in] + \definemeasure[figure:height][11in] +\stopmode + +\startmode[previewpage-S6] + \definemeasure[figure:width] [600pt] + \definemeasure[figure:height][450pt] +\stopmode + +\startxmlsetups xml:resource:a + \button + [ + width=150pt, + height=100pt, + offset=10pt, + frame=off, + background=color, + backgroundcolor=white, + color= + ] + { + \externalfigure + [\xmltext{#1}{rlx:file}] + [factor=max] + } + [ + grid:\CurrentLabel + ] +\stopxmlsetups + +\startxmlsetups xml:resource:b + \framed + [ + width=150pt, + height=100pt, + offset=10pt, + frame=off, + background=color, + backgroundcolor=white, + color= + ] + { + \externalfigure [ + \xmltext{#1}{rlx:file} + ] [ + factor=max + ] + } +\stopxmlsetups + +\startxmlsetups xml:resource:data + + % using a layer makes more sense but we had this ... + + \xmldoifelsetext{#1}{/rlx:label} { + \edef\CurrentLabel{\xmltext{#1}{rlx:label}} + } { + \edef\CurrentLabel{\xmltext{#1}{rlx:file}} + } + + \button { + \hbox to \hsize { + \forgetall + \dontcomplain + \pagereference[data:\CurrentLabel] + + %\ifnum\CurrentPage=1 \pagereference[begin]\fi + + \expanded{\figureindex{\xmltext{#1}{/rlx:label}}} + + \vbox to 100pt { + \hsize30pt + \vskip5pt + \hbox to \hsize { + \hss + \strut + \bf + \at[asis:\CurrentLabel] + \hss + } + \vfill + } + \advance\hsize by -30pt + \doifelsemode {clipgrid-distance,clipgrid-steps} { + \xmlsetup{#1}{xml:resource:a} + } { + \xmlsetup{#1}{xml:resource:b} + } + \edef\CurrentWidth {\the\dimexpr\figurenaturalwidth} + \edef\CurrentHeight{\the\dimexpr\figurenaturalheight} + \advance\hsize by -150pt + \hskip10pt + \advance\hsize by -10pt + \vbox to 100pt { + \hsize40pt + \framed [ + offset=overlay, + framecolor=darkred, + rulethickness=.5pt + ] { + \scale [ + width=40pt + ] { + \framed [ + width=\measure{figure:width}, + height=\measure{figure:height}, + offset=overlay, + frame=off, + background=color, + backgroundcolor=white + ] { + \externalfigure + [ + \xmltext{#1}{rlx:file} + ] [ + reset=yes + ] + } + } + } + \vfill + } + \advance\hsize by -40pt + \hskip10pt + \advance\hsize by -10pt + \vbox to 100pt { + \blank[disable] + \starttabulate[|Bel|p|] + \NC file \NC \xmltext{#1}{/rlx:file} \NC \NR + \xmldoif{#1}{/rlx:label} {\NC label \NC \xmltext{#1}{/rlx:label} \NC \NR} + \NC dimensions \NC \CurrentWidth\ * \CurrentHeight \NC \NR + \xmldoif{#1}{/rlx:copyright} {\NC copyright \NC \xmltext{#1}{/rlx:copyright} \NC \NR} + \xmldoif{#1}{/rlx:status} {\NC status \NC \xmltext{#1}{/rlx:status} \NC \NR} + \xmldoif{#1}{/rlx:comment} {\NC comment \NC \xmltext{#1}{/rlx:comment} \NC \NR} + \stoptabulate + \vfill + } + } + } [ + asis:\CurrentLabel + ] + + \vskip10pt + +\stopxmlsetups + +\startxmlsetups xml:description + + \starttabulate[|lBe|p|] + \xmldoif{#1}{/rlx:organization} {\NC organization \NC \xmltext{#1}{/rlx:organization} \NC \NR} + \xmldoif{#1}{/rlx:project} {\NC project \NC \xmltext{#1}{/rlx:project} \NC \NR} + \xmldoif{#1}{/rlx:product} {\NC product \NC \xmltext{#1}{/rlx:product} \NC \NR} + \xmldoif{#1}{/rlx:comment} {\NC comment \NC \xmltext{#1}{/rlx:comment} \NC \NR} + \NC specification \NC \attachment[datafile] \NC \NR + \stoptabulate + +\stopxmlsetups + +\starttext + + \xmlfilter{main}{/rlx:library/rlx:resource/command(xml:resource:asis)} + + \subject {Figure collection} + + \xmlfilter{main}{/rlx:library/rlx:description/command(xml:description)} + + \subject [list] {List of figures} + + \xmlfilter{main}{/rlx:library/rlx:resource/command(xml:resource:data)} + + \page + + \subject [index] {Index of figures} + + \startcolumns + \placeregister[figureindex] + \stopcolumns + +\stoptext + +% \doifmodeelse{clipgrid-distance,clipgrid-steps}{\page}{\stoptext} + +% \startuniqueMPgraphic{clipgrid}{dx,dy,nx,ny,type} +% numeric gdx, gdy, lbx, lby ; +% if \MPvar{type}=1 : +% gdx := \MPvar{dy} ; +% gdy := \MPvar{dx} ; +% else : +% gdx := OverlayWidth /\MPvar{nx} ; +% gdy := OverlayHeight/\MPvar{ny} ; +% fi ; +% lbx := gdx ; +% lby := gdy ; +% defaultfont := "\truefontname{Mono}" ; +% defaultscale := .5 ; +% numeric pen ; pen := .25pt ; +% def MyGrid text t = +% draw vlingrid (0,OverlayWidth ,gdy,OverlayWidth ,OverlayHeight) t ; +% draw hlingrid (0,OverlayHeight,gdx,OverlayHeight,OverlayWidth ) t ; +% enddef ; +% pickup pencircle scaled pen ; +% MyGrid withcolor white ; +% MyGrid dashed evenly scaled pen ; +% draw OverlayBox withcolor white ; +% draw OverlayBox dashed evenly scaled pen ; +% draw vlinlabel.bot(0,eps+OverlayWidth /lby,2,OverlayWidth ) ; +% draw hlinlabel.lft(0,eps+OverlayHeight/lbx,2,OverlayHeight) ; +% setbounds currentpicture to OverlayBox enlarged (2*EmWidth) ; +% \stopuniqueMPgraphic + +% \presetMPvariable[clipgrid][dx=10pt] +% \presetMPvariable[clipgrid][dy=10pt] +% \presetMPvariable[clipgrid][nx=10] +% \presetMPvariable[clipgrid][ny=10] + +% \startmode[clipgrid-distance] +% \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=1}] +% \stopmode + +% \startmode[clipgrid-steps] +% \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=2}] +% \stopmode + +% \setupexternalfigures +% [background={color,foreground,grid}, +% backgroundcolor=white] + +% \def\StartFigureD +% {\StartFigureA} + +% \def\StopFigureD +% {\doglobal\increment\CurrentPage +% \setupbackgrounds[page][background=page] +% \startpagefigure[\XMLflush{rlx:file}][offset=20pt]% +% \doifelsenothing{\XMLflush{rlx:label}} +% {\expanded{\definereference[Description][about:\XMLflush{rlx:file}]}% +% \expanded{\pagereference[grid:\XMLflush{rlx:file}]}} +% {\expanded{\definereference[Description][about:\XMLflush{rlx:label}]}% +% \expanded{\pagereference[grid:\XMLflush{rlx:label}]}} +% \stoppagefigure +% %\pagefigure[\XMLflush{rlx:file}][offset=20pt] +% \setupbackgrounds[page][background=] +% \egroup} + +% \defineXMLignore [rlx:description] +% \defineXMLenvironment [rlx:figure] \StartFigureD \StopFigureD + +% \doglobal\newcounter\CurrentPage + +% \processXMLfilegrouped{\jobfullname} \page + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-res-50.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-res-50.mkiv new file mode 100644 index 00000000000..62a86b7a744 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-res-50.mkiv @@ -0,0 +1,431 @@ +%D \module +%D [ file=x-res-50, +%D version=2004.02.18, +%D title=\CONTEXT\ Style File, +%D subtitle=Multimedia Presentation, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The xml mapping has to be redone! + +\endinput + +%D This is a preliminary module, using a preliminary xml media format that +%D looks as follows (record is embedded in resource library element): +%D +%D \starttyping +%D <rl:mediaclip label="sample 1"> +%D <rl:name>Sample One</rl:name> +%D <rl:mime>application/x-shockwave-flash</rl:mime> +%D <rl:file>http://localhost/mb.swf</rl:file> +%D <rl:width>8cm</rl:width> +%D <rl:height>6cm</rl:height> +%D <rl:text>Nothing special to be said.</rl:text> +%D <rl:picture>cow.pdf</rl:picture> +%D </rl:mediaclip> +%D +%D <rl:mediaclip label="sample 2"> +%D <rl:name>Sample Two</rl:name> +%D <rl:mime>audio/mpeg</rl:mime> +%D <rl:file>mb.mp3</rl:file> +%D <rl:picture>mb.jpg</rl:picture> +%D </rl:mediaclip> +%D \stoptyping +%D +%D \starttyping +%D texexec --pdf --use=med-show yourfile.xml +%D \stoptyping +%D +%D Bonus: +%D +%D \starttyping +%D --arg="url=http://localhost:8881/e:/media" +%D \stoptyping + +% output=pdftex + +% \nopdfcompression + +% bugs in recognizing embedded stream cq. player +% bugs in layers + hide/vide +% bugs in save javascripts +% bugs all over the place + +% in principe kan menu overal hetzelfde zijn als we via JS per pagina de clip var zetten, +% hoewel, misschien zal het menu gaan afhangen van de soort clip + +% viewerlayer (eigenschap) aan framed en layer + +\usemodule[meta-dum] \usemodule[contml] \autoXMLnamespace [context] + +\doifelsevariable{environment}{url} + {\setvariables[mediaclip][url=\getvariable{environment}{url}/]} + {\setvariables[mediaclip][url=]} + +\startmode [silent] + + \setvariables[mediaclip:option][start=] + +\stopmode + +\startnotmode [silent] + + \setvariables[mediaclip:option][start=auto] + +\stopnotmode + +\chardef\XMLtokensreduction=1 \dontcomplain % \showframe \pdfcompresslevel=0 + +\setuppapersize + [S6][S6] + +\definemeasure [GapSize] [\dimexpr( 15pt)] +\definemeasure [EdgeWidth] [\dimexpr(100pt)] +\definemeasure [TextWidth] [\dimexpr(.5\textwidth)] +\definemeasure [RenderingWidth] [\dimexpr(\textwidth)] +\definemeasure [RenderingHeight] [\dimexpr(\textheight)] + +% \XMLflush{rl:ratio}\dimexpr(.75\textwidth), + +\setuplayout + [backspace=\measure{GapSize}, + topspace=\measure{GapSize}, + header=0pt, + footer=0pt, + margin=0pt, + edgedistance=2\measure{GapSize}, + rightedge=\measure{EdgeWidth}, + bottomdistance=2\measure{GapSize}, + bottom=2\measure{GapSize}, + height=fit, + width=fit] + +\setupinteraction + [state=start, + color=lightgray, + contrastcolor=lightgray, + openaction=PresetFields, + closeaction=ForgetChanges, + menu=on, + click=no] + +\setupinteractionscreen + [option=max] + +\setupcolors + [state=start] + +\usetypescript + [palatino][texnansi] + +\setupbodyfont + [palatino] + +\definecolor[darkgray] [s=.2] +\definecolor[mediumgray][s=.5] +\definecolor[lightgray] [s=.8] +\definecolor[transgray] [s=1,t=.9,a=1] + +\setupbackgrounds + [page] + [backgroundoffset=\measure{GapSize}, + background={color,pagebutton}, + backgroundcolor=black] + +\definelayer + [main] + [width=\textwidth, + height=\textheight] + +\definelayer + [extra] + [width=\rightedgewidth, + height=\bottomheight] + +\setupbackgrounds + [text] + [backgroundoffset=0pt, + background=main] + +\setupbackgrounds + [bottom][rightedge] + [backgroundoffset=0pt, + background=extra] + +% java scripts + +\startJSpreamble {handy} used now + + function ForgetChanges () + { this.dirty = false } + + function PresetFields () + { this.syncAnnotScan() } + +\stopJSpreamble + +\definereference[PresetFields] [JS(PresetFields)] +\definereference[ForgetChanges][JS(ForgetChanges)] + +% layers + +\defineviewerlayer [menulayer] [title=menulayer] +\defineviewerlayer [textlayer] [title=textlayer,state=stop] +\defineviewerlayer [datalayer] [title=datalayer,state=stop] + +\setupfield + [rollbutton] + [fieldlayer=menulayer] + +\setupfield + [rollbutton] + [option=auto] + +\definepalet + [rollover] + [n=darkgray, + r=lightgray, + d=darkgray] + +% list + +\definelist + [clips] + [expansion=yes, + criterium=text, + alternative=f] + +% navigation + +\defineoverlay[pagebutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer},ToggleLayer{menulayer}}] +\defineoverlay[textbutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer}}] +\defineoverlay[databutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer}}] + +% clips + +\defineXMLenvironment + [rl:mediaclip] + {\setups[mediaclip:start]} + {\setups[mediaclip:stop]} + +\newcounter\MediaClip + +\startsetups[mediaclip:start] + + \bgroup \startXMLignore + + % no \startstandardmakeup here since we need the dsta in the menuconstruction + + \defineXMLsave [rl:name] + \defineXMLsave [rl:visualization] + \defineXMLsave [rl:file] + \defineXMLsave [rl:mime] + \defineXMLsave [rl:picture] [backgroundcolor=lightgray] + + \defineXMLsavecontent [rl:text] {No additional info.} + \defineXMLsavecontent [rl:width] {\measure{RenderingWidth}} + \defineXMLsavecontent [rl:height] {\measure{RenderingHeight}} + \defineXMLsavecontent [rl:aspect] {1} + +\stopsetups + +\startsetups[mediaclip:stop] + + \startstandardmakeup + + \doifXMLdataelse{rl:file} + {\setups[mediaclip:file:yes]} + {} + + \doifXMLdataelse{rl:picture} + {\doifelse{\XMLflush{rl:picture}}{self} + {\setups[mediaclip:picture:self]} + {\setups[mediaclip:picture:yes]}} + {\setups[mediaclip:picture:no]} + + \doifXMLdata{rl:text} + {\setups[mediaclip:text]} + + \setlayerframed + [extra] + [preset=rightbottom] + [frame=off,offset=overlay,width=fit,background=databutton,align=left] + {\startviewerlayer[datalayer]\setups[mediaclip:data]\stopviewerlayer} + + \doifXMLdataelse{rl:name} + {\writetolist[clips]{}{\XMLflush{rl:name}}} + {\writetolist[clips]{}{\XMLpar{rl:mediaclip}{label}{unknown}}} + + \stopstandardmakeup + + \stopXMLignore \egroup + +\stopsetups + +\setuptabulate + [before=, + after=] + +\def\rlCleanupFileName#1% + {\bgroup + \def\cleanup##1##2{\ifnum##1##2=20 \space\else\char\octnumber{##1##2}\fi}% + \defineactivecharacter 37 {\cleanup}% + \scantokens{#1}% + \egroup} + +\startsetups[mediaclip:data] + + \noindent \buttonframed + [framecolor=lightgray, + foregroundcolor=lightgray] + {\bf\expanded{\rlCleanupFileName{\XMLflush{rl:file}}}} + + \vskip.75\measure{GapSize} + + \noindent \buttonframed + [framecolor=lightgray, + foregroundcolor=lightgray] + {\bf\XMLflush{rl:mime}} + +\stopsetups + +\startsetups[mediaclip:picture:self] + + \definerenderingwindow + [mediaclip] + [width=\XMLflush{rl:width}, + height=\XMLflush{rl:height}, + frame=off, + openpageaction=StartCurrentRendering, + closepageaction=StopCurrentRendering] + + \setlayer + [main] + {\placerenderingwindow[mediaclip][mediaclip-\MediaClip]} + +\stopsetups + +\startsetups[mediaclip:picture:yes] + + \setlayer + [main] + {\externalfigure + [\XMLflush{rl:picture}] + [background=color, + backgroundcolor=\XMLpar{rl:picture}{backgroundcolor}{lightgray}, + factor=max, + width=\XMLflush{rl:width}, + height=\XMLflush{rl:height}]} + +\stopsetups + +\startsetups[mediaclip:picture:no] + + \setlayer + [main] + {\externalfigure + [dummy] + [width=\XMLflush{rl:width}, + height=\XMLflush{rl:height}]} + +\stopsetups + +\startsetups[mediaclip:file:yes] + + \doglobal\increment\MediaClip + + \useexternalrendering + [mediaclip-\MediaClip] + [\XMLflush{rl:mime}] + [\getvariable{mediaclip}{url}\XMLflush{rl:file}] + [\getvariable{mediaclip:option}{start}] + +\stopsetups + +\defineinteractionmenu + [navigation] [right] + +\defineinteractionmenu + [control] [bottom] + +\setupinteractionmenu + [navigation,control] + [state=start, + frame=on, + middle=\hskip.5\measure{GapSize}, + inbetween=\vskip.5\measure{GapSize}] + +\setupinteractionmenu + [right,bottom] + [distance=overlay] + +\startinteractionmenu [navigation] + \rob [HideLayer{textlayer},FirstPage] First Page \\ + \rob [HideLayer{textlayer},PreviousPage] Previous Page \\ + \rob [HideLayer{textlayer},NextPage] Next Page \\ + \rob [HideLayer{textlayer},LastPage] Last Page \\ + \rob [HideLayer{textlayer},clips] List Of Clips \\ + \rob [ForgetChanges,CloseDocument] Close Document \\ +\stopinteractionmenu + +\startinteractionmenu [control] + \rob [StartRendering{mediaclip-\MediaClip}] Start \\ + \rob [StopRendering{mediaclip-\MediaClip}] Stop \\ + \rob [PauseRendering{mediaclip-\MediaClip}] Pause \\ + \rob [ResumeRendering{mediaclip-\MediaClip}] Resume \\ + \rob [ToggleLayer{datalayer}] Info \\ + \doifXMLdata{rl:text}{\rob [HideLayer{datalayer},ToggleLayer{textlayer}] Text \\} +\stopinteractionmenu + +\startsetups[mediaclip:text] + + \setlayer + [extra] + [preset=rightbottom] + {\startviewerlayer[textlayer] + \framed + [align=normal, + frame=off, + width=\measure{TextWidth}, + foregroundcolor=darkgray, + background={color,textbutton}, + backgroundcolor=lightgray] + {\XMLflush{rl:text}} + \stopviewerlayer} + +\stopsetups + +\setupcolors[textcolor=lightgray] + +\startsetups [library:start] + + \starttext + + \setupinteractionmenu[control][state=stop] + + \title[clips]{List of Media Clips} + + \placelist[clips] \page + + \setupinteractionmenu[control][state=start] + +\stopsetups + +\startsetups [library:stop] + + \stoptext + +\stopsetups + +\defineXMLenvironment [rl:resourcelibrary] + {\setups[library:start]} + {\setups[library:stop]} + +\doifelsenothing{\inputfilename} + {\processXMLfile{mediaclient.xml}} + {\processXMLfile{\inputfilename}} diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-setups-basics.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-basics.mkiv new file mode 100644 index 00000000000..39547591cd7 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-basics.mkiv @@ -0,0 +1,876 @@ +%D \module +%D [ file=setups-basics, % x-set-11, +%D version=2016.04.05, % 2004.10.31, +%D remark=setupx.tex: 1998.07.20 and later, +%D title=\CONTEXT\ Setup Definitions, +%D subtitle=Macro Definitions, +%D author={Hans Hagen & Wolfgang Schuster}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D We can make this module a bit cleaner using more recent features or we go \LUA\ +%D completely but as this style evolved over 15 years it's a waste of time. +%D +%D As we also have a help server we can make a common framework for this \unknown\ +%D but even then, this file is also a test for the the \XML\ processor. +%D +%D Traditionally we used the sorter to generate the lists while nowadays we can +%D as well use the \XML\ mechanisms directly. We cannot change too much because +%D manuals depend on it. +%D +%D Currently we load the \XML\ file and when not in the english interface we just +%D remap the relevant words to their translation. + +\unprotect + +\defineregister + [texmacro] + +\definesorting + [texcommand] + +\setupsorting + [texcommand] + [\c!command=\showsetupinlist, + \c!criterium=\setupparameter\c!criterium] + +\pushmacro\setuptext + +\defineframedtext + [setuptext] + [\c!width=\hsize, + \c!height=\v!fit, + \c!align=\v!right, + \c!offset=0.75\emwidth] + +\popmacro\setuptext + +\installcorenamespace{interfacesetup} + +\installsetuponlycommandhandler \??interfacesetup {setup} % \??interfacesetup + +\setupsetup + [\c!before=, + \c!after=, + \c!command=\setup, + \c!criterium=\v!used] + +%D General: + +\unexpanded\def\setupnumfont {} +\unexpanded\def\setuptxtfont {} +\unexpanded\def\setupintfont {\WORD} +\unexpanded\def\setupvarfont {\sl} +\unexpanded\def\setupoptfont {\sl} +\unexpanded\def\setupalwcolor{} +\unexpanded\def\setupoptcolor{darkgray} + +\unexpanded\def\setupvarword#1{{\sl\detokenize{#1}}} +\unexpanded\def\setupintword#1{\WORD{\detokenize{#1}}} +\unexpanded\def\setuptxtword#1{\detokenize{#1}} + +\unexpanded\def\cmd_internal_value#1% + {\dontleavehmode + \begingroup + \setupintfont{#1}% + \endgroup} + +\unexpanded\def\cmd_text_value#1% + {\dontleavehmode + \begingroup + \setupvarfont{#1}% + \endgroup} + +\unexpanded\def\cmd_command_value#1% + {\begingroup + \setupvarfont{#1}% + \endgroup} + +%D Loading: + +\let\currentSETUPfullname\s!unknown + +\startxmlsetups xml:setups:assemblename + \doifelse {\xmlatt{#1}{type}} {environment} { + \doifsomethingelse {\xmlatt{#1}{begin}} { + \edef\currentSETUPprefix{\xmllastatt}% + } { + \let\currentSETUPprefix\e!start + } + } { + \let\currentSETUPprefix\empty + } + \edef\currentSETUPname{\xmlatt{#1}{name}} + \let\currentSETUPgenerated\empty + \doifelsenothing {\xmlatt{#1}{variant}} { + \let\currentSETUPvariant\empty + } { + \def\currentSETUPvariant{:\xmllastatt} + } + \edef\currentSETUPfullname { + \currentSETUPprefix + \currentSETUPname + \currentSETUPvariant + \currentSETUPgenerated + } +\stopxmlsetups + +\startxmlsetups xml:setups:register + \xmlsetup{#1}{xml:setups:assemblename} + % not really needed if we just use setups + \expanded{\texcommand[stp:x:\currentSETUPfullname]{#1}} +\stopxmlsetups + +\startluacode + + local find, gsub = string.find, string.gsub + + local context = context + + local setupvarword = context.formatted.setupvarword + local setupintword = context.formatted.setupintword + local setuptxtword = context.formatted.setuptxtword + + local getsetupstring = interfaces.getsetupstring + + -- normally a lookup is fast enough but here we can have many setups + -- spread over many files so we do a little speedup here + + local setups = moduledata.setups or { } + moduledata.setups = setups + local definitions = { } + setups.definitions = definitions + + function xml.functions.setups_define(id) + local x = lxml.getid(id) + for c in xml.collected(x,"cd:interface/cd:define") do + definitions[c.at.name] = c + end + + for c in xml.collected(x,"cd:interface/cd:interface") do + c.at.file = c.__f__ + c.at["xmlns:cd"] = nil + -- c.dt[#c.dt+1] = " " + end + + local interface = interfaces.currentinterface or "en" + + if interface ~= "en" then + + local constants = interfaces.complete.constants + local variables = interfaces.complete.variables + local commands = interfaces.complete.commands + local elements = interfaces.complete.elements + + local function replace(pattern,attribute,one,two) + for e in xml.collected(x,pattern) do + local t = e.at[attribute] + if t then + local c = one[t] or (two and two[t]) + if c then + local v = c[interface] + if v then + e.at[attribute] = v + end + end + end + end + end + + replace('cd:command', 'name', commands, elements) + replace('cd:string', 'value', commands, elements) + replace('cd:variable' , 'value', variables) + + replace('cd:parameter', 'name', constants) + replace('cd:constant', 'type', variables) + replace('cd:constant', 'default', variables) + replace('cd:variable', 'type', variables) + replace('cd:inherit', 'name', commands, elements) + + end + + if tex.modes["setups:save"] and environment.currentrun == 1 then + local s = tostring(x) + s = gsub(s,"\n*%s*(</cd:interface>)%s+(<cd:interface)", "\n\n %1\n\n %2") + s = gsub(s,"\n*%s*(</cd:interface>)%s+(</cd:interface>)","\n\n %1\n\n %2") + io.savedata("context-"..interface..".xml",s) + end + + end + + function moduledata.setups.resolved(name) + lxml.flush(definitions[name]) + end + + function xml.finalizers.s_count(collected) + local n = 0 + for i=1,#collected do + local c = collected[i] + local tg = c.tg + if tg == "resolve" then + local d = definitions[c.at.name] + n = n + xml.count(d,"/*") + elseif tg == "delimiter" then + -- skip + else + n = n + 1 + end + end + context(n) + end + + interfaces.implement { + name = "getsetupstring", + actions = function(s) + local g = getsetupstring(s) + if not find(s,"^cd:") then + setuptxtword(g) + elseif find(s,"%-.$") then + setupvarword(g) + else + setupintword(g) -- cap + end + end, + overload = true, + arguments = "string", + } + +\stopluacode + +% <?xml version="1.0" encoding="UTF-8"?> +% +% <cd:interface xmlns:cd="http://www.pragma-ade.com/commands"> +% +% <cd:interfacefile filename="i-document.xml"/> +% <cd:interfacefile filename="i-file.xml"/> +% +% </cd:interface> + +\startxmlsetups xml:setups:interfacefile + \loadsetups[\xmlatt{#1}{filename}] +\stopxmlsetups + +\startxmlsetups xml:setups:basics + \xmlincludeoptions{#1}{interfacefile|include}{filename}{recurse,basename} + \xmlsetsetup{#1}{*}{xml:setups:*} + \xmlfunction{#1}{setups_define} +\stopxmlsetups + +\xmlregisterdocumentsetup{setups}{xml:setups:basics} + +\let\loadedsetups\empty % we load more setups, setups:<name> + +\unexpanded\def\loadsetups + {\dosingleempty\cmd_load_setups} + +\def\cmd_load_setups[#1]% + {\edef\m_cmd_asked_setups{#1}% + \doifnotmode{no-setup-main}{\def\m_cmd_asked_setups{i-context.xml}}% + \ifx\m_cmd_asked_setups\empty \else + \doonlyonce{setups:#1} + {\doglobal\prependtocommalist{setups:#1}\loadedsetups + \doiffileexistselse{#1} + {\xmlloadonly{setups:#1}{#1}{setups}}% + {\xmlloadonly{setups:#1}{#1.xml}{setups}}% + % qualified path saves > 50% runtime + \xmlfilter{setups:#1}{/interface//command/command(xml:setups:register)}}% + \fi} + +\newconstant \c_cmd_kind +\newconditional\c_cmd_doing_line +\newconditional\c_cmd_measuring +\newconditional\c_cmd_show_setup +\newcount \c_cmd_current_argument +\newcount \c_cmd_maximum_argument +\newdimen \d_cmd_current_width +\let \m_cmd_current_hash \empty +\let \m_cmd_current_file \empty + +\unexpanded\def\basicsetup{\c_cmd_kind\zerocount\cmd_show_setup} +\unexpanded\def\shortsetup{\c_cmd_kind\plusone \cmd_show_setup} +\unexpanded\def\setup {\c_cmd_kind\plustwo \cmd_show_setup} +\unexpanded\def\showsetup {\c_cmd_kind\plustwo \cmd_show_setup} + +\unexpanded\def\showsetupinlist#1#2#3% + {\c_cmd_kind\plustwo\xmlsetup{#3}{xml:setups:typeset}\par} + +\installtextracker + {cmd.showsetup} + {\settrue\c_cmd_show_setup} + {\setfalse\c_cmd_show_setup} + +\unexpanded\def\cmd_show_setup + {\doifelsenextoptionalcs\cmd_show_setup_yes\cmd_show_setup_nop} + +\def\cmd_show_setup_yes[#1]% + {\iffirstargument + \cmd_show_setup_nop{#1}% + \else + \expandafter\cmd_show_setup_nop + \fi} + +\def\cmd_show_setup_nop#1% this will trigger 'used' + {\registersort[texcommand][stp:x:#1]% + \ifconditional\c_cmd_show_setup + \writestatus{setup}{#1 / \rawsynonymname{texcommand}{stp:x:#1}}% + \fi + \startelement[setup][name=#1]% + \startelement[noexport][comment={setup definition #1}]% + \xmlsetup{\rawsynonymname{texcommand}{stp:x:#1}}{xml:setups:typeset} + \stopelement + \stopelement} + +\unexpanded\def\placesetup {\placelistofsorts[texcommand][\c!criterium=\v!used]} +\unexpanded\def\placeallsetups{\placelistofsorts[texcommand][\c!criterium=\v!all ]} + +% todo: grouped + +\let\placeeverysetup\placeallsetups + +%D Typesetting: + +\startxmlsetups xml:setups:typeset + \doifelsenothing {#1} { + \xmlsetup{#1}{xml:setups:typeset:nop} + } { + \xmlsetup{#1}{xml:setups:typeset:yes} + } +\stopxmlsetups + +\startxmlsetups xml:setups:typeset:nop + \blank + \type {MISSING SETUP} + \blank +\stopxmlsetups + +\startxmlsetups xml:setups:make:string + \xmlatt{#1}{value} +\stopxmlsetups + +\startxmlsetups xml:setups:make:variable + \xmlatt{#1}{value} +\stopxmlsetups + +\let\m_cmd_current_hash\empty +\let\m_cmd_current_file\empty +\let\m_cmd_font \empty +\let\m_cmd_name \empty +\let\m_cmd_start \empty +\let\m_cmd_stop \empty + +\startxmlsetups xml:setups:make:prepare + \edef\m_cmd_current_hash{\xmlatt{#1}{hash}} + \xdef\m_cmd_current_file{\xmlatt{#1}{file}}% + \xmldoifelseempty{#1}{/sequence} { + \edef\m_cmd_name{\xmlatt{#1}{name}} + } { + \edef\m_cmd_name{\xmlfilter{#1}{/sequence/(string|variable)/command(xml:setups:make:*)}} + } + \doifelse {\xmlatt{#1}{type}} {environment} { + \doifsomethingelse {\xmlatt{#1}{begin}} { + \edef\m_cmd_start{\xmllastatt} + } { + \let\m_cmd_start\e!start + } + \doifsomethingelse {\xmlatt{#1}{end}} { + \edef\m_cmd_stop{\xmllastatt} + } { + \let\m_cmd_stop\e!stop + } + } { + \let\m_cmd_start\empty + \let\m_cmd_stop \empty + } + \doifelse {\xmlatt{#1}{generated}} {yes} { + \let\m_cmd_font\ttsl + } { + \let\m_cmd_font\relax + } +\stopxmlsetups + +\startsetups xml:setups:make:start + \bgroup + \settrue\c_cmd_doing_line + \m_cmd_font + \letterbackslash + \m_cmd_start + \m_cmd_name + \ignorespaces + \egroup +\stopsetups + +\startsetups xml:setups:make:stop + \ifx\m_cmd_stop\empty \else + \bgroup + \settrue\c_cmd_doing_line + \hskip.5em\unknown\hskip.5em + \m_cmd_font + \letterbackslash + \m_cmd_stop + \m_cmd_name + \ignorespaces + \egroup + \fi +\stopsetups + +\startxmlsetups xml:setups:typeset:line + \ttbf + \nohyphens + \xmlsetup{#1}{xml:setups:make:prepare} + \directsetup{xml:setups:make:start} + \xmldoif{#1}{/arguments} { + \bgroup + \settrue\c_cmd_doing_line + \global\c_cmd_current_argument\zerocount + \ignorespaces + \xmlfilter{#1}{/arguments/text()} + \egroup + } + \directsetup{xml:setups:make:stop} +\stopxmlsetups + +\startxmlsetups xml:setups:typeset:raw + \tttf + \nohyphens + \veryraggedright + \global\c_cmd_current_argument\zerocount + \global\c_cmd_maximum_argument\xmlfilter{#1}{/arguments/*/s_count()}\relax + \xmlsetup{#1}{xml:setups:make:prepare} + \directsetup{xml:setups:make:start} + \xmldoif{#1}{/arguments} { + \settrue\c_cmd_doing_line + \bgroup + \global\c_cmd_current_argument\zerocount + \ignorespaces + \xmlfilter{#1}{/arguments/text()} + \egroup + } + \directsetup{xml:setups:make:stop} +\stopxmlsetups + +\startxmlsetups xml:setups:typeset:detail + \xmldoif{#1}{/arguments} { + \bgroup + \setfalse\c_cmd_doing_line + \global\c_cmd_current_argument\zerocount + %\blank[\v!line] % packed mode (we could do \startunpacked ...) + \godown[.75\lineheight] + \switchtobodyfont[\v!small] + \ignorespaces\xmlfilter{#1}{/arguments/text()}\endgraf + \egroup + } +\stopxmlsetups + +\startxmlsetups xml:setups:typeset:yes + \glet\m_cmd_current_file\empty + \ifcase\c_cmd_kind + \xmlsetup{#1}{xml:setups:typeset:line} + \or + \getvalue{\e!start setuptext} + \xmlsetup{#1}{xml:setups:typeset:raw} + \getvalue{\e!stop setuptext} + \or + \getvalue{\e!start setuptext} + \xmlsetup{#1}{xml:setups:typeset:raw} + \endgraf + \xmlsetup{#1}{xml:setups:typeset:detail} + \getvalue{\e!stop setuptext} + \fi + \glet\m_cmd_current_file\empty +\stopxmlsetups + +\startsetups xml:setups:overlay:file + \vbox to \overlayheight \bgroup + \infofont + \vfill + \scratchdimen.5\exheight + \hbox to \overlaywidth \bgroup + \strut + \hss + \m_cmd_current_file + \hskip\dimexpr\scratchdimen+\strutdp\relax + \egroup + \vskip\scratchdimen + \egroup +\stopsetups + +\defineoverlay + [setupfilename] + [\directsetup{xml:setups:overlay:file}] + +\startxmlsetups xml:setups:resolve + \ignorespaces + \ctxlua{moduledata.setups.resolved('\xmlatt{#1}{name}')} +\stopxmlsetups + +%D This is the first pass; here we generate the top line. + +\startxmlsetups xml:setups:define + \ignorespaces\xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:setups:sequence + \ignorespaces\xmlflush{#1} +\stopxmlsetups + +\startxmlsetups xml:setups:string + \xmlatt{#1}{value}\ignorespaces +\stopxmlsetups + +\startxmlsetups xml:setups:delimiter + \ifconditional\c_cmd_doing_line + \kern.5\emwidth + \letterbackslash\xmlatt{#1}{name} + \fi + \ignorespaces +\stopxmlsetups + +\startxmlsetups xml:setups:content \showSETUPcomponent{#1}{content} \stopxmlsetups +\startxmlsetups xml:setups:displaymath \showSETUPcomponent{#1}{displaymath}\stopxmlsetups +\startxmlsetups xml:setups:index \showSETUPcomponent{#1}{index} \stopxmlsetups +\startxmlsetups xml:setups:math \showSETUPcomponent{#1}{math} \stopxmlsetups +\startxmlsetups xml:setups:nothing \showSETUPcomponent{#1}{nothing} \stopxmlsetups +\startxmlsetups xml:setups:file \showSETUPcomponent{#1}{file} \stopxmlsetups +\startxmlsetups xml:setups:position \showSETUPcomponent{#1}{position} \stopxmlsetups +\startxmlsetups xml:setups:reference \showSETUPcomponent{#1}{reference} \stopxmlsetups +\startxmlsetups xml:setups:csname \showSETUPcomponent{#1}{csname} \stopxmlsetups +\startxmlsetups xml:setups:destination \showSETUPcomponent{#1}{destination}\stopxmlsetups +\startxmlsetups xml:setups:triplet \showSETUPcomponent{#1}{triplet} \stopxmlsetups +\startxmlsetups xml:setups:word \showSETUPcomponent{#1}{word} \stopxmlsetups +\startxmlsetups xml:setups:template \showSETUPcomponent{#1}{template} \stopxmlsetups +\startxmlsetups xml:setups:angles \showSETUPcomponent{#1}{angles} \stopxmlsetups +\startxmlsetups xml:setups:apply \showSETUPcomponent{#1}{apply} \stopxmlsetups +\startxmlsetups xml:setups:twowords \showSETUPcomponent{#1}{twowords} \stopxmlsetups +\startxmlsetups xml:setups:threewords \showSETUPcomponent{#1}{threewords} \stopxmlsetups +\startxmlsetups xml:setups:text \showSETUPcomponent{#1}{text} \stopxmlsetups + +% todo: cd:par => \par +% todo: cd:sep => \\ + +\unexpanded\def\showSETUPcomponent#1#2% + {\ifconditional\c_cmd_doing_line + \getvalue{showSETUP#2}{#1}% + \else + \simpleSETUPargument{#2}% + \fi} + +%D This is the second pass; here we generate the table. + +\unexpanded\def\startfirstSETUPcolumn#1% + {\bgroup + \scratchdimen2\emwidth + \advance\leftskip \scratchdimen + \noindent\llap{\hbox to \scratchdimen{#1\hss}}} + +\unexpanded\def\stopfirstSETUPcolumn + {\endgraf + \egroup} + +\unexpanded\def\startsecondSETUPcolumn#1#2% + {\bgroup + \scratchdimen2.5\emwidth + \advance\hangindent\dimexpr\d_cmd_current_width+\scratchdimen\relax + \noindent \hbox to \hangindent{#1\hss\hbox to \scratchdimen{\hss#2\hss}}} + +\unexpanded\def\stopsecondSETUPcolumn + {\endgraf + \egroup} + +\unexpanded\def\secondSETUPcolumn#1#2% + {\startsecondSETUPcolumn{#1}{#2}\stopsecondSETUPcolumn} + +\startxmlsetups xml:setups:assignments + \ifconditional\c_cmd_doing_line + \ifcase\c_cmd_kind + \expandafter\showSETUPline + \else + \expandafter\showSETUP + \fi{#1}{assignment\xmlattdef{#1}{delimiters}{brackets}} + \else + \global\d_cmd_current_width\zeropoint + \setbox\scratchbox\vbox\bgroup + \settrue\c_cmd_measuring + \xmlall{#1}{/(parameter|resolve)} + \egroup + \global\d_cmd_current_width\themaxboxwidth\scratchbox\relax + \startfirstSETUPcolumn{\showSETUPnumber}% + \ignorespaces + \xmldoifelse {#1} {/(parameter|inherit|resolve)} { + \xmlflush{#1} + } { + \unknown + } + \stopfirstSETUPcolumn + \blank[\v!halfline] + \ignorespaces + \fi +\stopxmlsetups + +\startxmlsetups xml:setups:keywords + \ifconditional\c_cmd_doing_line + \ifcase\c_cmd_kind + \expandafter\showSETUPline + \else + \expandafter\showSETUP + \fi{#1}{\xmlattdef{#1}{delimiters}{brackets}} + \else + \startfirstSETUPcolumn{\showSETUPnumber}% + \ignorespaces + \xmlflush{#1} + \stopfirstSETUPcolumn + \blank[\v!halfline] + \ignorespaces + \fi +\stopxmlsetups + +\startxmlsetups xml:setups:parameter + \ifconditional\c_cmd_measuring + \getsetupstring{\xmlatt{#1}{name}}\par + \else + \startsecondSETUPcolumn{\getsetupstring{\xmlatt{#1}{name}}}{=} + \ignorespaces + \xmlflush{#1} + \doifmode{interface:setup:defaults} { + \ifx\m_cmd_current_hash\empty \else + \begingroup + % todo, make a one level expansion of parameter + \let\emwidth \relax + \let\exheight\relax + \edef\temp{\csname named\m_cmd_current_hash parameter\endcsname\empty{\xmlatt{#1}{name}}} + \ifx\temp\empty \else + =\space + \detokenize\expandafter{\temp} + \fi + \endgroup + \fi + } + \stopsecondSETUPcolumn + \fi + \ignorespaces +\stopxmlsetups + +%xmlmapvalue{setups:method}{class} {:} +\xmlmapvalue{setups:method}{range} {:} +\xmlmapvalue{setups:method}{apply} {->} +\xmlmapvalue{setups:method}{factor}{*} +\xmlmapvalue{setups:method}{none} {} + +\startxmlsetups xml:setups:constant:value + \getsetupstring{\xmlatt{#1}{type}} +\stopxmlsetups + +\startxmlsetups xml:setups:constant + \doifelsemode {setups-pass-one} { + } { + \doifsomethingelse{\xmlatt{#1}{prefix}} { + \getsetupstring{\xmllastatt} + \xmlmappedvalue{setups:method}{\xmlatt{#1}{method}}{none} + } { + \doif {\xmlatt{#1}{default}} {yes} { + \underbar % next needs to be {braced} + } + } + {\getsetupstring{\xmlatt{#1}{type}}} + \space + \ignorespaces + } +\stopxmlsetups + +\startxmlsetups xml:setups:variable + \doifelsemode {setups-pass-one} { + \expanded{\setupintfont{\xmlatt{#1}{value}}}\ignorespaces + } { + \getsetupstring{\xmlatt{#1}{value}} + \space + \ignorespaces + } +\stopxmlsetups + +\startxmlsetups xml:setups:inherit + \secondSETUPcolumn { + \cmd_text_value{\getsetupstring{cd:inherits}} + \enspace + \letterbackslash + \xmlatt{#1}{name} + } {} + \ignorespaces +\stopxmlsetups + +\unexpanded\def\simpleSETUPargument#1% + {\startfirstSETUPcolumn{\showSETUPnumber}% + \cmd_internal_value{#1}% + \stopfirstSETUPcolumn + \blank[\v!halfline] + \ignorespaces} + +%D Auxiliary. + +\unexpanded\def\showSETUP#1#2% + {\bgroup + \global\advance\c_cmd_current_argument\plusone + \setbox0=\hbox + {\doifelse{\xmlatt{#1}{list}}{yes} + {\getsetupstring{cd:#2-l}}% + {\getsetupstring{cd:#2-s}}}% + \setbox2=\hbox to \wd0 + {\hss + \raise1.25\exheight\hbox + {\txx\ifcase\c_cmd_maximum_argument \relax + \or*\else\the\c_cmd_current_argument + \fi}% + \hss}% + \setbox4=\hbox to \wd0 + {\hss + \lower2\exheight\hbox + \bgroup + \txx + \doif {\xmlatt{#1}{optional}} {yes} + {\getsetupstring{cd:optional}}% + \egroup + \hss}% + \ht2\ht\strutbox + \dp4\dp\strutbox + \hskip.5\emwidth + \wd0\zeropoint + \box0 + \wd2\zeropoint + \box2 + \box4% + \egroup + \ignorespaces} + +\unexpanded\def\showSETUPline#1#2% + {\kern.5\emwidth + \getsetupstring{cd:#2-s}% + \ignorespaces} + +\unexpanded\def\showSETUPnumber + {\global\advance\c_cmd_current_argument\plusone + \hbox to 2\emwidth + {\ifcase\c_cmd_maximum_argument \relax + \or*\else\the\c_cmd_current_argument + \fi + \hss}} + +% todo: replace = by lower + +\unexpanded\def\setupEQsymbol % we raise the number already + {.\lower.25\exheight\hpack{=}.} + +\unexpanded\def\setupAPPLYsymbol % we raise the number already + {..\lower.25\exheight\hpack{=>}..} + +% arguments + +\unexpanded\def\showSETUPdisplaymath#1{\showSETUP {#1}{displaymath}} +\unexpanded\def\showSETUPindex #1{\showSETUP {#1}{index}} +\unexpanded\def\showSETUPmath #1{\showSETUP {#1}{math}} +\unexpanded\def\showSETUPnothing #1{\showSETUP {#1}{nothing}} +\unexpanded\def\showSETUPfile #1{\showSETUP {#1}{file}} +\unexpanded\def\showSETUPposition #1{\showSETUP {#1}{position}} +\unexpanded\def\showSETUPtemplate #1{\showSETUP {#1}{template}} +\unexpanded\def\showSETUPangles #1{\showSETUP {#1}{angle}} +\unexpanded\def\showSETUPreference #1{\showSETUP {#1}{reference}} +\unexpanded\def\showSETUPapply #1{\showSETUP {#1}{apply}} +\unexpanded\def\showSETUPtwowords #1{\showSETUP {#1}{twowords}} +\unexpanded\def\showSETUPthreewords #1{\showSETUP {#1}{threewords}} +\unexpanded\def\showSETUPcsname #1{\showSETUP {#1}{noargument}} +\unexpanded\def\showSETUPdestination#1{\showSETUP {#1}{destination}} +\unexpanded\def\showSETUPtriplet #1{\showSETUP {#1}{triplet}} +\unexpanded\def\showSETUPword #1{\showSETUP {#1}{word}} +\unexpanded\def\showSETUPcontent #1{\showSETUP {#1}{content}} +\unexpanded\def\showSETUPtext #1{\showSETUP {#1}{textual}} +\unexpanded\def\showSETUPto #1{\showSETUPline{#1}{to}} +\unexpanded\def\showSETUPmacro #1{\showSETUP {#1}{macro}} + +% A prelude to a rewrite and some more: + +% \definetype[parametercommand][\v!type] +% \definetype[parameterkey] [\v!type] +% \definetype[parametervalue] [\v!type][\c!space=\v!on] + +% todo: no list but hash .. + +\definetype[parametercommand] +\definetype[parameterkey] +\definetype[parametervalue] [\c!space=\v!on] + +\setuptype [parametercommand] [\c!color=darkmagenta] +\setuptype [parametervalue] [\c!color=darkyellow] + +\startxmlsetups xml:setups:parameters:value + \edef\currentsetupparameterkey {\xmlatt{#1}{name}} + \edef\currentsetupparametervalue{\begincsname named\currentsetupparametercategory parameter\endcsname\currentsetupparameterinstance\currentsetupparameterkey} + \ifx\currentsetupparameterinstance\empty + \expanded { + \NC \parameterkey {\currentsetupparameterkey} + \NC \parametervalue{\detokenize\expandafter{\currentsetupparametervalue}} + \NC \NR + } + \else\ifx\currentsetupparametervalue\empty + \else + \edef\currentsetupparameterdefault{\begincsname named\currentsetupparametercategory parameter\endcsname\empty\currentsetupparameterkey} + \ifx\currentsetupparametervalue\currentsetupparameterdefault + % skip + \else + \expanded { + \NC \parameterkey {\currentsetupparameterkey} + \NC \parametervalue{\detokenize\expandafter{\currentsetupparametervalue}} + \NC \NR + } + \fi + \fi\fi +\stopxmlsetups + +\startxmlsetups xml:setups:parameters:values + \blank[big] + \expanded { + \parametercommand { + \currentsetupparametercommand + \space:\space + \ifx\currentsetupparameterinstance\empty + defaults + \else + \currentsetupparameterinstance + \fi + } + } + \blank[big,samepage] + \starttabulate[|l|p|] + \xmlall + {#1} + {/interface/command[@name=='\currentsetupparametercommand' or @handler=='\currentsetupparametercommand']/arguments/assignments/parameter/command(xml:setups:parameters:value)} + \ifnum\noftabulaterows = \zerocount + \NC \parameterkey{no specific settings} \NC \NC \NR + \fi + \stoptabulate +\stopxmlsetups + +\starttexdefinition showrootvalues [#1] + \edef\currentsetupparametercategory{#1} + \edef\currentsetupparametercommand{setup#1} + \let\currentsetupparameterinstance\empty + \xmlsetup{\loadedsetups}{xml:setups:parameters:values} +\stoptexdefinition + +\starttexdefinition showinstancevalues [#1]#2[#3] + \edef\currentsetupparametercategory{#1} + \edef\currentsetupparametercommand{setup#1} + \edef\currentsetupparameterinstance{#3} + \xmlsetup{\loadedsetups}{xml:setups:parameters:values} +\stoptexdefinition + +% official interface + +\unexpanded\def\cmdinternal#1% + {{\tttf\getsetupstring{#1}}} % todo color .. highlight + +\let\cmdbasicsetup\basicsetup +\let\cmdshortsetup\shortsetup +\let\cmdfullsetup \showsetup + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-setups-generate.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-generate.mkiv new file mode 100644 index 00000000000..f64489e8d63 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-generate.mkiv @@ -0,0 +1,18 @@ +%D \module +%D [ file=setups-generate, +%D version=2016.04.05, +%D title=\CONTEXT\ Setup Definitions, +%D subtitle=Macro Definitions, +%D author={Hans Hagen & Wolfgang Schuster}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\enablemode[setups:save] + +\input x-setups-overview.mkiv + +\endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-setups-overview.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-overview.mkiv new file mode 100644 index 00000000000..35ded7a8600 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-overview.mkiv @@ -0,0 +1,259 @@ +%D \module +%D [ file=setups-basics, % x-set-12, +%D version=2016.04.05, % 2004.10.31, +%D remark=setupx.tex: 1998.07.20 and later, +%D title=\CONTEXT\ Setup Definitions, +%D subtitle=Macro Definitions, +%D author={Hans Hagen & Wolfgang Schuster}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\usemodule[setups-basics] + +\unprotect + +\definecolor[TitleColor][r=.375,g=.125,b=.125] +\definecolor[TitleColor][r=.125,g=.375,b=.125] +\definecolor[TitleColor][r=.125,g=.125,b=.375] +\definecolor[TitleColor][r=.375,g=.375,b=.125] +\definecolor[TitleColor][r=.375,g=.125,b=.375] +\definecolor[TitleColor][r=.125,g=.375,b=.375] + +\definecolor[TitleColor][r=.25,g=.20,b=.15] +\definecolor[TitleColor][r=.25,g=.15,b=.20] +\definecolor[TitleColor][r=.20,g=.15,b=.25] +\definecolor[TitleColor][r=.20,g=.25,b=.15] +\definecolor[TitleColor][r=.15,g=.20,b=.25] +\definecolor[TitleColor][r=.15,g=.25,b=.20] + +\doifelsemode {setups:traditional} { + + \startinterface english \loadsetups[cont-en.xml] \stopinterface + \startinterface dutch \loadsetups[cont-nl.xml] \stopinterface + \startinterface german \loadsetups[cont-de.xml] \stopinterface + \startinterface french \loadsetups[cont-fr.xml] \stopinterface + \startinterface italian \loadsetups[cont-it.xml] \stopinterface + \startinterface czech \loadsetups[cont-cs.xml] \stopinterface + \startinterface romanian \loadsetups[cont-ro.xml] \stopinterface + +} { + + \loadsetups[i-context.xml] + +} + +\startinterface dutch \definecolor[LocalColor][r=.75,g=.25,b=.25] \stopinterface +\startinterface english \definecolor[LocalColor][r=.25,g=.75,b=.25] \stopinterface +\startinterface german \definecolor[LocalColor][r=.25,g=.25,b=.75] \stopinterface +\startinterface french \definecolor[LocalColor][r=.75,g=.75,b=.25] \stopinterface +\startinterface czech \definecolor[LocalColor][r=.75,g=.25,b=.75] \stopinterface +\startinterface italian \definecolor[LocalColor][r=.25,g=.75,b=.75] \stopinterface +\startinterface romanian \definecolor[LocalColor][r=.5,g=.4,b=.3] \stopinterface +% \definecolor[LocalColor][r=.5,g=.3,b=.4] +% \definecolor[LocalColor][r=.4,g=.3,b=.5] +% \definecolor[LocalColor][r=.4,g=.5,b=.3] +% \definecolor[LocalColor][r=.3,g=.4,b=.5] +% \definecolor[LocalColor][r=.3,g=.5,b=.4] + +\startinterface english \definecolor[TitleColor][r=.375,g=.125,b=.125] \stopinterface +\startinterface dutch \definecolor[TitleColor][r=.125,g=.375,b=.125] \stopinterface +\startinterface german \definecolor[TitleColor][r=.125,g=.125,b=.375] \stopinterface +\startinterface french \definecolor[TitleColor][r=.375,g=.375,b=.125] \stopinterface +\startinterface italian \definecolor[TitleColor][r=.375,g=.125,b=.375] \stopinterface +\startinterface czech \definecolor[TitleColor][r=.125,g=.375,b=.375] \stopinterface +\startinterface romanian \definecolor[TitleColor][r=.25,g=.20,b=.15] \stopinterface +% \definecolor[TitleColor][r=.25,g=.15,b=.20] +% \definecolor[TitleColor][r=.20,g=.15,b=.25] +% \definecolor[TitleColor][r=.20,g=.25,b=.15] +% \definecolor[TitleColor][r=.15,g=.20,b=.25] +% \definecolor[TitleColor][r=.15,g=.25,b=.20] + +\definecolor [lightgray] [s=.9] +\definecolor [darkgray] [s=.1] + +\usetypescript[palatino] +\setupbodyfont[palatino,9pt] + +\defineoverlay + [cover] + [\hbox to \paperwidth{\hss\reuseMPgraphic{cover+back}}] + +\defineoverlay + [back] + [\hbox to \paperwidth{\reuseMPgraphic{cover+back}\hss}] + +\startreusableMPgraphic{cover+back} + numeric h, w ; path p, q, r ; color f, d ; pair s ; + h := OverlayHeight ; w := 2*OverlayWidth ; + r := unitsquare xyscaled (w,h) ; + fill r withcolor \MPcolor{lightgray} ; + set_grid(w,h,w/8,w/16) ; + forever : + s := center r randomized (w,h) ; + if new_on_grid(xpart s, ypart s) : + s := (dx,dy) ; + p := fullsquare xyscaled(w/4,w/8) ; + q := (-4w,ypart ulcorner p) -- .5[ulcorner p, urcorner p] -- (4w,ypart urcorner p) ; + q := q shifted (0,-w/24) ; + p := p randomized (w/40,w/40) ; + q := q randomized (0,w/100) ; + q := q cutafter (p cutafter point 3 of p) ; + q := q cutbefore (p cutbefore point 3 of p) ; + d := .5[\MPcolor{LocalColor},\MPcolor{lightgray}] randomized (.5,.9) ; + f := \MPcolor{lightgray} randomized (.5,.9) ; + pickup pencircle scaled (w/100) ; + fill p shifted s withcolor f ; + draw p shifted s withcolor d ; + draw q shifted s withcolor d ; + fi ; + exitif grid_full ; + endfor ; + setbounds currentpicture to r ; +\stopreusableMPgraphic + +\definelayout + [titlepage] + [\c!backspace=1cm, + \c!topspace=1cm, + \c!width=\v!middle, + \c!height=\v!middle, + \c!header=0pt, + \c!footer=0pt] + +\setuplayout + [\c!backspace=2cm, + \c!topspace=1.5cm, + \c!header=0cm, + \c!footer=0cm, + \c!width=\v!middle, + \c!height=\v!middle] + +\setuppagenumbering + [\c!alternative=\v!doublesided] + +\setupsetup + [\c!criterium=\v!all] + +\setupframedtexts + [setuptext] + [\c!before=\blank, + \c!after=\blank, + \c!frame=\v!on, + \c!rulethickness=1pt, + \c!framecolor=TitleColor] + +\setupunderbar + [\c!rulethickness=1pt, + \c!rulecolor=TitleColor] + +\dontcomplain + +\starttext + +\setupbackgrounds + [\v!rightpage] + [\c!background=cover] + +\setuplayout + [titlepage] + +\startsetups text:commands + \startinterface dutch \strut commando's \par \stopinterface + \startinterface english \strut commands \par \stopinterface + \startinterface german \strut befehle \par \stopinterface + \startinterface french \strut commandes \par \stopinterface + \startinterface czech \strut p\v{r}ikazy \par \stopinterface + \startinterface italian \strut comandi \par \stopinterface + \startinterface romanian \strut comenzile \par \stopinterface +\stopsetups + +\startsetups text:uppercase + \startinterface dutch NL\stopinterface + \startinterface english EN\stopinterface + \startinterface german DE\stopinterface + \startinterface french FR\stopinterface + \startinterface czech CS\stopinterface + \startinterface italian IT\stopinterface + \startinterface romanian RO\stopinterface +\stopsetups + +\startsetups text:lowercase + \startinterface dutch \strut nl / nederlands \par \stopinterface + \startinterface english \strut en / english \par \stopinterface + \startinterface german \strut de / deutsch \par \stopinterface + \startinterface french \strut fr / fran\c{c}ais \par \stopinterface + \startinterface czech \strut cs / \v{c}esk\'y \par \stopinterface + \startinterface italian \strut it / italiano \par \stopinterface + \startinterface romanian \strut ro / rom\^{a}n\u{a} \par \stopinterface +\stopsetups + +\startmakeup[\v!standard] + \dontcomplain + \setupalign[\v!left] + \startcolor[TitleColor] + \definedfont[RegularBold at 100pt]\setstrut + \strut Con\TeX t \par + \definedfont[RegularBold at 50pt]\setstrut + \setups[text:commands] + \vfill + \definedfont[RegularBold at 150pt]\setstrut + \setups[text:uppercase] + \stopcolor +\stopmakeup + +\setuplayout % needed ? + +\setupbackgrounds + [\v!rightpage] + [\c!background=] + +\startmakeup[\v!standard] + \dontcomplain + \startcolor[TitleColor] + \definedfont[RegularBold at 100pt]\setstrut + \setupalign[\v!left] + \strut Con\TeX t \par + \definedfont[RegularBold at 50pt]\setstrut + \setups[text:commands] + \vfill + \definedfont[RegularBold at 24pt]\setupinterlinespace + \setups[text:lowercase] + \par \strut \currentdate \par + \stopcolor +\stopmakeup + +\protect + +\placeeverysetup + +\unprotect + +\page[\v!yes,\v!blank,\v!right,\v!left] + +\setuplayout + [titlepage] + +\setupbackgrounds + [\v!leftpage] + [\c!background=back] + +\startmakeup[\v!standard][\c!page=] + \dontcomplain + \startcolor[TitleColor] + \definedfont[RegularBold at 24pt]\setupinterlinespace + \setupalign[\v!left] + \vfill + PRAGMA ADE \par + Ridderstraat 27 \par + 8061GH Hasselt NL \par + www.pragma-ade.com \par + \stopcolor +\stopmakeup + +\protect + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-setups-proofing.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-proofing.mkiv new file mode 100644 index 00000000000..e40ee2ad10a --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-setups-proofing.mkiv @@ -0,0 +1,50 @@ +%D \module +%D [ file=setups-proofing, +%D version=2016.04.05, +%D title=\CONTEXT\ Setup Definitions, +%D subtitle=Macro Definitions, +%D author={Hans Hagen & Wolfgang Schuster}, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% <?context-directive job ctxfile x-setups.ctx ?> + +\usemodule[x][setups-basics] + +\unprotect + +\loadsetups + [\jobname.xml] + +\setupbodyfont + [10pt] + +\setuplayout + [\c!width=middle, + \c!topspace=1cm, + \c!bottomspace=1cm, + \c!backspace=1cm, + \c!cutspace=1cm, + \c!footer=0pt, + \c!header=1cm] + +\setuplayout + [\v!middle] + +\setupframedtext + [setuptext] + [\c!background=setupfilename] + +\protect + +\starttext + + \loadsetups[i-common-definitions] + + \placeeverysetup + +\stoptext diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-setups.ctx b/Master/texmf-dist/tex/context/modules/mkiv/x-setups.ctx new file mode 100644 index 00000000000..0ca4d8f6f49 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-setups.ctx @@ -0,0 +1,15 @@ +<?xml version='1.0' standalone='yes'?> + +<!-- this is also a demo of using the xml interface --> + +<ctx:job> + <ctx:message>generating interface setups</ctx:message> + <ctx:process> + <ctx:flags> + <ctx:flag>purge</ctx:flag> + </ctx:flags> + <ctx:resources> + <ctx:environment>x-setups-proofing.mkiv</ctx:environment> + </ctx:resources> + </ctx:process> +</ctx:job> diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-steps.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-steps.mkiv new file mode 100644 index 00000000000..29b3f7eaa6e --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-steps.mkiv @@ -0,0 +1,102 @@ +%D \module +%D [ file=m-steps, +%D version=2001.05.28, +%D title=\CONTEXT\ Modules, +%D subtitle=Step Charts \& Tables, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The \XML\ interface. This module can be made way more efficient +%D in \MKIV\ using textext but it makes only sense to do this when +%D I really need it in a demanding application. Probably half of the +%D code in m-steps.tex can go. + +\usemodule[m][steps] + +\unprotect + +\installcorenamespace {xmlstepchart} +\installcorenamespace {xmlsteptable} + +\def\xmlstepchartdirective#1{\executeifdefined{\??xmlstepchart#1}\gobbletwoarguments} % {#2}{#3} +\def\xmlsteptabledirective#1{\executeifdefined{\??xmlsteptable#1}\gobbletwoarguments} % {#2}{#3} + +\setvalue{\??xmlstepchart charts}{\setsomevalue\@@STPC} +\setvalue{\??xmlstepchart cells}{\setsomevalue\@@STEC} +\setvalue{\??xmlstepchart texts}{\setsomevalue\@@STET} +\setvalue{\??xmlstepchart lines}{\setsomevalue\@@STEL} + +\setvalue{\??xmlsteptable tables}{\setsomevalue\@@STPT} +\setvalue{\??xmlsteptable cells}{\setsomevalue\@@STEC} +\setvalue{\??xmlsteptable texts}{\setsomevalue\@@STET} +\setvalue{\??xmlsteptable lines}{\setsomevalue\@@STEL} + +\startxmlsetups xml:ct:define + \xmlsetsetup {#1} {ct:*} {xml:ct:*} + % \xmlsetsetup {#1} {ct:stepaligntable/cells} {xml:ct:stepaligntable:cells} + % \xmlsetsetup {#1} {ct:stepaligntable/lines} {xml:ct:stepaligntable:lines} +\stopxmlsetups + +\xmlregisterns{ct}{stepcharts} + +\xmlregistersetup{xml:ct:define} + +\startxmlsetups xml:ct:prep + \expanded{\prep[\xmltoparameters{#1}]}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:ct:text + \expanded{\text[\xmltoparameters{#1}]}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:ct:texts + \expanded{\texts[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} +\stopxmlsetups + +\startxmlsetups xml:ct:cell + \expanded{\cell[\xmltoparameters{#1}]}{\xmlflush{#1}} +\stopxmlsetups + +\startxmlsetups xml:ct:cells + \expanded{\cells[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}} +\stopxmlsetups + +\startxmlsetups xml:ct:lines + \expanded{\startlines[\xmltoparameters{#1}]} + \xmlflush{#1} + \stoplines +\stopxmlsetups + +\startxmlsetups xml:ct:steptable + \expanded{\startSTEPtable[\xmltoparameters{#1}]} + \xmlflush{#1} + \stopSTEPtable +\stopxmlsetups + +\startxmlsetups xml:ct:stepchart + \expanded{\startSTEPchart[\xmltoparameters{#1}]} + \xmlflush{#1} + \stopSTEPchart +\stopxmlsetups + +% \startxmlsetups xml:ct:stepaligntable +% \expanded{\startSTEPaligntable[\xmltoparameters{#1}]} +% \xmlflush{#1} +% \stopSTEPaligntable +% \stopxmlsetups +% +% \startxmlsetups xml:ct:stepaligntable:cells +% \expanded{\cells[\xmltoparameters{#1}]} {\xmltext{#1}{/ct:c1}} {\xmltext{#1}{/ct:c2}} {\xmltext{#1}{/ct:c3}} +% \stopxmlsetups +% +% \startxmlsetups xml:ct:stepaligntable:lines +% \expanded{\setupSTEPlines[\xmltoparameters{#1}]} +% \xmlflush{#1} +% \stopxmlsetups + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-udhr.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-udhr.mkiv new file mode 100644 index 00000000000..e081bfd5971 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-udhr.mkiv @@ -0,0 +1,98 @@ +%D \module +%D [ file=x-udhr, +%D version=2011.06.11, +%D title=\CONTEXT\ Modules, +%D subtitle=Unicode Language Test Files, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D The XML files can be fetched from: \from[http://unicode.org/udhr/]. + +\startmodule[udhr] + +\startxmlsetups udhr:basics + \xmlsetsetup {#1} {*} {udhr:*} +\stopxmlsetups + +\xmlregistersetup{udhr:basics} + +\startxmlsetups udhr:udhr + + \mainlanguage[\xmlatt{#1}{language}] + + \starttitle[title=\xmltext{#1}{/title}] + \xmlfirst{#1}{/preamble} + \xmlall{#1}{/article} + \stoptitle + +\stopxmlsetups + +\startxmlsetups udhr:preamble + \startsubject[title=\xmltext{#1}{/title}] + \xmlall{#1}{/*)} + \stopsubject +\stopxmlsetups + +\startxmlsetups udhr:article + \startsubject[title=\xmltext{#1}{/title}] + \xmlall{#1}{/*)} + \stopsubject +\stopxmlsetups + +\startxmlsetups udhr:orderedlist + \startitemize[n] + \xmlflush{#1} + \stopitemize +\stopxmlsetups + +\startxmlsetups udhr:listitem + \startitem + \xmlflush{#1} + \stopitem +\stopxmlsetups + +\startxmlsetups udhr:para + \xmlflush{#1} + \par +\stopxmlsetups + +\setupbodyfont + [dejavu,10pt] + +\setuplayout + [width-=middle, + height=middle, + footer=0cm, + header=1.5cm] + +\setupwhitespace + [big] + +\setuphead + [chapter] + [header=high, + style=\bfb, + align=middle] + +\setuphead + [section] + [style=\bfa, + align=middle] + +\setuptolerance + [verytolerant] + +\continueifinputfile{x-udhr.mkiv} + +% todo: when argument given then process it + +\starttext + \xmlprocessfile{main}{udhr_nld.xml}{} +\stoptext + +\stopmodule diff --git a/Master/texmf-dist/tex/context/modules/mkiv/x-xfdf.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/x-xfdf.mkiv new file mode 100644 index 00000000000..460220ed943 --- /dev/null +++ b/Master/texmf-dist/tex/context/modules/mkiv/x-xfdf.mkiv @@ -0,0 +1,72 @@ +%D \module +%D [ file=x-xfdf, +%D version=2011.09.07, +%D title=\CONTEXT\ XML Modules, +%D subtitle=\XFDF, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D This is a revival of using \XFDF, but now in a more \MKIV-ish way. We +%D supported it long ago already in \MKII\ but never used it at a large +%D scale (not that much user interest anyway). + +\startmodule[xfdf] + +% see xfdf-001.xfdf and xfdf-001.tex + +% %D Possible speedup but hardly worth the trouble. +% +% \startluacode +% +% local hashes = { } table.setmetatableindex(hashes,function(t,k) local v = { } t[k] = v return v end) +% +% function xml.functions.xfdf_collect_values(root) +% local hash = hashes[root] +% for c in xml.collected(root,"/xfdf/fields/field/value") do +% hash[xml.parent(c).at.name] = c +% end +% end +% +% function xml.functions.xfdf_get_values(root,name) +% return hashes[root][name] +% end +% +% function lxml.xfdf_get_values(root,name) +% xml.sprint(hashes[lxml.id(root)][name]) +% end +% +% \stopluacode +% +% \def\xfdfvalue#1#2% +% {\ctxlua{lxml.xfdf_get_values("#1","#2")}} + +\startxmlsetups xfdf:define + \xmlsetsetup{#1}{*}{xfdf:*} + % \xmlfilter {#1}{./function(xfdf_collect_values)} +\stopxmlsetups + +\xmlregisterns{xfdf}{http://ns.adobe.com/xfdf/} + +\xmlregisterdocumentsetup{xfdf}{xfdf:define} + +\startxmlsetups xfdf:value + \xmlflush{#1} +\stopxmlsetups + +\def\xfdfload #1#2{\xmlloadonly{#1}{#2}{xfdf}} +\def\xfdfvalue#1#2{\xmlfirst{#1}{/xfdf/fields/field[@name='#2']/value}} +\def\xfdftext #1#2{\xmlfirst{#1}{/xfdf/fields/field[@name='#2']/value/paragraphs()}} + +% \startxmlsetups xfdf:b +% \bold{\xmlflush{#1}} +% \stopxmlsetups + +% \xfdfload {whatever}{xfdf-001.xfdf} +% \xfdfvalue{whatever}{somefield} + +\stopmodule |