diff options
author | Hans Hagen <pragma@wxs.nl> | 2010-07-30 11:35:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2010-07-30 11:35:00 +0200 |
commit | d879fd040aa85b55875d8aed16394351518dde21 (patch) | |
tree | 09d8d98b17282cb23362b8c94fe124b48afe89b9 /tex | |
parent | 84903d24d6d930438bb3cc4322c4b14271b713aa (diff) | |
download | context-d879fd040aa85b55875d8aed16394351518dde21.tar.gz |
stable 2010.07.30 11:35
Diffstat (limited to 'tex')
110 files changed, 3253 insertions, 782 deletions
diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua index 243e3fbd5..655500055 100644 --- a/tex/context/base/back-ini.lua +++ b/tex/context/base/back-ini.lua @@ -8,7 +8,9 @@ if not modules then modules = { } end modules ['back-ini'] = { backends = backends or { } -local trace_backend = false local function nothing() return nil end +local trace_backend = false + +local function nothing() return nil end local report_backends = logs.new("backends") @@ -32,6 +34,8 @@ backends.nodeinjections = { reference = nothing, destination = nothing, + addtags = nothing, + } backends.codeinjections = { @@ -83,6 +87,13 @@ backends.codeinjections = { setfigurecolorspace = nothing, setfigurealternative = nothing, + enabletags = nothing, + maptag = nothing, + mapping = nothing, -- returns table + + mergereferences = nothing, + mergelayers = nothing, + } backends.registrations = { diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua index 323d23a65..d43bdb701 100644 --- a/tex/context/base/back-pdf.lua +++ b/tex/context/base/back-pdf.lua @@ -31,18 +31,16 @@ local registrations = backends.pdf.registrations local pdfliteral, register = nodes.pdfliteral, nodes.register -local pdfconstant = lpdf.constant -local pdfstring = lpdf.string -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfverbose = lpdf.verbose -local pdfflushobject = lpdf.flushobject -local pdfreserveobject = lpdf.reserveobject -local pdfannotation = nodes.pdfannotation - -local pdfreserveobj = pdf.reserveobj -local pdfimmediateobj = pdf.immediateobj +local pdfconstant = lpdf.constant +local pdfstring = lpdf.string +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfverbose = lpdf.verbose +local pdfflushobject = lpdf.flushobject +local pdfimmediateobject = lpdf.immediateobject + +local pdfannotation_node = nodes.pdfannotation function nodeinjections.rgbcolor(r,g,b) return register(pdfliteral(format("%s %s %s rg %s %s %s RG",r,g,b,r,g,b))) @@ -134,7 +132,7 @@ function codeinjections.insertmovie(specification) Movie = moviedict, A = controldict, } - node.write(pdfannotation(width,height,0,action())) + node.write(pdfannotation_node(width,height,0,action())) end function codeinjections.insertsound(specification) @@ -154,7 +152,7 @@ function codeinjections.insertsound(specification) Movie = sounddict, A = controldict, } - node.write(pdfannotation(0,0,0,action())) + node.write(pdfannotation_node(0,0,0,action())) end end @@ -197,14 +195,22 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range, Domain = { 0, 1 }, Range = range, } - local n = pdfimmediateobj("stream",format("{ %s }",funct),dictionary()) + local n = pdfimmediateobject("stream",format("{ %s }",funct),dictionary()) + +--~ local n = pdfobject { +--~ type = "stream", +--~ immediate = true, +--~ string = format("{ %s }",funct), +--~ attr = dictionary(), +--~ } + local array = pdfarray { pdf_separation, pdfconstant(spotcolornames[name] or name), colorspace, pdfreference(n), } - local m = pdfimmediateobj(tostring(array)) + local m = pdfimmediateobject(tostring(array)) local mr = pdfreference(m) spotcolorhash[name] = m documentcolorspaces[name] = mr @@ -222,14 +228,14 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range, Domain = domain, Range = range, } - local n = pdfimmediateobj("stream",format("{ %s %s }",rep("pop ",noffractions),funct),dictionary()) + local n = pdfimmediateobject("stream",format("{ %s %s }",rep("pop ",noffractions),funct),dictionary()) local array = pdfarray { pdf_device_n, cnames, colorspace, pdfreference(n), } - local m = pdfimmediateobj(tostring(array)) + local m = pdfimmediateobject(tostring(array)) local mr = pdfreference(m) spotcolorhash[name] = m documentcolorspaces[name] = mr @@ -256,7 +262,7 @@ local function registersomeindexcolor(name,noffractions,names,p,colorspace,range Domain = domain, Range = range, } - local n = pdfimmediateobj("stream",format("{ %s %s }",rep("exch pop ",noffractions),funct),dictionary()) -- exch pop + local n = pdfimmediateobject("stream",format("{ %s %s }",rep("exch pop ",noffractions),funct),dictionary()) -- exch pop local a = pdfarray { pdf_device_n, cnames, @@ -280,7 +286,7 @@ local function registersomeindexcolor(name,noffractions,names,p,colorspace,range vector[#vector+1] = concat(set) end vector = pdfverbose { "<", concat(vector, " "), ">" } - local n = pdfimmediateobj(tostring(pdfarray{ pdf_indexed, a, 255, vector })) + local n = pdfimmediateobject(tostring(pdfarray{ pdf_indexed, a, 255, vector })) lpdf.adddocumentcolorspace(format("%s_indexed",name),pdfreference(n)) return n end @@ -393,7 +399,7 @@ function registrations.transparency(n,a,t) BM = transparencies[1], AIS = false, } - local m = pdfimmediateobj(tostring(d)) + local m = pdfimmediateobject(tostring(d)) local mr = pdfreference(m) transparencyhash[0] = m documenttransparencies[0] = mr @@ -408,7 +414,7 @@ function registrations.transparency(n,a,t) BM = transparencies[a] or transparencies[0], AIS = false, } - local m = pdfimmediateobj(tostring(d)) + local m = pdfimmediateobject(tostring(d)) local mr = pdfreference(m) transparencyhash[n] = m documenttransparencies[n] = mr @@ -440,14 +446,14 @@ function codeinjections.setfigurealternative(data,figure) if displayfigure then -- figure.aform = true img.immediatewrite(figure) - local a = lpdf.array { - lpdf.dictionary { - Image = lpdf.reference(figure.objnum), + local a = pdfarray { + pdfdictionary { + Image = pdfreference(figure.objnum), DefaultForPrinting = true, } } - local d = lpdf.dictionary { - Alternates = lpdf.reference(pdf.immediateobj(tostring(a))), + local d = pdfdictionary { + Alternates = pdfreference(pdfimmediateobject(tostring(a))), } displayfigure.attr = d() return displayfigure, figures.current() diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv index a10afd5b9..3cae2afd2 100644 --- a/tex/context/base/back-pdf.mkiv +++ b/tex/context/base/back-pdf.mkiv @@ -119,7 +119,7 @@ %D The following will move to the backend \LUA\ code: \appendtoks \ctxlua{backends.codeinjections.finalizepage ()}\to \everybackendshipout % is immediate -\appendtoks \ctxlua{backends.codeinjections.finalizedocument()}\to \everylastbackendshipout % is immediate +%appendtoks \ctxlua{backends.codeinjections.finalizedocument()}\to \everylastbackendshipout % is immediate %D Temporary hack, will be removed or improved or default. diff --git a/tex/context/base/bibl-bib.mkiv b/tex/context/base/bibl-bib.mkiv index 10abe5cb8..e4a92b3c0 100644 --- a/tex/context/base/bibl-bib.mkiv +++ b/tex/context/base/bibl-bib.mkiv @@ -627,7 +627,7 @@ \ifx\currentbibtexsessiontag\empty % can't really happen \else\ifx\currentbibtexcriterium\v!all - \doplacepublicationindeed + \dotypesetbibtexpublication % was \doplacepublicationindeed \else \ctxlua{bibtex.hacks.doifalreadyplaced("\currentbibtexsessiontag")} \donothing diff --git a/tex/context/base/buff-ini.mkiv b/tex/context/base/buff-ini.mkiv index 13f69554f..64bc66149 100644 --- a/tex/context/base/buff-ini.mkiv +++ b/tex/context/base/buff-ini.mkiv @@ -176,6 +176,9 @@ \def\thebuffernumber#1% {\csname\??bu#1\c!number\endcsname} + +\def\thedefinedbuffer#1% + {def-\csname\??bu#1\c!number\endcsname} \unexpanded\def\getbuffer {\dodoubleempty\dogetbuffer} @@ -199,13 +202,17 @@ \def\doprocessbufferverbatim {\doinitializeverbatim - \ctxlua{buffers.type("\currentbuffer","\typingparameter\c!strip")}} + \dostarttagged\t!verbatim\currentbuffer + \ctxlua{buffers.type("\currentbuffer","\typingparameter\c!strip")}% + \dostoptagged} \def\doprocessbufferlinesverbatim#1#2#3% {#2% % todo, set up numbers \doinitializeverbatim + \dostarttagged\t!verbatim\currentbuffer \ctxlua{buffers.type("\currentbuffer","\typingparameter\c!strip")} + \dostoptagged #3} \def\doifelsebuffer#1% diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv index cc8882ac6..59b484983 100644 --- a/tex/context/base/buff-ver.mkiv +++ b/tex/context/base/buff-ver.mkiv @@ -344,7 +344,9 @@ \def\dodotypeAA#1% {\doinitializeverbatim \def\obs{\obeyedspace}% + \dostarttagged\t!verbatim\currenttyping \ctxlua{buffers.hooks.flush_inline(\!!bs\detokenize{#1}\!!es)}% + \dostoptagged \egroup} \def\dodotypeB#1% @@ -356,7 +358,9 @@ \def\dodotypeBB#1% {\doinitializeverbatim + \dostarttagged\t!verbatim\currenttyping \ctxlua{buffers.visualizers.flush_nested(\!!bs\detokenize{#1}\!!es,false)}% + \dostoptagged \egroup \gobbleoneargument} % grab last > @@ -370,7 +374,9 @@ \def\dodotypeCC#1% {\doinitializeverbatim \ifx\obeycharacters\setupprettytype % temp hack, we need a proper signal + \dostarttagged\t!verbatim\currenttyping \ctxlua{buffers.hooks.flush_inline([\!!bs\detokenize{#1}\!!es,true)}% + \dostoptagged \else \def\obs{\obeyedspace}% \ctxlua{buffers.visualizers.flush_nested(\!!bs\detokenize{#1}\!!es,true)}% @@ -388,7 +394,9 @@ \def\dodotypeDD#1% {\doinitializeverbatim + \dostarttagged\t!verbatim\currenttyping \ctxlua{buffers.hooks.flush_inline(\!!bs\detokenize{#1}\!!es,true)}% + \dostoptagged \egroup \gobbleoneargument} % grab last > @@ -634,7 +642,9 @@ \def\dotypefileverbatim {\doinitializeverbatim \beginofverbatimlines + \dostarttagged\t!verbatimblock\currenttyping \ctxlua{buffers.typefile("\readfilename","\typingparameter\c!strip","\typingparameter\c!range")}% + \dostoptagged \endofverbatimlines} \def\dotypefilelinesverbatim#1#2% @@ -645,7 +655,9 @@ {} {\doinitializeverbatim \beginofverbatimlines + \dostarttagged\t!verbatimblock\currenttyping \ctxlua{buffers.type("_typing_","\typingparameter\c!strip","\typingparameter\c!range")}% + \dostoptagged \endofverbatimlines \csname#2\endcsname}} diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex index a0eaec3bf..cae797270 100644 --- a/tex/context/base/cont-new.tex +++ b/tex/context/base/cont-new.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2010.07.15 15:01} +\newcontextversion{2010.07.30 11:35} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 32bcfbe24..13e091ea8 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -167,6 +167,7 @@ \loadmarkfile{lxml-sor} \loadmarkfile{strc-ini} +\loadmarkfile{strc-tag} \loadmarkfile{strc-doc} \loadmarkfile{strc-mar} \loadmarkfile{strc-prc} @@ -328,6 +329,7 @@ \loadmarkfile{grph-trf} \loadmarkfile{grph-inc} \loadmarkfile{grph-fig} +\loadmarkfile{grph-epd} \loadmarkfile{pack-box} \loadmarkfile{pack-bar} diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex index 16f1f44e6..4abee1332 100644 --- a/tex/context/base/context.tex +++ b/tex/context/base/context.tex @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2010.07.15 15:01} +\edef\contextversion{2010.07.30 11:35} %D For those who want to use this: diff --git a/tex/context/base/core-mis.mkiv b/tex/context/base/core-mis.mkiv index e2bd28bd5..6e159532f 100644 --- a/tex/context/base/core-mis.mkiv +++ b/tex/context/base/core-mis.mkiv @@ -706,11 +706,13 @@ \ifnum\subsentencelevel=\plusone \dontleavehmode % was \leaveoutervmode \fi + \dostarttagged\t!subsentence\empty \symbol[\ifodd\subsentencelevel\c!leftsentence\else\c!leftsubsentence\fi]% }% \ignorespaces} \def\endofsubsentence % relax prevents space gobbling {\symbol[\ifodd\subsentencelevel\c!rightsentence\else\c!rightsubsentence\fi]% + \dostoptagged \global\advance\subsentencelevel\minusone \unskip \kern\subsentencesignal\relax @@ -741,6 +743,7 @@ \unexpanded\def\startsubsentence{\beginofsubsentence \prewordbreak\beginofsubsentencespacing} \unexpanded\def\stopsubsentence {\endofsubsentencespacing\prewordbreak\endofsubsentence} +\unexpanded\def\subsentence {\groupedcommand\startsubsentence\stopsubsentence} %D \defineXMLenvironment [subsentence] %D {|<|} @@ -885,6 +888,7 @@ \unexpanded\def\startdelimitedtext[#1]% {\bgroup \pushdelimitedtext{#1}% + \dostarttagged\t!delimitedblock\currentdelimitedtext \doifelse{\delimitedtextparameter\c!method}\s!font {\def\dostopdelimitedtext {\removeunwantedspaces\ignoredelimitedtext\c!right}% @@ -895,39 +899,6 @@ \doifinsetelse{\delimitedtextparameter\c!location}{\v!paragraph,\v!margin}% {\dosingleempty\dostartdelimitedtextpar}\dostartdelimitedtexttxt}} -% \def\dostartdelimitedtextpar[#1]% -% {\let\dostopdelimitedtext\dostopdelimitedtextpar -% \doifsomething{\delimitedtextparameter\c!spacebefore} -% {\blank[\delimitedtextparameter\c!spacebefore]}% -% \delimitedtextparameter\c!before -% % nicer: -% % \doadaptleftskip {\delimitedtextparameter\c!leftmargin}% -% % \doadaptrightskip{\delimitedtextparameter\c!rightmargin}% -% % backward compatible: -% \doifelsenothing{#1} -% {\endgraf -% \doadaptleftskip {\delimitedtextparameter\c!leftmargin}% -% \doadaptrightskip{\delimitedtextparameter\c!rightmargin}% -% \let\dodostopdelimitedtextpar\endgraf} -% {\startnarrower[#1]\let\dodostopdelimitedtextpar\stopnarrower}% -% % so far -% % \dochecknextindentation{\??ci\currentdelimitedtext}% AM: not here -% \dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color\empty -% \leftdelimitedtextmark -% \ignorespaces} - -% \def\dostopdelimitedtextpar -% {\removeunwantedspaces -% \removelastskip -% \rightdelimitedtextmark -% \dostopattributes -% \dodostopdelimitedtextpar -% \delimitedtextparameter\c!after -% \doifsomething{\delimitedtextparameter\c!spaceafter} -% {\blank[\delimitedtextparameter\c!spaceafter]}% -% \dochecknextindentation{\??ci\currentdelimitedtext}% AM: here -% \dorechecknextindentation}% AM: This was missing! - \def\dostartdelimitedtextpar[#1]% {\let\dostopdelimitedtext\dostopdelimitedtextpar \doifsomething{\delimitedtextparameter\c!spacebefore} @@ -978,6 +949,7 @@ \unexpanded\def\stopdelimitedtext {\dostopdelimitedtext + \dostoptagged \popdelimitedtext \egroup} @@ -1113,35 +1085,56 @@ \def\handlerightdelimitedtext#1% {\dohandlerightdelimitedtext{#1}\relax} +% \unexpanded\def\dodelimitedtextpar +% {\dohandleleftdelimitedtext\c!left\relax +% \groupedcommand +% \donothing +% {\dohandlerightdelimitedtext\c!right\removelastskip +% \popdelimitedtext}} + \unexpanded\def\dodelimitedtextpar - {\dohandleleftdelimitedtext\c!left\relax - \groupedcommand - \donothing + {\groupedcommand + {\dostarttagged\t!delimited\currentdelimitedtext % block? + \dohandleleftdelimitedtext\c!left\relax} {\dohandlerightdelimitedtext\c!right\removelastskip + \dostoptagged \popdelimitedtext}} \unexpanded\def\dodelimitedtexttxt {\doifelse{\delimitedtextparameter\c!style}\v!normal \doquoteddelimited\doattributeddelimited} +% \def\doquoteddelimited +% {\dohandleleftdelimitedtext\c!left\relax +% \groupedcommand +% \donothing +% {\dohandlerightdelimitedtext\c!right +% \removelastskip +% \popdelimitedtext}} + \def\doquoteddelimited - {\dohandleleftdelimitedtext\c!left\relax - \groupedcommand - \donothing + {\groupedcommand + {\dostarttagged\t!delimited\currentdelimitedtext + \dohandleleftdelimitedtext\c!left\relax} {\dohandlerightdelimitedtext\c!right \removelastskip + \dostoptagged \popdelimitedtext}} \def\doattributeddelimited {\groupedcommand - {\dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color} + {\dostarttagged\t!delimited\currentdelimitedtext + \dostartattributes{\??ci\currentdelimitedtext}\c!style\c!color} {\dostopattributes + \dostoptagged \popdelimitedtext}} \def\dofontdrivendelimited {\simplegroupedcommand - {\languageparameter{\c!left\currentdelimitedtext}} + {\dostarttagged\t!delimited\currentdelimitedtext + \languageparameter{\c!left\currentdelimitedtext}} {\languageparameter{\c!right\currentdelimitedtext}% + \dostoptagged \popdelimitedtext}} % testcase for nesting: diff --git a/tex/context/base/core-sys.mkiv b/tex/context/base/core-sys.mkiv index 649e5e65c..7b1f2825a 100644 --- a/tex/context/base/core-sys.mkiv +++ b/tex/context/base/core-sys.mkiv @@ -206,16 +206,20 @@ \setuvalue{#1}% {\groupedcommand {\getvalue{\??be#1\c!commands}% + \dostarttagged\t!construct{#1}% \dostartattributes{\??be#1}\c!style\c!color} {\dostopattributes + \dostoptagged \getvalue{\??be#1\c!inbetween}}}% \setvalue{\e!start#1}% {\getvalue{\??be#1\c!before}% \bgroup \getvalue{\??be#1\c!commands}% + \dostarttagged\t!construct{#1}% \dostartattributes{\??be#1}\c!style\c!color\empty}% \setvalue{\e!stop#1}% {\dostopattributes + \dostoptagged \egroup \getvalue{\??be#1\c!after}}} diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index 68efdcb0c..2a8f31364 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -72,8 +72,10 @@ local function initializer() if not r then r = math.random() math.setrandomseedi(r,"initialize") + report_jobcontrol("initializing randomizer with %s",r) else math.setrandomseedi(r,"previous run") + report_jobcontrol("resuming randomizer with %s",r) end jobvariables.tobesaved.randomseed = r for cs, value in next, jobvariables.collected do diff --git a/tex/context/base/core-uti.mkiv b/tex/context/base/core-uti.mkiv index 352093ff5..d16d33ce0 100644 --- a/tex/context/base/core-uti.mkiv +++ b/tex/context/base/core-uti.mkiv @@ -26,10 +26,15 @@ job.comment("format: \contextformat") job.comment("stamp: \contextversion") job.comment("escape: \!!bs\space...\space\!!es") - job.initialize("\jobname.tuc","\jobname.tua") }% \to \everystarttext +\appendtoks + \ctxlua { + job.initialize("\jobname.tuc","\jobname.tua") + }% +\to \everyjob + \def\notuccompression{\ctxlua{job.pack=false}} %D Some styles might use these use these commands: diff --git a/tex/context/base/data-kps.lua b/tex/context/base/data-kps.lua deleted file mode 100644 index 09d502409..000000000 --- a/tex/context/base/data-kps.lua +++ /dev/null @@ -1,101 +0,0 @@ -if not modules then modules = { } end modules ['luat-kps'] = { - version = 1.001, - comment = "companion to luatools.lua", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - ---[[ldx-- -<p>This file is used when we want the input handlers to behave like -<type>kpsewhich</type>. What to do with the following:</p> - -<typing> -{$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c} -$SELFAUTOLOC : /usr/tex/bin/platform -$SELFAUTODIR : /usr/tex/bin -$SELFAUTOPARENT : /usr/tex -</typing> - -<p>How about just forgetting about them?</p> ---ldx]]-- - -local suffixes = resolvers.suffixes -local formats = resolvers.formats - -suffixes['gf'] = { '<resolution>gf' } -suffixes['pk'] = { '<resolution>pk' } -suffixes['base'] = { 'base' } -suffixes['bib'] = { 'bib' } -suffixes['bst'] = { 'bst' } -suffixes['cnf'] = { 'cnf' } -suffixes['mem'] = { 'mem' } -suffixes['mf'] = { 'mf' } -suffixes['mfpool'] = { 'pool' } -suffixes['mft'] = { 'mft' } -suffixes['mppool'] = { 'pool' } -suffixes['graphic/figure'] = { 'eps', 'epsi' } -suffixes['texpool'] = { 'pool' } -suffixes['PostScript header'] = { 'pro' } -suffixes['ist'] = { 'ist' } -suffixes['web'] = { 'web', 'ch' } -suffixes['cweb'] = { 'w', 'web', 'ch' } -suffixes['cmap files'] = { 'cmap' } -suffixes['lig files'] = { 'lig' } -suffixes['bitmap font'] = { } -suffixes['MetaPost support'] = { } -suffixes['TeX system documentation'] = { } -suffixes['TeX system sources'] = { } -suffixes['dvips config'] = { } -suffixes['type42 fonts'] = { } -suffixes['web2c files'] = { } -suffixes['other text files'] = { } -suffixes['other binary files'] = { } -suffixes['opentype fonts'] = { 'otf' } - -suffixes['fmt'] = { 'fmt' } -suffixes['texmfscripts'] = { 'rb','lua','py','pl' } - -suffixes['pdftex config'] = { } -suffixes['Troff fonts'] = { } - -suffixes['ls-R'] = { } - ---[[ldx-- -<p>If you wondered abou tsome of the previous mappings, how about -the next bunch:</p> ---ldx]]-- - -formats['bib'] = '' -formats['bst'] = '' -formats['mft'] = '' -formats['ist'] = '' -formats['web'] = '' -formats['cweb'] = '' -formats['MetaPost support'] = '' -formats['TeX system documentation'] = '' -formats['TeX system sources'] = '' -formats['Troff fonts'] = '' -formats['dvips config'] = '' -formats['graphic/figure'] = '' -formats['ls-R'] = '' -formats['other text files'] = '' -formats['other binary files'] = '' - -formats['gf'] = '' -formats['pk'] = '' -formats['base'] = 'MFBASES' -formats['cnf'] = '' -formats['mem'] = 'MPMEMS' -formats['mf'] = 'MFINPUTS' -formats['mfpool'] = 'MFPOOL' -formats['mppool'] = 'MPPOOL' -formats['texpool'] = 'TEXPOOL' -formats['PostScript header'] = 'TEXPSHEADERS' -formats['cmap files'] = 'CMAPFONTS' -formats['type42 fonts'] = 'T42FONTS' -formats['web2c files'] = 'WEB2C' -formats['pdftex config'] = 'PDFTEXCONFIG' -formats['texmfscripts'] = 'TEXMFSCRIPTS' -formats['bitmap font'] = '' -formats['lig files'] = 'LIGFONTS' diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 85577f4a7..5e4d598f1 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -336,7 +336,8 @@ local n = 0 -- we can also move rscale to here (more consistent) -function define.command_2(global,cs,str,size,classfeatures,fontfeatures,classfallbacks,fontfallbacks,mathsize,textsize,relativeid) +function define.command_2(global,cs,str,size,classfeatures,fontfeatures,classfallbacks,fontfallbacks, + mathsize,textsize,relativeid,classgoodies,goodies) if trace_defining then report_define("memory usage before: %s",statistics.memused()) end @@ -355,6 +356,7 @@ function define.command_2(global,cs,str,size,classfeatures,fontfeatures,classfal specification.sub = (sub and sub ~= "" and sub) or specification.sub specification.mathsize = mathsize specification.textsize = textsize + specification.goodies = goodies if detail and detail ~= "" then specification.method, specification.detail = method or "*", detail elseif specification.detail and specification.detail ~= "" then @@ -375,7 +377,8 @@ function define.command_2(global,cs,str,size,classfeatures,fontfeatures,classfal texsetcount("global","lastfontid",-1) elseif type(tfmdata) == "number" then if trace_defining then - report_define("reusing %s with id %s as \\%s (features: %s/%s, fallbacks: %s/%s)",name,tfmdata,cs,classfeatures,fontfeatures,classfallbacks,fontfallbacks) + report_define("reusing %s with id %s as \\%s (features: %s/%s, fallbacks: %s/%s, goodies: %s/%s)", + name,tfmdata,cs,classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies) end tex.definefont(global,cs,tfmdata) -- resolved (when designsize is used): diff --git a/tex/context/base/font-def.lua b/tex/context/base/font-def.lua index a35c4856f..ea5b69a6b 100644 --- a/tex/context/base/font-def.lua +++ b/tex/context/base/font-def.lua @@ -290,6 +290,15 @@ function define.resolve(specification) else specification.forced = specification.forced end + -- for the moment here (goodies eset outside features) + local goodies = specification.goodies + if goodies and goodies ~= "" then + local normalgoodies = specification.features.normal.goodies + if not normalgoodies or normalgoodies == "" then + specification.features.normal.goodies = goodies + end + end + -- specification.hash = lower(specification.name .. ' @ ' .. tfm.hash_features(specification)) if specification.sub and specification.sub ~= "" then specification.hash = specification.sub .. ' @ ' .. specification.hash diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua index e17a47ca2..f0d52974a 100644 --- a/tex/context/base/font-gds.lua +++ b/tex/context/base/font-gds.lua @@ -297,3 +297,4 @@ fonts.goodies.register("mathematics", initialize) -- tex/fonts/data/foundry/collection -- -- see lfg files in distribution + diff --git a/tex/context/base/font-ini.lua b/tex/context/base/font-ini.lua index 296af06e1..94522130c 100644 --- a/tex/context/base/font-ini.lua +++ b/tex/context/base/font-ini.lua @@ -26,6 +26,8 @@ fontloader.totable = fontloader.to_table fonts = fonts or { } +-- we will also have des and fam hashes + fonts.ids = fonts.ids or { } fonts.identifiers = fonts.ids -- aka fontdata fonts.chr = fonts.chr or { } fonts.characters = fonts.chr -- aka chardata fonts.qua = fonts.qua or { } fonts.quads = fonts.qua -- aka quaddata diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv index 2df094330..e08f5bdd9 100644 --- a/tex/context/base/font-ini.mkiv +++ b/tex/context/base/font-ini.mkiv @@ -74,6 +74,7 @@ \registerctxluafile{font-ota}{1.001} % otf analyzers \registerctxluafile{font-otp}{1.001} % otf pack \registerctxluafile{font-otc}{1.001} % otf context +\registerctxluafile{font-oth}{1.001} % otf helpers \registerctxluafile{font-vf} {1.001} \registerctxluafile{font-def}{1.001} \registerctxluafile{font-ctx}{1.001} @@ -734,7 +735,9 @@ "\@@fontfallbacks", 0\currentmathsize, \number\dimexpr\textface\relax, - "\relativefontid" % experiment + "\relativefontid", % experiment + "\@@fontclassgoodies", % experiment (not yet used) + "\@@fontgoodies" % experiment )}% \edef\somefontspec{at \somefontsize}% we need the resolved designsize (for fallbacks) \expandafter\let\expandafter\lastrawfontcall\csname#2\endcsname @@ -742,7 +745,8 @@ \def\updatefontclassparameters {\edef\@@fontclassfeatures {\ifcsname\fontclass\fontstyle\s!features \endcsname\csname\fontclass\fontstyle\s!features \endcsname\fi}% - \edef\@@fontclassfallbacks{\ifcsname\fontclass\fontstyle\s!fallbacks\endcsname\csname\fontclass\fontstyle\s!fallbacks\endcsname\fi}} + \edef\@@fontclassfallbacks{\ifcsname\fontclass\fontstyle\s!fallbacks\endcsname\csname\fontclass\fontstyle\s!fallbacks\endcsname\fi}% + \edef\@@fontclassgoodies {\ifcsname\fontclass\fontstyle\s!goodies \endcsname\csname\fontclass\fontstyle\s!goodies \endcsname\fi}} % resolve @@ -760,6 +764,13 @@ \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksyes\csname\??ff #1\endcsname\else \let \@@fontfallbacks \empty \fi\fi\fi\fi} +\def\@@thegoodiesyes#1% + {\ifcsname\??ff\fontclass#1\s!goodies \endcsname\@EA\let\@EA\@@fontgoodies \csname\??ff\fontclass#1\s!goodies \endcsname\else + \ifcsname\??ff #1\s!goodies \endcsname\@EA\let\@EA\@@fontgoodies \csname\??ff #1\s!goodies \endcsname\else + \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thegoodiesyes \csname\??ff\fontclass #1\endcsname\else + \ifcsname\??ff #1\endcsname\@EA \@@thegoodiesyes \csname\??ff #1\endcsname\else + \let \@@fontgoodies \empty \fi\fi\fi\fi} + \def\@@thefeaturesnop#1% {\ifcsname\??ff#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff#1\s!features \endcsname\else \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesnop \csname\??ff #1\endcsname\else @@ -770,13 +781,20 @@ \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksnop\csname\??ff #1\endcsname\else \let \@@fontfallbacks \empty \fi\fi} +\def\@@thegoodiesnop#1% + {\ifcsname\??ff#1\s!goodies \endcsname\@EA\let\@EA\@@fontgoodies \csname\??ff#1\s!goodies \endcsname\else + \ifcsname\??ff #1\endcsname\@EA \@@thegoodiesnop \csname\??ff #1\endcsname\else + \let \@@fontgoodies \empty \fi\fi} + \def\updatefontparametersyes {\@@thefeaturesyes \somefontname - \@@thefallbacksyes\somefontname} + \@@thefallbacksyes\somefontname + \@@thegoodiesyes \somefontname} \def\updatefontparametersnop {\@@thefeaturesnop \somefontname - \@@thefallbacksnop\somefontname} + \@@thefallbacksnop\somefontname + \@@thegoodiesnop \somefontname} \def\updatefontparameters {\ifx\fontclass\empty\updatefontparametersnop\else\updatefontparametersyes\fi} @@ -786,6 +804,8 @@ \let\@@fontfallbacks\empty \let\@@fontfeatures \empty +\let\@@fontgoodies \empty + \let\@@hyphenchar \empty % todo, will go to encoding %D This brings down maps processing from 466 to 309 seconds @@ -972,19 +992,23 @@ \def\nonodefinefontsynonymnop {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined - \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined} + \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined + \@EA\let\csname\??ff\@@fontname\s!goodies \endcsname\undefined} \def\nonodefinefontsynonymyes {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined - \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined} + \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined + \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!goodies \endcsname\undefined} \def\dodododefinefontsynonymnop {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\@@ff@@features - \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks} + \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks + \@EA\let\csname\??ff\@@fontname\s!goodies \endcsname\@@ff@@goodies} \def\dodododefinefontsynonymyes {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features - \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks} + \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks + \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!goodies \endcsname\@@ff@@goodies} \let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater @@ -2139,10 +2163,11 @@ \trycurrentfontclass{#1}% \fi\fi\fi} -\def\savefontclassparameters#1#2#3#4% #1=rm|ss|.. rscale features fallbacks +\def\savefontclassparameters#1#2#3#4#5% #1=rm|ss|.. rscale features fallbacks goodies {\setxvalue{\fontclass#1\s!rscale }{#2}% \setxvalue{\fontclass#1\s!features }{#3}% - \setxvalue{\fontclass#1\s!fallbacks}{#4}} + \setxvalue{\fontclass#1\s!fallbacks}{#4}% + \setxvalue{\fontclass#1\s!goodies }{#5}} \settrue\autotypescripts @@ -3756,24 +3781,43 @@ \definefontsize[\c!a] \definefontsize[\c!b] \definefontsize[\c!c] \definefontsize[\c!d] -\definealternativestyle [\v!mediaeval] [\os] [] -\definealternativestyle [\v!normal] [\tf] [] -\definealternativestyle [\v!bold] [\bf] [] -\definealternativestyle [\v!type] [\tt] [] -\definealternativestyle [\v!mono] [\tt] [] -\definealternativestyle [\v!slanted] [\sl] [] -\definealternativestyle [\v!italic] [\it] [] -\definealternativestyle [\v!boldslanted,\v!slantedbold] [\bs] [] -\definealternativestyle [\v!bolditalic,\v!italicbold] [\bi] [] -\definealternativestyle [\v!small,\v!smallnormal] [\tfx] [] -\definealternativestyle [\v!smallbold] [\bfx] [] -\definealternativestyle [\v!smalltype] [\ttx] [] -\definealternativestyle [\v!smallslanted] [\slx] [] -\definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\bsx] [] -\definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\bix] [] - -\definealternativestyle [\v!sans,\v!sansserif] [\ss] [] -\definealternativestyle [\v!sansbold] [\ss\bf] [] +\definealternativestyle [\v!mediaeval] [\os] [] +\definealternativestyle [\v!normal] [\tf] [] +\definealternativestyle [\v!bold] [\bf] [] +\definealternativestyle [\v!type] [\tt] [] +\definealternativestyle [\v!mono] [\tt] [] +\definealternativestyle [\v!slanted] [\sl] [] +\definealternativestyle [\v!italic] [\it] [] +\definealternativestyle [\v!boldslanted,\v!slantedbold] [\bs] [] +\definealternativestyle [\v!bolditalic,\v!italicbold] [\bi] [] + +% \definealternativestyle [\v!small,\v!smallnormal] [\tfx] [] +% \definealternativestyle [\v!smallbold] [\bfx] [] +% \definealternativestyle [\v!smalltype] [\ttx] [] +% \definealternativestyle [\v!smallslanted] [\slx] [] +% \definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\bsx] [] +% \definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\bix] [] + +\definealternativestyle [\v!small,\v!smallnormal] [\setsmallbodyfont\tf] [] +\definealternativestyle [\v!smallbold] [\setsmallbodyfont\bf] [] +\definealternativestyle [\v!smalltype] [\setsmallbodyfont\tt] [] +\definealternativestyle [\v!smallslanted] [\setsmallbodyfont\sl] [] +\definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\setsmallbodyfont\bs] [] +\definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\setsmallbodyfont\bi] [] + +\definealternativestyle [\v!bigger] [\setbigbodyfont \tf] [] +\definealternativestyle [\v!smaller] [\setsmallbodyfont\tf] [] + +\definealternativestyle [\v!sans,\v!sansserif] [\ss] [] +\definealternativestyle [\v!sansbold] [\ss\bf] [] + +%D We can go on and on and on: +%D +%D \starttyping +%D \setupbodyfontenvironment[default][p=0.8,q=0.6] +%D \definefontsize[p] +%D \definefontsize[q] +%D \stoptyping %D Slow but handy: diff --git a/tex/context/base/font-otb.lua b/tex/context/base/font-otb.lua index 65933b240..f76e6686c 100644 --- a/tex/context/base/font-otb.lua +++ b/tex/context/base/font-otb.lua @@ -168,7 +168,7 @@ local function prepare_base_substitutions(tfmdata,kind,value) -- we can share so if pv then local upv = unicodes[pv] if upv then - if type(upv) == "table" then + if type(upv) == "table" then -- zero change that table upv = upv[1] end if characters[upv] then @@ -196,7 +196,7 @@ local function prepare_base_substitutions(tfmdata,kind,value) -- we can share so if pc then local upc = unicodes[pc] if upc then - if type(upc) == "table" then + if type(upc) == "table" then -- zero change that table upc = upc[1] end if characters[upc] then diff --git a/tex/context/base/font-oth.lua b/tex/context/base/font-oth.lua new file mode 100644 index 000000000..62ff41c40 --- /dev/null +++ b/tex/context/base/font-oth.lua @@ -0,0 +1,45 @@ +if not modules then modules = { } end modules ['font-oth'] = { + version = 1.001, + comment = "companion to font-oth.lua (helpers)", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local lpegmatch = lpeg.match +local splitter = lpeg.Ct(lpeg.splitat(" ")) + +local collect_lookups = fonts.otf.collect_lookups + +-- For the moment there is no need to cache this but this might +-- happen when I get the feeling that there is a performance +-- penalty involved. + +function fonts.otf.get_alternate(tfmdata,k,kind,value) + if value then + local shared = tfmdata.shared + local otfdata = shared and shared.otfdata + if otfdata then + local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language) + if validlookups then + local lookups = tfmdata.descriptions[k].slookups -- we assume only slookups (we can always extend) + if lookups then + local unicodes = tfmdata.unicodes -- names to unicodes + local choice = tonumber(value) + for l=1,#lookuplist do + local lookup = lookuplist[l] + local p = lookups[lookup] + if p then + local pc = p[2] -- p.components + if pc then + pc = lpegmatch(splitter,pc) + return unicodes[pc[choice] or pc[#pc]] + end + end + end + end + end + end + end + return k +end diff --git a/tex/context/base/font-pat.lua b/tex/context/base/font-pat.lua index b6531abb9..9f679f663 100644 --- a/tex/context/base/font-pat.lua +++ b/tex/context/base/font-pat.lua @@ -108,19 +108,19 @@ local function patch_domh(data,filename,threshold) m.DisplayOperatorMinHeight = threshold end end - if tex.luatexversion < 48 then - for _, g in next, data.glyphs do - local name = g.name - if find(name,"^integral$") or find(name,"^integral%.vsize") then - local width, italic = g.width or 0, g.italic_correction or 0 - local newwidth = width - italic - if trace_loading then - report_otf("patching width of %s: %s (width) - %s (italic) = %s",name,width,italic,newwidth) - end - g.width = newwidth - end - end - end +-- if tex.luatexversion < 48 then +-- for _, g in next, data.glyphs do +-- local name = g.name +-- if find(name,"^integral$") or find(name,"^integral%.vsize") then +-- local width, italic = g.width or 0, g.italic_correction or 0 +-- local newwidth = width - italic +-- if trace_loading then +-- report_otf("patching width of %s: %s (width) - %s (italic) = %s",name,width,italic,newwidth) +-- end +-- g.width = newwidth +-- end +-- end +-- end end patches["cambria"] = function(data,filename) patch_domh(data,filename,2800) end diff --git a/tex/context/base/grph-epd.lua b/tex/context/base/grph-epd.lua new file mode 100644 index 000000000..c687e40a8 --- /dev/null +++ b/tex/context/base/grph-epd.lua @@ -0,0 +1,23 @@ +if not modules then modules = { } end modules ['grph-epd'] = { + version = 1.001, + comment = "companion to grph-epd.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local variables = interfaces.variables + +-- todo: page, name, file, url + +function figures.mergegoodies(optionlist) + local options = aux.settings_to_hash(optionlist) + local all = options[variables.all] or options[variables.yes] + if all or options[variables.reference] then + backends.codeinjections.mergereferences() + end + if all or options[variables.layer] then + backends.codeinjections.mergelayers() + end + +end diff --git a/tex/context/base/grph-epd.mkiv b/tex/context/base/grph-epd.mkiv new file mode 100644 index 000000000..b23631b79 --- /dev/null +++ b/tex/context/base/grph-epd.mkiv @@ -0,0 +1,58 @@ +%D \module +%D [ file=grph-epd, +%D version=2010.07.29, +%D title=\CONTEXT\ Graphic Macros, +%D subtitle=Merging Goodies, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 Graphic Macros / Merging Coodies} + +\unprotect + +\registerctxluafile{lpdf-epd}{1.001} +\registerctxluafile{lpdf-epa}{1.001} +\registerctxluafile{grph-epd}{1.001} + +\def\figurereference {\ctxlua{figures.tprint("status","reference")}} + +\defineoverlay[epdf-overlay][\directsetup{epdf-overlay}] + +\startsetups epdf-overlay + \ctxlua{figures.mergegoodies("\@@efinteraction")}% + \reference[\figurereference]{}% todo: dest area +\stopsetups + +\def\doaddpdffiguregoodies + {\global\setbox\foundexternalfigure\vbox\bgroup + \framed[\c!offset=\v!overlay,\c!background={\v!foreground,epdf-overlay}]{\box\foundexternalfigure}% + \egroup} + +\appendtoks + \iflocation\doif\figurefiletype{pdf}{\doifnot\@@efinteraction\v!none\doaddpdffiguregoodies}\fi +\to \externalfigurepostprocessors + +\protect \endinput + +% /Properties << /xxxx 22 0 R >> +% 21 0 obj << /Type /OCG /Name (xxxx) >> endobj +% 22 0 obj << /OCGs [ 21 0 R ] /Type /OCMD >> endobj + +% \def\setepdflayer#1#2#3#4#5#6% x y w h (in bp) 0/1 destination +% {\setlayer +% [epdflinks] +% [\c!x=#1bp,\c!y=#1\s!bp,\c!preset=\v!leftbottom] +% {\button +% [\c!width=#3\s!bp,\c!height=#4\s!bp,\c!offset=\v!overlay,\c!frame=\ifnum#5=1 on\else\v!off]% +% {}[#6]}} + +% \def\setepdflayer#1#2#3#4#5#6% x y w h (in bp) 0/1 destination +% {\setlayer +% [epdflinks] +% [\c!x=#1bp,\c!y=#1\s!bp,\c!preset=\v!leftbottom] +% {\gotowdhtbox{#3\s!bp}{#4\s!bp}[#6]}} diff --git a/tex/context/base/grph-fig.mkiv b/tex/context/base/grph-fig.mkiv index e10dc0a32..0cf9bea2b 100644 --- a/tex/context/base/grph-fig.mkiv +++ b/tex/context/base/grph-fig.mkiv @@ -41,11 +41,14 @@ \def\dodoplaceexternalfigure[#1][#2][#3][#4][#5]% {\bgroup +\dostarttagged\t!image\empty \pushmacro\textunderscore \edef\textunderscore{\string_}% brrr, temp hack, still needed? \calculateexternalfigure[][#1][#2][#3][#4][#5]% [] is dummy dwcomp \popmacro\textunderscore +\global\setbox\foundexternalfigure\naturalvbox attr \imageattribute 2 {\box\foundexternalfigure}% \box\foundexternalfigure +\dostoptagged \egroup} \def\externalfigurereplacement#1#2#3% @@ -576,6 +579,7 @@ [\c!option=, \c!object=\v!yes, % we only check for no \c!reset=\v!no, + \c!interaction=\v!none, \c!maxwidth=\@@efwidth, \c!maxheight=\@@efheight, \c!bodyfont=\bodyfontsize, diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index c933d6a5f..6fa611694 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -35,6 +35,8 @@ The TeX-Lua mix is suboptimal. This has to do with the fact that we cannot run TeX code from within Lua. Some more functionality will move to Lua. ]]-- +-- commands.writestatus -> report + local format, lower, find, match, gsub, gmatch = string.format, string.lower, string.find, string.match, string.gsub, string.gmatch local texsprint, texbox = tex.sprint, tex.box local contains = table.contains @@ -227,40 +229,45 @@ do local figuredata = { } local callstack = { } - function figures.new() + function figures.new() -- we could use metatables status -> used -> request but it needs testing + local request = { + name = false, + label = false, + format = false, + page = false, + width = false, + height = false, + preview = false, + ["repeat"] = false, + controls = false, + display = false, + conversion = false, + cache = false, + prefix = false, + size = false, + } + local used = { + fullname = false, + format = false, + name = false, + path = false, + suffix = false, + width = false, + height = false, + } + local status = { + status = 0, + converted = false, + cached = false, + fullname = false, + format = false, + } + -- setmetatable(status, { __index = used }) + -- setmetatable(used, { __index = request }) figuredata = { - request = { - name = false, - label = false, - format = false, - page = false, - width = false, - height = false, - preview = false, - ["repeat"] = false, - controls = false, - display = false, - conversion = false, - cache = false, - prefix = false, - size = false, - }, - used = { - fullname = false, - format = false, - name = false, - path = false, - suffix = false, - width = false, - height = false, - }, - status = { - status = 0, - converted = false, - cached = false, - fullname = false, - format = false, - }, + request = request, + used = used, + status = status, } return figuredata end @@ -649,13 +656,13 @@ function figures.identifiers.default(data) local dr, du, ds = data.request, data.used, data.status local l = locate(dr) local foundname = l.foundname - local fullname = l.fullname or foundname + local fullname = l.fullname or foundname if fullname then - du.format = l.format or false + du.format = l.format or false du.fullname = fullname -- can be cached ds.fullname = foundname -- original - ds.format = l.format - ds.status = (l.found and 10) or 0 + ds.format = l.format + ds.status = (l.found and 10) or 0 end return data end @@ -699,6 +706,7 @@ function figures.done(data) ds.height = box.height ds.xscale = ds.width /(du.width or 1) ds.yscale = ds.height/(du.height or 1) + ds.page = ds.page or du.page or dr.page -- sort of redundant but can be limited --~ print(table.serialize(figures.current())) return data end diff --git a/tex/context/base/grph-inc.mkiv b/tex/context/base/grph-inc.mkiv index 16ee1097a..639ca7d75 100644 --- a/tex/context/base/grph-inc.mkiv +++ b/tex/context/base/grph-inc.mkiv @@ -77,6 +77,7 @@ \def\figurexscale {\ctxlua{figures.tprint("status","xscale",1)}} \def\figureyscale {\ctxlua{figures.tprint("status","yscale",1)}} +\def\figuresize {\ctxlua{figures.tprint("request","size")}} \def\figurelabel {\ctxlua{figures.tprint("request","label")}} \def\figurefileoriginal {\ctxlua{figures.tprint("request","name")}} \def\figurefilepage {\ctxlua{figures.tprint("request","page",1)}} @@ -151,6 +152,8 @@ % \let\@@efforegroundcolor\empty % + \let\@@efinteraction\@@exinteraction + % \let\@@efhfactor \empty \let\@@efwfactor \empty \let\@@effactor \empty diff --git a/tex/context/base/lang-ini.mkiv b/tex/context/base/lang-ini.mkiv index 24b0ec6f4..37f3fdb10 100644 --- a/tex/context/base/lang-ini.mkiv +++ b/tex/context/base/lang-ini.mkiv @@ -220,12 +220,17 @@ \unexpanded\def\setuplanguage {\dodoubleempty\dosetuplanguage} +\ifdefined\docomplexlanguage \else \let\docomplexlanguage\relax \fi + \def\dosetuplanguage[#1][#2]% {\ifsecondargument + \pushmacro\currentlanguage % can be default \edef\currentsetuplanguage{\reallanguagetag{#1}}% \getparameters[\??la\currentsetuplanguage][#2]% \the\everysetuplanguage - \doif\currentsetuplanguage\currentlanguage\docomplexlanguage + \popmacro\currentlanguage + %\doif\currentsetuplanguage\currentlanguage we can have influenced inheritance (default) + \docomplexlanguage \else \let\currentsetuplanguage\currentlanguage \getparameters[\??la\currentsetuplanguage][#1]% @@ -273,6 +278,12 @@ \c!rightcompoundhyphen=\compoundhyphen, \c!leftcompoundhyphen=] +% to be tested: +% +% \setuplanguage +% [\s!default] +% [\c!righthyphenchar="AD] + %D The values \type {leftsentence} and \type %D {rightsentence} can be (and are) used to implement %D automatic subsentence boundary glyphs, like in {\fr diff --git a/tex/context/base/lang-lab.mkiv b/tex/context/base/lang-lab.mkiv index 42f2db8ff..545a64455 100644 --- a/tex/context/base/lang-lab.mkiv +++ b/tex/context/base/lang-lab.mkiv @@ -41,14 +41,15 @@ \let\handletextprefix\relax -\newconditional\protecttextprefixes +\let\protecttextprefixes\zerocount \let\currenttextprefixtag \s!unknown \let\currenttextprefixclass\s!unknown -\unexpanded\def\setupheadtext {\setfalse\protecttextprefixes\let\currenttextprefixclass\??mh\dodoubleempty\dosetupsometextprefix} -\unexpanded\def\setuplabeltext {\setfalse\protecttextprefixes\let\currenttextprefixclass\??ml\dodoubleempty\dosetupsometextprefix} -\unexpanded\def\setupmathlabeltext{\setfalse\protecttextprefixes\let\currenttextprefixclass\??mm\dodoubleempty\dosetupsometextprefix} +\unexpanded\def\setupheadtext {\let\protecttextprefixes\zerocount\let\currenttextprefixclass\??mh\dodoubleempty\dosetupsometextprefix} +\unexpanded\def\setuplabeltext {\let\protecttextprefixes\zerocount\let\currenttextprefixclass\??ml\dodoubleempty\dosetupsometextprefix} +\unexpanded\def\setupmathlabeltext{\let\protecttextprefixes\zerocount\let\currenttextprefixclass\??mm\dodoubleempty\dosetupsometextprefix} +\unexpanded\def\setuptaglabeltext {\let\protecttextprefixes\plustwo \let\currenttextprefixclass\??me\dodoubleempty\dosetupsometextprefix} \def\dosetupsometextprefix[#1][#2]% {\ifsecondargument @@ -66,14 +67,19 @@ {\doassignsometextprefix{#1}[#2,,]} \def\doassignsometextprefix#1% - {\ifconditional\protecttextprefixes + {\ifcase\protecttextprefixes + % no checking + \expandafter\doassignsometextprefixyes + \or + % checking \ifcsname\currenttextprefixclass\currenttextprefixtag#1\endcsname \expandafter\expandafter\expandafter\doassignsometextprefixnop \else \expandafter\expandafter\expandafter\doassignsometextprefixyes \fi - \else - \expandafter\doassignsometextprefixyes + \or + % simple assignment (a bit overkill but it fits in the whole) + \expandafter\doassignsometextprefixdumb \fi{#1}} \ifdefined\Word\else \let\Word\relax \fi @@ -92,12 +98,15 @@ \expandafter\def\csname\currenttextprefixclass\currenttextprefixtag#1\endcsname{{#2}\empty}% \fi \else - \expandafter\def\csname\currenttextprefixclass\currenttextprefixtag#1\endcsname{{#2}{#3}}% + \expandafter\def\csname\currenttextprefixclass\currenttextprefixtag#1\endcsname{{#2}{#3}}% \fi} \def\doassignsometextprefixnop#1[#2]% {} +\def\doassignsometextprefixdumb#1[#2,#3]% + {\expandafter\def\csname\currenttextprefixclass\currenttextprefixtag#1\endcsname{#2}} + %D By changing the meaning of \type {\handletextprefix} we %D can filter the left and right labeltext as well as convert %D labels to uppercase. @@ -128,6 +137,7 @@ \def\labellanguage {\reallanguagetag{\defaultlanguage\currentmainlanguage}} \def\headlanguage {\reallanguagetag{\defaultlanguage\currentmainlanguage}} \def\mathlabellanguage{\reallanguagetag{\defaultlanguage\currentmainlanguage}} +\def\taglabellanguage {\reallanguagetag{\defaultlanguage\currentmainlanguage}} \appendtoks \let\labellanguage\currentlanguage \to \everycurrentdate @@ -135,7 +145,8 @@ \def\dogetupsomelabeltext {\dodogetupsomelabeltext \labellanguage } % second argument is textlabel \def\dogetupsomeheadtext {\dodogetupsomeheadtext \headlanguage } % second argument is headlabel -\def\dogetupsomemathlabeltext{\dodogetupsomemathlabeltext\mathlabellanguage } % second argument is headlabel +\def\dogetupsomemathlabeltext{\dodogetupsomemathlabeltext\mathlabellanguage } +\def\dogetupsometaglabeltext {\dodogetupsometaglabeltext \taglabellanguage } \def\dodogetupsomelabeltext#1#2% {\ifcsname\??ml#1#2\endcsname @@ -176,6 +187,19 @@ \let\thetextprefix\dummytextprefix \fi\fi\fi\fi} +\def\dodogetupsometaglabeltext#1#2% special + {\ifcsname\??me#1#2\endcsname + \csname\??me#1#2\endcsname + \else\ifcsname\??la\mathlabellanguage\s!default\endcsname + \expandafter\dodogetupsomemathlabeltext\csname\??la\mathlabellanguage\s!default\endcsname{#2}% + \else\ifcsname\??me#2\endcsname + \csname\??me#2\endcsname + \else\ifcsname\??me\s!en#2\endcsname + \csname\??me\s!en#2\endcsname + \else + #2% + \fi\fi\fi\fi} + % The WORD variants are a bit inefficient when #1/#2 are empty but they are % seldom used (one can better set the style). @@ -224,9 +248,9 @@ %D head and label texts without replacing predefined ones. %D These are internal macros. -\def\presetheadtext {\settrue\protecttextprefixes\let\currenttextprefixclass\??mh\dodoubleempty\dosetupsometextprefix} -\def\presetlabeltext {\settrue\protecttextprefixes\let\currenttextprefixclass\??ml\dodoubleempty\dosetupsometextprefix} -\def\presetmathlabeltext{\settrue\protecttextprefixes\let\currenttextprefixclass\??mm\dodoubleempty\dosetupsometextprefix} +\def\presetheadtext {\let\protecttextprefixes\plusone\let\currenttextprefixclass\??mh\dodoubleempty\dosetupsometextprefix} +\def\presetlabeltext {\let\protecttextprefixes\plusone\let\currenttextprefixclass\??ml\dodoubleempty\dosetupsometextprefix} +\def\presetmathlabeltext{\let\protecttextprefixes\plusone\let\currenttextprefixclass\??mm\dodoubleempty\dosetupsometextprefix} %D \macros %D {translate} diff --git a/tex/context/base/lang-mis.mkiv b/tex/context/base/lang-mis.mkiv index 0df45877b..11374e8b5 100644 --- a/tex/context/base/lang-mis.mkiv +++ b/tex/context/base/lang-mis.mkiv @@ -277,7 +277,7 @@ \let\domathmodediscretionary\handlemathmodediscretionary -\def\dotextmodediscretionary#1% +\def\dotextmodediscretionary#1% grouped ! {\bgroup \let\nextnextnext\egroup \def\next##1#1% diff --git a/tex/context/base/lang-sla.tex b/tex/context/base/lang-sla.tex index 45a92b289..7892123bb 100644 --- a/tex/context/base/lang-sla.tex +++ b/tex/context/base/lang-sla.tex @@ -121,7 +121,7 @@ \c!rightquote=\upperrightsingleninequote, \c!leftquotation=\lowerleftdoubleninequote, \c!rightquotation=\upperrightdoubleninequote, - \c!date={\v!day,\ ,\v!month,\ ,\v!year}, + \c!date={\v!day,{.},\ ,\v!month,\ ,\v!year}, \s!mapping=ec, \s!encoding=ec] diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua index f6392fd37..89ccb2235 100644 --- a/tex/context/base/lpdf-ano.lua +++ b/tex/context/base/lpdf-ano.lua @@ -35,17 +35,17 @@ local specials = jobreferences.specials local handlers = jobreferences.handlers local executers = jobreferences.executers -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfunicode = lpdf.unicode -local pdfconstant = lpdf.constant -local pdfflushobject = lpdf.flushobject -local pdfreserveobject = lpdf.reserveobject -local pdfannotation = nodes.pdfannotation -local pdfdestination = nodes.pdfdestination - -local pdfpagereference = tex.pdfpageref +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfconstant = lpdf.constant +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject +local pdfpagereference = lpdf.pagereference + +local pdfannotation_node = nodes.pdfannotation +local pdfdestination_node = nodes.pdfdestination local pdf_uri = pdfconstant("URI") local pdf_gotor = pdfconstant("GoToR") @@ -60,16 +60,18 @@ local pdf_border = pdfarray { 0, 0, 0 } local cache = { } local function pagedest(n) - local pd = cache[n] - if not pd then - local a = pdfarray { - pdfreference(pdfpagereference(n)), - pdfconstant("Fit") - } - pd = pdfreference(pdfflushobject(a)) - cache[n] = pd + if n > 0 then + local pd = cache[n] + if not pd then + local a = pdfarray { + pdfreference(pdfpagereference(n)), + pdfconstant("Fit") + } + pd = pdfreference(pdfflushobject(a)) + cache[n] = pd + end + return pd end - return pd end lpdf.pagedest = pagedest @@ -97,10 +99,17 @@ local function link(url,filename,destination,page,actions) URI = url, } elseif filename and filename ~= "" then + -- no page ? + if destination == "" then + destination = nil + end + if not destination and page then + destination = pdfarray { page - 1, pdfconstant("Fit") } + end return pdfdictionary { S = pdf_gotor, -- can also be pdf_launch F = filename, - D = (destination and destination ~= "" and destination), -- or defaultdestination, + D = destination or defaultdestination, -- D is mandate NewWindow = (actions.newwindow and true) or nil, } elseif destination and destination ~= "" then @@ -195,7 +204,7 @@ local function pdfaction(actions) end end -lpdf.pdfaction = pdfaction +lpdf.action = pdfaction function codeinjections.prerollreference(actions) local main = actions and pdfaction(actions) @@ -205,6 +214,7 @@ function codeinjections.prerollreference(actions) Border = pdf_border, H = (not actions.highlight and pdf_n) or nil, A = main, + F = 4, -- print (mandate in pdf/a) -- does not work at all in spite of specification -- OC = (actions.layer and lpdf.layerreferences[actions.layer]) or nil, -- OC = backends.pdf.layerreference(actions.layer), @@ -238,7 +248,7 @@ function nodeinjections.reference(width,height,depth,prerolled) if trace_references then report_references("w=%s, h=%s, d=%s, a=%s",width,height,depth,prerolled) end - return pdfannotation(width,height,depth,prerolled) + return pdfannotation_node(width,height,depth,prerolled) end end @@ -246,7 +256,7 @@ function nodeinjections.destination(width,height,depth,name,view) if trace_destinations then report_destinations("w=%s, h=%s, d=%s, n=%s, v=%s",width,height,depth,name,view or "no view") end - return pdfdestination(width,height,depth,name,view) + return pdfdestination_node(width,height,depth,name,view) end -- runners and specials @@ -337,7 +347,7 @@ function specials.page(var,actions) -- better resolve in strc-ref local file = var.f if file then file = jobreferences.checkedfile(file) - return link(nil,file,nil,p or var.operation,actions) + return link(nil,file,nil,var.operation,actions) else local p = jobreferences.pages[var.operation] if type(p) == "function" then diff --git a/tex/context/base/lpdf-epa.lua b/tex/context/base/lpdf-epa.lua new file mode 100644 index 000000000..35c0c086b --- /dev/null +++ b/tex/context/base/lpdf-epa.lua @@ -0,0 +1,162 @@ +if not modules then modules = { } end modules ['lpdf-epa'] = { + version = 1.001, + comment = "companion to lpdf-epa.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is a rather experimental feature and the code will probably +-- change. + +local type, tonumber = type, tonumber +local format = string.format + +local trace_links = false trackers.register("figures.links", function(v) trace_links = v end) + +local report_link = logs.new("links") + +local variables = interfaces.variables + +local function add_link(x,y,w,h,destination,what) + if trace_links then + report_link("dx: %04i, dy: %04i, wd: %04i, ht: %04i, destination: %s, type: %s",x,y,w,h,destination,what) + end + context.setlayer ( + { "epdflinks" }, + { x = x .. "bp", y = y .. "bp", preset = "leftbottom" }, + function() + -- context.blackrule { width = w.."bp", height = h.."bp", depth = "0bp" } + context.button ( + { + width = w.."bp", + height = h.."bp", + offset = variables.overlay, + frame = trace_links and variables.on or variables.off, + }, + "", + { destination } + ) + end + ) +end + +local function link_goto(x,y,w,h,document,annotation,pagesdata,pagedata,namespace) + -- print("border",table.unpack(annotation.Border.all)) + -- print("flags",annotation.F) + -- print("pagenumbers",pagedata.reference.num,destination[1].num) + -- print("pagerefs",pagedata.number,pagesdata.references[destination[1].num]) + local destination = annotation.A.D -- [ 18 0 R /Fit ] + local what = "page" + if type(destination) == "string" then + local destinations = document.Catalog.Destinations + local wanted = destinations[destination] + destination = wanted and wanted.D + if destination then what = "named" end + end + local whereto = destination and destination[1] -- array + if whereto and whereto.num then + local currentpage = pagedata.number + local destinationpage = pagesdata.references[whereto.num] + add_link(x,y,w,h,namespace .. destinationpage,what) + return + end +end + +local function link_uri(x,y,w,h,document,annotation) + local url = annotation.A.URI + if url then + add_link(x,y,w,h,format("url(%s)",url),"url") + end +end + +local function link_file(x,y,w,h,document,annotation) + local filename = annotation.A.F + if filename then + local destination = annotation.A.D + if not destination then + add_link(x,y,w,h,format("file(%s)",filename),"file") + elseif type(destination) == "string" then + add_link(x,y,w,h,format("%s::%s",filename,destination),"file (named)") + else + destination = destination[1] -- array + if tonumber(destination) then + add_link(x,y,w,h,format("%s::page(%s)",filename,destination),"file (page)") + else + add_link(x,y,w,h,format("file(%s)",filename),"file") + end + end + end +end + +function backends.codeinjections.mergereferences(specification) + if figures and not specification then + specification = figures and figures.current() + specification = specification and specification.status + end + if specification then + local fullname = specification.fullname + local document = lpdf.load(fullname) + if document then + local pagenumber = specification.page or 1 + local xscale = specification.yscale or 1 + local yscale = specification.yscale or 1 + local size = specification.size or "crop" -- todo + local pagesdata = document.Catalog.Pages + local pagedata = pagesdata[pagenumber] + local annotations = pagedata.Annots + local namespace = format("lpdf-epa-%s-",file.removesuffix(file.basename(fullname))) + local reference = namespace .. pagenumber + if annotations.size > 0 then + local llx, lly, urx, ury = table.unpack(pagedata.MediaBox.all) + local width, height = xscale * (urx - llx), yscale * (ury - lly) -- \\overlaywidth, \\overlayheight + context.definelayer( { "epdflinks" }, { height = height.."bp" , width = width.."bp" }) + for i=1,annotations.size do + local annotation = annotations[i] + local subtype = annotation.Subtype + local a_llx, a_lly, a_urx, a_ury = table.unpack(annotation.Rect.all) + local x, y = xscale * (a_llx - llx), yscale * (a_lly - lly) + local w, h = xscale * (a_urx - a_llx), yscale * (a_ury - a_lly) + if subtype == "Link" then + local linktype = annotation.A.S + if linktype == "GoTo" then + link_goto(x,y,w,h,document,annotation,pagesdata,pagedata,namespace) + elseif linktype == "GoToR" then + link_file(x,y,w,h,document,annotation) + elseif linktype == "URI" then + link_uri(x,y,w,h,document,annotation) + elseif trace_links then + report_link("unsupported link annotation '%s'",linktype) + end + elseif trace_links then + report_link("unsupported annotation '%s'",subtype) + end + end + context.flushlayer { "epdflinks" } + context("\\gdef\\figurereference{%s}",reference) -- global + specification.reference = reference + return namespace + end + end + end + return ""-- no namespace, empty, not nil +end + +function backends.codeinjections.mergelayers(specification) + if not specification then + specification = figures and figures.current() + specification = specification and specification.status + end + if specification then + local fullname = specification.fullname + local document = lpdf.load(fullname) + if document then + local pagenumber = specification.page or 1 + local pagesdata = document.Catalog.Pages + local pagedata = pagesdata[pagenumber] + local resources = pagedata.Resources +--~ table.print(resources) +--~ local properties = resources.Properties + end + end +end diff --git a/tex/context/base/lpdf-epd.lua b/tex/context/base/lpdf-epd.lua new file mode 100644 index 000000000..23ab0674c --- /dev/null +++ b/tex/context/base/lpdf-epd.lua @@ -0,0 +1,246 @@ +if not modules then modules = { } end modules ['lpdf-epd'] = { + version = 1.001, + comment = "companion to lpdf-epa.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is an experimental layer around the epdf library. Because that +-- library is not yet finished and will get a clear api (independent of +-- the underlying pdf library which has an instable api) it will take +-- a while before this module is completed. Also, some integration with +-- other lpdf code might happen (i.e. we might generate lpdf objects). + +local setmetatable, rawset = setmetatable, rawset + +-- used: +-- +-- arrayGet arrayGetNF dictLookup getTypeName arrayGetLength +-- getNum getString getBool getName getRef +-- getResourceDict getMediaBox getCropBox getBleedBox getTrimBox getArtBox +-- getPageRef getKindName findDestgetNumPages getDests getPage getCatalog getAnnots + +-- -- -- helpers -- -- -- + +local cache_lookups = false + +local checked_access + +local array_access = { + __index = function(t,k) + local d = t.__data__ + if tonumber(k) then + return checked_access(t,k,d:arrayGetNF(k)) + elseif k == "all" then + local result = { } + for i=1,t.size do + result[i] = checked_access(t,k,d:arrayGetNF(i)) + end + return result + elseif k == "width" then + return checked_access(t,k,d:arrayGetNF(3)) - checked_access(t,k,d:arrayGetNF(1)) + elseif k == "height" then + return checked_access(t,k,d:arrayGetNF(4)) - checked_access(t,k,d:arrayGetNF(2)) + end + end, +} + +local dictionary_access = { + __index = function(t,k) + return checked_access(t,k,t.__data__:dictLookup(k)) + end +} + +checked_access = function(tab,key,v) + local n = v:getTypeName() +--~ print("!!!!!!!!!!!!!!",n) + if n == "array" then + local t = { __data__ = v, size = v:arrayGetLength() } + setmetatable(t,array_access) + if cache_lookups then rawset(tab,key,t) end + return t + elseif n == "dictionary" then + local t = { __data__ = v, } + setmetatable(t,dictionary_access) + if cache_lookups then rawset(tab,key,t) end + return t + elseif n == "real" or n == "integer" then + return v:getNum() + elseif n == "string" then + return v:getString() + elseif n == "boolean" then + return v:getBool() + elseif n == "name" then + return v:getName() + elseif n == "ref" then + return v:getRef(v.num,v.gen) + else + return v + end +end + +local basic_annots_access = { + __index = function(t,k) + local a = { + __data__ = t.__data__:arrayGet(k), + } + setmetatable(a,dictionary_access) + if cache_lookups then rawset(t,k,a) end + return a + end +} + +local basic_resources_access = { -- == dictionary_access + __index = function(t,k) +--~ local d = t.__data__ +--~ print(d) +--~ print(d:getTypeName()) + return checked_access(t,k,t.__data__:dictLookup(k)) + end +} + +local basic_box_access = { + __index = function(t,k) + local d = t.__data__ + if k == "all" then return { d.x1, d.y1, d.x2, d.y2 } + elseif k == "width" then return d.x2 - d.x1 + elseif k == "height" then return d.y2 - d.y1 + elseif k == 1 then return d.x1 + elseif k == 2 then return d.y1 + elseif k == 3 then return d.x2 + elseif k == 4 then return d.y2 + else return 0 end + end +} + +-- -- -- pages -- -- -- + +local page_access = { + __index = function(t,k) + local d = t.__data__ + if k == "Annots" then + local annots = d:getAnnots() + local a = { + __data__ = annots, + size = annots:arrayGetLength() + } + setmetatable(a,basic_annots_access) + rawset(t,k,a) + return a + elseif k == "Resources" then + local r = { + __data__ = d:getResourceDict(), + } + setmetatable(r,basic_resources_access) + rawset(t,k,r) + return r + elseif k == "MediaBox" or k == "TrimBox" or k == "CropBox" or k == "ArtBox" or k == "BleedBox" then + local b = { + -- __data__ = d:getMediaBox(), + __data__ = d["get"..k](d), + } + setmetatable(b,basic_box_access) + rawset(t,k,b) + return b + end + end +} + +-- -- -- catalog -- -- -- + +local destination_access = { + __index = function(t,k) + if k == "D" then + local d = t.__data__ + local p = { + d:getPageRef(k), d:getKindName(k) + } + if cache_lookups then rawset(t,k,p) end -- not needed + return p + end + end +} + +local destinations_access = { + __index = function(t,k) + local d = t.__catalog__ + local p = { + __data__ = d:findDest(k), + } + setmetatable(p,destination_access) + if cache_lookups then rawset(t,k,p) end + return p + end +} + +local catalog_access = { + __index = function(t,k) + local c = t.__catalog__ + if k == "Pages" then + local s = c:getNumPages() + local r = { + } + local p = { + __catalog__ = c, + size = s, + references = r, + } + -- we load all pages as we need to resolve refs + for i=1,s do + local di, ri = c:getPage(i), c:getPageRef(i) + local pi = { + __data__ = di, + reference = ri, + number = i, + } + setmetatable(pi,page_access) + p[i], r[ri.num] = pi, i + end + -- setmetatable(p,pages_access) + rawset(t,k,p) + return p + elseif k == "Destinations" or k == "Dest" then + local d = c:getDests() + local p = { + __catalog__ = c, + } + setmetatable(p,destinations_access) + rawset(t,k,p) + return p + elseif k == "Metadata" then + local m = c:readMetadata() + local p = { -- we fake a stream dictionary + __catalog__ = c, + stream = m, + Type = "Metadata", + Subtype = "XML", + Length = #m, + } + -- rawset(t,k,p) + return p + end + end +} + +local document_access = { + __index = function(t,k) + if k == "Catalog" then + local c = { + __catalog__ = t.__root__:getCatalog(), + } + setmetatable(c,catalog_access) + rawset(t,k,c) + return c + end + end +} + +function lpdf.load(filename) + local document = { + __root__ = epdf.open(filename), + filename = filename, + } + setmetatable(document,document_access) + return document +end diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua index 893962b0e..455ddcf5f 100644 --- a/tex/context/base/lpdf-fld.lua +++ b/tex/context/base/lpdf-fld.lua @@ -27,17 +27,18 @@ local registrations = backends.pdf.registrations local registeredsymbol = codeinjections.registeredsymbol -local pdfstream = lpdf.stream -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfunicode = lpdf.unicode -local pdfstring = lpdf.string -local pdfconstant = lpdf.constant -local pdftoeight = lpdf.toeight -local pdfflushobject = lpdf.flushobject -local pdfreserveobject = lpdf.reserveobject -local pdfannotation = nodes.pdfannotation +local pdfstream = lpdf.stream +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfconstant = lpdf.constant +local pdftoeight = lpdf.toeight +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject + +local pdfannotation_node = nodes.pdfannotation local submitoutputformat = 0 -- 0=unknown 1=HTML 2=FDF 3=XML => not yet used, needs to be checked @@ -119,7 +120,7 @@ end local function checked(what) if what and what ~= "" then local set, bug = jobreferences.identify("",what) - return not bug and #set > 0 and lpdf.pdfaction(set) + return not bug and #set > 0 and lpdf.action(set) end end @@ -586,7 +587,7 @@ local function finishfields() end end -lpdf.registerdocumentfinalizer(finishfields) +lpdf.registerdocumentfinalizer(finishfields,"form fields") local pdf_widget = pdfconstant("Widget") local pdf_tx = pdfconstant("Tx") @@ -634,7 +635,7 @@ end local function save_kid(field,specification,d) local kn = pdfreserveobject() field.kids[#field.kids+1] = pdfreference(kn) - node.write(pdfannotation(specification.width,specification.height,0,d(),kn)) + node.write(pdfannotation_node(specification.width,specification.height,0,d(),kn)) end function methods.line(name,specification,variant,extras) diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua index e0cc98c27..09fb1d096 100644 --- a/tex/context/base/lpdf-ini.lua +++ b/tex/context/base/lpdf-ini.lua @@ -13,8 +13,8 @@ local texwrite, texset, texsprint, ctxcatcodes = tex.write, tex.set, tex.sprint, local sind, cosd = math.sind, math.cosd local lpegmatch = lpeg.match -local pdfreserveobj = pdf and pdf.reserveobj or function() return 1 end -- for testing -local pdfimmediateobj = pdf and pdf.immediateobj or function() return 2 end -- for testing +local pdfreserveobject = pdf and pdf.reserveobj or function() return 1 end -- for testing +local pdfimmediateobject = pdf and pdf.immediateobj or function() return 2 end -- for testing local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end) local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end) @@ -331,7 +331,7 @@ lpdf.verbose = pdfverbose local names, cache = { }, { } function lpdf.reserveobject(name) - local r = pdfreserveobj() + local r = pdfreserveobject() if name then names[name] = r if trace_objects then @@ -343,7 +343,30 @@ function lpdf.reserveobject(name) return r end ---~ local pdfreserveobject = lpdf.reserveobject +function lpdf.reserveannotation() + return pdfreserveobject("annot") +end + +lpdf.immediateobject = pdf.immediateobj +lpdf.object = pdf.obj -- the table interface, todo: auto attr() and so +lpdf.pagereference = pdf.pageref or tex.pdfpageref + +--~ local pdfobj = pdf.obj + +--~ function lpdf.object(t) +--~ local attr = t.attr +--~ if type(attr) == "function" then +--~ t.attr = attr() +--~ end +--~ local str = t.string +--~ if str then +--~ t.string = tostring(str) +--~ end +--~ if not t.type then +--~ t.type = "raw" +--~ end +--~ pdfobj(t) +--~ end function lpdf.flushobject(name,data) if data then @@ -356,7 +379,7 @@ function lpdf.flushobject(name,data) report_backends("flushing object data to reserved object with name '%s'",name) end end - return pdfimmediateobj(name,tostring(data)) + return pdfimmediateobject(name,tostring(data)) else if trace_objects then if trace_detail then @@ -365,20 +388,20 @@ function lpdf.flushobject(name,data) report_backends("flushing object data to reserved object with number %s",name) end end - return pdfimmediateobj(tostring(data)) + return pdfimmediateobject(tostring(data)) end else if trace_objects and trace_detail then report_backends("flushing object data -> %s",tostring(name)) end - return pdfimmediateobj(tostring(name)) + return pdfimmediateobject(tostring(name)) end end function lpdf.sharedobj(content) local r = cache[content] if not r then - r = pdfreference(pdfimmediateobj(content)) + r = pdfreference(pdfimmediateobject(content)) cache[content] = r end return r @@ -447,6 +470,8 @@ local function resetpageproperties() pagesattributes = pdfdictionary() end +resetpageproperties() + local function setpageproperties() --~ texset("global", "pdfpageresources", pageresources ()) --~ texset("global", "pdfpageattr", pageattributes ()) @@ -460,10 +485,14 @@ function lpdf.addtopageresources (k,v) pageresources [k] = v end function lpdf.addtopageattributes (k,v) pageattributes [k] = v end function lpdf.addtopagesattributes(k,v) pagesattributes[k] = v end -local function set(where,f,when,what) - when = when or 2 +local function set(where,what,f,when,comment) + if type(when) == "string" then + when, comment = 2, when + elseif not when then + when = 2 + end local w = where[when] - w[#w+1] = f + w[#w+1] = { f, comment } if trace_finalizers then report_backends("%s set: [%s,%s]",what,when,#w) end @@ -473,27 +502,29 @@ local function run(where,what) for i=1,#where do local w = where[i] for j=1,#w do + local wj = w[j] if trace_finalizers then - report_backends("%s finalizer: [%s,%s]",what,i,j) + report_backends("%s finalizer: [%s,%s] %s",what,i,j,wj[2] or "") end - w[j]() + wj[1]() end end end -function lpdf.registerpagefinalizer(f,when) - set(pagefinalizers,f,when,"page") +function lpdf.registerpagefinalizer(f,when,comment) + set(pagefinalizers,"page",f,when,comment) end -function lpdf.registerdocumentfinalizer(f,when) - set(documentfinalizers,f,when,"document") +function lpdf.registerdocumentfinalizer(f,when,comment) + set(documentfinalizers,"document",f,when,comment) end function lpdf.finalizepage() if not environment.initex then - resetpageproperties() + -- resetpageproperties() -- maybe better before run(pagefinalizers,"page") setpageproperties() + resetpageproperties() -- maybe better before end end @@ -507,11 +538,8 @@ function lpdf.finalizedocument() end end -if callbacks.known("finish_pdffile") then - callbacks.register("finish_pdffile",function() if not environment.initex then run(documentfinalizers,"document") end end) - function lpdf.finalizedocument() end -end - +--~ callbacks.register("finish_pdfoage", lpdf.finalizepage) +callbacks.register("finish_pdffile", lpdf.finalizedocument) -- some minimal tracing, handy for checking the order @@ -538,22 +566,22 @@ function lpdf.addtocatalog(k,v) if not (lpdf.protectresources and catalog[k]) th function lpdf.addtoinfo (k,v) if not (lpdf.protectresources and info [k]) then trace_set("info", k) info [k] = v end end function lpdf.addtonames (k,v) if not (lpdf.protectresources and names [k]) then trace_set("names", k) names [k] = v end end -local dummy = pdfreserveobj() -- else bug in hvmd due so some internal luatex conflict +local dummy = pdfreserveobject() -- else bug in hvmd due so some internal luatex conflict -local r_extgstates, d_extgstates = pdfreserveobj(), pdfdictionary() local p_extgstates = pdfreference(r_extgstates) -local r_colorspaces, d_colorspaces = pdfreserveobj(), pdfdictionary() local p_colorspaces = pdfreference(r_colorspaces) -local r_patterns, d_patterns = pdfreserveobj(), pdfdictionary() local p_patterns = pdfreference(r_patterns) -local r_shades, d_shades = pdfreserveobj(), pdfdictionary() local p_shades = pdfreference(r_shades) +local r_extgstates, d_extgstates = pdfreserveobject(), pdfdictionary() local p_extgstates = pdfreference(r_extgstates) +local r_colorspaces, d_colorspaces = pdfreserveobject(), pdfdictionary() local p_colorspaces = pdfreference(r_colorspaces) +local r_patterns, d_patterns = pdfreserveobject(), pdfdictionary() local p_patterns = pdfreference(r_patterns) +local r_shades, d_shades = pdfreserveobject(), pdfdictionary() local p_shades = pdfreference(r_shades) local function checkextgstates () if next(d_extgstates ) then lpdf.addtopageresources("ExtGState", p_extgstates ) end end local function checkcolorspaces() if next(d_colorspaces) then lpdf.addtopageresources("ColorSpace",p_colorspaces) end end local function checkpatterns () if next(d_patterns ) then lpdf.addtopageresources("Pattern", p_patterns ) end end local function checkshades () if next(d_shades ) then lpdf.addtopageresources("Shading", p_shades ) end end -local function flushextgstates () if next(d_extgstates ) then trace_flush("extgstates") pdfimmediateobj(r_extgstates, tostring(d_extgstates )) end end -local function flushcolorspaces() if next(d_colorspaces) then trace_flush("colorspaces") pdfimmediateobj(r_colorspaces,tostring(d_colorspaces)) end end -local function flushpatterns () if next(d_patterns ) then trace_flush("patterns") pdfimmediateobj(r_patterns, tostring(d_patterns )) end end -local function flushshades () if next(d_shades ) then trace_flush("shades") pdfimmediateobj(r_shades, tostring(d_shades )) end end +local function flushextgstates () if next(d_extgstates ) then trace_flush("extgstates") pdfimmediateobject(r_extgstates, tostring(d_extgstates )) end end +local function flushcolorspaces() if next(d_colorspaces) then trace_flush("colorspaces") pdfimmediateobject(r_colorspaces,tostring(d_colorspaces)) end end +local function flushpatterns () if next(d_patterns ) then trace_flush("patterns") pdfimmediateobject(r_patterns, tostring(d_patterns )) end end +local function flushshades () if next(d_shades ) then trace_flush("shades") pdfimmediateobject(r_shades, tostring(d_shades )) end end local collected = pdfdictionary { ExtGState = p_extgstates, @@ -571,19 +599,19 @@ function lpdf.adddocumentcolorspace(k,v) d_colorspaces[k] = v end function lpdf.adddocumentpattern (k,v) d_patterns [k] = v end function lpdf.adddocumentshade (k,v) d_shades [k] = v end -lpdf.registerdocumentfinalizer(flushextgstates,3) -lpdf.registerdocumentfinalizer(flushcolorspaces,3) -lpdf.registerdocumentfinalizer(flushpatterns,3) -lpdf.registerdocumentfinalizer(flushshades,3) +lpdf.registerdocumentfinalizer(flushextgstates,3,"extended graphic states") +lpdf.registerdocumentfinalizer(flushcolorspaces,3,"color spaces") +lpdf.registerdocumentfinalizer(flushpatterns,3,"patterns") +lpdf.registerdocumentfinalizer(flushshades,3,"shades") -lpdf.registerdocumentfinalizer(flushcatalog,3) -lpdf.registerdocumentfinalizer(flushinfo,3) -lpdf.registerdocumentfinalizer(flushnames,3) +lpdf.registerdocumentfinalizer(flushcatalog,3,"catalog") +lpdf.registerdocumentfinalizer(flushinfo,3,"info") +lpdf.registerdocumentfinalizer(flushnames,3,"names") -lpdf.registerpagefinalizer(checkextgstates,3) -lpdf.registerpagefinalizer(checkcolorspaces,3) -lpdf.registerpagefinalizer(checkpatterns,3) -lpdf.registerpagefinalizer(checkshades,3) +lpdf.registerpagefinalizer(checkextgstates,3,"extended graphic states") +lpdf.registerpagefinalizer(checkcolorspaces,3,"color spaces") +lpdf.registerpagefinalizer(checkpatterns,3,"patterns") +lpdf.registerpagefinalizer(checkshades,3,"shades") -- in strc-bkm: lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1) diff --git a/tex/context/base/lpdf-ini.mkiv b/tex/context/base/lpdf-ini.mkiv index 7c7dce3ef..64ce6eb43 100644 --- a/tex/context/base/lpdf-ini.mkiv +++ b/tex/context/base/lpdf-ini.mkiv @@ -25,6 +25,7 @@ \registerctxluafile{lpdf-fld}{1.001} \registerctxluafile{lpdf-u3d}{1.001} \registerctxluafile{lpdf-swf}{1.001} +\registerctxluafile{lpdf-tag}{1.001} \unprotect diff --git a/tex/context/base/lpdf-mis.lua b/tex/context/base/lpdf-mis.lua index ac471e4e0..0d9061daa 100644 --- a/tex/context/base/lpdf-mis.lua +++ b/tex/context/base/lpdf-mis.lua @@ -28,17 +28,16 @@ local copy_node = node.copy local pdfliteral, register = nodes.pdfliteral, nodes.register -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfboolean = lpdf.boolean -local pdfconstant = lpdf.constant -local pdfreference = lpdf.reference -local pdfunicode = lpdf.unicode -local pdfverbose = lpdf.verbose -local pdfstring = lpdf.string -local pdfflushobject = lpdf.flushobject - -local pdfimmediateobj = pdf.immediateobj +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfboolean = lpdf.boolean +local pdfconstant = lpdf.constant +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfverbose = lpdf.verbose +local pdfstring = lpdf.string +local pdfflushobject = lpdf.flushobject +local pdfimmediateobject = lpdf.immediateobject local tobasepoints = number.tobasepoints local variables = interfaces.variables @@ -58,7 +57,7 @@ local function initializenegative() Range = a, Domain = a, } - local negative = pdfdictionary { Type = g, TR = pdfreference(pdfimmediateobj("stream","1 exch sub",d())) } + local negative = pdfdictionary { Type = g, TR = pdfreference(pdfimmediateobject("stream","1 exch sub",d())) } local positive = pdfdictionary { Type = g, TR = pdfconstant("Identity") } lpdf.adddocumentextgstate("GSnegative", pdfreference(pdfflushobject(negative))) lpdf.adddocumentextgstate("GSPositive", pdfreference(pdfflushobject(positive))) @@ -118,10 +117,10 @@ end local function flushdocumentactions() if opendocument then - lpdf.addtocatalog("OpenAction",lpdf.pdfaction(opendocument)) + lpdf.addtocatalog("OpenAction",lpdf.action(opendocument)) end if closedocument then - lpdf.addtocatalog("CloseAction",lpdf.pdfaction(closedocument)) + lpdf.addtocatalog("CloseAction",lpdf.action(closedocument)) end end @@ -129,17 +128,17 @@ local function flushpageactions() if openpage or closepage then local d = pdfdictionary() if openpage then - d.O = lpdf.pdfaction(openpage) + d.O = lpdf.action(openpage) end if closepage then - d.C = lpdf.pdfaction(closepage) + d.C = lpdf.action(closepage) end lpdf.addtopageattributes("AA",d) end end -lpdf.registerpagefinalizer(flushpageactions) -lpdf.registerdocumentfinalizer(flushdocumentactions) +lpdf.registerpagefinalizer(flushpageactions,"page actions") +lpdf.registerdocumentfinalizer(flushdocumentactions,"document actions") --- info @@ -189,7 +188,7 @@ local function flushjavascripts() local name, script = t[i][1], t[i][2] local j = pdfdictionary { S = pdf_javascript, - JS = pdfreference(pdfimmediateobj("stream",script)), + JS = pdfreference(pdfimmediateobject("stream",script)), } a[#a+1] = pdfstring(name) a[#a+1] = pdfreference(pdfflushobject(j)) @@ -198,7 +197,7 @@ local function flushjavascripts() end end -lpdf.registerdocumentfinalizer(flushjavascripts) +lpdf.registerdocumentfinalizer(flushjavascripts,"javascripts") -- -- -- @@ -288,8 +287,8 @@ local function pagespecification() -- lpdf.addtopageattributes("ArtBox",box) end -lpdf.registerpagefinalizer(pagespecification) -lpdf.registerdocumentfinalizer(documentspecification) +lpdf.registerpagefinalizer(pagespecification,"page specification") +lpdf.registerdocumentfinalizer(documentspecification,"document specification") -- Page Label support ... -- @@ -332,4 +331,4 @@ local function featurecreep() lpdf.addtocatalog("PageLabels", pdfdictionary { Nums = list }) end -lpdf.registerdocumentfinalizer(featurecreep) +lpdf.registerdocumentfinalizer(featurecreep,"featurecreep") diff --git a/tex/context/base/lpdf-pdx.lua b/tex/context/base/lpdf-pdx.lua index 43b0b87dc..db1217c53 100644 --- a/tex/context/base/lpdf-pdx.lua +++ b/tex/context/base/lpdf-pdx.lua @@ -6,6 +6,10 @@ if not modules then modules = { } end modules ['lpdf-pdx'] = { license = "see context related readme files", } +local trace_colorprofiles = false trackers.register("backend.colorprofiles", function(v) trace_colorprofiles = v end) + +local report_backends = logs.new("backends") + local codeinjections = backends.codeinjections -- normally it is registered local variables = interfaces.variables @@ -16,6 +20,7 @@ local pdfreference = lpdf.reference local pdfflushobject = lpdf.flushobject local pdfstring = lpdf.string local pdfverbose = lpdf.verbose +local pdfobject = lpdf.object local lower, gmatch = string.lower, string.gmatch @@ -47,9 +52,9 @@ function codeinjections.useinternalICCprofile(colorspace,filename) local channel = channels[colorspace] if channel and filename ~= "" then local a = pdfdictionary { N = channel } - profile = pdf.obj { + profile = pdfobject { compresslevel = 0, - immediate = true, + immediate = true, -- ! type = "stream", file = filename, attr = a(), @@ -85,30 +90,51 @@ function codeinjections.useexternalICCprofile(colorspace,name,urls,checksum,vers end end -local function embedprofile(colorspace,filename) - local colorspace = lower(colorspace) - local n = codeinjections.useinternalICCprofile(colorspace,filename) - if n then - local a = pdfarray { - pdfconstant("ICCBased"), - pdfreference(n), - } - lpdf.adddocumentcolorspace(prefixes[colorspace],pdfreference(pdfflushobject(a))) -- part of page /Resources - defaults[lower(colorspace)] = filename - end -end - +local loaded = { } function codeinjections.useICCdefaultprofile(colorspace,filename) - defaults[lower(colorspace)] = filename -end - -local function flushembeddedprofiles() - for colorspace, filename in next, defaults do - embedprofile(colorspace,filename) + local colorspace = lower(colorspace) + if not loaded[colorspace] then + local n = codeinjections.useinternalICCprofile(colorspace,filename) + if n then + local a = pdfarray { + pdfconstant("ICCBased"), + pdfreference(n), + } + -- used in page /Resources, so this must be inserted at runtime + lpdf.adddocumentcolorspace(prefixes[colorspace],pdfreference(pdfflushobject(a))) + if trace_colorprofiles then + report_backends("including color profile '%s' from '%s'",colorspace,filename) + end + elseif trace_colorprofiles then + report_backends("no color profile '%s' in '%s'",colorspace,filename) + end + loaded = true + elseif trace_colorprofiles then + report_backends("color profile '%s' is already included",colorspace) end end +--~ The following is somewhat cleaner but then we need to flag that there are +--~ color spaces set so that the page flusher does not optimize the (at that +--~ moment) still empty array away. So, next(d_colorspaces) should then become +--~ a different test, i.e. also on flag. I'll add that when we need more forward +--~ referencing. +--~ +--~ local function embedprofile = codeinjections.useICCdefaultprofile +--~ +--~ local function flushembeddedprofiles() +--~ for colorspace, filename in next, defaults do +--~ embedprofile(colorspace,filename) +--~ end +--~ end +--~ +--~ function codeinjections.useICCdefaultprofile(colorspace,filename) +--~ defaults[lower(colorspace)] = filename +--~ end +--~ +--~ lpdf.registerdocumentfinalizer(flushembeddedprofiles,1,"embedded color profiles") + function codeinjections.usePDFXoutputintent(id,name,reference,outputcondition,info) local d = { Type = pdfconstant("OutputIntent"), @@ -125,6 +151,9 @@ function codeinjections.usePDFXoutputintent(id,name,reference,outputcondition,in d["DestOutputProfile"] = pdfreference(icc) end intents[#intents+1] = pdfreference(pdfflushobject(pdfdictionary(d))) + if trace_colorprofiles then + report_backends("adding output intent '%s' with id '%s' (entry %s)",name,id,#intents) + end end local function flushoutputintents() @@ -133,6 +162,4 @@ local function flushoutputintents() end end - -lpdf.registerdocumentfinalizer(flushoutputintents,1) -lpdf.registerdocumentfinalizer(flushembeddedprofiles,1) +lpdf.registerdocumentfinalizer(flushoutputintents,2,"output intents") diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua index e6bbd67fe..0e4e34c2a 100644 --- a/tex/context/base/lpdf-ren.lua +++ b/tex/context/base/lpdf-ren.lua @@ -103,8 +103,8 @@ local function flushpagelayers() end end -lpdf.registerpagefinalizer (flushpagelayers) -lpdf.registerdocumentfinalizer(flushtextlayers) +lpdf.registerpagefinalizer (flushpagelayers,"layers") +lpdf.registerdocumentfinalizer(flushtextlayers,"layers") local function setlayer(what,arguments) -- maybe just a gmatch of even better, earlier in lpeg diff --git a/tex/context/base/lpdf-swf.lua b/tex/context/base/lpdf-swf.lua index 9fe0cd09f..34e72f1ec 100644 --- a/tex/context/base/lpdf-swf.lua +++ b/tex/context/base/lpdf-swf.lua @@ -11,14 +11,15 @@ if not modules then modules = { } end modules ['lpdf-swf'] = { local format = string.format -local pdfconstant = lpdf.constant -local pdfboolean = lpdf.boolean -local pdfstring = lpdf.string -local pdfunicode = lpdf.unicode -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfnull = lpdf.null -local pdfreference = lpdf.reference +local pdfconstant = lpdf.constant +local pdfboolean = lpdf.boolean +local pdfstring = lpdf.string +local pdfunicode = lpdf.unicode +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfnull = lpdf.null +local pdfreference = lpdf.reference +local pdfimmediateobject = lpdf.immediateobject function backends.pdf.helpers.insertswf(spec) @@ -38,7 +39,7 @@ function backends.pdf.helpers.insertswf(spec) }, } - local fref = pdfreference(pdf.immediateobj(tostring(flash))) + local fref = pdfreference(pdfimmediateobject(tostring(flash))) local configuration = pdfdictionary { Configurations = pdfarray { fref }, @@ -50,7 +51,7 @@ function backends.pdf.helpers.insertswf(spec) }, } - local cref = pdfreference(pdf.immediateobj(tostring(configuration))) + local cref = pdfreference(pdfimmediateobject(tostring(configuration))) local activation = pdfdictionary { Activation = pdfdictionary { @@ -96,7 +97,7 @@ function backends.pdf.helpers.insertswf(spec) } } - local aref = pdfreference(pdf.immediateobj(tostring(activation))) + local aref = pdfreference(pdfimmediateobject(tostring(activation))) local annotation = pdfdictionary { Subtype = pdfconstant("RichMedia"), diff --git a/tex/context/base/lpdf-tag.lua b/tex/context/base/lpdf-tag.lua new file mode 100644 index 000000000..591def8b1 --- /dev/null +++ b/tex/context/base/lpdf-tag.lua @@ -0,0 +1,390 @@ +if not modules then modules = { } end modules ['lpdf-tag'] = { + version = 1.001, + comment = "companion to lpdf-tag.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local format, match, concat = string.format, string.match, table.concat +local lpegmatch = lpeg.match +local utfchar = utf.char + +local trace_tags = false trackers.register("structure.tags", function(v) trace_tags = v end) + +local report_tags = logs.new("tags") + +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfboolean = lpdf.boolean +local pdfconstant = lpdf.constant +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject +local pdfpagereference = lpdf.pagereference + +local new_pdfliteral = nodes.pdfliteral + +local hlist = node.id("hlist") +local vlist = node.id("vlist") +local glyph = node.id("glyph") +local glue = node.id("glue") +local disc = node.id("disc") +local whatsit = node.id("whatsit") + +local a_tagged = attributes.private('tagged') +local a_image = attributes.private('image') + +local has_attribute, set_attribute, traverse_nodes, traverse_id = node.has_attribute, node.set_attribute, node.traverse, node.traverse_id +local tosequence = nodes.tosequence +local copy_node, slide_nodelist = node.copy, node.slide + +local structure_stack = { } +local structure_kids = pdfarray() +local structure_ref = pdfreserveobject() +local parent_ref = pdfreserveobject() +local root = { pref = pdfreference(structure_ref), kids = structure_kids } +local tree = { } +local elements = { } +local names = pdfarray() +local taglist = { } -- set later + +local colonsplitter = lpeg.splitat(":") +local dashsplitter = lpeg.splitat("-") + +local add_ids = false -- true + +local mapping = { + document = "Div", + + division = "Div", + paragraph = "P", + construct = "Span", + + structure = "Sect", + structuretitle = "H", + structurenumber = "H", + structurecontent = "Div", + + itemgroup = "L", + item = "Li", + itemtag = "Lbl", + itemcontent = "LBody", + + description = "Li", + descriptiontag = "Lbl", + descriptioncontent = "LBody", + + verbatimblock = "Code", + verbatim = "Code", + + register = "Div", + registersection = "Div", + registertag = "Span", + registerentries = "Div", + registerentry = "Span", + registersee = "Span", + registerpages = "Span", + registerpage = "Span", + + table = "Table", + tablerow = "TR", + tablecell = "TD", + tabulate = "Table", + tabulaterow = "TR", + tabulatecell = "TD", + + list = "TOC", + listitem = "TOCI", + listtag = "Lbl", + listcontent = "P", + listdata = "P", + listpage = "Reference", + + delimitedblock = "BlockQuote", + delimited = "Quote", + subsentence = "Span", + + float = "Div", + floatcaption = "Caption", + floattag = "Span", + floattext = "Span", + floatcontent = "P", + + image = "P", + mpgraphic = "P", + + formulaset = "Div", + formula = "Div", + formulatag = "Span", + formulacontent = "P", + subformula = "Div", + + link = "Link", + + math = "Div", + mn = "Span", + mi = "Span", + mo = "Span", + ms = "Span", + mrow = "Span", + msubsup = "Span", + msub = "Span", + msup = "Span", + merror = "Span", + munderover = "Span", + munder = "Span", + mover = "Span", + mtext = "Span", + mfrac = "Span", + mroot = "Span", + msqrt = "Span", +} + +local usedmapping = { } +local usedlabels = { } + +function backends.codeinjections.mapping() + return mapping -- future versions may provide a copy +end + +function backends.codeinjections.maptag(original,target) + mapping[original] = target +end + +local function finishstructure() + if #structure_kids > 0 then + local nums = pdfarray() + for i=1,#tree do + nums[#nums+1] = i-1 + nums[#nums+1] = pdfreference(pdfflushobject(tree[i])) + end + local parenttree = pdfdictionary { + Nums = nums + } + -- we need to split names into smaller parts (e.g. alphabetic or so) + if add_ids then + local kids = pdfdictionary { + Limits = pdfarray { names[1], names[#names-1] }, + Names = names, + } + local idtree = pdfdictionary { + Kids = pdfarray { pdfreference(pdfflushobject(kids)) }, + } + end + -- + local rolemap = pdfdictionary() + for k, v in next, usedmapping do + k = usedlabels[k] or k + rolemap[k] = pdfconstant(mapping[k] or "Span") -- or "Div" + end + local structuretree = pdfdictionary { + Type = pdfconstant("StructTreeRoot"), + K = pdfreference(pdfflushobject(structure_kids)), + ParentTree = pdfreference(pdfflushobject(parent_ref,parenttree)), + IDTree = (add_ids and pdfreference(pdfflushobject(idtree))) or nil, + RoleMap = rolemap, + } + pdfflushobject(structure_ref,structuretree) + lpdf.addtocatalog("StructTreeRoot",pdfreference(structure_ref)) + -- + local markinfo = pdfdictionary { + Marked = pdfboolean(true), + -- UserProperties = pdfboolean(true), + -- Suspects = pdfboolean(true), + } + lpdf.addtocatalog("MarkInfo",pdfreference(pdfflushobject(markinfo))) + -- + for fulltag, element in next, elements do + pdfflushobject(element.knum,element.kids) + end + end +end + +lpdf.registerdocumentfinalizer(finishstructure,"document structure") + +local index, pageref, pagenum, list = 0, nil, 0, nil + +local pdf_mcr = pdfconstant("MCR") +local pdf_struct_element = pdfconstant("StructElem") + +local function initializepage() + index = 0 + pagenum = tex.count.realpageno + pageref = pdfreference(pdfpagereference(pagenum)) + list = pdfarray() + tree[pagenum] = list -- we can flush after done, todo +end + +local function finishpage() + -- flush what can be flushed + lpdf.addtopageattributes("StructParents",pagenum-1) +end + +-- here we can flush and free elements that are finished + +local function makeelement(fulltag,parent) + local tag, n = lpegmatch(dashsplitter,fulltag) + local tg, detail = lpegmatch(colonsplitter,tag) + local k, r = pdfarray(), pdfreserveobject() + usedmapping[tg] = true + tg = usedlabels[tg] or tg + local d = pdfdictionary { + Type = pdf_struct_element, + S = pdfconstant(tg), + ID = (add_ids and fulltag) or nil, + T = detail and detail or nil, + P = parent.pref, + Pg = pageref, + K = pdfreference(r), +--~ Alt = " Who cares ", +--~ ActualText = " Hi Hans ", + } + local s = pdfreference(pdfflushobject(d)) + if add_ids then + names[#names+1] = fulltag + names[#names+1] = s + end + local kids = parent.kids + kids[#kids+1] = s + elements[fulltag] = { tag = tag, pref = s, kids = k, knum = r, pnum = pagenum } +end + +local function makecontent(parent,start,stop,slist,id) + local tag, kids = parent.tag, parent.kids + local last = index + if id == "image" then + local d = pdfdictionary { + Type = pdf_mcr, + Pg = pageref, + MCID = last, + Alt = "image", + } + kids[#kids+1] = d + elseif pagenum == parent.pnum then + kids[#kids+1] = last + else + local d = pdfdictionary { + Type = pdf_mcr, + Pg = pageref, + MCID = last, + } + -- kids[#kids+1] = pdfreference(pdfflushobject(d)) + kids[#kids+1] = d + end + -- + local bliteral = new_pdfliteral(format("/%s <</MCID %s>>BDC",tag,last)) + local prev = start.prev + if prev then + prev.next, bliteral.prev = bliteral, prev + end + start.prev, bliteral.next = bliteral, start + if slist and slist.list == start then + slist.list = bliteral + elseif not prev then + report_tags("this can't happen: injection in front of nothing") + end + -- + local eliteral = new_pdfliteral("EMC") + local next = stop.next + if next then + next.prev, eliteral.next = eliteral, next + end + stop.next, eliteral.prev = eliteral, stop + -- + index = index + 1 + list[index] = parent.pref + return bliteral, eliteral +end + +-- -- -- + +local level, last, ranges, range = 0, nil, { }, { } + +local function collectranges(head,list) + for n in traverse_nodes(head) do + local id = n.id -- 14: image, 8: literal (mp) + if id == glyph then + local at = has_attribute(n,a_tagged) + if not at then + range = nil + elseif last ~= at then + range = { at, "glyph", n, n, list } -- attr id start stop list + ranges[#ranges+1] = range + last = at + elseif range then + range[4] = n -- stop + end + elseif id == hlist or id == vlist then + local at = has_attribute(n,a_image) + if at then + local at = has_attribute(n,a_tagged) + if not at then + range = nil + else + ranges[#ranges+1] = { at, "image", n, n, list } -- attr id start stop list + end + last = nil + else + slide_nodelist(n.list) -- temporary hack till math gets slided (tracker item) + collectranges(n.list,n) + end + end + end +end + +function backends.nodeinjections.addtags(head) + -- no need to adapt head, as we always operate on lists + level, last, ranges, range = 0, nil, { }, { } + initializepage() + collectranges(head) + if trace_tags then + for i=1,#ranges do + local range = ranges[i] + local attr, id, start, stop = range[1], range[2], range[3], range[4] + local tags = taglist[attr] + if tags then + report_tags("%s => %s : %05i %s",tosequence(start,start),tosequence(stop,stop),attr,concat(tags," ")) + end + end + end + for i=1,#ranges do + local range = ranges[i] + local attr, id, start, stop, list = range[1], range[2], range[3], range[4], range[5] + local tags = taglist[attr] + local prev = root + local noftags, tag = #tags, nil + for j=1,noftags do + local tag = tags[j] + if not elements[tag] then + makeelement(tag,prev) + end + prev = elements[tag] + end + local b, e = makecontent(prev,start,stop,list,id) + if start == head then + report_tags("this can't happen: parent list gets tagged") + head = b + end + end + finishpage() + -- can be separate feature + -- + -- injectspans(head) -- does to work yet + -- + return head, true +end + +function backends.codeinjections.enabletags(tg,lb) + taglist = tg + usedlabels = lb + structure.tags.handler = backends.nodeinjections.addtags + tasks.enableaction("shipouts","structure.tags.handler") + tasks.enableaction("shipouts","nodes.accessibility.handler") + tasks.enableaction("math","noads.add_tags") + if trace_tags then + report_tags("enabling structure tags") + end +end diff --git a/tex/context/base/lpdf-u3d.lua b/tex/context/base/lpdf-u3d.lua index f7a62c6c9..1bb99dc21 100644 --- a/tex/context/base/lpdf-u3d.lua +++ b/tex/context/base/lpdf-u3d.lua @@ -16,19 +16,18 @@ if not modules then modules = { } end modules ['lpdf-u3d'] = { local format, find = string.format, string.find local cos, sin, sqrt, pi, atan2, abs = math.cos, math.sin, math.sqrt, math.pi, math.atan2, math.abs -local pdfconstant = lpdf.constant -local pdfboolean = lpdf.boolean -local pdfnumber = lpdf.number -local pdfunicode = lpdf.unicode -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfnull = lpdf.null -local pdfreference = lpdf.reference - -local pdfimmediateobj = pdf.immediateobj - -local checkedkey = lpdf.checkedkey -local limited = lpdf.limited +local pdfconstant = lpdf.constant +local pdfboolean = lpdf.boolean +local pdfnumber = lpdf.number +local pdfunicode = lpdf.unicode +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfnull = lpdf.null +local pdfreference = lpdf.reference +local pdfimmediateobject = lpdf.immediateobject + +local checkedkey = lpdf.checkedkey +local limited = lpdf.limited local schemes = table.tohash { "Artwork", "None", "White", "Day", "Night", "Hard", @@ -388,12 +387,12 @@ function backends.pdf.helpers.insert3d(spec) -- width, height, factor, display, if js then local jsref = stored_js[js] if not jsref then - jsref = pdfimmediateobj("streamfile",js) + jsref = pdfimmediateobject("streamfile",js) stored_js[js] = jsref end attr.OnInstantiate = pdfreference(jsref) end - stored_3d[label] = pdfimmediateobj("streamfile",foundname,attr()) + stored_3d[label] = pdfimmediateobject("streamfile",foundname,attr()) stream = 1 else stream = stream + 1 @@ -456,7 +455,7 @@ function backends.pdf.helpers.insert3d(spec) -- width, height, factor, display, }, ProcSet = pdfarray { pdfconstant("PDF"), pdfconstant("ImageC") }, } - local pwd = pdfimmediateobj( + local pwd = pdfimmediateobject( "stream", format("q /GS gs %s 0 0 %s 0 0 cm /IM Do Q", factor*width,factor*height), diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua index 40a81e7d4..323e3c79d 100644 --- a/tex/context/base/lpdf-wid.lua +++ b/tex/context/base/lpdf-wid.lua @@ -16,20 +16,20 @@ local registrations = backends.pdf.registrations local executers = jobreferences.executers local variables = interfaces.variables -local pdfconstant = lpdf.constant -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfunicode = lpdf.unicode -local pdfstring = lpdf.string -local pdfcolorspec = lpdf.colorspec -local pdfflushobject = lpdf.flushobject -local pdfreserveobject = lpdf.reserveobject - -local pdfreserveobj = pdf.reserveobj -local pdfimmediateobj = pdf.immediateobj - -local pdfannotation = nodes.pdfannotation +local pdfconstant = lpdf.constant +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfcolorspec = lpdf.colorspec +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject +local pdfreserveannotation = lpdf.reserveobject +local pdfimmediateobject = lpdf.immediateobject +local pdfpagereference = lpdf.pagereference + +local pdfannotation_node = nodes.pdfannotation local hpack_node, write_node = node.hpack, node.write @@ -135,10 +135,10 @@ function codeinjections.registercomment(specification) Parent = pdfreference(nd), } d.Popup = pdfreference(nc) - texbox["commentboxone"] = hpack_node(pdfannotation(0,0,0,d(),nd)) -- current dir - texbox["commentboxtwo"] = hpack_node(pdfannotation(specification.width,specification.height,0,c(),nc)) -- current dir + texbox["commentboxone"] = hpack_node(pdfannotation_node(0,0,0,d(),nd)) -- current dir + texbox["commentboxtwo"] = hpack_node(pdfannotation_node(specification.width,specification.height,0,c(),nc)) -- current dir else - texbox["commentboxone"] = hpack_node(pdfannotation(0,0,0,d())) -- current dir + texbox["commentboxone"] = hpack_node(pdfannotation_node(0,0,0,d())) -- current dir texbox["commentboxtwo"] = nil end end @@ -160,7 +160,7 @@ function codeinjections.embedfile(filename) else local basename = file.basename(filename) local a = pdfdictionary { Type = pdfconstant("EmbeddedFile") } - local f = pdfimmediateobj("streamfile",filename,a()) + local f = pdfimmediateobject("streamfile",filename,a()) local d = pdfdictionary { Type = pdfconstant("Filespec"), F = pdfstring(newname or basename), @@ -211,7 +211,7 @@ function codeinjections.attachfile(specification) local width = specification.width or 0 local height = specification.height or 0 local depth = specification.depth or 0 - write_node(pdfannotation(width,height,depth,d())) + write_node(pdfannotation_node(width,height,depth,d())) end function codeinjections.attachmentid(filename) @@ -255,20 +255,20 @@ local function insertrenderingwindow(label,width,height,specification) local actions = nil if openpage or closepage then actions = pdfdictionary { - PO = (openpage and lpdf.pdfaction(openpage )) or nil, - PC = (closepage and lpdf.pdfaction(closepage)) or nil, + PO = (openpage and lpdf.action(openpage )) or nil, + PC = (closepage and lpdf.action(closepage)) or nil, } end local page = tonumber(specification.page) or texcount.realpageno local d = pdfdictionary { Subtype = pdfconstant("Screen"), - P = pdfreference(tex.pdfpageref(page)), + P = pdfreference(pdfpagereference(page)), A = mf[label], Border = pdfarray { 0, 0, 0 } , AA = actions, } - local r = pdfreserveobj("annot") - write_node(pdfannotation(width,height,0,d(),r)) -- save ref + local r = pdfreserveannotation() + write_node(pdfannotation_node(width,height,0,d(),r)) -- save ref return pdfreference(r) end diff --git a/tex/context/base/lpdf-xmp.lua b/tex/context/base/lpdf-xmp.lua index c8e7b2b57..79f732be0 100644 --- a/tex/context/base/lpdf-xmp.lua +++ b/tex/context/base/lpdf-xmp.lua @@ -14,6 +14,8 @@ local trace_xmp = false trackers.register("backend.xmp", function(v) trace_xmp local pdfdictionary = lpdf.dictionary local pdfconstant = lpdf.constant +local pdfreference = lpdf.reference +local pdfobject = lpdf.object -- i wonder why this begin end is empty / w (no time now to look into it) @@ -119,7 +121,6 @@ end local t = { } for i=1,24 do t[i] = random() end local function flushxmpinfo() - commands.freezerandomseed(os.clock()) -- hack local t = { } for i=1,24 do t[i] = char(96 + random(26)) end @@ -144,22 +145,25 @@ local function flushxmpinfo() texio.write("log","\n% ",(gsub(blob,"[\r\n]","\n%% ")),"\n") end blob = format(xpacket,packetid,blob) - if tex.pdfcompresslevel > 0 then + if not verbose and tex.pdfcompresslevel > 0 then blob = gsub(blob,">%s+<","><") end - local r = pdf.obj { + local r = pdfobject { immediate = true, compresslevel = 0, type = "stream", string = blob, attr = md(), } - lpdf.addtocatalog("Metadata",lpdf.reference(r)) + lpdf.addtocatalog("Metadata",pdfreference(r)) commands.defrostrandomseed() -- hack - end -- his will be enabled when we can inhibit compression for a stream at the lua end -lpdf.registerdocumentfinalizer(flushxmpinfo,1) +lpdf.registerdocumentfinalizer(flushxmpinfo,1,"metadata") + +directives.register("backend.verbosexmp", function(v) + verbose = v +end) diff --git a/tex/context/base/luat-cnf.lua b/tex/context/base/luat-cnf.lua index 054de7c81..8be5dc7c3 100644 --- a/tex/context/base/luat-cnf.lua +++ b/tex/context/base/luat-cnf.lua @@ -116,7 +116,7 @@ local function makestub() io.savedata(name,format("%s\n\n%s",concat(t,"\n"),format(stub,firsttable))) end -lua.registerfinalizer(makestub) +lua.registerfinalizer(makestub,"create stub file") -- to be moved here: -- diff --git a/tex/context/base/luat-cod.lua b/tex/context/base/luat-cod.lua index 4a1a3d6f0..a5239e7ae 100644 --- a/tex/context/base/luat-cod.lua +++ b/tex/context/base/luat-cod.lua @@ -51,15 +51,19 @@ end local finalizers = { } -function lua.registerfinalizer(f) +function lua.registerfinalizer(f,comment) if type(f) == "function"then - finalizers[#finalizers+1] = f + finalizers[#finalizers+1] = { action = f, comment = comment } end end -function lua.finalize() +function lua.finalize(logger) for i=1,#finalizers do - finalizers[i]() + local finalizer = finalizers[i] + finalizer.action() + if logger then + logger("finalizing lua", "action: %s",finalizer.comment) + end end end diff --git a/tex/context/base/luat-cod.mkiv b/tex/context/base/luat-cod.mkiv index 94d245a3f..5104f3e6b 100644 --- a/tex/context/base/luat-cod.mkiv +++ b/tex/context/base/luat-cod.mkiv @@ -61,6 +61,6 @@ \registerctxluafile{luat-cod}{1.001} -\everydump\expandafter{\the\everydump\ctxlua{lua.finalize()}} +% \everydump\expandafter{\the\everydump\ctxlua{lua.finalize()}} \endinput diff --git a/tex/context/base/luat-ini.mkiv b/tex/context/base/luat-ini.mkiv index b7a0eb516..63cf02d01 100644 --- a/tex/context/base/luat-ini.mkiv +++ b/tex/context/base/luat-ini.mkiv @@ -243,4 +243,23 @@ \def\luaconditional#1{\ifcase#1tru\else fals\fi e} +%D Goodie: +%D +%D \starttyping +%D \ctxluacode{context("%0.5f",1/3)} +%D \stoptyping + +\long\def\ctxluacode + {\begingroup + \obeylualines + \obeyluatokens + \catcode`\{\plusone + \catcode`\}\plustwo + \afterassignment\doctxluacode + \scratchtoks=} + +\def\doctxluacode + {\normalexpanded{\endgroup\noexpand\directlua\zerocount\expandafter{\the\scratchtoks}}} + + \protect \endinput diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua index d33cbddd6..f40428d37 100644 --- a/tex/context/base/luat-run.lua +++ b/tex/context/base/luat-run.lua @@ -8,6 +8,10 @@ if not modules then modules = { } end modules ['luat-run'] = { local format, rpadd = string.format, string.rpadd +local trace_lua_dump = false trackers .register("system.dump", function(v) trace_lua_dump = v end) + +local report_lua_dump = logs.new("lua dump actions") + luatex = luatex or { } local start_actions = { } @@ -59,6 +63,10 @@ end function luatex.report_output_log() end +function luatex.pre_dump_actions() + lua.finalize(trace_lua_dump and report_lua_dump or nil) +end + -- this can be done later callbacks.register('start_run', luatex.start_run, "actions performed at the beginning of a run") @@ -72,3 +80,5 @@ callbacks.register('stop_page_number', luatex.stop_shipout_page, "actions callbacks.register('process_input_buffer', false, "actions performed when reading data") callbacks.register('process_output_buffer', false, "actions performed when writing data") + +callbacks.register("pre_dump", luatex.pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua index 4d7af73e4..98a14e35f 100644 --- a/tex/context/base/luat-sto.lua +++ b/tex/context/base/luat-sto.lua @@ -52,7 +52,7 @@ local function finalize() -- we can prepend the string with "evaluate:" end end -lua.registerfinalizer(finalize) +lua.registerfinalizer(finalize,"evaluate storage") local function dump() for i=1,#data do @@ -86,7 +86,7 @@ local function dump() end end -lua.registerfinalizer(dump) +lua.registerfinalizer(dump,"dump storage") -- we also need to count at generation time (nicer for message) diff --git a/tex/context/base/math-ini.mkiv b/tex/context/base/math-ini.mkiv index c960e8d7c..729e10443 100644 --- a/tex/context/base/math-ini.mkiv +++ b/tex/context/base/math-ini.mkiv @@ -46,11 +46,23 @@ \registerctxluafile{math-vfu}{1.001} \registerctxluafile{math-map}{1.001} \registerctxluafile{math-noa}{1.001} +\registerctxluafile{math-tag}{1.001} \definesystemattribute[mathalphabet] \chardef\mathalphabetattribute \dogetattributeid{mathalphabet} \definesystemattribute[mathsize] \chardef\mathsizeattribute \dogetattributeid{mathsize} \definesystemattribute[mathpunctuation] \chardef\mathpunctuationattribute \dogetattributeid{mathpunctuation} \definesystemattribute[mathgreek] \chardef\mathgreekattribute \dogetattributeid{mathgreek} +\definesystemattribute[mathalternate] \chardef\mathalternateattribute \dogetattributeid{mathalternate} + +% experiment + +% Normally this is applied to only one character. +% +% $ABC$ $\cal ABC$ $\mathaltcal ABC$ + +\def\mathalternate#1{\ctxlua{mathematics.setalternate(0,"#1")}} % fam 0 + +\def\mathaltcal{\mathalternate{cal}\cal} % ss01 in xits % todo: only in mmode diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua index d8c6b2b20..2b4f9b6fa 100644 --- a/tex/context/base/math-noa.lua +++ b/tex/context/base/math-noa.lua @@ -9,6 +9,8 @@ if not modules then modules = { } end modules ['math-noa'] = { -- beware: this is experimental code and there will be a more -- generic (attribute value driven) interface too but for the -- moment this is ok +-- +-- we will also make dedicated processors (faster) local utf = unicode.utf8 @@ -29,19 +31,19 @@ local trace_analyzing = false trackers.register("math.analyzing", function(v) local report_noads = logs.new("mathematics") -local noad_ord = 0 -local noad_op_displaylimits = 1 -local noad_op_limits = 2 -local noad_op_nolimits = 3 -local noad_bin = 4 -local noad_rel = 5 -local noad_open = 6 -local noad_close = 7 -local noad_punct = 8 -local noad_inner = 9 -local noad_under = 10 -local noad_over = 11 -local noad_vcenter = 12 +local noad_ord = 0 +local noad_op_displaylimits = 1 +local noad_op_limits = 2 +local noad_op_nolimits = 3 +local noad_bin = 4 +local noad_rel = 5 +local noad_open = 6 +local noad_close = 7 +local noad_punct = 8 +local noad_inner = 9 +local noad_under = 10 +local noad_over = 11 +local noad_vcenter = 12 -- obsolete: -- @@ -337,6 +339,76 @@ function noads.respace_characters(head,style,penalties) return true end +-- math alternates + +function fonts.initializers.common.mathalternates(tfmdata) + local goodies = tfmdata.goodies + if goodies then + for i=1,#goodies do + -- first one counts + -- we can consider sharing the attributes ... todo (only once scan) + local mathgoodies = goodies[i].mathematics + local alternates = mathgoodies and mathgoodies.alternates + if alternates then + local lastattribute, attributes = 0, { } + for k, v in next, alternates do + lastattribute = lastattribute + 1 + v.attribute = lastattribute + attributes[lastattribute] = v + end + tfmdata.shared.mathalternates = alternates -- to be checked if shared is ok here + tfmdata.shared.mathalternatesattributes = attributes -- to be checked if shared is ok here + return + end + end + end +end + +fonts.otf.tables.features['mathalternates'] = 'Additional math alternative shapes' + +fonts.otf.features.register('mathalternates',true) +table.insert(fonts.triggers,"mathalternates") + +fonts.initializers.base.otf.mathalternates = fonts.initializers.common.mathalternates +fonts.initializers.node.otf.mathalternates = fonts.initializers.common.mathalternates + +local get_alternate = fonts.otf.get_alternate + +local mathalternate = attributes.private("mathalternate") + +local alternate = { } -- noads.processors.alternate = alternate + +function mathematics.setalternate(fam,tag) + local id = font_of_family(fam) + local tfmdata = fontdata[id] + local mathalternates = tfmdata.shared.mathalternates + if mathalternates then + local m = mathalternates[tag] + tex.attribute[mathalternate] = m and m.attribute or attributes.unsetvalue + end +end + +alternate[math_char] = function(pointer) + local a = has_attribute(pointer,mathalternate) + if a and a > 0 then + set_attribute(pointer,mathalternate,0) + local tfmdata = fontdata[font_of_family(pointer.fam)] -- we can also have a famdata + local mathalternatesattributes = tfmdata.shared.mathalternatesattributes + if mathalternatesattributes then + local what = mathalternatesattributes[a] + local alt = get_alternate(tfmdata,pointer.char,what.feature,what.value) + if alt then + pointer.char = alt + end + end + end +end + +function noads.check_alternates(head,style,penalties) + process(head,alternate) + return true +end + -- the normal builder function noads.mlist_to_hlist(head,style,penalties) diff --git a/tex/context/base/math-tag.lua b/tex/context/base/math-tag.lua new file mode 100644 index 000000000..7180435f5 --- /dev/null +++ b/tex/context/base/math-tag.lua @@ -0,0 +1,247 @@ +if not modules then modules = { } end modules ['math-tag'] = { + version = 1.001, + comment = "companion to math-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local has_attribute = nodes.has_attribute +local set_attribute = nodes.set_attribute +local set_attributes = nodes.set_attributes + +local traverse_nodes = node.traverse + +local math_noad = node.id("noad") -- attr nucleus sub sup +local math_noad = node.id("noad") -- attr nucleus sub sup +local math_accent = node.id("accent") -- attr nucleus sub sup accent +local math_radical = node.id("radical") -- attr nucleus sub sup left degree +local math_fraction = node.id("fraction") -- attr nucleus sub sup left right +local math_box = node.id("sub_box") -- attr list +local math_sub = node.id("sub_mlist") -- attr list +local math_char = node.id("math_char") -- attr fam char +local math_text_char = node.id("math_text_char") -- attr fam char +local math_delim = node.id("delim") -- attr small_fam small_char large_fam large_char +local math_style = node.id("style") -- attr style +local math_choice = node.id("choice") -- attr display text script scriptscript +local math_fence = node.id("fence") -- attr subtype + +local hlist = node.id("hlist") +local vlist = node.id("vlist") +local glyph = node.id("glyph") + +local a_tagged = attributes.private('tagged') + +local start_tagged = structure.tags.start +local stop_tagged = structure.tags.stop +local chardata = characters.data + +local process + +local function processsubsup(start) + local nucleus, sup, sub = start.nucleus, start.sup, start.sub + if sub then + if sup then + set_attribute(start,a_tagged,start_tagged("msubsup")) + process(nucleus) + process(sup) + process(sub) + stop_tagged() + else + set_attribute(start,a_tagged,start_tagged("msub")) + process(nucleus) + process(sub) + stop_tagged() + end + elseif sup then + set_attribute(start,a_tagged,start_tagged("msup")) + process(nucleus) + process(sup) + stop_tagged() + else + process(nucleus) + end +end + +process = function(start) -- we cannot use the processor as we have no finalizers (yet) + while start do + local id = start.id + if id == math_char then + -- check for code + local ch = chardata[start.char] + local mc = ch and ch.mathclass + if mc == "number" then + set_attribute(start,a_tagged,start_tagged("mn")) + elseif mc == "variable" or not mc then -- variable is default + set_attribute(start,a_tagged,start_tagged("mi")) + else + set_attribute(start,a_tagged,start_tagged("mo")) + end + stop_tagged() + break + elseif id == math_text_char then + -- check for code + set_attribute(start,a_tagged,start_tagged("ms")) + stop_tagged() + break + elseif id == math_delim then + -- check for code + set_attribute(start,a_tagged,start_tagged("mo")) + stop_tagged() + break + elseif id == math_style then + -- has a next + elseif id == math_noad then + processsubsup(start) + elseif id == math_box or id == hlist or id == vlist then + -- keep an eye on math_box and see what ends up in there + local attr = has_attribute(start,a_tagged) + local text = start_tagged("mtext") + set_attribute(start,a_tagged,text) + local list = start.list + if not list then + -- empty list + elseif not attr then + -- box comes from strange place + set_attributes(list,a_tagged,text) + else + -- Beware, the first node in list is the actual list so we definitely + -- need to nest. This approach is a hack, maybe I'll make a proper + -- nesting feature to deal with this at another level. Here we just + -- fake structure by enforcing the inner one. + local taglist = structure.tags.taglist + local tagdata = taglist[attr] + local common = #tagdata + 1 + local function runner(list) -- quite inefficient + local cache = { } -- we can have nested unboxed mess so best local to runner + for n in traverse_nodes(list) do + local id = n.id + if id == hlist or id == vlist then + runner(n.list) + elseif id == glyph then + local aa = has_attribute(n,a_tagged) -- only glyph needed + if aa then + local ac = cache[aa] + if not ac then + local tagdata = taglist[aa] + local extra = #tagdata + if common <= extra then + for i=common,extra do + ac = start_tagged(tagdata[i]) -- can be made faster + end + for i=common,extra do + stop_tagged() -- can be made faster + end + else + ac = text + end + cache[aa] = ac + end + set_attribute(n,a_tagged,ac) + else + set_attribute(n,a_tagged,text) + end + end + end + end + runner(list) + end + stop_tagged() + elseif id == math_sub then + local list = start.list + if list then + set_attribute(start,a_tagged,start_tagged("mrow")) + process(list) + stop_tagged() + end + elseif id == math_fraction then + local num, denom, left, right = start.num, start.denom, start.left, start.right + if left then + set_attribute(left,a_tagged,start_tagged("mo")) + process(left) + stop_tagged() + end + set_attribute(start,a_tagged,start_tagged("mfrac")) + process(num) + process(denom) + stop_tagged() + if right then + set_attribute(right,a_tagged,start_tagged("mo")) + process(right) + stop_tagged() + end + elseif id == math_choice then + local display, text, script, scriptscript = start.display, start.text, start.script, start.scriptscript + if display then + process(display) + end + if text then + process(text) + end + if script then + process(script) + end + if scriptscript then + process(scriptscript) + end + elseif id == math_fence then + local delim = start.delim + if delim then + set_attribute(start,a_tagged,start_tagged("mo")) + process(delim) + stop_tagged() + end + elseif id == math_radical then + local left, degree = start.left, start.degree + if left then + process(left) -- mrow needed ? + end + if degree then + set_attribute(start,a_tagged,start_tagged("mroot")) + processsubsup(start) + process(degree) + stop_tagged() + else + set_attribute(start,a_tagged,start_tagged("msqrt")) + processsubsup(start) + stop_tagged() + end + elseif id == math_accent then + local accent, bot_accent = start.accent, start.bot_accent + if bot_accent then + if accent then + set_attribute(start,a_tagged,start_tagged("munderover")) + process(accent) + processsubsup(start) + process(bot_accent) + stop_tagged() + else + set_attribute(start,a_tagged,start_tagged("munder")) + processsubsup(start) + process(bot_accent) + stop_tagged() + end + elseif accent then + set_attribute(start,a_tagged,start_tagged("mover")) + process(accent) + processsubsup(start) + stop_tagged() + else + processsubsup(start) + end + else + set_attribute(start,a_tagged,start_tagged("merror")) + stop_tagged() + end + start = start.next + end +end + +function noads.add_tags(head,style,penalties) + set_attribute(head,a_tagged,start_tagged("math")) + set_attribute(head,a_tagged,start_tagged("mrow")) + process(head) + stop_tagged() + stop_tagged() + return true +end diff --git a/tex/context/base/mlib-pdf.mkiv b/tex/context/base/mlib-pdf.mkiv index 2681b0810..2e098730e 100644 --- a/tex/context/base/mlib-pdf.mkiv +++ b/tex/context/base/mlib-pdf.mkiv @@ -26,7 +26,8 @@ \xdef\MPheight{\the\dimexpr#4\onebasepoint-#2\onebasepoint\relax}} \def\startMPLIBtoPDF#1#2#3#4% watch the transparency reset - {\naturalhbox\bgroup + {\dostarttagged\t!mpgraphic\empty + \naturalhbox attr \imageattribute 1 \bgroup \doactivatecolor\s!black\forcecolorhack \MPLIBboundingbox{#1}{#2}{#3}{#4}% %\forgetall % done already elsewhere @@ -52,7 +53,8 @@ \wd\scratchbox\MPwidth \ht\scratchbox\MPheight \dopackageMPgraphic\scratchbox - \egroup} + \egroup + \dostoptagged} % \def\MPLIBtextext#1#2#3#4#5% % {\begingroup diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua index 0467498d0..a119b0836 100644 --- a/tex/context/base/mlib-run.lua +++ b/tex/context/base/mlib-run.lua @@ -41,9 +41,12 @@ local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming metapost = metapost or { } -metapost.showlog = false -metapost.lastlog = "" -metapost.texerrors = false +metapost.showlog = false +metapost.lastlog = "" +metapost.texerrors = false +metapost.exectime = metapost.exectime or { } -- hack + +local mplibone = tonumber(mplib.version()) <= 1.50 directives.register("mplib.texerrors", function(v) metapost.texerrors = v end) @@ -63,69 +66,6 @@ end metapost.finder = finder -metapost.parameters = { - hash_size = 100000, - main_memory = 4000000, - max_in_open = 50, - param_size = 100000, -} - -metapost.exectime = metapost.exectime or { } -- hack - -local preamble = [[ -boolean mplib; string mp_parent_version; -mplib := true; -mp_parent_version := "%s"; -input %s ; dump ; -]] - -function metapost.make(name, target, version) - starttiming(mplib) - target = file.replacesuffix(target or name, "mem") - local mpx = mplib.new ( table.merged ( - metapost.parameters, - { - ini_version = true, - find_file = finder, - job_name = file.removesuffix(target), - } - ) ) - if mpx then - starttiming(metapost.exectime) - local result = mpx:execute(format(preamble,version or "unknown",name)) - stoptiming(metapost.exectime) - mpx:finish() - end - stoptiming(mplib) -end - -function metapost.load(name) - starttiming(mplib) - local mpx = mplib.new ( table.merged ( - metapost.parameters, - { - ini_version = false, - mem_name = file.replacesuffix(name,"mem"), - find_file = finder, - -- job_name = "mplib", - } - ) ) - local result - if not mpx then - result = { status = 99, error = "out of memory"} - end - stoptiming(mplib) - return mpx, result -end - -function metapost.unload(mpx) - starttiming(mplib) - if mpx then - mpx:finish() - end - stoptiming(mplib) -end - function metapost.reporterror(result) if not result then report_mplib("mp error: no result object returned") @@ -149,90 +89,148 @@ function metapost.reporterror(result) return true end ---~ function metapost.checkformat(mpsinput) ---~ local mpsversion = environment.version or "unset version" ---~ local mpsinput = file.addsuffix(mpsinput or "metafun", "mp") ---~ local mpsformat = file.removesuffix(file.basename(mpsformat or texconfig.formatname or (tex and tex.formatname) or mpsinput)) ---~ local mpsbase = file.removesuffix(file.basename(mpsinput)) ---~ if mpsbase ~= mpsformat then ---~ mpsformat = mpsformat .. "-" .. mpsbase ---~ end ---~ mpsformat = file.addsuffix(mpsformat, "mem") ---~ local pth = file.dirname(texconfig.formatname or "") -- to be made dynamic ---~ if pth ~= "" then ---~ mpsformat = file.join(pth,mpsformat) ---~ end ---~ if lfs.isfile(mpsformat) then ---~ commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformat) ---~ local mpx, result = metapost.load(mpsformat) ---~ if mpx then ---~ local result = mpx:execute("show mp_parent_version ;") ---~ if not result.log then ---~ metapost.reporterror(result) ---~ else ---~ local version = match(result.log,">> *(.-)[\n\r]") or "unknown" ---~ version = gsub(version,"[\'\"]","") ---~ if version ~= mpsversion then ---~ commands.writestatus("mplib","version mismatch: %s <> %s", version or "unknown", mpsversion) ---~ else ---~ return mpx ---~ end ---~ end ---~ else ---~ commands.writestatus("mplib","error in loading '%s' from '%s'", mpsinput, mpsformat) ---~ metapost.reporterror(result) ---~ end ---~ end ---~ commands.writestatus("mplib","making '%s' into '%s'", mpsinput, mpsformat) ---~ metapost.make(mpsinput,mpsformat,mpsversion) -- somehow return ... fails here ---~ if lfs.isfile(mpsformat) then ---~ commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformat) ---~ return metapost.load(mpsformat) ---~ else ---~ commands.writestatus("mplib","problems with '%s' from '%s'", mpsinput, mpsformat) ---~ end ---~ end - -function metapost.checkformat(mpsinput) - local mpsversion = environment.version or "unset version" - local mpsinput = file.addsuffix(mpsinput or "metafun", "mp") - local mpsformat = file.removesuffix(file.basename(texconfig.formatname or (tex and tex.formatname) or mpsinput)) - local mpsbase = file.removesuffix(file.basename(mpsinput)) - if mpsbase ~= mpsformat then - mpsformat = mpsformat .. "-" .. mpsbase - end - mpsformat = file.addsuffix(mpsformat, "mem") - local mpsformatfullname = caches.getfirstreadablefile(mpsformat,"formats") or "" - if mpsformatfullname ~= "" then - commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformatfullname) - local mpx, result = metapost.load(mpsformatfullname) +if mplibone then + + local preamble = [[ + boolean mplib ; mplib := true ; + string mp_parent_version ; mp_parent_version := "%s" ; + input %s ; dump ; + ]] + + metapost.parameters = { + hash_size = 100000, + main_memory = 4000000, + max_in_open = 50, + param_size = 100000, + } + + function metapost.make(name, target, version) + starttiming(mplib) + target = file.replacesuffix(target or name, "mem") + local mpx = mplib.new ( table.merged ( + metapost.parameters, + { + ini_version = true, + find_file = finder, + job_name = file.removesuffix(target), + } + ) ) if mpx then - local result = mpx:execute("show mp_parent_version ;") - if not result.log then - metapost.reporterror(result) - else - local version = match(result.log,">> *(.-)[\n\r]") or "unknown" - version = gsub(version,"[\'\"]","") - if version ~= mpsversion then - commands.writestatus("mplib","version mismatch: %s <> %s", version or "unknown", mpsversion) + starttiming(metapost.exectime) + local result = mpx:execute(format(preamble,version or "unknown",name)) + stoptiming(metapost.exectime) + mpx:finish() + end + stoptiming(mplib) + end + + function metapost.load(name) + starttiming(mplib) + local mpx = mplib.new ( table.merged ( + metapost.parameters, + { + ini_version = false, + mem_name = file.replacesuffix(name,"mem"), + find_file = finder, + -- job_name = "mplib", + } + ) ) + local result + if not mpx then + result = { status = 99, error = "out of memory"} + end + stoptiming(mplib) + return mpx, result + end + + function metapost.checkformat(mpsinput) + local mpsversion = environment.version or "unset version" + local mpsinput = file.addsuffix(mpsinput or "metafun", "mp") + local mpsformat = file.removesuffix(file.basename(texconfig.formatname or (tex and tex.formatname) or mpsinput)) + local mpsbase = file.removesuffix(file.basename(mpsinput)) + if mpsbase ~= mpsformat then + mpsformat = mpsformat .. "-" .. mpsbase + end + mpsformat = file.addsuffix(mpsformat, "mem") + local mpsformatfullname = caches.getfirstreadablefile(mpsformat,"formats") or "" + if mpsformatfullname ~= "" then + commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformatfullname) + local mpx, result = metapost.load(mpsformatfullname) + if mpx then + local result = mpx:execute("show mp_parent_version ;") + if not result.log then + metapost.reporterror(result) else - return mpx + local version = match(result.log,">> *(.-)[\n\r]") or "unknown" + version = gsub(version,"[\'\"]","") + if version ~= mpsversion then + commands.writestatus("mplib","version mismatch: %s <> %s", version or "unknown", mpsversion) + else + return mpx + end end + else + commands.writestatus("mplib","error in loading '%s' from '%s'", mpsinput, mpsformatfullname) + metapost.reporterror(result) end + end + local mpsformatfullname = caches.setfirstwritablefile(mpsformat,"formats") + commands.writestatus("mplib","making '%s' into '%s'", mpsinput, mpsformatfullname) + metapost.make(mpsinput,mpsformatfullname,mpsversion) -- somehow return ... fails here + if lfs.isfile(mpsformatfullname) then + commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformatfullname) + return metapost.load(mpsformatfullname) + else + commands.writestatus("mplib","problems with '%s' from '%s'", mpsinput, mpsformatfullname) + end + end + +else + + local preamble = [[ + boolean mplib ; mplib := true ; + let dump = endinput ; + input %s ; + ]] + + function metapost.load(name) + starttiming(mplib) + local mpx = mplib.new { + ini_version = true, + find_file = finder, + } + local result + if not mpx then + result = { status = 99, error = "out of memory"} + else + result = mpx:execute(format(preamble, file.replacesuffix(name,"mp"))) + end + stoptiming(mplib) + metapost.reporterror(result) + return mpx, result + end + + function metapost.checkformat(mpsinput) + local mpsversion = environment.version or "unset version" + local mpsinput = file.addsuffix(mpsinput or "metafun", "mp") + commands.writestatus("mplib","loading '%s' (experimental metapost version two)",mpsinput) + local mpx, result = metapost.load(mpsinput) + if mpx then + return mpx else - commands.writestatus("mplib","error in loading '%s' from '%s'", mpsinput, mpsformatfullname) + commands.writestatus("mplib","error in loading '%s'",mpsinput) metapost.reporterror(result) end end - local mpsformatfullname = caches.setfirstwritablefile(mpsformat,"formats") - commands.writestatus("mplib","making '%s' into '%s'", mpsinput, mpsformatfullname) - metapost.make(mpsinput,mpsformatfullname,mpsversion) -- somehow return ... fails here - if lfs.isfile(mpsformatfullname) then - commands.writestatus("mplib","loading '%s' from '%s'", mpsinput, mpsformatfullname) - return metapost.load(mpsformatfullname) - else - commands.writestatus("mplib","problems with '%s' from '%s'", mpsinput, mpsformatfullname) + +end + +function metapost.unload(mpx) + starttiming(mplib) + if mpx then + mpx:finish() end + stoptiming(mplib) end local mpxformats = { } diff --git a/tex/context/base/mult-de.tex b/tex/context/base/mult-de.tex index f6f4f3bf9..608fdb1f8 100644 --- a/tex/context/base/mult-de.tex +++ b/tex/context/base/mult-de.tex @@ -90,6 +90,7 @@ \setinterfacevariable{bib}{bib} \setinterfacevariable{big}{gross} \setinterfacevariable{bigbodyfont}{bigbodyfont} +\setinterfacevariable{bigger}{bigger} \setinterfacevariable{bigpreference}{grosszuegig} \setinterfacevariable{blank}{blanko} \setinterfacevariable{blockquote}{blockquote} @@ -364,6 +365,7 @@ \setinterfacevariable{random}{zufaellig} \setinterfacevariable{readonly}{nurlesbar} \setinterfacevariable{rectangular}{rechteckig} +\setinterfacevariable{reference}{referenz} \setinterfacevariable{referral}{merkmal} \setinterfacevariable{register}{register} \setinterfacevariable{regular}{regular} @@ -411,6 +413,7 @@ \setinterfacevariable{smallbolditalic}{kleinfettitalic} \setinterfacevariable{smallboldslanted}{kleinfettgeneigt} \setinterfacevariable{smallcaps}{smallcaps} +\setinterfacevariable{smaller}{smaller} \setinterfacevariable{smallitalic}{kleinitalic} \setinterfacevariable{smallitalicbold}{kleinitalicfett} \setinterfacevariable{smallnormal}{kleinnormal} diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua index ce5af2bba..d877ad0f2 100644 --- a/tex/context/base/mult-def.lua +++ b/tex/context/base/mult-def.lua @@ -11143,6 +11143,14 @@ return { ["en"]="up", ["nl"]="omhoog", }, + ["smaller"]={ + ["en"]="smaller", + ["nl"]="kleiner", + }, + ["bigger"]={ + ["en"]="bigger", + ["nl"]="groter", + }, ["underbar"]={ ["cs"]="podtrzeno", ["de"]="unterstrichen", @@ -14721,6 +14729,16 @@ return { ["pe"]="مراجعه", ["ro"]="referinta", }, + ["reference"]={ + ["cs"]="odkaz", + ["de"]="referenz", + ["en"]="reference", + ["fr"]="reference", + ["it"]="riferimento", + ["nl"]="referentie", + ["pe"]="مرجع", + ["ro"]="referinta", + }, ["register"]={ ["cs"]="rejstrik", ["de"]="register", diff --git a/tex/context/base/mult-en.tex b/tex/context/base/mult-en.tex index 20917a034..cbaeb50d6 100644 --- a/tex/context/base/mult-en.tex +++ b/tex/context/base/mult-en.tex @@ -90,6 +90,7 @@ \setinterfacevariable{bib}{bib} \setinterfacevariable{big}{big} \setinterfacevariable{bigbodyfont}{bigbodyfont} +\setinterfacevariable{bigger}{bigger} \setinterfacevariable{bigpreference}{bigpreference} \setinterfacevariable{blank}{blank} \setinterfacevariable{blockquote}{blockquote} @@ -364,6 +365,7 @@ \setinterfacevariable{random}{random} \setinterfacevariable{readonly}{readonly} \setinterfacevariable{rectangular}{rectangular} +\setinterfacevariable{reference}{reference} \setinterfacevariable{referral}{referral} \setinterfacevariable{register}{register} \setinterfacevariable{regular}{regular} @@ -411,6 +413,7 @@ \setinterfacevariable{smallbolditalic}{smallbolditalic} \setinterfacevariable{smallboldslanted}{smallboldslanted} \setinterfacevariable{smallcaps}{smallcaps} +\setinterfacevariable{smaller}{smaller} \setinterfacevariable{smallitalic}{smallitalic} \setinterfacevariable{smallitalicbold}{smallitalicbold} \setinterfacevariable{smallnormal}{smallnormal} diff --git a/tex/context/base/mult-fr.tex b/tex/context/base/mult-fr.tex index 5244565e9..05b4ed1db 100644 --- a/tex/context/base/mult-fr.tex +++ b/tex/context/base/mult-fr.tex @@ -90,6 +90,7 @@ \setinterfacevariable{bib}{bib} \setinterfacevariable{big}{grand} \setinterfacevariable{bigbodyfont}{grandepolicecorp} +\setinterfacevariable{bigger}{bigger} \setinterfacevariable{bigpreference}{grandepreference} \setinterfacevariable{blank}{vide} \setinterfacevariable{blockquote}{blockquote} @@ -364,6 +365,7 @@ \setinterfacevariable{random}{aleatoire} \setinterfacevariable{readonly}{lectureseule} \setinterfacevariable{rectangular}{rectangulaire} +\setinterfacevariable{reference}{reference} \setinterfacevariable{referral}{referral} \setinterfacevariable{register}{registre} \setinterfacevariable{regular}{regulier} @@ -411,6 +413,7 @@ \setinterfacevariable{smallbolditalic}{italiquegraspetit} \setinterfacevariable{smallboldslanted}{inclinegraspetit} \setinterfacevariable{smallcaps}{petitescapitales} +\setinterfacevariable{smaller}{smaller} \setinterfacevariable{smallitalic}{italiquepetit} \setinterfacevariable{smallitalicbold}{grasitaliquepetit} \setinterfacevariable{smallnormal}{normalpetit} diff --git a/tex/context/base/mult-it.tex b/tex/context/base/mult-it.tex index ce14800de..5bac8d0b0 100644 --- a/tex/context/base/mult-it.tex +++ b/tex/context/base/mult-it.tex @@ -90,6 +90,7 @@ \setinterfacevariable{bib}{bib} \setinterfacevariable{big}{grande} \setinterfacevariable{bigbodyfont}{grossofontdeltesto} +\setinterfacevariable{bigger}{bigger} \setinterfacevariable{bigpreference}{grandepreferenza} \setinterfacevariable{blank}{rigovuoto} \setinterfacevariable{blockquote}{blockquote} @@ -364,6 +365,7 @@ \setinterfacevariable{random}{casuale} \setinterfacevariable{readonly}{solalettura} \setinterfacevariable{rectangular}{rettangolare} +\setinterfacevariable{reference}{riferimento} \setinterfacevariable{referral}{referral} \setinterfacevariable{register}{registro} \setinterfacevariable{regular}{regolare} @@ -411,6 +413,7 @@ \setinterfacevariable{smallbolditalic}{piccolograssettocorsivo} \setinterfacevariable{smallboldslanted}{piccolograssettoinclinato} \setinterfacevariable{smallcaps}{maiuscoletto} +\setinterfacevariable{smaller}{smaller} \setinterfacevariable{smallitalic}{piccolocorsivo} \setinterfacevariable{smallitalicbold}{piccolocorsivograssetto} \setinterfacevariable{smallnormal}{piccolonormale} diff --git a/tex/context/base/mult-nl.tex b/tex/context/base/mult-nl.tex index 074d5f3d5..58c106a22 100644 --- a/tex/context/base/mult-nl.tex +++ b/tex/context/base/mult-nl.tex @@ -90,6 +90,7 @@ \setinterfacevariable{bib}{bib} \setinterfacevariable{big}{groot} \setinterfacevariable{bigbodyfont}{grootkorps} +\setinterfacevariable{bigger}{groter} \setinterfacevariable{bigpreference}{grotevoorkeur} \setinterfacevariable{blank}{blanko} \setinterfacevariable{blockquote}{blokcitaat} @@ -364,6 +365,7 @@ \setinterfacevariable{random}{willekeurig} \setinterfacevariable{readonly}{alleenleesbaar} \setinterfacevariable{rectangular}{recht} +\setinterfacevariable{reference}{referentie} \setinterfacevariable{referral}{kenmerk} \setinterfacevariable{register}{register} \setinterfacevariable{regular}{regular} @@ -411,6 +413,7 @@ \setinterfacevariable{smallbolditalic}{kleinvetitalic} \setinterfacevariable{smallboldslanted}{kleinvetschuin} \setinterfacevariable{smallcaps}{smallcaps} +\setinterfacevariable{smaller}{kleiner} \setinterfacevariable{smallitalic}{kleinitalic} \setinterfacevariable{smallitalicbold}{kleinitalicvet} \setinterfacevariable{smallnormal}{kleinnormaal} diff --git a/tex/context/base/mult-ro.tex b/tex/context/base/mult-ro.tex index 738e49f72..48993ae1f 100644 --- a/tex/context/base/mult-ro.tex +++ b/tex/context/base/mult-ro.tex @@ -90,6 +90,7 @@ \setinterfacevariable{bib}{bib} \setinterfacevariable{big}{mare} \setinterfacevariable{bigbodyfont}{bigbodyfont} +\setinterfacevariable{bigger}{bigger} \setinterfacevariable{bigpreference}{preferintamare} \setinterfacevariable{blank}{blank} \setinterfacevariable{blockquote}{blockquote} @@ -364,6 +365,7 @@ \setinterfacevariable{random}{aleator} \setinterfacevariable{readonly}{readonly} \setinterfacevariable{rectangular}{rectangular} +\setinterfacevariable{reference}{referinta} \setinterfacevariable{referral}{referinta} \setinterfacevariable{register}{registru} \setinterfacevariable{regular}{regular} @@ -411,6 +413,7 @@ \setinterfacevariable{smallbolditalic}{micaldininclinat} \setinterfacevariable{smallboldslanted}{micaldininclinat} \setinterfacevariable{smallcaps}{majusculemici} +\setinterfacevariable{smaller}{smaller} \setinterfacevariable{smallitalic}{micitalic} \setinterfacevariable{smallitalicbold}{micitalicaldin} \setinterfacevariable{smallnormal}{micnormal} diff --git a/tex/context/base/mult-sys.tex b/tex/context/base/mult-sys.tex index 8804c470b..8b00b8d73 100644 --- a/tex/context/base/mult-sys.tex +++ b/tex/context/base/mult-sys.tex @@ -233,6 +233,7 @@ \definesystemconstant {handling} \definesystemconstant {features} \definesystemconstant {fallbacks} +\definesystemconstant {goodies} \definesystemconstant {background} \definesystemconstant {ucmap} @@ -491,6 +492,7 @@ \definesystemvariable {ds} % DoorSpringen \definesystemvariable {ef} % ExternFiguur \definesystemvariable {ec} % EnCoding +\definesystemvariable {el} % Elements \definesystemvariable {en} % ENvironments \definesystemvariable {ep} % ExternfiguurPreset \definesystemvariable {eq} % EQalign @@ -564,6 +566,7 @@ \definesystemvariable {ma} % MargeAchtergrond \definesystemvariable {mb} % MargeBlokken \definesystemvariable {md} % MoDule +\definesystemvariable {me} % MultilingualElement (tags) \definesystemvariable {mg} % Metapost paGe \definesystemvariable {mh} % MultilingualHead \definesystemvariable {mk} % MarKering diff --git a/tex/context/base/node-acc.lua b/tex/context/base/node-acc.lua new file mode 100644 index 000000000..f5c33a793 --- /dev/null +++ b/tex/context/base/node-acc.lua @@ -0,0 +1,102 @@ +if not modules then modules = { } end modules ['node-acc'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local traverse_nodes, traverse_id, has_attribute, copy_node = node.traverse, node.traverse_id, node.has_attribute, node.copy + +nodes.accessibility = nodes.accessibility or { } + +local glue = node.id("glue") +local glyph = node.id("glyph") +local hlist = node.id("hlist") +local vlist = node.id("vlist") + +local function injectspaces(head) + local p + for n in traverse_nodes(head) do + local id = n.id + if id == glue then -- todo: check for subtype related to spacing (13/14 but most seems to be 0) + -- local at = has_attribute(n,attribute) + -- if at then + if p and p.id == glyph then + local g = copy_node(p) + local s = copy_node(n.spec) + g.char, n.spec = 32, s + p.next, g.prev = g, p + g.next, n.prev = n, g + s.width = s.width - g.width + end + -- end + elseif id == hlist or id == vlist then + injectspaces(n.list,attribute) + end + p = n + end + return head, true +end + +nodes.accessibility.handler = injectspaces + +-- nodes.accessibility.handler(tex.box[255].list) + +-- todo: + +--~ local a_hyphenated = attributes.private('hyphenated') +--~ +--~ local hyphenated, codes = { }, { } +--~ +--~ local function compact(n) +--~ local t = { } +--~ for n in traverse_id(glyph,n) do +--~ t[#t+1] = utfchar(n.char) -- check for unicode +--~ end +--~ return concat(t,"") +--~ end +--~ +--~ local function injectspans(head) +--~ for n in traverse_nodes(head) do +--~ local id = n.id +--~ if id == disc then +--~ local r, p = n.replace, n.pre +--~ if r and p then +--~ local str = compact(r) +--~ local hsh = hyphenated[str] +--~ if not hsh then +--~ hsh = #codes + 1 +--~ hyphenated[str] = hsh +--~ codes[hsh] = str +--~ end +--~ set_attribute(n,a_hyphenated,hsh) +--~ end +--~ elseif id == hlist or id == vlist then +--~ injectspans(n.list) +--~ end +--~ end +--~ return head, true +--~ end +--~ +--~ nodes.injectspans = injectspans +--~ +--~ tasks.appendaction("processors", "words", "nodes.injectspans") +--~ +--~ local function injectspans(head) +--~ for n in traverse_nodes(head) do +--~ local id = n.id +--~ if id == disc then +--~ local a = has_attribute(n,a_hyphenated) +--~ if a then +--~ local str = codes[a] +--~ local b = new_pdfliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str))) +--~ local e = new_pdfliteral("EMC") +--~ node.insert_before(head,n,b) +--~ node.insert_after(head,n,e) +--~ end +--~ elseif id == hlist or id == vlist then +--~ injectspans(n.list) +--~ end +--~ end +--~ end diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua index 9ed71fd72..5ddf31e25 100644 --- a/tex/context/base/node-aux.lua +++ b/tex/context/base/node-aux.lua @@ -8,9 +8,11 @@ if not modules then modules = { } end modules ['node-aux'] = { local gsub, format = string.gsub, string.format -local free_node = node.free -local hpack_nodes = node.hpack -local node_fields = node.fields +local free_node, hpack_nodes, node_fields, traverse_nodes = node.free, node.hpack, node.fields, node.traverse +local has_attribute, set_attribute, unset_attribute, has_attribute = node.has_attribute, node.set_attribute, node.unset_attribute,node.has_attribute + +local hlist = node.id("hlist") +local vlist = node.id("vlist") function nodes.repack_hlist(list,...) local temp, b = hpack_nodes(list,...) @@ -143,3 +145,42 @@ end -- end -- end + +local function set_attributes(head,attr,value) + for n in traverse_nodes(head) do + set_attribute(n,attr,value) + local id = n.id + if id == hlist or id == vlist then + set_attributes(n.list,attr,value) + end + end +end + +local function set_unset_attributes(head,attr,value) + for n in traverse_nodes(head) do + if not has_attribute(n,attr) then + set_attribute(n,attr,value) + end + local id = n.id + if id == hlist or id == vlist then + set_unset_attributes(n.list,attr,value) + end + end +end + +local function unset_attributes(head,attr) + for n in traverse_nodes(head) do + unset_attribute(n,attr) + local id = n.id + if id == hlist or id == vlist then + unset_attributes(n.list,attr) + end + end +end + +nodes.set_attribute = set_attribute +nodes.unset_attribute = unset_attribute +nodes.has_attribute = has_attribute +nodes.set_attributes = set_attributes +nodes.set_unset_attributes = set_unset_attributes +nodes.unset_attributes = unset_attributes diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv index 23cf7b842..a5559e85d 100644 --- a/tex/context/base/node-ini.mkiv +++ b/tex/context/base/node-ini.mkiv @@ -32,6 +32,7 @@ \registerctxluafile{node-ext}{1.001} \registerctxluafile{node-inj}{1.001} % we might split it off \registerctxluafile{node-typ}{1.001} % experimental +\registerctxluafile{node-acc}{1.001} % experimental \newcount\shownodescounter diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index e85b50910..a25cf1f4a 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -338,7 +338,9 @@ nodes.setreference = setreference local function makereference(width,height,depth,reference) local sr = stack[reference] if sr then - report_backends("resolving reference attribute %s",reference) + if trace_references then + report_backends("resolving reference attribute %s",reference) + end local resolved, ht, dp, set = sr[1], sr[2], sr[3], sr[4] if ht then if height < ht then height = ht end @@ -363,10 +365,10 @@ local function makereference(width,height,depth,reference) result.width, result.height, result.depth = 0, 0, 0 if cleanupreferences then stack[reference] = nil end return result, resolved - else + elseif trace_references then report_backends("unable to resolve reference annotation %s",reference) end - else + elseif trace_references then report_backends("unable to resolve reference attribute %s",reference) end end @@ -402,7 +404,9 @@ nodes.setdestination = setdestination local function makedestination(width,height,depth,reference) local sr = stack[reference] if sr then - report_backends("resolving destination attribute %s",reference) + if trace_destinations then + report_backends("resolving destination attribute %s",reference) + end local resolved, ht, dp, name, view = sr[1], sr[2], sr[3], sr[4], sr[5] if ht then if height < ht then height = ht end @@ -443,7 +447,7 @@ local function makedestination(width,height,depth,reference) result.width, result.height, result.depth = 0, 0, 0 if cleanupdestinations then stack[reference] = nil end return result, resolved - else + elseif trace_destinations then report_backends("unable to resolve destination attribute %s",reference) end end diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua index 21bcae1d4..546f56916 100644 --- a/tex/context/base/node-res.lua +++ b/tex/context/base/node-res.lua @@ -290,4 +290,4 @@ statistics.register("node memory usage", function() -- comes after cleanup ! return status.node_mem_usage end) -lua.registerfinalizer(nodes.cleanup_reserved) +lua.registerfinalizer(nodes.cleanup_reserved, "cleanup reserved nodes") diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua index 74a730893..5e1df2da4 100644 --- a/tex/context/base/node-rul.lua +++ b/tex/context/base/node-rul.lua @@ -17,28 +17,33 @@ local rule = node.id("rule") function nodes.strip_range(first,last) -- todo: dir if first and last then -- just to be sure - local current = first - while current and current ~= last do - local id = current.id - if id == glyph or id == disc then - --~ if id == glyph or id == rule or id == disc then - first = current + if first == last then + return first, last + end + while first and first ~= last do + local id = first.id + if id == glyph or id == disc then -- or id == rule break else - current = current.next + first = first.next end end - local current = last - while current and current ~= first do - local id = current.id - --~ if id == glyph or id == rule or id == disc then - if id == glyph or id == disc then - last = current + if not first then + return nil, nil + elseif first == last then + return first, last + end + while last and last ~= first do + local id = last.id + if id == glyph or id == disc then -- or id == rule break else - current = current.prev + last = last.prev end end + if not last then + return nil, nil + end end return first, last end @@ -94,11 +99,13 @@ local checkdir = true -- this one needs to take layers into account (i.e. we need a list of -- critical attributes) +-- omkeren class en level -> scheelt functie call in analyse + local function process_words(attribute,data,flush,head,parent) -- we have hlistdir and local dir local n = head if n then - local f, l, a, d, i, level - local continue, done, strip = false, false, false + local f, l, a, d, i, class + local continue, done, strip, level = false, false, true, -1 while n do local id = n.id if id == glyph or id == rule then @@ -111,12 +118,18 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd l = n else -- possible extensions: when in same class then keep spanning + local newlevel, newclass = floor(aa/1000), aa%1000 +--~ strip = not continue or level == 1 -- 0 if f then - head, done = flush(head,f,l,d,level,parent,strip), true + if class == newclass then -- and newlevel > level then + head, done = flush(head,f,l,d,level,parent,false), true + else + head, done = flush(head,f,l,d,level,parent,strip), true + end end f, l, a = n, n, aa - level, i = floor(a/1000), a%1000 - d = data[i] + level, class = newlevel, newclass + d = data[class] continue = d.continue == variables.yes end else @@ -142,10 +155,18 @@ local function process_words(attribute,data,flush,head,parent) -- we have hlistd end elseif f then if continue then - if id == penalty or id == kern then + if id == penalty then l = n - elseif id == glue then + elseif id == kern then l = n + elseif id == glue then + -- catch \underbar{a} \underbar{a} (subtype test is needed) + if continue and has_attribute(n,attribute) and n.subtype == 0 then + l = n + else + head, done = flush(head,f,l,d,level,parent,strip), true + f, l, a = nil, nil, nil + end end else head, done = flush(head,f,l,d,level,parent,strip), true @@ -183,13 +204,23 @@ local a_viewerlayer = attributes.private("viewerlayer") local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose -- check for f and l -if f.id ~= glyph then - -- saveguard ... we need to deal with rules and so (math) - return head -end + if f.id ~= glyph then + -- saveguard ... we need to deal with rules and so (math) + return head + end local r, m - if true then - f, l = strip_range(f,l) + if strip then + if trace_ruled then + local before = n_tosequence(f,l,true) + f, l = strip_range(f,l) + local after = n_tosequence(f,l,true) + report_ruled("range stripper: %s -> %s",before,after) + else + f, l = strip_range(f,l) + end + end + if not f then + return head end local w = list_dimensions(parent.glue_set,parent.glue_sign,parent.glue_order,f,l.next) local method, offset, continue, dy, rulethickness, unit, order, max, ma, ca, ta = @@ -214,11 +245,11 @@ end local dp = -(offset+(i-1)*dy-rulethickness)*e + m local r = new_rule(w,ht,dp) local v = has_attribute(f,a_viewerlayer) --- quick hack -if v then - set_attribute(r,a_viewerlayer,v) -end --- + -- quick hack + if v then + set_attribute(r,a_viewerlayer,v) + end + -- if color then set_attribute(r,a_colorspace,colorspace) set_attribute(r,a_color,color) diff --git a/tex/context/base/node-rul.mkiv b/tex/context/base/node-rul.mkiv index 1270eb81d..8e6aa5790 100644 --- a/tex/context/base/node-rul.mkiv +++ b/tex/context/base/node-rul.mkiv @@ -122,11 +122,13 @@ \glet\dodoruled\dodoruledindeed \dodoruled} -\def\dodoruledindeed#1% +\def\dodoruledindeed#1% maybe reverse the 1000 {\advance\csname\??on:#1:c\endcsname\plusone \scratchcounter\csname\??on:#1:c\endcsname - \attribute\ruledattribute\numexpr1000*\scratchcounter - +\csname\??on#1\ifcsname\??on#1:\number\scratchcounter\s!parent\endcsname:\number\scratchcounter\fi:a\endcsname} + \attribute\ruledattribute\numexpr + 1000*\scratchcounter + +\csname\??on#1\ifcsname\??on#1:\number\scratchcounter\s!parent\endcsname:\number\scratchcounter\fi:a\endcsname + \relax} % ungrouped diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index 880b21b81..d2d02c8df 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -343,7 +343,7 @@ function nodes.tosequence(start,stop,compact) if start.components then t[#t+1] = nodes.tosequence(start.components,nil,compact) else - t[#t+1] = format("%s",utfchar(c)) + t[#t+1] = utfchar(c) end else t[#t+1] = format("U+%04X:%s",c,utfchar(c)) diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv index afacc2901..272ef0544 100644 --- a/tex/context/base/pack-rul.mkiv +++ b/tex/context/base/pack-rul.mkiv @@ -2011,10 +2011,10 @@ %D sort of newline signal. In horizontal boxes it expands to a %D space. -\def\vboxednewline +\unexpanded\def\vboxednewline {\endgraf\ignorespaces} -\def\hboxednewline +\unexpanded\def\hboxednewline {\unskip\normalspace\ignorespaces} %D We can set each rule on or off. The default setting is diff --git a/tex/context/base/page-ini.mkiv b/tex/context/base/page-ini.mkiv index 07d342282..497551f46 100644 --- a/tex/context/base/page-ini.mkiv +++ b/tex/context/base/page-ini.mkiv @@ -300,11 +300,14 @@ \expandafter\invokenormaloutputroutine \fi} -\mainoutput{\invokeoutputroutine} \output{\inotrtrue\the\mainoutput} +\mainoutput{\invokeoutputroutine} %D Some hooks: -\output{\inotrtrue\the\everybeforeoutput\the\mainoutput\the\everyafteroutput} +\def\setoutputroutine#1% + {\global\output{\inotrtrue\the\everybeforeoutput#1\the\everyafteroutput}} + +\setoutputroutine{\the\mainoutput} \ifx\pagediscards\undefined \let\pagediscards\relax \fi diff --git a/tex/context/base/page-mul.mkiv b/tex/context/base/page-mul.mkiv index c64fd0c64..791f328c5 100644 --- a/tex/context/base/page-mul.mkiv +++ b/tex/context/base/page-mul.mkiv @@ -443,12 +443,14 @@ \vskip-\struttotal \fi \global\savedpagetotal\pagetotal - \global\singlecolumnout\output + \global\singlecolumnout\output % hm %\global\output{\global\setbox\precolumnbox\vbox{\unvbox\normalpagebox}}% - \global\output{\global\setbox\precolumnbox\vbox{\dotopinsertions\unvbox\normalpagebox}}% + %\global\output{\global\setbox\precolumnbox\vbox{\dotopinsertions\unvbox\normalpagebox}}% + \setoutputroutine{\global\setbox\precolumnbox\vbox{\dotopinsertions\unvbox\normalpagebox}}% \eject % no \holdinginserts=1, can make footnote disappear ! \global\precolumnboxheight\ht\precolumnbox - \global\output{\continuousmulticolumnsout}% + %\global\output{\continuousmulticolumnsout}% + \setoutputroutine{\continuousmulticolumnsout}% \setcolumnfloats \dohandleallcolumns {\global\setbox\currenttopcolumnbox\emptybox}% @@ -493,17 +495,21 @@ \par \ifbalancecolumns \ifnum\multicolumnendsyncmethod=\plusone - \global\output{\continuousmulticolumnsout}% + %\global\output{\continuousmulticolumnsout}% + \setoutputroutine{\continuousmulticolumnsout}% \goodbreak \fi - \global\output{\balancedmulticolumnsout}% + %\global\output{\balancedmulticolumnsout}% + \setoutputroutine{\balancedmulticolumnsout}% \else \goodbreak \fi \eject % the prevdepth is important, try e.g. toclist in \prevdepth\zeropoint % columns before some noncolumned text text - \global\output\singlecolumnout - \global\output{\the\mainoutput}% % % % % todo + %\global\output\singlecolumnout + \setoutputroutine{\singlecolumnout}% + %\global\output{\the\mainoutput}% % % % % todo + \setoutputroutine{\the\mainoutput}% % % % % todo \ifvoid\precolumnbox\else \unvbox\precolumnbox \fi @@ -1160,7 +1166,8 @@ \showmessage\m!columns{10}\empty \global\setbox\firstcolumnbox\vbox{\unvbox0}% \fi - \global\output{\balancingerror}% + %\global\output{\balancingerror}% + \setoutputroutine{\balancingerror}% \b@selinebottomtrue % forces depth in separation rule \flushcolumnedpage\plusone \multicolumnseject diff --git a/tex/context/base/s-pre-69.tex b/tex/context/base/s-pre-69.tex new file mode 100644 index 000000000..d65940520 --- /dev/null +++ b/tex/context/base/s-pre-69.tex @@ -0,0 +1,314 @@ +%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] +%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)) + tex.sprint(tex.ctxcatcodes,string.format("\\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] + \ctxlua{document.SetParShape()} + \StartSteps} + +\def\StopItems + {\StopSteps + \stopstandardmakeup} + +\def\StartItem + {\dontleavehmode\llap{\symbol[mysymbol]\quad}\ignorespaces} + +\def\StopItem + {\removeunwantedspaces\nobreak\crlf\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()} + \StartSteps} + +\def\StopParagraphs + {\StopSteps + \stopstandardmakeup} + +\def\StartParagraph + {} + +\def\StopParagraph + {\par\FlushStep} + +\doifnotmode{demo}{\endinput} + +% 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/tex/context/base/strc-bkm.lua b/tex/context/base/strc-bkm.lua index f34d83ec5..79ed867de 100644 --- a/tex/context/base/strc-bkm.lua +++ b/tex/context/base/strc-bkm.lua @@ -9,6 +9,8 @@ if not modules then modules = { } end modules ['strc-bkm'] = { -- Future version will support adding arbitrary bookmarks with -- associated complex actions (rather trivial to implement). +-- this should become proper separated backend code + local format, concat, gsub = string.format, table.concat, string.gsub local texsprint, utfvalues = tex.sprint, string.utfvalues @@ -100,7 +102,7 @@ function bookmarks.place() end end -lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1) +lpdf.registerdocumentfinalizer(function() structure.bookmarks.place() end,1,"bookmarks") -- bkm --~ function nodes.toutf(list) diff --git a/tex/context/base/strc-des.mkiv b/tex/context/base/strc-des.mkiv index 29e4ea36c..42ea701f0 100644 --- a/tex/context/base/strc-des.mkiv +++ b/tex/context/base/strc-des.mkiv @@ -375,6 +375,8 @@ \def\@@stopdescription {\@@placedescriptionclosesymbol \par % else we loose +\dostoptagged +\dostoptagged \endgroup \descriptionparameter\c!after % which currentdescription is taken here? \egroup % temporary hack @@ -420,15 +422,19 @@ \ifcsname @@description\currentdescriptionlocation\endcsname \else \let\currentdescriptionlocation\v!left \fi +\dostarttagged\t!description\currentdescription +\dostarttagged\t!descriptiontag\empty \@@dostartdescription - \csname @@description\currentdescriptionlocation\endcsname} % args not needed + \csname @@description\currentdescriptionlocation\endcsname +\dostoptagged +\dostarttagged\t!descriptioncontent\empty} % args not needed \def\@@makedescription[#1]#2% - {\postponenotes % new, assumes grouping - \edef\currentdescriptionreference{#1}% - \doenumerationcheckconditions - \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#2},\c!bookmark=,\c!list=][]% - \@@dostartdescriptionindeed} + {\postponenotes % new, assumes grouping + \edef\currentdescriptionreference{#1}% + \doenumerationcheckconditions + \dodescriptioncomponent[\c!reference=#1,\c!label={\descriptionparameter\c!text},\c!title={#2},\c!bookmark=,\c!list=][]% + \@@dostartdescriptionindeed} \def\dostartstoreddescription {\@@dostartdescriptionindeed} diff --git a/tex/context/base/strc-flt.mkiv b/tex/context/base/strc-flt.mkiv index ea52aa82d..1d5114390 100644 --- a/tex/context/base/strc-flt.mkiv +++ b/tex/context/base/strc-flt.mkiv @@ -313,14 +313,18 @@ \def\thecurrentfloatnumber {\ifnofloatcaption \else \ifnofloatnumber \else \ifx\currentfloatnumber\relax\else + \dostarttagged\t!floattag\empty \labeltexts\currentfloat{\ctxlua{structure.lists.savedprefixednumber("\currentfloat",\currentfloatnumber)}}% + \dostoptagged \fi \fi \fi} \def\thecurrentfloatcaption {\ifnofloatcaption \else \ifx\currentfloatnumber\relax\else + \dostarttagged\t!floattext\empty \ctxlua{structure.lists.savedtitle("\currentfloat",\currentfloatnumber)}% + \dostoptagged \fi \fi} @@ -368,11 +372,11 @@ \begingroup \dosetfloatcaptionattributes\c!style\c!color \begingroup - \dosetfloatcaptionattributes\c!headstyle\c!headcolor + \dosetfloatcaptionattributes\c!headstyle\c!headcolor \labeltexts{#1}{\preparednumber}% \endgroup \begingroup - \dosetfloatcaptionattributes\c!textstyle\c!textcolor + \dosetfloatcaptionattributes\c!textstyle\c!textcolor \dotfskip{\floatcaptionparameter\c!distance}#3% \endgroup \endgroup}% @@ -611,6 +615,7 @@ \fi \global\insidefloattrue \begingroup % ** + \dostarttagged\t!float\currentfloat \ifmarginblocks \doifinset\v!margin{#2}{\hsize\@@mbwidth}% \fi @@ -620,15 +625,17 @@ \dowithnextboxcontent % better a \the\everyfloattoks {\setlocalfloathsize \floatparameter\c!inner + \dostarttagged\t!floatcontent\empty + \aftergroup\dostoptagged % tricky, never change \dowithnextboxcontent \postponenotes} % new {\doifsomething{\floatparameter\c!criterium} {\ifdim\wd\nextbox>\floatparameter\c!criterium\relax \edef\forcedfloatmethod{\floatvariable\c!fallback}% \ifx\forcedfloatmethod\empty\let\forcedfloatmethod\v!here\fi \fi}% - \xdocompletefloat{#1}{#3}{#2}{#4}% ** not yet done - % we need to carry over the par because of side floats - \doifnotinset\v!text{#2}{\carryoverpar\endgroup}% + \xdocompletefloat{#1}{#3}{#2}{#4}% ** not yet done + % we need to carry over the par because of side floats + \doifnotinset\v!text{#2}{\dostoptagged\carryoverpar\endgroup}% ** \global\sidefloatdownshift \zeropoint \global\sidefloatextrashift\zeropoint \ifparfloat @@ -799,6 +806,7 @@ \egroup % place the float \dofloat{#3}{\thecurrentfloatnumber}{\thecurrentfloatcaption}% +% \dostoptagged % tricky here, we need an extra mechanism (add to previous or so) \global\insidefloatfalse} \def\setlocalfloathsize @@ -1129,8 +1137,10 @@ \doifnotinset\v!tall{#1}% {\dp\floatbox\openstrutdepth}% dp\strutbox}% % toegevoegd \box\floatbox + \dostoptagged \blank[\floatsharedparameter\c!spaceafter]% \endgroup % ** +% \dostoptagged \doinsertfloatinfo} \def\somefacefloat[#1]% links, rechts, midden, hoog, midden, laag @@ -1271,7 +1281,8 @@ \locatefloat{\copy\tempfloatbox}}} \def\dopreparedocaption#1#2#3% - {\doifinsetelse{\floatcaptionparameter\c!location}{\v!top,\v!bottom} + {\dostarttagged\t!floatcaption\empty + \doifinsetelse{\floatcaptionparameter\c!location}{\v!top,\v!bottom} {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max} {\doifelse{\floatcaptionparameter\c!minwidth}\v!fit {\doifelse{\floatcaptionparameter\c!width}\v!max @@ -1287,7 +1298,8 @@ {\dopreparesidewidthcaption{#1}{#2}{#3}}}% new, special effects (see icare) {\doifinsetelse{\floatcaptionparameter\c!width}{\v!fit,\v!max} {\dopreparesideautocaption{#1}{#2}{#3}} - {\dopreparesidewidthcaption{#1}{#2}{#3}}}} + {\dopreparesidewidthcaption{#1}{#2}{#3}}}% + \dostoptagged} % \def\dosettempcaptionbox % {\dosetraggedvbox{\floatcaptionparameter\c!align}% diff --git a/tex/context/base/strc-itm.mkiv b/tex/context/base/strc-itm.mkiv index ab2f09f40..e012ce447 100644 --- a/tex/context/base/strc-itm.mkiv +++ b/tex/context/base/strc-itm.mkiv @@ -310,10 +310,12 @@ % \empty \else \getitemparameter\currentitemlevel\c!before - \fi\fi} + \fi\fi + \dostarttagged\t!itemgroup\currentitemgroup} \def\itemaftercommand - {\ifconditional\nowhitelistitem + {\dostoptagged + \ifconditional\nowhitelistitem \ifconditional\afterlistitem \ifcase\currentitemlevel\or\getitemparameter\currentitemlevel\c!after\fi \else @@ -769,7 +771,12 @@ \par \fi \dolistreference - \ifconditional\firstlistitem \else \endgroup \fi % toegevoegd, eerste \som opent groep + \ifconditional\firstlistitem + \else +\dostoptagged +\dostoptagged + \endgroup + \fi % toegevoegd, eerste \som opent groep \ifnum\itemcolumndepth=\currentitemlevel\relax \stopcolumns \global\itemcolumndepth\zerocount @@ -1142,6 +1149,9 @@ \chardef\autoitemgroupspacing=2 % 0 = voor/na, 1=tussen als geen voor 2=(prev)tussen=old/normal +% todo: assume startitem ... stopitem and do an autostopitem .. cleaner for +% elements + \def\complexdoitemgroupitem[#1]% {\def\currentitemreference{#1}% \ifconditional\textlistitem @@ -1176,6 +1186,8 @@ \fi \fi \else +\dostoptagged +\dostoptagged \ifconditional\textlistitem % was bugged: \inlinelistitem \ifhmode % WS: make the distance between items customizable, think about better default values -> see itemize-1.tex @@ -1190,7 +1202,10 @@ \vskip-\dimexpr\lastskip+\lineheight\relax \nobreak \fi +\dostarttagged\t!item\empty +\dostarttagged\t!itemtag\empty \dolistitem +\dostoptagged \relax \ifconditional\packlistitem \setupwhitespace[\v!none]% @@ -1198,6 +1213,7 @@ \getitemparameter\currentitemlevel\c!inner \marsymbol \let\marsymbol\relax +\dostarttagged\t!itemcontent\empty \strut % added 11-08-99 \setfalse\concatnextitem % new, concat \nobreak % else problems with intext items diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua index ea87715c9..6af062134 100644 --- a/tex/context/base/strc-lst.lua +++ b/tex/context/base/strc-lst.lua @@ -124,6 +124,26 @@ function lists.enhance(n) end end +function lists.enforce(n) + -- todo: symbolic names for counters + local l = cached[n] + if l then + -- + l.directives = nil -- might change + -- save in the right order (happens at shipout) + lists.tobesaved[#lists.tobesaved+1] = l + -- default enhancer (cross referencing) + l.references.realpage = texcount.realpageno + -- specific enhancer (kind of obsolete) + local kind = l.metadata.kind + local enhancer = kind and lists.enhancers[kind] + if enhancer then + enhancer(l) + end + return l + end +end + -- we can use level instead but we can also decide to remove level from the metadata local nesting = { } diff --git a/tex/context/base/strc-lst.mkiv b/tex/context/base/strc-lst.mkiv index bcf20c451..83faf75a7 100644 --- a/tex/context/base/strc-lst.mkiv +++ b/tex/context/base/strc-lst.mkiv @@ -97,6 +97,8 @@ %begingroup\attribute\destinationattribute\currentdestinationattribute\dontleavehmode\hbox{}\endgroup % todo \dontleavehmode\hbox attr \destinationattribute \currentdestinationattribute{}% todo % end of new + \else + \ctxlua{structure.lists.enhance(\currentlistnumber)}% direct injection \fi \endgroup} @@ -104,7 +106,8 @@ {\ctxlua{structure.lists.location(\currentlistindex)}} \def\structurelistpagenumber - {\ctxlua{structure.lists.prefixedpage( + {\dostarttagged\t!listpage\empty + \ctxlua{structure.lists.prefixedpage( "\currentlist", \currentlistindex, { @@ -120,25 +123,34 @@ starter = \!!bs\listparameter\c!pagestarter\!!es, stopper = \!!bs\listparameter\c!pagestopper\!!es, } - )}} + )}% + \dostoptagged} \def\structurelistrealpagenumber {\ctxlua{structure.lists.realpage("\currentlist",\currentlistindex)}} \def\structurelistfirst - {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"first")}} + {\dostarttagged\t!listdata{first} % ot always ok + \ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"first")}% + \dostoptagged} \def\structurelistsecond - {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"second")}} + {\dostarttagged\t!listdata{second}% + \ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"second")}% + \dostoptagged} \def\structurelistuservariable#1% - {\ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"#1")}} + {\dostarttagged\t!listdata{#1}% + \ctxlua{structure.lists.userdata("\currentlist",\currentlistindex,"#1")}% + \dostoptagged} % \appendtoks % \to \everystructurelist \unexpanded\def\placestructurelist#1#2#3% hm ... [][][] - {\ctxlua{structure.lists.process("#1","#2","#3")}} + {\dostarttagged\t!list\empty + \ctxlua{structure.lists.process("#1","#2","#3")}% + \dostoptagged} \unexpanded\def\analysestructurelist#1#2#3% {\ctxlua{structure.lists.analyze("#1","#2","#3")}} @@ -173,12 +185,14 @@ \edef\currentlist {#1}% \edef\currentlistmethod{#2}% \edef\currentlistindex {#3}% + \dostarttagged\t!listitem\currentlist \csname\@@structurelistprocess \ifcsname\@@structurelistprocess\currentlist:\currentlistmethod\endcsname\currentlist:\currentlistmethod\else \ifcsname\@@structurelistprocess\currentlistmethod \endcsname\currentlistmethod \else \ifcsname\@@structurelistprocess\currentlist \endcsname\currentlist \else \s!default \fi\fi\fi \endcsname + \dostoptagged \ctxlua{structure.lists.popnesting()}} % \installstructcurelistprocessor{pubs:userdata} @@ -902,10 +916,13 @@ \structurelistrealpagenumber} \def\structurelistgenerictitle - {\ctxlua{structure.lists.title("\currentlist",\currentlistindex)}} + {\dostarttagged\t!listcontent\empty + \ctxlua{structure.lists.title("\currentlist",\currentlistindex)}% + \dostoptagged} -\def\structurelistgenericnumber{\ctxlua{ - structure.lists.prefixednumber("\currentlist",\currentlistindex, { +\def\structurelistgenericnumber + {\dostarttagged\t!listtag\empty + \ctxlua{structure.lists.prefixednumber("\currentlist",\currentlistindex, { prefix = "\listparameter\c!prefix", separatorset = "\listparameter\c!prefixseparatorset", conversionset = "\listparameter\c!prefixconversionset", @@ -921,7 +938,8 @@ starter = \!!bs\listparameter\c!numberstarter\!!es, stopper = \!!bs\listparameter\c!numberstopper\!!es, segments = "\listparameter\c!numbersegments", - } )}} + } )}% + \dostoptagged} % new and yet undocumented (used in cocoa qa), temporarily disabled in mkiv % diff --git a/tex/context/base/strc-mat.mkiv b/tex/context/base/strc-mat.mkiv index 3728913cb..1e9bd8273 100644 --- a/tex/context/base/strc-mat.mkiv +++ b/tex/context/base/strc-mat.mkiv @@ -439,6 +439,7 @@ \def\dodostartformula[#1][#2]% setting leftskip adaption is slow ! {\bgroup % HERE \def\currentformula{#1}% + \dostarttagged\t!formula\currentformula \the\everybeforedisplayformula \formulaparskip\parskip \formulastrutdp\strutdepth @@ -453,7 +454,7 @@ \doifsomething{\formulaparameter\c!margin}% so we test first {\dosetleftskipadaption{\formulaparameter\c!margin}% \edef\leftdisplaymargin{\the\leftskipadaption}}% overloaded - \long\def\dostartformula##1{\bgroup\let\dostopformula\egroup}% + \long\def\dostartformula##1{\bgroup\dostarttagged\t!subformula\def\dostopformula{\dostoptagged\egroup}}% \freezedimenmacro\leftdisplayskip \freezedimenmacro\rightdisplayskip \freezedimenmacro\leftdisplaymargin @@ -474,8 +475,13 @@ \endgroup} \def\dostopformula - {\doplaceformulanumber + {\dostarttagged\t!formulatag\empty + \doplaceformulanumber + \dostoptagged + \dostarttagged\t!formulacontent\empty \getvalue{\e!stop\formulaparameter\c!alternative\v!formula}% + \dostoptagged + \dostoptagged \nonoindentation \checknextindentation[\formulaparameter\c!indentnext]% \egroup @@ -587,6 +593,7 @@ \def\dostartformulas[#1]#2\stopformulas % new / to be internationalized {\bgroup + \dostarttagged\t!formulaset\empty \global\settrue\insideformulas \edef\currentformulasreference{#1}% \handleformulasnumbering @@ -611,6 +618,7 @@ \egroup \stopdisplaymath \global\setfalse\insideformulas + \dostoptagged \egroup \the\everyresetformulas \hangafter\minusone % added for side floats diff --git a/tex/context/base/strc-not.lua b/tex/context/base/strc-not.lua index 1e761d657..466bc7a03 100644 --- a/tex/context/base/strc-not.lua +++ b/tex/context/base/strc-not.lua @@ -84,7 +84,8 @@ nodes.getn = getn -- we could make a special enhancer function notes.listindex(tag,n) - return notedata[tag][n] + local ndt = notedata[tag] + return ndt and ndt[n] end function notes.define(tag,kind,number) @@ -98,9 +99,10 @@ function notes.save(tag,newkind) if trace_notes then report_notes("saving state of '%s': %s -> %s",tag,state.kind,newkind or state.kind) end - state.saved = notedata[tag] + state.saveddata = notedata[tag] state.savedkind = state.kind state.kind = newkind or state.kind + state.saved = true notedata[tag] = { } end end @@ -111,9 +113,10 @@ function notes.restore(tag,forcedstate) if trace_notes then report_notes("restoring state of '%s': %s -> %s",tag,state.kind,state.savedkind) end - state.saved = nil + notedata[tag] = state.saveddata state.kind = forcedstate or state.savedkind - notedata[tag] = state.saved + state.saveddata = nil + state.saved = false end end @@ -249,13 +252,17 @@ function notes.postpone() end end -function notes.setsymbolpage(tag,n) - local l = notes.listindex(tag,n) - local p = texcount.realpageno - if trace_notes then - report_notes("note %s of '%s' with list index %s gets page %s",n,tag,l,p) +function notes.setsymbolpage(tag,n,l) + local l = l or notes.listindex(tag,n) + if l then + local p = texcount.realpageno + if trace_notes then + report_notes("note %s of '%s' with list index %s gets page %s",n,tag,l,p) + end + lists.cached[l].references.symbolpage = p + else + report_notes("internal error: note %s of '%s' is not initialized",n,tag) end - lists.cached[l].references.symbolpage = p end function notes.getsymbolpage(tag,n) diff --git a/tex/context/base/strc-not.mkiv b/tex/context/base/strc-not.mkiv index 751776326..58229a54f 100644 --- a/tex/context/base/strc-not.mkiv +++ b/tex/context/base/strc-not.mkiv @@ -637,15 +637,16 @@ \fi} \def\dolastnotesymbol - {\typesetsomenotesymbol\currentnote\currentnotenumber} + {\typesetsomenotesymbol\currentnote\currentnotenumber\currentdescriptionnumberentry} -\def\dotypesetsomenotesymbol#1#2% running text +\def\dotypesetsomenotesymbol#1#2#3% running text (messy: #1 and current mixed) {\dodonotesymbol - {\synchronizesomenotesymbol{#1}{#2}% - \ctxlua{structure.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry + {\synchronizesomenotesymbol{#1}{#2}{#3}% +% \ctxlua{structure.notes.number("\currentnote",\currentnotenumber)}% \currentdescriptionnumberentry + \ctxlua{structure.notes.number("#1",#2)}% \domovednote{#1}{#2}\v!previouspage\v!nextpage}} -\unexpanded\def\typesetsomenotesymbol#1#2% running text +\unexpanded\def\typesetsomenotesymbol#1#2#3% running text {\removeunwantedspaces \doifitalicelse\/\donothing % Charles IV \footnote{the fourth} \ifdim\lastkern=\notesignal @@ -653,8 +654,8 @@ \fi \nobreak \doifelse{\noteparameter\c!interaction}\v!no - {\dotypesetsomenotesymbol{#1}{#2}} - {\directgotobox{\dotypesetsomenotesymbol{#1}{#2}}[page(\ctxlua{structure.notes.getnumberpage("#1",\number#2)})]}% f: + {\dotypesetsomenotesymbol{#1}{#2}{#3}} + {\directgotobox{\dotypesetsomenotesymbol{#1}{#2}{#3}}[page(\ctxlua{structure.notes.getnumberpage("#1",\number#2)})]}% f: \globallet\lastnotesymbol\relax} \unexpanded\def\typesetdummynotesymbol % temp hack @@ -698,8 +699,10 @@ \ctxlua{structure.notes.number("\currentnote",\currentdescriptionnumberentry)}% \domovednote\currentdescription\currentdescriptionnumberentry\v!nextpage\v!previouspage}} -\def\synchronizesomenotesymbol#1#2% called more often than needed - {\normalexpanded{\noexpand\ctxlatelua{structure.notes.setsymbolpage("#1",#2)}}} +\def\synchronizesomenotesymbol#1#2#3% called more often than needed + {\iftrialtypesetting\else + \normalexpanded{\noexpand\ctxlatelua{structure.notes.setsymbolpage("#1",#2,#3)}}% + \fi} \def\handlenoteinsert#1#2% {\begingroup diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index f9b484173..8fab48697 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -902,7 +902,7 @@ local function identify(prefix,reference) set[i] = var end jobreferences.currentset = set --- print(bug,table.serialize(set)) +--~ print(bug,table.serialize(set)) return set, bug end diff --git a/tex/context/base/strc-ref.mkiv b/tex/context/base/strc-ref.mkiv index 921f5927e..91e975ea9 100644 --- a/tex/context/base/strc-ref.mkiv +++ b/tex/context/base/strc-ref.mkiv @@ -1081,7 +1081,9 @@ \begingroup \attribute\referenceattribute\attributeunsetvalue \iflocation +\dostarttagged\t!link\empty \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\ht\strutbox,\number\dp\strutbox,\extrareferencearguments)}% +\dostoptagged \setlocationattributes\??ia \setstrut % can be option \attribute\referenceattribute\lastreferenceattribute @@ -1094,7 +1096,9 @@ \begingroup \attribute\referenceattribute\attributeunsetvalue \iflocation +\dostarttagged\t!link\empty \ctxlua{jobreferences.inject("\referenceprefix","#2",\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax,\extrareferencearguments)}% +\dostoptagged \setlocationattributes\??ia \attribute\referenceattribute\lastreferenceattribute \fi @@ -1109,7 +1113,9 @@ \iflocation \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% {\expandtexincurrentreference +\dostarttagged\t!link\empty \ctxlua{jobreferences.injectcurrentset(\number\ht\strutbox,\number\dp\strutbox)}% +\dostoptagged \setlocationattributes\??ia \setstrut % can be option \attribute\referenceattribute\lastreferenceattribute}% @@ -1126,7 +1132,9 @@ \iflocation \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% {\expandtexincurrentreference +\dostarttagged\t!link\empty \ctxlua{jobreferences.injectcurrentset(\number\dimexpr\@@iaheight\relax,\number\dimexpr\@@iadepth\relax)}% +\dostoptagged \setlocationattributes\??ia \attribute\referenceattribute\lastreferenceattribute}% {\unknownreference{#3}}% @@ -1139,7 +1147,9 @@ \begingroup \attribute\referenceattribute\attributeunsetvalue \iflocation +\dostarttagged\t!link\empty \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% +\dostoptagged \setlocationattributes\??ia \hbox attr \referenceattribute \lastreferenceattribute {#1}% \else @@ -1152,7 +1162,9 @@ \begingroup \attribute\referenceattribute\attributeunsetvalue \iflocation +\dostarttagged\t!link\empty \ctxlua{jobreferences.inject("\referenceprefix","#3",nil,nil,\extrareferencearguments)}% +\dostoptagged \setlocationcolorspec{#1}% no consequence for strut \hbox attr \referenceattribute \lastreferenceattribute {#2}% \else @@ -1165,7 +1177,9 @@ \begingroup \attribute\referenceattribute\attributeunsetvalue \iflocation +\dostarttagged\t!link\empty \ctxlua{jobreferences.inject("\referenceprefix","#2",nil,nil,\extrareferencearguments)}% +\dostoptagged \hbox attr \referenceattribute \lastreferenceattribute {#1}% \else #1% @@ -1179,7 +1193,9 @@ \iflocation \ctxlua{jobreferences.doifelse("\referenceprefix","#2",\extrareferencearguments)}% {\expandtexincurrentreference +\dostarttagged\t!link\empty \ctxlua{jobreferences.injectcurrentset(nil,nil)}% +\dostoptagged \setlocationattributes\??ia \hbox attr \referenceattribute \lastreferenceattribute {#1}}% {\unknownreference{#2}}% @@ -1187,6 +1203,18 @@ #1% \fi \endgroup} + +\unexpanded\def\gotowdhtbox#1#2[#3]% fast variant for overlays + {\dontleavehmode + \begingroup + \attribute\referenceattribute\attributeunsetvalue + \ctxlua{jobreferences.doifelse("\referenceprefix","#3",\extrareferencearguments)}% + {\ctxlua{jobreferences.injectcurrentset(nil,nil)}% + \setbox\scratchbox\null\wd\scratchbox#1\ht\scratchbox#2% + \hbox attr \referenceattribute \lastreferenceattribute {\box\scratchbox}}% + {\unknownreference{#3}}% + \endgroup} + %D An reference to another document can be specified as a file %D or as an \URL. Both are handled by the same mechanism and diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv index 529e8cd1e..413ccb81a 100644 --- a/tex/context/base/strc-reg.mkiv +++ b/tex/context/base/strc-reg.mkiv @@ -577,12 +577,12 @@ \registerparameter\c!command{\strut#1}% \endgroup \registerparameter\c!after - \par\nobreak} - + \par + \nobreak} % b = <goodbreak> <before> <character> <after> <nobreak> -\setvalue{\??id:\c!indicator:b}#1% +\setvalue{\??id:\c!indicator:b}#1% will be shared with a {\registerparameter\c!before \begingroup\dosetregisterattributes\c!style\c!color \registerparameter\c!command{\strut#1}% @@ -603,47 +603,59 @@ \unexpanded\def\startregisteroutput {\endgraf \begingroup + \dostarttagged\t!register\currentregister \forgetparindent \forgetparskip} \unexpanded\def\stopregisteroutput {\endgraf + \dostoptagged \endgroup} \unexpanded\def\startregisterentries#1% depth {\endgraf \begingroup + \dostarttagged\t!registerentries\empty \dosetregisterattributes\c!textstyle\c!textcolor \advance\leftskip\numexpr#1-1\relax\dimexpr\registerparameter\c!distance\relax \hangindent\registerparameter\c!distance\hangafter\plusone} \unexpanded\def\stopregisterentries {\endgraf + \dostoptagged \endgroup} \unexpanded\def\startregistersection#1% title - {\registercharacter{#1}\endgraf} + {\dostarttagged\t!registersection\empty + \dostarttagged\t!registertag\empty + \registercharacter{#1}\endgraf + \dostoptagged} \unexpanded\def\stopregistersection - {\endgraf} + {\dostoptagged + \endgraf} \newconditional\registerpagedone \unexpanded\def\startregisterpages {\begingroup + \dostarttagged\t!registerpages\empty \setfalse\registerpagedone \dosetregisterattributes\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterpages - {\endgroup} + {\dostoptagged + \endgroup} \unexpanded\def\startregisterseewords {\begingroup \setfalse\registerpagedone + \dostarttagged\t!registerpage\empty \dosetregisterattributes\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterseewords - {\endgroup} + {\dostoptagged + \endgroup} \def\registerpageseparator% todo: , configurable {\ifconditional\registerpagedone @@ -665,20 +677,37 @@ \def\registeronepage#1#2#3% content {\registerpageseparator - \withregisterpagecommand{#1}{#2}{#3}} + \dostarttagged\t!registerpage\empty + \withregisterpagecommand{#1}{#2}{#3}% + \dostoptagged} \def\registerpagerange#1#2#3#4#5#6% content, content todo: -- configurable {\registerpageseparator + \dostarttagged\t!registerpagerange\empty + \dostarttagged\t!registerfrompage\empty \withregisterpagecommand{#1}{#2}{#3}% + \dostoptagged \registeronepagerangeseparator - \withregisterpagecommand{#4}{#5}{#6}} + \dostarttagged\t!registertopage\empty + \withregisterpagecommand{#4}{#5}{#6}% + \dostoptagged + \dostoptagged} \def\registeroneword#1#2#3% content {\registerpageseparator - \registerseeword{#3}} - -\def\defaultregisterentry #1{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#1}}}} -\def\defaultregisterseeword#1{\labeltexts\v!see{#1}} + \dostarttagged\t!registersee\empty + \registerseeword{#3}% + \dostoptagged} + +\def\defaultregisterentry#1% + {\dostarttagged\t!registerentry\empty + \registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#1}}}% + \dostoptagged} + +\def\defaultregisterseeword#1% + {\dostarttagged\t!registersee\empty + \labeltexts\v!see{#1}% + \dostoptagged} \let\registerseeword \defaultregisterseeword \let\registerentry \defaultregisterentry diff --git a/tex/context/base/strc-sbe.mkiv b/tex/context/base/strc-sbe.mkiv index 206ac8a9c..8497c37bb 100644 --- a/tex/context/base/strc-sbe.mkiv +++ b/tex/context/base/strc-sbe.mkiv @@ -61,11 +61,13 @@ % TODO \resetsectionmarks\zerosection \getstructureblockenvironment\currentstructureblock \structureblockparameter\c!before % don't move + \dostarttagged\t!division\currentstructureblock \to \everybeforestructureblock \appendtoks \structureblockparameter\c!after % don't move \doifsomething{\structureblockparameter\c!page}{\page[\structureblockparameter\c!page]}% + \dostoptagged % TODO \resetsectionmarks\zerosection \to \everyafterstructureblock diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv index 1968cbae9..2dd602448 100644 --- a/tex/context/base/strc-sec.mkiv +++ b/tex/context/base/strc-sec.mkiv @@ -255,6 +255,7 @@ \def\dostopstructurehead[#1]% {%\globalpopmacro\currentstructurehead \xdef\currentstructurehead{#1}% recover + \dostoptagged\dostoptagged \the\everyafterstructurehead} \def\donextstructurehead[#1][#2][#3]% @@ -357,13 +358,18 @@ % \unexpanded\def\fullstructureheadnumber{\labeltexts{\structureheadparameter\c!label}{\structurenumber}} % todo \unexpanded\def\fullstructureheadnumber - {\edef\currentstructureheadlabeltag{\currentstructureblock\c!label}% - \labeltexts{\structureheadparameter\currentstructureheadlabeltag}{\structurenumber}} + {\edef\currentstructureheadlabeltag{\currentstructureblock\c!label}% + \dostarttagged\t!structurenumber\empty + \labeltexts{\structureheadparameter\currentstructureheadlabeltag}{\structurenumber}% + \dostoptagged} % \def\fullstructureheadtitle {\structurevariable{titledata.title}} % no catcode! % \unexpanded\def\fullstructureheadtitle{\structureautocatcodedget{titledata.title}{\structureheadparameter\s!catcodes}} -\unexpanded\def\fullstructureheadtitle{\ctxlua{structure.sections.title()}} +\unexpanded\def\fullstructureheadtitle + {\dostarttagged\t!structuretitle\empty + \ctxlua{structure.sections.title()}% + \dostoptagged} \let\currentstructurehead \empty \let\currentstructureheadcoupling\empty @@ -516,6 +522,7 @@ \flushingcolumnfloatstrue \setfalse\ignorehandlepagebreak % ignorespaces prevents spaces creeping in when after=\dontleavehmode + \dostarttagged\t!structurecontent\empty \ifconditional\structureheadisdisplay % \ifdisplaysectionhead \ignorespaces \else @@ -567,12 +574,14 @@ \def\dostructureheadspacingbeforeyes {\docheckstructureheadbefore \dohandlestructureheadpagebreak - \structureheadparameter\c!inbetween} + \structureheadparameter\c!inbetween + \dostarttagged\t!structure\currentstructurehead} \def\dostructureheadspacingbeforenop {\docheckstructureheadbefore \docheckstructureheadlayout - \structureheadparameter\c!inbetween} + \structureheadparameter\c!inbetween + \dostarttagged\currentstructurehead\empty} % \def\emptystructureheadcorrection % {\ifconditional\structureheadleaveempty % inlined \emptyheadcorrection (with after=\blank) @@ -661,7 +670,7 @@ % \ifpagebreakdisabled % \global\pagebreakdisabledfalse % \else - \dopreventbreakafterstructureheadauto +% \dopreventbreakafterstructureheadauto % not ok as it binds the prev par % \fi \doif{\structureheadparameter\c!aligntitle}\v!float\indent \global\precedingstructurelevel\currentstructureheadlevel diff --git a/tex/context/base/strc-tag.lua b/tex/context/base/strc-tag.lua new file mode 100644 index 000000000..4381fc529 --- /dev/null +++ b/tex/context/base/strc-tag.lua @@ -0,0 +1,85 @@ +if not modules then modules = { } end modules ['strc-tag'] = { + version = 1.001, + comment = "companion to strc-tag.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is rather experimental code. + +local insert, remove, unpack, concat = table.insert, table.remove, table.unpack, table.concat +local gsub, find, topattern, format = string.gsub, string.find, string.topattern, string.format +local lpegmatch = lpeg.match +local texattribute = tex.attribute +local unsetvalue = attributes.unsetvalue + +structure.tags = structure.tags or { } + +local report_tags = logs.new("tags") + +local trace_tags = false trackers.register("structure.tags", function(v) trace_tags = v end) + +local a_tagged = attributes.private('tagged') +local a_image = attributes.private('image') + +local tags, labels, stack, chain, ids, enabled = { }, { }, { }, { }, { }, false -- no grouping assumed + +structure.tags.taglist = tags -- can best be hidden + +function structure.tags.start(tag,label,detail) + labels[label or tag] = tag + if detail and detail ~= "" then + tag = tag .. ":" .. detail + end + if not enabled then + backends.codeinjections.enabletags(tags,labels) + enabled = true + end + local n = (ids[tag] or 0) + 1 + ids[tag] = n + chain[#chain+1] = tag .. "-" .. n -- insert(chain,tag .. ":" .. n) + local t = #tags + 1 + stack[#stack+1] = t -- insert(stack,t) + tags[t] = { unpack(chain) } -- we can add key values for alt and actualtext if needed + texattribute[a_tagged] = t + return t +end + +function structure.tags.stop() + local t = stack[#stack] stack[#stack] = nil -- local t = remove(stack) + if not t then + if trace_tags then + report_tags("ignoring end tag, previous chain: %s",#chain > 0 and concat(chain[#chain]) or "none") + end + t = unsetvalue + else + chain[#chain] = nil -- remove(chain) + end + texattribute[a_tagged] = t + return t +end + +function structure.atlocation(str) + local location = gsub(concat(tags[texattribute[a_tagged]],"-"),"%-%d+","") + return find(location,topattern(str)) ~= nil +end + +function structure.tags.handler(head) -- we need a dummy + return head, false +end + +statistics.register("structure elements", function() + if enabled then + return format("%s element chains identified",#tags) + else + return nil + end +end) + +directives.register("backend.addtags", function(v) + if not enabled then + backends.codeinjections.enabletags(tags,labels) + enabled = true + end +end) diff --git a/tex/context/base/strc-tag.mkiv b/tex/context/base/strc-tag.mkiv new file mode 100644 index 000000000..53323050a --- /dev/null +++ b/tex/context/base/strc-tag.mkiv @@ -0,0 +1,192 @@ +%D \module +%D [ file=strc-tag, +%D version=2010.07.16, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Tags, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% key/values and other names might change (and probably will) + +\writestatus{loading}{ConTeXt Structure Macros / Tags} + +\registerctxluafile{strc-tag}{1.001} + +\unprotect + +% labels: temporary here + +\def\t!document {document} % Div + +\def\t!division {division} % Div +\def\t!paragraph {paragraph} % P +\def\t!construct {construct} % Span + +\def\t!structure {structure} % Sect +\def\t!structuretitle {structuretitle} % H +\def\t!structurenumber {structurenumber} % H +\def\t!structurecontent {structurecontent} % Div + +\def\t!itemgroup {itemgroup} % L +\def\t!item {item} % Li +\def\t!itemtag {itemtag} % Lbl +\def\t!itemcontent {itemcontent} % LBody + +\def\t!description {description} % Li +\def\t!descriptiontag {descriptiontag} % Lbl +\def\t!descriptioncontent{descriptioncontent} % LBody + +\def\t!verbatimblock {verbatimblock} % Code +\def\t!verbatim {verbatim} % Code + +\def\t!register {register} % Div +\def\t!registersection {registersection} % Div +\def\t!registertag {registertag} % Span +\def\t!registerentries {registerentries} % Div +\def\t!registerentry {registerentry} % Span +\def\t!registersee {registersee} % Span +\def\t!registerpages {registerpages} % Span +\def\t!registerpage {registerpage} % Span + +\def\t!table {table} % Table +\def\t!tablerow {tr} % TR +\def\t!tablecell {td} % TD +\def\t!tabulate {tabulate} % Table +\def\t!tabulaterow {row} % TR +\def\t!tabulatecell {cell} % TD + +\def\t!list {list} % TOC +\def\t!listitem {listitem} % TOCI +\def\t!listtag {listtag} % Lbl +\def\t!listcontent {listcontent} % P +\def\t!listdata {listdata} % P +\def\t!listpage {listpage} % Reference + +\def\t!delimitedblock {delimited} % BlockQuote +\def\t!delimited {delimited} % Quote +\def\t!subsentence {subsentence} % Span + +\def\t!float {float} % Div +\def\t!floatcaption {floatcaption} % Caption +\def\t!floattag {floattag} % Span +\def\t!floattext {floattext} % Span +\def\t!floatcontent {floatcontent} % P + +\def\t!image {image} % P + +\def\t!mpgraphic {mpgraphic} % P + +\def\t!formulaset {formulaset} % Div +\def\t!formula {formula} % Div +\def\t!formulatag {formulatag} % Span +\def\t!formulacontent {formulacontent} % P +\def\t!subformula {subformula} % Div + +\def\t!link {link} % Link + +% \setuptaglabeltext +% [en] +% [\t!document=document] + +% the real code + +\definesystemattribute[tagged] \chardef\taggedattribute \dogetattributeid{tagged} +\definesystemattribute[image] \chardef\imageattribute \dogetattributeid{image} + +% \def\mapelementtobackendtag {\dodoubleargument\domapelementtobackendtag} +% \def\domapelementtobackendtag[#1][#2]{\ctxlua{backends.codeinjections.maptag("#1","#2")}} + +% todo: indirect macro for trialtypesetting + +\unexpanded\def\dostartelement{\iftrialtypesetting\expandafter\noostartelement\else\expandafter\dodostartelement\fi} +\unexpanded\def\dostopelement {\iftrialtypesetting \else\expandafter\dodostopelement \fi} + +\unexpanded\def\dodostartelement[#1]{\ctxlua{structure.tags.start("#1","\dogetupsometaglabeltext{#1}")}} +\unexpanded\def\dodostopelement {\ctxlua{structure.tags.stop()}} + +\unexpanded\def\nostartelement[#1]{} +\unexpanded\def\nostopelement {} + +% beware: making this one unexpanded spoils tables (noalign problem) + +\def\dodostarttagged{\iftrialtypesetting\expandafter\nodostarttagged\else\expandafter\dododostarttagged\fi} +\def\dodostoptagged {\iftrialtypesetting \else\expandafter\dododostoptagged \fi} + +\def\dododostarttagged#1#2{\ctxlua{structure.tags.start("#1","\dogetupsometaglabeltext{#1}","#2")}} +\def\dododostoptagged {\ctxlua{structure.tags.stop()}} + +\def\nodostarttagged#1#2{} +\def\nodostoptagged {} + +\newtoks\everysetupstructure + +\def\setupstructure[#1]% + {\getparameters[\??el][#1]% + \the\everysetupstructure} + +\def\doenableelements + {\setuplanguage[\s!default][\s!righthyphenchar="AD]% for the moment here + \let\startelement\dostartelement + \let\stopelement \dostopelement} + +\def\dodisableelements + {\let\startelement\nostartelement + \let\stopelement \nostopelement} + +\def\doenabletagged + {\let\dostarttagged\dodostarttagged + \let\dostoptagged \dodostoptagged } + +\def\dodisabletagged + {\let\dostarttagged\nodostarttagged + \let\dostoptagged \nodostoptagged } + +\newtoks\everyenableelements +\newtoks\everydisableelements + +\appendtoks + \doenableelements + \doifelse\@@elmethod\v!auto\doenabletagged\dodisabletagged +\to \everyenableelements + +\appendtoks + \dodisableelements + \dodisabletagged +\to \everydisableelements + +\appendtoks + \doifelse\@@elstate\v!start{\the\everyenableelements}{\the\everydisableelements}% +\to \everysetupstructure + +\setupstructure + [\c!state=\v!stop, + \c!method=\v!auto] + +\unexpanded\def\startparagraph + {\dostarttagged\t!paragraph\empty} + +\unexpanded\def\stopparagraph + {\dostoptagged + \par} + +\appendtoks + \dostarttagged\t!document\empty +\to \everystarttext + +\appendtoks + \dostoptagged +\to \everystoptext + +% \doifinelementelse{structure:section} {yes} {no} +% \doifinelementelse{structure:chapter} {yes} {no} +% \doifinelementelse{division:*-structure:chapter} {yes} {no} + +\def\doifinelementelse#1% + {\ctxlua{commands.testcase(structure.atlocation("#1"))}} + +\protect diff --git a/tex/context/base/tabl-ntb.mkiv b/tex/context/base/tabl-ntb.mkiv index b24eaa85d..67d20a615 100644 --- a/tex/context/base/tabl-ntb.mkiv +++ b/tex/context/base/tabl-ntb.mkiv @@ -671,7 +671,7 @@ \executeifdefined{\@@rawtblprefix\v!start\v!oddeven\TBLlevel}\relax \executeifdefined{\@@rawtblprefix\v!start\number\TBLlevel}\relax} -\def\bTABLE +\unexpanded\def\bTABLE {\dosingleempty\dobTABLE} \def\dobTABLE[#1]% @@ -726,7 +726,7 @@ \unexpanded\def\eTH{\ignorespaces} \unexpanded\def\eTN{\ignorespaces} -\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode +\unexpanded\def\eTABLE % beware, we need to get rid of spurious spaces when in hmode {% tricky and dirty order -) \doifsometokselse\TBLhead % slow, better a flag {\the\TBLhead @@ -900,18 +900,35 @@ \fi \egroup}} +% \def\begintbl +% {\global\tblspn\zerocount +% \global\tblcol\zerocount +% \global\tblrow\zerocount +% \global\advance\tblrow\minusone +% \tabskip\zeropoint +% \halign\bgroup +% \registerparoptions % new +% \ignorespaces##\unskip&&\ignorespaces##\unskip\cr} + +% \def\endtbl +% {\egroup} + \def\begintbl {\global\tblspn\zerocount \global\tblcol\zerocount \global\tblrow\zerocount \global\advance\tblrow\minusone \tabskip\zeropoint + \dostarttagged\t!table\empty + \dostarttagged\t!tablerow\empty + \appendtoks\dostoptagged\dostarttagged\t!tablerow\empty\to\everycr \halign\bgroup \registerparoptions % new - \ignorespaces##\unskip&&\ignorespaces##\unskip\cr} + \ignorespaces##\unskip&&\dostarttagged\t!tablecell\empty\ignorespaces##\unskip\dostoptagged\cr} \def\endtbl - {\egroup} + {\dostoptagged\egroup + \dostoptagged} \setvalue{\tblnone TBL}#1#2% {\spanTBL{#1}{#2}} diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv index 400d8a659..007338146 100644 --- a/tex/context/base/tabl-tbl.mkiv +++ b/tex/context/base/tabl-tbl.mkiv @@ -348,6 +348,7 @@ \bgroup \noexpand\bbskip \bgroup % we cannot combine the if because a cell may have only one ## +\noexpand\dostarttagged\noexpand\t!tabulatecell\noexpand\empty \noexpand#1% \ifcase\tabulatereshape\else \beginreshapedtabulatepar @@ -373,6 +374,7 @@ \endreshapedtabulatepar \fi \noexpand#2% +\noexpand\dostoptagged \egroup \egroup &\noexpand\posttabrule\hskip\postabskip##% @@ -1370,7 +1372,12 @@ \setbox\tabulatebox\vbox \bgroup \fi % +\dostarttagged\t!tabulate\empty +\dostarttagged\t!tabulaterow\empty +\appendtoks\dostoptagged\dostarttagged\t!tabulaterow\empty\to\everycr \@EA\halign\@EA{\the\!!toksa\crcr\fulltabulatecontent\crcr}% +\dostoptagged +\dostoptagged \prevdepth\strutdp % nog eens beter, temporary hack \doifvalue{\??tt\currenttabulate\c!distance}\v!grid{\vskip-\strutdp}% experimental tm-prikkels % diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index 0706fa322..4c5ac401d 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -39,6 +39,8 @@ tasks.appendaction("shipouts", "normalizers", "nodes.add_references") tasks.appendaction("shipouts", "normalizers", "nodes.add_destinations") -- disabled tasks.appendaction("shipouts", "normalizers", "nodes.rules.process") -- disabled tasks.appendaction("shipouts", "normalizers", "nodes.shifts.process") -- disabled +tasks.appendaction("shipouts", "normalizers", "structure.tags.handler") -- disabled +tasks.appendaction("shipouts", "normalizers", "nodes.accessibility.handler") -- disabled tasks.appendaction("shipouts", "finishers", "shipouts.handle_color") -- disabled tasks.appendaction("shipouts", "finishers", "shipouts.handle_transparency") -- disabled @@ -50,6 +52,8 @@ tasks.appendaction("shipouts", "finishers", "shipouts.handle_viewerlayer") tasks.appendaction("math", "normalizers", "noads.relocate_characters", nil, "nohead") -- always on tasks.appendaction("math", "normalizers", "noads.resize_characters", nil, "nohead") -- always on tasks.appendaction("math", "normalizers", "noads.respace_characters", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.check_alternates", nil, "nohead") -- always on +tasks.appendaction("math", "normalizers", "noads.add_tags", nil, "nohead") -- disabled tasks.appendaction("math", "builders", "noads.mlist_to_hlist") -- always on @@ -86,6 +90,8 @@ tasks.disableaction("shipouts", "shipouts.handle_colorintent") tasks.disableaction("shipouts", "shipouts.handle_effect") tasks.disableaction("shipouts", "shipouts.handle_negative") tasks.disableaction("shipouts", "shipouts.handle_viewerlayer") +tasks.disableaction("shipouts", "structure.tags.handler") +tasks.disableaction("shipouts", "nodes.accessibility.handler") tasks.disableaction("shipouts", "nodes.add_references") tasks.disableaction("shipouts", "nodes.add_destinations") @@ -95,6 +101,8 @@ tasks.disableaction("mvlbuilders", "nodes.migrate_outwards") tasks.disableaction("processors", "parbuilders.solutions.splitters.split") tasks.disableaction("finalizers", "parbuilders.solutions.splitters.optimize") +tasks.disableaction("math", "noads.add_tags") + callbacks.freeze("find_.*_file", "find file using resolver") callbacks.freeze("read_.*_file", "read file at once") callbacks.freeze("open_.*_file", "open file for reading") diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index 109d84612..51b98c7f3 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -122,11 +122,21 @@ function tracers.printerror(offset) end end -function tracers.texerrormessage(...) -- for the moment we put this function here - local v = format(...) - tex.sprint(tex.ctxcatcodes,"\\errmessage{") - tex.sprint(tex.vrbcatcodes,v) - tex.print(tex.ctxcatcodes,"}") +if tex.error then + + function tracers.texerrormessage(...) -- for the moment we put this function here + tex.error(format(...), { }) + end + +else + + function tracers.texerrormessage(...) -- for the moment we put this function here + local v = format(...) + tex.sprint(tex.ctxcatcodes,"\\errmessage{") + tex.sprint(tex.vrbcatcodes,v) + tex.print(tex.ctxcatcodes,"}") + end + end directives.register("system.errorcontext", function(v) diff --git a/tex/context/base/trac-lmx.mkiv b/tex/context/base/trac-lmx.mkiv deleted file mode 100644 index a47d2b8bb..000000000 --- a/tex/context/base/trac-lmx.mkiv +++ /dev/null @@ -1,16 +0,0 @@ -%D \module -%D [ file=trac-lmx, -%D version=2005.09.02, -%D title=\CONTEXT\ Tracing Macros, -%D subtitle=LMX, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=PRAGMA] -%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 Tracing Macros / LMX} - -\registerctxluafile{trac-lmx}{1.001} diff --git a/tex/context/base/type-ini.mkiv b/tex/context/base/type-ini.mkiv index 4698a39be..8fb2c077a 100644 --- a/tex/context/base/type-ini.mkiv +++ b/tex/context/base/type-ini.mkiv @@ -403,12 +403,12 @@ \def\typefaceencoding{\defaultencoding} \def\dostarttypefacedefining#1#2#3% - {\geteparameters[\??ts][\s!rscale=\plusone,\s!features=,\s!fallbacks=,#3]% + {\geteparameters[\??ts][\s!rscale=\plusone,\s!features=,\s!fallbacks=,\s!goodies=,#3]% \pushmacro\fontclass \setcurrentfontclass{#1}% \pushmacro\relativefontsize \let\relativefontsize\@@tsrscale % still needed ? - \savefontclassparameters{#2}\@@tsrscale\@@tsfeatures\@@tsfallbacks} + \savefontclassparameters{#2}\@@tsrscale\@@tsfeatures\@@tsfallbacks\@@tsgoodies} \def\dostoptypefacedefining {\popmacro\relativefontsize diff --git a/tex/context/base/type-otf.mkiv b/tex/context/base/type-otf.mkiv index eacded942..b889e1ad2 100644 --- a/tex/context/base/type-otf.mkiv +++ b/tex/context/base/type-otf.mkiv @@ -1834,10 +1834,13 @@ \starttypescriptcollection[xits] % This one makes more sense. Xits uses the glyph collection from stix but packages - % it in a proper OpenType Math font. + % it in a proper OpenType Math font. From the Stix site: Version 1.1, which will + % include fonts packaged for use with Microsoft Office applications, is scheduled + % for release by the end of 2010. Version 1.2, which will include Type 1 fonts for + % use with LaTeX, will follow in 2011. So, we are on our own anyway. \starttypescript [math] [xits] [name] - \definefontsynonym[MathRoman][file:xits-math.otf][\s!features=\s!math\mathsizesuffix] + \definefontsynonym[MathRoman][file:xits-math.otf][\s!features=\s!math\mathsizesuffix,\s!goodies=xits-math] \stoptypescript \starttypescript [serif] [xits] [name] diff --git a/tex/context/base/x-mathml.mkiv b/tex/context/base/x-mathml.mkiv index 4d093a463..5e1046272 100644 --- a/tex/context/base/x-mathml.mkiv +++ b/tex/context/base/x-mathml.mkiv @@ -2286,6 +2286,12 @@ \ctxlua{lxml.mml.mmultiscripts("#1")} \stopxmlsetups +% goodie + +\definebuffer[mml] + +\def\stopmml{\xmlprocessbuffer{@mml@}{\thedefinedbuffer{mml}}{}} + \stopmodule \protect \endinput diff --git a/tex/context/fonts/xits-math.lfg b/tex/context/fonts/xits-math.lfg new file mode 100644 index 000000000..84e569e5f --- /dev/null +++ b/tex/context/fonts/xits-math.lfg @@ -0,0 +1,12 @@ +return { + name = "xits-math", + version = "1.00", + comment = "Goodies that complement xits.", + author = "Hans Hagen", + copyright = "ConTeXt development team", + mathematics = { + alternates = { + cal = { feature = 'ss01', value = 1, comment = "alternative calligraphic shapes" }, + } + } +} diff --git a/tex/context/interface/keys-cs.xml b/tex/context/interface/keys-cs.xml index 93d81caa6..40d5f2fae 100644 --- a/tex/context/interface/keys-cs.xml +++ b/tex/context/interface/keys-cs.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='velke'/> <cd:variable name='bigbodyfont' value='bigbodyfont'/> + <cd:variable name='bigger' value='bigger'/> <cd:variable name='bigpreference' value='vysokapriorita'/> <cd:variable name='blank' value='prazdny'/> <cd:variable name='blockquote' value='blockquote'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='nahodny'/> <cd:variable name='readonly' value='pouzeprocteni'/> <cd:variable name='rectangular' value='pravouhly'/> + <cd:variable name='reference' value='odkaz'/> <cd:variable name='referral' value='znacka'/> <cd:variable name='register' value='rejstrik'/> <cd:variable name='regular' value='pravidelne'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='maletucnekurzivni'/> <cd:variable name='smallboldslanted' value='maletucnesklonene'/> <cd:variable name='smallcaps' value='kapitalky'/> + <cd:variable name='smaller' value='smaller'/> <cd:variable name='smallitalic' value='malekurzivni'/> <cd:variable name='smallitalicbold' value='malekurzivnitucne'/> <cd:variable name='smallnormal' value='malenormalni'/> diff --git a/tex/context/interface/keys-de.xml b/tex/context/interface/keys-de.xml index 4c60d2be4..4ded5c635 100644 --- a/tex/context/interface/keys-de.xml +++ b/tex/context/interface/keys-de.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='gross'/> <cd:variable name='bigbodyfont' value='bigbodyfont'/> + <cd:variable name='bigger' value='bigger'/> <cd:variable name='bigpreference' value='grosszuegig'/> <cd:variable name='blank' value='blanko'/> <cd:variable name='blockquote' value='blockquote'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='zufaellig'/> <cd:variable name='readonly' value='nurlesbar'/> <cd:variable name='rectangular' value='rechteckig'/> + <cd:variable name='reference' value='referenz'/> <cd:variable name='referral' value='merkmal'/> <cd:variable name='register' value='register'/> <cd:variable name='regular' value='regular'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='kleinfettitalic'/> <cd:variable name='smallboldslanted' value='kleinfettgeneigt'/> <cd:variable name='smallcaps' value='smallcaps'/> + <cd:variable name='smaller' value='smaller'/> <cd:variable name='smallitalic' value='kleinitalic'/> <cd:variable name='smallitalicbold' value='kleinitalicfett'/> <cd:variable name='smallnormal' value='kleinnormal'/> diff --git a/tex/context/interface/keys-en.xml b/tex/context/interface/keys-en.xml index 26ee20ad3..995f53c93 100644 --- a/tex/context/interface/keys-en.xml +++ b/tex/context/interface/keys-en.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='big'/> <cd:variable name='bigbodyfont' value='bigbodyfont'/> + <cd:variable name='bigger' value='bigger'/> <cd:variable name='bigpreference' value='bigpreference'/> <cd:variable name='blank' value='blank'/> <cd:variable name='blockquote' value='blockquote'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='random'/> <cd:variable name='readonly' value='readonly'/> <cd:variable name='rectangular' value='rectangular'/> + <cd:variable name='reference' value='reference'/> <cd:variable name='referral' value='referral'/> <cd:variable name='register' value='register'/> <cd:variable name='regular' value='regular'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='smallbolditalic'/> <cd:variable name='smallboldslanted' value='smallboldslanted'/> <cd:variable name='smallcaps' value='smallcaps'/> + <cd:variable name='smaller' value='smaller'/> <cd:variable name='smallitalic' value='smallitalic'/> <cd:variable name='smallitalicbold' value='smallitalicbold'/> <cd:variable name='smallnormal' value='smallnormal'/> diff --git a/tex/context/interface/keys-fr.xml b/tex/context/interface/keys-fr.xml index ba6483365..3e52b484e 100644 --- a/tex/context/interface/keys-fr.xml +++ b/tex/context/interface/keys-fr.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='grand'/> <cd:variable name='bigbodyfont' value='grandepolicecorp'/> + <cd:variable name='bigger' value='bigger'/> <cd:variable name='bigpreference' value='grandepreference'/> <cd:variable name='blank' value='vide'/> <cd:variable name='blockquote' value='blockquote'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='aleatoire'/> <cd:variable name='readonly' value='lectureseule'/> <cd:variable name='rectangular' value='rectangulaire'/> + <cd:variable name='reference' value='reference'/> <cd:variable name='referral' value='referral'/> <cd:variable name='register' value='registre'/> <cd:variable name='regular' value='regulier'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='italiquegraspetit'/> <cd:variable name='smallboldslanted' value='inclinegraspetit'/> <cd:variable name='smallcaps' value='petitescapitales'/> + <cd:variable name='smaller' value='smaller'/> <cd:variable name='smallitalic' value='italiquepetit'/> <cd:variable name='smallitalicbold' value='grasitaliquepetit'/> <cd:variable name='smallnormal' value='normalpetit'/> diff --git a/tex/context/interface/keys-it.xml b/tex/context/interface/keys-it.xml index 098aba899..944dea0e9 100644 --- a/tex/context/interface/keys-it.xml +++ b/tex/context/interface/keys-it.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='grande'/> <cd:variable name='bigbodyfont' value='grossofontdeltesto'/> + <cd:variable name='bigger' value='bigger'/> <cd:variable name='bigpreference' value='grandepreferenza'/> <cd:variable name='blank' value='rigovuoto'/> <cd:variable name='blockquote' value='blockquote'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='casuale'/> <cd:variable name='readonly' value='solalettura'/> <cd:variable name='rectangular' value='rettangolare'/> + <cd:variable name='reference' value='riferimento'/> <cd:variable name='referral' value='referral'/> <cd:variable name='register' value='registro'/> <cd:variable name='regular' value='regolare'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='piccolograssettocorsivo'/> <cd:variable name='smallboldslanted' value='piccolograssettoinclinato'/> <cd:variable name='smallcaps' value='maiuscoletto'/> + <cd:variable name='smaller' value='smaller'/> <cd:variable name='smallitalic' value='piccolocorsivo'/> <cd:variable name='smallitalicbold' value='piccolocorsivograssetto'/> <cd:variable name='smallnormal' value='piccolonormale'/> diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml index d9eb33410..30044d0f1 100644 --- a/tex/context/interface/keys-nl.xml +++ b/tex/context/interface/keys-nl.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='groot'/> <cd:variable name='bigbodyfont' value='grootkorps'/> + <cd:variable name='bigger' value='groter'/> <cd:variable name='bigpreference' value='grotevoorkeur'/> <cd:variable name='blank' value='blanko'/> <cd:variable name='blockquote' value='blokcitaat'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='willekeurig'/> <cd:variable name='readonly' value='alleenleesbaar'/> <cd:variable name='rectangular' value='recht'/> + <cd:variable name='reference' value='referentie'/> <cd:variable name='referral' value='kenmerk'/> <cd:variable name='register' value='register'/> <cd:variable name='regular' value='regular'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='kleinvetitalic'/> <cd:variable name='smallboldslanted' value='kleinvetschuin'/> <cd:variable name='smallcaps' value='smallcaps'/> + <cd:variable name='smaller' value='kleiner'/> <cd:variable name='smallitalic' value='kleinitalic'/> <cd:variable name='smallitalicbold' value='kleinitalicvet'/> <cd:variable name='smallnormal' value='kleinnormaal'/> diff --git a/tex/context/interface/keys-pe.xml b/tex/context/interface/keys-pe.xml index 2b0a3f25b..543880d25 100644 --- a/tex/context/interface/keys-pe.xml +++ b/tex/context/interface/keys-pe.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='بزرگ'/> <cd:variable name='bigbodyfont' value='قلمبدنهبزرگ'/> + <cd:variable name='bigger' value='bigger'/> <cd:variable name='bigpreference' value='اولویتبزرگ'/> <cd:variable name='blank' value='خالی'/> <cd:variable name='blockquote' value='نقلبلوک'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='تصادفی'/> <cd:variable name='readonly' value='تنهاخواندنی'/> <cd:variable name='rectangular' value='چهارگوشه'/> + <cd:variable name='reference' value='مرجع'/> <cd:variable name='referral' value='مراجعه'/> <cd:variable name='register' value='ثبت'/> <cd:variable name='regular' value='منظم'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='ایتالیکمشکیکوچک'/> <cd:variable name='smallboldslanted' value='خوابیدهمشکیکوچک'/> <cd:variable name='smallcaps' value='smallcaps'/> + <cd:variable name='smaller' value='smaller'/> <cd:variable name='smallitalic' value='ایتالیککوچک'/> <cd:variable name='smallitalicbold' value='مشکیایتالیککوچک'/> <cd:variable name='smallnormal' value='نرمالکوچک'/> diff --git a/tex/context/interface/keys-ro.xml b/tex/context/interface/keys-ro.xml index 46f2ecd1e..b5d98845f 100644 --- a/tex/context/interface/keys-ro.xml +++ b/tex/context/interface/keys-ro.xml @@ -93,6 +93,7 @@ <cd:variable name='bib' value='bib'/> <cd:variable name='big' value='mare'/> <cd:variable name='bigbodyfont' value='bigbodyfont'/> + <cd:variable name='bigger' value='bigger'/> <cd:variable name='bigpreference' value='preferintamare'/> <cd:variable name='blank' value='blank'/> <cd:variable name='blockquote' value='blockquote'/> @@ -367,6 +368,7 @@ <cd:variable name='random' value='aleator'/> <cd:variable name='readonly' value='readonly'/> <cd:variable name='rectangular' value='rectangular'/> + <cd:variable name='reference' value='referinta'/> <cd:variable name='referral' value='referinta'/> <cd:variable name='register' value='registru'/> <cd:variable name='regular' value='regular'/> @@ -414,6 +416,7 @@ <cd:variable name='smallbolditalic' value='micaldininclinat'/> <cd:variable name='smallboldslanted' value='micaldininclinat'/> <cd:variable name='smallcaps' value='majusculemici'/> + <cd:variable name='smaller' value='smaller'/> <cd:variable name='smallitalic' value='micitalic'/> <cd:variable name='smallitalicbold' value='micitalicaldin'/> <cd:variable name='smallnormal' value='micnormal'/> diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua index 6fd20b1e9..3f96aa593 100644 --- a/tex/generic/context/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 07/15/10 15:01:32 +-- merge date : 07/30/10 11:35:46 do -- begin closure to overcome local limits and interference @@ -3112,6 +3112,8 @@ fontloader.totable = fontloader.to_table fonts = fonts or { } +-- we will also have des and fam hashes + fonts.ids = fonts.ids or { } fonts.identifiers = fonts.ids -- aka fontdata fonts.chr = fonts.chr or { } fonts.characters = fonts.chr -- aka chardata fonts.qua = fonts.qua or { } fonts.quads = fonts.qua -- aka quaddata @@ -7535,7 +7537,7 @@ local function prepare_base_substitutions(tfmdata,kind,value) -- we can share so if pv then local upv = unicodes[pv] if upv then - if type(upv) == "table" then + if type(upv) == "table" then -- zero change that table upv = upv[1] end if characters[upv] then @@ -7563,7 +7565,7 @@ local function prepare_base_substitutions(tfmdata,kind,value) -- we can share so if pc then local upc = unicodes[pc] if upc then - if type(upc) == "table" then + if type(upc) == "table" then -- zero change that table upc = upc[1] end if characters[upc] then @@ -11257,6 +11259,15 @@ function define.resolve(specification) else specification.forced = specification.forced end + -- for the moment here (goodies eset outside features) + local goodies = specification.goodies + if goodies and goodies ~= "" then + local normalgoodies = specification.features.normal.goodies + if not normalgoodies or normalgoodies == "" then + specification.features.normal.goodies = goodies + end + end + -- specification.hash = lower(specification.name .. ' @ ' .. tfm.hash_features(specification)) if specification.sub and specification.sub ~= "" then specification.hash = specification.sub .. ' @ ' .. specification.hash |