From 40b109062c5380736c95b98033d9f6d83bb4dc0d Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 22 Aug 2013 15:28:00 +0200 Subject: beta 2013.08.22 15:28 --- tex/context/base/char-ini.lua | 2 + tex/context/base/colo-ini.lua | 56 ++-- tex/context/base/colo-ini.mkiv | 2 + tex/context/base/context-version.pdf | Bin 4109 -> 4106 bytes tex/context/base/context.mkiv | 3 +- tex/context/base/core-def.mkiv | 1 + tex/context/base/file-mod.mkvi | 2 +- tex/context/base/font-afm.lua | 2 +- tex/context/base/font-otf.lua | 2 +- tex/context/base/mult-low.lua | 2 +- tex/context/base/status-files.pdf | Bin 24758 -> 24730 bytes tex/context/base/task-ini.lua | 2 + tex/context/base/typo-fln.lua | 284 +++++++++++++++++++++ tex/context/base/typo-fln.mkiv | 103 ++++++++ tex/generic/context/luatex/luatex-fonts-merged.lua | 4 +- 15 files changed, 439 insertions(+), 26 deletions(-) create mode 100644 tex/context/base/typo-fln.lua create mode 100644 tex/context/base/typo-fln.mkiv (limited to 'tex') diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua index b75f5eda7..dc6e067c0 100644 --- a/tex/context/base/char-ini.lua +++ b/tex/context/base/char-ini.lua @@ -483,6 +483,8 @@ setmetatableindex(characters.is_letter, mt) setmetatableindex(characters.is_command, mt) setmetatableindex(characters.is_spacing, mt) +-- todo: also define callers for the above + -- linebreak: todo: hash -- -- normative : BK CR LF CM SG GL CB SP ZW NL WJ JL JV JT H2 H3 diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua index b91e564e6..535ee71b8 100644 --- a/tex/context/base/colo-ini.lua +++ b/tex/context/base/colo-ini.lua @@ -287,6 +287,7 @@ local left = P("(") local right = P(")") local comma = P(",") local mixnumber = lpegpatterns.number / tonumber + + P("-") / function() return -1 end local mixname = C(P(1-left-right-comma)^1) ----- mixcolor = Cc("M") * mixnumber * left * mixname * (comma * mixname)^-1 * right * P(-1) local mixcolor = Cc("M") * mixnumber * left * mixname * (comma * mixname)^0 * right * P(-1) -- one is also ok @@ -643,7 +644,7 @@ local min = math.min -- a[b,c] -> b+a*(c-b) -local function f(one,two,i,fraction) +local function inbetween(one,two,i,fraction) local o, t = one[i], two[i] local otf = o + fraction * (t - o) if otf > 1 then @@ -652,6 +653,22 @@ local function f(one,two,i,fraction) return otf end +local function justone(one,fraction,i) + local otf = fraction * one[i] + if otf > 1 then + otf = 1 + end + return otf +end + +local function complement(one,fraction,i) + local otf = - fraction * (1 - one[i]) + if otf > 1 then + otf = 1 + end + return otf +end + function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,specs,global,freeze) fraction = tonumber(fraction) or 1 local one, two = colorvalues[c_one], colorvalues[c_two] @@ -663,37 +680,38 @@ function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,sp -- problems with weighted gray conversions and work with original values local ca if csone == 2 then - ca = register_color(name,'gray',f(one,two,2,fraction)) + ca = register_color(name,'gray',inbetween(one,two,2,fraction)) elseif csone == 3 then - ca = register_color(name,'rgb', f(one,two,3,fraction), - f(one,two,4,fraction), - f(one,two,5,fraction)) + ca = register_color(name,'rgb', inbetween(one,two,3,fraction), + inbetween(one,two,4,fraction), + inbetween(one,two,5,fraction)) elseif csone == 4 then - ca = register_color(name,'cmyk',f(one,two,6,fraction), - f(one,two,7,fraction), - f(one,two,8,fraction), - f(one,two,9,fraction)) + ca = register_color(name,'cmyk',inbetween(one,two,6,fraction), + inbetween(one,two,7,fraction), + inbetween(one,two,8,fraction), + inbetween(one,two,9,fraction)) else - ca = register_color(name,'gray',f(one,two,2,fraction)) + ca = register_color(name,'gray',inbetween(one,two,2,fraction)) end definecolor(name,ca,global,freeze) -- end else + local inbetween = fraction < 0 and complement or justone local csone = one[1] local ca if csone == 2 then - ca = register_color(name,'gray',fraction*one[2]) + ca = register_color(name,'gray',inbetween(one,fraction,2)) elseif csone == 3 then - ca = register_color(name,'rgb', fraction*one[3], - fraction*one[4], - fraction*one[5]) + ca = register_color(name,'rgb', inbetween(one,fraction,3), + inbetween(one,fraction,4), + inbetween(one,fraction,5)) elseif csone == 4 then - ca = register_color(name,'cmyk',fraction*one[6], - fraction*one[7], - fraction*one[8], - fraction*one[9]) + ca = register_color(name,'cmyk',inbetween(one,fraction,6), + inbetween(one,fraction,7), + inbetween(one,fraction,8), + inbetween(one,fraction,9)) else - ca = register_color(name,'gray',fraction*one[2]) + ca = register_color(name,'gray',inbetween(one,fraction,2)) end definecolor(name,ca,global,freeze) end diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv index 808a46c96..3fae31cbe 100644 --- a/tex/context/base/colo-ini.mkiv +++ b/tex/context/base/colo-ini.mkiv @@ -748,6 +748,8 @@ % % \definecolor[mycolorc][.5(blue,red)] % \definecolor[mycolord][.5(blue)] +% \definecolor[mycolord][-.5(blue,red)] % complement +% \definecolor[mycolord][-(blue)] % complement % % \enabledirectives[colors.pgf] % \definecolor[mycolorx][magenta!50!yellow] diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 7c7b75d2c..0fa8b1170 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 0e29ba277..e32839863 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2013.08.21 10:55} +\edef\contextversion{2013.08.22 15:28} \edef\contextkind {beta} %D For those who want to use this: @@ -296,6 +296,7 @@ \loadmarkfile{typo-pag} \loadmarkfile{typo-mar} \loadmarkfile{typo-itm} +\loadmarkfile{typo-fln} \loadmarkfile{buff-ini} \loadmarkfile{buff-ver} diff --git a/tex/context/base/core-def.mkiv b/tex/context/base/core-def.mkiv index dc2a30f4e..bc7432059 100644 --- a/tex/context/base/core-def.mkiv +++ b/tex/context/base/core-def.mkiv @@ -45,6 +45,7 @@ \flushpostponednodedata \typo_delimited_repeat \insertparagraphintro + \typo_firstline_set \to \everypar \appendtoks diff --git a/tex/context/base/file-mod.mkvi b/tex/context/base/file-mod.mkvi index 0dbd14bdb..a3d23c514 100644 --- a/tex/context/base/file-mod.mkvi +++ b/tex/context/base/file-mod.mkvi @@ -145,7 +145,7 @@ % \fi % \let\currentmoduleparameters\empty} -\def\moduleparameter#name#parameter% +\def\moduleparameter#name#parameter% should have been \namedmoduleparameter {\csname\??module \ifcsname\??module#name:#parameter\endcsname#name:#parameter\fi \endcsname} diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua index cb0c2438f..ac27d652c 100644 --- a/tex/context/base/font-afm.lua +++ b/tex/context/base/font-afm.lua @@ -640,7 +640,7 @@ local function copytotfm(data) if italicangle then parameters.italicangle = italicangle parameters.italicfactor = math.cos(math.rad(90+italicangle)) - parameters.slant = - math.round(math.tan(italicangle*math.pi/180)) + parameters.slant = - math.tan(italicangle*math.pi/180) end if monospaced then parameters.space_stretch = 0 diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index d13ec4acf..7e267b15b 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -2090,7 +2090,7 @@ local function copytotfm(data,cache_id) if italicangle then parameters.italicangle = italicangle parameters.italicfactor = math.cos(math.rad(90+italicangle)) - parameters.slant = - math.round(math.tan(italicangle*math.pi/180)) + parameters.slant = - math.tan(italicangle*math.pi/180) end if monospaced then parameters.space_stretch = 0 diff --git a/tex/context/base/mult-low.lua b/tex/context/base/mult-low.lua index 47e31978b..1e6d407cc 100644 --- a/tex/context/base/mult-low.lua +++ b/tex/context/base/mult-low.lua @@ -96,7 +96,7 @@ return { "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext","startdocument", "stopdocument", "documentvariable", "setupdocument", - "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", + "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule","setupmodule","currentmoduleparameter","moduleparameter", -- "startTEXpage", "stopTEXpage", -- "startMPpage", "stopMPpage", -- already catched by nested lexer diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index b30cca021..7e7cc02bd 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index 6bbc62773..ac3aee03a 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -33,6 +33,7 @@ appendaction("processors", "characters", "scripts.injectors.handler") appendaction("processors", "words", "builders.kernel.hyphenation") -- always on appendaction("processors", "words", "languages.words.check") -- disabled +appendaction("processors", "words", "typesetters.firstlines.handler") -- disabled appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split") -- experimental appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo @@ -123,6 +124,7 @@ disableaction("processors", "typesetters.digits.handler") disableaction("processors", "typesetters.breakpoints.handler") disableaction("processors", "typesetters.directions.handler") disableaction("processors", "languages.words.check") +disableaction("processors", "typesetters.firstlines.handler") disableaction("processors", "typesetters.spacings.handler") disableaction("processors", "typesetters.kerns.handler") disableaction("processors", "typesetters.italics.handler") diff --git a/tex/context/base/typo-fln.lua b/tex/context/base/typo-fln.lua new file mode 100644 index 000000000..322374ac0 --- /dev/null +++ b/tex/context/base/typo-fln.lua @@ -0,0 +1,284 @@ +if not modules then modules = { } end modules ['typo-fln'] = { + version = 1.001, + comment = "companion to typo-fln.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- When I ran into the following experimental code again, I figured that it dated +-- from the early days of mkiv, so I updates it a bit to fit into todays context. +-- In the process I might have messed up things. For instance we had a diffent +-- wrapper then using head and tail. + +-- todo: only letters (no punctuation) +-- todo: nuts + +local trace_firstlines = false trackers.register("typesetters.firstlines", function(v) trace_firstlines = v end) + +local report_firstlines = logs.reporter("nodes","firstlines") + +local nodes = nodes +local tasks = nodes.tasks + +local nodecodes = nodes.nodecodes +local glyph = nodecodes.glyph +local rule = nodecodes.rule +local disc = nodecodes.disc + +local traverse_id = nodes.traverse_id +local free_node_list = nodes.flush_list +local copy_node_list = nodes.copy_list +local insert_node_after = nodes.insert_after +local hpack_node_list = nodes.hpack + +local hpack_filter = nodes.processors.hpack_filter + +local newpenalty = nodes.pool.penalty + +typesetters.firstlines = typesetters.firstlines or { } +local firstlines = typesetters.firstlines + +local actions = { } +firstlines.actions = actions + +local busy = false +local settings = { } + +local a_firstline = attributes.private('firstline') +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local a_colorspace = attributes.private('colormodel') + +local unsetvalue = attributes.unsetvalue + +local variables = interfaces.variables + +----- is_letter = characters.is_letter +----- categories = characters.categories + +firstlines.actions[variables.line] = function(head,setting) + -- local attribute = fonts.specifiers.contextnumber(setting.feature) -- was experimental + local dynamic = setting.dynamic + local font = setting.font + -- make copy with dynamic feature attribute set + local list = copy_node_list(head) + for g in traverse_id(glyph,list) do + if dynamic > 0 then + g[0] = dynamic + end + g.font = font + end + local words = 0 + local nofchars = 0 + local nofwords = 1 + local going = true + local lastnofchars = 0 + local hsize = tex.hsize - tex.parindent - tex.leftskip.width - tex.rightskip.width -- can be a helper + while going do + -- (slow) stepwise pass (okay, we could do do a vsplit and stitch but why do difficult) + local temp = copy_node_list(list) + local start = temp + local ok = false + lastnofchars = nofchars + nofchars = 0 + words = 0 + local quit = false + while start do + -- also nicely quits on dics node + local id = start.id + if id == glyph then + -- if not is_letter[categories[start.char]] then + -- quit = true + -- elseif not ok then + if not ok then + words = words + 1 + ok = true + end + nofchars = nofchars + 1 + elseif id == disc then + -- this could be an option + else + quit = true + end + if quit then + ok = false + if words == nofwords then + local f = start.next + start.next = nil + free_node_list(f) + break + end + quit = false + end + start = start.next + end + if not start then + going = false + end + local pack = hpack_node_list(hpack_filter(temp)) + if pack.width > hsize then + nofchars = lastnofchars + break + else + nofwords = nofwords + 1 + end + free_node_list(pack) + end + -- set dynamic attribute in real list + local start = head + local ma = setting.ma or 0 + local ca = setting.ca + local ta = setting.ta + while start do + local id = start.id + if id == glyph then -- or id == disc then + if nofchars > 0 then + if dynamic > 0 then + start[0] = dynamic + end + start.font = font + if ca and ca > 0 then + start[a_colorspace] = ma == 0 and 1 or ma + start[a_color] = ca + end + if ta and ta > 0 then + start[a_transparency] = ta + end + nofchars = nofchars - 1 + if nofchars == 0 then + insert_node_after(head,start,newpenalty(-10000)) -- break + end + else + break + end + end + start = start.next + end + -- variant (no disc nodes) + -- if false then + -- for g in traverse_id(glyph,head) do + -- if nofchars > 0 then + -- if dynamic > 0 then + -- g[0] = dynamic + -- end + -- g.font = font + -- nofchars = nofchars - 1 + -- if nofchars == 0 then + -- insert_node_after(head,g,newpenalty(-10000)) -- break + -- end + -- end + -- end + -- end + return head, true +end + +firstlines.actions[variables.word] = function(head,setting) + -- local attribute = fonts.specifiers.contextnumber(setting.feature) -- was experimental + local dynamic = setting.dynamic + local font = setting.font + local words = 0 + local nofwords = setting.n or 1 + local start = head + local ok = false + local ma = setting.ma or 0 + local ca = setting.ca + local ta = setting.ta + while start do + local id = start.id + -- todo: delete disc nodes + if id == glyph then + if not ok then + words = words + 1 + ok = true + end + if ca and ca > 0 then + start[a_colorspace] = ma == 0 and 1 or ma + start[a_color] = ca + end + if ta and ta > 0 then + start[a_transparency] = ta + end + if dynamic > 0 then + start[0] = dynamic + end + start.font = font + elseif id == disc then + -- continue + else + ok = false + if words == nofwords then + break + end + end + start = start.next + end + return head, true +end + +local function process(namespace,attribute,head) + if not busy then + local start, attr = head, nil + while start do + attr = start[attribute] + if attr or start.id == glyph then + break + else + start = start.next + end + end + if attr then + local setting = settings[attr] + if setting then + local action = actions[setting.alternative] + if action then + busy = true + head, done = action(head,setting) + busy = false + end + end + for g in traverse_id(glyph,head) do + -- inefficient: we could quit at unset + g[attribute] = unsetvalue + end + return head, true + end + end + return head, false +end + +-- local enabled = false + +-- function firstlines.set(n) +-- if n == variables.reset or not tonumber(n) or n == 0 then +-- texsetattribute(a_firstline,unsetvalue) +-- else +-- if not enabled then +-- tasks.enableaction("processors","typesetters.firstlines.handler") +-- if trace_paragraphs then +-- report_firstlines("enabling firstlines") +-- end +-- enabled = true +-- end +-- texsetattribute(a_firstline,n) +-- end +-- end + +firstlines.attribute = a_firstline + +firstlines.handler = nodes.installattributehandler { + name = "firstlines", + namespace = firstlines, + processor = process, +} + +function firstlines.define(setting) + local n = #settings + 1 + settings[n] = setting + tasks.enableaction("processors","typesetters.firstlines.handler") + return n +end + +function commands.definefirstline(setting) + context(firstlines.define(setting)) +end diff --git a/tex/context/base/typo-fln.mkiv b/tex/context/base/typo-fln.mkiv new file mode 100644 index 000000000..98577d91e --- /dev/null +++ b/tex/context/base/typo-fln.mkiv @@ -0,0 +1,103 @@ +%D \module +%D [ file=typo-fln, +%D version=2013.08.22, % comes from the few years older m-newstuff +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=First Lines, +%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 Typesetting Macros / First Lines} + +%D I had this code laying around for a while \unknown\ probably as a side effect +%D of cleaning up the supp-fun modules. There is probably room for improvement +%D and more features. + +% \setupbodyfont[pagella] +% +% \starttext +% +% \setupindenting[medium,yes] +% +% \definefirstline +% [smallcaps] +% [alternative=line, +% color=darkred, +% style=\setfontfeature{smallcaps}] +% +% \setfirstline[smallcaps] \input tufte \par +% \setfirstline[smallcaps] \input ward \par +% \setfirstline[smallcaps] \input knuth \par +% \setfirstline[smallcaps] \input bryson \par +% +% \definefirstline +% [smallcaps] +% [alternative=word, +% color=darkblue, +% style=bold, +% n=2] +% +% \setfirstline[smallcaps] \input tufte \par +% \setfirstline[smallcaps] \input ward \par +% \setfirstline[smallcaps] \input knuth \par +% \setfirstline[smallcaps] \input bryson \par +% +% \stoptext + +\unprotect + +\registerctxluafile{typo-fln}{1.001} + +\definesystemattribute[firstline][public] + +\installcorenamespace {firstline} + +\installcommandhandler \??firstline {firstline} \??firstline + +\setupfirstline + [\c!alternative=\v!line, + %\c!style=, + %\c!color=, + \c!n=0] + +\appendtoks + \begingroup + \usefirstlinestyleandcolor\c!style\c!color + \setxvalue{\??firstline:\currentfirstline}{\ctxlua{commands.definefirstline { + alternative = "\firstlineparameter\c!alternative", + ma = \the\attribute\colormodelattribute, + ca = \the\attribute\colorattribute, + ta = \the\attribute\transparencyattribute, + n = \number\firstlineparameter\c!n, + font = \fontid\font, + dynamic = \number\attribute\zerocount, + }}}% + \endgroup +\to \everydefinefirstline + +\unexpanded\def\setfirstline[#1]% + {\edef\typo_firstline_set + {\typo_firstline_set_indeed{\number\csname\??firstline:#1\endcsname}}} + +\unexpanded\def\typo_firstline_set_indeed#1% + {\dontleavehmode + \begingroup + \attribute\firstlineattribute#1\relax + \kern\zeropoint % we need a node + \hskip\zeropoint\s!plus\emwidth\relax % can be an option + \globallet\typo_firstline_set\relax + \endgroup} + +\let\typo_firstline_set\relax + +% \appendtoks +% \typo_firstline_set % has to be done later +% \to \everypar + +\protect + +\endinput diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 65807e396..eb4194713 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 08/21/13 10:55:10 +-- merge date : 08/22/13 15:28:35 do -- begin closure to overcome local limits and interference @@ -6866,7 +6866,7 @@ local function copytotfm(data,cache_id) if italicangle then parameters.italicangle=italicangle parameters.italicfactor=math.cos(math.rad(90+italicangle)) - parameters.slant=- math.round(math.tan(italicangle*math.pi/180)) + parameters.slant=- math.tan(italicangle*math.pi/180) end if monospaced then parameters.space_stretch=0 -- cgit v1.2.3