diff options
Diffstat (limited to 'tex/context/base/typo-drp.lua')
-rw-r--r-- | tex/context/base/typo-drp.lua | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/tex/context/base/typo-drp.lua b/tex/context/base/typo-drp.lua new file mode 100644 index 000000000..b7815efc2 --- /dev/null +++ b/tex/context/base/typo-drp.lua @@ -0,0 +1,207 @@ +if not modules then modules = { } end modules ['typo-drp'] = { + version = 1.001, + comment = "companion to typo-drp.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- A playground for experiments. Currently we only have a dropped caps as special +-- but there might be more, so for the moment we keep this 'paragraphs' namespace +-- for this. + +local tonumber, type, next = tonumber, type, next +local ceil = math.ceil + +local utfbyte = utf.byte +local utfchar = utf.char + +local trace_initials = false trackers.register("typesetters.initials", function(v) trace_initials = v end) +local report_initials = logs.reporter("nodes","initials") + +local initials = typesetters.paragraphs or { } +typesetters.initials = initials or { } + +local nodes = nodes +local tasks = nodes.tasks + +local hpack_nodes = nodes.hpack +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes + +local new_kern = nodes.pool.kern +local insert_before = nodes.insert_before +local insert_after = nodes.insert_after + +local variables = interfaces.variables +local v_default = variables.default +local v_margin = variables.margin + +local texget = tex.get +local texsetattribute = tex.setattribute +local unsetvalue = attributes.unsetvalue + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local kern_node = nodecodes.kern +local whatsit_code = nodecodes.whatsit +local localpar_code = whatsitcodes.localpar + +local actions = { } +initials.actions = actions + +local a_initial = attributes.private("initial") +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local a_colorspace = attributes.private('colormodel') + +local settings = nil + +function initials.set(specification) + settings = specification or { } + settings.enabled = true + tasks.enableaction("processors","typesetters.initials.handler") + if trace_initials then + report_initials("enabling initials") + end + texsetattribute(a_initial,1) +end + +commands.setinitial = initials.set + +-- dropped caps experiment (will be done properly when luatex +-- stores the state in the local par node) .. btw, search still +-- works with dropped caps, as does an export + +-- we need a 'par' attribute and in fact for dropped caps we don't need +-- need an attribute ... dropit will become s state counter (or end up +-- in the localpar user data + +-- for the moment, each paragraph gets a number as id (attribute) ..problem +-- with nesting .. or anyhow, needed for tagging anyway + +-- todo: prevent linebreak .. but normally a initial ends up at the top of +-- a page so this has a low priority + +actions[v_default] = function(head,setting) + local done = false + if head.id == whatsit_code and head.subtype == localpar_code then + -- begin of par + local first = head.next + -- parbox .. needs to be set at 0 + if first and first.id == hlist_code then + first = first.next + end + -- we need to skip over kerns and glues (signals) + while first and first.id ~= glyph_code do + first = first.next + end + if first and first.id == glyph_code then + local char = first.char + local prev = first.prev + local next = first.next + -- if prev.id == hlist_code then + -- -- set the width to 0 + -- end + if next and next.id == kern_node then + next.kern = 0 + end + if setting.font then + first.font = setting.font + end + -- can be a helper + local ma = setting.ma or 0 + local ca = setting.ca + local ta = setting.ta + if ca and ca > 0 then + first[a_colorspace] = ma == 0 and 1 or ma + first[a_color] = ca + end + if ta and ta > 0 then + first[a_transparency] = ta + end + -- + local width = first.width + local height = first.height + local depth = first.depth + local distance = setting.distance or 0 + local voffset = setting.voffset or 0 + local hoffset = setting.hoffset or 0 + first.xoffset = - width - hoffset - distance - parindent + first.yoffset = - height - voffset + if true then + -- needed till we can store parindent with localpar + first.prev = nil + first.next = nil + local h = hpack_nodes(first) + h.width = 0 + h.height = 0 + h.depth = 0 + prev.next = h + next.prev = h + h.next = next + h.prev = prev + end + if setting.location == v_margin then + -- okay + else + local lines = tonumber(setting.n) or 0 + if lines == 0 then -- safeguard, not too precise + lines = ceil((height+voffset) / texget("baselineskip").width) + end + -- We cannot set parshape yet ... when we can I'll add a slope + -- option (positive and negative, in emwidth). + local hangafter = - lines + local hangindent = width + distance + parindent + if trace_initials then + report_initials("setting hangafter to %i and hangindent to %p",hangafter,hangindent) + end + tex.hangafter = hangafter + tex.hangindent = hangindent + if parindent ~= 0 then + insert_after(first,first,new_kern(-parindent)) + end + end + done = true + end + end + return head, done +end + +local function process(namespace,attribute,head) + local start = head + local attr = nil + while start do + attr = start[attribute] + if attr then + break + elseif start.id == glyph then + break + else + start = start.next + end + end + if attr then + -- here as we can process nested boxes first so we need to keep state + tasks.disableaction("processors","typesetters.initials.handler") + -- texsetattribute(attribute,unsetvalue) + local alternative = settings.alternative or v_default + local action = actions[alternative] or actions[v_default] + if action then + if trace_initials then + report_initials("processing initials, alternative %a",alternative) + end + local head, done = action(head,settings) + return head, done + end + end + return head, false +end + +initials.attribute = a_initial + +initials.handler = nodes.installattributehandler { + name = "initials", + namespace = initials, + processor = process, +} |